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 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::deAllocate %p\n", npobj);
|
---|
53 | }
|
---|
54 |
|
---|
55 | void
|
---|
56 | IcedTeaScriptablePluginObject::invalidate(NPObject *npobj)
|
---|
57 | {
|
---|
58 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::invalidate %p\n", npobj);
|
---|
59 | }
|
---|
60 |
|
---|
61 | bool
|
---|
62 | IcedTeaScriptablePluginObject::hasMethod(NPObject *npobj, NPIdentifier name_id)
|
---|
63 | {
|
---|
64 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::hasMethod %p\n", npobj);
|
---|
65 | return false;
|
---|
66 | }
|
---|
67 |
|
---|
68 | bool
|
---|
69 | IcedTeaScriptablePluginObject::invoke(NPObject *npobj, NPIdentifier name_id, const NPVariant *args,
|
---|
70 | uint32_t argCount,NPVariant *result)
|
---|
71 | {
|
---|
72 | PLUGIN_ERROR ("** 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 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::invokeDefault %p\n", npobj);
|
---|
81 | return false;
|
---|
82 | }
|
---|
83 |
|
---|
84 | bool
|
---|
85 | IcedTeaScriptablePluginObject::hasProperty(NPObject *npobj, NPIdentifier name_id)
|
---|
86 | {
|
---|
87 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::hasProperty %p\n", npobj);
|
---|
88 | return false;
|
---|
89 | }
|
---|
90 |
|
---|
91 | bool
|
---|
92 | IcedTeaScriptablePluginObject::getProperty(NPObject *npobj, NPIdentifier name_id, NPVariant *result)
|
---|
93 | {
|
---|
94 | // Package request?
|
---|
95 | if (IcedTeaPluginUtilities::NPIdentifierAsString(name_id) == "java")
|
---|
96 | {
|
---|
97 | //NPObject* obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(getInstanceFromMemberPtr(npobj), name);
|
---|
98 | //OBJECT_TO_NPVARIANT(obj, *result);
|
---|
99 |
|
---|
100 | //PLUGIN_ERROR ("Filling variant %p with object %p\n", result);
|
---|
101 | }
|
---|
102 |
|
---|
103 | return false;
|
---|
104 | }
|
---|
105 |
|
---|
106 | bool
|
---|
107 | IcedTeaScriptablePluginObject::setProperty(NPObject *npobj, NPIdentifier name_id, const NPVariant *value)
|
---|
108 | {
|
---|
109 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::setProperty %p\n", npobj);
|
---|
110 | return false;
|
---|
111 | }
|
---|
112 |
|
---|
113 | bool
|
---|
114 | IcedTeaScriptablePluginObject::removeProperty(NPObject *npobj, NPIdentifier name_id)
|
---|
115 | {
|
---|
116 | PLUGIN_ERROR ("** 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 | PLUGIN_ERROR ("** 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 | PLUGIN_ERROR ("** 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 | static NPClass
|
---|
143 | scriptable_plugin_object_class() {
|
---|
144 | NPClass np_class;
|
---|
145 | np_class.structVersion = NP_CLASS_STRUCT_VERSION;
|
---|
146 | np_class.allocate = allocate_scriptable_jp_object;
|
---|
147 | np_class.deallocate = IcedTeaScriptableJavaPackageObject::deAllocate;
|
---|
148 | np_class.invalidate = IcedTeaScriptableJavaPackageObject::invalidate;
|
---|
149 | np_class.hasMethod = IcedTeaScriptableJavaPackageObject::hasMethod;
|
---|
150 | np_class.invoke = IcedTeaScriptableJavaPackageObject::invoke;
|
---|
151 | np_class.invokeDefault = IcedTeaScriptableJavaPackageObject::invokeDefault;
|
---|
152 | np_class.hasProperty = IcedTeaScriptableJavaPackageObject::hasProperty;
|
---|
153 | np_class.getProperty = IcedTeaScriptableJavaPackageObject::getProperty;
|
---|
154 | np_class.setProperty = IcedTeaScriptableJavaPackageObject::setProperty;
|
---|
155 | np_class.removeProperty = IcedTeaScriptableJavaPackageObject::removeProperty;
|
---|
156 | np_class.enumerate = IcedTeaScriptableJavaPackageObject::enumerate;
|
---|
157 | np_class.construct = IcedTeaScriptableJavaPackageObject::construct;
|
---|
158 | return np_class;
|
---|
159 | }
|
---|
160 |
|
---|
161 | NPObject*
|
---|
162 | IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(NPP instance, const NPUTF8* name)
|
---|
163 | {
|
---|
164 | /* Shared NPClass instance for IcedTeaScriptablePluginObject */
|
---|
165 | static NPClass np_class = scriptable_plugin_object_class();
|
---|
166 |
|
---|
167 | NPObject* scriptable_object = browser_functions.createobject(instance, &np_class);
|
---|
168 | PLUGIN_DEBUG("Returning new scriptable package class: %p from instance %p with name %s\n", scriptable_object, instance, name);
|
---|
169 |
|
---|
170 | ((IcedTeaScriptableJavaPackageObject*) scriptable_object)->setPackageName(name);
|
---|
171 |
|
---|
172 | IcedTeaPluginUtilities::storeInstanceID(scriptable_object, instance);
|
---|
173 |
|
---|
174 | return scriptable_object;
|
---|
175 | }
|
---|
176 |
|
---|
177 | IcedTeaScriptableJavaPackageObject::IcedTeaScriptableJavaPackageObject(NPP instance)
|
---|
178 | {
|
---|
179 | PLUGIN_DEBUG("Constructing new scriptable java package object\n");
|
---|
180 | this->instance = instance;
|
---|
181 | this->package_name = new std::string();
|
---|
182 | }
|
---|
183 |
|
---|
184 | IcedTeaScriptableJavaPackageObject::~IcedTeaScriptableJavaPackageObject()
|
---|
185 | {
|
---|
186 | delete this->package_name;
|
---|
187 | }
|
---|
188 |
|
---|
189 | void
|
---|
190 | IcedTeaScriptableJavaPackageObject::setPackageName(const NPUTF8* name)
|
---|
191 | {
|
---|
192 | this->package_name->assign(name);
|
---|
193 | }
|
---|
194 |
|
---|
195 | std::string
|
---|
196 | IcedTeaScriptableJavaPackageObject::getPackageName()
|
---|
197 | {
|
---|
198 | return *this->package_name;
|
---|
199 | }
|
---|
200 |
|
---|
201 | void
|
---|
202 | IcedTeaScriptableJavaPackageObject::deAllocate(NPObject *npobj)
|
---|
203 | {
|
---|
204 | delete (IcedTeaScriptableJavaPackageObject*)npobj;
|
---|
205 | }
|
---|
206 |
|
---|
207 | void
|
---|
208 | IcedTeaScriptableJavaPackageObject::invalidate(NPObject *npobj)
|
---|
209 | {
|
---|
210 | // nothing to do for these
|
---|
211 | }
|
---|
212 |
|
---|
213 | bool
|
---|
214 | IcedTeaScriptableJavaPackageObject::hasMethod(NPObject *npobj, NPIdentifier name_id)
|
---|
215 | {
|
---|
216 | // Silly caller. Methods are for objects!
|
---|
217 | return false;
|
---|
218 | }
|
---|
219 |
|
---|
220 | bool
|
---|
221 | IcedTeaScriptableJavaPackageObject::invoke(NPObject *npobj, NPIdentifier name_id, const NPVariant *args,
|
---|
222 | uint32_t argCount,NPVariant *result)
|
---|
223 | {
|
---|
224 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::invoke %p\n", npobj);
|
---|
225 | return false;
|
---|
226 | }
|
---|
227 |
|
---|
228 | bool
|
---|
229 | IcedTeaScriptableJavaPackageObject::invokeDefault(NPObject *npobj, const NPVariant *args,
|
---|
230 | uint32_t argCount, NPVariant *result)
|
---|
231 | {
|
---|
232 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::invokeDefault %p\n", npobj);
|
---|
233 | return false;
|
---|
234 | }
|
---|
235 |
|
---|
236 | bool
|
---|
237 | IcedTeaScriptableJavaPackageObject::hasProperty(NPObject *npobj, NPIdentifier name_id)
|
---|
238 | {
|
---|
239 | std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id);
|
---|
240 |
|
---|
241 | PLUGIN_DEBUG("IcedTeaScriptableJavaPackageObject::hasProperty %s\n", name.c_str());
|
---|
242 |
|
---|
243 | bool hasProperty = false;
|
---|
244 | JavaResultData* java_result;
|
---|
245 | JavaRequestProcessor* java_request = new JavaRequestProcessor();
|
---|
246 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
247 | int plugin_instance_id = get_id_from_instance(instance);
|
---|
248 | IcedTeaScriptableJavaPackageObject* scriptable_obj = (IcedTeaScriptableJavaPackageObject*)npobj;
|
---|
249 |
|
---|
250 | PLUGIN_DEBUG("Object package name: \"%s\"\n", scriptable_obj->getPackageName().c_str());
|
---|
251 |
|
---|
252 | // "^java" is always a package
|
---|
253 | if (scriptable_obj->getPackageName().empty() && (name == "java" || name == "javax"))
|
---|
254 | {
|
---|
255 | return true;
|
---|
256 | }
|
---|
257 |
|
---|
258 | std::string property_name = scriptable_obj->getPackageName();
|
---|
259 | if (!property_name.empty())
|
---|
260 | property_name += ".";
|
---|
261 | property_name += name;
|
---|
262 |
|
---|
263 | PLUGIN_DEBUG("Looking for name \"%s\"\n", property_name.c_str());
|
---|
264 |
|
---|
265 | java_result = java_request->hasPackage(plugin_instance_id, property_name);
|
---|
266 |
|
---|
267 | if (!java_result->error_occurred && java_result->return_identifier != 0) hasProperty = true;
|
---|
268 |
|
---|
269 | // No such package. Do we have a class with that name?
|
---|
270 | if (!hasProperty)
|
---|
271 | {
|
---|
272 | java_result = java_request->findClass(plugin_instance_id, property_name);
|
---|
273 | }
|
---|
274 |
|
---|
275 | if (java_result->return_identifier != 0) hasProperty = true;
|
---|
276 |
|
---|
277 | delete java_request;
|
---|
278 |
|
---|
279 | return hasProperty;
|
---|
280 | }
|
---|
281 |
|
---|
282 | bool
|
---|
283 | IcedTeaScriptableJavaPackageObject::getProperty(NPObject *npobj, NPIdentifier name_id, NPVariant *result)
|
---|
284 | {
|
---|
285 | std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id);
|
---|
286 |
|
---|
287 | PLUGIN_DEBUG("IcedTeaScriptableJavaPackageObject::getProperty %s\n", name.c_str());
|
---|
288 |
|
---|
289 | if (!browser_functions.identifierisstring(name_id))
|
---|
290 | return false;
|
---|
291 |
|
---|
292 | bool isPropertyClass = false;
|
---|
293 | JavaResultData* java_result;
|
---|
294 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
295 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
296 | int plugin_instance_id = get_id_from_instance(instance);
|
---|
297 | IcedTeaScriptableJavaPackageObject* scriptable_obj = (IcedTeaScriptableJavaPackageObject*)npobj;
|
---|
298 |
|
---|
299 | std::string property_name = scriptable_obj->getPackageName();
|
---|
300 | if (!property_name.empty())
|
---|
301 | property_name += ".";
|
---|
302 | property_name += name;
|
---|
303 |
|
---|
304 | java_result = java_request.findClass(plugin_instance_id, property_name);
|
---|
305 | isPropertyClass = (java_result->return_identifier == 0);
|
---|
306 |
|
---|
307 | //NPIdentifier property = browser_functions.getstringidentifier(property_name.c_str());
|
---|
308 |
|
---|
309 | NPObject* obj;
|
---|
310 |
|
---|
311 | if (isPropertyClass)
|
---|
312 | {
|
---|
313 | PLUGIN_DEBUG("Returning package object\n");
|
---|
314 | obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(
|
---|
315 | IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj),
|
---|
316 | property_name.c_str());
|
---|
317 | }
|
---|
318 | else
|
---|
319 | {
|
---|
320 | PLUGIN_DEBUG("Returning Java object\n");
|
---|
321 | obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(
|
---|
322 | IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj),
|
---|
323 | *(java_result->return_string), "0", false);
|
---|
324 | }
|
---|
325 |
|
---|
326 | OBJECT_TO_NPVARIANT(obj, *result);
|
---|
327 |
|
---|
328 | return true;
|
---|
329 | }
|
---|
330 |
|
---|
331 | bool
|
---|
332 | IcedTeaScriptableJavaPackageObject::setProperty(NPObject *npobj, NPIdentifier name_id, const NPVariant *value)
|
---|
333 | {
|
---|
334 | // Can't be going around setting properties on namespaces.. that's madness!
|
---|
335 | return false;
|
---|
336 | }
|
---|
337 |
|
---|
338 | bool
|
---|
339 | IcedTeaScriptableJavaPackageObject::removeProperty(NPObject *npobj, NPIdentifier name_id)
|
---|
340 | {
|
---|
341 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::removeProperty %p\n", npobj);
|
---|
342 | return false;
|
---|
343 | }
|
---|
344 |
|
---|
345 | bool
|
---|
346 | IcedTeaScriptableJavaPackageObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
|
---|
347 | {
|
---|
348 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::enumerate %p\n", npobj);
|
---|
349 | return false;
|
---|
350 | }
|
---|
351 |
|
---|
352 | bool
|
---|
353 | IcedTeaScriptableJavaPackageObject::construct(NPObject *npobj, const NPVariant *args, uint32_t argCount,
|
---|
354 | NPVariant *result)
|
---|
355 | {
|
---|
356 | PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::construct %p\n", npobj);
|
---|
357 | return false;
|
---|
358 | }
|
---|
359 |
|
---|
360 | NPObject*
|
---|
361 | allocate_scriptable_java_object(NPP npp, NPClass *aClass)
|
---|
362 | {
|
---|
363 | PLUGIN_DEBUG("Allocating new scriptable Java object\n");
|
---|
364 | return new IcedTeaScriptableJavaObject(npp);
|
---|
365 | }
|
---|
366 |
|
---|
367 |
|
---|
368 | static NPClass
|
---|
369 | scriptable_java_package_object_class() {
|
---|
370 | NPClass np_class;
|
---|
371 | np_class.structVersion = NP_CLASS_STRUCT_VERSION;
|
---|
372 | np_class.allocate = allocate_scriptable_java_object;
|
---|
373 | np_class.deallocate = IcedTeaScriptableJavaObject::deAllocate;
|
---|
374 | np_class.invalidate = IcedTeaScriptableJavaObject::invalidate;
|
---|
375 | np_class.hasMethod = IcedTeaScriptableJavaObject::hasMethod;
|
---|
376 | np_class.invoke = IcedTeaScriptableJavaObject::invoke;
|
---|
377 | np_class.invokeDefault = IcedTeaScriptableJavaObject::invokeDefault;
|
---|
378 | np_class.hasProperty = IcedTeaScriptableJavaObject::hasProperty;
|
---|
379 | np_class.getProperty = IcedTeaScriptableJavaObject::getProperty;
|
---|
380 | np_class.setProperty = IcedTeaScriptableJavaObject::setProperty;
|
---|
381 | np_class.removeProperty = IcedTeaScriptableJavaObject::removeProperty;
|
---|
382 | np_class.enumerate = IcedTeaScriptableJavaObject::enumerate;
|
---|
383 | np_class.construct = IcedTeaScriptableJavaObject::construct;
|
---|
384 | return np_class;
|
---|
385 | }
|
---|
386 |
|
---|
387 | NPObject*
|
---|
388 | IcedTeaScriptableJavaObject::get_scriptable_java_object(NPP instance,
|
---|
389 | std::string class_id,
|
---|
390 | std::string instance_id,
|
---|
391 | bool isArray)
|
---|
392 | {
|
---|
393 | /* Shared NPClass instance for IcedTeaScriptablePluginObject */
|
---|
394 | static NPClass np_class = scriptable_java_package_object_class();
|
---|
395 |
|
---|
396 | std::string obj_key = class_id + ":" + instance_id;
|
---|
397 |
|
---|
398 | PLUGIN_DEBUG("get_scriptable_java_object searching for %s...\n", obj_key.c_str());
|
---|
399 | IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) IcedTeaPluginUtilities::getNPObjectFromJavaKey(obj_key);
|
---|
400 |
|
---|
401 | if (scriptable_object != NULL)
|
---|
402 | {
|
---|
403 | PLUGIN_DEBUG("Returning existing object %p\n", scriptable_object);
|
---|
404 | browser_functions.retainobject(scriptable_object);
|
---|
405 | return scriptable_object;
|
---|
406 | }
|
---|
407 |
|
---|
408 | // try to create normally
|
---|
409 | scriptable_object = (IcedTeaScriptableJavaObject*)browser_functions.createobject(instance, &np_class);
|
---|
410 |
|
---|
411 | // didn't work? try creating asynch
|
---|
412 | if (!scriptable_object)
|
---|
413 | {
|
---|
414 | AsyncCallThreadData thread_data = AsyncCallThreadData();
|
---|
415 | thread_data.result_ready = false;
|
---|
416 | thread_data.parameters = std::vector<void*>();
|
---|
417 | thread_data.result = std::string();
|
---|
418 |
|
---|
419 | thread_data.parameters.push_back(instance);
|
---|
420 | thread_data.parameters.push_back(&np_class);
|
---|
421 | thread_data.parameters.push_back(&scriptable_object);
|
---|
422 |
|
---|
423 | IcedTeaPluginUtilities::callAndWaitForResult(instance, &_createAndRetainJavaObject, &thread_data);
|
---|
424 | } else
|
---|
425 | {
|
---|
426 | // Else retain object and continue
|
---|
427 | browser_functions.retainobject(scriptable_object);
|
---|
428 | }
|
---|
429 |
|
---|
430 | 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);
|
---|
431 |
|
---|
432 | scriptable_object->class_id = class_id;
|
---|
433 | scriptable_object->is_object_array = isArray;
|
---|
434 |
|
---|
435 | if (instance_id != "0")
|
---|
436 | scriptable_object->instance_id = instance_id;
|
---|
437 |
|
---|
438 | IcedTeaPluginUtilities::storeInstanceID(scriptable_object, instance);
|
---|
439 | IcedTeaPluginUtilities::storeObjectMapping(obj_key, scriptable_object);
|
---|
440 |
|
---|
441 | PLUGIN_DEBUG("Inserting into object_map key %s->%p\n", obj_key.c_str(), scriptable_object);
|
---|
442 | return scriptable_object;
|
---|
443 | }
|
---|
444 |
|
---|
445 | /* Creates and retains a scriptable java object (intended to be called asynch.) */
|
---|
446 | void
|
---|
447 | _createAndRetainJavaObject(void* data)
|
---|
448 | {
|
---|
449 | PLUGIN_DEBUG("Asynchronously creating/retaining object ...\n");
|
---|
450 |
|
---|
451 | std::vector<void*> parameters = ((AsyncCallThreadData*) data)->parameters;
|
---|
452 | NPP instance = (NPP) parameters.at(0);
|
---|
453 | NPClass* np_class = (NPClass*) parameters.at(1);
|
---|
454 | NPObject** scriptable_object = (NPObject**) parameters.at(2);
|
---|
455 |
|
---|
456 | *scriptable_object = browser_functions.createobject(instance, np_class);
|
---|
457 | browser_functions.retainobject(*scriptable_object);
|
---|
458 |
|
---|
459 | ((AsyncCallThreadData*) data)->result_ready = true;
|
---|
460 | }
|
---|
461 |
|
---|
462 | bool
|
---|
463 | IcedTeaScriptableJavaPackageObject::is_valid_java_object(NPObject* object_ptr) {
|
---|
464 | return IcedTeaPluginUtilities::getInstanceFromMemberPtr(object_ptr) != NULL;
|
---|
465 | }
|
---|
466 |
|
---|
467 | bool
|
---|
468 | IcedTeaScriptableJavaObject::hasMethod(NPObject *npobj, NPIdentifier name_id)
|
---|
469 | {
|
---|
470 | std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id);
|
---|
471 | IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj;
|
---|
472 |
|
---|
473 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasMethod %s (ival=%d)\n", name.c_str(), browser_functions.intfromidentifier(name_id));
|
---|
474 | bool hasMethod = false;
|
---|
475 |
|
---|
476 | // If object is an array and requested "method" may be a number, check for it first
|
---|
477 | if ( !scriptable_object->is_object_array ||
|
---|
478 | (browser_functions.intfromidentifier(name_id) < 0))
|
---|
479 | {
|
---|
480 |
|
---|
481 | if (!browser_functions.identifierisstring(name_id))
|
---|
482 | return false;
|
---|
483 |
|
---|
484 | JavaResultData* java_result;
|
---|
485 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
486 |
|
---|
487 | java_result = java_request.hasMethod(scriptable_object->class_id, name);
|
---|
488 | hasMethod = java_result->return_identifier != 0;
|
---|
489 | }
|
---|
490 |
|
---|
491 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasMethod returning %d\n", hasMethod);
|
---|
492 | return hasMethod;
|
---|
493 | }
|
---|
494 |
|
---|
495 | bool
|
---|
496 | IcedTeaScriptableJavaObject::invoke(NPObject *npobj, NPIdentifier name_id, const NPVariant *args,
|
---|
497 | uint32_t argCount, NPVariant *result)
|
---|
498 | {
|
---|
499 | std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id);
|
---|
500 |
|
---|
501 | // Extract arg type array
|
---|
502 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::invoke %s. Args follow.\n", name.c_str());
|
---|
503 | for (int i=0; i < argCount; i++)
|
---|
504 | {
|
---|
505 | IcedTeaPluginUtilities::printNPVariant(args[i]);
|
---|
506 | }
|
---|
507 |
|
---|
508 | JavaResultData* java_result;
|
---|
509 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
510 |
|
---|
511 | IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj;
|
---|
512 |
|
---|
513 | std::string instance_id = scriptable_object->instance_id;
|
---|
514 | std::string class_id = scriptable_object->class_id;
|
---|
515 |
|
---|
516 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
517 |
|
---|
518 | // First, load the arguments into the java-side table
|
---|
519 | std::string id = std::string();
|
---|
520 | std::vector<std::string> arg_ids = std::vector<std::string>();
|
---|
521 | for (int i=0; i < argCount; i++) {
|
---|
522 | id.clear();
|
---|
523 | createJavaObjectFromVariant(instance, args[i], &id);
|
---|
524 |
|
---|
525 | if (id == "-1")
|
---|
526 | {
|
---|
527 | PLUGIN_ERROR("Unable to create arguments on Java side\n");
|
---|
528 | return false;
|
---|
529 | }
|
---|
530 |
|
---|
531 | arg_ids.push_back(id);
|
---|
532 | }
|
---|
533 |
|
---|
534 | if (instance_id.length() == 0) // Static
|
---|
535 | {
|
---|
536 | PLUGIN_DEBUG("Calling static method\n");
|
---|
537 | java_result = java_request.callStaticMethod(
|
---|
538 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
539 | scriptable_object->class_id, name, arg_ids);
|
---|
540 | } else
|
---|
541 | {
|
---|
542 | PLUGIN_DEBUG("Calling method normally\n");
|
---|
543 | java_result = java_request.callMethod(
|
---|
544 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
545 | scriptable_object->instance_id, name, arg_ids);
|
---|
546 | }
|
---|
547 |
|
---|
548 | if (java_result->error_occurred)
|
---|
549 | {
|
---|
550 | browser_functions.setexception(npobj, java_result->error_msg->c_str());
|
---|
551 | return false;
|
---|
552 | }
|
---|
553 |
|
---|
554 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::invoke converting and returning.\n");
|
---|
555 | return IcedTeaPluginUtilities::javaResultToNPVariant(instance, java_result->return_string, result);
|
---|
556 | }
|
---|
557 |
|
---|
558 | bool
|
---|
559 | IcedTeaScriptableJavaObject::hasProperty(NPObject *npobj, NPIdentifier name_id)
|
---|
560 | {
|
---|
561 | std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id);
|
---|
562 |
|
---|
563 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasProperty %s (ival=%d)\n", name.c_str(), browser_functions.intfromidentifier(name_id));
|
---|
564 | bool hasProperty = false;
|
---|
565 |
|
---|
566 | IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj;
|
---|
567 | // If it is an array, only length and indexes are valid
|
---|
568 | if (scriptable_object->is_object_array)
|
---|
569 | {
|
---|
570 | if (browser_functions.intfromidentifier(name_id) >= 0 || name == "length")
|
---|
571 | hasProperty = true;
|
---|
572 |
|
---|
573 | } else
|
---|
574 | {
|
---|
575 | if (!browser_functions.identifierisstring(name_id))
|
---|
576 | return false;
|
---|
577 |
|
---|
578 | if (name == "Packages")
|
---|
579 | {
|
---|
580 | hasProperty = true;
|
---|
581 | } else {
|
---|
582 |
|
---|
583 | JavaResultData* java_result;
|
---|
584 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
585 |
|
---|
586 | java_result = java_request.hasField(scriptable_object->class_id, name);
|
---|
587 |
|
---|
588 | hasProperty = java_result->return_identifier != 0;
|
---|
589 | }
|
---|
590 | }
|
---|
591 |
|
---|
592 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasProperty returning %d\n", hasProperty);
|
---|
593 | return hasProperty;
|
---|
594 | }
|
---|
595 |
|
---|
596 | bool
|
---|
597 | IcedTeaScriptableJavaObject::getProperty(NPObject *npobj, NPIdentifier name_id, NPVariant *result)
|
---|
598 | {
|
---|
599 | std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id);
|
---|
600 | bool is_string_id = browser_functions.identifierisstring(name_id);
|
---|
601 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::getProperty %s (ival=%d)\n", name.c_str(), browser_functions.intfromidentifier(name_id));
|
---|
602 |
|
---|
603 | JavaResultData* java_result;
|
---|
604 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
605 |
|
---|
606 | IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj;
|
---|
607 |
|
---|
608 | std::string instance_id = scriptable_object->getInstanceID();
|
---|
609 | std::string class_id = scriptable_object->getClassID();
|
---|
610 | NPP instance = scriptable_object->instance;
|
---|
611 |
|
---|
612 | if (instance_id.length() > 0) // Could be an array or a simple object
|
---|
613 | {
|
---|
614 | // If array and requesting length
|
---|
615 | if ( scriptable_object->is_object_array && name == "length")
|
---|
616 | {
|
---|
617 | java_result = java_request.getArrayLength(instance_id);
|
---|
618 | } else if ( scriptable_object->is_object_array &&
|
---|
619 | browser_functions.intfromidentifier(name_id) >= 0) // else if array and requesting index
|
---|
620 | {
|
---|
621 |
|
---|
622 | java_result = java_request.getArrayLength(instance_id);
|
---|
623 | if (java_result->error_occurred)
|
---|
624 | {
|
---|
625 | PLUGIN_ERROR("ERROR: Couldn't fetch array length\n");
|
---|
626 | return false;
|
---|
627 | }
|
---|
628 |
|
---|
629 | int length = atoi(java_result->return_string->c_str());
|
---|
630 |
|
---|
631 | // Access beyond size?
|
---|
632 | if (browser_functions.intfromidentifier(name_id) >= length)
|
---|
633 | {
|
---|
634 | VOID_TO_NPVARIANT(*result);
|
---|
635 | return true;
|
---|
636 | }
|
---|
637 |
|
---|
638 | std::string index = std::string();
|
---|
639 | IcedTeaPluginUtilities::itoa(browser_functions.intfromidentifier(name_id), &index);
|
---|
640 | java_result = java_request.getSlot(instance_id, index);
|
---|
641 |
|
---|
642 | } else // Everything else
|
---|
643 | {
|
---|
644 | if (!is_string_id) {
|
---|
645 | return false;
|
---|
646 | }
|
---|
647 |
|
---|
648 | if (name == "Packages")
|
---|
649 | {
|
---|
650 | NPObject* pkgObject = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(instance, "");
|
---|
651 | OBJECT_TO_NPVARIANT(pkgObject, *result);
|
---|
652 | return true;
|
---|
653 | }
|
---|
654 |
|
---|
655 | java_result = java_request.getField(
|
---|
656 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
657 | class_id, instance_id, name);
|
---|
658 | }
|
---|
659 | }
|
---|
660 | else
|
---|
661 | {
|
---|
662 | if (!is_string_id) {
|
---|
663 | return false;
|
---|
664 | }
|
---|
665 |
|
---|
666 | java_result = java_request.getStaticField(
|
---|
667 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
668 | class_id, name);
|
---|
669 | }
|
---|
670 |
|
---|
671 | if (java_result->error_occurred)
|
---|
672 | {
|
---|
673 | return false;
|
---|
674 | }
|
---|
675 |
|
---|
676 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::getProperty converting and returning.\n");
|
---|
677 | return IcedTeaPluginUtilities::javaResultToNPVariant(instance, java_result->return_string, result);
|
---|
678 | }
|
---|
679 |
|
---|
680 | bool
|
---|
681 | IcedTeaScriptableJavaObject::setProperty(NPObject *npobj, NPIdentifier name_id, const NPVariant *value)
|
---|
682 | {
|
---|
683 | std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id);
|
---|
684 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::setProperty %s (ival=%d) to:\n", name.c_str(), browser_functions.intfromidentifier(name_id));
|
---|
685 | IcedTeaPluginUtilities::printNPVariant(*value);
|
---|
686 |
|
---|
687 | JavaResultData* java_result;
|
---|
688 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
689 | IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj;
|
---|
690 |
|
---|
691 | std::string instance_id = scriptable_object->getInstanceID();
|
---|
692 | std::string class_id = scriptable_object->getClassID();
|
---|
693 |
|
---|
694 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
695 |
|
---|
696 | if (instance_id.length() > 0) // Could be an array or a simple object
|
---|
697 | {
|
---|
698 | // If array
|
---|
699 | if (scriptable_object->is_object_array && name == "length")
|
---|
700 | {
|
---|
701 | PLUGIN_ERROR("ERROR: Array length is not a modifiable property\n");
|
---|
702 | return false;
|
---|
703 | } else if ( scriptable_object->is_object_array &&
|
---|
704 | browser_functions.intfromidentifier(name_id) >= 0) // else if array and requesting index
|
---|
705 | {
|
---|
706 |
|
---|
707 | java_result = java_request.getArrayLength(instance_id);
|
---|
708 | if (java_result->error_occurred)
|
---|
709 | {
|
---|
710 | PLUGIN_ERROR("ERROR: Couldn't fetch array length\n");
|
---|
711 | return false;
|
---|
712 | }
|
---|
713 |
|
---|
714 | int length = atoi(java_result->return_string->c_str());
|
---|
715 |
|
---|
716 | // Access beyond size?
|
---|
717 | if (browser_functions.intfromidentifier(name_id) >= length)
|
---|
718 | {
|
---|
719 | return true;
|
---|
720 | }
|
---|
721 |
|
---|
722 | std::string index = std::string();
|
---|
723 | IcedTeaPluginUtilities::itoa(browser_functions.intfromidentifier(name_id), &index);
|
---|
724 |
|
---|
725 | std::string value_id = std::string();
|
---|
726 | createJavaObjectFromVariant(instance, *value, &value_id);
|
---|
727 |
|
---|
728 | java_result = java_request.setSlot(instance_id, index, value_id);
|
---|
729 |
|
---|
730 | } else // Everything else
|
---|
731 | {
|
---|
732 | std::string value_id = std::string();
|
---|
733 | createJavaObjectFromVariant(instance, *value, &value_id);
|
---|
734 |
|
---|
735 | java_result = java_request.setField(
|
---|
736 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
737 | class_id, instance_id, name, value_id);
|
---|
738 | }
|
---|
739 | }
|
---|
740 | else
|
---|
741 | {
|
---|
742 | std::string value_id = std::string();
|
---|
743 | createJavaObjectFromVariant(instance, *value, &value_id);
|
---|
744 |
|
---|
745 | java_result = java_request.setStaticField(
|
---|
746 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
747 | class_id, name, value_id);
|
---|
748 | }
|
---|
749 |
|
---|
750 | if (java_result->error_occurred)
|
---|
751 | {
|
---|
752 | return false;
|
---|
753 | }
|
---|
754 |
|
---|
755 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::setProperty returning.\n");
|
---|
756 | return true;
|
---|
757 | }
|
---|
758 |
|
---|
759 | bool
|
---|
760 | IcedTeaScriptableJavaObject::construct(NPObject *npobj, const NPVariant *args, uint32_t argCount,
|
---|
761 | NPVariant *result)
|
---|
762 | {
|
---|
763 | IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj;
|
---|
764 | // Extract arg type array
|
---|
765 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::construct %s. Args follow.\n", scriptable_object->getClassID().c_str());
|
---|
766 | for (int i=0; i < argCount; i++)
|
---|
767 | {
|
---|
768 | IcedTeaPluginUtilities::printNPVariant(args[i]);
|
---|
769 | }
|
---|
770 |
|
---|
771 | JavaResultData* java_result;
|
---|
772 | JavaRequestProcessor java_request = JavaRequestProcessor();
|
---|
773 |
|
---|
774 | NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
|
---|
775 |
|
---|
776 | // First, load the arguments into the java-side table
|
---|
777 | std::string id = std::string();
|
---|
778 | std::vector<std::string> arg_ids = std::vector<std::string>();
|
---|
779 | for (int i=0; i < argCount; i++) {
|
---|
780 | id.clear();
|
---|
781 | createJavaObjectFromVariant(instance, args[i], &id);
|
---|
782 | if (id == "0")
|
---|
783 | {
|
---|
784 | browser_functions.setexception(npobj, "Unable to create argument on Java side");
|
---|
785 | return false;
|
---|
786 | }
|
---|
787 |
|
---|
788 | arg_ids.push_back(id);
|
---|
789 | }
|
---|
790 |
|
---|
791 | java_result = java_request.newObject(
|
---|
792 | IcedTeaPluginUtilities::getSourceFromInstance(instance),
|
---|
793 | scriptable_object->class_id,
|
---|
794 | arg_ids);
|
---|
795 |
|
---|
796 | if (java_result->error_occurred)
|
---|
797 | {
|
---|
798 | browser_functions.setexception(npobj, java_result->error_msg->c_str());
|
---|
799 | return false;
|
---|
800 | }
|
---|
801 |
|
---|
802 | std::string return_obj_instance_id = *java_result->return_string;
|
---|
803 | std::string return_obj_class_id = scriptable_object->class_id;
|
---|
804 |
|
---|
805 | NPObject* obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(
|
---|
806 | IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj),
|
---|
807 | return_obj_class_id, return_obj_instance_id, false);
|
---|
808 |
|
---|
809 | OBJECT_TO_NPVARIANT(obj, *result);
|
---|
810 |
|
---|
811 | PLUGIN_DEBUG("IcedTeaScriptableJavaObject::construct returning.\n");
|
---|
812 | return true;
|
---|
813 | }
|
---|