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 class PMDASMClassLoader extends ClassLoader {
32
33 private static PMDASMClassLoader cachedPMDASMClassLoader;
34 private static ClassLoader cachedClassLoader;
35
36
37
38
39
40 public static synchronized PMDASMClassLoader getInstance(ClassLoader parent) {
41 if (parent == cachedClassLoader) return cachedPMDASMClassLoader;
42 cachedClassLoader = parent;
43 cachedPMDASMClassLoader = new PMDASMClassLoader(parent);
44 return cachedPMDASMClassLoader;
45 }
46
47
48
49 private PMDASMClassLoader(ClassLoader parent) {
50 super(parent);
51 }
52
53
54 private final Set<String> dontBother = new HashSet<String>();
55
56 @Override
57 public synchronized Class<?> loadClass(String name) throws ClassNotFoundException {
58 if (dontBother.contains(name)) {
59 throw new ClassNotFoundException(name);
60 }
61 try {
62 return super.loadClass(name);
63 } catch (ClassNotFoundException e) {
64 dontBother.add(name);
65 throw e;
66 }
67 }
68
69 public synchronized Map<String, String> getImportedClasses(String name) throws ClassNotFoundException {
70
71 if (dontBother.contains(name)) {
72 throw new ClassNotFoundException(name);
73 }
74 try {
75 ClassReader reader = new ClassReader(getResourceAsStream(name.replace('.', '/') + ".class"));
76 PMDASMVisitor asmVisitor = new PMDASMVisitor();
77 reader.accept(asmVisitor, 0);
78
79 List<String> inner = asmVisitor.getInnerClasses();
80 if (inner != null && !inner.isEmpty()) {
81 inner = new ArrayList<String>(inner);
82 for (String str: inner) {
83 reader = new ClassReader(getResourceAsStream(str.replace('.', '/') + ".class"));
84 reader.accept(asmVisitor, 0);
85 }
86 }
87 return asmVisitor.getPackages();
88 } catch (IOException e) {
89 dontBother.add(name);
90 throw new ClassNotFoundException(name, e);
91 }
92 }
93 }