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