Source Code Cross Referenced for Package.java in  » 6.0-JDK-Core » lang » java » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » lang » java.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package java.lang;
027
028        import java.io.InputStream;
029        import java.util.Enumeration;
030
031        import java.util.StringTokenizer;
032        import java.io.File;
033        import java.io.FileInputStream;
034        import java.io.FileNotFoundException;
035        import java.io.IOException;
036        import java.net.URL;
037        import java.net.MalformedURLException;
038        import java.security.AccessController;
039        import java.security.PrivilegedAction;
040
041        import java.util.jar.JarInputStream;
042        import java.util.jar.Manifest;
043        import java.util.jar.Attributes;
044        import java.util.jar.Attributes.Name;
045        import java.util.jar.JarException;
046        import java.util.Map;
047        import java.util.HashMap;
048        import java.util.Iterator;
049
050        import sun.net.www.ParseUtil;
051
052        import java.lang.annotation.Annotation;
053
054        /**
055         * {@code Package} objects contain version information
056         * about the implementation and specification of a Java package.
057         * This versioning information is retrieved and made available
058         * by the {@link ClassLoader} instance that
059         * loaded the class(es).  Typically, it is stored in the manifest that is
060         * distributed with the classes.
061         *
062         * <p>The set of classes that make up the package may implement a
063         * particular specification and if so the specification title, version number,
064         * and vendor strings identify that specification.
065         * An application can ask if the package is
066         * compatible with a particular version, see the {@link
067         * #isCompatibleWith isCompatibleWith}
068         * method for details.
069         *
070         * <p>Specification version numbers use a syntax that consists of nonnegative
071         * decimal integers separated by periods ".", for example "2.0" or
072         * "1.2.3.4.5.6.7".  This allows an extensible number to be used to represent
073         * major, minor, micro, etc. versions.  The version specification is described
074         * by the following formal grammar:
075         * <blockquote>
076         * <dl>
077         * <dt><i>SpecificationVersion:
078         * <dd>Digits RefinedVersion<sub>opt</sub></i>
079
080         * <p><dt><i>RefinedVersion:</i>
081         * <dd>{@code .} <i>Digits</i>
082         * <dd>{@code .} <i>Digits RefinedVersion</i>
083         *
084         * <p><dt><i>Digits:
085         * <dd>Digit
086         * <dd>Digits</i>
087         *
088         * <p><dt><i>Digit:</i>
089         * <dd>any character for which {@link Character#isDigit} returns {@code true},
090         * e.g. 0, 1, 2, ...
091         * </dl>
092         * </blockquote>
093         *
094         * <p>The implementation title, version, and vendor strings identify an
095         * implementation and are made available conveniently to enable accurate
096         * reporting of the packages involved when a problem occurs. The contents
097         * all three implementation strings are vendor specific. The
098         * implementation version strings have no specified syntax and should
099         * only be compared for equality with desired version identifiers.
100         *
101         * <p>Within each {@code ClassLoader} instance all classes from the same
102         * java package have the same Package object.  The static methods allow a package
103         * to be found by name or the set of all packages known to the current class
104         * loader to be found.
105         *
106         * @see ClassLoader#definePackage
107         */
108        public class Package implements  java.lang.reflect.AnnotatedElement {
109            /**
110             * Return the name of this package.
111             *
112             * @return  The fully-qualified name of this package as defined in the
113             *          <em>Java Language Specification, Third Edition</em>
114             *          <a href="http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.5.3">
115             *          &sect;6.5.3</a>, for example, {@code java.lang}
116             */
117            public String getName() {
118                return pkgName;
119            }
120
121            /**
122             * Return the title of the specification that this package implements.
123             * @return the specification title, null is returned if it is not known.
124             */
125            public String getSpecificationTitle() {
126                return specTitle;
127            }
128
129            /**
130             * Returns the version number of the specification
131             * that this package implements.
132             * This version string must be a sequence of nonnegative decimal
133             * integers separated by "."'s and may have leading zeros.
134             * When version strings are compared the most significant
135             * numbers are compared.
136             * @return the specification version, null is returned if it is not known.
137             */
138            public String getSpecificationVersion() {
139                return specVersion;
140            }
141
142            /**
143             * Return the name of the organization, vendor,
144             * or company that owns and maintains the specification
145             * of the classes that implement this package.
146             * @return the specification vendor, null is returned if it is not known.
147             */
148            public String getSpecificationVendor() {
149                return specVendor;
150            }
151
152            /**
153             * Return the title of this package.
154             * @return the title of the implementation, null is returned if it is not known.
155             */
156            public String getImplementationTitle() {
157                return implTitle;
158            }
159
160            /**
161             * Return the version of this implementation. It consists of any string
162             * assigned by the vendor of this implementation and does
163             * not have any particular syntax specified or expected by the Java
164             * runtime. It may be compared for equality with other
165             * package version strings used for this implementation
166             * by this vendor for this package.
167             * @return the version of the implementation, null is returned if it is not known.
168             */
169            public String getImplementationVersion() {
170                return implVersion;
171            }
172
173            /**
174             * Returns the name of the organization,
175             * vendor or company that provided this implementation.
176             * @return the vendor that implemented this package..
177             */
178            public String getImplementationVendor() {
179                return implVendor;
180            }
181
182            /**
183             * Returns true if this package is sealed.
184             *
185             * @return true if the package is sealed, false otherwise
186             */
187            public boolean isSealed() {
188                return sealBase != null;
189            }
190
191            /**
192             * Returns true if this package is sealed with respect to the specified
193             * code source url.
194             *
195             * @param url the code source url
196             * @return true if this package is sealed with respect to url
197             */
198            public boolean isSealed(URL url) {
199                return url.equals(sealBase);
200            }
201
202            /**
203             * Compare this package's specification version with a
204             * desired version. It returns true if
205             * this packages specification version number is greater than or equal
206             * to the desired version number. <p>
207             *
208             * Version numbers are compared by sequentially comparing corresponding
209             * components of the desired and specification strings.
210             * Each component is converted as a decimal integer and the values
211             * compared.
212             * If the specification value is greater than the desired
213             * value true is returned. If the value is less false is returned.
214             * If the values are equal the period is skipped and the next pair of
215             * components is compared.
216             *
217             * @param desired the version string of the desired version.
218             * @return true if this package's version number is greater
219             * 		than or equal to the desired version number
220             *
221             * @exception NumberFormatException if the desired or current version
222             *		is not of the correct dotted form.
223             */
224            public boolean isCompatibleWith(String desired)
225                    throws NumberFormatException {
226                if (specVersion == null || specVersion.length() < 1) {
227                    throw new NumberFormatException("Empty version string");
228                }
229
230                String[] sa = specVersion.split("\\.", -1);
231                int[] si = new int[sa.length];
232                for (int i = 0; i < sa.length; i++) {
233                    si[i] = Integer.parseInt(sa[i]);
234                    if (si[i] < 0)
235                        throw NumberFormatException.forInputString("" + si[i]);
236                }
237
238                String[] da = desired.split("\\.", -1);
239                int[] di = new int[da.length];
240                for (int i = 0; i < da.length; i++) {
241                    di[i] = Integer.parseInt(da[i]);
242                    if (di[i] < 0)
243                        throw NumberFormatException.forInputString("" + di[i]);
244                }
245
246                int len = Math.max(di.length, si.length);
247                for (int i = 0; i < len; i++) {
248                    int d = (i < di.length ? di[i] : 0);
249                    int s = (i < si.length ? si[i] : 0);
250                    if (s < d)
251                        return false;
252                    if (s > d)
253                        return true;
254                }
255                return true;
256            }
257
258            /**
259             * Find a package by name in the callers {@code ClassLoader} instance.
260             * The callers {@code ClassLoader} instance is used to find the package
261             * instance corresponding to the named class. If the callers
262             * {@code ClassLoader} instance is null then the set of packages loaded
263             * by the system {@code ClassLoader} instance is searched to find the
264             * named package. <p>
265             *
266             * Packages have attributes for versions and specifications only if the class
267             * loader created the package instance with the appropriate attributes. Typically,
268             * those attributes are defined in the manifests that accompany the classes.
269             *
270             * @param name a package name, for example, java.lang.
271             * @return the package of the requested name. It may be null if no package
272             * 		information is available from the archive or codebase.
273             */
274            public static Package getPackage(String name) {
275                ClassLoader l = ClassLoader.getCallerClassLoader();
276                if (l != null) {
277                    return l.getPackage(name);
278                } else {
279                    return getSystemPackage(name);
280                }
281            }
282
283            /**
284             * Get all the packages currently known for the caller's {@code ClassLoader}
285             * instance.  Those packages correspond to classes loaded via or accessible by
286             * name to that {@code ClassLoader} instance.  If the caller's
287             * {@code ClassLoader} instance is the bootstrap {@code ClassLoader}
288             * instance, which may be represented by {@code null} in some implementations,
289             * only packages corresponding to classes loaded by the bootstrap
290             * {@code ClassLoader} instance will be returned.
291             *
292             * @return a new array of packages known to the callers {@code ClassLoader}
293             * instance.  An zero length array is returned if none are known.
294             */
295            public static Package[] getPackages() {
296                ClassLoader l = ClassLoader.getCallerClassLoader();
297                if (l != null) {
298                    return l.getPackages();
299                } else {
300                    return getSystemPackages();
301                }
302            }
303
304            /**
305             * Get the package for the specified class.
306             * The class's class loader is used to find the package instance
307             * corresponding to the specified class. If the class loader
308             * is the bootstrap class loader, which may be represented by
309             * {@code null} in some implementations, then the set of packages
310             * loaded by the bootstrap class loader is searched to find the package.
311             * <p>
312             * Packages have attributes for versions and specifications only
313             * if the class loader created the package
314             * instance with the appropriate attributes. Typically those
315             * attributes are defined in the manifests that accompany
316             * the classes.
317             *
318             * @param class the class to get the package of.
319             * @return the package of the class. It may be null if no package
320             * 		information is available from the archive or codebase.  */
321            static Package getPackage(Class c) {
322                String name = c.getName();
323                int i = name.lastIndexOf('.');
324                if (i != -1) {
325                    name = name.substring(0, i);
326                    ClassLoader cl = c.getClassLoader();
327                    if (cl != null) {
328                        return cl.getPackage(name);
329                    } else {
330                        return getSystemPackage(name);
331                    }
332                } else {
333                    return null;
334                }
335            }
336
337            /**
338             * Return the hash code computed from the package name.
339             * @return the hash code computed from the package name.
340             */
341            public int hashCode() {
342                return pkgName.hashCode();
343            }
344
345            /**
346             * Returns the string representation of this Package.
347             * Its value is the string "package " and the package name.
348             * If the package title is defined it is appended.
349             * If the package version is defined it is appended.
350             * @return the string representation of the package.
351             */
352            public String toString() {
353                String spec = specTitle;
354                String ver = specVersion;
355                if (spec != null && spec.length() > 0)
356                    spec = ", " + spec;
357                else
358                    spec = "";
359                if (ver != null && ver.length() > 0)
360                    ver = ", version " + ver;
361                else
362                    ver = "";
363                return "package " + pkgName + spec + ver;
364            }
365
366            private Class<?> getPackageInfo() {
367                if (packageInfo == null) {
368                    try {
369                        packageInfo = Class.forName(pkgName + ".package-info",
370                                false, loader);
371                    } catch (ClassNotFoundException ex) {
372                        // store a proxy for the package info that has no annotations
373                        class PackageInfoProxy {
374                        }
375                        packageInfo = PackageInfoProxy.class;
376                    }
377                }
378                return packageInfo;
379            }
380
381            /**
382             * @throws NullPointerException {@inheritDoc}
383             * @since 1.5
384             */
385            public <A extends Annotation> A getAnnotation(
386                    Class<A> annotationClass) {
387                return getPackageInfo().getAnnotation(annotationClass);
388            }
389
390            /**
391             * @throws NullPointerException {@inheritDoc}
392             * @since 1.5
393             */
394            public boolean isAnnotationPresent(
395                    Class<? extends Annotation> annotationClass) {
396                return getPackageInfo().isAnnotationPresent(annotationClass);
397            }
398
399            /**
400             * @since 1.5
401             */
402            public Annotation[] getAnnotations() {
403                return getPackageInfo().getAnnotations();
404            }
405
406            /**
407             * @since 1.5
408             */
409            public Annotation[] getDeclaredAnnotations() {
410                return getPackageInfo().getDeclaredAnnotations();
411            }
412
413            /**
414             * Construct a package instance with the specified version
415             * information.
416             * @param pkgName the name of the package
417             * @param spectitle the title of the specification
418             * @param specversion the version of the specification
419             * @param specvendor the organization that maintains the specification
420             * @param impltitle the title of the implementation
421             * @param implversion the version of the implementation
422             * @param implvendor the organization that maintains the implementation
423             * @return a new package for containing the specified information.
424             */
425            Package(String name, String spectitle, String specversion,
426                    String specvendor, String impltitle, String implversion,
427                    String implvendor, URL sealbase, ClassLoader loader) {
428                pkgName = name;
429                implTitle = impltitle;
430                implVersion = implversion;
431                implVendor = implvendor;
432                specTitle = spectitle;
433                specVersion = specversion;
434                specVendor = specvendor;
435                sealBase = sealbase;
436                this .loader = loader;
437            }
438
439            /*
440             * Construct a package using the attributes from the specified manifest.
441             *
442             * @param name the package name
443             * @param man the optional manifest for the package
444             * @param url the optional code source url for the package
445             */
446            private Package(String name, Manifest man, URL url,
447                    ClassLoader loader) {
448                String path = name.replace('.', '/').concat("/");
449                String sealed = null;
450                String specTitle = null;
451                String specVersion = null;
452                String specVendor = null;
453                String implTitle = null;
454                String implVersion = null;
455                String implVendor = null;
456                URL sealBase = null;
457                Attributes attr = man.getAttributes(path);
458                if (attr != null) {
459                    specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
460                    specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
461                    specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
462                    implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
463                    implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
464                    implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
465                    sealed = attr.getValue(Name.SEALED);
466                }
467                attr = man.getMainAttributes();
468                if (attr != null) {
469                    if (specTitle == null) {
470                        specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
471                    }
472                    if (specVersion == null) {
473                        specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
474                    }
475                    if (specVendor == null) {
476                        specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
477                    }
478                    if (implTitle == null) {
479                        implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
480                    }
481                    if (implVersion == null) {
482                        implVersion = attr
483                                .getValue(Name.IMPLEMENTATION_VERSION);
484                    }
485                    if (implVendor == null) {
486                        implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
487                    }
488                    if (sealed == null) {
489                        sealed = attr.getValue(Name.SEALED);
490                    }
491                }
492                if ("true".equalsIgnoreCase(sealed)) {
493                    sealBase = url;
494                }
495                pkgName = name;
496                this .specTitle = specTitle;
497                this .specVersion = specVersion;
498                this .specVendor = specVendor;
499                this .implTitle = implTitle;
500                this .implVersion = implVersion;
501                this .implVendor = implVendor;
502                this .sealBase = sealBase;
503                this .loader = loader;
504            }
505
506            /*
507             * Returns the loaded system package for the specified name.
508             */
509            static Package getSystemPackage(String name) {
510                synchronized (pkgs) {
511                    Package pkg = (Package) pkgs.get(name);
512                    if (pkg == null) {
513                        name = name.replace('.', '/').concat("/");
514                        String fn = getSystemPackage0(name);
515                        if (fn != null) {
516                            pkg = defineSystemPackage(name, fn);
517                        }
518                    }
519                    return pkg;
520                }
521            }
522
523            /*
524             * Return an array of loaded system packages.
525             */
526            static Package[] getSystemPackages() {
527                // First, update the system package map with new package names
528                String[] names = getSystemPackages0();
529                synchronized (pkgs) {
530                    for (int i = 0; i < names.length; i++) {
531                        defineSystemPackage(names[i],
532                                getSystemPackage0(names[i]));
533                    }
534                    return (Package[]) pkgs.values().toArray(
535                            new Package[pkgs.size()]);
536                }
537            }
538
539            private static Package defineSystemPackage(final String iname,
540                    final String fn) {
541                return (Package) AccessController
542                        .doPrivileged(new PrivilegedAction() {
543                            public Object run() {
544                                String name = iname;
545                                // Get the cached code source url for the file name
546                                URL url = (URL) urls.get(fn);
547                                if (url == null) {
548                                    // URL not found, so create one
549                                    File file = new File(fn);
550                                    try {
551                                        url = ParseUtil.fileToEncodedURL(file);
552                                    } catch (MalformedURLException e) {
553                                    }
554                                    if (url != null) {
555                                        urls.put(fn, url);
556                                        // If loading a JAR file, then also cache the manifest
557                                        if (file.isFile()) {
558                                            mans.put(fn, loadManifest(fn));
559                                        }
560                                    }
561                                }
562                                // Convert to "."-separated package name
563                                name = name.substring(0, name.length() - 1)
564                                        .replace('/', '.');
565                                Package pkg;
566                                Manifest man = (Manifest) mans.get(fn);
567                                if (man != null) {
568                                    pkg = new Package(name, man, url, null);
569                                } else {
570                                    pkg = new Package(name, null, null, null,
571                                            null, null, null, null, null);
572                                }
573                                pkgs.put(name, pkg);
574                                return pkg;
575                            }
576                        });
577            }
578
579            /*
580             * Returns the Manifest for the specified JAR file name.
581             */
582            private static Manifest loadManifest(String fn) {
583                try {
584                    FileInputStream fis = new FileInputStream(fn);
585                    JarInputStream jis = new JarInputStream(fis, false);
586                    Manifest man = jis.getManifest();
587                    jis.close();
588                    return man;
589                } catch (IOException e) {
590                    return null;
591                }
592            }
593
594            // The map of loaded system packages
595            private static Map pkgs = new HashMap(31);
596
597            // Maps each directory or zip file name to its corresponding url
598            private static Map urls = new HashMap(10);
599
600            // Maps each code source url for a jar file to its manifest
601            private static Map mans = new HashMap(10);
602
603            private static native String getSystemPackage0(String name);
604
605            private static native String[] getSystemPackages0();
606
607            /*
608             * Private storage for the package name and attributes.
609             */
610            private final String pkgName;
611            private final String specTitle;
612            private final String specVersion;
613            private final String specVendor;
614            private final String implTitle;
615            private final String implVersion;
616            private final String implVendor;
617            private final URL sealBase;
618            private transient final ClassLoader loader;
619            private transient Class packageInfo;
620        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.