1 16 package com.google.gwt.dev.shell.ie; 17 18 import com.google.gwt.dev.shell.CompilingClassLoader; 19 import com.google.gwt.dev.shell.ModuleSpace; 20 import com.google.gwt.dev.util.log.AbstractTreeLogger; 21 22 import org.eclipse.swt.internal.ole.win32.COM; 23 import org.eclipse.swt.internal.ole.win32.COMObject; 24 import org.eclipse.swt.internal.ole.win32.DISPPARAMS; 25 import org.eclipse.swt.internal.ole.win32.GUID; 26 import org.eclipse.swt.internal.win32.OS; 27 import org.eclipse.swt.ole.win32.OleAutomation; 28 import org.eclipse.swt.ole.win32.Variant; 29 30 import java.lang.reflect.InvocationTargetException ; 31 import java.lang.reflect.Method ; 32 import java.util.Arrays ; 33 34 39 abstract class IDispatchImpl extends COMObject { 40 41 44 protected static class HResultException extends Exception { 45 private int hr; 46 47 private String source; 48 49 52 public HResultException(int hr) { 53 super(Integer.toString(hr)); 54 this.hr = hr; 55 source = "Java"; 56 } 57 58 61 public HResultException(String message) { 62 super(message); 63 hr = COM.DISP_E_EXCEPTION; 64 source = "Java"; 65 } 66 67 70 public HResultException(Throwable e) { 71 super(AbstractTreeLogger.getStackTraceAsString(e), e); 72 hr = COM.DISP_E_EXCEPTION; 73 source = "Java"; 74 } 75 76 80 public void fillExcepInfo(int pExcepInfo) { 81 if (hr == COM.DISP_E_EXCEPTION) { 82 String desc = getMessage(); 83 OS.MoveMemory(pExcepInfo + 0, new short[] {(short) hr}, 2); 89 90 if (source != null) { 91 int bstrSource = SwtOleGlue.sysAllocString(source); 92 OS.MoveMemory(pExcepInfo + 4, new int[] {bstrSource}, 4); 93 } 94 95 if (desc != null) { 96 int bstrDesc = SwtOleGlue.sysAllocString(desc); 97 OS.MoveMemory(pExcepInfo + 8, new int[] {bstrDesc}, 4); 98 } 99 100 OS.MoveMemory(pExcepInfo + 28, new int[] {0}, 4); 101 } 102 } 103 104 107 public int getHResult() { 108 return hr; 109 } 110 } 111 112 protected static final int DISP_E_UNKNOWNNAME = 0x80020006; 114 115 protected static Variant callMethod(CompilingClassLoader cl, Object jthis, 116 Variant[] params, Method method) throws InvocationTargetException , 117 HResultException { 118 Object [] javaParams = SwtOleGlue.convertVariantsToObjects( 120 method.getParameterTypes(), params, "Calling method '" 121 + method.getName() + "'"); 122 123 Object result = null; 124 try { 125 try { 126 result = method.invoke(jthis, javaParams); 127 } catch (IllegalAccessException e) { 128 e.printStackTrace(); 130 throw new RuntimeException (e); 131 } 132 } catch (NullPointerException e) { 133 137 StringBuffer sb = new StringBuffer (); 138 sb.append("Instance method '"); 139 sb.append(method.getName()); 140 sb.append("' needed a qualifying instance "); 141 sb.append("(did you forget to prefix the call with 'this.'?)"); 142 throw new HResultException(sb.toString()); 143 } finally { 144 for (int i = 0; i < javaParams.length; i++) { 145 if (javaParams[i] instanceof OleAutomation) { 146 OleAutomation tmp = (OleAutomation) javaParams[i]; 147 tmp.dispose(); 148 } 149 } 150 } 151 152 Class returnType = method.getReturnType(); 156 if (returnType.equals(Void.TYPE)) { 157 return new Variant(); 158 } 159 return SwtOleGlue.convertObjectToVariant(cl, returnType, result); 160 } 161 162 protected int refCount; 163 164 public IDispatchImpl() { 165 super(new int[] {2, 0, 0, 1, 3, 5, 8}); 166 } 167 168 public int AddRef() { 170 return ++refCount; 171 } 172 173 175 public int method0(int[] args) { 176 return QueryInterface(args[0], args[1]); 177 } 178 179 public int method1(int[] args) { 180 return AddRef(); 181 } 182 183 185 187 public int method2(int[] args) { 188 return Release(); 189 } 190 191 public int method5(int[] args) { 192 return GetIDsOfNames(args[0], args[1], args[2], args[3], args[4]); 193 } 194 195 public int method6(int[] args) { 196 return Invoke(args[0], args[1], args[2], args[3], args[4], args[5], 197 args[6], args[7]); 198 } 199 200 public int QueryInterface(int riid, int ppvObject) { 202 if (riid == 0 || ppvObject == 0) { 203 return COM.E_NOINTERFACE; 204 } 205 GUID guid = new GUID(); 206 COM.MoveMemory(guid, riid, GUID.sizeof); 207 208 if (COM.IsEqualGUID(guid, COM.IIDIUnknown)) { 209 COM.MoveMemory(ppvObject, new int[] {getAddress()}, 4); 210 AddRef(); 211 return COM.S_OK; 212 } 213 214 if (COM.IsEqualGUID(guid, COM.IIDIDispatch)) { 215 COM.MoveMemory(ppvObject, new int[] {getAddress()}, 4); 216 AddRef(); 217 return COM.S_OK; 218 } 219 220 COM.MoveMemory(ppvObject, new int[] {0}, 4); 221 return COM.E_NOINTERFACE; 222 } 223 224 public int Release() { 225 if (--refCount == 0) { 226 dispose(); 227 } 228 return refCount; 229 } 230 231 233 236 protected abstract void getIDsOfNames(String [] names, int[] ids) 237 throws HResultException; 238 239 242 protected abstract Variant invoke(int dispId, int flags, Variant[] params) 243 throws HResultException, InvocationTargetException ; 244 245 private Variant[] extractVariantArrayFromDispParamsPtr(int pDispParams) { 246 DISPPARAMS dispParams = new DISPPARAMS(); 247 COM.MoveMemory(dispParams, pDispParams, DISPPARAMS.sizeof); 248 Variant[] variants = new Variant[dispParams.cArgs]; 249 for (int i = 0, n = dispParams.cArgs; i < n; ++i) { 251 int varArgAddr = dispParams.rgvarg + Variant.sizeof * i; 252 variants[n - i - 1] = Variant.win32_new(varArgAddr); 253 } 254 return variants; 255 } 256 257 private final int GetIDsOfNames(int riid, int rgszNames, int cNames, 259 int lcid, int rgDispId) { 260 261 try { 262 if (cNames < 1) { 263 return COM.E_INVALIDARG; 264 } 265 266 String [] names = SwtOleGlue.extractStringArrayFromOleCharPtrPtr( 269 rgszNames, cNames); 270 int[] ids = new int[names.length]; 271 Arrays.fill(ids, -1); 272 273 getIDsOfNames(names, ids); 274 OS.MoveMemory(rgDispId, ids, ids.length * 4); 275 } catch (HResultException e) { 276 return e.getHResult(); 277 } catch (Throwable e) { 278 e.printStackTrace(); 279 return COM.E_FAIL; 280 } 281 282 return COM.S_OK; 283 } 284 285 private int Invoke(int dispIdMember, int riid, int lcid, int dwFlags, 286 int pDispParams, int pVarResult, int pExcepInfo, int pArgErr) { 287 288 HResultException ex = null; 289 Variant[] vArgs = null; 290 Variant result = null; 291 try { 292 vArgs = extractVariantArrayFromDispParamsPtr(pDispParams); 293 result = invoke(dispIdMember, dwFlags, vArgs); 294 if (pVarResult != 0) { 295 Variant.win32_copy(pVarResult, result); 296 } 297 } catch (HResultException e) { 298 e.printStackTrace(); 301 ex = e; 302 303 } catch (InvocationTargetException e) { 304 307 Throwable t = e.getTargetException(); 308 ex = new HResultException(t); 309 ModuleSpace.setThrownJavaException(t); 310 } catch (Exception e) { 311 e.printStackTrace(); 314 ex = new HResultException(e); 315 } finally { 316 for (int i = 0; i < vArgs.length; ++i) { 319 if (vArgs[i] != null) { 320 vArgs[i].dispose(); 321 } 322 } 323 324 if (result != null) { 325 result.dispose(); 326 } 327 } 328 329 if (ex != null) { 330 ex.fillExcepInfo(pExcepInfo); 333 return ex.getHResult(); 334 } 335 336 return COM.S_OK; 337 } 338 } 340 | Popular Tags |