KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lobobrowser > js > JavaObjectWrapper


1 /*
2     GNU LESSER GENERAL PUBLIC LICENSE
3     Copyright (C) 2006 The Lobo Project
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19     Contact info: xamjadmin@users.sourceforge.net
20 */

21 package org.lobobrowser.js;
22
23 import org.mozilla.javascript.*;
24 import java.lang.reflect.*;
25 import java.util.logging.Level JavaDoc;
26 import java.util.logging.Logger JavaDoc;
27
28 public class JavaObjectWrapper extends ScriptableObject {
29     private static final Logger JavaDoc logger = Logger.getLogger(JavaObjectWrapper.class.getName());
30     private static final boolean loggableInfo = logger.isLoggable(Level.INFO);
31     private final Object JavaDoc delegate;
32     private final JavaClassWrapper classWrapper;
33     
34     public JavaObjectWrapper(JavaClassWrapper classWrapper) throws InstantiationException JavaDoc, IllegalAccessException JavaDoc {
35         this.classWrapper = classWrapper;
36         // Retaining a strong reference, but note
37
// that the object wrapper map uses weak keys
38
// and weak values.
39
Object JavaDoc delegate = this.classWrapper.newInstance();
40         this.delegate = delegate;
41     }
42
43     public JavaObjectWrapper(JavaClassWrapper classWrapper, Object JavaDoc delegate) {
44         if(delegate == null) {
45             throw new IllegalArgumentException JavaDoc("Argument delegate cannot be null.");
46         }
47         this.classWrapper = classWrapper;
48         // Retaining a strong reference, but note
49
// that the object wrapper map uses weak keys
50
// and weak values.
51
this.delegate = delegate;
52     }
53     
54     /**
55      * Returns the Java object.
56      * @return An object or <code>null</code> if garbage collected.
57      */

58     public Object JavaDoc getJavaObject() {
59         // Cannot retain delegate with a strong reference.
60
return this.delegate;
61     }
62     
63     public String JavaDoc getClassName() {
64         return this.classWrapper.getClassName();
65     }
66     
67     public Object JavaDoc get(int index, Scriptable start) {
68         PropertyInfo pinfo = this.classWrapper.getIntegerIndexer();
69         if(pinfo == null) {
70             return super.get(index, start);
71         }
72         else {
73             try {
74                 Method getter = pinfo.getGetter();
75                 if(getter == null) {
76                     throw new EvaluatorException("Indexer is write-only");
77                 }
78                 // Cannot retain delegate with a strong reference.
79
Object JavaDoc javaObject = this.getJavaObject();
80                 if(javaObject == null) {
81                     throw new IllegalStateException JavaDoc("Java object (class=" + this.classWrapper + ") is null.");
82                 }
83                 Object JavaDoc raw = getter.invoke(javaObject, new Object JavaDoc[] { new Integer JavaDoc(index) });
84                 return JavaScript.getInstance().getJavascriptObject(raw, this.getParentScope());
85             } catch(Exception JavaDoc err) {
86                 throw new WrappedException(err);
87             }
88         }
89     }
90
91     public Object JavaDoc get(String JavaDoc name, Scriptable start) {
92         PropertyInfo pinfo = this.classWrapper.getProperty(name);
93         if(pinfo != null) {
94             Method getter = pinfo.getGetter();
95             if(getter == null) {
96                 throw new EvaluatorException("Property '" + name + "' is not readable");
97             }
98             try {
99                 // Cannot retain delegate with a strong reference.
100
Object JavaDoc javaObject = this.getJavaObject();
101                 if(javaObject == null) {
102                     throw new IllegalStateException JavaDoc("Java object (class=" + this.classWrapper + ") is null.");
103                 }
104                 Object JavaDoc val = getter.invoke(javaObject, (Object JavaDoc[]) null);
105                 return JavaScript.getInstance().getJavascriptObject(val, start.getParentScope());
106             } catch(Exception JavaDoc err) {
107                 throw new WrappedException(err);
108             }
109         }
110         else {
111             Function f = this.classWrapper.getFunction(name);
112             if(f != null) {
113                 return f;
114             }
115             else {
116                 PropertyInfo ni = this.classWrapper.getNameIndexer();
117                 if(ni != null) {
118                     Method getter = ni.getGetter();
119                     if(getter != null) {
120                         // Cannot retain delegate with a strong reference.
121
Object JavaDoc javaObject = this.getJavaObject();
122                         if(javaObject == null) {
123                             throw new IllegalStateException JavaDoc("Java object (class=" + this.classWrapper + ") is null.");
124                         }
125                         try {
126                             Object JavaDoc val = getter.invoke(javaObject, new Object JavaDoc[] { name });
127                             if(val == null) {
128                                 // There might not be an indexer setter.
129
return super.get(name, start);
130                             }
131                             else {
132                                 return JavaScript.getInstance().getJavascriptObject(val, start.getParentScope());
133                             }
134                         } catch(Exception JavaDoc err) {
135                             throw new WrappedException(err);
136                         }
137                     }
138                     else {
139                         return super.get(name, start);
140                     }
141                 }
142                 else {
143                     return super.get(name, start);
144                 }
145             }
146         }
147     }
148
149     public void put(int index, Scriptable start, Object JavaDoc value) {
150         PropertyInfo pinfo = this.classWrapper.getIntegerIndexer();
151         if(pinfo == null) {
152             super.put(index, start, value);
153         }
154         else {
155             try {
156                 Method setter = pinfo.getSetter();
157                 if(setter == null) {
158                     throw new EvaluatorException("Indexer is read-only");
159                 }
160                 Object JavaDoc actualValue;
161                 actualValue = JavaScript.getInstance().getJavaObject(value, pinfo.getPropertyType());
162                 setter.invoke(this.getJavaObject(), new Object JavaDoc[] { new Integer JavaDoc(index), actualValue });
163             } catch(Exception JavaDoc err) {
164                 throw new WrappedException(err);
165             }
166         }
167     }
168
169     public void put(String JavaDoc name, Scriptable start, Object JavaDoc value) {
170         PropertyInfo pinfo = this.classWrapper.getProperty(name);
171         if(pinfo != null) {
172             Method setter = pinfo.getSetter();
173             if(setter == null) {
174                 throw new EvaluatorException("Property '" + name + "' is not settable in " + this.classWrapper.getClassName() + ".");
175             }
176             try {
177                 Object JavaDoc actualValue;
178                 actualValue = JavaScript.getInstance().getJavaObject(value, pinfo.getPropertyType());
179                 setter.invoke(this.getJavaObject(), new Object JavaDoc[] { actualValue });
180             } catch(IllegalArgumentException JavaDoc iae) {
181                 Exception JavaDoc newException = new IllegalArgumentException JavaDoc("Property named '" + name + "' could not be set with value " + value + ".", iae);
182                 throw new WrappedException(newException);
183             } catch(Exception JavaDoc err) {
184                 throw new WrappedException(err);
185             }
186         }
187         else {
188             PropertyInfo ni = this.classWrapper.getNameIndexer();
189             if(ni != null) {
190                 Method setter = ni.getSetter();
191                 if(setter != null) {
192                     try {
193                         Object JavaDoc actualValue;
194                         actualValue = JavaScript.getInstance().getJavaObject(value, ni.getPropertyType());
195                         setter.invoke(this.getJavaObject(), new Object JavaDoc[] { name, actualValue });
196                     } catch(Exception JavaDoc err) {
197                         throw new WrappedException(err);
198                     }
199                 }
200                 else {
201                     super.put(name, start, value);
202                 }
203             }
204             else {
205                 super.put(name, start, value);
206             }
207         }
208     }
209     
210     public static Function getConstructor(String JavaDoc className, JavaClassWrapper classWrapper, Scriptable scope) {
211         return new JavaConstructorObject(className, classWrapper);
212     }
213
214     public static Function getConstructor(String JavaDoc className, JavaClassWrapper classWrapper, Scriptable scope, JavaInstantiator instantiator) {
215         return new JavaConstructorObject(className, classWrapper, instantiator);
216     }
217
218     public java.lang.Object JavaDoc getDefaultValue(java.lang.Class JavaDoc hint) {
219         if(loggableInfo) {
220             logger.info("getDefaultValue(): hint=" + hint + ",this=" + this.getJavaObject());
221         }
222         if(hint == null || String JavaDoc.class.equals(hint)) {
223             Object JavaDoc javaObject = this.getJavaObject();
224             if(javaObject == null) {
225                 throw new IllegalStateException JavaDoc("Java object (class=" + this.classWrapper + ") is null.");
226             }
227             return javaObject.toString();
228         }
229         else if(Number JavaDoc.class.isAssignableFrom(hint)) {
230             Object JavaDoc javaObject = this.getJavaObject();
231             if(javaObject instanceof Number JavaDoc) {
232                 return javaObject;
233             }
234             else if(javaObject instanceof String JavaDoc) {
235                 return Double.valueOf((String JavaDoc) javaObject);
236             }
237             else {
238                 return super.getDefaultValue(hint);
239             }
240         }
241         else {
242             return super.getDefaultValue(hint);
243         }
244     }
245
246     public String JavaDoc toString() {
247         Object JavaDoc javaObject = this.getJavaObject();
248         String JavaDoc type = javaObject == null ? "<null>" : javaObject.getClass().getName();
249         return "JavaObjectWrapper[object=" + this.getJavaObject() + ",type=" + type + "]";
250     }
251 }
252
Popular Tags