1 22 package org.jboss.proxy.compiler; 27 import java.lang.reflect.Method ; 28 import java.lang.reflect.Modifier ; 29 import java.rmi.RemoteException ; 30 31 import org.jboss.iiop.rmi.AttributeAnalysis; 32 import org.jboss.iiop.rmi.ExceptionAnalysis; 33 import org.jboss.iiop.rmi.InterfaceAnalysis; 34 import org.jboss.iiop.rmi.OperationAnalysis; 35 import org.jboss.iiop.rmi.RMIIIOPViolationException; 36 import org.jboss.iiop.rmi.marshal.CDRStream; 37 import org.jboss.iiop.rmi.marshal.strategy.StubStrategy; 38 import org.jboss.proxy.ejb.DynamicIIOPStub; 39 40 48 public class IIOPStubCompiler 49 { 50 52 56 private static final Class [] stubStrategyParams = { 57 String [].class, String [].class, String [].class, String .class, 58 ClassLoader .class 59 }; 60 61 65 private static final Class [] invokeParams = { 66 String .class, StubStrategy.class, Object [].class 67 }; 68 69 73 private static final Class [] corbaObjectParam = { 74 org.omg.CORBA.Object .class 75 }; 76 77 80 private static final Class [] stringParam = { 81 String .class 82 }; 83 84 87 private static final Class [] noParams = { }; 88 89 91 95 private static String strategy(int methodIndex) { 96 return "$s" + methodIndex; 97 } 98 99 103 private static String init(int methodIndex) { 104 return "$i" + methodIndex; 105 } 106 107 123 private static void generateMethodCode(ProxyAssembler asm, 124 Class superclass, 125 Method m, 126 String idlName, 127 String strategyField, 128 String initMethod) 129 { 130 String methodName = m.getName(); 131 Class returnType = m.getReturnType(); 132 Class [] paramTypes = m.getParameterTypes(); 133 Class [] exceptions = m.getExceptionTypes(); 134 135 asm.addMember(Modifier.PRIVATE + Modifier.STATIC, 137 StubStrategy.class, null, strategyField); 138 139 asm.addMember(Modifier.PUBLIC + Modifier.FINAL, 141 returnType, methodName, paramTypes, exceptions); 142 { 143 asm.pushLocal(0); asm.pushConstant(idlName); 147 asm.pushField(asm, strategyField); 148 if (paramTypes.length == 0) { 150 asm.pushField(Util.class, "NOARGS"); 151 } else { 152 asm.pushConstant(paramTypes.length); 153 asm.pushNewArray(Object .class); 154 for (int j = 0; j < paramTypes.length; j++) { 155 Class t = paramTypes[j]; 156 asm.dup(); 157 asm.pushConstant(j); 158 asm.pushLocal(1 + j); 159 if (t.isPrimitive()) { 160 asm.invoke(Util.class, "wrap", new Class []{ t }); 161 } 162 asm.setElement(Object .class); 163 } 164 } 165 String invoke = "invoke"; 167 if (returnType.isPrimitive() && returnType != Void.TYPE) { 168 String typeName = returnType.getName(); 169 invoke += (Character.toUpperCase(typeName.charAt(0)) 170 + typeName.substring(1)); 171 } 172 asm.invoke(superclass, invoke, invokeParams); 173 if (!returnType.isPrimitive() && returnType != Object .class) { 174 asm.checkCast(returnType); 175 } 176 asm.ret(); 177 } 178 179 asm.addMember(Modifier.PRIVATE + Modifier.STATIC, 181 Void.TYPE, initMethod, noParams, null); 182 { 183 int i; 184 int len; 185 186 len = paramTypes.length; 189 asm.pushConstant(len); 190 asm.pushNewArray(String .class); 191 for (i = 0; i < len; i++) { 192 asm.dup(); 193 asm.pushConstant(i); 194 asm.pushConstant(CDRStream.abbrevFor(paramTypes[i])); 195 asm.setElement(String .class); 196 } 197 198 len = exceptions.length; 201 int n = 0; 202 for (i = 0; i < len; i++) { 203 if (!RemoteException .class.isAssignableFrom(exceptions[i])) { 204 n++; 205 } 206 } 207 asm.pushConstant(n); 208 asm.pushNewArray(String .class); 209 try { 210 int j = 0; 211 for (i = 0; i < len; i++) { 212 if (!RemoteException .class.isAssignableFrom(exceptions[i])) { 213 asm.dup(); 214 asm.pushConstant(j); 215 asm.pushConstant( 216 ExceptionAnalysis.getExceptionAnalysis(exceptions[i]) 217 .getExceptionRepositoryId()); 218 asm.setElement(String .class); 219 j++; 220 } 221 } 222 } 223 catch (RMIIIOPViolationException e) { 224 throw new RuntimeException ("Cannot obtain " 225 + "exception repository id for " 226 + exceptions[i].getName() + ":\n" + e); 227 } 228 229 asm.pushConstant(n); 232 asm.pushNewArray(String .class); 233 int j = 0; 234 for (i = 0; i < len; i++) { 235 if (!RemoteException .class.isAssignableFrom(exceptions[i])) { 236 asm.dup(); 237 asm.pushConstant(j); 238 asm.pushConstant(exceptions[i].getName()); 239 asm.setElement(String .class); 240 j++; 241 } 242 } 243 244 asm.pushConstant(CDRStream.abbrevFor(returnType)); 247 248 asm.pushField(Util.class, "NULLCL"); 251 252 asm.invoke(StubStrategy.class, "forMethod", stubStrategyParams); 254 255 asm.setField(asm, strategyField); 257 258 asm.ret(); 259 } 260 } 261 262 272 private static byte[] generateCode(InterfaceAnalysis interfaceAnalysis, 273 Class superclass, String stubClassName) 274 { 275 ProxyAssembler asm = 276 new ProxyAssembler(stubClassName, 277 Modifier.PUBLIC | Modifier.FINAL, 278 superclass, 279 new Class [] { interfaceAnalysis.getCls() }); 280 281 int methodIndex = 0; 282 283 AttributeAnalysis[] attrs = interfaceAnalysis.getAttributes(); 284 for (int i = 0; i < attrs.length; i++) { 285 OperationAnalysis op = attrs[i].getAccessorAnalysis(); 286 generateMethodCode(asm, superclass, op.getMethod(), op.getIDLName(), 287 strategy(methodIndex), init(methodIndex)); 288 methodIndex++; 289 op = attrs[i].getMutatorAnalysis(); 290 if (op != null) { 291 generateMethodCode(asm, superclass, 292 op.getMethod(), op.getIDLName(), 293 strategy(methodIndex), init(methodIndex)); 294 methodIndex++; 295 } 296 } 297 298 OperationAnalysis[] ops = interfaceAnalysis.getOperations(); 299 for (int i = 0; i < ops.length; i++) { 300 generateMethodCode(asm, superclass, 301 ops[i].getMethod(), ops[i].getIDLName(), 302 strategy(methodIndex), init(methodIndex)); 303 methodIndex++; 304 } 305 306 asm.addMember(Modifier.PUBLIC, Void.TYPE, "<init>", noParams, null); 308 { 309 asm.pushLocal(0); 310 asm.invoke(superclass, "<init>", noParams); 311 asm.ret(); 312 } 313 314 asm.addMember(Modifier.PUBLIC, String .class, "toString", noParams, null); 316 { 317 { 318 asm.pushConstant("JBossDynStub[" 319 + interfaceAnalysis.getCls().getName() + ", "); 320 { 321 { 322 asm.pushLocal(0); 323 asm.invoke(superclass, "_orb", noParams); 324 } 325 asm.pushLocal(0); 326 asm.invoke(org.omg.CORBA.ORB .class, 327 "object_to_string", corbaObjectParam); 328 } 329 asm.invoke(String .class, "concat", stringParam); 330 } 331 asm.pushConstant("]"); 332 asm.invoke(String .class, "concat", stringParam); 333 asm.ret(); 334 } 335 336 String [] ids = interfaceAnalysis.getAllTypeIds(); 338 asm.addMember(Modifier.PRIVATE + Modifier.STATIC, String [].class, 339 null, "$ids"); 340 asm.addMember(Modifier.PUBLIC + Modifier.FINAL, 341 String [].class, "_ids", noParams, null); 342 { 343 asm.pushField(asm, "$ids"); 344 asm.ret(); 345 } 346 347 asm.addMember(Modifier.STATIC, Void.TYPE, "<clinit>", noParams, null); 349 { 350 354 asm.pushConstant(ids.length); 355 asm.pushNewArray(String .class); 356 for (int i = 0; i < ids.length; i++) { 357 asm.dup(); 358 asm.pushConstant(i); 359 asm.pushConstant(ids[i]); 360 asm.setElement(String .class); 361 } 362 asm.setField(asm, "$ids"); 363 364 int n = methodIndex; for (methodIndex = 0; methodIndex < n; methodIndex++) { 366 asm.invoke(asm, init(methodIndex), noParams); 367 } 368 369 373 asm.ret(); 374 } 375 376 return asm.getCode(); 377 } 378 379 389 private static byte[] makeCode(InterfaceAnalysis interfaceAnalysis, 390 Class superclass, String stubClassName) 391 { 392 393 byte code[] = generateCode(interfaceAnalysis, superclass, stubClassName); 394 return code; 406 } 407 408 410 418 public static byte[] compile(Class intf, String stubClassName) 419 { 420 InterfaceAnalysis interfaceAnalysis = null; 421 422 try { 423 interfaceAnalysis = InterfaceAnalysis.getInterfaceAnalysis(intf); 424 } 425 catch (RMIIIOPViolationException e) { 426 throw new RuntimeException ("RMI/IIOP Violation:\n" + e); 427 } 428 return makeCode(interfaceAnalysis, DynamicIIOPStub.class, stubClassName); 429 } 430 431 } 432 | Popular Tags |