Hi,

This patch merges the package annotation support I just checked into the
generics branch back to the trunk. Note again that if you're a VM
maintainer and you use a custom version of
VMClassLoader, this is a breaking change and your version of
VMClassLoader will have to be updated as well (simply add an extra null
parameter to the Package constructor).

Regards,
Jeroen

2006-04-23  Jeroen Frijters  <[EMAIL PROTECTED]>

        * java/lang/ClassLoader.java (definePackage): Added argument to
        Package constructor.
        * java/lang/Package.java (Package): Added ClassLoader argument.
        (loader): New field.
        (getAnnotation, getAnnotations, getDeclaredAnnotations,
        isAnnotationPresent): Merged from generics branch.
        * vm/reference/java/lang/VMClassLoader.java (static): Added
argument
        to Package constructor.
Index: java/lang/ClassLoader.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/ClassLoader.java,v
retrieving revision 1.60
diff -u -r1.60 ClassLoader.java
--- java/lang/ClassLoader.java  22 Apr 2006 22:22:08 -0000      1.60
+++ java/lang/ClassLoader.java  23 Apr 2006 09:46:51 -0000
@@ -836,7 +836,7 @@
       throw new IllegalArgumentException("Package " + name
                                          + " already defined");
     Package p = new Package(name, specTitle, specVendor, specVersion,
-                            implTitle, implVendor, implVersion, sealed);
+                            implTitle, implVendor, implVersion, sealed, this);
     synchronized (definedPackages)
       {
         definedPackages.put(name, p);
Index: java/lang/Package.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/Package.java,v
retrieving revision 1.17
diff -u -r1.17 Package.java
--- java/lang/Package.java      2 Jul 2005 20:32:38 -0000       1.17
+++ java/lang/Package.java      23 Apr 2006 09:46:04 -0000
@@ -39,6 +39,8 @@
 
 import gnu.classpath.VMStackWalker;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
 import java.net.URL;
 import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
@@ -70,9 +72,10 @@
  * @see ClassLoader#definePackage(String, String, String, String, String,
  *      String, String, URL)
  * @since 1.2
- * @status updated to 1.4
+ * @status updated to 1.5
  */
 public class Package
+  implements AnnotatedElement
 {
   /** The name of the Package */
   private final String name;
@@ -98,6 +101,9 @@
   /** If sealed the origin of the package classes, otherwise null */
   private final URL sealed;
 
+  /** The class loader that defined this package */
+  private ClassLoader loader;
+
   /**
    * A package local constructor for the Package class. All parameters except
    * the <code>name</code> of the package may be <code>null</code>.
@@ -115,7 +121,8 @@
    */
   Package(String name,
          String specTitle, String specVendor, String specVersion,
-         String implTitle, String implVendor, String implVersion, URL sealed)
+         String implTitle, String implVendor, String implVersion, URL sealed,
+          ClassLoader loader)
   {
     if (name == null)
       throw new IllegalArgumentException("null Package name");
@@ -128,6 +135,7 @@
     this.specVendor = specVendor;
     this.specVersion = specVersion;
     this.sealed = sealed;
+    this.loader = loader;
   }
 
   /**
@@ -233,7 +241,7 @@
    *
    * @return true if the version is compatible, false otherwise
    *
-   * @Throws NumberFormatException if either version string is invalid
+   * @throws NumberFormatException if either version string is invalid
    * @throws NullPointerException if either version string is null
    */
   public boolean isCompatibleWith(String version)
@@ -315,4 +323,82 @@
     return ("package " + name + (specTitle == null ? "" : ", " + specTitle)
            + (specVersion == null ? "" : ", version " + specVersion));
   }
+
+  /**
+   * Returns this package's 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 package's 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 package.  If there are
+   * no annotations associated with this package, 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
+   * package, and hence no effect on the return value of this method for
+   * future callers.
+   *
+   * @return this package' annotations.
+   * @since 1.5
+   */
+  public Annotation[] getAnnotations()
+  {
+    /** All a package's annotations are declared within it. */
+    return getDeclaredAnnotations();
+  }
+
+  /**
+   * Returns all annotations directly defined by this package.  If there are
+   * no annotations associated with this package, 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
+   * package, and hence no effect on the return value of this method for
+   * future callers.
+   *
+   * @return the annotations directly defined by this package.
+   * @since 1.5
+   */
+  public Annotation[] getDeclaredAnnotations()
+  {
+    try
+      {
+        Class pkgInfo = Class.forName(name + ".package-info", false, loader);
+        return pkgInfo.getDeclaredAnnotations();
+      }
+    catch (ClassNotFoundException _)
+      {
+        return new Annotation[0];
+      }
+  }
+
+  /**
+   * Returns true if an annotation for the specified type is associated
+   * with this package.  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]: Signature is Class<? extends Annotation> */
+  public boolean isAnnotationPresent(Class
+                                    annotationClass)
+  {
+    return getAnnotation(annotationClass) != null;
+  }
+
 } // class Package
Index: vm/reference/java/lang/VMClassLoader.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/vm/reference/java/lang/VMClassLoader.java,v
retrieving revision 1.36
diff -u -r1.36 VMClassLoader.java
--- vm/reference/java/lang/VMClassLoader.java   19 Apr 2006 15:47:43 -0000      
1.36
+++ vm/reference/java/lang/VMClassLoader.java   23 Apr 2006 09:48:37 -0000
@@ -104,6 +104,7 @@
                   "GNU Classpath",
                   "GNU",
                   Configuration.CLASSPATH_VERSION,
+                  null,
                   null);
 
             definedPackages.put(packages[i], p);

Reply via email to