1 28 29 package com.caucho.ejb.gen; 30 31 import com.caucho.java.AbstractGenerator; 32 import com.caucho.util.IntMap; 33 import com.caucho.util.L10N; 34 import com.caucho.vfs.IOExceptionWrapper; 35 36 import javax.ejb.EJBHome ; 37 import javax.ejb.EJBLocalHome ; 38 import javax.ejb.EJBLocalObject ; 39 import javax.ejb.EJBObject ; 40 import java.io.IOException ; 41 import java.lang.reflect.Method ; 42 import java.util.ArrayList ; 43 44 47 abstract class JVMStubGenerator extends AbstractGenerator { 48 protected static final L10N L = new L10N(JVMStubGenerator.class); 49 50 static IntMap _immutableClasses; 53 54 protected boolean _isProxy = false; 55 protected ArrayList <Method > _proxyMethods = new ArrayList <Method >(); 56 protected Class _remoteClass; 57 58 void setProxy(boolean isProxy) 59 { 60 _isProxy = isProxy; 61 } 62 63 66 abstract protected void printHeader() 67 throws IOException ; 68 69 74 protected void printMethod(String name, Method method) 75 throws IOException 76 { 77 Class ret = method.getReturnType(); 78 Class []params = method.getParameterTypes(); 79 80 printMethodHeader(name, method); 81 82 boolean needsSerialization = printMethodHead(params, ret); 83 84 printCall(method.getName(), params, ret); 85 86 printMethodFooter(ret, needsSerialization); 87 } 88 89 protected boolean printMethodHead(Class []params, Class ret) 90 throws IOException 91 { 92 println("{"); 93 pushDepth(); 94 println("Thread thread = Thread.currentThread();"); 95 println("ClassLoader oldLoader = thread.getContextClassLoader();"); 96 97 boolean needsSerialization = false; 98 for (int i = 0; i < params.length; i++) { 99 if (needsSerialization(params[i])) { 100 if (! needsSerialization) { 101 println("com.caucho.ejb.protocol.SelfSerializer ser;"); 102 println("ser = com.caucho.ejb.protocol.SelfSerializer.allocate();"); 103 } 104 println("ser.write(a" + i + ");"); 105 needsSerialization = true; 106 } 107 } 108 109 if (needsSerialization(ret) && ! needsSerialization) { 110 println("com.caucho.ejb.protocol.SelfSerializer ser;"); 111 println("ser = com.caucho.ejb.protocol.SelfSerializer.allocate();"); 112 needsSerialization = true; 113 } 114 115 if (! ret.getName().equals("void")) { 116 printClass(ret); 117 println(" _ret;"); 118 } 119 120 println(); 121 if (! _isProxy) { 122 println(_remoteClass.getName() + " obj;"); 123 println("obj = (" + _remoteClass.getName() + ") _caucho_getObject();"); 124 } 125 else { 126 println("Object obj = _caucho_getObject();"); 127 } 128 println("thread.setContextClassLoader(_caucho_getClassLoader());"); 129 println("try {"); 130 pushDepth(); 131 132 return needsSerialization; 133 } 134 135 protected void printMethodFooter(Class ret, boolean needsSerialization) 136 throws IOException 137 { 138 if (needsSerialization(ret)) { 139 if (needsSerialization) 140 println("ser.clear();"); 141 needsSerialization = true; 142 println("ser.write(_ret);"); 143 println("thread.setContextClassLoader(oldLoader);"); 144 print("_ret = ("); 145 printClass(ret); 146 println(") ser.read();"); 147 } 148 149 popDepth(); 150 println("} finally {"); 151 pushDepth(); 152 println("thread.setContextClassLoader(oldLoader);"); 153 154 if (needsSerialization) 155 println("ser.close();"); 156 157 popDepth(); 158 println("}"); 159 160 if (! ret.getName().equals("void")) 161 println("return _ret;"); 162 163 popDepth(); 164 println("}"); 165 } 166 167 void printCall(String name, Class []params, Class retType) 168 throws IOException 169 { 170 if (_isProxy) { 171 printProxyCall(name, params, retType); 172 return; 173 } 174 175 if (! retType.equals(void.class)) 176 print("_ret = "); 177 178 print("obj." + name + "("); 179 for (int i = 0; i < params.length; i++) { 180 if (i != 0) 181 print(", "); 182 if (needsSerialization(params[i])) { 183 print("("); 184 printClass(params[i]); 185 print(") ser.read()"); 186 } 187 else 188 print("a" + i); 189 } 190 println(");"); 191 } 192 193 void printProxyCall(String name, Class []params, Class retType) 194 throws IOException 195 { 196 Method method; 197 198 try { 199 method = _remoteClass.getMethod(name, params); 200 } catch (NoSuchMethodException e) { 201 throw new IOExceptionWrapper(e); 202 } 203 _proxyMethods.add(method); 204 205 if (_isProxy) { 206 println("try {"); 207 pushDepth(); 208 } 209 210 int index = _proxyMethods.size() - 1; 211 212 boolean retNeedsSerialization = needsSerialization(retType); 213 214 if (retType.equals(void.class)) { 215 } 216 else if (! retNeedsSerialization) { 217 print("_ret = ("); 218 printClass(retType); 219 print(")"); 220 } 221 else { 222 print("Object _oret = "); 223 } 224 225 if (retType.isPrimitive()) 226 print("com.caucho.ejb.JVMObject.to_" + retType.getName() + "("); 227 228 print("method" + index + ".invoke(obj, new Object[] {"); 229 for (int i = 0; i < params.length; i++) { 230 if (i != 0) 231 print(", "); 232 if (needsSerialization(params[i])) { 233 print("("); 234 printClass(params[i]); 235 print(") ser.read()"); 236 } 237 else if (params[i].isPrimitive()) 238 printToObject("a" + i, params[i]); 239 else 240 print("a" + i); 241 } 242 if (retType.isPrimitive()) 243 println("}));"); 244 else 245 println("});"); 246 247 if (retNeedsSerialization) { 248 println("ser.clear();"); 250 println("ser.write(_oret);"); 251 println("thread.setContextClassLoader(oldLoader);"); 252 print("_ret = ("); 253 printClass(method.getReturnType()); 254 println(") ser.read();"); 255 } 256 257 popDepth(); 258 println("} catch (java.lang.IllegalAccessException e) {"); 259 println(" throw com.caucho.ejb.EJBExceptionWrapper.createRuntime(e);"); 260 println("} catch (java.lang.reflect.InvocationTargetException e) {"); 261 println(" throw com.caucho.ejb.EJBExceptionWrapper.createRuntime(e);"); 262 println("}"); 263 } 264 265 void printToObject(String name, Class cl) 266 throws IOException 267 { 268 if (boolean.class.equals(cl)) 269 print("new Boolean(" + name + ")"); 270 else if (byte.class.equals(cl)) 271 print("new Byte(" + name + ")"); 272 else if (short.class.equals(cl)) 273 print("new Short(" + name + ")"); 274 else if (char.class.equals(cl)) 275 print("new Character(" + name + ")"); 276 else if (int.class.equals(cl)) 277 print("new Integer(" + name + ")"); 278 else if (long.class.equals(cl)) 279 print("new Long(" + name + ")"); 280 else if (float.class.equals(cl)) 281 print("new Float(" + name + ")"); 282 else if (double.class.equals(cl)) 283 print("new Double(" + name + ")"); 284 else 285 throw new RuntimeException (L.l("can't create object for type {0}", 286 cl.getName())); 287 } 288 289 292 void printFooter() 293 throws IOException 294 { 295 for (int i = 0; i < _proxyMethods.size(); i++) { 296 println("static java.lang.reflect.Method method" + i + ";"); 297 } 298 if (_proxyMethods.size() > 0) { 299 println("protected void _caucho_init_methods(Class cl)"); 300 println("{"); 301 pushDepth(); 302 println("try {"); 303 pushDepth(); 304 for (int i = 0; i < _proxyMethods.size(); i++) { 305 Method method = _proxyMethods.get(i); 306 307 print("method" + i + " = cl.getMethod(\""); 308 print(method.getName()); 309 print("\", new Class[] {"); 310 Class []paramTypes = method.getParameterTypes(); 311 for (int j = 0; j < paramTypes.length; j++) { 312 if (j != 0) 313 print(", "); 314 printClass(paramTypes[j]); 315 print(".class"); 316 } 317 println("});"); 318 } 319 popDepth(); 320 println("} catch (Exception e) {"); 321 println(" com.caucho.ejb.EJBExceptionWrapper.createRuntime(e);"); 322 println("}"); 323 popDepth(); 324 println("}"); 325 } 326 327 popDepth(); 328 println("}"); 329 } 330 331 338 boolean needsSerialization(Class cl) 339 { 340 if (cl.isPrimitive()) 341 return false; 342 else if (! _isProxy && EJBObject .class.isAssignableFrom(cl)) 343 return false; 344 else if (! _isProxy && EJBLocalObject .class.isAssignableFrom(cl)) 345 return false; 346 else if (! _isProxy && EJBHome .class.isAssignableFrom(cl)) 347 return false; 348 else if (! _isProxy && EJBLocalHome .class.isAssignableFrom(cl)) 349 return false; 350 else 351 return _immutableClasses.get(cl) < 0; 352 } 353 354 357 protected void printVersionChange() 358 throws IOException 359 { 360 println("if (com.caucho.ejb.Version.getVersionId() != " + 361 com.caucho.ejb.Version.getVersionId() + ")"); 362 println(" return true;"); 363 } 364 365 static { 366 _immutableClasses = new IntMap(); 367 _immutableClasses.put(String .class, 1); 368 _immutableClasses.put(Byte .class, 1); 369 _immutableClasses.put(Character .class, 1); 370 _immutableClasses.put(Short .class, 1); 371 _immutableClasses.put(Integer .class, 1); 372 _immutableClasses.put(Long .class, 1); 373 _immutableClasses.put(Float .class, 1); 374 _immutableClasses.put(Double .class, 1); 375 _immutableClasses.put(Class .class, 1); 376 } 377 } 378 | Popular Tags |