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 java = p;
052 ClassFileTools.ClassLocation cl = ClassFileTools.findClassFile(java.getName()+".package-info", _classPath);
053 if (cl==null) { _ai = null; return; }
054 _ai = new RuntimeVisibleAnnotationsAttributeInfo[0];
055 _ai[0] = (RuntimeVisibleAnnotationsAttributeInfo)
056 cl.getClassFile().getAttribute(RuntimeVisibleAnnotationsAttributeInfo.getAttributeName());
057 try {
058 cl.close();
059 }
060 catch(IOException e) { /* ignore */ }
061 }
062
063 /**
064 * Return the annotated element.
065 *
066 * @return annotated element
067 */
068 protected AnnotatedElement getAnnotatedElement() {
069 return java;
070 }
071
072 /**
073 * Return the name of this package.
074 *
075 * @return The name of this package using the Java language dot notation for the package. i.e java.lang
076 */
077 public String getName() {
078 return java.getName();
079 }
080
081 /**
082 * Return the title of the specification that this package implements.
083 *
084 * @return the specification title, null is returned if it is not known.
085 */
086 public String getSpecificationTitle() {
087 return java.getSpecificationTitle();
088 }
089
090 /**
091 * Returns the version number of the specification that this package implements. This version string must be a
092 * sequence of positive decimal integers separated by "."'s and may have leading zeros. When version strings are
093 * compared the most significant numbers are compared.
094 *
095 * @return the specification version, null is returned if it is not known.
096 */
097 public String getSpecificationVersion() {
098 return java.getSpecificationVersion();
099 }
100
101 /**
102 * Return the name of the organization, vendor, or company that owns and maintains the specification of the classes
103 * that implement this package.
104 *
105 * @return the specification vendor, null is returned if it is not known.
106 */
107 public String getSpecificationVendor() {
108 return java.getSpecificationVendor();
109 }
110
111 /**
112 * Return the title of this package.
113 *
114 * @return the title of the implementation, null is returned if it is not known.
115 */
116 public String getImplementationTitle() {
117 return java.getImplementationTitle();
118 }
119
120 /**
121 * Return the version of this implementation. It consists of any string assigned by the vendor of this
122 * implementation and does not have any particular syntax specified or expected by the Java runtime. It may be
123 * compared for equality with other package version strings used for this implementation by this vendor for this
124 * package.
125 *
126 * @return the version of the implementation, null is returned if it is not known.
127 */
128 public String getImplementationVersion() {
129 return java.getImplementationVersion();
130 }
131
132 /**
133 * Returns the name of the organization, vendor or company that provided this implementation.
134 *
135 * @return the vendor that implemented this package..
136 */
137 public String getImplementationVendor() {
138 return java.getImplementationVendor();
139 }
140
141 /**
142 * Returns true if this package is sealed.
143 *
144 * @return true if the package is sealed, false otherwise
145 */
146 public boolean isSealed() {
147 return java.isSealed();
148 }
149
150 /**
151 * Returns true if this package is sealed with respect to the specified code source url.
152 *
153 * @param url the code source url
154 *
155 * @return true if this package is sealed with respect to url
156 */
157 public boolean isSealed(URL url) {
158 return java.isSealed(url);
159 }
160
161 /**
162 * Compare this package's specification version with a desired version. It returns true if this packages
163 * specification version number is greater than or equal to the desired version number. <p>
164 * <p/>
165 * Version numbers are compared by sequentially comparing corresponding components of the desired and specification
166 * strings. Each component is converted as a decimal integer and the values compared. If the specification value is
167 * greater than the desired value true is returned. If the value is less false is returned. If the values are equal
168 * the period is skipped and the next pair of components is compared.
169 *
170 * @param desired the version string of the desired version.
171 *
172 * @return true if this package's version number is greater than or equal to the desired version number
173 *
174 * @throws NumberFormatException if the desired or current version is not of the correct dotted form.
175 */
176 public boolean isCompatibleWith(String desired) throws NumberFormatException {
177 return java.isCompatibleWith(desired);
178 }
179
180 /**
181 * Return the hash code computed from the package name.
182 *
183 * @return the hash code computed from the package name.
184 */
185 public int hashCode() {
186 return java.hashCode();
187 }
188
189 /**
190 * Returns the string representation of this Package. Its value is the string "package " and the package name. If
191 * the package title is defined it is appended. If the package version is defined it is appended.
192 *
193 * @return the string representation of the package.
194 */
195 public String toString() {
196 return java.toString();
197 }
198
199 /**
200 * Compares this <code>Constructor</code> against the specified object. Returns true if the objects are the same. Two
201 * <code>Constructor</code> objects are the same if they were declared by the same class and have the same formal
202 * parameter types.
203 */
204 public boolean equals(Object obj) {
205 return (obj!=null)&&(obj.getClass().equals(this.getClass()) && (java.equals(obj)));
206 }
207 }