1 22 package org.jboss.aop; 23 24 import java.util.Map ; 25 26 import org.jboss.aop.classpool.AOPClassPool; 27 import org.jboss.aop.instrument.Instrumentor; 28 import org.jboss.aop.instrument.InstrumentorFactory; 29 30 import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap; 31 import javassist.ByteArrayClassPath; 32 import javassist.ClassPool; 33 import javassist.CtClass; 34 import javassist.NotFoundException; 35 36 44 public class SuperClassesFirstWeavingStrategy extends WeavingStrategySupport { 45 46 private boolean verbose = AspectManager.verbose; 47 public static final String AOP_PACKAGE = Advised.class.getPackage().getName(); 48 49 public byte[] translate(AspectManager manager, String className, ClassLoader loader, byte[] classfileBuffer) throws Exception 50 { 51 if (isReEntry()) 52 { 53 return null; 54 } 55 setReEntry(); 56 manager.transformationStarted = true; 57 try 58 { 59 if (manager.isNonAdvisableClassName(className)) 60 { 61 return null; 62 } 63 64 AOPClassPool pool = (AOPClassPool) manager.registerClassLoader(loader); 65 66 CtClassTransformationInfo info = obtainCtClassInfo(pool, className, classfileBuffer); 67 CtClass clazz = instrumentClass(manager, pool, info, true); 68 if (clazz != null) 69 { 70 pool.lockInCache(info.getClazz()); 71 if (AspectManager.debugClasses) 72 { 73 info.getClazz().debugWriteFile(); 74 } 75 byte[] rtn = info.getClazz().toBytecode(); 76 if (AspectManager.getPrune()) info.getClazz().prune(); 77 return rtn; 78 } 79 else 80 { 81 pool.soften(info.getClazz()); 82 } 83 return null; 84 } 85 catch (Exception ex) 86 { 87 if (!(ex instanceof NotFoundException)) 88 { 89 if (verbose) 90 ex.printStackTrace(); 91 else 92 System.err.println("[error] " + ex.getMessage() + 93 ".. Do verbose mode if you want full stack trace."); 94 95 } 96 throw ex; 97 } 98 finally 99 { 100 clearReEntry(); 101 } 102 } 103 104 private CtClassTransformationInfo obtainCtClassInfo(AOPClassPool pool, String className, byte[] classfileBuffer) throws NotFoundException 105 { 106 try 107 { 108 return new CtClassTransformationInfo(pool.getLocally(className), className); 109 } 110 catch (NotFoundException e) 111 { 112 ByteArrayClassPath cp = new ByteArrayClassPath(className, classfileBuffer); 115 pool.insertClassPath(cp); 116 return new CtClassTransformationInfo(pool.getLocally(className), className); 117 } 118 catch(Error e) 119 { 120 return null; 121 } 122 } 123 124 private CtClass instrumentClass(AspectManager manager, AOPClassPool pool, CtClassTransformationInfo info, boolean isLoadedClass) throws NotFoundException, Exception 125 { 126 try 127 { 128 CtClass superClass = info.getClazz().getSuperclass(); 129 if (superClass != null && !Instrumentor.implementsAdvised(info.getClazz())) 130 { 131 CtClassTransformationInfo superInfo = new CtClassTransformationInfo(superClass, superClass.getName()); 132 133 ClassPool superPool = superClass.getClassPool(); 134 if (superPool instanceof AOPClassPool) 135 { 136 AspectManager aspectManager = manager; 137 if (manager instanceof Domain && superPool != pool) 138 { 139 aspectManager = AspectManager.instance(superPool.getClassLoader()); 141 } 142 instrumentClass(aspectManager, (AOPClassPool)superPool, superInfo, false); 143 } 144 } 145 146 if (manager.isNonAdvisableClassName(info.getClassName())) 147 { 148 return null; 149 } 150 151 if (info.getClass().isArray()) 152 { 153 if (verbose) System.out.println("[cannot compile] isArray: " + info.getClassName()); 154 pool.flushClass(info.getClassName()); 155 return null; 156 } 157 if (info.getClazz().isInterface()) 158 { 159 if (verbose) System.out.println("[cannot compile] isInterface: " + info.getClassName()); 160 info.getClazz().prune(); 162 return null; 163 } 164 if (info.getClazz().isFrozen()) 165 { 166 if(isAdvised(pool, info.getClazz())) 167 return null; 168 if (verbose) System.out.println("[warning] isFrozen: " + info.getClassName() + " " + info.getClazz().getClassPool()); 169 if (!isLoadedClass) 170 { 171 info = obtainCtClassInfo(pool, info.getClassName(), null); 172 } 173 else 174 return null; 175 } 177 178 boolean transformed = info.getClazz().isModified(); 179 if (!transformed) 180 { 181 ClassAdvisor advisor = 182 AdvisorFactory.getClassAdvisor(info.getClazz(), manager); 183 Instrumentor instrumentor = InstrumentorFactory.getInstrumentor( 184 pool, 185 manager, 186 manager.dynamicStrategy.getJoinpointClassifier(), 187 manager.dynamicStrategy.getDynamicTransformationObserver(info.getClazz())); 188 189 if (!Instrumentor.isTransformable(info.getClazz())) 190 { 191 if (verbose) System.out.println("[cannot compile] implements Untransformable: " + info.getClassName()); 192 return null; 195 } 196 197 manager.attachMetaData(advisor, info.getClazz(), true); 198 manager.applyInterfaceIntroductions(advisor, info.getClazz()); 199 transformed = instrumentor.transform(info.getClazz(), advisor); 200 } 201 if (transformed) 202 { 203 if (!isLoadedClass ) 204 { 205 info.setTransformed(transformed); 206 } 207 return info.getClazz(); 208 } 209 return null; 210 } 211 catch(Exception e) 212 { 213 throw new RuntimeException ("Error converting class ", e); 214 } 215 finally 216 { 217 } 218 } 219 220 public boolean isAdvised(ClassPool pool, CtClass clazz) throws NotFoundException 221 { 222 CtClass[] interfaces = clazz.getInterfaces(); 223 CtClass advised = pool.get(AOP_PACKAGE + ".Advised"); 224 for (int i = 0; i < interfaces.length; i++) 225 { 226 if (interfaces[i].equals(advised)) return true; 227 if (interfaces[i].getName().equals(AOP_PACKAGE + ".Advised")) return true; 228 } 229 return false; 230 } 231 232 233 private class CtClassTransformationInfo 234 { 235 boolean transformed; 236 CtClass clazz; 237 String className; 238 private CtClassTransformationInfo(CtClass clazz, String className) 239 { 240 this.clazz = clazz; 241 this.className = className; 242 } 243 244 private CtClassTransformationInfo(CtClass clazz, String className, boolean transformed) 245 { 246 this.clazz = clazz; 247 this.className = className; 248 this.transformed = transformed; 249 } 250 251 private CtClass getClazz() 252 { 253 return clazz; 254 } 255 256 private boolean isTransformed() 257 { 258 return transformed; 259 } 260 261 private void setTransformed(boolean transformed) 262 { 263 this.transformed = transformed; 264 } 265 266 private String getClassName() 267 { 268 return className; 269 } 270 } 271 272 273 } 274 | Popular Tags |