001 package edu.rice.cs.cunit.subAnnot; 002 003 import edu.rice.cs.cunit.classFile.ClassFileTools; 004 import edu.rice.cs.cunit.classFile.attributes.RuntimeVisibleAnnotationsAttributeInfo; 005 006 import java.lang.reflect.AnnotatedElement; 007 import java.util.ArrayList; 008 import java.util.List; 009 import java.net.URL; 010 import java.io.IOException; 011 012 /** 013 * Extended Package class to support annotations with subclassing. 014 * 015 * @author Mathias Ricken 016 */ 017 public class PackageEx extends AAnnotatedElementEx { 018 /** 019 * The java.lang.reflect.Package object that represents the package. 020 */ 021 public final Package java; 022 023 /** 024 * Return an extended Package instance for the class with the specified package name. 025 * @param s package name 026 * @return package 027 */ 028 @SuppressWarnings("unchecked") 029 public static PackageEx getPackage(String s) { 030 return new PackageEx(Package.getPackage(s)); 031 } 032 033 /** 034 * Return an array of all extended Package instances known to the caller's ClassLoader instance. 035 * @return array of packages 036 */ 037 @SuppressWarnings("unchecked") 038 public static PackageEx[] getPackages() { 039 List<PackageEx> list = new ArrayList<PackageEx>(); 040 for(Package p: Package.getPackages()) { 041 list.add(new PackageEx(p)); 042 } 043 return list.toArray(new PackageEx[list.size()]); 044 } 045 046 /** 047 * Create an extended Package instance for the specified package. 048 * @param p package 049 */ 050 public PackageEx(Package p) { 051 this(p, null); 052 } 053 054 /** 055 * Create an extended Package instance for the specified package. 056 * @param p package 057 * @param c class loader 058 */ 059 public PackageEx(Package p, ClassLoader c) { 060 super(c); 061 java = p; 062 ClassFileTools.ClassLocation cl = ClassFileTools.findClassFile(java.getName()+".package-info", _classPath); 063 if (cl==null) { _ai = null; return; } 064 _ai = new RuntimeVisibleAnnotationsAttributeInfo[1]; 065 _ai[0] = (RuntimeVisibleAnnotationsAttributeInfo) 066 cl.getClassFile().getAttribute(RuntimeVisibleAnnotationsAttributeInfo.getAttributeName()); 067 try { 068 cl.close(); 069 } 070 catch(IOException e) { /* ignore */ } 071 } 072 073 /** 074 * Return the annotated element. 075 * 076 * @return annotated element 077 */ 078 protected AnnotatedElement getAnnotatedElement() { 079 return java; 080 } 081 082 /** 083 * Return the name of this package. 084 * 085 * @return The name of this package using the Java language dot notation for the package. i.e java.lang 086 */ 087 public String getName() { 088 return java.getName(); 089 } 090 091 /** 092 * Return the title of the specification that this package implements. 093 * 094 * @return the specification title, null is returned if it is not known. 095 */ 096 public String getSpecificationTitle() { 097 return java.getSpecificationTitle(); 098 } 099 100 /** 101 * Returns the version number of the specification that this package implements. This version string must be a 102 * sequence of positive decimal integers separated by "."'s and may have leading zeros. When version strings are 103 * compared the most significant numbers are compared. 104 * 105 * @return the specification version, null is returned if it is not known. 106 */ 107 public String getSpecificationVersion() { 108 return java.getSpecificationVersion(); 109 } 110 111 /** 112 * Return the name of the organization, vendor, or company that owns and maintains the specification of the classes 113 * that implement this package. 114 * 115 * @return the specification vendor, null is returned if it is not known. 116 */ 117 public String getSpecificationVendor() { 118 return java.getSpecificationVendor(); 119 } 120 121 /** 122 * Return the title of this package. 123 * 124 * @return the title of the implementation, null is returned if it is not known. 125 */ 126 public String getImplementationTitle() { 127 return java.getImplementationTitle(); 128 } 129 130 /** 131 * Return the version of this implementation. It consists of any string assigned by the vendor of this 132 * implementation and does not have any particular syntax specified or expected by the Java runtime. It may be 133 * compared for equality with other package version strings used for this implementation by this vendor for this 134 * package. 135 * 136 * @return the version of the implementation, null is returned if it is not known. 137 */ 138 public String getImplementationVersion() { 139 return java.getImplementationVersion(); 140 } 141 142 /** 143 * Returns the name of the organization, vendor or company that provided this implementation. 144 * 145 * @return the vendor that implemented this package.. 146 */ 147 public String getImplementationVendor() { 148 return java.getImplementationVendor(); 149 } 150 151 /** 152 * Returns true if this package is sealed. 153 * 154 * @return true if the package is sealed, false otherwise 155 */ 156 public boolean isSealed() { 157 return java.isSealed(); 158 } 159 160 /** 161 * Returns true if this package is sealed with respect to the specified code source url. 162 * 163 * @param url the code source url 164 * 165 * @return true if this package is sealed with respect to url 166 */ 167 public boolean isSealed(URL url) { 168 return java.isSealed(url); 169 } 170 171 /** 172 * Compare this package's specification version with a desired version. It returns true if this packages 173 * specification version number is greater than or equal to the desired version number. <p> 174 * <p/> 175 * Version numbers are compared by sequentially comparing corresponding components of the desired and specification 176 * strings. Each component is converted as a decimal integer and the values compared. If the specification value is 177 * greater than the desired value true is returned. If the value is less false is returned. If the values are equal 178 * the period is skipped and the next pair of components is compared. 179 * 180 * @param desired the version string of the desired version. 181 * 182 * @return true if this package's version number is greater than or equal to the desired version number 183 * 184 * @throws NumberFormatException if the desired or current version is not of the correct dotted form. 185 */ 186 public boolean isCompatibleWith(String desired) throws NumberFormatException { 187 return java.isCompatibleWith(desired); 188 } 189 190 /** 191 * Return the hash code computed from the package name. 192 * 193 * @return the hash code computed from the package name. 194 */ 195 public int hashCode() { 196 return java.hashCode(); 197 } 198 199 /** 200 * Returns the string representation of this Package. Its value is the string "package " and the package name. If 201 * the package title is defined it is appended. If the package version is defined it is appended. 202 * 203 * @return the string representation of the package. 204 */ 205 public String toString() { 206 return java.toString(); 207 } 208 209 /** 210 * Compares this <code>Constructor</code> against the specified object. Returns true if the objects are the same. Two 211 * <code>Constructor</code> objects are the same if they were declared by the same class and have the same formal 212 * parameter types. 213 */ 214 public boolean equals(Object obj) { 215 return (obj!=null)&&(obj.getClass().equals(this.getClass()) && (java.equals(obj))); 216 } 217 }