source: trunk/icedtea-web/plugin/icedteanp/IcedTeaScriptablePluginObject.cc

Last change on this file was 429, checked in by dmik, 11 years ago

icedtea-web: Merge version 1.5.1 from vendor to trunk.

File size: 28.2 KB
Line 
1/* IcedTeaScriptablePluginObject.cc
2
3 Copyright (C) 2009, 2010 Red Hat
4
5This file is part of IcedTea.
6
7IcedTea is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12IcedTea is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with IcedTea; see the file COPYING. If not, write to the
19Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301 USA.
21
22Linking this library statically or dynamically with other modules is
23making a combined work based on this library. Thus, the terms and
24conditions of the GNU General Public License cover the whole
25combination.
26
27As a special exception, the copyright holders of this library give you
28permission to link this library with independent modules to produce an
29executable, regardless of the license terms of these independent
30modules, and to copy and distribute the resulting executable under
31terms of your choice, provided that you also meet, for each linked
32independent module, the terms and conditions of the license of that
33module. An independent module is a module which is not derived from
34or based on this library. If you modify this library, you may extend
35this exception to your version of the library, but you are not
36obligated to do so. If you do not wish to do so, delete this
37exception statement from your version. */
38
39#include <typeinfo>
40
41#include "IcedTeaScriptablePluginObject.h"
42
43IcedTeaScriptablePluginObject::IcedTeaScriptablePluginObject(NPP instance)
44{
45 this->instance = instance;
46 IcedTeaPluginUtilities::storeInstanceID(this, instance);
47}
48
49void
50IcedTeaScriptablePluginObject::deAllocate(NPObject *npobj)
51{
52 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::deAllocate %p\n", npobj);
53}
54
55void
56IcedTeaScriptablePluginObject::invalidate(NPObject *npobj)
57{
58 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::invalidate %p\n", npobj);
59}
60
61bool
62IcedTeaScriptablePluginObject::hasMethod(NPObject *npobj, NPIdentifier name_id)
63{
64 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::hasMethod %p\n", npobj);
65 return false;
66}
67
68bool
69IcedTeaScriptablePluginObject::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
76bool
77IcedTeaScriptablePluginObject::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
84bool
85IcedTeaScriptablePluginObject::hasProperty(NPObject *npobj, NPIdentifier name_id)
86{
87 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::hasProperty %p\n", npobj);
88 return false;
89}
90
91bool
92IcedTeaScriptablePluginObject::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
106bool
107IcedTeaScriptablePluginObject::setProperty(NPObject *npobj, NPIdentifier name_id, const NPVariant *value)
108{
109 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::setProperty %p\n", npobj);
110 return false;
111}
112
113bool
114IcedTeaScriptablePluginObject::removeProperty(NPObject *npobj, NPIdentifier name_id)
115{
116 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::removeProperty %p\n", npobj);
117 return false;
118}
119
120bool
121IcedTeaScriptablePluginObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
122{
123 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptablePluginObject::enumerate %p\n", npobj);
124 return false;
125}
126
127bool
128IcedTeaScriptablePluginObject::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
135NPObject*
136allocate_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
142static NPClass
143scriptable_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
161NPObject*
162IcedTeaScriptableJavaPackageObject::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
177IcedTeaScriptableJavaPackageObject::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
184IcedTeaScriptableJavaPackageObject::~IcedTeaScriptableJavaPackageObject()
185{
186 delete this->package_name;
187}
188
189void
190IcedTeaScriptableJavaPackageObject::setPackageName(const NPUTF8* name)
191{
192 this->package_name->assign(name);
193}
194
195std::string
196IcedTeaScriptableJavaPackageObject::getPackageName()
197{
198 return *this->package_name;
199}
200
201void
202IcedTeaScriptableJavaPackageObject::deAllocate(NPObject *npobj)
203{
204 delete (IcedTeaScriptableJavaPackageObject*)npobj;
205}
206
207void
208IcedTeaScriptableJavaPackageObject::invalidate(NPObject *npobj)
209{
210 // nothing to do for these
211}
212
213bool
214IcedTeaScriptableJavaPackageObject::hasMethod(NPObject *npobj, NPIdentifier name_id)
215{
216 // Silly caller. Methods are for objects!
217 return false;
218}
219
220bool
221IcedTeaScriptableJavaPackageObject::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
228bool
229IcedTeaScriptableJavaPackageObject::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
236bool
237IcedTeaScriptableJavaPackageObject::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
282bool
283IcedTeaScriptableJavaPackageObject::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
331bool
332IcedTeaScriptableJavaPackageObject::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
338bool
339IcedTeaScriptableJavaPackageObject::removeProperty(NPObject *npobj, NPIdentifier name_id)
340{
341 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::removeProperty %p\n", npobj);
342 return false;
343}
344
345bool
346IcedTeaScriptableJavaPackageObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
347{
348 PLUGIN_ERROR ("** Unimplemented: IcedTeaScriptableJavaPackageObject::enumerate %p\n", npobj);
349 return false;
350}
351
352bool
353IcedTeaScriptableJavaPackageObject::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
360NPObject*
361allocate_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
368static NPClass
369scriptable_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
387NPObject*
388IcedTeaScriptableJavaObject::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.) */
446void
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
462bool
463IcedTeaScriptableJavaPackageObject::is_valid_java_object(NPObject* object_ptr) {
464 return IcedTeaPluginUtilities::getInstanceFromMemberPtr(object_ptr) != NULL;
465}
466
467bool
468IcedTeaScriptableJavaObject::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
495bool
496IcedTeaScriptableJavaObject::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
558bool
559IcedTeaScriptableJavaObject::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
596bool
597IcedTeaScriptableJavaObject::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
680bool
681IcedTeaScriptableJavaObject::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
759bool
760IcedTeaScriptableJavaObject::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}
Note: See TracBrowser for help on using the repository browser.