1
2
3
4 package net.sourceforge.pmd.lang.java.typeresolution;
5
6 import java.io.IOException;
7 import java.util.ArrayList;
8 import java.util.HashSet;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Set;
12
13 import net.sourceforge.pmd.lang.java.typeresolution.visitors.PMDASMVisitor;
14
15 import org.objectweb.asm.ClassReader;
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 public final class PMDASMClassLoader extends ClassLoader {
32
33 private static PMDASMClassLoader cachedPMDASMClassLoader;
34 private static ClassLoader cachedClassLoader;
35
36
37
38
39
40
41 public static synchronized PMDASMClassLoader getInstance(ClassLoader parent) {
42 if (parent.equals(cachedClassLoader)) {
43 return cachedPMDASMClassLoader;
44 }
45 cachedClassLoader = parent;
46 cachedPMDASMClassLoader = new PMDASMClassLoader(parent);
47 return cachedPMDASMClassLoader;
48 }
49
50
51
52 private PMDASMClassLoader(ClassLoader parent) {
53 super(parent);
54 }
55
56
57 private final Set<String> dontBother = new HashSet<String>();
58
59 @Override
60 public synchronized Class<?> loadClass(String name) throws ClassNotFoundException {
61 if (dontBother.contains(name)) {
62 throw new ClassNotFoundException(name);
63 }
64 try {
65 return super.loadClass(name);
66 } catch (ClassNotFoundException e) {
67 dontBother.add(name);
68 throw e;
69 } catch (NoClassDefFoundError e) {
70 dontBother.add(name);
71
72
73
74 throw new ClassNotFoundException(name, e);
75 }
76 }
77
78 public synchronized Map<String, String> getImportedClasses(String name) throws ClassNotFoundException {
79
80 if (dontBother.contains(name)) {
81 throw new ClassNotFoundException(name);
82 }
83 try {
84 ClassReader reader = new ClassReader(getResourceAsStream(name.replace('.', '/') + ".class"));
85 PMDASMVisitor asmVisitor = new PMDASMVisitor();
86 reader.accept(asmVisitor, 0);
87
88 List<String> inner = asmVisitor.getInnerClasses();
89 if (inner != null && !inner.isEmpty()) {
90 inner = new ArrayList<String>(inner);
91
92 for (String str : inner) {
93 reader = new ClassReader(getResourceAsStream(str.replace('.', '/') + ".class"));
94 reader.accept(asmVisitor, 0);
95 }
96 }
97 return asmVisitor.getPackages();
98 } catch (IOException e) {
99 dontBother.add(name);
100 throw new ClassNotFoundException(name, e);
101 }
102 }
103 }