1 /* Package.java -- information about a package
2 Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java
.util
.NoSuchElementException
;
42 import java
.util
.StringTokenizer
;
45 * Everything you ever wanted to know about a package. This class makes it
46 * possible to attach specification and implementation information to a
47 * package as explained in the
48 * <a href="http://java.sun.com/products/jdk/1.3/docs/guide/versioning/spec/VersioningSpecification.html#PackageVersionSpecification">Package Versioning Specification</a>
50 * <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.
53 * <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
55 * specification as implemented by a package. A package is considered
56 * compatible with another version if the version of the specification is
57 * equal or higher then the requested version. Version numbers are represented
58 * as strings of positive numbers separated by dots (e.g. "1.2.0").
59 * The first number is called the major number, the second the minor,
60 * the third the micro, etc. A version is considered higher then another
61 * version if it has a bigger major number then the another version or when
62 * the major numbers of the versions are equal if it has a bigger minor number
63 * then the other version, etc. (If a version has no minor, micro, etc numbers
64 * then they are considered the be 0.)
66 * @author Mark Wielaard <mark@klomp.org>
67 * @see ClassLoader#definePackage(String, String, String, String, String,
68 * String, String, URL)
70 * @status updated to 1.4
74 /** The name of the Package */
75 final private String name
;
77 /** The name if the implementation */
78 final private String implTitle
;
80 /** The vendor that wrote this implementation */
81 final private String implVendor
;
83 /** The version of this implementation */
84 final private String implVersion
;
86 /** The name of the specification */
87 final private String specTitle
;
89 /** The name of the specification designer */
90 final private String specVendor
;
92 /** The version of this specification */
93 final private String specVersion
;
95 /** If sealed the origin of the package classes, otherwise null */
96 final private URL sealed
;
99 * A package local constructor for the Package class. All parameters except
100 * the <code>name</code> of the package may be <code>null</code>.
101 * There are no public constructors defined for Package; this is a package
102 * local constructor that is used by java.lang.Classloader.definePackage().
104 * @param name The name of the Package
105 * @param specTitle The name of the specification
106 * @param specVendor The name of the specification designer
107 * @param specVersion The version of this specification
108 * @param implTitle The name of the implementation
109 * @param implVendor The vendor that wrote this implementation
110 * @param implVersion The version of this implementation
111 * @param sealed If sealed the origin of the package classes
114 String specTitle
, String specVendor
, String specVersion
,
115 String implTitle
, String implVendor
, String implVersion
, URL sealed
)
118 throw new IllegalArgumentException("null Package name");
121 this.implTitle
= implTitle
;
122 this.implVendor
= implVendor
;
123 this.implVersion
= implVersion
;
124 this.specTitle
= specTitle
;
125 this.specVendor
= specVendor
;
126 this.specVersion
= specVersion
;
127 this.sealed
= sealed
;
131 * Returns the Package name in dot-notation.
133 * @return the non-null package name
135 public String
getName()
141 * Returns the name of the specification, or null if unknown.
143 * @return the specification title
145 public String
getSpecificationTitle()
151 * Returns the version of the specification, or null if unknown.
153 * @return the specification version
155 public String
getSpecificationVersion()
161 * Returns the name of the specification designer, or null if unknown.
163 * @return the specification vendor
165 public String
getSpecificationVendor()
171 * Returns the name of the implementation, or null if unknown.
173 * @return the implementation title
175 public String
getImplementationTitle()
181 * Returns the version of this implementation, or null if unknown.
183 * @return the implementation version
185 public String
getImplementationVersion()
191 * Returns the vendor that wrote this implementation, or null if unknown.
193 * @return the implementation vendor
195 public String
getImplementationVendor()
201 * Returns true if this Package is sealed.
203 * @return true if the package is sealed
205 public boolean isSealed()
207 return sealed
!= null;
211 * Returns true if this Package is sealed and the origin of the classes is
214 * @param url the URL to test
215 * @return true if the package is sealed by this URL
216 * @throws NullPointerException if url is null
218 public boolean isSealed(URL url
)
220 return url
.equals(sealed
);
224 * Checks if the version of the specification is higher or at least as high
225 * as the desired version. Comparison is done by sequentially comparing
226 * dotted decimal numbers from the parameter and from
227 * <code>getSpecificationVersion</code>.
229 * @param version the (minimal) desired version of the specification
230 * @throws NumberFormatException if either version string is invalid
231 * @throws NullPointerException if either version string is null
233 public boolean isCompatibleWith(String version
)
235 StringTokenizer versionTokens
= new StringTokenizer(version
, ".");
236 StringTokenizer specTokens
= new StringTokenizer(specVersion
, ".");
239 while (versionTokens
.hasMoreElements())
241 int vers
= Integer
.parseInt(versionTokens
.nextToken());
242 int spec
= Integer
.parseInt(specTokens
.nextToken());
245 else if (spec
> vers
)
247 // They must be equal, next Token please!
250 catch (NoSuchElementException e
)
252 // This must have been thrown by spec.nextToken() so return false.
255 // They must have been exactly the same version.
256 // Or the specVersion has more subversions. That is also good.
261 * Returns the named package if it is known by the callers class loader.
262 * It may return null if the package is unknown, when there is no
263 * information on that particular package available or when the callers
264 * classloader is null.
266 * @param name the name of the desired package
267 * @return the package by that name in the current ClassLoader
269 public static Package
getPackage(String name
)
271 // Get the caller's classloader
272 ClassLoader cl
= VMSecurityManager
.currentClassLoader();
273 return cl
!= null ? cl
.getPackage(name
) : null;
277 * 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.
280 * @return an array of all known packages
282 public static Package
[] getPackages()
284 // Get the caller's classloader
285 Class c
= VMSecurityManager
.getClassContext()[1];
286 ClassLoader cl
= c
.getClassLoader();
287 // Sun's implementation returns the packages loaded by the bootstrap
288 // classloader if cl is null, but right now our bootstrap classloader
289 // does not create any Packages.
290 return cl
!= null ? cl
.getPackages() : new Package
[0];
294 * Returns the hashCode of the name of this package.
296 * @return the hash code
298 public int hashCode()
300 return name
.hashCode();
304 * Returns a string representation of this package. It is specified to
305 * be <code>"package " + getName() + (getSpecificationTitle() == null
306 * ? "" : ", " + getSpecificationTitle()) + (getSpecificationVersion()
307 * == null ? "" : ", version " + getSpecificationVersion())</code>.
309 * @return the string representation of the package
311 public String
toString()
313 return ("package " + name
+ (specTitle
== null ?
"" : ", " + specTitle
)
314 + (specVersion
== null ?
"" : ", version " + specVersion
));