01: /**
02: * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03: */package net.sourceforge.pmd.typeresolution;
04:
05: import net.sourceforge.pmd.typeresolution.visitors.PMDASMVisitor;
06:
07: import org.objectweb.asm.ClassReader;
08:
09: import java.io.IOException;
10: import java.util.LinkedList;
11: import java.util.HashSet;
12: import java.util.List;
13: import java.util.Map;
14: import java.util.Set;
15:
16: /*
17: * I've refactored this class to not cache the results any more. This is a
18: * tradeoff in testing I've found the CPU tradeoff is negligeable. With the
19: * cache, large codebases consumed a lot of memory and slowed down greatly when
20: * approaching 3,000 classes. I'm adding this comment in case someone is looking
21: * at this code and thinks a cache may help.
22: */
23: public class PMDASMClassLoader extends ClassLoader {
24:
25: public PMDASMClassLoader(ClassLoader parent) {
26: super (parent);
27: }
28:
29: private Set<String> dontBother = new HashSet<String>();
30:
31: public synchronized Map<String, String> getImportedClasses(
32: String name) throws ClassNotFoundException {
33:
34: if (dontBother.contains(name)) {
35: throw new ClassNotFoundException(name);
36: }
37: try {
38: ClassReader reader = new ClassReader(
39: getResourceAsStream(name.replace('.', '/')
40: + ".class"));
41: PMDASMVisitor asmVisitor = new PMDASMVisitor();
42: reader.accept(asmVisitor, 0);
43:
44: List<String> inner = asmVisitor.getInnerClasses();
45: if (inner != null && !inner.isEmpty()) {
46: inner = new LinkedList<String>(inner); // to avoid ConcurrentModificationException
47: for (String str : inner) {
48: reader = new ClassReader(getResourceAsStream(str
49: .replace('.', '/')
50: + ".class"));
51: reader.accept(asmVisitor, 0);
52: }
53: }
54: return asmVisitor.getPackages();
55: } catch (IOException e) {
56: dontBother.add(name);
57: throw new ClassNotFoundException(name);
58: }
59: }
60: }
|