OSDN Git Service

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