001    package net.sourceforge.retroweaver.runtime.java.lang;
002    
003    import java.lang.reflect.Constructor;
004    import java.lang.reflect.Method;
005    
006    import net.sourceforge.retroweaver.runtime.java.lang.annotation.AIB;
007    import net.sourceforge.retroweaver.runtime.java.lang.annotation.Annotation;
008    import net.sourceforge.retroweaver.runtime.java.lang.reflect.GenericSignatureFormatError;
009    import net.sourceforge.retroweaver.runtime.java.lang.reflect.MalformedParameterizedTypeException;
010    import net.sourceforge.retroweaver.runtime.java.lang.reflect.ReflectionDescriptor;
011    import net.sourceforge.retroweaver.runtime.java.lang.reflect.Type;
012    import net.sourceforge.retroweaver.runtime.java.lang.reflect.TypeVariable;
013    
014    /**
015     * Replacements for methods added to java.lang.Class in Java 1.5.
016     */
017    public final class Class_ {
018    
019            private Class_() {
020                    // private constructor
021            }
022    
023              public static boolean isAnnotation( Class c ) {
024                return      Annotation.class.isAssignableFrom(c);
025              }
026    
027              /**
028               * Returns this element's annotation for the specified type if such an annotation is present, else null.
029               * 
030               */
031              public static <T extends Annotation> T getAnnotation( Class c, Class<T> annotationType ) {
032                      if ( annotationType == null ) {
033                  throw new NullPointerException( "Null annotationType" );
034                }
035    
036                return AIB.getAib(c).getClassAnnotation(annotationType);
037              }
038    
039              /**
040               * Returns all annotations present on this element.
041               */
042              public static Annotation[] getAnnotations( Class c ) {
043                return AIB.getAib(c).getClassAnnotations();
044              }
045    
046              /**
047               * Returns all annotations that are directly present on this element.
048               */
049              public static Annotation[] getDeclaredAnnotations( Class c ) {
050                return AIB.getAib(c).getDeclaredClassAnnotations();
051              }
052    
053              /**
054               * Returns true if an annotation for the specified type is present on this element, else false.
055               */
056              public static boolean isAnnotationPresent( Class c, Class<? extends Annotation> annotationType ) {
057                return getAnnotation( c, annotationType ) != null;
058              }
059    
060            /**
061             * Replacement for Class.asSubclass(Class).
062             * 
063             * @param c a Class
064             * @param superclass another Class which must be a superclass of <i>c</i>
065             * @return <i>c</i>
066             * @throws java.lang.ClassCastException if <i>c</i> is
067             */
068            public static Class asSubclass(Class<?> c, Class<?> superclass) {
069                    if (!superclass.isAssignableFrom(c)) {
070                            throw new ClassCastException(superclass.getName());
071                    }
072                    return c;
073            }
074    
075            /**
076             * Replacement for Class.cast(Object). Throws a ClassCastException if <i>obj</i>
077             * is not an instance of class <var>c</var>, or a subtype of <var>c</var>.
078             * 
079             * @param c Class we want to cast <var>obj</var> to
080             * @param object object we want to cast
081             * @return The object, or <code>null</code> if the object is
082             * <code>null</code>.
083             * @throws java.lang.ClassCastException if <var>obj</var> is not
084             * <code>null</code> or an instance of <var>c</var>
085             */
086            public static Object cast(Class c, Object object) {
087                    if (object == null || c.isInstance(object)) {
088                            return object;
089                    } else {
090                            throw new ClassCastException(c.getName());
091                    }
092            }
093    
094            /**
095             * Replacement for Class.isEnum().
096             * 
097             * @param class_ class we want to test.
098             * @return true if the class was declared as an Enum.
099             */
100            public static <T> boolean isEnum(Class<T> class_) {
101                    Class c = class_.getSuperclass();
102    
103                    if (c == null) {
104                            return false;
105                    }
106    
107                    return Enum.class.isAssignableFrom(c);
108            }
109    
110            /**
111             * Replacement for Class.getEnumConstants().
112             * 
113             * @param class_ class we want to get Enum constants for.
114             * @return The elements of this enum class or null if this does not represent an enum type.
115             */
116            public static <T> T[] getEnumConstants(Class<T> class_) {
117                    if (!isEnum(class_)) {
118                            return null;
119                    }
120    
121                    return Enum.getEnumValues(class_).clone();
122            }
123    
124            /**
125            * replacement for Class.isAnonymousClass()
126            */
127            public static boolean isAnonymousClass(Class class_) {
128                    return getSimpleName(class_).length() == 0;
129            }
130    
131            /**
132            * replacement for Class.getSimpleName()
133            */
134            public static String getSimpleName(Class class_) {
135                    if (class_.isArray()) {
136                            return getSimpleName(class_.getComponentType()) + "[]";
137                    }
138    
139                    String className = class_.getName();
140    
141                    int i = className.lastIndexOf('$');
142                    if (i != -1) {
143                            do {
144                                    i++;
145                            } while (i < className.length() && Character.isDigit(className.charAt(i)));
146                            return className.substring(i);
147                    }
148    
149                    return className.substring(className.lastIndexOf('.') + 1);
150            }
151    
152            /**
153             * replacement for Class.isSynthetic()
154             */
155            public static boolean isSynthetic(Class class_) {
156                    throw new UnsupportedOperationException("NotImplemented");
157            }
158    
159            public static TypeVariable[] getTypeParameters(Class class_)
160                            throws GenericSignatureFormatError {
161                    return ReflectionDescriptor.getReflectionDescriptor(class_).getTypeParameters();
162            }
163    
164            public static Type getGenericSuperclass(Class class_)
165                            throws GenericSignatureFormatError, TypeNotPresentException,
166                            MalformedParameterizedTypeException
167            {
168                    return ReflectionDescriptor.getReflectionDescriptor(class_).getGenericSuperclass();
169            }
170    
171            public static Type[] getGenericInterfaces(Class class_) throws GenericSignatureFormatError,
172                            TypeNotPresentException, MalformedParameterizedTypeException
173            {
174                    return ReflectionDescriptor.getReflectionDescriptor(class_).getGenericInterfaces();
175            }
176    
177            public static Method getEnclosingMethod(Class class_) {
178                    return ReflectionDescriptor.getReflectionDescriptor(class_).getEnclosingMethod();
179            }
180    
181            public static Constructor<?> getEnclosingConstructor(Class class_) {
182                    return ReflectionDescriptor.getReflectionDescriptor(class_).getEnclosingConstructor();
183            }
184    
185            public static Class<?> getEnclosingClass(Class class_) {
186                    return ReflectionDescriptor.getReflectionDescriptor(class_).getEnclosingClass();
187            }
188    
189            public static String getCanonicalName(Class class_) {
190                    if (class_.isArray()) {
191                            Class component = class_.getComponentType();
192                            String s = getCanonicalName(component);
193                            return s == null ? null : s + "[]";
194                    }
195    
196                    if (isLocalClass(class_) || isAnonymousClass(class_)) {
197                            return null;
198                    }
199    
200                    return class_.getName().replace('$', '.');
201            }
202    
203            public static boolean isLocalClass(Class class_) {
204                    return getEnclosingMethod(class_) != null && !isAnonymousClass(class_);
205            }
206    
207            public static boolean isMemberClass(Class class_) {
208                    if (getEnclosingClass(class_) != null) {
209                            return !(isLocalClass(class_) || isAnonymousClass(class_));
210                    }
211                    return false;
212            }
213    
214    }