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

Last change on this file since 384 was 348, checked in by dmik, 13 years ago

vendor: Add icedtea-web v1.1.2 to current.

File size: 30.7 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 printf ("** Unimplemented: IcedTeaScriptablePluginObject::deAllocate %p\n", npobj);
53}
54
55void
56IcedTeaScriptablePluginObject::invalidate(NPObject *npobj)
57{
58 printf ("** Unimplemented: IcedTeaScriptablePluginObject::invalidate %p\n", npobj);
59}
60
61bool
62IcedTeaScriptablePluginObject::hasMethod(NPObject *npobj, NPIdentifier name)
63{
64 printf ("** Unimplemented: IcedTeaScriptablePluginObject::hasMethod %p\n", npobj);
65 return false;
66}
67
68bool
69IcedTeaScriptablePluginObject::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
76bool
77IcedTeaScriptablePluginObject::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
84bool
85IcedTeaScriptablePluginObject::hasProperty(NPObject *npobj, NPIdentifier name)
86{
87 printf ("** Unimplemented: IcedTeaScriptablePluginObject::hasProperty %p\n", npobj);
88 return false;
89}
90
91bool
92IcedTeaScriptablePluginObject::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
106bool
107IcedTeaScriptablePluginObject::setProperty(NPObject *npobj, NPIdentifier name, const NPVariant *value)
108{
109 printf ("** Unimplemented: IcedTeaScriptablePluginObject::setProperty %p\n", npobj);
110 return false;
111}
112
113bool
114IcedTeaScriptablePluginObject::removeProperty(NPObject *npobj, NPIdentifier name)
115{
116 printf ("** Unimplemented: IcedTeaScriptablePluginObject::removeProperty %p\n", npobj);
117 return false;
118}
119
120bool
121IcedTeaScriptablePluginObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
122{
123 printf ("** 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 printf ("** 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
142NPObject*
143IcedTeaScriptablePluginObject::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
173IcedTeaScriptableJavaPackageObject::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
180IcedTeaScriptableJavaPackageObject::~IcedTeaScriptableJavaPackageObject()
181{
182 delete this->package_name;
183}
184
185void
186IcedTeaScriptableJavaPackageObject::setPackageName(const NPUTF8* name)
187{
188 this->package_name->append(name);
189}
190
191std::string
192IcedTeaScriptableJavaPackageObject::getPackageName()
193{
194 return this->package_name->c_str();
195}
196
197void
198IcedTeaScriptableJavaPackageObject::deAllocate(NPObject *npobj)
199{
200 browser_functions.releaseobject(npobj);
201}
202
203void
204IcedTeaScriptableJavaPackageObject::invalidate(NPObject *npobj)
205{
206 // nothing to do for these
207}
208
209bool
210IcedTeaScriptableJavaPackageObject::hasMethod(NPObject *npobj, NPIdentifier name)
211{
212 // Silly caller. Methods are for objects!
213 return false;
214}
215
216bool
217IcedTeaScriptableJavaPackageObject::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
224bool
225IcedTeaScriptableJavaPackageObject::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
232bool
233IcedTeaScriptableJavaPackageObject::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
277bool
278IcedTeaScriptableJavaPackageObject::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
324bool
325IcedTeaScriptableJavaPackageObject::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
331bool
332IcedTeaScriptableJavaPackageObject::removeProperty(NPObject *npobj, NPIdentifier name)
333{
334 printf ("** Unimplemented: IcedTeaScriptableJavaPackageObject::removeProperty %p\n", npobj);
335 return false;
336}
337
338bool
339IcedTeaScriptableJavaPackageObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
340{
341 printf ("** Unimplemented: IcedTeaScriptableJavaPackageObject::enumerate %p\n", npobj);
342 return false;
343}
344
345bool
346IcedTeaScriptableJavaPackageObject::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
353NPObject*
354allocate_scriptable_java_object(NPP npp, NPClass *aClass)
355{
356 PLUGIN_DEBUG("Allocating new scriptable Java object\n");
357 return new IcedTeaScriptableJavaObject(npp);
358}
359
360NPObject*
361IcedTeaScriptableJavaPackageObject::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.) */
437void
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
453bool
454IcedTeaScriptableJavaPackageObject::is_valid_java_object(NPObject* object_ptr) {
455 return IcedTeaPluginUtilities::getInstanceFromMemberPtr(object_ptr) != NULL;
456}
457
458IcedTeaScriptableJavaObject::IcedTeaScriptableJavaObject(NPP instance)
459{
460 this->instance = instance;
461 this->class_id = new std::string();
462 this->instance_id = new std::string();
463}
464
465IcedTeaScriptableJavaObject::~IcedTeaScriptableJavaObject()
466{
467 delete this->class_id;
468 delete this->instance_id;
469}
470
471void
472IcedTeaScriptableJavaObject::setClassIdentifier(std::string class_id)
473{
474 this->class_id->append(class_id);
475}
476
477void
478IcedTeaScriptableJavaObject::setInstanceIdentifier(std::string instance_id)
479{
480 this->instance_id->append(instance_id);
481}
482
483void
484IcedTeaScriptableJavaObject::setIsArray(bool isArray)
485{
486 this->isObjectArray = isArray;
487}
488
489void
490IcedTeaScriptableJavaObject::deAllocate(NPObject *npobj)
491{
492 browser_functions.releaseobject(npobj);
493}
494
495void
496IcedTeaScriptableJavaObject::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
508bool
509IcedTeaScriptableJavaObject::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
536bool
537IcedTeaScriptableJavaObject::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
605bool
606IcedTeaScriptableJavaObject::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
613bool
614IcedTeaScriptableJavaObject::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
653bool
654IcedTeaScriptableJavaObject::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
735bool
736IcedTeaScriptableJavaObject::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
816bool
817IcedTeaScriptableJavaObject::removeProperty(NPObject *npobj, NPIdentifier name)
818{
819 printf ("** Unimplemented: IcedTeaScriptableJavaObject::removeProperty %p\n", npobj);
820 return false;
821}
822
823bool
824IcedTeaScriptableJavaObject::enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
825{
826 printf ("** Unimplemented: IcedTeaScriptableJavaObject::enumerate %p\n", npobj);
827 return false;
828}
829
830bool
831IcedTeaScriptableJavaObject::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}
Note: See TracBrowser for help on using the repository browser.