package org.concord.otrunk.asm; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.net.URL; import java.util.ArrayList; import org.concord.framework.otrunk.OTObject; import org.concord.framework.otrunk.otcore.OTClass; import org.concord.framework.otrunk.otcore.OTClassProperty; import org.concord.otrunk.AbstractOTObject; import org.objectweb.asm.ClassAdapter; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; public class GeneratedClassLoader extends ClassLoader { public GeneratedClassLoader(ClassLoader parent) { super(parent); } @SuppressWarnings("unchecked") public Class<? extends AbstractOTObject> generateClass(Class<? extends OTObject> abstractClass, OTClass otClass) throws IOException { String name = abstractClass.getName() + "_Generated"; Class<? extends AbstractOTObject> existingClass = (Class<? extends AbstractOTObject>)findLoadedClass(name); if(existingClass != null){ return existingClass; } URL resource = abstractClass.getClassLoader().getResource(abstractClass.getName().replace(".","/") + ".class"); InputStream resourceAsStream = resource.openStream(); ClassWriter cw = new ClassWriter(0); // TraceClassVisitor cv = new TraceClassVisitor(cw, new PrintWriter(System.out)); ClassAdapter ca = new ImplementOTClassAdapter(cw, abstractClass, otClass); // TraceClassVisitor cv2 = new TraceClassVisitor(ca, new PrintWriter(System.out)); ClassReader cr = new ClassReader(resourceAsStream); cr.accept(ca, 0); byte[] b = cw.toByteArray(); Class<? extends AbstractOTObject> klass = (Class<? extends AbstractOTObject>) defineClass(name, b, 0, b.length); // initialize the static fields with the OTClassProperties ArrayList<OTClassProperty> allClassProperties = otClass.getOTAllClassProperties(); for (OTClassProperty classProperty : allClassProperties) { String staticFieldName = ImplementOTClassAdapter.getStaticFieldName(classProperty.getName()); try { Field declaredField = klass.getDeclaredField(staticFieldName); declaredField.set(null, classProperty); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); continue; } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); continue; } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return klass; } }