Hi, I moved getEnumConstant from VMClass to Class in this version of the patch. Again, unless anyone complains this will go in sometime next week.
Regards, Jeroen
Index: java/lang/Class.java =================================================================== RCS file: /cvsroot/classpath/classpath/java/lang/Class.java,v retrieving revision 1.47 diff -u -r1.47 Class.java --- java/lang/Class.java 7 Apr 2006 19:45:45 -0000 1.47 +++ java/lang/Class.java 22 Apr 2006 09:09:25 -0000 @@ -1,5 +1,5 @@ /* Class.java -- Representation of a Java class. - Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005 + Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation This file is part of GNU Classpath. @@ -44,7 +44,9 @@ import java.io.InputStream; import java.io.ObjectStreamClass; import java.io.Serializable; +import java.lang.annotation.Annotation; import java.lang.reflect.Array; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericDeclaration; @@ -100,7 +102,7 @@ * @see ClassLoader */ public final class Class - implements Serializable, Type, GenericDeclaration + implements Serializable, Type, AnnotatedElement, GenericDeclaration { /** * Compatible with JDK 1.0+. @@ -640,17 +642,16 @@ public boolean equals(Object o) { - if(o instanceof MethodKey) + if (o instanceof MethodKey) { - MethodKey m = (MethodKey)o; - if(m.name.equals(name) && m.params.length == params.length && m.returnType == returnType) + MethodKey m = (MethodKey) o; + if (m.name.equals(name) && m.params.length == params.length + && m.returnType == returnType) { - for(int i = 0; i < params.length; i++) + for (int i = 0; i < params.length; i++) { - if(m.params[i] != params[i]) - { - return false; - } + if (m.params[i] != params[i]) + return false; } return true; } @@ -1260,7 +1261,7 @@ return c.defaultAssertionStatus; } - /* + /** * <p> * Casts this class to represent a subclass of the specified class. * This method is useful for `narrowing' the type of a class so that @@ -1369,6 +1370,46 @@ } /** + * Returns the enumeration constants of this class, or + * null if this class is not an <code>Enum</code>. + * + * @return an array of <code>Enum</code> constants + * associated with this class, or null if this + * class is not an <code>enum</code>. + * @since 1.5 + */ + /* FIXME[GENERICS]: T[] getEnumConstants() */ + public Object[] getEnumConstants() + { + if (isEnum()) + { + try + { + return (Object[]) + getMethod("values", new Class[0]).invoke(null, new Object[0]); + } + catch (NoSuchMethodException exception) + { + throw new Error("Enum lacks values() method"); + } + catch (IllegalAccessException exception) + { + throw new Error("Unable to access Enum class"); + } + catch (InvocationTargetException exception) + { + throw new + RuntimeException("The values method threw an exception", + exception); + } + } + else + { + return null; + } + } + + /** * Returns true if this class is an <code>Enum</code>. * * @return true if this is an enumeration class. @@ -1421,6 +1462,50 @@ } /** + * Returns this class' annotation for the specified annotation type, + * or <code>null</code> if no such annotation exists. + * + * @param annotationClass the type of annotation to look for. + * @return this class' annotation for the specified type, or + * <code>null</code> if no such annotation exists. + * @since 1.5 + */ + /* FIXME[GENERICS]: <T extends Annotation> T getAnnotation(Class <T>) */ + public Annotation getAnnotation(Class annotationClass) + { + Annotation foundAnnotation = null; + Annotation[] annotations = getAnnotations(); + for (int i = 0; i < annotations.length; i++) + if (annotations[i].annotationType() == annotationClass) + foundAnnotation = annotations[i]; + return foundAnnotation; + } + + /** + * Returns all annotations associated with this class. If there are + * no annotations associated with this class, then a zero-length array + * will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * class, and hence no effect on the return value of this method for + * future callers. + * + * @return this class' annotations. + * @since 1.5 + */ + public Annotation[] getAnnotations() + { + HashSet set = new HashSet(); + set.addAll(Arrays.asList(getDeclaredAnnotations())); + Class[] interfaces = getInterfaces(); + for (int i = 0; i < interfaces.length; i++) + set.addAll(Arrays.asList(interfaces[i].getAnnotations())); + Class superClass = getSuperclass(); + if (superClass != null) + set.addAll(Arrays.asList(superClass.getAnnotations())); + return (Annotation[]) set.toArray(new Annotation[set.size()]); + } + + /** * <p> * Returns the canonical name of this class, as defined by section * 6.7 of the Java language specification. Each package, top-level class, @@ -1460,6 +1545,22 @@ } /** + * Returns all annotations directly defined by this class. If there are + * no annotations associated with this class, then a zero-length array + * will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * class, and hence no effect on the return value of this method for + * future callers. + * + * @return the annotations directly defined by this class. + * @since 1.5 + */ + public Annotation[] getDeclaredAnnotations() + { + return VMClass.getDeclaredAnnotations(this); + } + + /** * Returns the class which immediately encloses this class. If this class * is a top-level class, this method returns <code>null</code>. * @@ -1622,6 +1723,22 @@ } /** + * Returns true if an annotation for the specified type is associated + * with this class. This is primarily a short-hand for using marker + * annotations. + * + * @param annotationClass the type of annotation to look for. + * @return true if an annotation exists for the specified type. + * @since 1.5 + */ + /* FIXME[GENERICS]: Should be Class<? extends Annotation> */ + public boolean isAnnotationPresent(Class + annotationClass) + { + return getAnnotation(annotationClass) != null; + } + + /** * Returns true if this object represents an anonymous class. * * @return true if this object represents an anonymous class. Index: vm/reference/java/lang/VMClass.java =================================================================== RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/VMClass.java,v retrieving revision 1.16 diff -u -r1.16 VMClass.java --- vm/reference/java/lang/VMClass.java 3 Apr 2006 20:09:14 -0000 1.16 +++ vm/reference/java/lang/VMClass.java 22 Apr 2006 09:06:54 -0000 @@ -1,5 +1,5 @@ /* VMClass.java -- VM Specific Class methods - Copyright (C) 2003, 2004, 2005 Free Software Foundation + Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation This file is part of GNU Classpath. @@ -37,6 +37,7 @@ package java.lang; +import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -331,6 +332,20 @@ } /** + * Returns all annotations directly defined by the specified class. If + * there are no annotations associated with this class, then a zero-length + * array will be returned. The returned array may be modified by the client + * code, but this will have no effect on the annotation content of this + * class, and hence no effect on the return value of this method for + * future callers. + * + * @param klass the class whose annotations should be returned. + * @return the annotations directly defined by the specified class. + * @since 1.5 + */ + static native Annotation[] getDeclaredAnnotations(Class klass); + + /** * <p> * Returns the canonical name of the specified class, as defined by section * 6.7 of the Java language specification. Each package, top-level class,