Move WebCore into Source
[WebKit-https.git] / Source / WebCore / bridge / jni / jsc / JavaClassJSC.cpp
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple 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 "JavaClassJSC.h"
28
29 #if ENABLE(JAVA_BRIDGE)
30
31 #include "JNIUtility.h"
32 #include "JSDOMWindow.h"
33 #include <runtime/Identifier.h>
34 #include <runtime/JSLock.h>
35
36 using namespace JSC::Bindings;
37
38 JavaClass::JavaClass(jobject anInstance)
39 {
40     jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
41
42     if (!aClass) {
43         LOG_ERROR("Unable to call getClass on instance %p", anInstance);
44         m_name = fastStrDup("<Unknown>");
45         return;
46     }
47
48     if (jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;")) {
49         const char* classNameC = getCharactersFromJString(className);
50         m_name = fastStrDup(classNameC);
51         releaseCharactersForJString(className, classNameC);
52     } else
53         m_name = fastStrDup("<Unknown>");
54
55     int i;
56     JNIEnv* env = getJNIEnv();
57
58     // Get the fields
59     if (jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;")) {
60         int numFields = env->GetArrayLength(fields);
61         for (i = 0; i < numFields; i++) {
62             jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
63             JavaField* aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
64             {
65                 JSLock lock(SilenceAssertionsOnly);
66                 m_fields.set(((UString)aField->name()).impl(), aField);
67             }
68             env->DeleteLocalRef(aJField);
69         }
70         env->DeleteLocalRef(fields);
71     }
72
73     // Get the methods
74     if (jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;")) {
75         int numMethods = env->GetArrayLength(methods);
76         for (i = 0; i < numMethods; i++) {
77             jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
78             JavaMethod* aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
79             MethodList* methodList;
80             {
81                 JSLock lock(SilenceAssertionsOnly);
82
83                 methodList = m_methods.get(((UString)aMethod->name()).impl());
84                 if (!methodList) {
85                     methodList = new MethodList();
86                     m_methods.set(((UString)aMethod->name()).impl(), methodList);
87                 }
88             }
89             methodList->append(aMethod);
90             env->DeleteLocalRef(aJMethod);
91         }
92         env->DeleteLocalRef(methods);
93     }
94
95     env->DeleteLocalRef(aClass);
96 }
97
98 JavaClass::~JavaClass()
99 {
100     fastFree(const_cast<char*>(m_name));
101
102     JSLock lock(SilenceAssertionsOnly);
103
104     deleteAllValues(m_fields);
105     m_fields.clear();
106
107     MethodListMap::const_iterator end = m_methods.end();
108     for (MethodListMap::const_iterator it = m_methods.begin(); it != end; ++it) {
109         const MethodList* methodList = it->second;
110         deleteAllValues(*methodList);
111         delete methodList;
112     }
113     m_methods.clear();
114 }
115
116 MethodList JavaClass::methodsNamed(const Identifier& identifier, Instance*) const
117 {
118     MethodList* methodList = m_methods.get(identifier.ustring().impl());
119
120     if (methodList)
121         return *methodList;
122     return MethodList();
123 }
124
125 Field* JavaClass::fieldNamed(const Identifier& identifier, Instance*) const
126 {
127     return m_fields.get(identifier.ustring().impl());
128 }
129
130 bool JavaClass::isNumberClass() const
131 {
132     return (!strcmp(m_name, "java.lang.Byte")
133         || !strcmp(m_name, "java.lang.Short")
134         || !strcmp(m_name, "java.lang.Integer")
135         || !strcmp(m_name, "java.lang.Long")
136         || !strcmp(m_name, "java.lang.Float")
137         || !strcmp(m_name, "java.lang.Double"));
138 }
139
140 bool JavaClass::isBooleanClass() const
141 {
142     return !strcmp(m_name, "java.lang.Boolean");
143 }
144
145 bool JavaClass::isStringClass() const
146 {
147     return !strcmp(m_name, "java.lang.String");
148 }
149
150 #endif // ENABLE(JAVA_BRIDGE)