Source Code Cross Referenced for ProxyClassLoader.java in  » IDE-Netbeans » library » org » netbeans » 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 » IDE Netbeans » library » org.netbeans 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans;
043:
044:        import java.io.IOException;
045:        import java.net.URL;
046:        import java.util.ArrayList;
047:        import java.util.Arrays;
048:        import java.util.Collections;
049:        import java.util.Enumeration;
050:        import java.util.HashMap;
051:        import java.util.HashSet;
052:        import java.util.Iterator;
053:        import java.util.LinkedHashSet;
054:        import java.util.List;
055:        import java.util.Map;
056:        import java.util.Set;
057:        import java.util.logging.Level;
058:        import java.util.logging.Logger;
059:        import org.openide.util.Enumerations;
060:        import org.openide.util.Lookup;
061:
062:        /**
063:         * A class loader that has multiple parents and uses them for loading
064:         * classes and resources. It is optimized for working in the enviroment 
065:         * of a deeply nested classloader hierarchy. It uses shared knowledge 
066:         * about package population to route the loading request directly 
067:         * to the correct classloader. 
068:         * It doesn't load classes or resources itself, but allows subclasses
069:         * to add such functionality.
070:         * 
071:         * @author  Petr Nejedly, Jesse Glick
072:         */
073:        public class ProxyClassLoader extends ClassLoader implements 
074:                Util.PackageAccessibleClassLoader {
075:
076:            private static final Logger LOGGER = Logger
077:                    .getLogger(ProxyClassLoader.class.getName());
078:            private static final boolean LOG_LOADING;
079:            private static final ClassLoader TOP_CL = ProxyClassLoader.class
080:                    .getClassLoader();
081:
082:            static {
083:                boolean prop1 = System
084:                        .getProperty("org.netbeans.ProxyClassLoader.level") != null;
085:                LOG_LOADING = prop1 || LOGGER.isLoggable(Level.FINE);
086:            }
087:
088:            /** All known packages */
089:            private final Map<String, Package> packages = new HashMap<String, Package>();
090:
091:            /** All parents of this classloader, including their parents recursively */
092:            private ProxyClassLoader[] parents;
093:
094:            private final boolean transitive;
095:
096:            /** The base class loader that is before all ProxyClassLoaders. */
097:            private ClassLoader systemCL = TOP_CL;
098:
099:            /** A shared map of all packages known by all classloaders. Also covers META-INF based resources.
100:             * It contains two kinds of keys: dot-separated package names and slash-separated
101:             * META-INF resource names, e.g. {"org.foobar", "/services/org.foobar.Foo"} 
102:             */
103:            private static Map<String, Set<ProxyClassLoader>> packageCoverage = new HashMap<String, Set<ProxyClassLoader>>();
104:
105:            private Set<ProxyClassLoader> parentSet = new HashSet<ProxyClassLoader>();
106:
107:            private static Map<String, Boolean> sclPackages = Collections
108:                    .synchronizedMap(new HashMap<String, Boolean>());
109:
110:            /** Create a multi-parented classloader.
111:             * @param parents all direct parents of this classloader, except system one.
112:             * @param coveredPackages Enumeration of Strings if format "org.something" 
113:            +     *   containing all packages to be covered by this classloader. 
114:             * @param transitive whether other PCLs depending on this one will
115:             *                   automatically search through its parent list
116:             */
117:            public ProxyClassLoader(ClassLoader[] parents, boolean transitive) {
118:                super (TOP_CL);
119:                this .transitive = transitive;
120:
121:                this .parents = coalesceParents(parents);
122:                parentSet.addAll(Arrays.asList(this .parents));
123:            }
124:
125:            protected final void addCoveredPackages(
126:                    Iterable<String> coveredPackages) {
127:                synchronized (packageCoverage) {
128:                    for (String pkg : coveredPackages) {
129:                        Set<ProxyClassLoader> delegates = packageCoverage
130:                                .get(pkg);
131:                        if (delegates == null) {
132:                            delegates = Collections
133:                                    .<ProxyClassLoader> singleton(this );
134:                            packageCoverage.put(pkg, delegates);
135:                        } else if (delegates.size() == 1) {
136:                            delegates = new HashSet<ProxyClassLoader>(delegates);
137:                            packageCoverage.put(pkg, delegates);
138:                            delegates.add(this );
139:                        } else {
140:                            delegates.add(this );
141:                        }
142:                    }
143:                }
144:
145:            }
146:
147:            // this is used only by system classloader, maybe we can redesign it a bit
148:            // to live without this functionality, then destroy may also go away
149:            /** Add new parents dynamically.
150:             * @param nueparents the new parents to add (append to list)
151:             * @throws IllegalArgumentException in case of a null or cyclic parent (duplicate OK)
152:             */
153:            public void append(ClassLoader[] nueparents)
154:                    throws IllegalArgumentException {
155:                if (nueparents == null)
156:                    throw new IllegalArgumentException("null parents array"); // NOI18N
157:
158:                for (ClassLoader cl : nueparents) {
159:                    if (cl == null)
160:                        throw new IllegalArgumentException("null parent: "
161:                                + Arrays.asList(nueparents)); // NOI18N
162:                }
163:
164:                ProxyClassLoader[] resParents = null;
165:                ModuleFactory moduleFactory = Lookup.getDefault().lookup(
166:                        ModuleFactory.class);
167:                if (moduleFactory != null
168:                        && moduleFactory.removeBaseClassLoader()) {
169:                    // this hack is here to prevent having the application classloader
170:                    // as parent to all module classloaders.
171:                    systemCL = ClassLoader.getSystemClassLoader();
172:                    resParents = coalesceAppend(new ProxyClassLoader[0],
173:                            nueparents);
174:                } else {
175:                    resParents = coalesceAppend(parents, nueparents);
176:                }
177:                synchronized (this ) {
178:                    // synchronized because we don't want to mess up potentially running
179:                    // classloading
180:                    parents = resParents;
181:                    parentSet.clear();
182:                    parentSet.addAll(Arrays.asList(parents));
183:                }
184:            }
185:
186:            /**
187:             * Loads the class with the specified name.  The implementation of
188:             * this method searches for classes in the following order:<p>
189:             * <ol>
190:             * <li> Looks for a known package and pass the loading to the ClassLoader 
191:                    for that package. 
192:             * <li> For unknown packages passes the call directly 
193:             *      already been loaded.
194:             * </ol>
195:             *
196:             * @param     name the name of the class
197:             * @param     resolve if <code>true</code> then resolve the class
198:             * @return	  the resulting <code>Class</code> object
199:             * @exception ClassNotFoundException if the class could not be found
200:             */
201:            @Override
202:            protected synchronized Class loadClass(String name, boolean resolve)
203:                    throws ClassNotFoundException {
204:                if (LOG_LOADING && !name.startsWith("java.util.logging.")) {
205:                    LOGGER.log(Level.FINEST, "{0} initiated loading of {1}",
206:                            new Object[] { this , name });
207:                }
208:
209:                Class cls = null;
210:
211:                int last = name.lastIndexOf('.');
212:                if (last == -1) {
213:                    throw new ClassNotFoundException(
214:                            "Will not load classes from default package ("
215:                                    + name + ")"); // NOI18N
216:                }
217:
218:                // Strip+intern or use from package coverage
219:                String pkg = (last >= 0) ? name.substring(0, last) : "";
220:
221:                final String path = pkg.replace('.', '/') + "/";
222:
223:                Set<ProxyClassLoader> del = packageCoverage.get(pkg);
224:
225:                Boolean boo = sclPackages.get(pkg);
226:                if ((boo == null || boo.booleanValue())
227:                        && shouldDelegateResource(path, null)) {
228:                    try {
229:                        cls = systemCL.loadClass(name);
230:                        if (boo == null)
231:                            sclPackages.put(pkg, true);
232:                        return cls; // try SCL first
233:                    } catch (ClassNotFoundException e) {
234:                        // No dissaster, try other loaders
235:                    }
236:                }
237:
238:                if (del == null) {
239:                    // uncovered package, go directly to SCL (may throw the CNFE for us)
240:                    //if (shouldDelegateResource(path, null)) cls = systemCL.loadClass(name);
241:                } else if (del.size() == 1) {
242:                    // simple package coverage
243:                    ProxyClassLoader pcl = del.iterator().next();
244:                    if (pcl == this 
245:                            || (parentSet.contains(pcl) && shouldDelegateResource(
246:                                    path, pcl))) {
247:                        cls = pcl.selfLoadClass(pkg, name);
248:                        if (cls != null)
249:                            sclPackages.put(pkg, false);
250:                    }/* else { // maybe it is also covered by SCL
251:                                    if (shouldDelegateResource(path, null)) cls = systemCL.loadClass(name);
252:                                }*/
253:                } else {
254:                    // multicovered package, search in order
255:                    for (ProxyClassLoader pcl : parents) { // all our accessible parents
256:                        if (del.contains(pcl)
257:                                && shouldDelegateResource(path, pcl)) { // that cover given package
258:                            cls = pcl.selfLoadClass(pkg, name);
259:                            if (cls != null)
260:                                break;
261:                        }
262:                    }
263:                    if (cls == null && del.contains(this ))
264:                        cls = selfLoadClass(pkg, name);
265:                    if (cls != null)
266:                        sclPackages.put(pkg, false);
267:                }
268:                if (cls == null && shouldDelegateResource(path, null))
269:                    cls = systemCL.loadClass(name); // may throw CNFE
270:                if (cls == null)
271:                    throw new ClassNotFoundException(name);
272:                if (resolve)
273:                    resolveClass(cls);
274:                return cls;
275:            }
276:
277:            /** May return null */
278:            private synchronized Class selfLoadClass(String pkg, String name) {
279:                Class cls = findLoadedClass(name);
280:                if (cls == null) {
281:                    cls = doLoadClass(pkg, name);
282:                    if (LOG_LOADING && !name.startsWith("java.util.logging."))
283:                        LOGGER.log(Level.FINEST, "{0} loaded {1}",
284:                                new Object[] { this , name });
285:                }
286:                return cls;
287:            }
288:
289:            /** This ClassLoader can't load anything itself. Subclasses
290:             * may override this method to do some class loading themselves. The
291:             * implementation should not throw any exception, just return
292:             * <CODE>null</CODE> if it can't load required class.
293:             *
294:             * @param  name the name of the class
295:             * @return the resulting <code>Class</code> object or <code>null</code>
296:             */
297:            protected Class doLoadClass(String pkg, String name) {
298:                return null;
299:            }
300:
301:            private String stripInitialSlash(String resource) { // #90310
302:                if (resource.startsWith("/")) {
303:                    LOGGER
304:                            .log(
305:                                    Level.WARNING,
306:                                    "Should not use initial '/' in calls to ClassLoader.getResource(s): {0}",
307:                                    resource);
308:                    return resource.substring(1);
309:                } else {
310:                    return resource;
311:                }
312:            }
313:
314:            /**
315:             * Finds the resource with the given name.
316:             * @param  name a "/"-separated path name that identifies the resource.
317:             * @return a URL for reading the resource, or <code>null</code> if
318:             *      the resource could not be found.
319:             * @see #findResource(String)
320:             */
321:            @Override
322:            public final URL getResource(String name) {
323:                URL url = null;
324:                name = stripInitialSlash(name);
325:
326:                int last = name.lastIndexOf('/');
327:                if (last == -1) {
328:                    printDefaultPackageWarning(name);
329:                }
330:
331:                String pkg = (last >= 0) ? name.substring(0, last).replace('/',
332:                        '.') : "";
333:                String path = name.substring(0, last + 1);
334:
335:                Boolean systemPackage = sclPackages.get(pkg);
336:                if ((systemPackage == null || systemPackage)
337:                        && shouldDelegateResource(path, null)) {
338:                    URL u = systemCL.getResource(name);
339:                    if (u != null) {
340:                        if (systemPackage == null) {
341:                            sclPackages.put(pkg, true);
342:                        }
343:                        return u;
344:                    }
345:                    // else try other loaders
346:                }
347:
348:                Set<ProxyClassLoader> del = packageCoverage.get(pkg);
349:
350:                if (del == null) {
351:                    // uncovered package, go directly to SCL
352:                    if (shouldDelegateResource(path, null))
353:                        url = systemCL.getResource(name);
354:                } else if (del.size() == 1) {
355:                    // simple package coverage
356:                    ProxyClassLoader pcl = del.iterator().next();
357:                    if (pcl == this 
358:                            || (parentSet.contains(pcl) && shouldDelegateResource(
359:                                    path, pcl)))
360:                        url = pcl.findResource(name);
361:                } else {
362:                    // multicovered package, search in order
363:                    for (ProxyClassLoader pcl : parents) { // all our accessible parents
364:                        if (del.contains(pcl)
365:                                && shouldDelegateResource(path, pcl)) { // that cover given package
366:                            url = pcl.findResource(name);
367:                            if (url != null)
368:                                break;
369:                        }
370:                    }
371:                    if (url == null && del.contains(this ))
372:                        url = findResource(name);
373:                }
374:
375:                // uncovered package, go directly to SCL
376:                if (url == null && shouldDelegateResource(path, null))
377:                    url = systemCL.getResource(name);
378:
379:                return url;
380:            }
381:
382:            /** This ClassLoader can't load anything itself. Subclasses
383:             * may override this method to do some resource loading themselves.
384:             *
385:             * @param  name the resource name
386:             * @return a URL for reading the resource, or <code>null</code>
387:             *      if the resource could not be found.
388:             */
389:            @Override
390:            protected URL findResource(String name) {
391:                return null;
392:            }
393:
394:            /**
395:             * Finds all the resource with the given name. The implementation of
396:             * this method uses the {@link #simpleFindResources(String)} method to find
397:             * all the resources available from this classloader and adds all the 
398:             * resources from all the parents.
399:             *
400:             * @param  name the resource name
401:             * @return an Enumeration of URLs for the resources
402:             * @throws IOException if I/O errors occur
403:             */
404:            @Override
405:            protected final synchronized Enumeration<URL> findResources(
406:                    String name) throws IOException {
407:                name = stripInitialSlash(name);
408:                final int slashIdx = name.lastIndexOf('/');
409:                if (slashIdx == -1) {
410:                    printDefaultPackageWarning(name);
411:                }
412:
413:                final String path = name.substring(0, slashIdx + 1);
414:                List<Enumeration<URL>> sub = new ArrayList<Enumeration<URL>>();
415:
416:                // always consult SCL first
417:                if (shouldDelegateResource(path, null))
418:                    sub.add(systemCL.getResources(name));
419:
420:                if (name.startsWith("META-INF/")) { // common but expensive resources
421:
422:                    String relName = name.substring(8);
423:                    Set<ProxyClassLoader> del = packageCoverage.get(relName);
424:
425:                    if (del != null) { // unclaimed resource, go directly to SCL
426:                        for (ProxyClassLoader pcl : parents) { // all our accessible parents
427:                            if (del.contains(pcl)
428:                                    && shouldDelegateResource(path, pcl)) { // that cover given package
429:                                sub.add(pcl.simpleFindResources(name));
430:                            }
431:                        }
432:                        if (del.contains(this ))
433:                            sub.add(simpleFindResources(name));
434:                    }
435:                } else { // Don't bother optimizing this call by domains.
436:                    for (ProxyClassLoader pcl : parents) {
437:                        if (shouldDelegateResource(path, pcl))
438:                            sub.add(pcl.simpleFindResources(name));
439:                    }
440:                    sub.add(simpleFindResources(name));
441:                }
442:                // Should not be duplicates, assuming the parent loaders are properly distinct
443:                // from one another and do not overlap in JAR usage, which they ought not.
444:                // Anyway MetaInfServicesLookup, the most important client of this method, does
445:                // its own duplicate filtering already.
446:                return Enumerations.concat(Collections.enumeration(sub));
447:            }
448:
449:            protected Enumeration<URL> simpleFindResources(String name)
450:                    throws IOException {
451:                return super .findResources(name);
452:            }
453:
454:            /**
455:             * Returns a Package that has been defined by this class loader or any
456:             * of its parents.
457:             *
458:             * @param  name the package name
459:             * @return the Package corresponding to the given name, or null if not found
460:             */
461:            @Override
462:            protected Package getPackage(String name) {
463:                return getPackageFast(name, true);
464:            }
465:
466:            /**
467:             * Faster way to find a package.
468:             * @param name package name in org.netbeans.modules.foo format
469:             * @param sname package name in org/netbeans/modules/foo/ format
470:             * @param recurse whether to also ask parents
471:             * @return located package, or null
472:             */
473:            protected Package getPackageFast(String name, boolean recurse) {
474:                synchronized (packages) {
475:                    Package pkg = packages.get(name);
476:                    if (pkg != null) {
477:                        return pkg;
478:                    }
479:                    if (!recurse) {
480:                        return null;
481:                    }
482:                    for (int i = 0; i < parents.length; i++) {
483:                        ProxyClassLoader par = parents[i];
484:                        pkg = par.getPackageFast(name, false);
485:                        if (pkg != null)
486:                            break;
487:                    }
488:                    if (pkg == null) {
489:                        // Cannot access either Package.getSystemPackage nor ClassLoader.getPackage
490:                        // from here, so do the best we can though it will cause unnecessary
491:                        // duplication of the package cache (PCL.packages vs. CL.packages):
492:                        pkg = super .getPackage(name);
493:                    }
494:                    if (pkg != null) {
495:                        packages.put(name, pkg);
496:                    }
497:                    return pkg;
498:                }
499:            }
500:
501:            /** This is here just for locking serialization purposes.
502:             * Delegates to super.definePackage with proper locking.
503:             * Also tracks the package in our private cache, since
504:             * getPackageFast(...,...,false) will not call super.getPackage.
505:             */
506:            @Override
507:            protected Package definePackage(String name, String specTitle,
508:                    String specVersion, String specVendor, String implTitle,
509:                    String implVersion, String implVendor, URL sealBase)
510:                    throws IllegalArgumentException {
511:                synchronized (packages) {
512:                    Package pkg = super .definePackage(name, specTitle,
513:                            specVersion, specVendor, implTitle, implVersion,
514:                            implVendor, sealBase);
515:                    packages.put(name, pkg);
516:                    return pkg;
517:                }
518:            }
519:
520:            /**
521:             * Returns all of the Packages defined by this class loader and its parents.
522:             *
523:             * @return the array of <code>Package</code> objects defined by this
524:             * <code>ClassLoader</code>
525:             */
526:            @Override
527:            protected synchronized Package[] getPackages() {
528:                return getPackages(new HashSet<ClassLoader>());
529:            }
530:
531:            /**
532:             * Returns all of the Packages defined by this class loader and its parents.
533:             * Do not recurse to parents in addedParents set. It speeds up execution
534:             * time significantly.
535:             * @return the array of <code>Package</code> objects defined by this
536:             * <code>ClassLoader</code>
537:             */
538:            private synchronized Package[] getPackages(
539:                    Set<ClassLoader> addedParents) {
540:                Map<String, Package> all = new HashMap<String, Package>();
541:                // XXX call shouldDelegateResource on each?
542:                addPackages(all, super .getPackages());
543:                for (int i = 0; i < parents.length; i++) {
544:                    ClassLoader par = parents[i];
545:                    if (par instanceof  ProxyClassLoader
546:                            && addedParents.add(par)) {
547:                        // XXX should ideally use shouldDelegateResource here...
548:                        addPackages(all, ((ProxyClassLoader) par)
549:                                .getPackages(addedParents));
550:                    }
551:                }
552:                synchronized (packages) {
553:                    all.keySet().removeAll(packages.keySet());
554:                    packages.putAll(all);
555:                }
556:                return packages.values().toArray(new Package[packages.size()]);
557:            }
558:
559:            public Package getPackageAccessibly(String name) {
560:                return getPackage(name);
561:            }
562:
563:            public Package[] getPackagesAccessibly() {
564:                return getPackages();
565:            }
566:
567:            /**
568:             * #38368: Warn that the default package should not be used.
569:             */
570:            private static void printDefaultPackageWarning(String name) {
571:                // #42201 - commons-logging lib tries to read its config from this file, ignore
572:                if (!"commons-logging.properties".equals(name)
573:                        && !"jndi.properties".equals(name)) { // NOI18N
574:                    LOGGER
575:                            .log(
576:                                    Level.INFO,
577:                                    null,
578:                                    new IllegalStateException(
579:                                            "You are trying to access file: "
580:                                                    + name
581:                                                    + " from the default package. Please see http://www.netbeans.org/download/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/classpath.html#default_package"));
582:                }
583:            }
584:
585:            /** Coalesce parent classloaders into an optimized set.
586:             * This means that all parents of the specified classloaders
587:             * are also added recursively, removing duplicates along the way.
588:             * Search order should be preserved (parents before children, stable w.r.t. inputs).
589:             * @param loaders list of suggested parents (no nulls or duplicates permitted)
590:             * @return optimized list of parents (no nulls or duplicates)
591:             * @throws IllegalArgumentException if there are cycles
592:             */
593:            private ProxyClassLoader[] coalesceParents(ClassLoader[] loaders)
594:                    throws IllegalArgumentException {
595:                return coalesceAppend(new ProxyClassLoader[0], loaders);
596:            }
597:
598:            /** Coalesce a new set of loaders into the existing ones.
599:             */
600:            private ProxyClassLoader[] coalesceAppend(
601:                    ProxyClassLoader[] existing, ClassLoader[] appended)
602:                    throws IllegalArgumentException {
603:                int likelySize = existing.length + appended.length;
604:
605:                LinkedHashSet<ClassLoader> uniq = new LinkedHashSet<ClassLoader>(
606:                        likelySize);
607:                uniq.addAll(Arrays.asList(existing));
608:
609:                if (uniq.containsAll(Arrays.asList(appended)))
610:                    return existing; // No change required.
611:
612:                for (ClassLoader l : appended)
613:                    addRec(uniq, l); // add all loaders (maybe recursively)
614:
615:                // validate the configuration
616:                // it is valid if all heading non-ProxyClassLoaders are parents of the last one
617:                boolean head = true;
618:                List<ProxyClassLoader> pcls = new ArrayList<ProxyClassLoader>(
619:                        uniq.size());
620:                for (ClassLoader l : uniq) {
621:                    if (head) {
622:                        if (l instanceof  ProxyClassLoader) {
623:                            // only PCLs after this point
624:                            head = false;
625:                            pcls.add((ProxyClassLoader) l);
626:                        } else {
627:                            if (isParentOf(systemCL, l)) {
628:                                systemCL = l;
629:                            } else {
630:                                throw new IllegalArgumentException(
631:                                        "Bad ClassLoader ordering: "
632:                                                + Arrays.asList(appended));
633:                            }
634:                        }
635:                    } else {
636:                        if (l instanceof  ProxyClassLoader) {
637:                            pcls.add((ProxyClassLoader) l);
638:                        } else {
639:                            throw new IllegalArgumentException(
640:                                    "Bad ClassLoader ordering: "
641:                                            + Arrays.asList(appended));
642:
643:                        }
644:                    }
645:                }
646:
647:                ProxyClassLoader[] ret = pcls.toArray(new ProxyClassLoader[pcls
648:                        .size()]);
649:                return ret;
650:            }
651:
652:            private static boolean isParentOf(ClassLoader parent,
653:                    ClassLoader child) {
654:                while (child != null) {
655:                    if (child == parent)
656:                        return true;
657:                    child = child.getParent();
658:                }
659:                return false;
660:            }
661:
662:            private void addRec(Set<ClassLoader> resultingUnique,
663:                    ClassLoader loader) throws IllegalArgumentException {
664:                if (loader == this )
665:                    throw new IllegalArgumentException("cycle in parents"); // NOI18N
666:                if (resultingUnique.contains(loader))
667:                    return;
668:                if (loader instanceof  ProxyClassLoader
669:                        && ((ProxyClassLoader) loader).transitive) {
670:                    for (ProxyClassLoader lpar : ((ProxyClassLoader) loader).parents) {
671:                        addRec(resultingUnique, lpar);
672:                    }
673:                }
674:                resultingUnique.add(loader);
675:            }
676:
677:            private void addPackages(Map<String, Package> all, Package[] pkgs) {
678:                // Would be easier if Package.equals() was just defined sensibly...
679:                for (int i = 0; i < pkgs.length; i++) {
680:                    all.put(pkgs[i].getName(), pkgs[i]);
681:                }
682:            }
683:
684:            protected final void setSystemClassLoader(ClassLoader s) {
685:                systemCL = s;
686:            }
687:
688:            protected boolean shouldDelegateResource(String pkg,
689:                    ClassLoader parent) {
690:                return true;
691:            }
692:
693:            /** Called before releasing the classloader so it can itself unregister
694:             * from the global ClassLoader pool */
695:            public void destroy() {
696:                synchronized (packageCoverage) {
697:                    for (Iterator<String> it = packageCoverage.keySet()
698:                            .iterator(); it.hasNext();) {
699:                        String pkg = it.next();
700:                        Set<ProxyClassLoader> set = packageCoverage.get(pkg);
701:                        if (set.contains(this ) && set.size() == 1) {
702:                            it.remove();
703:                        } else {
704:                            set.remove(this);
705:                        }
706:                    }
707:                }
708:            }
709:
710:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.