1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.clazz.reflect;
17
18 import java.lang.reflect.Constructor;
19
20 import org.apache.commons.clazz.Clazz;
21 import org.apache.commons.clazz.ClazzAccessException;
22 import org.apache.commons.clazz.ClazzLoader;
23 import org.apache.commons.clazz.ModelClazzLoader;
24
25
26
27
28
29
30 public abstract class ReflectedClazzLoader extends ClazzLoader {
31
32 private ClassLoader classLoader;
33
34 public ReflectedClazzLoader(
35 ModelClazzLoader modelClazzLoader,
36 ClassLoader classLoader)
37 {
38 super(modelClazzLoader);
39 this.classLoader = classLoader;
40 }
41
42 public String getClazzName(Object instance) {
43 if (instance == null) {
44 return null;
45 }
46 return Clazz.getCanonicalClassName(instance.getClass());
47 }
48
49 public Clazz getClazzForName(String name) {
50 Class javaClass = null;
51 try {
52 if (classLoader != null) {
53 javaClass = classLoader.loadClass(name);
54 }
55 else {
56 javaClass = Class.forName(name);
57 }
58 }
59 catch (ClassNotFoundException ex) {
60
61 }
62
63 if (javaClass == null) {
64 try {
65 javaClass = getClazzForCanonicalName(classLoader, name);
66 }
67 catch (ClassNotFoundException ex) {
68
69 }
70 }
71 if (javaClass == null) {
72 return null;
73 }
74
75 if (javaClass.isArray()) {
76
77 }
78 else {
79 Clazz clazz = lookupCustomClazz(javaClass);
80 if (clazz != null) {
81 return clazz;
82 }
83 }
84 if (!isSupportedClass(javaClass)) {
85 return null;
86 }
87 return createClazz(javaClass);
88 }
89
90
91
92
93
94
95
96
97
98
99
100 protected Clazz lookupCustomClazz(Class javaClass) {
101 if (javaClass.isPrimitive()) {
102 return null;
103 }
104
105 String customClazzName = javaClass.getName() + getModel() + "Clazz";
106
107 Class customClazzClass;
108 try {
109 if (classLoader == null) {
110 classLoader = getClass().getClassLoader();
111 }
112 if (classLoader != null) {
113 customClazzClass = classLoader.loadClass(customClazzName);
114 }
115 else {
116 customClazzClass = Class.forName(customClazzName);
117 }
118 }
119 catch (ClassNotFoundException e) {
120 return null;
121 }
122
123 if (!Clazz.class.isAssignableFrom(customClazzClass)) {
124 return null;
125 }
126
127 Constructor constructor;
128 try {
129 constructor =
130 customClazzClass.getConstructor(
131 new Class[] { ClazzLoader.class, Class.class });
132 if (constructor == null) {
133 return null;
134 }
135 }
136 catch (NoSuchMethodException e) {
137 return null;
138 }
139
140 try {
141 return (Clazz) constructor.newInstance(
142 new Object[] { getModelClazzLoader(), javaClass });
143 }
144 catch (Exception e) {
145 throw new ClazzAccessException(
146 "Cannot instantiate custom ReflectedClazz " + customClazzName,
147 e);
148 }
149 }
150
151
152
153
154
155
156 private static Class getClazzForCanonicalName(
157 ClassLoader classLoader,
158 String name)
159 throws ClassNotFoundException
160 {
161 int arrayDepth = 0;
162 while (name.endsWith("[]")) {
163 arrayDepth++;
164 name = name.substring(0, name.length() - 2);
165 }
166
167 if (name.equals("boolean")) {
168 return getPrimitiveType(classLoader, arrayDepth, Boolean.TYPE, 'Z');
169 }
170 else if (name.equals("byte")) {
171 return getPrimitiveType(classLoader, arrayDepth, Byte.TYPE, 'B');
172 }
173 else if (name.equals("char")) {
174 return
175 getPrimitiveType(classLoader, arrayDepth, Character.TYPE, 'C');
176 }
177 else if (name.equals("short")) {
178 return getPrimitiveType(classLoader, arrayDepth, Short.TYPE, 'S');
179 }
180 else if (name.equals("int")) {
181 return getPrimitiveType(classLoader, arrayDepth, Integer.TYPE, 'I');
182 }
183 else if (name.equals("long")) {
184 return getPrimitiveType(classLoader, arrayDepth, Long.TYPE, 'J');
185 }
186 else if (name.equals("float")) {
187 return getPrimitiveType(classLoader, arrayDepth, Float.TYPE, 'F');
188 }
189 else if (name.equals("double")) {
190 return getPrimitiveType(classLoader, arrayDepth, Double.TYPE, 'D');
191 }
192 if (arrayDepth != 0) {
193 StringBuffer buffer = new StringBuffer();
194 for (int i = 0; i < arrayDepth; i++) {
195 buffer.append('[');
196 }
197 buffer.append('L');
198 buffer.append(name);
199 buffer.append(';');
200 name = buffer.toString();
201 }
202
203 if (classLoader != null) {
204 return classLoader.loadClass(name);
205 }
206 else {
207 return Class.forName(name);
208 }
209 }
210
211
212
213
214
215 private static Class getPrimitiveType(
216 ClassLoader classLoader,
217 int arrayDepth,
218 Class primitiveType,
219 char typeLetter)
220 throws ClassNotFoundException
221 {
222 if (arrayDepth == 0) {
223 return primitiveType;
224 }
225
226 StringBuffer buffer = new StringBuffer();
227 for (int i = 0; i < arrayDepth; i++) {
228 buffer.append('[');
229 }
230 buffer.append(typeLetter);
231 String name = buffer.toString();
232
233 if (classLoader != null) {
234 return classLoader.loadClass(name);
235 }
236 else {
237 return Class.forName(name);
238 }
239 }
240
241
242
243
244
245
246 public boolean isMember(Object instance) {
247 if (instance == null) {
248 return false;
249 }
250 return isSupportedClass(instance.getClass());
251 }
252
253
254
255
256 protected boolean isSupportedClass(Class javaClass) {
257 return true;
258 }
259
260
261
262
263
264
265
266 protected abstract Clazz createClazz(Class javaClass);
267
268
269
270
271 public Clazz defineClazz(
272 String name,
273 Class clazzClass,
274 Class instanceClass)
275 {
276 return null;
277 }
278 }