KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > dev > shell > ie > JsValueIE6


1 /*
2  * Copyright 2007 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 package com.google.gwt.dev.shell.ie;
17
18 import com.google.gwt.dev.shell.CompilingClassLoader;
19 import com.google.gwt.dev.shell.JsValue;
20 import com.google.gwt.dev.shell.LowLevel;
21
22 import org.eclipse.swt.internal.ole.win32.COM;
23 import org.eclipse.swt.internal.ole.win32.DISPPARAMS;
24 import org.eclipse.swt.internal.ole.win32.EXCEPINFO;
25 import org.eclipse.swt.internal.ole.win32.GUID;
26 import org.eclipse.swt.internal.ole.win32.IDispatch;
27 import org.eclipse.swt.internal.ole.win32.IUnknown;
28 import org.eclipse.swt.internal.win32.OS;
29 import org.eclipse.swt.ole.win32.OleAutomation;
30 import org.eclipse.swt.ole.win32.Variant;
31
32 /**
33  * Represents an IE JavaScript value.
34  */

35 public class JsValueIE6 extends JsValue {
36
37   private static class JsCleanupIE6 implements JsCleanup {
38     private Variant variant;
39
40     public JsCleanupIE6(Variant variant) {
41       this.variant = variant;
42     }
43
44     public void doCleanup() {
45       variant.dispose();
46     }
47   }
48
49   private static Variant maybeCopyVariant(Variant variant) {
50     if (variant == null) {
51       return new Variant();
52     }
53     switch (variant.getType()) {
54       case COM.VT_DISPATCH: {
55         IDispatch dispatch = variant.getDispatch();
56         dispatch.AddRef();
57         return new Variant(dispatch);
58       }
59       case COM.VT_UNKNOWN: {
60         IUnknown unknown = variant.getUnknown();
61         unknown.AddRef();
62         return new Variant(unknown);
63       }
64     }
65     return variant;
66   }
67
68   // a null variant means the JsValue is undefined (void)
69
private Variant variant;
70
71   /**
72    * Create a null JsValue.
73    */

74   public JsValueIE6() {
75     this.variant = null;
76   }
77
78   /**
79    * Create a JsValue given a variant.
80    *
81    * @param variant JS value
82    */

83   public JsValueIE6(Variant variant) {
84     this.variant = maybeCopyVariant(variant);
85   }
86
87   /*
88    * (non-Javadoc)
89    *
90    * @see com.google.gwt.dev.shell.JsValue#getBoolean()
91    */

92   public boolean getBoolean() {
93     return variant.getBoolean();
94   }
95
96   /*
97    * (non-Javadoc)
98    *
99    * @see com.google.gwt.dev.shell.JsValue#getInt()
100    */

101   public int getInt() {
102     return variant.getInt();
103   }
104
105   /*
106    * (non-Javadoc)
107    *
108    * @see com.google.gwt.dev.shell.JsValue#getNumber()
109    */

110   public double getNumber() {
111     return variant.getDouble();
112   }
113
114   /*
115    * (non-Javadoc)
116    *
117    * @see com.google.gwt.dev.shell.JsValue#getString()
118    */

119   public String JavaDoc getString() {
120     return variant.getString();
121   }
122
123   /*
124    * (non-Javadoc)
125    *
126    * @see com.google.gwt.dev.shell.JsValue#getTypeString()
127    */

128   public String JavaDoc getTypeString() {
129     switch (variant.getType()) {
130       case COM.VT_BOOL:
131         return "boolean";
132       case COM.VT_I1:
133       case COM.VT_I2:
134       case COM.VT_I4:
135       case COM.VT_I8:
136       case COM.VT_UI1:
137       case COM.VT_UI2:
138       case COM.VT_UI4:
139       case COM.VT_R4:
140       case COM.VT_R8:
141         return "number";
142       case COM.VT_BSTR:
143         return "string";
144       case COM.VT_EMPTY:
145         return "undefined";
146       case COM.VT_NULL:
147         return "null";
148       case COM.VT_DISPATCH:
149         return isWrappedJavaObject() ? "Java Object" : "JavaScript object";
150       default:
151         return "unexpected Variant type";
152     }
153   }
154
155   /**
156    * Return the underlying Variant object. PLATFORM-SPECIFIC.
157    */

158   public Variant getVariant() {
159     return maybeCopyVariant(variant);
160   }
161
162   /*
163    * (non-Javadoc)
164    *
165    * @see com.google.gwt.dev.shell.JsValue#getWrappedJavaObject()
166    */

167   public Object JavaDoc getWrappedJavaObject() {
168     return tryToUnwrapWrappedJavaObject();
169   }
170
171   /*
172    * (non-Javadoc)
173    *
174    * @see com.google.gwt.dev.shell.JsValue#isBoolean()
175    */

176   public boolean isBoolean() {
177     return variant != null && variant.getType() == COM.VT_BOOL;
178   }
179
180   /*
181    * (non-Javadoc)
182    *
183    * @see com.google.gwt.dev.shell.JsValue#isInt()
184    */

185   public boolean isInt() {
186     if (variant == null) {
187       return false;
188     }
189     switch (variant.getType()) {
190       case COM.VT_I1:
191       case COM.VT_I2:
192       case COM.VT_I4:
193       case COM.VT_UI1:
194       case COM.VT_UI2:
195         // note that VT_UI4 is excluded since it may not fit in an int
196
return true;
197       default:
198         return false;
199     }
200   }
201
202   /*
203    * (non-Javadoc)
204    *
205    * @see com.google.gwt.dev.shell.JsValue#isJavaScriptObject()
206    */

207   public boolean isJavaScriptObject() {
208     if (variant == null) {
209       return false;
210     }
211     if (variant.getType() != COM.VT_DISPATCH) {
212       return false;
213     }
214     return tryToUnwrapWrappedJavaObject() == null;
215   }
216
217   /*
218    * (non-Javadoc)
219    *
220    * @see com.google.gwt.dev.shell.JsValue#isNull()
221    */

222   public boolean isNull() {
223     return variant != null && variant.getType() == COM.VT_NULL;
224   }
225
226   /*
227    * (non-Javadoc)
228    *
229    * @see com.google.gwt.dev.shell.JsValue#isNumber()
230    */

231   public boolean isNumber() {
232     if (variant == null) {
233       return false;
234     }
235     switch (variant.getType()) {
236       case COM.VT_I1:
237       case COM.VT_I2:
238       case COM.VT_I4:
239       case COM.VT_I8:
240       case COM.VT_UI1:
241       case COM.VT_UI2:
242       case COM.VT_UI4:
243       case COM.VT_R4:
244       case COM.VT_R8:
245         return true;
246       default:
247         return false;
248     }
249   }
250
251   /*
252    * (non-Javadoc)
253    *
254    * @see com.google.gwt.dev.shell.JsValue#isString()
255    */

256   public boolean isString() {
257     if (variant == null) {
258       return false;
259     }
260     if (variant.getType() == COM.VT_BSTR) {
261       return true;
262     }
263     // see if the variant is a wrapper object
264
if (variant.getType() != COM.VT_DISPATCH) {
265       return false;
266     }
267     OleAutomation auto = null;
268     Variant result = null;
269     try {
270       auto = new OleAutomation(variant.getDispatch());
271       // see if it has a valueOf method
272
int[] ids = auto.getIDsOfNames(new String JavaDoc[] {"valueOf"});
273       if (ids == null) {
274         return false;
275       }
276       result = auto.invoke(ids[0]);
277       /*
278        * If the return type of the valueOf method is string, we assume it is a
279        * String wrapper object.
280        */

281       return result.getType() == COM.VT_BSTR;
282     } finally {
283       if (auto != null) {
284         auto.dispose();
285       }
286       if (result != null) {
287         result.dispose();
288       }
289     }
290   }
291
292   /*
293    * (non-Javadoc)
294    *
295    * @see com.google.gwt.dev.shell.JsValue#isUndefined()
296    */

297   public boolean isUndefined() {
298     return variant == null || variant.getType() == COM.VT_EMPTY;
299   }
300
301   /*
302    * (non-Javadoc)
303    *
304    * @see com.google.gwt.dev.shell.JsValue#isWrappedJavaObject()
305    */

306   public boolean isWrappedJavaObject() {
307     if (variant == null) {
308       return false;
309     }
310     if (variant.getType() != COM.VT_DISPATCH) {
311       return false;
312     }
313     return tryToUnwrapWrappedJavaObject() != null;
314   }
315
316   /*
317    * (non-Javadoc)
318    *
319    * @see com.google.gwt.dev.shell.JsValue#setBoolean(boolean)
320    */

321   public void setBoolean(boolean val) {
322     setVariant(new Variant(val));
323   }
324
325   /*
326    * (non-Javadoc)
327    *
328    * @see com.google.gwt.dev.shell.JsValue#setByte(byte)
329    */

330   public void setByte(byte val) {
331     setVariant(new Variant(val));
332   }
333
334   /*
335    * (non-Javadoc)
336    *
337    * @see com.google.gwt.dev.shell.JsValue#setChar(char)
338    */

339   public void setChar(char val) {
340     setVariant(new Variant(val));
341   }
342
343   /*
344    * (non-Javadoc)
345    *
346    * @see com.google.gwt.dev.shell.JsValue#setDouble(double)
347    */

348   public void setDouble(double val) {
349     setVariant(new Variant(val));
350   }
351
352   /*
353    * (non-Javadoc)
354    *
355    * @see com.google.gwt.dev.shell.JsValue#setInt(int)
356    */

357   public void setInt(int val) {
358     setVariant(new Variant(val));
359   }
360
361   /*
362    * (non-Javadoc)
363    *
364    * @see com.google.gwt.dev.shell.JsValue#setNull()
365    */

366   public void setNull() {
367     setVariant(new Variant(0, COM.VT_NULL));
368   }
369
370   /*
371    * (non-Javadoc)
372    *
373    * @see com.google.gwt.dev.shell.JsValue#setShort(short)
374    */

375   public void setShort(short val) {
376     setVariant(new Variant(val));
377   }
378
379   /*
380    * (non-Javadoc)
381    *
382    * @see com.google.gwt.dev.shell.JsValue#setString(java.lang.String)
383    */

384   public void setString(String JavaDoc val) {
385     setVariant(new Variant(val));
386   }
387
388   /*
389    * (non-Javadoc)
390    *
391    * @see com.google.gwt.dev.shell.JsValue#setUndefined()
392    */

393   public void setUndefined() {
394     setVariant(null);
395   }
396
397   public void setValue(JsValue other) {
398     setVariant(maybeCopyVariant(((JsValueIE6) other).variant));
399   }
400
401   /*
402    * (non-Javadoc)
403    *
404    * @see com.google.gwt.dev.shell.JsValue#setWrappedJavaObject(com.google.gwt.dev.shell.CompilingClassLoader,
405    * java.lang.Object)
406    */

407   public void setWrappedJavaObject(CompilingClassLoader cl, Object JavaDoc val) {
408     IDispatchImpl dispObj;
409     if (val == null) {
410       setNull();
411       return;
412     } else if (val instanceof IDispatchImpl) {
413       dispObj = (IDispatchImpl)val;
414     } else {
415       dispObj = new IDispatchProxy(cl, val);
416     }
417     IDispatch disp = new IDispatch(dispObj.getAddress());
418     disp.AddRef();
419     setVariant(new Variant(disp));
420   }
421
422   /*
423    * (non-Javadoc)
424    *
425    * @see com.google.gwt.dev.shell.JsValue#createCleanupObject()
426    */

427   protected JsCleanup createCleanupObject() {
428     return new JsCleanupIE6(variant);
429   }
430
431   /**
432    * Reset the underlying variant, freeing the old one if necessary.
433    *
434    * @param val the new Variant to store
435    */

436   protected void setVariant(Variant val) {
437     if (variant != null) {
438       variant.dispose();
439     }
440     variant = val;
441   }
442   
443   private Object JavaDoc tryToUnwrapWrappedJavaObject() {
444     /*
445      * This implementation copied from OleAutomation.invoke(). We used to have a
446      * varArg.getAutomation().invoke() implementation, but it turns out the
447      * querying for typeInfo that occurs in the OleAutomation(IDispatch)
448      * constructor will cause a VM crash on some kinds of JavaScript objects,
449      * such as the window.alert function. So we do it by hand.
450      */

451     IDispatch dispatch = variant.getDispatch();
452     Variant result = new Variant();
453     int pVarResultAddress = 0;
454     int globalRef = 0;
455     try {
456       pVarResultAddress = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT,
457           Variant.sizeof);
458       int[] pArgErr = new int[1];
459       int hr = dispatch.Invoke(IDispatchProxy.DISPID_MAGIC_GETGLOBALREF,
460           new GUID(), COM.LOCALE_USER_DEFAULT, COM.DISPATCH_METHOD,
461           new DISPPARAMS(), pVarResultAddress, new EXCEPINFO(), pArgErr);
462
463       if (hr >= COM.S_OK) {
464         result = Variant.win32_new(pVarResultAddress);
465         globalRef = result.getInt();
466       }
467       if (globalRef != 0) {
468         // This is really a Java object being passed back via an IDispatchProxy.
469
IDispatchProxy proxy = (IDispatchProxy) LowLevel.objFromGlobalRefInt(globalRef);
470         return proxy.getTarget();
471       }
472       return null;
473     } finally {
474       if (result != null) {
475         result.dispose();
476       }
477       if (pVarResultAddress != 0) {
478         COM.VariantClear(pVarResultAddress);
479         OS.GlobalFree(pVarResultAddress);
480       }
481     }
482   }
483
484 }
485
Popular Tags