Source Code Cross Referenced for URLClassPath.java in  » 6.0-JDK-Modules » j2me » sun » misc » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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 geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » sun.misc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)URLClassPath.java	1.74 06/10/11
003:         *
004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.  
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER  
006:         *   
007:         * This program is free software; you can redistribute it and/or  
008:         * modify it under the terms of the GNU General Public License version  
009:         * 2 only, as published by the Free Software Foundation.   
010:         *   
011:         * This program is distributed in the hope that it will be useful, but  
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of  
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  
014:         * General Public License version 2 for more details (a copy is  
015:         * included at /legal/license.txt).   
016:         *   
017:         * You should have received a copy of the GNU General Public License  
018:         * version 2 along with this work; if not, write to the Free Software  
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  
020:         * 02110-1301 USA   
021:         *   
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa  
023:         * Clara, CA 95054 or visit www.sun.com if you need additional  
024:         * information or have any questions. 
025:         *
026:         */
027:
028:        package sun.misc;
029:
030:        import java.util.Enumeration;
031:        import java.util.HashMap;
032:        import java.util.LinkedList;
033:        import java.util.Hashtable;
034:        import java.util.NoSuchElementException;
035:        import java.util.Stack;
036:        import java.util.Set;
037:        import java.util.HashSet;
038:        import java.util.StringTokenizer;
039:        import java.util.ArrayList;
040:        import java.util.jar.JarFile;
041:        import sun.net.www.ParseUtil;
042:        import java.util.zip.ZipEntry;
043:        import java.util.jar.JarEntry;
044:        import java.util.jar.Manifest;
045:        import java.util.jar.Attributes;
046:        import java.util.jar.Attributes.Name;
047:        import java.net.JarURLConnection;
048:        import java.net.MalformedURLException;
049:        import java.net.URL;
050:        import java.net.URLConnection;
051:        import java.net.HttpURLConnection;
052:        import java.net.URLStreamHandler;
053:        import java.net.URLStreamHandlerFactory;
054:        import java.io.File;
055:        import java.io.FileInputStream;
056:        import java.io.FileNotFoundException;
057:        import java.io.InputStream;
058:        import java.io.IOException;
059:        import java.security.AccessController;
060:        import java.security.AccessControlException;
061:        import java.security.Permission;
062:        import java.security.PrivilegedExceptionAction;
063:        import java.security.cert.Certificate;
064:
065:        /**
066:         * This class is used to maintain a search path of URLs for loading classes
067:         * and resources from both JAR files and directories.
068:         *
069:         * @author  David Connelly
070:         * @version 1.62, 03/09/00
071:         */
072:        public class URLClassPath {
073:            final static String USER_AGENT_JAVA_VERSION = "UA-Java-Version";
074:            final static String JAVA_VERSION;
075:
076:            static {
077:                JAVA_VERSION = (String) java.security.AccessController
078:                        .doPrivileged(new sun.security.action.GetPropertyAction(
079:                                "java.version"));
080:            }
081:
082:            /* The original search path of URLs. */
083:            private ArrayList path = new ArrayList();
084:
085:            /* The stack of unopened URLs */
086:            private Stack urls = new Stack();
087:
088:            /* The resulting search path of Loaders */
089:            private ArrayList loaders = new ArrayList();
090:
091:            /* Map of each URL opened to its corresponding Loader */
092:            private HashMap lmap = new HashMap();
093:
094:            /* The jar protocol handler to use when creating new URLs */
095:            private URLStreamHandler jarHandler;
096:
097:            /**
098:             * Creates a new URLClassPath for the given URLs. The URLs will be
099:             * searched in the order specified for classes and resources. A URL
100:             * ending with a '/' is assumed to refer to a directory. Otherwise,
101:             * the URL is assumed to refer to a JAR file.
102:             *
103:             * @param urls the directory and JAR file URLs to search for classes
104:             *        and resources
105:             * @param factory the URLStreamHandlerFactory to use when creating new URLs
106:             */
107:            public URLClassPath(URL[] urls, URLStreamHandlerFactory factory) {
108:                for (int i = 0; i < urls.length; i++) {
109:                    path.add(urls[i]);
110:                }
111:                push(urls);
112:                if (factory != null) {
113:                    jarHandler = factory.createURLStreamHandler("jar");
114:                }
115:            }
116:
117:            public URLClassPath(URL[] urls) {
118:                this (urls, null);
119:            }
120:
121:            /**
122:             * Appends the specified URL to the search path of directory and JAR
123:             * file URLs from which to load classes and resources.
124:             */
125:            public void addURL(URL url) {
126:                synchronized (urls) {
127:                    urls.add(0, url);
128:                    path.add(url);
129:                }
130:            }
131:
132:            /**
133:             * Returns the original search path of URLs.
134:             */
135:            public URL[] getURLs() {
136:                synchronized (urls) {
137:                    return (URL[]) path.toArray(new URL[path.size()]);
138:                }
139:            }
140:
141:            /**
142:             * Finds the resource with the specified name on the URL search path
143:             * or null if not found or security check fails.
144:             *
145:             * @param name 	the name of the resource
146:             * @param check     whether to perform a security check
147:             * @return a <code>URL</code> for the resource, or <code>null</code>
148:             * if the resource could not be found.
149:             */
150:            public URL findResource(String name, boolean check) {
151:                Loader loader;
152:                for (int i = 0; (loader = getLoader(i)) != null; i++) {
153:                    URL url = loader.findResource(name, check);
154:                    if (url != null) {
155:                        return url;
156:                    }
157:                }
158:                return null;
159:            }
160:
161:            /**
162:             * Finds the first Resource on the URL search path which has the specified
163:             * name. Returns null if no Resource could be found.
164:             *
165:             * @param name the name of the Resource
166:             * @param check 	whether to perform a security check
167:             * @return the Resource, or null if not found
168:             */
169:            public Resource getResource(String name, boolean check) {
170:                Loader loader;
171:                for (int i = 0; (loader = getLoader(i)) != null; i++) {
172:                    Resource res = loader.getResource(name, check);
173:                    if (res != null) {
174:                        return res;
175:                    }
176:                }
177:                return null;
178:            }
179:
180:            /**
181:             * Finds all resources on the URL search path with the given name.
182:             * Returns an enumeration of the URL objects.
183:             *
184:             * @param name the resource name
185:             * @return an Enumeration of all the urls having the specified name
186:             */
187:            public Enumeration findResources(final String name,
188:                    final boolean check) {
189:                return new Enumeration() {
190:                    private int index = 0;
191:                    private URL url = null;
192:
193:                    private boolean next() {
194:                        if (url != null) {
195:                            return true;
196:                        } else {
197:                            Loader loader;
198:                            while ((loader = getLoader(index++)) != null) {
199:                                url = loader.findResource(name, check);
200:                                if (url != null) {
201:                                    return true;
202:                                }
203:                            }
204:                            return false;
205:                        }
206:                    }
207:
208:                    public boolean hasMoreElements() {
209:                        return next();
210:                    }
211:
212:                    public Object nextElement() {
213:                        if (!next()) {
214:                            throw new NoSuchElementException();
215:                        }
216:                        URL u = url;
217:                        url = null;
218:                        return u;
219:                    }
220:                };
221:            }
222:
223:            public Resource getResource(String name) {
224:                return getResource(name, true);
225:            }
226:
227:            /**
228:             * Finds all resources on the URL search path with the given name.
229:             * Returns an enumeration of the Resource objects.
230:             *
231:             * @param name the resource name
232:             * @return an Enumeration of all the resources having the specified name
233:             */
234:            public Enumeration getResources(final String name,
235:                    final boolean check) {
236:                return new Enumeration() {
237:                    private int index = 0;
238:                    private Resource res = null;
239:
240:                    private boolean next() {
241:                        if (res != null) {
242:                            return true;
243:                        } else {
244:                            Loader loader;
245:                            while ((loader = getLoader(index++)) != null) {
246:                                res = loader.getResource(name, check);
247:                                if (res != null) {
248:                                    return true;
249:                                }
250:                            }
251:                            return false;
252:                        }
253:                    }
254:
255:                    public boolean hasMoreElements() {
256:                        return next();
257:                    }
258:
259:                    public Object nextElement() {
260:                        if (!next()) {
261:                            throw new NoSuchElementException();
262:                        }
263:                        Resource r = res;
264:                        res = null;
265:                        return r;
266:                    }
267:                };
268:            }
269:
270:            public Enumeration getResources(final String name) {
271:                return getResources(name, true);
272:            }
273:
274:            /*
275:             * Returns the Loader at the specified position in the URL search
276:             * path. The URLs are opened and expanded as needed. Returns null
277:             * if the specified index is out of range.
278:             */
279:            private synchronized Loader getLoader(int index) {
280:                // Expand URL search path until the request can be satisfied
281:                // or the URL stack is empty.
282:                while (loaders.size() < index + 1) {
283:                    // Pop the next URL from the URL stack
284:                    URL url;
285:                    synchronized (urls) {
286:                        if (urls.empty()) {
287:                            return null;
288:                        } else {
289:                            url = (URL) urls.pop();
290:                        }
291:                    }
292:                    // Skip this URL if it already has a Loader. (Loader
293:                    // may be null in the case where URL has not been opened
294:                    // but is referenced by a JAR index.)
295:                    if (lmap.containsKey(url)) {
296:                        continue;
297:                    }
298:                    // Otherwise, create a new Loader for the URL.
299:                    Loader loader;
300:                    try {
301:                        loader = getLoader(url);
302:                        // If the loader defines a local class path then add the
303:                        // URLs to the list of URLs to be opened.
304:                        URL[] urls = loader.getClassPath();
305:                        if (urls != null) {
306:                            push(urls);
307:                        }
308:                    } catch (IOException e) {
309:                        // Silently ignore for now...
310:                        continue;
311:                    }
312:                    // Finally, add the Loader to the search path.
313:                    loaders.add(loader);
314:                    lmap.put(url, loader);
315:                }
316:                return (Loader) loaders.get(index);
317:            }
318:
319:            /*
320:             * Returns the Loader for the specified base URL.
321:             */
322:            private Loader getLoader(final URL url) throws IOException {
323:                try {
324:                    return (Loader) java.security.AccessController
325:                            .doPrivileged(new java.security.PrivilegedExceptionAction() {
326:                                public Object run() throws IOException {
327:                                    String file = url.getFile();
328:                                    if (file != null && file.endsWith("/")) {
329:                                        if ("file".equals(url.getProtocol())) {
330:                                            return new FileLoader(url);
331:                                        } else {
332:                                            return new Loader(url);
333:                                        }
334:                                    } else {
335:                                        return new JarLoader(url, jarHandler,
336:                                                lmap);
337:                                    }
338:                                }
339:                            });
340:                } catch (java.security.PrivilegedActionException pae) {
341:                    throw (IOException) pae.getException();
342:                }
343:            }
344:
345:            /*
346:             * Pushes the specified URLs onto the list of unopened URLs.
347:             */
348:            private void push(URL[] us) {
349:                synchronized (urls) {
350:                    for (int i = us.length - 1; i >= 0; --i) {
351:                        urls.push(us[i]);
352:                    }
353:                }
354:            }
355:
356:            /**
357:             * Convert class path specification into an array of file URLs.
358:             *
359:             * The path of the file is encoded before conversion into URL
360:             * form so that reserved characters can safely appear in the path.
361:             */
362:            public static URL[] pathToURLs(String path) {
363:                StringTokenizer st = new StringTokenizer(path,
364:                        File.pathSeparator);
365:                URL[] urls = new URL[st.countTokens()];
366:                int count = 0;
367:                while (st.hasMoreTokens()) {
368:                    File f = new File(st.nextToken());
369:                    try {
370:                        f = new File(f.getCanonicalPath());
371:                    } catch (IOException x) {
372:                        // use the non-canonicalized filename
373:                    }
374:                    try {
375:                        urls[count++] = ParseUtil.fileToEncodedURL(f);
376:                    } catch (IOException x) {
377:                    }
378:                }
379:
380:                if (urls.length != count) {
381:                    URL[] tmp = new URL[count];
382:                    System.arraycopy(urls, 0, tmp, 0, count);
383:                    urls = tmp;
384:                }
385:                return urls;
386:            }
387:
388:            /*
389:             * Check whether the resource URL should be returned.
390:             * Return null on security check failure.
391:             * Called by java.net.URLClassLoader.
392:             */
393:            public URL checkURL(URL url) {
394:                try {
395:                    check(url);
396:                } catch (Exception e) {
397:                    return null;
398:                }
399:
400:                return url;
401:            }
402:
403:            /*
404:             * Check whether the resource URL should be returned.
405:             * Throw exception on failure.
406:             * Called internally within this file.
407:             */
408:            static void check(URL url) throws IOException {
409:                SecurityManager security = System.getSecurityManager();
410:                if (security != null) {
411:                    URLConnection urlConnection = url.openConnection();
412:                    Permission perm = urlConnection.getPermission();
413:                    if (perm != null) {
414:                        try {
415:                            security.checkPermission(perm);
416:                        } catch (SecurityException se) {
417:                            // fallback to checkRead/checkConnect for pre 1.2
418:                            // security managers
419:                            if ((perm instanceof  java.io.FilePermission)
420:                                    && perm.getActions().indexOf("read") != -1) {
421:                                security.checkRead(perm.getName());
422:                            } else if ((perm instanceof  java.net.SocketPermission)
423:                                    && perm.getActions().indexOf("connect") != -1) {
424:                                URL locUrl = url;
425:                                if (urlConnection instanceof  JarURLConnection) {
426:                                    locUrl = ((JarURLConnection) urlConnection)
427:                                            .getJarFileURL();
428:                                }
429:                                security.checkConnect(locUrl.getHost(), locUrl
430:                                        .getPort());
431:                            } else {
432:                                throw se;
433:                            }
434:                        }
435:                    }
436:                }
437:            }
438:
439:            /**
440:             * Inner class used to represent a loader of resources and classes
441:             * from a base URL.
442:             */
443:            private static class Loader {
444:                private final URL base;
445:
446:                /*
447:                 * Creates a new Loader for the specified URL.
448:                 */
449:                Loader(URL url) {
450:                    base = url;
451:                }
452:
453:                /*
454:                 * Returns the base URL for this Loader.
455:                 */
456:                URL getBaseURL() {
457:                    return base;
458:                }
459:
460:                URL findResource(final String name, boolean check) {
461:                    /* Bugid 5018127: do not throw exception if name is null */
462:                    if (name == null)
463:                        return null;
464:
465:                    URL url;
466:                    try {
467:                        url = new URL(base, name);
468:                    } catch (MalformedURLException e) {
469:                        throw new IllegalArgumentException("name");
470:                    }
471:
472:                    try {
473:                        if (check) {
474:                            URLClassPath.check(url);
475:                        }
476:
477:                        /*
478:                         * For a HTTP connection we use the HEAD method to
479:                         * check if the resource exists.
480:                         */
481:                        URLConnection uc = url.openConnection();
482:                        if (uc instanceof  HttpURLConnection) {
483:                            HttpURLConnection hconn = (HttpURLConnection) uc;
484:                            hconn.setRequestMethod("HEAD");
485:                            if (hconn.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST) {
486:                                return null;
487:                            }
488:                        } else {
489:                            // our best guess for the other cases 
490:                            InputStream is = url.openStream();
491:                            is.close();
492:                        }
493:                        return url;
494:                    } catch (Exception e) {
495:                        return null;
496:                    }
497:                }
498:
499:                Resource getResource(final String name, boolean check) {
500:                    final URL url;
501:                    try {
502:                        url = new URL(base, name);
503:                    } catch (MalformedURLException e) {
504:                        throw new IllegalArgumentException("name");
505:                    }
506:                    final URLConnection uc;
507:                    try {
508:                        if (check) {
509:                            URLClassPath.check(url);
510:                        }
511:                        uc = url.openConnection();
512:                        InputStream in = uc.getInputStream();
513:                    } catch (Exception e) {
514:                        return null;
515:                    }
516:                    return new Resource() {
517:                        public String getName() {
518:                            return name;
519:                        }
520:
521:                        public URL getURL() {
522:                            return url;
523:                        }
524:
525:                        public URL getCodeSourceURL() {
526:                            return base;
527:                        }
528:
529:                        public InputStream getInputStream() throws IOException {
530:                            return uc.getInputStream();
531:                        }
532:
533:                        public int getContentLength() throws IOException {
534:                            return uc.getContentLength();
535:                        }
536:                    };
537:                }
538:
539:                /*
540:                 * Returns the Resource for the specified name, or null if not
541:                 * found or the caller does not have the permission to get the
542:                 * resource.
543:                 */
544:                Resource getResource(final String name) {
545:                    return getResource(name, true);
546:                }
547:
548:                /*
549:                 * Returns the local class path for this loader, or null if none.
550:                 */
551:                URL[] getClassPath() throws IOException {
552:                    return null;
553:                }
554:            }
555:
556:            /*
557:             * Inner class used to represent a Loader of resources from a JAR URL.
558:             */
559:            private static class JarLoader extends Loader {
560:                private JarFile jar;
561:                private URL csu;
562:                private JarIndex index;
563:                private URLStreamHandler handler;
564:                private HashMap lmap;
565:
566:                /*
567:                 * Creates a new JarLoader for the specified URL referring to
568:                 * a JAR file.
569:                 */
570:                JarLoader(URL url, URLStreamHandler jarHandler,
571:                        HashMap loaderMap) throws IOException {
572:                    super (new URL("jar", "", -1, url + "!/", jarHandler));
573:                    jar = getJarFile(url);
574:                    index = JarIndex.getJarIndex(jar);
575:                    csu = url;
576:                    handler = jarHandler;
577:                    lmap = loaderMap;
578:                    if (index != null) {
579:                        String[] jarfiles = index.getJarFiles();
580:                        // Add all the dependent URLs to the lmap so that loaders
581:                        // will not be created for them by URLClassPath.getLoader(int)
582:                        // if the same URL occurs later on the main class path.  We set 
583:                        // Loader to null here to avoid creating a Loader for each 
584:                        // URL until we actually need to try to load something from them.
585:                        for (int i = 0; i < jarfiles.length; i++) {
586:                            try {
587:                                URL jarURL = new URL(csu, jarfiles[i]);
588:                                // If a non-null loader already exists, leave it alone.
589:                                if (!lmap.containsKey(jarURL)) {
590:                                    lmap.put(jarURL, null);
591:                                }
592:                            } catch (MalformedURLException e) {
593:                                continue;
594:                            }
595:                        }
596:                    }
597:                }
598:
599:                private JarFile getJarFile(URL url) throws IOException {
600:                    // Optimize case where url refers to a local jar file
601:                    if ("file".equals(url.getProtocol())) {
602:                        FileURLMapper p = new FileURLMapper(url);
603:                        if (!p.exists()) {
604:                            throw new FileNotFoundException(p.getPath());
605:                        }
606:                        return new JarFile(p.getPath());
607:                    }
608:                    URLConnection uc = getBaseURL().openConnection();
609:                    uc
610:                            .setRequestProperty(USER_AGENT_JAVA_VERSION,
611:                                    JAVA_VERSION);
612:                    return ((JarURLConnection) uc).getJarFile();
613:                }
614:
615:                /*
616:                 * Returns the index of this JarLoader if it exists.
617:                 */
618:                JarIndex getIndex() {
619:                    return index;
620:                }
621:
622:                /* 
623:                 * Creates the resource and if the check flag is set to true, checks if
624:                 * is its okay to return the resource.
625:                 */
626:                Resource checkResource(final String name, boolean check,
627:                        final JarEntry entry) {
628:
629:                    final URL url;
630:                    try {
631:                        url = new URL(getBaseURL(), name);
632:                        if (check) {
633:                            URLClassPath.check(url);
634:                        }
635:                    } catch (MalformedURLException e) {
636:                        return null;
637:                        // throw new IllegalArgumentException("name");
638:                    } catch (IOException e) {
639:                        return null;
640:                    } catch (AccessControlException e) {
641:                        return null;
642:                    }
643:
644:                    return new Resource() {
645:                        public String getName() {
646:                            return name;
647:                        }
648:
649:                        public URL getURL() {
650:                            return url;
651:                        }
652:
653:                        public URL getCodeSourceURL() {
654:                            return csu;
655:                        }
656:
657:                        public InputStream getInputStream() throws IOException {
658:                            return jar.getInputStream(entry);
659:                        }
660:
661:                        public int getContentLength() {
662:                            return (int) entry.getSize();
663:                        }
664:
665:                        public Manifest getManifest() throws IOException {
666:                            return jar.getManifest();
667:                        };
668:
669:                        public Certificate[] getCertificates() {
670:                            return entry.getCertificates();
671:                        };
672:                    };
673:                }
674:
675:                /*
676:                 * Returns true iff atleast one resource in the jar file has the same
677:                 * package name as that of the specified resource name.
678:                 */
679:                boolean validIndex(final String name) {
680:                    String packageName = name;
681:                    int pos;
682:                    if ((pos = name.lastIndexOf("/")) != -1) {
683:                        packageName = name.substring(0, pos);
684:                    }
685:
686:                    String entryName;
687:                    ZipEntry entry;
688:                    Enumeration enum_ = jar.entries();
689:                    while (enum_.hasMoreElements()) {
690:                        entry = (ZipEntry) enum_.nextElement();
691:                        entryName = entry.getName();
692:                        if ((pos = entryName.lastIndexOf("/")) != -1)
693:                            entryName = entryName.substring(0, pos);
694:                        if (entryName.equals(packageName)) {
695:                            return true;
696:                        }
697:                    }
698:                    return false;
699:                }
700:
701:                /*
702:                 * Returns the URL for a resource with the specified name
703:                 */
704:                URL findResource(final String name, boolean check) {
705:                    Resource rsc = getResource(name, check);
706:                    if (rsc != null) {
707:                        return rsc.getURL();
708:                    }
709:                    return null;
710:                }
711:
712:                /*
713:                 * Returns the JAR Resource for the specified name.
714:                 */
715:                Resource getResource(final String name, boolean check) {
716:                    final JarEntry entry = jar.getJarEntry(name);
717:                    if (entry != null)
718:                        return checkResource(name, check, entry);
719:
720:                    if (index == null)
721:                        return null;
722:
723:                    HashSet visited = new HashSet();
724:                    return getResource(name, check, visited);
725:                }
726:
727:                /*
728:                 * Version of getResource() that tracks the jar files that have been
729:                 * visited by linking through the index files. This helper method uses
730:                 * a HashSet to store the URLs of jar files that have been searched and
731:                 * uses it to avoid going into an infinite loop, looking for a
732:                 * non-existent resource
733:                 */
734:                Resource getResource(final String name, boolean check,
735:                        Set visited) {
736:
737:                    Resource res;
738:                    Object[] jarFiles;
739:                    int count = 0;
740:                    LinkedList jarFilesList = null;
741:
742:                    /* If there no jar files in the index that can potential contain
743:                     * this resource then return immediately.
744:                     */
745:                    if ((jarFilesList = index.get(name)) == null)
746:                        return null;
747:
748:                    do {
749:                        jarFiles = jarFilesList.toArray();
750:                        int size = jarFilesList.size();
751:                        /* loop through the mapped jar file list */
752:                        while (count < size) {
753:                            String jarName = (String) jarFiles[count++];
754:                            JarLoader newLoader;
755:                            final URL url;
756:
757:                            try {
758:                                url = new URL(csu, jarName);
759:                                if ((newLoader = (JarLoader) lmap.get(url)) == null) {
760:                                    /* no loader has been set up for this jar file
761:                                     * before 
762:                                     */
763:                                    newLoader = (JarLoader) AccessController
764:                                            .doPrivileged(new PrivilegedExceptionAction() {
765:                                                public Object run()
766:                                                        throws IOException {
767:                                                    return new JarLoader(url,
768:                                                            handler, lmap);
769:                                                }
770:                                            });
771:
772:                                    /* this newly opened jar file has its own index,
773:                                     * merge it into the parent's index, taking into
774:                                     * account the relative path.
775:                                     */
776:                                    JarIndex newIndex = ((JarLoader) newLoader)
777:                                            .getIndex();
778:                                    if (newIndex != null) {
779:                                        int pos = jarName.lastIndexOf("/");
780:                                        newIndex
781:                                                .merge(
782:                                                        this .index,
783:                                                        (pos == -1 ? null
784:                                                                : jarName
785:                                                                        .substring(
786:                                                                                0,
787:                                                                                pos + 1)));
788:                                    }
789:
790:                                    /* put it in the global hashtable */
791:                                    lmap.put(url, newLoader);
792:                                }
793:                            } catch (java.security.PrivilegedActionException pae) {
794:                                continue;
795:                            } catch (MalformedURLException e) {
796:                                continue;
797:                            }
798:
799:                            /* Note that the addition of the url to the list of visited
800:                             * jars incorporates a check for presence in the hashmap
801:                             */
802:                            boolean visitedURL = !visited.add(url);
803:                            if (!visitedURL) {
804:                                final JarEntry entry = newLoader.jar
805:                                        .getJarEntry(name);
806:                                if (entry != null) {
807:                                    return newLoader.checkResource(name, check,
808:                                            entry);
809:                                }
810:
811:                                /* Verify that at least one other resource with the
812:                                 * same package name as the lookedup resource is
813:                                 * present in the new jar
814:                                 */
815:                                if (!newLoader.validIndex(name)) {
816:                                    /* the mapping is wrong */
817:                                    throw new InvalidJarIndexException(
818:                                            "Invalid index");
819:                                }
820:                            }
821:
822:                            /* If newLoader is the current loader or if it is a
823:                             * loader that has already been searched or if the new
824:                             * loader does not have an index then skip it
825:                             * and move on to the next loader. 
826:                             */
827:                            if (visitedURL || newLoader == this 
828:                                    || newLoader.getIndex() == null) {
829:                                continue;
830:                            }
831:
832:                            /* Process the index of the new loader
833:                             */
834:                            if ((res = newLoader.getResource(name, check,
835:                                    visited)) != null) {
836:                                return res;
837:                            }
838:                        }
839:                        // Get the list of jar files again as the list could have grown
840:                        // due to merging of index files.
841:                        jarFilesList = index.get(name);
842:
843:                        // If the count is unchanged, we are done.
844:                    } while (count < jarFilesList.size());
845:                    return null;
846:                }
847:
848:                /*
849:                 * Returns the JAR file local class path, or null if none.
850:                 */
851:                URL[] getClassPath() throws IOException {
852:                    if (index != null) {
853:                        return null;
854:                    }
855:
856:                    parseExtensionsDependencies();
857:                    // we probably don't want SharedSecrets in J2ME
858:                    //if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary
859:                    Manifest man = jar.getManifest();
860:                    if (man != null) {
861:                        Attributes attr = man.getMainAttributes();
862:                        if (attr != null) {
863:                            String value = attr.getValue(Name.CLASS_PATH);
864:                            if (value != null) {
865:                                return parseClassPath(csu, value);
866:                            }
867:                        }
868:                    }
869:                    //}
870:                    return null;
871:                }
872:
873:                /*
874:                 * parse the standard extension dependencies
875:                 */
876:                private void parseExtensionsDependencies() throws IOException {
877:                    ExtensionDependency.checkExtensionsDependencies(jar);
878:                }
879:
880:                /*
881:                 * Parses value of the Class-Path manifest attribute and returns
882:                 * an array of URLs relative to the specified base URL.
883:                 */
884:                private URL[] parseClassPath(URL base, String value)
885:                        throws MalformedURLException {
886:                    StringTokenizer st = new StringTokenizer(value);
887:                    URL[] urls = new URL[st.countTokens()];
888:                    int i = 0;
889:                    while (st.hasMoreTokens()) {
890:                        String path = st.nextToken();
891:                        urls[i] = new URL(base, path);
892:                        i++;
893:                    }
894:                    return urls;
895:                }
896:            }
897:
898:            /*
899:             * Inner class used to represent a loader of classes and resources
900:             * from a file URL that refers to a directory.
901:             */
902:            private static class FileLoader extends Loader {
903:                private File dir;
904:
905:                FileLoader(URL url) throws IOException {
906:                    super (url);
907:                    if (!"file".equals(url.getProtocol())) {
908:                        throw new IllegalArgumentException("url");
909:                    }
910:                    String path = url.getFile()
911:                            .replace('/', File.separatorChar);
912:                    path = ParseUtil.decode(path);
913:                    dir = new File(path);
914:                }
915:
916:                /*
917:                 * Returns the URL for a resource with the specified name
918:                 */
919:                URL findResource(final String name, boolean check) {
920:                    Resource rsc = getResource(name, check);
921:                    if (rsc != null) {
922:                        return rsc.getURL();
923:                    }
924:                    return null;
925:                }
926:
927:                Resource getResource(final String name, boolean check) {
928:                    final URL url;
929:                    try {
930:                        URL normalizedBase = new URL(getBaseURL(), ".");
931:                        url = new URL(getBaseURL(), name);
932:
933:                        if (url.getFile().startsWith(normalizedBase.getFile()) == false) {
934:                            // requested resource had ../..'s in path
935:                            return null;
936:                        }
937:
938:                        if (check)
939:                            URLClassPath.check(url);
940:                        final File file = new File(dir, name.replace('/',
941:                                File.separatorChar));
942:                        if (file.exists()) {
943:                            return new Resource() {
944:                                public String getName() {
945:                                    return name;
946:                                };
947:
948:                                public URL getURL() {
949:                                    return url;
950:                                };
951:
952:                                public URL getCodeSourceURL() {
953:                                    return getBaseURL();
954:                                };
955:
956:                                public InputStream getInputStream()
957:                                        throws IOException {
958:                                    return new FileInputStream(file);
959:                                };
960:
961:                                public int getContentLength()
962:                                        throws IOException {
963:                                    return (int) file.length();
964:                                };
965:                            };
966:                        }
967:                    } catch (Exception e) {
968:                        return null;
969:                    }
970:                    return null;
971:                }
972:            }
973:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.