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 44 import java.io.Serializable ; 45 46 import java.lang.reflect.Method ; 47 48 import java.util.Hashtable ; 49 import java.util.Vector ; 50 51 52 68 public class MetaObjectInterfaceClassGenerator 69 extends AbstractInterfaceClassGenerator { 70 protected static Logger logger = Logger.getLogger(MetaObjectInterfaceClassGenerator.class.getName()); 71 protected static final String IMPL_FIELD_NAME = "impl"; private static MetaObjectInterfaceClassGenerator instance; 73 74 private static Hashtable generatedClassesCache = new Hashtable (); 76 77 protected Class cl; 80 protected String className; 81 protected String packageName; 82 83 protected boolean isPrimitive = false; 85 86 public MetaObjectInterfaceClassGenerator() { 87 this.cl = ProActiveInterface.class; 91 92 this.className = cl.getName(); 94 95 } 97 98 public static MetaObjectInterfaceClassGenerator instance() { 99 if (instance == null) { 100 return new MetaObjectInterfaceClassGenerator(); 101 } else { 102 return instance; 103 } 104 } 105 106 109 public static byte[] getClassData(String classname) { 110 return (byte[]) getGeneratedClassesCache().get(classname); 111 } 112 113 117 public static Hashtable getGeneratedClassesCache() { 118 return generatedClassesCache; 119 } 120 121 public ProActiveInterface generateInterface(final String fcInterfaceName, 122 Component owner, InterfaceType interfaceType, boolean isInternal, 123 boolean isPrimitive) throws InterfaceGenerationFailedException { 124 try { 125 if (logger.isDebugEnabled()) { 126 logger.debug("generating metaobject interface reference"); 127 } 128 129 interfacesToImplement = new Vector (); 131 132 interfacesToImplement.add(Class.forName( 134 interfaceType.getFcItfSignature())); 135 136 interfacesToImplement.addElement(Serializable .class); 138 139 this.stubClassFullName = org.objectweb.proactive.core.component.asmgen.Utils.getMetaObjectClassName(fcInterfaceName, 140 interfaceType.getFcItfSignature()); 141 142 Class generated_class; 143 144 try { 146 generated_class = loadClass(stubClassFullName); 147 } catch (ClassNotFoundException cnfe) { 148 byte[] bytes; 149 setInfos(); 150 bytes = create(); 151 getGeneratedClassesCache().put(stubClassFullName, bytes); 152 if (logger.isDebugEnabled()) { 153 logger.debug("added " + stubClassFullName + " to cache"); 154 logger.debug("generated classes cache is : " + 155 getGeneratedClassesCache().toString()); 156 } 157 158 generated_class = defineClass(stubClassFullName, bytes); 172 } 173 174 ProActiveInterface reference = (ProActiveInterface) generated_class.newInstance(); 175 reference.setName(fcInterfaceName); 176 reference.setOwner(owner); 177 reference.setType(interfaceType); 178 reference.setIsInternal(isInternal); 179 180 return reference; 181 } catch (ClassNotFoundException e) { 182 throw new InterfaceGenerationFailedException("cannot find interface signature class", 183 e); 184 } catch (IllegalAccessException e) { 185 throw new InterfaceGenerationFailedException("constructor not accessible", 186 e); 187 } catch (InstantiationException e) { 188 throw new InterfaceGenerationFailedException("constructor belongs to an abstract class?", 189 e); 190 } 191 } 192 193 protected void createGetAndSetFcItfImplMethods() { 194 CodeVisitor cv = this.classGenerator.visitMethod(ACC_PUBLIC, 196 "getFcItfImpl", "()" + OBJECT_TYPE, null, null); 197 198 cv.visitVarInsn(ALOAD, 0); 200 cv.visitFieldInsn(GETFIELD, this.stubClassFullName.replace('.', '/'), 201 IMPL_FIELD_NAME, OBJECT_TYPE); 202 cv.visitInsn(ARETURN); 203 204 cv.visitMaxs(0, 0); 207 208 cv = this.classGenerator.visitMethod(ACC_PUBLIC, "setFcItfImpl", 210 "(" + OBJECT_TYPE + ")V", null, null); 211 212 cv.visitVarInsn(ALOAD, 0); 214 cv.visitVarInsn(ALOAD, 1); 215 216 cv.visitFieldInsn(PUTFIELD, this.stubClassFullName.replace('.', '/'), 218 IMPL_FIELD_NAME, OBJECT_TYPE); 219 cv.visitInsn(RETURN); 220 221 cv.visitMaxs(0, 0); 224 225 return; 226 } 227 228 protected CodeVisitor createMethod(int methodIndex, Method m) { 229 String itf = Type.getInternalName(m.getDeclaringClass()); 230 String method_name = m.getName(); 231 String method_descriptor = Type.getMethodDescriptor(m); 232 CodeVisitor cv = createMethodGenerator(m); 233 234 cv.visitVarInsn(ALOAD, 0); 237 cv.visitFieldInsn(GETFIELD, this.stubClassFullName.replace('.', '/'), 238 IMPL_FIELD_NAME, OBJECT_TYPE); 239 240 if (interfacesToImplement.size() > 1) { 242 cv.visitTypeInsn(CHECKCAST, itf); 243 } 244 245 Class [] paramTypes = m.getParameterTypes(); 247 int offset = 1; 248 for (int i = 0; i < paramTypes.length; ++i) { 249 cv.visitVarInsn(ILOAD + getOpcodeOffset(paramTypes[i]), offset); 250 offset += getSize(paramTypes[i]); 251 } 252 253 cv.visitMethodInsn(INVOKEINTERFACE, itf, method_name, method_descriptor); 255 256 createReturnCode(cv, m.getReturnType()); 258 259 cv.visitMaxs(0, 0); 261 return cv; 262 } 263 264 protected void createFields() { 265 this.classGenerator.visitField(ACC_PROTECTED, IMPL_FIELD_NAME, 267 OBJECT_TYPE, null, null); 268 } 269 270 protected void createStaticVariables() { 271 } 273 274 protected void createStaticInitializer() throws ClassNotFoundException { 275 } 276 277 280 protected void createDefaultMethods() { 281 createGetAndSetFcItfImplMethods(); 282 } 283 } 284 | Popular Tags |