1 31 package org.objectweb.proactive.core.component.asmgen; 32 33 import org.apache.log4j.Logger; 34 35 import org.objectweb.asm.CodeVisitor; 36 import org.objectweb.asm.Type; 37 38 import org.objectweb.fractal.api.Component; 39 import org.objectweb.fractal.api.type.InterfaceType; 40 41 import org.objectweb.proactive.core.component.ProActiveInterface; 42 import org.objectweb.proactive.core.component.exceptions.InterfaceGenerationFailedException; 43 import org.objectweb.proactive.core.mop.StubObject; 44 import org.objectweb.proactive.core.mop.Utils; 45 46 import java.io.Serializable ; 47 48 import java.lang.reflect.Method ; 49 50 import java.util.Hashtable ; 51 import java.util.Map ; 52 import java.util.Vector ; 53 54 55 71 public class RepresentativeInterfaceClassGenerator 72 extends AbstractInterfaceClassGenerator { 73 protected static Logger logger = Logger.getLogger(RepresentativeInterfaceClassGenerator.class.getName()); 74 75 protected static final String PROXY_TYPE = "Lorg/objectweb/proactive/core/mop/Proxy;"; 77 protected static final String STUB_INTERFACE_NAME = "org/objectweb/proactive/core/mop/StubObject"; 78 protected static final String PROXY_FIELD_NAME = "myProxy"; 79 80 private static Hashtable generatedClassesCache = new Hashtable (); 82 private static RepresentativeInterfaceClassGenerator instance; 83 84 protected boolean isPrimitive = false; 86 private String fcInterfaceName = null; 87 88 public RepresentativeInterfaceClassGenerator() { 89 this.cl = ProActiveInterface.class; 93 94 this.className = cl.getName(); 96 97 } 99 100 public static RepresentativeInterfaceClassGenerator instance() { 101 if (instance == null) { 102 return new RepresentativeInterfaceClassGenerator(); 103 } else { 104 return instance; 105 } 106 } 107 108 111 public static byte[] getClassData(String classname) { 112 return (byte[]) getGeneratedClassesCache().get(classname); 113 } 114 115 119 public static Map getGeneratedClassesCache() { 120 return generatedClassesCache; 121 } 122 123 public ProActiveInterface generateInterface(final String fcInterfaceName, 124 Component owner, InterfaceType interfaceType, boolean isInternal) 125 throws InterfaceGenerationFailedException { 126 try { 127 this.fcInterfaceName = fcInterfaceName; 128 129 interfacesToImplement = new Vector (); 132 133 interfacesToImplement.add(Class.forName( 135 interfaceType.getFcItfSignature())); 136 137 interfacesToImplement.addElement(Serializable .class); 139 140 interfacesToImplement.addElement(StubObject.class); 142 143 this.stubClassFullName = org.objectweb.proactive.core.component.asmgen.Utils.getMetaObjectComponentRepresentativeClassName(fcInterfaceName, 144 interfaceType.getFcItfSignature()); 145 Class generated_class; 147 148 try { 150 generated_class = loadClass(stubClassFullName); 151 } catch (ClassNotFoundException cnfe) { 152 byte[] bytes; 153 setInfos(); 154 bytes = create(); 155 RepresentativeInterfaceClassGenerator.generatedClassesCache.put(stubClassFullName, 156 bytes); 157 if (logger.isDebugEnabled()) { 158 logger.debug("added " + stubClassFullName + " to cache"); 159 } 160 if (logger.isDebugEnabled()) { 161 logger.debug("generated classes cache is : " + 162 generatedClassesCache.toString()); 163 } 164 165 generated_class = defineClass(stubClassFullName, bytes); 183 } 184 185 ProActiveInterface reference = (ProActiveInterface) generated_class.newInstance(); 186 reference.setName(fcInterfaceName); 187 reference.setOwner(owner); 188 reference.setType(interfaceType); 189 reference.setIsInternal(isInternal); 190 191 return reference; 192 } catch (ClassNotFoundException e) { 193 throw new InterfaceGenerationFailedException("cannot find interface signature class", 194 e); 195 } catch (IllegalAccessException e) { 196 throw new InterfaceGenerationFailedException("constructor not accessible", 197 e); 198 } catch (InstantiationException e) { 199 throw new InterfaceGenerationFailedException("constructor belongs to an abstract class?", 200 e); 201 } 203 } 204 205 protected CodeVisitor createMethod(int methodIndex, Method m) { 206 CodeVisitor cv = createMethodGenerator(m); 207 208 cv.visitVarInsn(ALOAD, 0); 210 cv.visitFieldInsn(GETFIELD, this.stubClassFullName.replace('.', '/'), 211 PROXY_FIELD_NAME, PROXY_TYPE); 212 213 cv.visitFieldInsn(GETSTATIC, this.stubClassFullName.replace('.', '/'), 215 "methods", METHOD_ARRAY_TYPE); 216 pushInt(cv, methodIndex); 217 cv.visitInsn(AALOAD); 218 219 Class [] paramTypes = m.getParameterTypes(); 220 221 pushInt(cv, paramTypes.length); 224 225 cv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); 227 228 int indexInParameterArray = 1; for (int i = 0; i < paramTypes.length; i++) { 231 cv.visitInsn(DUP); 234 235 pushInt(cv, i); 237 238 Class param = paramTypes[i]; 240 241 if (param.isPrimitive()) { 243 int opcode = ILOAD; 244 String type; 245 String desc; 246 if (param == Byte.TYPE) { 247 type = "java/lang/Byte"; 248 desc = "B"; 249 } else if (param == Integer.TYPE) { 250 type = "java/lang/Integer"; 251 desc = "I"; 252 } else if (param == Boolean.TYPE) { 253 type = "java/lang/Boolean"; 254 desc = "Z"; 255 } else if (param == Double.TYPE) { 256 opcode = DLOAD; 257 type = "java/lang/Double"; 258 desc = "D"; 259 } else if (param == Float.TYPE) { 260 opcode = FLOAD; 261 type = "java/lang/Float"; 262 desc = "F"; 263 } else if (param == Long.TYPE) { 264 opcode = LLOAD; 265 type = "java/lang/Long"; 266 desc = "J"; 267 } else if (param == Character.TYPE) { 268 type = "java/lang/Character"; 269 desc = "C"; 270 } else 271 { 272 type = "java/lang/Short"; 273 desc = "S"; 274 } 275 cv.visitTypeInsn(NEW, type); 276 cv.visitInsn(DUP); 277 cv.visitVarInsn(opcode, indexInParameterArray); 278 cv.visitMethodInsn(INVOKESPECIAL, type, "<init>", 279 "(" + desc + ")V"); 280 } else { 281 cv.visitVarInsn(ALOAD, indexInParameterArray); 282 } 283 indexInParameterArray += (((param == Double.TYPE) || 284 (param == Long.TYPE)) ? 2 : 1); 285 286 cv.visitInsn(AASTORE); 288 } 289 290 cv.visitFieldInsn(GETSTATIC, this.stubClassFullName.replace('.', '/'), 293 FUNCTIONAL_INTERFACE_NAME_FIELD_NAME, FUNCTIONAL_INTERFACE_NAME_TYPE); 294 295 cv.visitMethodInsn(INVOKESTATIC, 296 "org/objectweb/proactive/core/mop/MethodCall", 297 "getComponentMethodCall", 298 "(" + METHOD_TYPE + OBJECT_ARRAY_TYPE + 299 FUNCTIONAL_INTERFACE_NAME_TYPE + ")" + METHODCALL_TYPE); 300 cv.visitMethodInsn(INVOKEINTERFACE, 303 "org/objectweb/proactive/core/mop/Proxy", "reify", 304 "(" + METHODCALL_TYPE + ")" + OBJECT_TYPE); 305 306 if (m.getReturnType().isPrimitive()) { 309 this.createUnwrappingCode(cv, m.getReturnType()); 310 } else { 311 cv.visitTypeInsn(CHECKCAST, Type.getInternalName(m.getReturnType())); 314 } 315 createReturnCode(cv, m.getReturnType()); 316 cv.visitMaxs(0, 0); 318 return cv; 319 } 320 321 protected void createFields() { 322 this.classGenerator.visitField(ACC_PROTECTED, PROXY_FIELD_NAME, 324 PROXY_TYPE, null, null); 325 } 326 327 protected void createStaticVariables() { 328 this.classGenerator.visitField(ACC_PROTECTED | ACC_STATIC, "methods", 331 METHOD_ARRAY_TYPE, null, null); 332 333 this.classGenerator.visitField(ACC_PROTECTED | ACC_STATIC, 335 FUNCTIONAL_INTERFACE_NAME_FIELD_NAME, 336 FUNCTIONAL_INTERFACE_NAME_TYPE, fcInterfaceName, null); 337 } 338 339 protected void createStaticInitializer() throws ClassNotFoundException { 340 CodeVisitor cv = this.classGenerator.visitMethod(ACC_STATIC, 342 "<clinit>", "()V", null, null); 343 344 pushInt(cv, this.methods.length); 348 349 cv.visitTypeInsn(ANEWARRAY, "java/lang/reflect/Method"); 351 352 cv.visitFieldInsn(PUTSTATIC, this.stubClassFullName.replace('.', '/'), 354 "methods", METHOD_ARRAY_TYPE); 355 356 pushInt(cv, interfacesToImplement.size()); 358 359 cv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); 361 362 cv.visitVarInsn(ASTORE, 1); 364 365 for (int i = 0; i < interfacesToImplement.size(); i++) { 367 cv.visitVarInsn(ALOAD, 1); 369 370 pushInt(cv, i); 372 373 String s = ((Class ) interfacesToImplement.elementAt(i)).getName(); 375 cv.visitLdcInsn(s); 376 377 cv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", 379 "(Ljava/lang/String;)Ljava/lang/Class;"); 380 381 cv.visitInsn(AASTORE); 385 } 386 387 for (int i = 0; i < this.methods.length; i++) { 389 cv.visitFieldInsn(GETSTATIC, 391 this.stubClassFullName.replace('.', '/'), "methods", 392 METHOD_ARRAY_TYPE); 393 pushInt(cv, i); 394 395 int indexInClassArray = interfacesToImplement.indexOf(this.methods[i].getDeclaringClass()); 397 if (indexInClassArray == -1) { 398 } 399 400 cv.visitVarInsn(ALOAD, 1); 402 403 pushInt(cv, indexInClassArray); 405 cv.visitInsn(AALOAD); 406 407 cv.visitLdcInsn(this.methods[i].getName()); 410 411 pushInt(cv, this.methods[i].getParameterTypes().length); 416 417 cv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); 419 420 cv.visitVarInsn(ASTORE, 2); 422 423 for (int j = 0; j < this.methods[i].getParameterTypes().length; 425 j++) { 426 Class currentParameter = this.methods[i].getParameterTypes()[j]; 427 428 cv.visitVarInsn(ALOAD, 2); 430 431 pushInt(cv, j); 433 434 if (currentParameter.isPrimitive()) { 437 cv.visitFieldInsn(GETSTATIC, 439 Type.getInternalName(Utils.getWrapperClass( 440 currentParameter)), "TYPE", "Ljava/lang/Class;"); 441 } else { 442 cv.visitLdcInsn(currentParameter.getName()); 444 445 cv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", 447 "forName", "(Ljava/lang/String;)Ljava/lang/Class;"); 448 } 449 450 cv.visitInsn(AASTORE); 452 } 453 454 cv.visitVarInsn(ALOAD, 2); 456 457 cv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", 459 "getDeclaredMethod", 460 "(Ljava/lang/String;[Ljava/lang/Class;)" + METHOD_TYPE); 461 462 cv.visitInsn(AASTORE); 464 } 465 466 cv.visitInsn(RETURN); 468 469 cv.visitMaxs(0, 0); 472 473 return; 474 } 475 476 protected void createGetAndSetProxyMethods() { 477 CodeVisitor cv = this.classGenerator.visitMethod(ACC_PUBLIC, 479 "getProxy", "()" + PROXY_TYPE, null, null); 480 481 cv.visitVarInsn(ALOAD, 0); 483 cv.visitFieldInsn(GETFIELD, this.stubClassFullName.replace('.', '/'), 484 PROXY_FIELD_NAME, PROXY_TYPE); 485 cv.visitInsn(ARETURN); 486 487 cv.visitMaxs(0, 0); 490 491 cv = this.classGenerator.visitMethod(ACC_PUBLIC, "setProxy", 493 "(" + PROXY_TYPE + ")V", null, null); 494 495 cv.visitVarInsn(ALOAD, 0); 497 cv.visitVarInsn(ALOAD, 1); 498 cv.visitFieldInsn(PUTFIELD, this.stubClassFullName.replace('.', '/'), 499 PROXY_FIELD_NAME, PROXY_TYPE); 500 cv.visitInsn(RETURN); 501 502 cv.visitMaxs(0, 0); 505 506 return; 507 } 508 509 protected static int lengthOfType(Class cl) { 510 int result; 511 if (cl.isPrimitive()) { 512 if ((cl.equals(Long.TYPE)) || (cl.equals(Double.TYPE))) { 513 result = 2; 514 } else { 515 result = 1; 516 } 517 } else { 518 result = 1; 519 } 520 return result; 521 } 522 523 526 protected void createDefaultMethods() { 527 createGetAndSetProxyMethods(); 528 } 529 } 530 | Popular Tags |