001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.bind.v2.model.nav;
038:
039: import java.util.Collection;
040:
041: import com.sun.xml.bind.v2.runtime.Location;
042:
043: /**
044: * Provides unified view of the underlying reflection library,
045: * such as {@code java.lang.reflect} and/or APT.
046: *
047: * <p>
048: * This interface provides navigation over the reflection model
049: * to decouple the caller from any particular implementation.
050: * This allows the JAXB RI to reuse much of the code between
051: * the compile time (which works on top of APT) and the run-time
052: * (which works on top of {@code java.lang.reflect})
053: *
054: * <p>
055: * {@link Navigator} instances are stateless and immutable.
056: *
057: *
058: * <h2>Parameterization</h2>
059: * <h3>C</h3>
060: * <p>
061: * A Java class declaration (not an interface, a class and an enum.)
062: *
063: * <h3>T</h3>
064: * <p>
065: * A Java type. This includs declaration, but also includes such
066: * things like arrays, primitive types, parameterized types, and etc.
067: *
068: * @author Kohsuke Kawaguchi (kk@kohsuke.org)
069: */
070: public interface Navigator<T, C, F, M> {
071: /**
072: * Gets the base class of the specified class.
073: *
074: * @return
075: * null if the parameter represents {@link Object}.
076: */
077: C getSuperClass(C clazz);
078:
079: /**
080: * Gets the parameterization of the given base type.
081: *
082: * <p>
083: * For example, given the following
084: * <pre><xmp>
085: * interface Foo<T> extends List<List<T>> {}
086: * interface Bar extends Foo<String> {}
087: * </xmp></pre>
088: * This method works like this:
089: * <pre><xmp>
090: * getBaseClass( Bar, List ) = List<List<String>
091: * getBaseClass( Bar, Foo ) = Foo<String>
092: * getBaseClass( Foo<? extends Number>, Collection ) = Collection<List<? extends Number>>
093: * getBaseClass( ArrayList<? extends BigInteger>, List ) = List<? extends BigInteger>
094: * </xmp></pre>
095: *
096: * @param type
097: * The type that derives from {@code baseType}
098: * @param baseType
099: * The class whose parameterization we are interested in.
100: * @return
101: * The use of {@code baseType} in {@code type}.
102: * or null if the type is not assignable to the base type.
103: */
104: T getBaseClass(T type, C baseType);
105:
106: /**
107: * Gets the fully-qualified name of the class.
108: * ("java.lang.Object" for {@link Object})
109: */
110: String getClassName(C clazz);
111:
112: /**
113: * Gets the display name of the type object
114: *
115: * @return
116: * a human-readable name that the type represents.
117: */
118: String getTypeName(T rawType);
119:
120: /**
121: * Gets the short name of the class ("Object" for {@link Object}.)
122: *
123: * For nested classes, this method should just return the inner name.
124: * (for example "Inner" for "com.acme.Outer$Inner".
125: */
126: String getClassShortName(C clazz);
127:
128: /**
129: * Gets all the declared fields of the given class.
130: */
131: Collection<? extends F> getDeclaredFields(C clazz);
132:
133: /**
134: * Gets the named field declared on the given class.
135: *
136: * This method doesn't visit ancestors, but does recognize
137: * non-public fields.
138: *
139: * @return
140: * null if not found
141: */
142: F getDeclaredField(C clazz, String fieldName);
143:
144: /**
145: * Gets all the declared methods of the given class
146: * (regardless of their access modifiers, regardless
147: * of whether they override methods of the base classes.)
148: *
149: * <p>
150: * Note that this method does not list methods declared on base classes.
151: *
152: * @return
153: * can be empty but always non-null.
154: */
155: Collection<? extends M> getDeclaredMethods(C clazz);
156:
157: /**
158: * Gets the class that declares the given field.
159: */
160: C getDeclaringClassForField(F field);
161:
162: /**
163: * Gets the class that declares the given method.
164: */
165: C getDeclaringClassForMethod(M method);
166:
167: /**
168: * Gets the type of the field.
169: */
170: T getFieldType(F f);
171:
172: /**
173: * Gets the name of the field.
174: */
175: String getFieldName(F field);
176:
177: /**
178: * Gets the name of the method, such as "toString" or "equals".
179: */
180: String getMethodName(M m);
181:
182: /**
183: * Gets the return type of a method.
184: */
185: T getReturnType(M m);
186:
187: /**
188: * Returns the list of parameters to the method.
189: */
190: T[] getMethodParameters(M method);
191:
192: /**
193: * Returns true if the method is static.
194: */
195: boolean isStaticMethod(M method);
196:
197: /**
198: * Checks if {@code sub} is a sub-type of {@code sup}.
199: *
200: * TODO: should this method take T or C?
201: */
202: boolean isSubClassOf(T sub, T sup);
203:
204: /**
205: * Gets the representation of the given Java type in {@code T}.
206: *
207: * @param c
208: * can be a primitive, array, class, or anything.
209: * (therefore the return type has to be T, not C)
210: */
211: T ref(Class c);
212:
213: /**
214: * Gets the T for the given C.
215: */
216: T use(C c);
217:
218: /**
219: * If the given type is an use of class declaration,
220: * returns the type casted as {@code C}.
221: * Otherwise null.
222: *
223: * <p>
224: * TODO: define the exact semantics.
225: */
226: C asDecl(T type);
227:
228: /**
229: * Gets the {@code C} representation for the given class.
230: *
231: * The behavior is undefined if the class object represents
232: * primitives, arrays, and other types that are not class declaration.
233: */
234: C asDecl(Class c);
235:
236: /**
237: * Checks if the type is an array type.
238: */
239: boolean isArray(T t);
240:
241: /**
242: * Checks if the type is an array type but not byte[].
243: */
244: boolean isArrayButNotByteArray(T t);
245:
246: /**
247: * Gets the component type of the array.
248: *
249: * @param t
250: * must be an array.
251: */
252: T getComponentType(T t);
253:
254: /** The singleton instance. */
255: public static final ReflectionNavigator REFLECTION = new ReflectionNavigator();
256:
257: /**
258: * Gets the i-th type argument from a parameterized type.
259: *
260: * For example, {@code getTypeArgument([Map<Integer,String>],0)=Integer}
261: *
262: * @throws IllegalArgumentException
263: * If t is not a parameterized type
264: * @throws IndexOutOfBoundsException
265: * If i is out of range.
266: *
267: * @see #isParameterizedType(Object)
268: */
269: T getTypeArgument(T t, int i);
270:
271: /**
272: * Returns true if t is a parameterized type.
273: */
274: boolean isParameterizedType(T t);
275:
276: /**
277: * Checks if the given type is a primitive type.
278: */
279: boolean isPrimitive(T t);
280:
281: /**
282: * Returns the representation for the given primitive type.
283: *
284: * @param primitiveType
285: * must be Class objects like {@link Integer#TYPE}.
286: */
287: T getPrimitive(Class primitiveType);
288:
289: /**
290: * Returns a location of the specified class.
291: */
292: Location getClassLocation(C clazz);
293:
294: Location getFieldLocation(F field);
295:
296: Location getMethodLocation(M getter);
297:
298: /**
299: * Returns true if the given class has a no-arg default constructor.
300: * The constructor does not need to be public.
301: */
302: boolean hasDefaultConstructor(C clazz);
303:
304: /**
305: * Returns true if the field is static.
306: */
307: boolean isStaticField(F field);
308:
309: /**
310: * Returns true if the method is public.
311: */
312: boolean isPublicMethod(M method);
313:
314: /**
315: * Returns true if the field is public.
316: */
317: boolean isPublicField(F field);
318:
319: /**
320: * Returns true if this is an enum class.
321: */
322: boolean isEnum(C clazz);
323:
324: /**
325: * Computes the erasure
326: */
327: <P> T erasure(T contentInMemoryType);
328:
329: // This unused P is necessary to make ReflectionNavigator.erasure work nicely
330:
331: /**
332: * Returns true if this is an abstract class.
333: */
334: boolean isAbstract(C clazz);
335:
336: /**
337: * Returns true if this is a final class.
338: */
339: boolean isFinal(C clazz);
340:
341: /**
342: * Gets the enumeration constants from an enum class.
343: *
344: * @param clazz
345: * must derive from {@link Enum}.
346: *
347: * @return
348: * can be empty but never null.
349: */
350: F[] getEnumConstants(C clazz);
351:
352: /**
353: * Gets the representation of the primitive "void" type.
354: */
355: T getVoidType();
356:
357: /**
358: * Gets the package name of the given class.
359: *
360: * @return
361: * i.e. "", "java.lang" but not null.
362: */
363: String getPackageName(C clazz);
364:
365: /**
366: * Finds the class/interface/enum/annotation of the given name.
367: *
368: * @param referencePoint
369: * The class that refers to the specified class.
370: * @return
371: * null if not found.
372: */
373: C findClass(String className, C referencePoint);
374:
375: /**
376: * Returns true if this method is a bridge method as defined in JLS.
377: */
378: boolean isBridgeMethod(M method);
379:
380: /**
381: * Returns true if the given method is overriding another one
382: * defined in the base class 'base' or its ancestors.
383: */
384: boolean isOverriding(M method, C base);
385:
386: /**
387: * Returns true if 'clazz' is an interface.
388: */
389: boolean isInterface(C clazz);
390:
391: /**
392: * Returns true if the field is transient.
393: */
394: boolean isTransient(F f);
395:
396: /**
397: * Returns true if the given class is an inner class.
398: *
399: * This is only used to improve the error diagnostics, so
400: * it's OK to fail to detect some inner classes as such.
401: *
402: * Note that this method should return false for nested classes
403: * (static classes.)
404: */
405: boolean isInnerClass(C clazz);
406: }
|