1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   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.util.Collection;
  29 
  30 import com.sun.xml.internal.bind.v2.runtime.Location;
  31 
  32 /**
  33  * Provides unified view of the underlying reflection library,
  34  * such as {@code java.lang.reflect} and/or Annotation Processing.
  35  *
  36  * <p>
  37  * This interface provides navigation over the reflection model
  38  * to decouple the caller from any particular implementation.
  39  * This allows the JAXB RI to reuse much of the code between
  40  * the compile time (which works on top of Annotation Processing) and the run-time
  41  * (which works on top of {@code java.lang.reflect})
  42  *
  43  * <p>
  44  * {@link Navigator} instances are stateless and immutable.
  45  *
  46  *
  47  * <h2>Parameterization</h2>
  48  * <h3>C</h3>
  49  * <p>
  50  * A Java class declaration (not an interface, a class and an enum.)
  51  *
  52  * <h3>T</h3>
  53  * <p>
  54  * A Java type. This includs declaration, but also includes such
  55  * things like arrays, primitive types, parameterized types, and etc.
  56  *
  57  * @author Kohsuke Kawaguchi (kk@kohsuke.org)
  58  */
  59 public interface Navigator<T,C,F,M> {
  60     /**
  61      * Gets the base class of the specified class.
  62      *
  63      * @return
  64      *      null if the parameter represents {@link Object}.
  65      */
  66     C getSuperClass(C clazz);
  67 
  68     /**
  69      * Gets the parameterization of the given base type.
  70      *
  71      * <p>
  72      * For example, given the following
  73      * <pre>{@code
  74      * interface Foo<T> extends List<List<T>> {}
  75      * interface Bar extends Foo<String> {}
  76      * }</pre>
  77      * This method works like this:
  78      * <pre>{@code
  79      * getBaseClass( Bar, List ) = List<List<String>>
  80      * getBaseClass( Bar, Foo  ) = Foo<String>
  81      * getBaseClass( Foo<? extends Number>, Collection ) = Collection<List<? extends Number>>
  82      * getBaseClass( ArrayList<? extends BigInteger>, List ) = List<? extends BigInteger>
  83      * }</pre>
  84      *
  85      * @param type
  86      *      The type that derives from {@code baseType}
  87      * @param baseType
  88      *      The class whose parameterization we are interested in.
  89      * @return
  90      *      The use of {@code baseType} in {@code type}.
  91      *      or null if the type is not assignable to the base type.
  92      */
  93     T getBaseClass(T type, C baseType);
  94 
  95     /**
  96      * Gets the fully-qualified name of the class.
  97      * ("java.lang.Object" for {@link Object})
  98      */
  99     String getClassName(C clazz);
 100 
 101     /**
 102      * Gets the display name of the type object
 103      *
 104      * @return
 105      *      a human-readable name that the type represents.
 106      */
 107     String getTypeName(T rawType);
 108 
 109     /**
 110      * Gets the short name of the class ("Object" for {@link Object}.)
 111      *
 112      * For nested classes, this method should just return the inner name.
 113      * (for example "Inner" for "com.acme.Outer$Inner".
 114      */
 115     String getClassShortName(C clazz);
 116 
 117     /**
 118      * Gets all the declared fields of the given class.
 119      */
 120     Collection<? extends F> getDeclaredFields(C clazz);
 121 
 122     /**
 123      * Gets the named field declared on the given class.
 124      *
 125      * This method doesn't visit ancestors, but does recognize
 126      * non-public fields.
 127      *
 128      * @return
 129      *      null if not found
 130      */
 131     F getDeclaredField(C clazz, String fieldName);
 132 
 133     /**
 134      * Gets all the declared methods of the given class
 135      * (regardless of their access modifiers, regardless
 136      * of whether they override methods of the base classes.)
 137      *
 138      * <p>
 139      * Note that this method does not list methods declared on base classes.
 140      *
 141      * @return
 142      *      can be empty but always non-null.
 143      */
 144     Collection<? extends M> getDeclaredMethods(C clazz);
 145 
 146     /**
 147      * Gets the class that declares the given field.
 148      */
 149     C getDeclaringClassForField(F field);
 150 
 151     /**
 152      * Gets the class that declares the given method.
 153      */
 154     C getDeclaringClassForMethod(M method);
 155 
 156     /**
 157      * Gets the type of the field.
 158      */
 159     T getFieldType(F f);
 160 
 161     /**
 162      * Gets the name of the field.
 163      */
 164     String getFieldName(F field);
 165 
 166     /**
 167      * Gets the name of the method, such as "toString" or "equals".
 168      */
 169     String getMethodName(M m);
 170 
 171     /**
 172      * Gets the return type of a method.
 173      */
 174     T getReturnType(M m);
 175 
 176     /**
 177      * Returns the list of parameters to the method.
 178      */
 179     T[] getMethodParameters(M method);
 180 
 181     /**
 182      * Returns true if the method is static.
 183      */
 184     boolean isStaticMethod(M method);
 185 
 186     /**
 187      * Checks if {@code sub} is a sub-type of {@code sup}.
 188      *
 189      * TODO: should this method take T or C?
 190      */
 191     boolean isSubClassOf(T sub, T sup);
 192 
 193     /**
 194      * Gets the representation of the given Java type in {@code T}.
 195      *
 196      * @param c
 197      *      can be a primitive, array, class, or anything.
 198      *      (therefore the return type has to be T, not C)
 199      */
 200     T ref(Class c);
 201 
 202     /**
 203      * Gets the T for the given C.
 204      */
 205     T use(C c);
 206 
 207     /**
 208      * If the given type is an use of class declaration,
 209      * returns the type casted as {@code C}.
 210      * Otherwise null.
 211      *
 212      * <p>
 213      * TODO: define the exact semantics.
 214      */
 215     C asDecl(T type);
 216 
 217     /**
 218      * Gets the {@code C} representation for the given class.
 219      *
 220      * The behavior is undefined if the class object represents
 221      * primitives, arrays, and other types that are not class declaration.
 222      */
 223     C asDecl(Class c);
 224 
 225     /**
 226      * Checks if the type is an array type.
 227      */
 228     boolean isArray(T t);
 229 
 230     /**
 231      * Checks if the type is an array type but not byte[].
 232      */
 233     boolean isArrayButNotByteArray(T t);
 234 
 235     /**
 236      * Gets the component type of the array.
 237      *
 238      * @param t
 239      *      must be an array.
 240      */
 241     T getComponentType(T t);
 242 
 243     /**
 244      * Gets the i-th type argument from a parameterized type.
 245      *
 246      * For example, {@code getTypeArgument([Map<Integer,String>],0)=Integer}
 247      *
 248      * @throws IllegalArgumentException
 249      *      If t is not a parameterized type
 250      * @throws IndexOutOfBoundsException
 251      *      If i is out of range.
 252      *
 253      * @see #isParameterizedType(Object)
 254      */
 255     T getTypeArgument(T t, int i);
 256 
 257     /**
 258      * Returns true if t is a parameterized type.
 259      */
 260     boolean isParameterizedType(T t);
 261 
 262     /**
 263      * Checks if the given type is a primitive type.
 264      */
 265     boolean isPrimitive(T t);
 266 
 267     /**
 268      * Returns the representation for the given primitive type.
 269      *
 270      * @param primitiveType
 271      *      must be Class objects like {@link Integer#TYPE}.
 272      */
 273     T getPrimitive(Class primitiveType);
 274 
 275     /**
 276      * Returns a location of the specified class.
 277      */
 278     Location getClassLocation(C clazz);
 279 
 280     Location getFieldLocation(F field);
 281 
 282     Location getMethodLocation(M getter);
 283 
 284     /**
 285      * Returns true if the given class has a no-arg default constructor.
 286      * The constructor does not need to be public.
 287      */
 288     boolean hasDefaultConstructor(C clazz);
 289 
 290     /**
 291      * Returns true if the field is static.
 292      */
 293     boolean isStaticField(F field);
 294 
 295     /**
 296      * Returns true if the method is public.
 297      */
 298     boolean isPublicMethod(M method);
 299 
 300     /**
 301      * Returns true if the method is final.
 302      */
 303     boolean isFinalMethod(M method);
 304 
 305     /**
 306      * Returns true if the field is public.
 307      */
 308     boolean isPublicField(F field);
 309 
 310     /**
 311      * Returns true if this is an enum class.
 312      */
 313     boolean isEnum(C clazz);
 314 
 315     /**
 316      * Computes the erasure
 317      */
 318     <P> T erasure(T contentInMemoryType);
 319     // This unused P is necessary to make ReflectionNavigator.erasure work nicely
 320 
 321     /**
 322      * Returns true if this is an abstract class.
 323      */
 324     boolean isAbstract(C clazz);
 325 
 326     /**
 327      * Returns true if this is a final class.
 328      */
 329     boolean isFinal(C clazz);
 330 
 331     /**
 332      * Gets the enumeration constants from an enum class.
 333      *
 334      * @param clazz
 335      *      must derive from {@link Enum}.
 336      *
 337      * @return
 338      *      can be empty but never null.
 339      */
 340     F[] getEnumConstants(C clazz);
 341 
 342     /**
 343      * Gets the representation of the primitive "void" type.
 344      */
 345     T getVoidType();
 346 
 347     /**
 348      * Gets the package name of the given class.
 349      *
 350      * @return
 351      *      i.e. "", "java.lang" but not null.
 352      */
 353     String getPackageName(C clazz);
 354 
 355     /**
 356      * Finds ObjectFactory for the given referencePoint.
 357      *
 358      * @param referencePoint
 359      *      The class that refers to the specified class.
 360      * @return
 361      *      null if not found.
 362      */
 363     C loadObjectFactory(C referencePoint, String packageName);
 364 
 365     /**
 366      * Returns true if this method is a bridge method as defined in JLS.
 367      */
 368     boolean isBridgeMethod(M method);
 369 
 370     /**
 371      * Returns true if the given method is overriding another one
 372      * defined in the base class 'base' or its ancestors.
 373      */
 374     boolean isOverriding(M method, C base);
 375 
 376     /**
 377      * Returns true if 'clazz' is an interface.
 378      */
 379     boolean isInterface(C clazz);
 380 
 381     /**
 382      * Returns true if the field is transient.
 383      */
 384     boolean isTransient(F f);
 385 
 386     /**
 387      * Returns true if the given class is an inner class.
 388      *
 389      * This is only used to improve the error diagnostics, so
 390      * it's OK to fail to detect some inner classes as such.
 391      *
 392      * Note that this method should return false for nested classes
 393      * (static classes.)
 394      */
 395     boolean isInnerClass(C clazz);
 396 
 397     /**
 398      * Checks if types are the same
 399      * @param t1 type
 400      * @param t2 type
 401      * @return true if types are the same
 402      */
 403     boolean isSameType(T t1, T t2);
 404 }