1 25 26 package org.objectweb.easybeans.enhancer; 27 28 import static org.objectweb.easybeans.enhancer.injection.InjectionClassAdapter.JAVA_LANG_OBJECT; 29 30 import java.io.IOException ; 31 import java.io.InputStream ; 32 import java.util.List ; 33 import java.util.Map ; 34 35 import org.objectweb.asm.ClassReader; 36 import org.objectweb.asm.ClassWriter; 37 import org.objectweb.easybeans.deployment.annotations.metadata.ClassAnnotationMetadata; 38 import org.objectweb.easybeans.deployment.annotations.metadata.EjbJarAnnotationMetadata; 39 import org.objectweb.easybeans.enhancer.bean.BeanClassAdapter; 40 import org.objectweb.easybeans.enhancer.injection.InjectionClassAdapter; 41 import org.objectweb.easybeans.enhancer.interceptors.InterceptorClassAdapter; 42 import org.objectweb.easybeans.loader.EasyBeansClassLoader; 43 import org.objectweb.easybeans.log.JLog; 44 import org.objectweb.easybeans.log.JLogFactory; 45 46 51 public class Enhancer { 52 53 56 private static JLog logger = JLogFactory.getLog(Enhancer.class); 57 58 61 private EjbJarAnnotationMetadata ejbJarAnnotationMetadata = null; 62 63 66 private ClassLoader loader = null; 67 68 71 private Map <String , Object > map = null; 72 73 79 public Enhancer(final ClassLoader loader, final EjbJarAnnotationMetadata ejbJarAnnotationMetadata, 80 final Map <String , Object > map) { 81 this.loader = loader; 82 this.ejbJarAnnotationMetadata = ejbJarAnnotationMetadata; 83 this.map = map; 84 } 85 86 90 public void enhance() throws EnhancerException { 91 92 for (ClassAnnotationMetadata classAnnotationMetadata : ejbJarAnnotationMetadata 94 .getClassAnnotationMetadataCollection()) { 95 if (classAnnotationMetadata.isInterceptor() && !classAnnotationMetadata.isBean() 96 && !classAnnotationMetadata.wasModified()) { 97 logger.debug("ClassAdapter on interceptor : {0}", classAnnotationMetadata.getClassName()); 98 99 enhanceSuperClass(classAnnotationMetadata); 102 103 ClassReader cr = getClassReader(classAnnotationMetadata); 105 ClassWriter cw = new ClassWriter(true); 106 InterceptorClassAdapter cv = new InterceptorClassAdapter(classAnnotationMetadata, cw); 107 InjectionClassAdapter cv2 = new InjectionClassAdapter(classAnnotationMetadata, cv, map, false); 108 cr.accept(cv2, false); 109 classAnnotationMetadata.setModified(); 110 defineClass(loader, classAnnotationMetadata.getClassName().replace("/", "."), cw.toByteArray()); 111 } 112 } 113 for (ClassAnnotationMetadata classAnnotationMetadata : ejbJarAnnotationMetadata 115 .getClassAnnotationMetadataCollection()) { 116 if (classAnnotationMetadata.isBean()) { 117 118 enhanceSuperClass(classAnnotationMetadata); 121 122 123 ClassReader cr = getClassReader(classAnnotationMetadata); 125 ClassWriter cw = new ClassWriter(true); 126 BeanClassAdapter cv = new BeanClassAdapter(classAnnotationMetadata, cw); 127 InterceptorClassAdapter itcpClassAdapter = new InterceptorClassAdapter(classAnnotationMetadata, cv); 128 InjectionClassAdapter cv2 = new InjectionClassAdapter(classAnnotationMetadata, itcpClassAdapter, map, false); 129 cr.accept(cv2, false); 130 131 loadDefinedClasses(loader, itcpClassAdapter.getDefinedClasses()); 133 134 defineClass(loader, classAnnotationMetadata.getClassName().replace("/", "."), cw.toByteArray()); 135 136 } 137 138 } 139 } 140 141 142 147 protected void enhanceSuperClass(final ClassAnnotationMetadata classAnnotationMetadata) throws EnhancerException { 148 String superClass = classAnnotationMetadata.getSuperName(); 151 if (!superClass.equals(JAVA_LANG_OBJECT)) { 152 ClassAnnotationMetadata superMetaData = ejbJarAnnotationMetadata.getClassAnnotationMetadata(superClass); 153 if (superMetaData != null && !superMetaData.wasModified()) { 154 ClassReader cr = getClassReader(superMetaData); 155 ClassWriter cw = new ClassWriter(true); 156 InjectionClassAdapter cv = new InjectionClassAdapter(superMetaData, cw, map, false); 157 cr.accept(cv, false); 158 superMetaData.setModified(); 159 defineClass(loader, superMetaData.getClassName().replace("/", "."), cw.toByteArray()); 160 enhanceSuperClass(superMetaData); 161 } 162 } 163 164 } 165 166 171 private static void loadDefinedClasses(final ClassLoader loader, final List <DefinedClass> lst) { 172 if (lst != null) { 173 for (DefinedClass definedClass : lst) { 174 defineClass(loader, definedClass.getClassName(), definedClass.getBytes()); 175 } 176 } 177 } 178 179 180 186 protected ClassReader getClassReader(final ClassAnnotationMetadata classAnnotationMetadata) 187 throws EnhancerException { 188 String className = classAnnotationMetadata.getClassName() + ".class"; 189 InputStream is = loader.getResourceAsStream(className); 190 if (is == null) { 191 throw new EnhancerException("Cannot find input stream in classloader " + loader + " for class " + className); 192 } 193 ClassReader cr = null; 194 try { 195 cr = new ClassReader(is); 196 } catch (IOException e) { 197 throw new EnhancerException("Cannot load input stream for class '" + className + "' in classloader '" 198 + loader); 199 } 200 return cr; 201 } 202 203 209 public static void defineClass(final ClassLoader loader, final String className, final byte[] b) { 210 if (loader instanceof EasyBeansClassLoader) { 211 ((EasyBeansClassLoader) loader).addClassDefinition(className, b); 212 } else { 213 try { 216 Class cls = Class.forName("java.lang.ClassLoader"); 218 java.lang.reflect.Method method = cls.getDeclaredMethod("defineClass", new Class [] {String .class, 219 byte[].class, int.class, int.class}); 220 221 method.setAccessible(true); 223 try { 224 Object [] args = new Object [] {className, b, new Integer (0), new Integer (b.length)}; 225 method.invoke(loader, args); 226 } finally { 227 method.setAccessible(false); 228 } 229 } catch (Exception e) { 230 throw new RuntimeException (e); 231 } 232 } 233 234 235 } 236 237 240 protected EjbJarAnnotationMetadata getEjbJarAnnotationMetadata() { 241 return ejbJarAnnotationMetadata; 242 } 243 244 247 protected Map <String , Object > getMap() { 248 return map; 249 } 250 251 254 protected ClassLoader getClassLoader() { 255 return loader; 256 } 257 258 } 259 | Popular Tags |