1 /*
2 * Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "config.h"
27 #include "jni_class.h"
28
29 #if ENABLE(MAC_JAVA_BRIDGE)
30
31 #include "JSDOMWindow.h"
32 #include <runtime/Identifier.h>
33 #include <runtime/JSLock.h>
34 #include "jni_utility.h"
35 #include "jni_runtime.h"
36
37 using namespace JSC::Bindings;
38
JavaClass(jobject anInstance)39 JavaClass::JavaClass(jobject anInstance)
40 {
41 jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
42
43 if (!aClass) {
44 fprintf(stderr, "%s: unable to call getClass on instance %p\n", __PRETTY_FUNCTION__, anInstance);
45 return;
46 }
47
48 jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;");
49 const char *classNameC = getCharactersFromJString(className);
50 _name = strdup(classNameC);
51 releaseCharactersForJString(className, classNameC);
52
53 int i;
54 JNIEnv *env = getJNIEnv();
55
56 // Get the fields
57 jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;");
58 int numFields = env->GetArrayLength(fields);
59 for (i = 0; i < numFields; i++) {
60 jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
61 JavaField *aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
62 {
63 JSLock lock(SilenceAssertionsOnly);
64 _fields.set(aField->name(), aField);
65 }
66 env->DeleteLocalRef(aJField);
67 }
68
69 // Get the methods
70 jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;");
71 int numMethods = env->GetArrayLength(methods);
72 for (i = 0; i < numMethods; i++) {
73 jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
74 JavaMethod *aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
75 MethodList* methodList;
76 {
77 JSLock lock(SilenceAssertionsOnly);
78
79 methodList = _methods.get(aMethod->name());
80 if (!methodList) {
81 methodList = new MethodList();
82 _methods.set(aMethod->name(), methodList);
83 }
84 }
85 methodList->append(aMethod);
86 env->DeleteLocalRef(aJMethod);
87 }
88 #ifdef ANDROID_FIX
89 env->DeleteLocalRef(fields);
90 env->DeleteLocalRef(methods);
91 env->DeleteLocalRef(aClass);
92 #endif
93 }
94
~JavaClass()95 JavaClass::~JavaClass() {
96 free((void *)_name);
97
98 JSLock lock(SilenceAssertionsOnly);
99
100 deleteAllValues(_fields);
101 _fields.clear();
102
103 MethodListMap::const_iterator end = _methods.end();
104 for (MethodListMap::const_iterator it = _methods.begin(); it != end; ++it) {
105 const MethodList* methodList = it->second;
106 deleteAllValues(*methodList);
107 delete methodList;
108 }
109 _methods.clear();
110 }
111
methodsNamed(const Identifier & identifier,Instance *) const112 MethodList JavaClass::methodsNamed(const Identifier& identifier, Instance*) const
113 {
114 MethodList *methodList = _methods.get(identifier.ustring().rep());
115
116 if (methodList)
117 return *methodList;
118 return MethodList();
119 }
120
fieldNamed(const Identifier & identifier,Instance *) const121 Field *JavaClass::fieldNamed(const Identifier& identifier, Instance*) const
122 {
123 return _fields.get(identifier.ustring().rep());
124 }
125
isNumberClass() const126 bool JavaClass::isNumberClass() const
127 {
128 return ((strcmp(_name, "java.lang.Byte") == 0 ||
129 strcmp(_name, "java.lang.Short") == 0 ||
130 strcmp(_name, "java.lang.Integer") == 0 ||
131 strcmp(_name, "java.lang.Long") == 0 ||
132 strcmp(_name, "java.lang.Float") == 0 ||
133 strcmp(_name, "java.lang.Double") == 0) );
134 }
135
isBooleanClass() const136 bool JavaClass::isBooleanClass() const
137 {
138 return strcmp(_name, "java.lang.Boolean") == 0;
139 }
140
isStringClass() const141 bool JavaClass::isStringClass() const
142 {
143 return strcmp(_name, "java.lang.String") == 0;
144 }
145
146 #endif // ENABLE(MAC_JAVA_BRIDGE)
147