1 |
/* java.lang.Package - Everything you ever wanted to know about a package. |
/* Package.java -- information about a package |
2 |
Copyright (C) 2000, 2001 Free Software Foundation, Inc. |
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. |
3 |
|
|
4 |
This file is part of GNU Classpath. |
This file is part of GNU Classpath. |
5 |
|
|
49 |
* section of the |
* section of the |
50 |
* <a href="http://java.sun.com/products/jdk/1.3/docs/guide/versioning/spec/VersioningSpecification.html">Product Versioning Specification</a>. |
* <a href="http://java.sun.com/products/jdk/1.3/docs/guide/versioning/spec/VersioningSpecification.html">Product Versioning Specification</a>. |
51 |
* It also allows packages to be sealed with respect to the originating URL. |
* It also allows packages to be sealed with respect to the originating URL. |
52 |
* <p> |
* |
53 |
* The most usefull method is the <code>isCompatibleWith()</code> method that |
* <p>The most useful method is the <code>isCompatibleWith()</code> method that |
54 |
* compares a desired version of a specification with the version of the |
* compares a desired version of a specification with the version of the |
55 |
* specification as implemented by a package. A package is considered |
* specification as implemented by a package. A package is considered |
56 |
* compatible with another version if the version of the specification is |
* compatible with another version if the version of the specification is |
63 |
* then the other version, etc. (If a version has no minor, micro, etc numbers |
* then the other version, etc. (If a version has no minor, micro, etc numbers |
64 |
* then they are considered the be 0.) |
* then they are considered the be 0.) |
65 |
* |
* |
66 |
|
* @author Mark Wielaard <mark@klomp.org> |
67 |
|
* @see ClassLoader#definePackage(String, String, String, String, String, |
68 |
|
* String, String, URL) |
69 |
* @since 1.2 |
* @since 1.2 |
70 |
* @author Mark Wielaard (mark@klomp.org) |
* @status updated to 1.4 |
71 |
*/ |
*/ |
72 |
public class Package |
public class Package |
73 |
{ |
{ |
76 |
|
|
77 |
/** The name if the implementation */ |
/** The name if the implementation */ |
78 |
final private String implTitle; |
final private String implTitle; |
79 |
|
|
80 |
/** The vendor that wrote this implementation */ |
/** The vendor that wrote this implementation */ |
81 |
final private String implVendor; |
final private String implVendor; |
82 |
|
|
83 |
/** The version of this implementation */ |
/** The version of this implementation */ |
84 |
final private String implVersion; |
final private String implVersion; |
85 |
|
|
86 |
/** The name of the specification */ |
/** The name of the specification */ |
87 |
final private String specTitle; |
final private String specTitle; |
88 |
|
|
89 |
/** The name of the specification designer */ |
/** The name of the specification designer */ |
90 |
final private String specVendor; |
final private String specVendor; |
91 |
|
|
92 |
/** The version of this specification */ |
/** The version of this specification */ |
93 |
final private String specVersion; |
final private String specVersion; |
94 |
|
|
95 |
/** If sealed the origin of the package classes, otherwise null */ |
/** If sealed the origin of the package classes, otherwise null */ |
96 |
final private URL sealed; |
final private URL sealed; |
97 |
|
|
98 |
/** |
/** |
99 |
* A package local constructor for the Package class. |
* A package local constructor for the Package class. All parameters except |
100 |
* All parameters except the <code>name</code> of the package may be |
* the <code>name</code> of the package may be <code>null</code>. |
101 |
* <code>null</code>. |
* There are no public constructors defined for Package; this is a package |
|
* There are no public constructors defined for Package this is a package |
|
102 |
* local constructor that is used by java.lang.Classloader.definePackage(). |
* local constructor that is used by java.lang.Classloader.definePackage(). |
103 |
* |
* |
104 |
* @param name The name of the Package |
* @param name the name of the Package |
105 |
* @param specTitle The name of the specification |
* @param specTitle the name of the specification |
106 |
* @param specVendor The name of the specification designer |
* @param specVendor the name of the specification designer |
107 |
* @param specVersion The version of this specification |
* @param specVersion the version of this specification |
108 |
* @param implTitle The name of the implementation |
* @param implTitle the name of the implementation |
109 |
* @param implVendor The vendor that wrote this implementation |
* @param implVendor the vendor that wrote this implementation |
110 |
* @param implVersion The version of this implementation |
* @param implVersion the version of this implementation |
111 |
* @param sealed If sealed the origin of the package classes |
* @param sealed if sealed the origin of the package classes |
112 |
*/ |
*/ |
113 |
Package(String name, |
Package(String name, |
114 |
String specTitle, String specVendor, String specVersion, |
String specTitle, String specVendor, String specVersion, |
116 |
{ |
{ |
117 |
if (name == null) |
if (name == null) |
118 |
throw new IllegalArgumentException("null Package name"); |
throw new IllegalArgumentException("null Package name"); |
|
|
|
119 |
this.name = name; |
this.name = name; |
|
|
|
120 |
this.implTitle = implTitle; |
this.implTitle = implTitle; |
121 |
this.implVendor = implVendor; |
this.implVendor = implVendor; |
122 |
this.implVersion = implVersion; |
this.implVersion = implVersion; |
|
|
|
123 |
this.specTitle = specTitle; |
this.specTitle = specTitle; |
124 |
this.specVendor = specVendor; |
this.specVendor = specVendor; |
125 |
this.specVersion = specVersion; |
this.specVersion = specVersion; |
|
|
|
126 |
this.sealed = sealed; |
this.sealed = sealed; |
127 |
} |
} |
128 |
|
|
129 |
/** |
/** |
130 |
* Returns the Package name. |
* Returns the Package name in dot-notation. |
131 |
|
* |
132 |
|
* @return the non-null package name |
133 |
*/ |
*/ |
134 |
public String getName() |
public String getName() |
135 |
{ |
{ |
136 |
return name; |
return name; |
137 |
} |
} |
138 |
|
|
139 |
/** |
/** |
140 |
* Returns the name of the implementation or null if unknown. |
* Returns the name of the specification, or null if unknown. |
141 |
|
* |
142 |
|
* @return the specification title |
143 |
*/ |
*/ |
144 |
public String getImplementationTitle() |
public String getSpecificationTitle() |
145 |
{ |
{ |
146 |
return implTitle; |
return specTitle; |
147 |
} |
} |
148 |
|
|
149 |
/** |
/** |
150 |
* Returns the vendor that wrote this implementation or null if unknown. |
* Returns the version of the specification, or null if unknown. |
151 |
|
* |
152 |
|
* @return the specification version |
153 |
*/ |
*/ |
154 |
public String getImplementationVendor() |
public String getSpecificationVersion() |
155 |
{ |
{ |
156 |
return implVendor; |
return specVersion; |
157 |
} |
} |
158 |
|
|
159 |
/** |
/** |
160 |
* Returns the version of this implementation or null if unknown. |
* Returns the name of the specification designer, or null if unknown. |
161 |
|
* |
162 |
|
* @return the specification vendor |
163 |
*/ |
*/ |
164 |
public String getImplementationVersion() |
public String getSpecificationVendor() |
165 |
{ |
{ |
166 |
return implVersion; |
return specVendor; |
167 |
} |
} |
168 |
|
|
169 |
/** |
/** |
170 |
* Returns the name of the specification or null if unknown. |
* Returns the name of the implementation, or null if unknown. |
171 |
|
* |
172 |
|
* @return the implementation title |
173 |
*/ |
*/ |
174 |
public String getSpecificationTitle() |
public String getImplementationTitle() |
175 |
{ |
{ |
176 |
return specTitle; |
return implTitle; |
177 |
} |
} |
178 |
|
|
179 |
/** |
/** |
180 |
* Returns the name of the specification designer or null if unknown. |
* Returns the version of this implementation, or null if unknown. |
181 |
|
* |
182 |
|
* @return the implementation version |
183 |
*/ |
*/ |
184 |
public String getSpecificationVendor() |
public String getImplementationVersion() |
185 |
{ |
{ |
186 |
return specVendor; |
return implVersion; |
187 |
} |
} |
188 |
|
|
189 |
/** |
/** |
190 |
* Returns the version of the specification or null if unknown. |
* Returns the vendor that wrote this implementation, or null if unknown. |
191 |
|
* |
192 |
|
* @return the implementation vendor |
193 |
*/ |
*/ |
194 |
public String getSpecificationVersion() |
public String getImplementationVendor() |
195 |
{ |
{ |
196 |
return specVersion; |
return implVendor; |
197 |
} |
} |
198 |
|
|
199 |
/** |
/** |
200 |
* Returns true if this Package is sealed. |
* Returns true if this Package is sealed. |
201 |
|
* |
202 |
|
* @return true if the package is sealed |
203 |
*/ |
*/ |
204 |
public boolean isSealed() |
public boolean isSealed() |
205 |
{ |
{ |
206 |
return (sealed != null); |
return sealed != null; |
207 |
} |
} |
208 |
|
|
209 |
/** |
/** |
210 |
* Returns true if this Package is sealed and the origin of the classes is |
* Returns true if this Package is sealed and the origin of the classes is |
211 |
* the given URL. |
* the given URL. |
212 |
* |
* |
213 |
* @param url |
* @param url the URL to test |
214 |
|
* @return true if the package is sealed by this URL |
215 |
|
* @throws NullPointerException if url is null |
216 |
*/ |
*/ |
217 |
public boolean isSealed(URL url) |
public boolean isSealed(URL url) |
218 |
{ |
{ |
221 |
|
|
222 |
/** |
/** |
223 |
* Checks if the version of the specification is higher or at least as high |
* Checks if the version of the specification is higher or at least as high |
224 |
* as the desired version. |
* as the desired version. Comparison is done by sequentially comparing |
225 |
|
* dotted decimal numbers from the parameter and from |
226 |
|
* <code>getSpecificationVersion</code>. |
227 |
|
* |
228 |
* @param version the (minimal) desired version of the specification |
* @param version the (minimal) desired version of the specification |
229 |
* @exception NumberFormatException when either version or the |
* @throws NumberFormatException if either version string is invalid |
230 |
* specification version is not a correctly formatted version number |
* @throws NullPointerException if either version string is null |
|
* @exception NullPointerException if the supplied version or the |
|
|
* Package specification version is null. |
|
231 |
*/ |
*/ |
232 |
public boolean isCompatibleWith(String version) throws NumberFormatException |
public boolean isCompatibleWith(String version) |
233 |
{ |
{ |
234 |
StringTokenizer versionTokens = new StringTokenizer(version, "."); |
StringTokenizer versionTokens = new StringTokenizer(version, "."); |
235 |
StringTokenizer specTokens = new StringTokenizer(specVersion, "."); |
StringTokenizer specTokens = new StringTokenizer(specVersion, "."); |
236 |
try |
try |
237 |
{ |
{ |
238 |
while (versionTokens.hasMoreElements()) |
while (versionTokens.hasMoreElements()) |
239 |
{ |
{ |
240 |
int vers = Integer.parseInt(versionTokens.nextToken()); |
int vers = Integer.parseInt(versionTokens.nextToken()); |
241 |
int spec = Integer.parseInt(specTokens.nextToken()); |
int spec = Integer.parseInt(specTokens.nextToken()); |
242 |
if (spec < vers) |
if (spec < vers) |
243 |
return false; |
return false; |
244 |
else if (spec > vers) |
else if (spec > vers) |
245 |
return true; |
return true; |
246 |
// They must be equal, next Token please! |
// They must be equal, next Token please! |
247 |
} |
} |
248 |
} |
} |
249 |
catch (NoSuchElementException e) |
catch (NoSuchElementException e) |
250 |
{ |
{ |
251 |
// this must have been thrown by spec.netToken() so return false |
// This must have been thrown by spec.nextToken() so return false. |
252 |
return false; |
return false; |
253 |
} |
} |
|
|
|
254 |
// They must have been exactly the same version. |
// They must have been exactly the same version. |
255 |
// Or the specVersion has more subversions. That is also good. |
// Or the specVersion has more subversions. That is also good. |
256 |
return true; |
return true; |
261 |
* It may return null if the package is unknown, when there is no |
* It may return null if the package is unknown, when there is no |
262 |
* information on that particular package available or when the callers |
* information on that particular package available or when the callers |
263 |
* classloader is null. |
* classloader is null. |
264 |
|
* |
265 |
* @param name the name of the desired package |
* @param name the name of the desired package |
266 |
|
* @return the package by that name in the current ClassLoader |
267 |
*/ |
*/ |
268 |
public static Package getPackage(String name) |
public static Package getPackage(String name) |
269 |
{ |
{ |
270 |
// Get the caller's classloader |
// Get the caller's classloader |
271 |
Class c = VMSecurityManager.getClassContext()[1]; |
Class c = VMSecurityManager.getClassContext()[1]; |
272 |
ClassLoader cl = c.getClassLoader(); |
ClassLoader cl = c.getClassLoader(); |
273 |
|
return cl != null ? cl.getPackage(name) : null; |
|
if (cl != null) |
|
|
return cl.getPackage(name); |
|
|
else |
|
|
return null; |
|
274 |
} |
} |
275 |
|
|
276 |
/** |
/** |
277 |
* Returns all the packages that are known to the callers class loader. |
* Returns all the packages that are known to the callers class loader. |
278 |
* It may return an empty array if the classloader of the caller is null. |
* It may return an empty array if the classloader of the caller is null. |
279 |
|
* |
280 |
|
* @return an array of all known packages |
281 |
*/ |
*/ |
282 |
public static Package[] getPackages() |
public static Package[] getPackages() |
283 |
{ |
{ |
284 |
// Get the caller's classloader |
// Get the caller's classloader |
285 |
Class c = VMSecurityManager.getClassContext()[1]; |
Class c = VMSecurityManager.getClassContext()[1]; |
286 |
ClassLoader cl = c.getClassLoader(); |
ClassLoader cl = c.getClassLoader(); |
287 |
|
// Sun's implementation returns the packages loaded by the bootstrap |
288 |
if (cl != null) |
// classloader if cl is null, but right now our bootstrap classloader |
289 |
return cl.getPackages(); |
// does not create any Packages. |
290 |
else |
return cl != null ? cl.getPackages() : new Package[0]; |
|
return new Package[0]; |
|
291 |
} |
} |
292 |
|
|
293 |
/** |
/** |
294 |
* Returns the hashCode of the name of this package. |
* Returns the hashCode of the name of this package. |
295 |
|
* |
296 |
|
* @return the hash code |
297 |
*/ |
*/ |
298 |
public int hashCode() |
public int hashCode() |
299 |
{ |
{ |
300 |
return name.hashCode(); |
return name.hashCode(); |
301 |
} |
} |
302 |
|
|
303 |
/** |
/** |
304 |
* Returns a string representation of this package name, specification, |
* Returns a string representation of this package. It is specified to |
305 |
* implementation and class origin if sealed. |
* be <code>"package " + getName() + (getSpecificationTitle() == null |
306 |
|
* ? "" : ", " + getSpecificationTitle()) + (getSpecificationVersion() |
307 |
|
* == null ? "" : ", version " + getSpecificationVersion())</code>. |
308 |
|
* |
309 |
|
* @return the string representation of the package |
310 |
*/ |
*/ |
311 |
public String toString() |
public String toString() |
312 |
{ |
{ |
313 |
return "package: " + name + |
return "package " + name + (specTitle == null ? "" : ", " + specTitle) |
314 |
" spec: " + specTitle + |
+ (specVersion == null ? "" : ", version " + specVersion); |
|
" version: " + specVersion + |
|
|
" vendor: " + specVendor + |
|
|
" implementation: " + implTitle + |
|
|
" version: " + implVersion + |
|
|
" vendor: " + implVendor + " sealed: " + sealed; |
|
315 |
} |
} |
316 |
} |
} // class Package |