blob: 16f7a09ccec6206c2f77474aec7ebcde83d88685 [file] [log] [blame]
jat@google.com134be542009-08-03 15:30:11 +00001/*
2 * Copyright 2008 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
15 */
16
17#include "Debug.h"
18
19#include "JavaObject.h"
20#include "Plugin.h"
21#include "NPVariantWrapper.h"
22
23using std::string;
24
25static string IdentifierName(NPIdentifier name) {
26 string iname;
27 if (NPN_IdentifierIsString(name)) {
28 iname = NPN_UTF8FromIdentifier(name);
29 } else {
30 char buf[50];
31 snprintf(buf, sizeof(buf), "%d", NPN_IntFromIdentifier(name));
32 iname = buf;
33 }
34 return iname;
35}
36
37JavaObject* JavaObject::create(ScriptableInstance* plugin, int id) {
38 Debug::log(Debug::Spam) << "Creating Java object id=" << id;
39 NPClass* npClass = GetNPClass<JavaObject>();
40 NPObject* obj = NPN_CreateObject(plugin->getNPP(), npClass);
41 Debug::log(Debug::Spam) << " addr=" << obj << Debug::flush;
42 JavaObject* jObj = static_cast<JavaObject*>(obj);
43 jObj->setObjectId(id);
44 return jObj;
45}
46
47bool JavaObject::isInstance(NPObject* obj) {
48 return obj->_class == GetNPClass<JavaObject>();
49}
50
51JavaObject::~JavaObject() {
52 if (plugin) {
53 plugin->destroyJavaWrapper(this);
54 } else {
55 Debug::log(Debug::Spam) << "Destroying JavaObject " << objectId << " after plugin destroyed"
56 << Debug::flush;
57 }
58}
59
60bool JavaObject::enumeration(NPIdentifier** propReturn, uint32_t* count) {
61 Debug::log(Debug::Debugging) << "JavaObject::enumeration(" << objectId << ")"
62 << Debug::flush;
63 int n = 1;
64 NPIdentifier* props = static_cast<NPIdentifier*>(NPN_MemAlloc(sizeof(NPIdentifier) * n));
65 props[0] = idID;
66 *propReturn = props;
67 *count = n;
68 return true;
69}
70
71bool JavaObject::getProperty(NPIdentifier prop, NPVariant *result) {
72 if (!plugin) {
73 Debug::log(Debug::Spam) << "Ignoring getProperty on " << objectId << " after plugin destroyed"
74 << Debug::flush;
75 VOID_TO_NPVARIANT(*result);
76 return true;
77 }
78 Debug::log(Debug::Spam) << "JavaObject::getProperty(" << objectId << ")" << Debug::flush;
79 if (NPN_IdentifierIsString(prop)) {
80 if (prop == plugin->toStringID) {
81 return plugin->JavaObject_getToStringTearOff(result);
82 }
83 if (prop == idID) {
84 INT32_TO_NPVARIANT(objectId, *result);
85 return true;
86 }
87 // all other properties are numeric dispatchIDs
88 return false;
89 }
90 int dispId = NPN_IntFromIdentifier(prop);
91 // JavaObject_getProperty will retain the return value if needed.
92 return plugin->JavaObject_getProperty(objectId, dispId, result);
93}
94
95bool JavaObject::hasMethod(NPIdentifier method) {
96 if (!plugin) {
97 Debug::log(Debug::Spam) << "Ignoring hasMethod on " << objectId << " after plugin destroyed"
98 << Debug::flush;
99 return true;
100 }
101 Debug::log(Debug::Spam) << "JavaObject::hasMethod(" << objectId << ", method="
102 << IdentifierName(method) << ")" << Debug::flush;
103 return false;
104// return !NPN_IdentifierIsString(method);
105}
106
107bool JavaObject::hasProperty(NPIdentifier prop) {
108 if (!plugin) {
109 Debug::log(Debug::Spam) << "Ignoring hasProperty on " << objectId << " after plugin destroyed"
110 << Debug::flush;
111 return true;
112 }
113 Debug::log(Debug::Spam) << "JavaObject::hasProperty(" << objectId << ", prop="
114 << IdentifierName(prop) << ")" << Debug::flush;
115 return !NPN_IdentifierIsString(prop) || prop == idID || prop == plugin->toStringID;
116}
117
118bool JavaObject::invokeDefault(const NPVariant *args, uint32_t argCount, NPVariant *result) {
119 if (argCount < 2 || !NPVariantProxy::isInt(args[0])
120 || (!NPVariantProxy::isNull(args[1]) && !NPVariantProxy::isObject(args[1]))) {
121 Debug::log(Debug::Error) << "incorrect arguments to invokeDefault" << Debug::flush;
122 return false;
123 }
124 if (!plugin) {
125 Debug::log(Debug::Spam) << "Ignoring invokeDefault on " << objectId << " after plugin destroyed"
126 << Debug::flush;
127 VOID_TO_NPVARIANT(*result);
128 return true;
129 }
130 Debug::log(Debug::Debugging) << "JavaObject::invokeDefault(" << objectId;
131 for (uint32_t i = 0; i < argCount; ++i) {
132 Debug::log(Debug::Debugging) << ", " << NPVariantProxy::toString(args[i]);
133 }
134 Debug::log(Debug::Debugging) << ")" << Debug::flush;
135 int dispId = NPVariantProxy::getAsInt(args[0]);
136 int objId = objectId;
137 if (!NPVariantProxy::isNull(args[1])) {
138 NPObject* thisObj = NPVariantProxy::getAsObject(args[1]);
139 if (isInstance(thisObj)) {
140 JavaObject* thisJavaObj = static_cast<JavaObject*>(thisObj);
141 objId = thisJavaObj->objectId;
142 }
143 }
144 // JavaObject_invoke will retain the return value if needed.
145 return plugin->JavaObject_invoke(objId, dispId, args + 2, argCount - 2, result);
146}
147
148bool JavaObject::invoke(NPIdentifier name, const NPVariant *args,
149 uint32_t argCount, NPVariant *result) {
150 VOID_TO_NPVARIANT(*result);
151 if (!plugin) {
152 Debug::log(Debug::Spam) << "Ignoring invoke on " << objectId << " after plugin destroyed"
153 << Debug::flush;
154 return true;
155 }
156 string methodName(NPN_UTF8FromIdentifier(name));
157 Debug::log(Debug::Spam) << "JavaObject::invoke(" << objectId << ", method="
158 << methodName << ")" << Debug::flush;
159 if (name == plugin->toStringID) {
160 // -1 is magic and means a raw toString().
161 return plugin->JavaObject_invoke(objectId, -1, args, argCount, result);
162 }
163 // toString is the only method we support invoking directly on a Java wrapper
164 return false;
165}
166
167bool JavaObject::setProperty(NPIdentifier prop, const NPVariant *value) {
168 if (!plugin) {
169 Debug::log(Debug::Spam) << "Ignoring setProperty on " << objectId << " after plugin destroyed"
170 << Debug::flush;
171 return true;
172 }
173 Debug::log(Debug::Spam) << "JavaObject::setProperty(" << objectId << ", val="
174 << NPVariantProxy::toString(*value) << ")" << Debug::flush;
175 if (NPN_IdentifierIsString(prop)) {
176 // any non-numeric properties are read-only
177 return false;
178 }
179 int dispId = NPN_IntFromIdentifier(prop);
180 return plugin->JavaObject_setProperty(objectId, dispId, value);
181}