aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.bind.v2.model.nav; aoqi@0: aoqi@0: import java.lang.reflect.Field; aoqi@0: import java.lang.reflect.Method; aoqi@0: import java.lang.reflect.Proxy; aoqi@0: import java.lang.reflect.Type; aoqi@0: import java.util.Collection; aoqi@0: aoqi@0: import com.sun.xml.internal.bind.v2.runtime.Location; aoqi@0: aoqi@0: /** aoqi@0: * Provides unified view of the underlying reflection library, aoqi@0: * such as {@code java.lang.reflect} and/or Annotation Processing. aoqi@0: * aoqi@0: *
aoqi@0: * This interface provides navigation over the reflection model aoqi@0: * to decouple the caller from any particular implementation. aoqi@0: * This allows the JAXB RI to reuse much of the code between aoqi@0: * the compile time (which works on top of Annotation Processing) and the run-time aoqi@0: * (which works on top of {@code java.lang.reflect}) aoqi@0: * aoqi@0: *
aoqi@0: * {@link Navigator} instances are stateless and immutable. aoqi@0: * aoqi@0: * aoqi@0: *
aoqi@0: * A Java class declaration (not an interface, a class and an enum.) aoqi@0: * aoqi@0: *
aoqi@0: * A Java type. This includs declaration, but also includes such
aoqi@0: * things like arrays, primitive types, parameterized types, and etc.
aoqi@0: *
aoqi@0: * @author Kohsuke Kawaguchi (kk@kohsuke.org)
aoqi@0: */
aoqi@0: public interface Navigator
aoqi@0: * For example, given the following
aoqi@0: *
aoqi@0: * Note that this method does not list methods declared on base classes.
aoqi@0: *
aoqi@0: * @return
aoqi@0: * can be empty but always non-null.
aoqi@0: */
aoqi@0: Collection extends M> getDeclaredMethods(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the class that declares the given field.
aoqi@0: */
aoqi@0: C getDeclaringClassForField(F field);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the class that declares the given method.
aoqi@0: */
aoqi@0: C getDeclaringClassForMethod(M method);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the type of the field.
aoqi@0: */
aoqi@0: T getFieldType(F f);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the name of the field.
aoqi@0: */
aoqi@0: String getFieldName(F field);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the name of the method, such as "toString" or "equals".
aoqi@0: */
aoqi@0: String getMethodName(M m);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the return type of a method.
aoqi@0: */
aoqi@0: T getReturnType(M m);
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns the list of parameters to the method.
aoqi@0: */
aoqi@0: T[] getMethodParameters(M method);
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns true if the method is static.
aoqi@0: */
aoqi@0: boolean isStaticMethod(M method);
aoqi@0:
aoqi@0: /**
aoqi@0: * Checks if {@code sub} is a sub-type of {@code sup}.
aoqi@0: *
aoqi@0: * TODO: should this method take T or C?
aoqi@0: */
aoqi@0: boolean isSubClassOf(T sub, T sup);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the representation of the given Java type in {@code T}.
aoqi@0: *
aoqi@0: * @param c
aoqi@0: * can be a primitive, array, class, or anything.
aoqi@0: * (therefore the return type has to be T, not C)
aoqi@0: */
aoqi@0: T ref(Class c);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the T for the given C.
aoqi@0: */
aoqi@0: T use(C c);
aoqi@0:
aoqi@0: /**
aoqi@0: * If the given type is an use of class declaration,
aoqi@0: * returns the type casted as {@code C}.
aoqi@0: * Otherwise null.
aoqi@0: *
aoqi@0: *
aoqi@0: * TODO: define the exact semantics.
aoqi@0: */
aoqi@0: C asDecl(T type);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the {@code C} representation for the given class.
aoqi@0: *
aoqi@0: * The behavior is undefined if the class object represents
aoqi@0: * primitives, arrays, and other types that are not class declaration.
aoqi@0: */
aoqi@0: C asDecl(Class c);
aoqi@0:
aoqi@0: /**
aoqi@0: * Checks if the type is an array type.
aoqi@0: */
aoqi@0: boolean isArray(T t);
aoqi@0:
aoqi@0: /**
aoqi@0: * Checks if the type is an array type but not byte[].
aoqi@0: */
aoqi@0: boolean isArrayButNotByteArray(T t);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the component type of the array.
aoqi@0: *
aoqi@0: * @param t
aoqi@0: * must be an array.
aoqi@0: */
aoqi@0: T getComponentType(T t);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the i-th type argument from a parameterized type.
aoqi@0: *
aoqi@0: * For example, {@code getTypeArgument([Map T erasure(T contentInMemoryType);
aoqi@0: // This unused P is necessary to make ReflectionNavigator.erasure work nicely
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns true if this is an abstract class.
aoqi@0: */
aoqi@0: boolean isAbstract(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns true if this is a final class.
aoqi@0: */
aoqi@0: boolean isFinal(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the enumeration constants from an enum class.
aoqi@0: *
aoqi@0: * @param clazz
aoqi@0: * must derive from {@link Enum}.
aoqi@0: *
aoqi@0: * @return
aoqi@0: * can be empty but never null.
aoqi@0: */
aoqi@0: F[] getEnumConstants(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the representation of the primitive "void" type.
aoqi@0: */
aoqi@0: T getVoidType();
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the package name of the given class.
aoqi@0: *
aoqi@0: * @return
aoqi@0: * i.e. "", "java.lang" but not null.
aoqi@0: */
aoqi@0: String getPackageName(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Finds ObjectFactory for the given referencePoint.
aoqi@0: *
aoqi@0: * @param referencePoint
aoqi@0: * The class that refers to the specified class.
aoqi@0: * @return
aoqi@0: * null if not found.
aoqi@0: */
aoqi@0: C loadObjectFactory(C referencePoint, String packageName);
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns true if this method is a bridge method as defined in JLS.
aoqi@0: */
aoqi@0: boolean isBridgeMethod(M method);
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns true if the given method is overriding another one
aoqi@0: * defined in the base class 'base' or its ancestors.
aoqi@0: */
aoqi@0: boolean isOverriding(M method, C base);
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns true if 'clazz' is an interface.
aoqi@0: */
aoqi@0: boolean isInterface(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns true if the field is transient.
aoqi@0: */
aoqi@0: boolean isTransient(F f);
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns true if the given class is an inner class.
aoqi@0: *
aoqi@0: * This is only used to improve the error diagnostics, so
aoqi@0: * it's OK to fail to detect some inner classes as such.
aoqi@0: *
aoqi@0: * Note that this method should return false for nested classes
aoqi@0: * (static classes.)
aoqi@0: */
aoqi@0: boolean isInnerClass(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Checks if types are the same
aoqi@0: * @param t1 type
aoqi@0: * @param t2 type
aoqi@0: * @return true if types are the same
aoqi@0: */
aoqi@0: boolean isSameType(T t1, T t2);
aoqi@0: }
aoqi@0: * This method works like this:
aoqi@0: * > {}
aoqi@0: * interface Bar extends Foo
aoqi@0: *
aoqi@0: * @param type
aoqi@0: * The type that derives from {@code baseType}
aoqi@0: * @param baseType
aoqi@0: * The class whose parameterization we are interested in.
aoqi@0: * @return
aoqi@0: * The use of {@code baseType} in {@code type}.
aoqi@0: * or null if the type is not assignable to the base type.
aoqi@0: */
aoqi@0: T getBaseClass(T type, C baseType);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the fully-qualified name of the class.
aoqi@0: * ("java.lang.Object" for {@link Object})
aoqi@0: */
aoqi@0: String getClassName(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the display name of the type object
aoqi@0: *
aoqi@0: * @return
aoqi@0: * a human-readable name that the type represents.
aoqi@0: */
aoqi@0: String getTypeName(T rawType);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the short name of the class ("Object" for {@link Object}.)
aoqi@0: *
aoqi@0: * For nested classes, this method should just return the inner name.
aoqi@0: * (for example "Inner" for "com.acme.Outer$Inner".
aoqi@0: */
aoqi@0: String getClassShortName(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets all the declared fields of the given class.
aoqi@0: */
aoqi@0: Collection extends F> getDeclaredFields(C clazz);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the named field declared on the given class.
aoqi@0: *
aoqi@0: * This method doesn't visit ancestors, but does recognize
aoqi@0: * non-public fields.
aoqi@0: *
aoqi@0: * @return
aoqi@0: * null if not found
aoqi@0: */
aoqi@0: F getDeclaredField(C clazz, String fieldName);
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets all the declared methods of the given class
aoqi@0: * (regardless of their access modifiers, regardless
aoqi@0: * of whether they override methods of the base classes.)
aoqi@0: *
aoqi@0: *
aoqi@0: * getBaseClass( Bar, Foo ) = Foo
>
aoqi@0: * getBaseClass( ArrayList extends BigInteger>, List ) = List extends BigInteger>
aoqi@0: *