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 }