src/share/jaxws_classes/com/sun/xml/internal/bind/v2/model/nav/ReflectionNavigator.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 450
b0c2840e2513
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

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

mercurial