1 | /* IcedTeaScriptablePluginObject.cc
|
---|
2 |
|
---|
3 | Copyright (C) 2009, 2010 Red Hat
|
---|
4 |
|
---|
5 | This file is part of IcedTea.
|
---|
6 |
|
---|
7 | IcedTea is free software; you can redistribute it and/or modify
|
---|
8 | it under the terms of the GNU General Public License as published by
|
---|
9 | the Free Software Foundation; either version 2, or (at your option)
|
---|
10 | any later version.
|
---|
11 |
|
---|
12 | IcedTea is distributed in the hope that it will be useful, but
|
---|
13 | WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
15 | General Public License for more details.
|
---|
16 |
|
---|
17 | You should have received a copy of the GNU General Public License
|
---|
18 | along with IcedTea; see the file COPYING. If not, write to the
|
---|
19 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
---|
20 | 02110-1301 USA.
|
---|
21 |
|
---|
22 | Linking this library statically or dynamically with other modules is
|
---|
23 | making a combined work based on this library. Thus, the terms and
|
---|
24 | conditions of the GNU General Public License cover the whole
|
---|
25 | combination.
|
---|
26 |
|
---|
27 | As a special exception, the copyright holders of this library give you
|
---|
28 | permission to link this library with independent modules to produce an
|
---|
29 | executable, regardless of the license terms of these independent
|
---|
30 | modules, and to copy and distribute the resulting executable under
|
---|
31 | terms of your choice, provided that you also meet, for each linked
|
---|
32 | independent module, the terms and conditions of the license of that
|
---|
33 | module. An independent module is a module which is not derived from
|
---|
34 | or based on this library. If you modify this library, you may extend
|
---|
35 | this exception to your version of the library, but you are not
|
---|
36 | obligated to do so. If you do not wish to do so, delete this
|
---|
37 | exception statement from your version. */
|
---|
38 |
|
---|
39 | #include <typeinfo>
|
---|
40 |
|
---|
41 | #include "IcedTeaScriptablePluginObject.h"
|
---|
42 |
|
---|
43 | IcedTeaScriptablePluginObject::IcedTeaScriptablePluginObject(NPP instance)
|
---|
44 | {
|
---|
45 | this->instance = instance;
|
---|
46 | IcedTeaPluginUtilities::storeInstanceID(this, instance);
|
---|
47 | }
|
---|
48 |
|
---|
49 | void
|
---|
50 | IcedTeaScriptablePluginObject::deAllocate(NPObject *npobj)
|
---|
51 | {
|
---|
52 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::deAllocate %p\n", npobj);
|
---|
53 | }
|
---|
54 |
|
---|
55 | void
|
---|
56 | IcedTeaScriptablePluginObject::invalidate(NPObject *npobj)
|
---|
57 | {
|
---|
58 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::invalidate %p\n", npobj);
|
---|
59 | }
|
---|
60 |
|
---|
61 | bool
|
---|
62 | IcedTeaScriptablePluginObject::hasMethod(NPObject *npobj, NPIdentifier name)
|
---|
63 | {
|
---|
64 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::hasMethod %p\n", npobj);
|
---|
65 | return false;
|
---|
66 | }
|
---|
67 |
|
---|
68 | bool
|
---|
69 | IcedTeaScriptablePluginObject::invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args,
|
---|
70 | uint32_t argCount,NPVariant *result)
|
---|
71 | {
|
---|
72 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::invoke %p\n", npobj);
|
---|
73 | return false;
|
---|
74 | }
|
---|
75 |
|
---|
76 | bool
|
---|
77 | IcedTeaScriptablePluginObject::invokeDefault(NPObject *npobj, const NPVariant *args,
|
---|
78 | uint32_t argCount, NPVariant *result)
|
---|
79 | {
|
---|
80 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::invokeDefault %p\n", npobj);
|
---|
81 | return false;
|
---|
82 | }
|
---|
83 |
|
---|
84 | bool
|
---|
85 | IcedTeaScriptablePluginObject::hasProperty(NPObject *npobj, NPIdentifier name)
|
---|
86 | {
|
---|
87 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::hasProperty %p\n", npobj);
|
---|
88 | return false;
|
---|
89 | }
|
---|
90 |
|
---|
91 | bool
|
---|
92 | IcedTeaScriptablePluginObject::getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
|
---|
93 | {
|
---|
94 | // Package request?
|
---|
95 | if (!strcmp(browser_functions.utf8fromidentifier(name), "java"))
|
---|
96 | {
|
---|
97 | //NPObject* obj = IcedTeaScriptablePluginObject::get_scriptable_java_package_object(getInstanceFromMemberPtr(npobj), name);
|
---|
98 | //OBJECT_TO_NPVARIANT(obj, *result);
|
---|
99 |
|
---|
100 | //printf ("Filling variant %p with object %p\n", result);
|
---|
101 | }
|
---|
102 |
|
---|
103 | return false;
|
---|
104 | }
|
---|
105 |
|
---|
106 | bool
|
---|
107 | IcedTeaScriptablePluginObject::setProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
|
---|
108 | {
|
---|
109 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::setProperty %p\n", npobj);
|
---|
110 | return false;
|
---|
111 | }
|
---|
112 |
|
---|
113 | bool
|
---|
114 | IcedTeaScriptablePluginObject::removeProperty(NPObject *npobj, NPIdentifier name)
|
---|
115 | {
|
---|
116 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::removeProperty %p\n", npobj);
|
---|
117 | return false;
|
---|
118 | }
|
---|
119 |
|
---|
120 | bool
|
---|
121 | IcedTeaScriptablePluginObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
|
---|
122 | {
|
---|
123 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::enumerate %p\n", npobj);
|
---|
124 | return false;
|
---|
125 | }
|
---|
126 |
|
---|
127 | bool
|
---|
128 | IcedTeaScriptablePluginObject::construct(NPObject *npobj, const NPVariant *args, uint32_t argCount,
|
---|
129 | NPVariant *result)
|
---|
130 | {
|
---|
131 | printf ("** Unimplemented: IcedTeaScriptablePluginObject::construct %p\n", npobj);
|
---|
132 | return false;
|
---|
133 | }
|
---|
134 |
|
---|
135 | NPObject*
|
---|
136 | allocate_scriptable_jp_object(NPP npp, NPClass *aClass)
|
---|
137 | {
|
---|
138 | PLUGIN_DEBUG("Allocating new scriptable Java Package object\n");
|
---|
139 | return new IcedTeaScriptableJavaPackageObject(npp);
|
---|
140 | }
|
---|
141 |
|
---|
142 | NPObject*
|
---|
143 | IcedTeaScriptablePluginObject::get_scriptable_java_package_object(NPP instance, const NPUTF8* name)
|
---|
144 | {
|
---|
145 |
|
---|
146 | NPObject* scriptable_object;
|
---|
147 |
|
---|
148 | NPClass* np_class = new NPClass();
|
---|
149 | np_class->structVersion = NP_CLASS_STRUCT_VERSION;
|
---|
150 | np_class->allocate = allocate_scriptable_jp_object;
|
---|
151 | np_class->deallocate = IcedTeaScriptableJavaPackageObject::deAllocate;
|
---|
152 | np_class->invalidate = IcedTeaScriptableJavaPackageObject::invalidate;
|
---|
153 | np_class->hasMethod = IcedTeaScriptableJavaPackageObject::hasMethod;
|
---|
154 | np_class->invoke = IcedTeaScriptableJavaPackageObject::invoke;
|
---|
155 | np_class->invokeDefault = IcedTeaScriptableJavaPackageObject::invokeDefault;
|
---|
156 | np_class->hasProperty = IcedTeaScriptableJavaPackageObject::hasProperty;
|
---|
157 | np_class->getProperty = IcedTeaScriptableJavaPackageObject::getProperty;
|
---|
158 | np_class->setProperty = IcedTeaScriptableJavaPackageObject::setProperty;
|
---|
159 | np_class->removeProperty = IcedTeaScriptableJavaPackageObject::removeProperty;
|
---|
160 | np_class->enumerate = IcedTeaScriptableJavaPackageObject::enumerate;
|
---|
161 | np_class->construct = IcedTeaScriptableJavaPackageObject::construct;
|
---|
162 |
|
---|
163 | scriptable_object = browser_functions.createobject(instance, np_class);
|
---|
164 | PLUGIN_DEBUG("Returning new scriptable package class: %p from instance %p with name %s\n", scriptable_object, instance, name);
|
---|
165 |
|
---|
166 | ((IcedTeaScriptableJavaPackageObject*) scriptable_object)->setPackageName(name);
|
---|
167 |
|
---|
168 | IcedTeaPluginUtilities::storeInstanceID(scriptable_object, instance);
|
---|
169 |
|
---|
170 | return scriptable_object;
|
---|
171 | }
|
---|
172 |
|
---|
173 | IcedTeaScriptableJavaPackageObject::IcedTeaScriptableJavaPackageObject(NPP instance)
|
---|
174 | {
|
---|
175 | PLUGIN_DEBUG("Constructing new scriptable java package object\n");
|
---|
176 | this->instance = instance;
|
---|
177 | this->package_name = new std::string();
|
---|
178 | }
|
---|
179 |
|
---|
180 | IcedTeaScriptableJavaPackageObject::~IcedTeaScriptableJavaPackageObject()
|
---|
181 | {
|
---|
182 | delete this->package_name;
|
---|
183 | }
|
---|
184 |
|
---|
185 | void
|
---|
186 | IcedTeaScriptableJavaPackageObject::setPackageName(const NPUTF8* name)
|
---|
187 | {
|
---|
188 | this->package_name->append(name);
|
---|
189 | }
|
---|
190 |
|
---|
191 | std::string
|
---|
192 | IcedTeaScriptableJavaPackageObject::getPackageName()
|
---|
193 | {
|
---|
194 | return this->package_name->c_str();
|
---|
195 | }
|
---|
196 |
|
---|
197 | void
|
---|
198 | IcedTeaScriptableJavaPackageObject::deAllocate(NPObject *npobj)
|
---|
199 | {
|
---|
200 | browser_functions.releaseobject(npobj);
|
---|
201 | }
|
---|
202 |
|
---|
203 | void
|
---|
204 | IcedTeaScriptableJavaPackageObject::invalidate(NPObject *npobj)
|
---|
205 | {
|
---|
206 | // nothing to do for these
|
---|
207 | }
|
---|
208 |
|
---|
209 | bool
|
---|
210 | IcedTeaScriptableJavaPackageObject::hasMethod(NPObject *npobj, NPIdentifier name)
|
---|
211 | {
|
---|
212 | // Silly caller. Methods are for objects!
|
---|
213 | return false;
|
---|
214 | }
|
---|
215 |
|
---|
216 | bool
|
---|
217 | IcedTeaScriptableJavaPackageObject::invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args,
|
---|
218 | uint32_t argCount,NPVariant *result)
|
---|
219 | {
|
---|
220 | printf ("** Unimplemented: IcedTeaScriptableJavaPackageObject::invoke %p\n", npobj);
|
---|
221 | return false;
|
---|
222 | }
|
---|
223 |
|
---|
224 | bool
|
---|
225 | IcedTeaScriptableJavaPackageObject::invokeDefault(NPObject *npobj, const NPVariant *args,
|
---|
226 | uint32_t argCount, NPVariant *result)
|
---|
227 | {
|
---|
228 | printf ("** Unimplemented: IcedTeaScriptableJavaPackageObject::invokeDefault %p\n", npobj);
|
---|
229 | return false;
|
---|
230 | }
|
---|
231 |
|
---|
232 | bool
|
---|
233 | IcedTeaScriptableJavaPackageObject::hasProperty(NPObject *npobj, NPIdentifier name)
|
---|
234 | {
|
---|
235 | PLUGIN_DEBUG("IcedTeaScriptableJavaPackageObject::hasProperty %s\n", browser_functions.utf8fromidentifier(name));
|
---|
236 |
|
---|
237 | bool hasProperty = false;
|
---|
238 | JavaResultData* java_result;
|
---|
239 | JavaRequestProcessor* java_request = new JavaRequestProcessor();
|
---|
240 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
241 | int plugin_instance_id = get_id_from_instance(instance);
|
---|
242 |
|
---|
243 | PLUGIN_DEBUG("Object package name: \"%s\"\n", ((IcedTeaScriptableJavaPackageObject*) npobj)->getPackageName().c_str());
|
---|
244 |
|
---|
245 | // "^java" is always a package
|
---|
246 | if (((IcedTeaScriptableJavaPackageObject*) npobj)->getPackageName().length() == 0 &&
|
---|
247 | ( !strcmp(browser_functions.utf8fromidentifier(name), "java") ||
|
---|
248 | !strcmp(browser_functions.utf8fromidentifier(name), "javax")))
|
---|
249 | {
|
---|
250 | return true;
|
---|
251 | }
|
---|
252 |
|
---|
253 | std::string property_name = ((IcedTeaScriptableJavaPackageObject*) npobj)->getPackageName();
|
---|
254 | if (property_name.length() > 0)
|
---|
255 | property_name += ".";
|
---|
256 | property_name += browser_functions.utf8fromidentifier(name);
|
---|
257 |
|
---|
258 | PLUGIN_DEBUG("Looking for name \"%s\"\n", property_name.c_str());
|
---|
259 |
|
---|
260 | java_result = java_request->hasPackage(plugin_instance_id, property_name);
|
---|
261 |
|
---|
262 | if (!java_result->error_occurred && java_result->return_identifier != 0) hasProperty = true;
|
---|
263 |
|
---|
264 | // No such package. Do we have a class with that name?
|
---|
265 | if (!hasProperty)
|
---|
266 | {
|
---|
267 | java_result = java_request->findClass(plugin_instance_id, property_name);
|
---|
268 | }
|
---|
269 |
|
---|
270 | if (java_result->return_identifier != 0) hasProperty = true;
|
---|
271 |
|
---|
272 | delete java_request;
|
---|
273 |
|
---|
274 | return hasProperty;
|
---|
275 | }
|
---|
276 |
|
---|
277 | bool
|
---|
278 | IcedTeaScriptableJavaPackageObject::getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
|
---|
279 | {
|
---|
280 |
|
---|
281 | PLUGIN_DEBUG("IcedTeaScriptableJavaPackageObject::getProperty %s\n", browser_functions.utf8fromidentifier(name));
|
---|
282 |
|
---|
283 | if (!browser_functions.utf8fromidentifier(name))
|
---|
284 | return false;
|
---|
285 |
|
---|
286 | bool isPropertyClass = false;
|
---|
287 | JavaResultData* java_result;
|
---|
288 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
289 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
290 | int plugin_instance_id = get_id_from_instance(instance);
|
---|
291 |
|
---|
292 | std::string property_name = ((IcedTeaScriptableJavaPackageObject*) npobj)->getPackageName();
|
---|
293 | if (property_name.length() > 0)
|
---|
294 | property_name += ".";
|
---|
295 | property_name += browser_functions.utf8fromidentifier(name);
|
---|
296 |
|
---|
297 | java_result = java_request.findClass(plugin_instance_id, property_name);
|
---|
298 | isPropertyClass = (java_result->return_identifier == 0);
|
---|
299 |
|
---|
300 | //NPIdentifier property = browser_functions.getstringidentifier(property_name.c_str());
|
---|
301 |
|
---|
302 | NPObject* obj;
|
---|
303 |
|
---|
304 | if (isPropertyClass)
|
---|
305 | {
|
---|
306 | PLUGIN_DEBUG("Returning package object\n");
|
---|
307 | obj = IcedTeaScriptablePluginObject::get_scriptable_java_package_object(
|
---|
308 | IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj),
|
---|
309 | property_name.c_str());
|
---|
310 | }
|
---|
311 | else
|
---|
312 | {
|
---|
313 | PLUGIN_DEBUG("Returning Java object\n");
|
---|
314 | obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object(
|
---|
315 | IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj),
|
---|
316 | *(java_result->return_string), "0", false);
|
---|
317 | }
|
---|
318 |
|
---|
319 | OBJECT_TO_NPVARIANT(obj, *result);
|
---|
320 |
|
---|
321 | return true;
|
---|
322 | }
|
---|
323 |
|
---|
324 | bool
|
---|
325 | IcedTeaScriptableJavaPackageObject::setProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
|
---|
326 | {
|
---|
327 | // Can't be going around setting properties on namespaces.. that's madness!
|
---|
328 | return false;
|
---|
329 | }
|
---|
330 |
|
---|
331 | bool
|
---|
332 | IcedTeaScriptableJavaPackageObject::removeProperty(NPObject *npobj, NPIdentifier name)
|
---|
333 | {
|
---|
334 | printf ("** Unimplemented: IcedTeaScriptableJavaPackageObject::removeProperty %p\n", npobj);
|
---|
335 | return false;
|
---|
336 | }
|
---|
337 |
|
---|
338 | bool
|
---|
339 | IcedTeaScriptableJavaPackageObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
|
---|
340 | {
|
---|
341 | printf ("** Unimplemented: IcedTeaScriptableJavaPackageObject::enumerate %p\n", npobj);
|
---|
342 | return false;
|
---|
343 | }
|
---|
344 |
|
---|
345 | bool
|
---|
346 | IcedTeaScriptableJavaPackageObject::construct(NPObject *npobj, const NPVariant *args, uint32_t argCount,
|
---|
347 | NPVariant *result)
|
---|
348 | {
|
---|
349 | printf ("** Unimplemented: IcedTeaScriptableJavaPackageObject::construct %p\n", npobj);
|
---|
350 | return false;
|
---|
351 | }
|
---|
352 |
|
---|
353 | NPObject*
|
---|
354 | allocate_scriptable_java_object(NPP npp, NPClass *aClass)
|
---|
355 | {
|
---|
356 | PLUGIN_DEBUG("Allocating new scriptable Java object\n");
|
---|
357 | return new IcedTeaScriptableJavaObject(npp);
|
---|
358 | }
|
---|
359 |
|
---|
360 | NPObject*
|
---|
361 | IcedTeaScriptableJavaPackageObject::get_scriptable_java_object(NPP instance,
|
---|
362 | std::string class_id,
|
---|
363 | std::string instance_id,
|
---|
364 | bool isArray)
|
---|
365 | {
|
---|
366 | NPObject* scriptable_object;
|
---|
367 |
|
---|
368 | std::string obj_key = std::string();
|
---|
369 | obj_key += class_id;
|
---|
370 | obj_key += ":";
|
---|
371 | obj_key += instance_id;
|
---|
372 |
|
---|
373 | PLUGIN_DEBUG("get_scriptable_java_object searching for %s...\n", obj_key.c_str());
|
---|
374 | scriptable_object = IcedTeaPluginUtilities::getNPObjectFromJavaKey(obj_key);
|
---|
375 |
|
---|
376 | if (scriptable_object != NULL)
|
---|
377 | {
|
---|
378 | PLUGIN_DEBUG("Returning existing object %p\n", scriptable_object);
|
---|
379 | browser_functions.retainobject(scriptable_object);
|
---|
380 | return scriptable_object;
|
---|
381 | }
|
---|
382 |
|
---|
383 |
|
---|
384 | NPClass* np_class = new NPClass();
|
---|
385 | np_class->structVersion = NP_CLASS_STRUCT_VERSION;
|
---|
386 | np_class->allocate = allocate_scriptable_java_object;
|
---|
387 | np_class->deallocate = IcedTeaScriptableJavaObject::deAllocate;
|
---|
388 | np_class->invalidate = IcedTeaScriptableJavaObject::invalidate;
|
---|
389 | np_class->hasMethod = IcedTeaScriptableJavaObject::hasMethod;
|
---|
390 | np_class->invoke = IcedTeaScriptableJavaObject::invoke;
|
---|
391 | np_class->invokeDefault = IcedTeaScriptableJavaObject::invokeDefault;
|
---|
392 | np_class->hasProperty = IcedTeaScriptableJavaObject::hasProperty;
|
---|
393 | np_class->getProperty = IcedTeaScriptableJavaObject::getProperty;
|
---|
394 | np_class->setProperty = IcedTeaScriptableJavaObject::setProperty;
|
---|
395 | np_class->removeProperty = IcedTeaScriptableJavaObject::removeProperty;
|
---|
396 | np_class->enumerate = IcedTeaScriptableJavaObject::enumerate;
|
---|
397 | np_class->construct = IcedTeaScriptableJavaObject::construct;
|
---|
398 |
|
---|
399 | // try to create normally
|
---|
400 | scriptable_object = browser_functions.createobject(instance, np_class);
|
---|
401 |
|
---|
402 | // didn't work? try creating asynch
|
---|
403 | if (!scriptable_object)
|
---|
404 | {
|
---|
405 | AsyncCallThreadData thread_data = AsyncCallThreadData();
|
---|
406 | thread_data.result_ready = false;
|
---|
407 | thread_data.parameters = std::vector<void*>();
|
---|
408 | thread_data.result = std::string();
|
---|
409 |
|
---|
410 | thread_data.parameters.push_back(instance);
|
---|
411 | thread_data.parameters.push_back(np_class);
|
---|
412 | thread_data.parameters.push_back(&scriptable_object);
|
---|
413 |
|
---|
414 | IcedTeaPluginUtilities::callAndWaitForResult(instance, &_createAndRetainJavaObject, &thread_data);
|
---|
415 | } else
|
---|
416 | {
|
---|
417 | // Else retain object and continue
|
---|
418 | browser_functions.retainobject(scriptable_object);
|
---|
419 | }
|
---|
420 |
|
---|
421 | PLUGIN_DEBUG("Constructed new Java Object with classid=%s, instanceid=%s, isArray=%d and scriptable_object=%p\n", class_id.c_str(), instance_id.c_str(), isArray, scriptable_object);
|
---|
422 |
|
---|
423 | ((IcedTeaScriptableJavaObject*) scriptable_object)->setClassIdentifier(class_id);
|
---|
424 | ((IcedTeaScriptableJavaObject*) scriptable_object)->setIsArray(isArray);
|
---|
425 |
|
---|
426 | if (instance_id != "0")
|
---|
427 | ((IcedTeaScriptableJavaObject*) scriptable_object)->setInstanceIdentifier(instance_id);
|
---|
428 |
|
---|
429 | IcedTeaPluginUtilities::storeInstanceID(scriptable_object, instance);
|
---|
430 | IcedTeaPluginUtilities::storeObjectMapping(obj_key, scriptable_object);
|
---|
431 |
|
---|
432 | PLUGIN_DEBUG("Inserting into object_map key %s->%p\n", obj_key.c_str(), scriptable_object);
|
---|
433 | return scriptable_object;
|
---|
434 | }
|
---|
435 |
|
---|
436 | /* Creates and retains a scriptable java object (intended to be called asynch.) */
|
---|
437 | void
|
---|
438 | _createAndRetainJavaObject(void* data)
|
---|
439 | {
|
---|
440 | PLUGIN_DEBUG("Asynchronously creating/retaining object ...\n");
|
---|
441 |
|
---|
442 | std::vector<void*> parameters = ((AsyncCallThreadData*) data)->parameters;
|
---|
443 | NPP instance = (NPP) parameters.at(0);
|
---|
444 | NPClass* np_class = (NPClass*) parameters.at(1);
|
---|
445 | NPObject** scriptable_object = (NPObject**) parameters.at(2);
|
---|
446 |
|
---|
447 | *scriptable_object = browser_functions.createobject(instance, np_class);
|
---|
448 | browser_functions.retainobject(*scriptable_object);
|
---|
449 |
|
---|
450 | ((AsyncCallThreadData*) data)->result_ready = true;
|
---|
451 | }
|
---|
452 |
|
---|
453 | bool
|
---|
454 | IcedTeaScriptableJavaPackageObject::is_valid_java_object(NPObject* object_ptr) {
|
---|
455 | return IcedTeaPluginUtilities::getInstanceFromMemberPtr(object_ptr) != NULL;
|
---|
456 | }
|
---|
457 |
|
---|
458 | IcedTeaScriptableJavaObject::IcedTeaScriptableJavaObject(NPP instance)
|
---|
459 | {
|
---|
460 | this->instance = instance;
|
---|
461 | this->class_id = new std::string();
|
---|
462 | this->instance_id = new std::string();
|
---|
463 | }
|
---|
464 |
|
---|
465 | IcedTeaScriptableJavaObject::~IcedTeaScriptableJavaObject()
|
---|
466 | {
|
---|
467 | delete this->class_id;
|
---|
468 | delete this->instance_id;
|
---|
469 | }
|
---|
470 |
|
---|
471 | void
|
---|
472 | IcedTeaScriptableJavaObject::setClassIdentifier(std::string class_id)
|
---|
473 | {
|
---|
474 | this->class_id->append(class_id);
|
---|
475 | }
|
---|
476 |
|
---|
477 | void
|
---|
478 | IcedTeaScriptableJavaObject::setInstanceIdentifier(std::string instance_id)
|
---|
479 | {
|
---|
480 | this->instance_id->append(instance_id);
|
---|
481 | }
|
---|
482 |
|
---|
483 | void
|
---|
484 | IcedTeaScriptableJavaObject::setIsArray(bool isArray)
|
---|
485 | {
|
---|
486 | this->isObjectArray = isArray;
|
---|
487 | }
|
---|
488 |
|
---|
489 | void
|
---|
490 | IcedTeaScriptableJavaObject::deAllocate(NPObject *npobj)
|
---|
491 | {
|
---|
492 | browser_functions.releaseobject(npobj);
|
---|
493 | }
|
---|
494 |
|
---|
495 | void
|
---|
496 | IcedTeaScriptableJavaObject::invalidate(NPObject *npobj)
|
---|
497 | {
|
---|
498 | IcedTeaPluginUtilities::removeInstanceID(npobj);
|
---|
499 |
|
---|
500 | std::string obj_key = std::string();
|
---|
501 | obj_key += ((IcedTeaScriptableJavaObject*) npobj)->getClassID();
|
---|
502 | obj_key += ":";
|
---|
503 | obj_key += ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID();
|
---|
504 |
|
---|
505 | IcedTeaPluginUtilities::removeObjectMapping(obj_key);
|
---|
506 | }
|
---|
507 |
|
---|
508 | bool
|
---|
509 | IcedTeaScriptableJavaObject::hasMethod(NPObject *npobj, NPIdentifier name)
|
---|
510 | {
|
---|
511 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasMethod %s (ival=%d)\n", browser_functions.utf8fromidentifier(name), browser_functions.intfromidentifier(name));
|
---|
512 | bool hasMethod = false;
|
---|
513 |
|
---|
514 | // If object is an array and requested "method" may be a number, check for it first
|
---|
515 | if ( !((IcedTeaScriptableJavaObject*) npobj)->isArray() ||
|
---|
516 | (browser_functions.intfromidentifier(name) < 0))
|
---|
517 | {
|
---|
518 |
|
---|
519 | if (!browser_functions.utf8fromidentifier(name))
|
---|
520 | return false;
|
---|
521 |
|
---|
522 | JavaResultData* java_result;
|
---|
523 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
524 |
|
---|
525 | std::string classId = std::string(((IcedTeaScriptableJavaObject*) npobj)->getClassID());
|
---|
526 | std::string methodName = browser_functions.utf8fromidentifier(name);
|
---|
527 |
|
---|
528 | java_result = java_request.hasMethod(classId, methodName);
|
---|
529 | hasMethod = java_result->return_identifier != 0;
|
---|
530 | }
|
---|
531 |
|
---|
532 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasMethod returning %d\n", hasMethod);
|
---|
533 | return hasMethod;
|
---|
534 | }
|
---|
535 |
|
---|
536 | bool
|
---|
537 | IcedTeaScriptableJavaObject::invoke(NPObject *npobj, NPIdentifier name, const NPVariant *args,
|
---|
538 | uint32_t argCount, NPVariant *result)
|
---|
539 | {
|
---|
540 | NPUTF8* method_name = browser_functions.utf8fromidentifier(name);
|
---|
541 |
|
---|
542 | // Extract arg type array
|
---|
543 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::invoke %s. Args follow.\n", method_name);
|
---|
544 | for (int i=0; i < argCount; i++)
|
---|
545 | {
|
---|
546 | IcedTeaPluginUtilities::printNPVariant(args[i]);
|
---|
547 | }
|
---|
548 |
|
---|
549 | JavaResultData* java_result;
|
---|
550 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
551 |
|
---|
552 | NPObject* obj;
|
---|
553 | std::string instance_id = ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID();
|
---|
554 | std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID();
|
---|
555 | std::string callee;
|
---|
556 | std::string source;
|
---|
557 |
|
---|
558 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
559 |
|
---|
560 | // First, load the arguments into the java-side table
|
---|
561 | std::string id = std::string();
|
---|
562 | std::vector<std::string> arg_ids = std::vector<std::string>();
|
---|
563 | for (int i=0; i < argCount; i++) {
|
---|
564 | id.clear();
|
---|
565 | createJavaObjectFromVariant(instance, args[i], &id);
|
---|
566 |
|
---|
567 | if (id == "-1")
|
---|
568 | {
|
---|
569 | printf("Unable to create arguments on Java side\n");
|
---|
570 | return false;
|
---|
571 | }
|
---|
572 |
|
---|
573 | arg_ids.push_back(id);
|
---|
574 | }
|
---|
575 |
|
---|
576 | if (instance_id.length() == 0) // Static
|
---|
577 | {
|
---|
578 | PLUGIN_DEBUG("Calling static method\n");
|
---|
579 | callee = ((IcedTeaScriptableJavaObject*) npobj)->getClassID();
|
---|
580 | java_result = java_request.callStaticMethod(
|
---|
581 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
582 | callee, browser_functions.utf8fromidentifier(name), arg_ids);
|
---|
583 | } else
|
---|
584 | {
|
---|
585 | PLUGIN_DEBUG("Calling method normally\n");
|
---|
586 | callee = ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID();
|
---|
587 | java_result = java_request.callMethod(
|
---|
588 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
589 | callee, browser_functions.utf8fromidentifier(name), arg_ids);
|
---|
590 | }
|
---|
591 |
|
---|
592 | if (java_result->error_occurred)
|
---|
593 | {
|
---|
594 | // error message must be allocated on heap
|
---|
595 | char* error_msg = (char*) malloc(java_result->error_msg->length()*sizeof(char));
|
---|
596 | strcpy(error_msg, java_result->error_msg->c_str());
|
---|
597 | browser_functions.setexception(npobj, error_msg);
|
---|
598 | return false;
|
---|
599 | }
|
---|
600 |
|
---|
601 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::invoke converting and returning.\n");
|
---|
602 | return IcedTeaPluginUtilities::javaResultToNPVariant(instance, java_result->return_string, result);
|
---|
603 | }
|
---|
604 |
|
---|
605 | bool
|
---|
606 | IcedTeaScriptableJavaObject::invokeDefault(NPObject *npobj, const NPVariant *args,
|
---|
607 | uint32_t argCount, NPVariant *result)
|
---|
608 | {
|
---|
609 | printf ("** Unimplemented: IcedTeaScriptableJavaObject::invokeDefault %p\n", npobj);
|
---|
610 | return false;
|
---|
611 | }
|
---|
612 |
|
---|
613 | bool
|
---|
614 | IcedTeaScriptableJavaObject::hasProperty(NPObject *npobj, NPIdentifier name)
|
---|
615 | {
|
---|
616 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasProperty %s (ival=%d)\n", browser_functions.utf8fromidentifier(name), browser_functions.intfromidentifier(name));
|
---|
617 | bool hasProperty = false;
|
---|
618 |
|
---|
619 | // If it is an array, only length and indexes are valid
|
---|
620 | if (((IcedTeaScriptableJavaObject*) npobj)->isArray())
|
---|
621 | {
|
---|
622 | if (browser_functions.intfromidentifier(name) >= 0 ||
|
---|
623 | !strcmp(browser_functions.utf8fromidentifier(name), "length"))
|
---|
624 | hasProperty = true;
|
---|
625 |
|
---|
626 | } else
|
---|
627 | {
|
---|
628 |
|
---|
629 | if (!browser_functions.utf8fromidentifier(name))
|
---|
630 | return false;
|
---|
631 |
|
---|
632 | if (!strcmp(browser_functions.utf8fromidentifier(name), "Packages"))
|
---|
633 | {
|
---|
634 | hasProperty = true;
|
---|
635 | } else {
|
---|
636 |
|
---|
637 | JavaResultData* java_result;
|
---|
638 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
639 |
|
---|
640 | std::string class_id = std::string(((IcedTeaScriptableJavaObject*) npobj)->getClassID());
|
---|
641 | std::string fieldName = browser_functions.utf8fromidentifier(name);
|
---|
642 |
|
---|
643 | java_result = java_request.hasField(class_id, fieldName);
|
---|
644 |
|
---|
645 | hasProperty = java_result->return_identifier != 0;
|
---|
646 | }
|
---|
647 | }
|
---|
648 |
|
---|
649 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasProperty returning %d\n", hasProperty);
|
---|
650 | return hasProperty;
|
---|
651 | }
|
---|
652 |
|
---|
653 | bool
|
---|
654 | IcedTeaScriptableJavaObject::getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result)
|
---|
655 | {
|
---|
656 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::getProperty %s (ival=%d)\n", browser_functions.utf8fromidentifier(name), browser_functions.intfromidentifier(name));
|
---|
657 |
|
---|
658 | bool isPropertyClass = false;
|
---|
659 | JavaResultData* java_result;
|
---|
660 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
661 |
|
---|
662 | NPObject* obj;
|
---|
663 | std::string instance_id = ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID();
|
---|
664 | std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID();
|
---|
665 | NPP instance = ((IcedTeaScriptableJavaObject*) npobj)->getInstance();
|
---|
666 |
|
---|
667 | if (instance_id.length() > 0) // Could be an array or a simple object
|
---|
668 | {
|
---|
669 | // If array and requesting length
|
---|
670 | if ( ((IcedTeaScriptableJavaObject*) npobj)->isArray() &&
|
---|
671 | browser_functions.utf8fromidentifier(name) &&
|
---|
672 | !strcmp(browser_functions.utf8fromidentifier(name), "length"))
|
---|
673 | {
|
---|
674 | java_result = java_request.getArrayLength(instance_id);
|
---|
675 | } else if ( ((IcedTeaScriptableJavaObject*) npobj)->isArray() &&
|
---|
676 | browser_functions.intfromidentifier(name) >= 0) // else if array and requesting index
|
---|
677 | {
|
---|
678 |
|
---|
679 | java_result = java_request.getArrayLength(instance_id);
|
---|
680 | if (java_result->error_occurred)
|
---|
681 | {
|
---|
682 | printf("ERROR: Couldn't fetch array length\n");
|
---|
683 | return false;
|
---|
684 | }
|
---|
685 |
|
---|
686 | int length = atoi(java_result->return_string->c_str());
|
---|
687 |
|
---|
688 | // Access beyond size?
|
---|
689 | if (browser_functions.intfromidentifier(name) >= length)
|
---|
690 | {
|
---|
691 | VOID_TO_NPVARIANT(*result);
|
---|
692 | return true;
|
---|
693 | }
|
---|
694 |
|
---|
695 | std::string index = std::string();
|
---|
696 | IcedTeaPluginUtilities::itoa(browser_functions.intfromidentifier(name), &index);
|
---|
697 | java_result = java_request.getSlot(instance_id, index);
|
---|
698 |
|
---|
699 | } else // Everything else
|
---|
700 | {
|
---|
701 | if (!browser_functions.utf8fromidentifier(name))
|
---|
702 | return false;
|
---|
703 |
|
---|
704 | if (!strcmp(browser_functions.utf8fromidentifier(name), "Packages"))
|
---|
705 | {
|
---|
706 | NPObject* pkgObject = IcedTeaScriptablePluginObject::get_scriptable_java_package_object(instance, "");
|
---|
707 | OBJECT_TO_NPVARIANT(pkgObject, *result);
|
---|
708 | return true;
|
---|
709 | }
|
---|
710 |
|
---|
711 | java_result = java_request.getField(
|
---|
712 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
713 | class_id, instance_id, browser_functions.utf8fromidentifier(name));
|
---|
714 | }
|
---|
715 | }
|
---|
716 | else
|
---|
717 | {
|
---|
718 | if (!browser_functions.utf8fromidentifier(name))
|
---|
719 | return true;
|
---|
720 |
|
---|
721 | java_result = java_request.getStaticField(
|
---|
722 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
723 | class_id, browser_functions.utf8fromidentifier(name));
|
---|
724 | }
|
---|
725 |
|
---|
726 | if (java_result->error_occurred)
|
---|
727 | {
|
---|
728 | return false;
|
---|
729 | }
|
---|
730 |
|
---|
731 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::getProperty converting and returning.\n");
|
---|
732 | return IcedTeaPluginUtilities::javaResultToNPVariant(instance, java_result->return_string, result);
|
---|
733 | }
|
---|
734 |
|
---|
735 | bool
|
---|
736 | IcedTeaScriptableJavaObject::setProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
|
---|
737 | {
|
---|
738 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::setProperty %s (ival=%d) to:\n", browser_functions.utf8fromidentifier(name), browser_functions.intfromidentifier(name));
|
---|
739 | IcedTeaPluginUtilities::printNPVariant(*value);
|
---|
740 |
|
---|
741 | bool isPropertyClass = false;
|
---|
742 | JavaResultData* java_result;
|
---|
743 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
744 |
|
---|
745 | NPObject* obj;
|
---|
746 | std::string instance_id = ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID();
|
---|
747 | std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID();
|
---|
748 |
|
---|
749 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
750 |
|
---|
751 | if (instance_id.length() > 0) // Could be an array or a simple object
|
---|
752 | {
|
---|
753 | // If array
|
---|
754 | if ( ((IcedTeaScriptableJavaObject*) npobj)->isArray() &&
|
---|
755 | browser_functions.utf8fromidentifier(name) &&
|
---|
756 | !strcmp(browser_functions.utf8fromidentifier(name), "length"))
|
---|
757 | {
|
---|
758 | printf("ERROR: Array length is not a modifiable property\n");
|
---|
759 | return false;
|
---|
760 | } else if ( ((IcedTeaScriptableJavaObject*) npobj)->isArray() &&
|
---|
761 | browser_functions.intfromidentifier(name) >= 0) // else if array and requesting index
|
---|
762 | {
|
---|
763 |
|
---|
764 | java_result = java_request.getArrayLength(instance_id);
|
---|
765 | if (java_result->error_occurred)
|
---|
766 | {
|
---|
767 | printf("ERROR: Couldn't fetch array length\n");
|
---|
768 | return false;
|
---|
769 | }
|
---|
770 |
|
---|
771 | int length = atoi(java_result->return_string->c_str());
|
---|
772 |
|
---|
773 | // Access beyond size?
|
---|
774 | if (browser_functions.intfromidentifier(name) >= length)
|
---|
775 | {
|
---|
776 | return true;
|
---|
777 | }
|
---|
778 |
|
---|
779 | std::string index = std::string();
|
---|
780 | IcedTeaPluginUtilities::itoa(browser_functions.intfromidentifier(name), &index);
|
---|
781 |
|
---|
782 | std::string value_id = std::string();
|
---|
783 | createJavaObjectFromVariant(instance, *value, &value_id);
|
---|
784 |
|
---|
785 | java_result = java_request.setSlot(instance_id, index, value_id);
|
---|
786 |
|
---|
787 | } else // Everything else
|
---|
788 | {
|
---|
789 | std::string value_id = std::string();
|
---|
790 | createJavaObjectFromVariant(instance, *value, &value_id);
|
---|
791 |
|
---|
792 | java_result = java_request.setField(
|
---|
793 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
794 | class_id, instance_id, browser_functions.utf8fromidentifier(name), value_id);
|
---|
795 | }
|
---|
796 | }
|
---|
797 | else
|
---|
798 | {
|
---|
799 | std::string value_id = std::string();
|
---|
800 | createJavaObjectFromVariant(instance, *value, &value_id);
|
---|
801 |
|
---|
802 | java_result = java_request.setStaticField(
|
---|
803 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
804 | class_id, browser_functions.utf8fromidentifier(name), value_id);
|
---|
805 | }
|
---|
806 |
|
---|
807 | if (java_result->error_occurred)
|
---|
808 | {
|
---|
809 | return false;
|
---|
810 | }
|
---|
811 |
|
---|
812 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::setProperty returning.\n");
|
---|
813 | return true;
|
---|
814 | }
|
---|
815 |
|
---|
816 | bool
|
---|
817 | IcedTeaScriptableJavaObject::removeProperty(NPObject *npobj, NPIdentifier name)
|
---|
818 | {
|
---|
819 | printf ("** Unimplemented: IcedTeaScriptableJavaObject::removeProperty %p\n", npobj);
|
---|
820 | return false;
|
---|
821 | }
|
---|
822 |
|
---|
823 | bool
|
---|
824 | IcedTeaScriptableJavaObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
|
---|
825 | {
|
---|
826 | printf ("** Unimplemented: IcedTeaScriptableJavaObject::enumerate %p\n", npobj);
|
---|
827 | return false;
|
---|
828 | }
|
---|
829 |
|
---|
830 | bool
|
---|
831 | IcedTeaScriptableJavaObject::construct(NPObject *npobj, const NPVariant *args, uint32_t argCount,
|
---|
832 | NPVariant *result)
|
---|
833 | {
|
---|
834 | // Extract arg type array
|
---|
835 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::construct %s. Args follow.\n", ((IcedTeaScriptableJavaObject*) npobj)->getClassID().c_str());
|
---|
836 | for (int i=0; i < argCount; i++)
|
---|
837 | {
|
---|
838 | IcedTeaPluginUtilities::printNPVariant(args[i]);
|
---|
839 | }
|
---|
840 |
|
---|
841 | JavaResultData* java_result;
|
---|
842 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
843 |
|
---|
844 | NPObject* obj;
|
---|
845 | std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID();
|
---|
846 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
847 |
|
---|
848 | // First, load the arguments into the java-side table
|
---|
849 | std::string id = std::string();
|
---|
850 | std::vector<std::string> arg_ids = std::vector<std::string>();
|
---|
851 | for (int i=0; i < argCount; i++) {
|
---|
852 | id.clear();
|
---|
853 | createJavaObjectFromVariant(instance, args[i], &id);
|
---|
854 | if (id == "0")
|
---|
855 | {
|
---|
856 | // error message must be allocated on heap
|
---|
857 | char* error_msg = (char*) malloc(1024*sizeof(char));
|
---|
858 | strcpy(error_msg, "Unable to create argument on Java side");
|
---|
859 |
|
---|
860 | browser_functions.setexception(npobj, error_msg);
|
---|
861 | return false;
|
---|
862 | }
|
---|
863 |
|
---|
864 | arg_ids.push_back(id);
|
---|
865 | }
|
---|
866 |
|
---|
867 | java_result = java_request.newObject(
|
---|
868 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
869 | class_id,
|
---|
870 | arg_ids);
|
---|
871 |
|
---|
872 | if (java_result->error_occurred)
|
---|
873 | {
|
---|
874 | // error message must be allocated on heap
|
---|
875 | int length = java_result->error_msg->length();
|
---|
876 | char* error_msg = (char*) malloc((length+1)*sizeof(char));
|
---|
877 | strcpy(error_msg, java_result->error_msg->c_str());
|
---|
878 |
|
---|
879 | browser_functions.setexception(npobj, error_msg);
|
---|
880 | return false;
|
---|
881 | }
|
---|
882 |
|
---|
883 | std::string return_obj_instance_id = std::string();
|
---|
884 | std::string return_obj_class_id = class_id;
|
---|
885 | return_obj_instance_id.append(*(java_result->return_string));
|
---|
886 |
|
---|
887 | obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object(
|
---|
888 | IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj),
|
---|
889 | return_obj_class_id, return_obj_instance_id, false);
|
---|
890 |
|
---|
891 | OBJECT_TO_NPVARIANT(obj, *result);
|
---|
892 |
|
---|
893 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::construct returning.\n");
|
---|
894 | return true;
|
---|
895 | }
|
---|