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

Java Source Code / Java Documentation
1. JDK Core
2. JDK Modules
3. JDK Modules com.sun
4. JDK Modules com.sun.java
5. JDK Modules Platform
6. JDK Modules sun
7. Open Source Build
8. Open Source Graphic Library
9. Open Source IDE Eclipse
10. Open Source J2EE
11. Open Source JDBC Driver
12. Open Source Library
13. Open Source Library Database
14. Open Source Net
15. Open Source Script
16. Science
17. Security
18. Sevlet Container
19. SUN GlassFish
20. Swing Library
21. Web Services apache cxf 2.0.1
22. Web Services AXIS2
23. XML
Microsoft Office Word 2007 Tutorial
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java Source Code / Java Documentation » 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:        }
w_w__w__.__ja__v__a2_s___.__com_ | Contact Us
Copyright 2003 - 08 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.