author | mkos |
Mon, 31 Mar 2014 10:43:20 +0200 | |
changeset 23782 | 953bfc3fbe31 |
parent 22427 | 1f8304cd1d53 |
child 25685 | c4d4cbb36e12 |
permissions | -rw-r--r-- |
12009 | 1 |
/* |
23782
953bfc3fbe31
8036030: Update JAX-WS RI integration to latest version
mkos
parents:
22427
diff
changeset
|
2 |
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
12009 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. Oracle designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Oracle in the LICENSE file that accompanied this code. |
|
10 |
* |
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
24 |
*/ |
|
25 |
||
26 |
package com.sun.xml.internal.bind.v2.model.nav; |
|
27 |
||
28 |
import java.lang.reflect.Array; |
|
29 |
import java.lang.reflect.Field; |
|
30 |
import java.lang.reflect.GenericArrayType; |
|
31 |
import java.lang.reflect.GenericDeclaration; |
|
32 |
import java.lang.reflect.Method; |
|
33 |
import java.lang.reflect.Modifier; |
|
34 |
import java.lang.reflect.ParameterizedType; |
|
35 |
import java.lang.reflect.Type; |
|
36 |
import java.lang.reflect.TypeVariable; |
|
37 |
import java.lang.reflect.WildcardType; |
|
38 |
import java.util.Arrays; |
|
39 |
import java.util.Collection; |
|
40 |
||
41 |
import com.sun.xml.internal.bind.v2.runtime.Location; |
|
42 |
||
43 |
/** |
|
44 |
* {@link Navigator} implementation for {@code java.lang.reflect}. |
|
45 |
* |
|
46 |
*/ |
|
22427 | 47 |
/*package*/final class ReflectionNavigator implements Navigator<Type, Class, Field, Method> { |
48 |
||
49 |
// ---------- Singleton ----------------- |
|
50 |
private static final ReflectionNavigator INSTANCE = new ReflectionNavigator(); |
|
12009 | 51 |
|
22427 | 52 |
/*package*/static ReflectionNavigator getInstance() { |
53 |
return INSTANCE; |
|
12009 | 54 |
} |
55 |
||
22427 | 56 |
private ReflectionNavigator() { |
57 |
} |
|
58 |
// --------------------------------------- |
|
59 |
||
12009 | 60 |
public Class getSuperClass(Class clazz) { |
61 |
if (clazz == Object.class) { |
|
62 |
return null; |
|
63 |
} |
|
64 |
Class sc = clazz.getSuperclass(); |
|
65 |
if (sc == null) { |
|
66 |
sc = Object.class; // error recovery |
|
67 |
} |
|
68 |
return sc; |
|
69 |
} |
|
22427 | 70 |
|
12009 | 71 |
private static final TypeVisitor<Type, Class> baseClassFinder = new TypeVisitor<Type, Class>() { |
72 |
||
73 |
public Type onClass(Class c, Class sup) { |
|
74 |
// t is a raw type |
|
75 |
if (sup == c) { |
|
76 |
return sup; |
|
77 |
} |
|
78 |
||
79 |
Type r; |
|
80 |
||
81 |
Type sc = c.getGenericSuperclass(); |
|
82 |
if (sc != null) { |
|
83 |
r = visit(sc, sup); |
|
84 |
if (r != null) { |
|
85 |
return r; |
|
86 |
} |
|
87 |
} |
|
88 |
||
89 |
for (Type i : c.getGenericInterfaces()) { |
|
90 |
r = visit(i, sup); |
|
91 |
if (r != null) { |
|
92 |
return r; |
|
93 |
} |
|
94 |
} |
|
95 |
||
96 |
return null; |
|
97 |
} |
|
98 |
||
99 |
public Type onParameterizdType(ParameterizedType p, Class sup) { |
|
100 |
Class raw = (Class) p.getRawType(); |
|
101 |
if (raw == sup) { |
|
102 |
// p is of the form sup<...> |
|
103 |
return p; |
|
104 |
} else { |
|
105 |
// recursively visit super class/interfaces |
|
106 |
Type r = raw.getGenericSuperclass(); |
|
107 |
if (r != null) { |
|
108 |
r = visit(bind(r, raw, p), sup); |
|
109 |
} |
|
110 |
if (r != null) { |
|
111 |
return r; |
|
112 |
} |
|
113 |
for (Type i : raw.getGenericInterfaces()) { |
|
114 |
r = visit(bind(i, raw, p), sup); |
|
115 |
if (r != null) { |
|
116 |
return r; |
|
117 |
} |
|
118 |
} |
|
119 |
return null; |
|
120 |
} |
|
121 |
} |
|
122 |
||
123 |
public Type onGenericArray(GenericArrayType g, Class sup) { |
|
124 |
// not clear what I should do here |
|
125 |
return null; |
|
126 |
} |
|
127 |
||
128 |
public Type onVariable(TypeVariable v, Class sup) { |
|
129 |
return visit(v.getBounds()[0], sup); |
|
130 |
} |
|
131 |
||
132 |
public Type onWildcard(WildcardType w, Class sup) { |
|
133 |
// not clear what I should do here |
|
134 |
return null; |
|
135 |
} |
|
136 |
||
137 |
/** |
|
138 |
* Replaces the type variables in {@code t} by its actual arguments. |
|
139 |
* |
|
140 |
* @param decl |
|
141 |
* provides a list of type variables. See {@link GenericDeclaration#getTypeParameters()} |
|
142 |
* @param args |
|
143 |
* actual arguments. See {@link ParameterizedType#getActualTypeArguments()} |
|
144 |
*/ |
|
145 |
private Type bind(Type t, GenericDeclaration decl, ParameterizedType args) { |
|
146 |
return binder.visit(t, new BinderArg(decl, args.getActualTypeArguments())); |
|
147 |
} |
|
148 |
}; |
|
149 |
||
150 |
private static class BinderArg { |
|
151 |
||
152 |
final TypeVariable[] params; |
|
153 |
final Type[] args; |
|
154 |
||
155 |
BinderArg(TypeVariable[] params, Type[] args) { |
|
156 |
this.params = params; |
|
157 |
this.args = args; |
|
158 |
assert params.length == args.length; |
|
159 |
} |
|
160 |
||
161 |
public BinderArg(GenericDeclaration decl, Type[] args) { |
|
162 |
this(decl.getTypeParameters(), args); |
|
163 |
} |
|
164 |
||
165 |
Type replace(TypeVariable v) { |
|
166 |
for (int i = 0; i < params.length; i++) { |
|
167 |
if (params[i].equals(v)) { |
|
168 |
return args[i]; |
|
169 |
} |
|
170 |
} |
|
171 |
return v; // this is a free variable |
|
172 |
} |
|
173 |
} |
|
174 |
private static final TypeVisitor<Type, BinderArg> binder = new TypeVisitor<Type, BinderArg>() { |
|
175 |
||
176 |
public Type onClass(Class c, BinderArg args) { |
|
177 |
return c; |
|
178 |
} |
|
179 |
||
180 |
public Type onParameterizdType(ParameterizedType p, BinderArg args) { |
|
181 |
Type[] params = p.getActualTypeArguments(); |
|
182 |
||
183 |
boolean different = false; |
|
184 |
for (int i = 0; i < params.length; i++) { |
|
185 |
Type t = params[i]; |
|
186 |
params[i] = visit(t, args); |
|
187 |
different |= t != params[i]; |
|
188 |
} |
|
189 |
||
190 |
Type newOwner = p.getOwnerType(); |
|
191 |
if (newOwner != null) { |
|
192 |
newOwner = visit(newOwner, args); |
|
193 |
} |
|
194 |
different |= p.getOwnerType() != newOwner; |
|
195 |
||
196 |
if (!different) { |
|
197 |
return p; |
|
198 |
} |
|
199 |
||
200 |
return new ParameterizedTypeImpl((Class<?>) p.getRawType(), params, newOwner); |
|
201 |
} |
|
202 |
||
203 |
public Type onGenericArray(GenericArrayType g, BinderArg types) { |
|
204 |
Type c = visit(g.getGenericComponentType(), types); |
|
205 |
if (c == g.getGenericComponentType()) { |
|
206 |
return g; |
|
207 |
} |
|
208 |
||
209 |
return new GenericArrayTypeImpl(c); |
|
210 |
} |
|
211 |
||
212 |
public Type onVariable(TypeVariable v, BinderArg types) { |
|
213 |
return types.replace(v); |
|
214 |
} |
|
215 |
||
216 |
public Type onWildcard(WildcardType w, BinderArg types) { |
|
217 |
// TODO: this is probably still incorrect |
|
218 |
// bind( "? extends T" ) with T= "? extends Foo" should be "? extends Foo", |
|
219 |
// not "? extends (? extends Foo)" |
|
220 |
Type[] lb = w.getLowerBounds(); |
|
221 |
Type[] ub = w.getUpperBounds(); |
|
222 |
boolean diff = false; |
|
223 |
||
224 |
for (int i = 0; i < lb.length; i++) { |
|
225 |
Type t = lb[i]; |
|
226 |
lb[i] = visit(t, types); |
|
227 |
diff |= (t != lb[i]); |
|
228 |
} |
|
229 |
||
230 |
for (int i = 0; i < ub.length; i++) { |
|
231 |
Type t = ub[i]; |
|
232 |
ub[i] = visit(t, types); |
|
233 |
diff |= (t != ub[i]); |
|
234 |
} |
|
235 |
||
236 |
if (!diff) { |
|
237 |
return w; |
|
238 |
} |
|
239 |
||
240 |
return new WildcardTypeImpl(lb, ub); |
|
241 |
} |
|
242 |
}; |
|
243 |
||
244 |
public Type getBaseClass(Type t, Class sup) { |
|
245 |
return baseClassFinder.visit(t, sup); |
|
246 |
} |
|
247 |
||
248 |
public String getClassName(Class clazz) { |
|
249 |
return clazz.getName(); |
|
250 |
} |
|
251 |
||
252 |
public String getTypeName(Type type) { |
|
253 |
if (type instanceof Class) { |
|
254 |
Class c = (Class) type; |
|
255 |
if (c.isArray()) { |
|
256 |
return getTypeName(c.getComponentType()) + "[]"; |
|
257 |
} |
|
258 |
return c.getName(); |
|
259 |
} |
|
260 |
return type.toString(); |
|
261 |
} |
|
262 |
||
263 |
public String getClassShortName(Class clazz) { |
|
264 |
return clazz.getSimpleName(); |
|
265 |
} |
|
266 |
||
267 |
public Collection<? extends Field> getDeclaredFields(Class clazz) { |
|
268 |
return Arrays.asList(clazz.getDeclaredFields()); |
|
269 |
} |
|
270 |
||
271 |
public Field getDeclaredField(Class clazz, String fieldName) { |
|
272 |
try { |
|
273 |
return clazz.getDeclaredField(fieldName); |
|
274 |
} catch (NoSuchFieldException e) { |
|
275 |
return null; |
|
276 |
} |
|
277 |
} |
|
278 |
||
279 |
public Collection<? extends Method> getDeclaredMethods(Class clazz) { |
|
280 |
return Arrays.asList(clazz.getDeclaredMethods()); |
|
281 |
} |
|
282 |
||
283 |
public Class getDeclaringClassForField(Field field) { |
|
284 |
return field.getDeclaringClass(); |
|
285 |
} |
|
286 |
||
287 |
public Class getDeclaringClassForMethod(Method method) { |
|
288 |
return method.getDeclaringClass(); |
|
289 |
} |
|
290 |
||
291 |
public Type getFieldType(Field field) { |
|
292 |
if (field.getType().isArray()) { |
|
293 |
Class c = field.getType().getComponentType(); |
|
294 |
if (c.isPrimitive()) { |
|
295 |
return Array.newInstance(c, 0).getClass(); |
|
296 |
} |
|
297 |
} |
|
298 |
return fix(field.getGenericType()); |
|
299 |
} |
|
300 |
||
301 |
public String getFieldName(Field field) { |
|
302 |
return field.getName(); |
|
303 |
} |
|
304 |
||
305 |
public String getMethodName(Method method) { |
|
306 |
return method.getName(); |
|
307 |
} |
|
308 |
||
309 |
public Type getReturnType(Method method) { |
|
310 |
return fix(method.getGenericReturnType()); |
|
311 |
} |
|
312 |
||
313 |
public Type[] getMethodParameters(Method method) { |
|
314 |
return method.getGenericParameterTypes(); |
|
315 |
} |
|
316 |
||
317 |
public boolean isStaticMethod(Method method) { |
|
318 |
return Modifier.isStatic(method.getModifiers()); |
|
319 |
} |
|
320 |
||
321 |
public boolean isFinalMethod(Method method) { |
|
322 |
return Modifier.isFinal(method.getModifiers()); |
|
323 |
} |
|
324 |
||
325 |
public boolean isSubClassOf(Type sub, Type sup) { |
|
326 |
return erasure(sup).isAssignableFrom(erasure(sub)); |
|
327 |
} |
|
328 |
||
329 |
public Class ref(Class c) { |
|
330 |
return c; |
|
331 |
} |
|
332 |
||
333 |
public Class use(Class c) { |
|
334 |
return c; |
|
335 |
} |
|
336 |
||
337 |
public Class asDecl(Type t) { |
|
338 |
return erasure(t); |
|
339 |
} |
|
340 |
||
341 |
public Class asDecl(Class c) { |
|
342 |
return c; |
|
343 |
} |
|
344 |
/** |
|
345 |
* Implements the logic for {@link #erasure(Type)}. |
|
346 |
*/ |
|
347 |
private static final TypeVisitor<Class, Void> eraser = new TypeVisitor<Class, Void>() { |
|
348 |
||
16791 | 349 |
public Class onClass(Class c, Void v) { |
12009 | 350 |
return c; |
351 |
} |
|
352 |
||
16791 | 353 |
public Class onParameterizdType(ParameterizedType p, Void v) { |
12009 | 354 |
// TODO: why getRawType returns Type? not Class? |
355 |
return visit(p.getRawType(), null); |
|
356 |
} |
|
357 |
||
16791 | 358 |
public Class onGenericArray(GenericArrayType g, Void v) { |
12009 | 359 |
return Array.newInstance( |
360 |
visit(g.getGenericComponentType(), null), |
|
361 |
0).getClass(); |
|
362 |
} |
|
363 |
||
16791 | 364 |
public Class onVariable(TypeVariable tv, Void v) { |
365 |
return visit(tv.getBounds()[0], null); |
|
12009 | 366 |
} |
367 |
||
16791 | 368 |
public Class onWildcard(WildcardType w, Void v) { |
12009 | 369 |
return visit(w.getUpperBounds()[0], null); |
370 |
} |
|
371 |
}; |
|
372 |
||
373 |
/** |
|
374 |
* Returns the runtime representation of the given type. |
|
375 |
* |
|
376 |
* This corresponds to the notion of the erasure in JSR-14. |
|
377 |
* |
|
378 |
* <p> |
|
379 |
* Because of the difference in the way Annotation Processing and the Java reflection |
|
380 |
* treats primitive type and array type, we can't define this method |
|
381 |
* on {@link Navigator}. |
|
382 |
* |
|
383 |
* <p> |
|
384 |
* It made me realize how difficult it is to define the common navigation |
|
385 |
* layer for two different underlying reflection library. The other way |
|
386 |
* is to throw away the entire parameterization and go to the wrapper approach. |
|
387 |
*/ |
|
388 |
public <T> Class<T> erasure(Type t) { |
|
389 |
return eraser.visit(t, null); |
|
390 |
} |
|
391 |
||
392 |
public boolean isAbstract(Class clazz) { |
|
393 |
return Modifier.isAbstract(clazz.getModifiers()); |
|
394 |
} |
|
395 |
||
396 |
public boolean isFinal(Class clazz) { |
|
397 |
return Modifier.isFinal(clazz.getModifiers()); |
|
398 |
} |
|
399 |
||
400 |
/** |
|
401 |
* Returns the {@link Type} object that represents {@code clazz<T1,T2,T3>}. |
|
402 |
*/ |
|
403 |
public Type createParameterizedType(Class rawType, Type... arguments) { |
|
404 |
return new ParameterizedTypeImpl(rawType, arguments, null); |
|
405 |
} |
|
406 |
||
407 |
public boolean isArray(Type t) { |
|
408 |
if (t instanceof Class) { |
|
409 |
Class c = (Class) t; |
|
410 |
return c.isArray(); |
|
411 |
} |
|
412 |
if (t instanceof GenericArrayType) { |
|
413 |
return true; |
|
414 |
} |
|
415 |
return false; |
|
416 |
} |
|
417 |
||
418 |
public boolean isArrayButNotByteArray(Type t) { |
|
419 |
if (t instanceof Class) { |
|
420 |
Class c = (Class) t; |
|
421 |
return c.isArray() && c != byte[].class; |
|
422 |
} |
|
423 |
if (t instanceof GenericArrayType) { |
|
424 |
t = ((GenericArrayType) t).getGenericComponentType(); |
|
425 |
return t != Byte.TYPE; |
|
426 |
} |
|
427 |
return false; |
|
428 |
} |
|
429 |
||
430 |
public Type getComponentType(Type t) { |
|
431 |
if (t instanceof Class) { |
|
432 |
Class c = (Class) t; |
|
433 |
return c.getComponentType(); |
|
434 |
} |
|
435 |
if (t instanceof GenericArrayType) { |
|
436 |
return ((GenericArrayType) t).getGenericComponentType(); |
|
437 |
} |
|
438 |
||
439 |
throw new IllegalArgumentException(); |
|
440 |
} |
|
441 |
||
442 |
public Type getTypeArgument(Type type, int i) { |
|
443 |
if (type instanceof ParameterizedType) { |
|
444 |
ParameterizedType p = (ParameterizedType) type; |
|
445 |
return fix(p.getActualTypeArguments()[i]); |
|
446 |
} else { |
|
447 |
throw new IllegalArgumentException(); |
|
448 |
} |
|
449 |
} |
|
450 |
||
451 |
public boolean isParameterizedType(Type type) { |
|
452 |
return type instanceof ParameterizedType; |
|
453 |
} |
|
454 |
||
455 |
public boolean isPrimitive(Type type) { |
|
456 |
if (type instanceof Class) { |
|
457 |
Class c = (Class) type; |
|
458 |
return c.isPrimitive(); |
|
459 |
} |
|
460 |
return false; |
|
461 |
} |
|
462 |
||
463 |
public Type getPrimitive(Class primitiveType) { |
|
464 |
assert primitiveType.isPrimitive(); |
|
465 |
return primitiveType; |
|
466 |
} |
|
467 |
||
468 |
public Location getClassLocation(final Class clazz) { |
|
469 |
return new Location() { |
|
470 |
||
471 |
@Override |
|
472 |
public String toString() { |
|
473 |
return clazz.getName(); |
|
474 |
} |
|
475 |
}; |
|
476 |
} |
|
477 |
||
478 |
public Location getFieldLocation(final Field field) { |
|
479 |
return new Location() { |
|
480 |
||
481 |
@Override |
|
482 |
public String toString() { |
|
483 |
return field.toString(); |
|
484 |
} |
|
485 |
}; |
|
486 |
} |
|
487 |
||
488 |
public Location getMethodLocation(final Method method) { |
|
489 |
return new Location() { |
|
490 |
||
491 |
@Override |
|
492 |
public String toString() { |
|
493 |
return method.toString(); |
|
494 |
} |
|
495 |
}; |
|
496 |
} |
|
497 |
||
498 |
public boolean hasDefaultConstructor(Class c) { |
|
499 |
try { |
|
500 |
c.getDeclaredConstructor(); |
|
501 |
return true; |
|
502 |
} catch (NoSuchMethodException e) { |
|
22427 | 503 |
return false; // todo: do this WITHOUT exception throw |
12009 | 504 |
} |
505 |
} |
|
506 |
||
507 |
public boolean isStaticField(Field field) { |
|
508 |
return Modifier.isStatic(field.getModifiers()); |
|
509 |
} |
|
510 |
||
511 |
public boolean isPublicMethod(Method method) { |
|
512 |
return Modifier.isPublic(method.getModifiers()); |
|
513 |
} |
|
514 |
||
515 |
public boolean isPublicField(Field field) { |
|
516 |
return Modifier.isPublic(field.getModifiers()); |
|
517 |
} |
|
518 |
||
519 |
public boolean isEnum(Class c) { |
|
520 |
return Enum.class.isAssignableFrom(c); |
|
521 |
} |
|
522 |
||
523 |
public Field[] getEnumConstants(Class clazz) { |
|
524 |
try { |
|
525 |
Object[] values = clazz.getEnumConstants(); |
|
526 |
Field[] fields = new Field[values.length]; |
|
527 |
for (int i = 0; i < values.length; i++) { |
|
528 |
fields[i] = clazz.getField(((Enum) values[i]).name()); |
|
529 |
} |
|
530 |
return fields; |
|
531 |
} catch (NoSuchFieldException e) { |
|
532 |
// impossible |
|
533 |
throw new NoSuchFieldError(e.getMessage()); |
|
534 |
} |
|
535 |
} |
|
536 |
||
537 |
public Type getVoidType() { |
|
538 |
return Void.class; |
|
539 |
} |
|
540 |
||
541 |
public String getPackageName(Class clazz) { |
|
542 |
String name = clazz.getName(); |
|
543 |
int idx = name.lastIndexOf('.'); |
|
544 |
if (idx < 0) { |
|
545 |
return ""; |
|
546 |
} else { |
|
547 |
return name.substring(0, idx); |
|
548 |
} |
|
549 |
} |
|
550 |
||
22427 | 551 |
@Override |
552 |
public Class loadObjectFactory(Class referencePoint, String pkg) { |
|
23782
953bfc3fbe31
8036030: Update JAX-WS RI integration to latest version
mkos
parents:
22427
diff
changeset
|
553 |
ClassLoader cl = SecureLoader.getClassClassLoader(referencePoint); |
22427 | 554 |
if (cl == null) |
555 |
cl = SecureLoader.getSystemClassLoader(); |
|
556 |
||
12009 | 557 |
try { |
22427 | 558 |
return cl.loadClass(pkg + ".ObjectFactory"); |
12009 | 559 |
} catch (ClassNotFoundException e) { |
560 |
return null; |
|
561 |
} |
|
562 |
} |
|
563 |
||
564 |
public boolean isBridgeMethod(Method method) { |
|
565 |
return method.isBridge(); |
|
566 |
} |
|
567 |
||
568 |
public boolean isOverriding(Method method, Class base) { |
|
569 |
// this isn't actually correct, |
|
570 |
// as the JLS considers |
|
571 |
// class Derived extends Base<Integer> { |
|
572 |
// Integer getX() { ... } |
|
573 |
// } |
|
574 |
// class Base<T> { |
|
575 |
// T getX() { ... } |
|
576 |
// } |
|
577 |
// to be overrided. Handling this correctly needs a careful implementation |
|
578 |
||
579 |
String name = method.getName(); |
|
580 |
Class[] params = method.getParameterTypes(); |
|
581 |
||
582 |
while (base != null) { |
|
583 |
try { |
|
584 |
if (base.getDeclaredMethod(name, params) != null) { |
|
585 |
return true; |
|
586 |
} |
|
587 |
} catch (NoSuchMethodException e) { |
|
588 |
// recursively go into the base class |
|
589 |
} |
|
590 |
||
591 |
base = base.getSuperclass(); |
|
592 |
} |
|
593 |
||
594 |
return false; |
|
595 |
} |
|
596 |
||
597 |
public boolean isInterface(Class clazz) { |
|
598 |
return clazz.isInterface(); |
|
599 |
} |
|
600 |
||
601 |
public boolean isTransient(Field f) { |
|
602 |
return Modifier.isTransient(f.getModifiers()); |
|
603 |
} |
|
604 |
||
605 |
public boolean isInnerClass(Class clazz) { |
|
606 |
return clazz.getEnclosingClass() != null && !Modifier.isStatic(clazz.getModifiers()); |
|
607 |
} |
|
608 |
||
609 |
@Override |
|
610 |
public boolean isSameType(Type t1, Type t2) { |
|
611 |
return t1.equals(t2); |
|
612 |
} |
|
613 |
||
614 |
/** |
|
615 |
* JDK 5.0 has a bug of creating {@link GenericArrayType} where it shouldn't. |
|
616 |
* fix that manually to work around the problem. |
|
617 |
* |
|
618 |
* See bug 6202725. |
|
619 |
*/ |
|
620 |
private Type fix(Type t) { |
|
621 |
if (!(t instanceof GenericArrayType)) { |
|
622 |
return t; |
|
623 |
} |
|
624 |
||
625 |
GenericArrayType gat = (GenericArrayType) t; |
|
626 |
if (gat.getGenericComponentType() instanceof Class) { |
|
627 |
Class c = (Class) gat.getGenericComponentType(); |
|
628 |
return Array.newInstance(c, 0).getClass(); |
|
629 |
} |
|
630 |
||
631 |
return t; |
|
632 |
} |
|
633 |
} |