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