1 4 package net.sourceforge.pmd.typeresolution; 5 6 import net.sourceforge.pmd.typeresolution.visitors.PMDASMVisitor; 7 8 import org.objectweb.asm.ClassReader; 9 import org.objectweb.asm.ClassWriter; 10 11 import java.io.IOException ; 12 import java.util.HashMap ; 13 import java.util.HashSet ; 14 import java.util.List ; 15 import java.util.Map ; 16 import java.util.Set ; 17 18 public class PMDASMClassLoader extends ClassLoader { 19 20 public PMDASMClassLoader() { 21 } 22 23 public synchronized Class loadClass(String name) throws ClassNotFoundException { 24 return defineClass(name); 25 } 26 27 private Map importedClasses = new HashMap (); 28 29 private Set dontBother = new HashSet (); 30 31 public Map getImportedClasses(String className) { 32 Map ret = (Map ) importedClasses.get(className); 33 return ret == null ? new HashMap () : ret; 34 } 35 36 private Class defineClass(String name) throws ClassNotFoundException { 37 38 if (dontBother.contains(name)) { 39 throw new ClassNotFoundException (name); 40 } 41 try { 42 if (name.startsWith("java.")) { 43 return Class.forName(name); 44 } 45 if (importedClasses.containsKey(name)) { 46 if (super.findLoadedClass(name) != null) { 47 return super.findLoadedClass(name); 48 } 49 } 50 ClassReader reader = new ClassReader(getResourceAsStream(name.replace('.', '/') + ".class")); 51 PMDASMVisitor asmVisitor = new PMDASMVisitor(); 52 reader.accept(asmVisitor, 0); 53 54 List inner = asmVisitor.getInnerClasses(); 55 if (inner != null && !inner.isEmpty()) { 56 for (int ix = 0; ix < inner.size(); ix++) { 57 String str = (String ) inner.get(ix); 58 ClassReader innerReader = new ClassReader(getResourceAsStream(str.replace('.', '/') + ".class")); 59 innerReader.accept(asmVisitor, 0); 60 } 61 } 62 importedClasses.put(name, asmVisitor.getPackages()); 63 ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); 64 reader.accept(writer, 0); 65 66 byte[] byteCode = writer.toByteArray(); 67 return defineClass(name, byteCode, 0, byteCode.length); 68 } catch (ClassNotFoundException e) { 69 dontBother.add(name); 70 throw e; 71 } catch (IOException e) { 72 dontBother.add(name); 73 throw new ClassNotFoundException (name, e); 74 } 75 } 76 } | Popular Tags |