1
2
3
4
5
6
7
8
9
10 package org.mule.util.scan;
11
12 import org.mule.util.scan.annotations.ClosableClassReader;
13
14 import java.io.IOException;
15 import java.io.InputStream;
16 import java.net.URL;
17
18 import org.objectweb.asm.ClassReader;
19 import org.objectweb.asm.commons.EmptyVisitor;
20
21
22
23
24 public class InterfaceClassScanner extends EmptyVisitor implements ClassScanner
25 {
26 private Class interfaceClass;
27
28 private boolean match;
29
30 private String className;
31
32 private ClassLoader classLoader;
33
34 public InterfaceClassScanner(Class interfaceClass)
35 {
36 this(interfaceClass, Thread.currentThread().getContextClassLoader());
37 }
38
39 public InterfaceClassScanner(Class interfaceClass, ClassLoader classLoader)
40 {
41 if(!interfaceClass.isInterface())
42 {
43 throw new IllegalArgumentException("The class need to be an interface");
44 }
45 this.interfaceClass = interfaceClass;
46
47 this.classLoader = classLoader;
48 }
49
50 public void visit(int i, int i1, String s, String s1, String superName, String[] interfaces)
51 {
52 if (interfaces != null && interfaces.length > 0)
53 {
54 for (int j = 0; j < interfaces.length; j++)
55 {
56 String anInterface = interfaces[j].replace("/", ".");
57 if (interfaceClass.getName().equals(anInterface))
58 {
59 match = true;
60 className = s;
61 break;
62 }
63 else
64 {
65
66 ClassScanner scanner = scan(anInterface);
67 match = scanner.isMatch();
68 className = s;
69 }
70
71 }
72 }
73
74 else if (superName == null)
75 {
76 return;
77 }
78 else
79 {
80
81 ClassScanner scanner = scan(superName);
82 match = scanner.isMatch();
83 className = scanner.getClassName();
84
85 if(match)
86 {
87 className = s;
88 }
89 }
90 }
91
92 protected ClassScanner scan(String name)
93 {
94 try
95 {
96 InterfaceClassScanner scanner = new InterfaceClassScanner(interfaceClass, classLoader);
97 URL classURL = getClassURL(name);
98 if(classURL==null)
99 {
100 throw new RuntimeException("Failed to read class URL for name: " + name);
101 }
102 InputStream classStream = classURL.openStream();
103 ClassReader r = new ClosableClassReader(classStream);
104
105 r.accept(scanner, 0);
106 return scanner;
107 }
108 catch (IOException e)
109 {
110 throw new RuntimeException(name, e);
111 }
112 }
113
114 public boolean isMatch()
115 {
116 return match;
117 }
118
119 public String getClassName()
120 {
121 return className;
122 }
123
124 public URL getClassURL(String className)
125 {
126 String resource = className.replace(".", "/") + ".class";
127 return classLoader.getResource(resource);
128 }
129 }