Source Code Cross Referenced for ProjectClassLoader.java in  » UML » jrefactory » org » acm » seguin » project » 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 » UML » jrefactory » org.acm.seguin.project 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * The Apache Software License, Version 1.1
0003:         *
0004:         * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
0005:         * reserved.
0006:         *
0007:         * Redistribution and use in source and binary forms, with or without
0008:         * modification, are permitted provided that the following conditions
0009:         * are met:
0010:         *
0011:         * 1. Redistributions of source code must retain the above copyright
0012:         *    notice, this list of conditions and the following disclaimer.
0013:         *
0014:         * 2. Redistributions in binary form must reproduce the above copyright
0015:         *    notice, this list of conditions and the following disclaimer in
0016:         *    the documentation and/or other materials provided with the
0017:         *    distribution.
0018:         *
0019:         * 3. The end-user documentation included with the redistribution, if
0020:         *    any, must include the following acknowlegement:
0021:         *       "This product includes software developed by the
0022:         *        Apache Software Foundation (http://www.apache.org/)."
0023:         *    Alternately, this acknowlegement may appear in the software itself,
0024:         *    if and wherever such third-party acknowlegements normally appear.
0025:         *
0026:         * 4. The names "Ant" and "Apache Software
0027:         *    Foundation" must not be used to endorse or promote products derived
0028:         *    from this software without prior written permission. For written
0029:         *    permission, please contact apache@apache.org.
0030:         *
0031:         * 5. Products derived from this software may not be called "Apache"
0032:         *    nor may "Apache" appear in their names without prior written
0033:         *    permission of the Apache Group.
0034:         *
0035:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0036:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0037:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0038:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0039:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0040:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0041:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0042:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0043:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0044:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0045:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0046:         * SUCH DAMAGE.
0047:         * ====================================================================
0048:         *
0049:         * This software consists of voluntary contributions made by many
0050:         * individuals on behalf of the Apache Software Foundation.  For more
0051:         * information on the Apache Software Foundation, please see
0052:         * <http://www.apache.org/>.
0053:         */
0054:
0055:        package org.acm.seguin.project;
0056:
0057:        import java.lang.reflect.Constructor;
0058:        import java.lang.reflect.Method;
0059:        import java.lang.reflect.InvocationTargetException;
0060:        import java.util.Enumeration;
0061:        import java.util.Vector;
0062:        import java.util.Hashtable;
0063:        import java.util.zip.ZipFile;
0064:        import java.util.zip.ZipEntry;
0065:        import java.io.File;
0066:        import java.io.InputStream;
0067:        import java.io.FileInputStream;
0068:        import java.io.IOException;
0069:        import java.io.ByteArrayOutputStream;
0070:        import java.net.URL;
0071:        import java.net.MalformedURLException;
0072:
0073:        /**
0074:         * Used to load classes within ant with a different claspath from
0075:         * that used to start ant. Note that it is possible to force a class
0076:         * into this loader even when that class is on the system classpath by
0077:         * using the forceLoadClass method. Any subsequent classes loaded by that
0078:         * class will then use this loader rather than the system class loader.
0079:         *
0080:         * @author Conor MacNeill
0081:         * @author <a href="mailto:Jesse.Glick@netbeans.com">Jesse Glick</a>
0082:         * @author Magesh Umasankar
0083:         * @author Mike Atkinson
0084:         * @version    $Id: ProjectClassLoader.java,v 1.4 2004/03/25 20:24:34 mikeatkinson Exp $
0085:         * @since      2.8.01
0086:         */
0087:        public class ProjectClassLoader extends ClassLoader {
0088:
0089:            /**
0090:             * An enumeration of all resources of a given name found within the
0091:             * classpath of this class loader. This enumeration is used by the
0092:             * ClassLoader.findResources method, which is in
0093:             * turn used by the ClassLoader.getResources method.
0094:             *
0095:             * @see AntClassLoader#findResources(String)
0096:             * @see java.lang.ClassLoader#getResources(String)
0097:             * @author <a href="mailto:hermand@alumni.grinnell.edu">David A. Herman</a>
0098:             */
0099:            private class ResourceEnumeration implements  Enumeration {
0100:
0101:                /**
0102:                 * The name of the resource being searched for.
0103:                 */
0104:                private String resourceName;
0105:
0106:                /**
0107:                 * The index of the next classpath element to search.
0108:                 */
0109:                private int pathElementsIndex;
0110:
0111:                /**
0112:                 * The URL of the next resource to return in the enumeration. If this
0113:                 * field is <code>null</code> then the enumeration has been completed,
0114:                 * i.e., there are no more elements to return.
0115:                 */
0116:                private URL nextResource;
0117:
0118:                /**
0119:                 * Constructs a new enumeration of resources of the given name found
0120:                 * within this class loader's classpath.
0121:                 *
0122:                 * @param name the name of the resource to search for.
0123:                 */
0124:                ResourceEnumeration(String name) {
0125:                    this .resourceName = name;
0126:                    this .pathElementsIndex = 0;
0127:                    findNextResource();
0128:                }
0129:
0130:                /**
0131:                 * Indicates whether there are more elements in the enumeration to
0132:                 * return.
0133:                 *
0134:                 * @return <code>true</code> if there are more elements in the
0135:                 *         enumeration; <code>false</code> otherwise.
0136:                 */
0137:                public boolean hasMoreElements() {
0138:                    return (this .nextResource != null);
0139:                }
0140:
0141:                /**
0142:                 * Returns the next resource in the enumeration.
0143:                 *
0144:                 * @return the next resource in the enumeration
0145:                 */
0146:                public Object nextElement() {
0147:                    URL ret = this .nextResource;
0148:                    findNextResource();
0149:                    return ret;
0150:                }
0151:
0152:                /**
0153:                 * Locates the next resource of the correct name in the classpath and
0154:                 * sets <code>nextResource</code> to the URL of that resource. If no
0155:                 * more resources can be found, <code>nextResource</code> is set to
0156:                 * <code>null</code>.
0157:                 */
0158:                private void findNextResource() {
0159:                    URL url = null;
0160:                    while ((pathElementsIndex < pathComponents.size())
0161:                            && (url == null)) {
0162:                        //try {
0163:                        File pathComponent = (File) pathComponents
0164:                                .elementAt(pathElementsIndex);
0165:                        url = getResourceURL(pathComponent, this .resourceName);
0166:                        pathElementsIndex++;
0167:                        //} catch (ProjectException e) {
0168:                        //    // ignore path elements which are not valid relative to the
0169:                        //    // project
0170:                        //}
0171:                    }
0172:                    this .nextResource = url;
0173:                }
0174:            }
0175:
0176:            /**
0177:             * The size of buffers to be used in this classloader.
0178:             */
0179:            private static final int BUFFER_SIZE = 8192;
0180:
0181:            /**
0182:             * The components of the classpath that the classloader searches
0183:             * for classes.
0184:             */
0185:            private Vector pathComponents = new Vector();
0186:
0187:            /**
0188:             * The project to which this class loader belongs.
0189:             */
0190:            private Project project;
0191:
0192:            /**
0193:             * Indicates whether the parent class loader should be
0194:             * consulted before trying to load with this class loader.
0195:             */
0196:            private boolean parentFirst = true;
0197:
0198:            /**
0199:             * These are the package roots that are to be loaded by the parent class
0200:             * loader regardless of whether the parent class loader is being searched
0201:             * first or not.
0202:             */
0203:            private Vector systemPackages = new Vector();
0204:
0205:            /**
0206:             * These are the package roots that are to be loaded by this class loader
0207:             * regardless of whether the parent class loader is being searched first
0208:             * or not.
0209:             */
0210:            private Vector loaderPackages = new Vector();
0211:
0212:            /**
0213:             * Whether or not this classloader will ignore the base
0214:             * classloader if it can't find a class.
0215:             *
0216:             * @see #setIsolated(boolean)
0217:             */
0218:            private boolean ignoreBase = false;
0219:
0220:            /**
0221:             * The parent class loader, if one is given or can be determined.
0222:             */
0223:            private ClassLoader parent = null;
0224:
0225:            /**
0226:             * A hashtable of zip files opened by the classloader (File to ZipFile).
0227:             */
0228:            private Hashtable zipFiles = new Hashtable();
0229:
0230:            /**
0231:             * The context loader saved when setting the thread's current
0232:             * context loader.
0233:             */
0234:            private ClassLoader savedContextLoader = null;
0235:            /**
0236:             * Whether or not the context loader is currently saved.
0237:             */
0238:            private boolean isContextLoaderSaved = false;
0239:
0240:            /**
0241:             * Reflection method reference for getProtectionDomain;
0242:             * used to avoid 1.1-compatibility problems.
0243:             */
0244:            private static Method getProtectionDomain = null;
0245:
0246:            /**
0247:             * Creates a classloader for the given project.
0248:             *
0249:             * @param project The project to which this classloader is to belong.
0250:             *                Must not be <code>null</code>.
0251:             */
0252:            public ProjectClassLoader(Project project) {
0253:                parent = ProjectClassLoader.class.getClassLoader();
0254:                this .project = project;
0255:                //project.addBuildListener(this);
0256:                if (project == null) {
0257:                    return;
0258:                }
0259:                Path classpath = new Path(project, project.getClassPath());
0260:                if (classpath != null) {
0261:                    try {
0262:                        Path actualClasspath = classpath
0263:                                .concatSystemClasspath("ignore");
0264:                        String[] pathElements = actualClasspath.list();
0265:                        for (int i = 0; i < pathElements.length; ++i) {
0266:                            addPathElement(pathElements[i]);
0267:                        }
0268:                    } catch (ProjectException e) {
0269:                        // ignore path elements which are invalid
0270:                        // relative to the project
0271:                    }
0272:                }
0273:            }
0274:
0275:            /**
0276:             * Creates a classloader for the given project.
0277:             *
0278:             * @param parent The parent classloader to which unsatisfied loading
0279:             *               attempts are delegated. May be <code>null</code>,
0280:             *               in which case the classloader which loaded this
0281:             *               class is used as the parent.
0282:             * @param project The project to which this classloader is to belong.
0283:             *                Must not be <code>null</code>.
0284:             * @param parentFirst If <code>true</code>, indicates that the parent
0285:             *                    classloader should be consulted  before trying to
0286:             *                    load the a class through this loader.
0287:             */
0288:            public ProjectClassLoader(ClassLoader parent, Project project,
0289:                    boolean parentFirst) {
0290:                this (project);
0291:                if (parent != null) {
0292:                    this .parent = parent;
0293:                }
0294:                this .parentFirst = parentFirst;
0295:                addJavaLibraries();
0296:            }
0297:
0298:            /**
0299:             * Creates a classloader for the given project.
0300:             *
0301:             * @param project The project to which this classloader is to belong.
0302:             *                Must not be <code>null</code>.
0303:             * @param parentFirst If <code>true</code>, indicates that the parent
0304:             *                    classloader should be consulted before trying to
0305:             *                    load the a class through this loader.
0306:             */
0307:            public ProjectClassLoader(Project project, boolean parentFirst) {
0308:                this (null, project, parentFirst);
0309:            }
0310:
0311:            /**
0312:             * Creates an empty class loader. The classloader should be configured
0313:             * with path elements to specify where the loader is to look for
0314:             * classes.
0315:             *
0316:             * @param parent The parent classloader to which unsatisfied loading
0317:             *               attempts are delegated. May be <code>null</code>,
0318:             *               in which case the classloader which loaded this
0319:             *               class is used as the parent.
0320:             * @param parentFirst If <code>true</code>, indicates that the parent
0321:             *                    classloader should be consulted before trying to
0322:             *                    load the a class through this loader.
0323:             */
0324:            public ProjectClassLoader(ClassLoader parent, boolean parentFirst) {
0325:                if (parent != null) {
0326:                    this .parent = parent;
0327:                } else {
0328:                    parent = ProjectClassLoader.class.getClassLoader();
0329:                }
0330:                project = null;
0331:                this .parentFirst = parentFirst;
0332:            }
0333:
0334:            /**
0335:             * Logs a message through the project object if one has been provided.
0336:             *
0337:             * @param message The message to log.
0338:             *                Should not be <code>null</code>.
0339:             *
0340:             * @param priority The logging priority of the message.
0341:             */
0342:            protected void log(String message) {
0343:                if (project != null) {
0344:                    project.log(message);
0345:                }
0346:                //         else {
0347:                //             System.out.println(message);
0348:                //         }
0349:            }
0350:
0351:            /**
0352:             * Sets the current thread's context loader to this classloader, storing
0353:             * the current loader value for later resetting.
0354:             */
0355:            //public void setThreadContextLoader() {
0356:            //    if (isContextLoaderSaved) {
0357:            //        throw new ProjectException("Context loader has not been reset");
0358:            //    }
0359:            //    if (LoaderUtils.isContextLoaderAvailable()) {
0360:            //        savedContextLoader = LoaderUtils.getContextClassLoader();
0361:            //        ClassLoader loader = this;
0362:            //        if (project != null 
0363:            //            && "only".equals(project.getProperty("build.sysclasspath"))) {
0364:            //            loader = this.getClass().getClassLoader();
0365:            //        }
0366:            //        LoaderUtils.setContextClassLoader(loader);
0367:            //        isContextLoaderSaved = true;
0368:            //    }
0369:            //}
0370:            /**
0371:             * Resets the current thread's context loader to its original value.
0372:             */
0373:            //public void resetThreadContextLoader() {
0374:            //    if (LoaderUtils.isContextLoaderAvailable()
0375:            //        && isContextLoaderSaved) {
0376:            //        LoaderUtils.setContextClassLoader(savedContextLoader);
0377:            //        savedContextLoader = null;
0378:            //        isContextLoaderSaved = false;
0379:            //    }
0380:            //}
0381:
0382:            /**
0383:             * Adds an element to the classpath to be searched.
0384:             *
0385:             * @param pathElement The path element to add. Must not be
0386:             *                    <code>null</code>.
0387:             *
0388:             * @exception ProjectException if the given path element cannot be resolved
0389:             *                           against the project.
0390:             */
0391:            public void addPathElement(String pathElement)
0392:                    throws ProjectException {
0393:                File pathComponent = project != null ? project
0394:                        .resolveFile(pathElement) : new File(pathElement);
0395:                pathComponents.addElement(pathComponent);
0396:            }
0397:
0398:            /**
0399:             * Returns the classpath this classloader will consult.
0400:             *
0401:             * @return the classpath used for this classloader, with elements
0402:             *         separated by the path separator for the system.
0403:             */
0404:            public String getClasspath() {
0405:                StringBuffer sb = new StringBuffer();
0406:                boolean firstPass = true;
0407:                Enumeration enumx = pathComponents.elements();
0408:                while (enumx.hasMoreElements()) {
0409:                    if (!firstPass) {
0410:                        sb.append(System.getProperty("path.separator"));
0411:                    } else {
0412:                        firstPass = false;
0413:                    }
0414:                    sb.append(((File) enumx.nextElement()).getAbsolutePath());
0415:                }
0416:                return sb.toString();
0417:            }
0418:
0419:            /**
0420:             * Sets whether this classloader should run in isolated mode. In
0421:             * isolated mode, classes not found on the given classpath will
0422:             * not be referred to the parent class loader but will cause a
0423:             * ClassNotFoundException.
0424:             *
0425:             * @param isolated Whether or not this classloader should run in
0426:             *                 isolated mode.
0427:             */
0428:            public void setIsolated(boolean isolated) {
0429:                ignoreBase = isolated;
0430:            }
0431:
0432:            /**
0433:             * Forces initialization of a class in a JDK 1.1 compatible, albeit hacky
0434:             * way.
0435:             *
0436:             * @param theClass The class to initialize.
0437:             *                 Must not be <code>null</code>.
0438:             */
0439:            public static void initializeClass(Class theClass) {
0440:                // ***HACK*** We ask the VM to create an instance
0441:                // by voluntarily providing illegal arguments to force
0442:                // the VM to run the class' static initializer, while
0443:                // at the same time not running a valid constructor.
0444:
0445:                final Constructor[] cons = theClass.getDeclaredConstructors();
0446:                //At least one constructor is guaranteed to be there, but check anyway.
0447:                if (cons != null) {
0448:                    if (cons.length > 0 && cons[0] != null) {
0449:                        final String[] strs = new String[256];
0450:                        try {
0451:                            cons[0].newInstance(strs);
0452:                            // Expecting an exception to be thrown by this call:
0453:                            // IllegalArgumentException: wrong number of Arguments
0454:                        } catch (Throwable t) {
0455:                            // Ignore - we are interested only in the side
0456:                            // effect - that of getting the static initializers
0457:                            // invoked.  As we do not want to call a valid
0458:                            // constructor to get this side effect, an
0459:                            // attempt is made to call a hopefully
0460:                            // invalid constructor - come on, nobody
0461:                            // would have a constructor that takes in
0462:                            // 256 String arguments ;-)
0463:                            // (In fact, they can't - according to JVM spec
0464:                            // section 4.10, the number of method parameters is limited
0465:                            // to 255 by the definition of a method descriptor.
0466:                            // Constructors count as methods here.)
0467:                        }
0468:                    }
0469:                }
0470:            }
0471:
0472:            /**
0473:             * Adds a package root to the list of packages which must be loaded on the
0474:             * parent loader.
0475:             *
0476:             * All subpackages are also included.
0477:             *
0478:             * @param packageRoot The root of all packages to be included.
0479:             *                    Should not be <code>null</code>.
0480:             */
0481:            public void addSystemPackageRoot(String packageRoot) {
0482:                systemPackages.addElement(packageRoot
0483:                        + (packageRoot.endsWith(".") ? "" : "."));
0484:            }
0485:
0486:            /**
0487:             * Adds a package root to the list of packages which must be loaded using
0488:             * this loader.
0489:             *
0490:             * All subpackages are also included.
0491:             *
0492:             * @param packageRoot The root of all packages to be included.
0493:             *                    Should not be <code>null</code>.
0494:             */
0495:            public void addLoaderPackageRoot(String packageRoot) {
0496:                loaderPackages.addElement(packageRoot
0497:                        + (packageRoot.endsWith(".") ? "" : "."));
0498:            }
0499:
0500:            /**
0501:             * Loads a class through this class loader even if that class is available
0502:             * on the parent classpath.
0503:             *
0504:             * This ensures that any classes which are loaded by the returned class
0505:             * will use this classloader.
0506:             *
0507:             * @param classname The name of the class to be loaded.
0508:             *                  Must not be <code>null</code>.
0509:             *
0510:             * @return the required Class object
0511:             *
0512:             * @exception ClassNotFoundException if the requested class does not exist
0513:             *                                   on this loader's classpath.
0514:             */
0515:            public Class forceLoadClass(String classname)
0516:                    throws ClassNotFoundException {
0517:                log("force loading " + classname);
0518:
0519:                Class theClass = findLoadedClass(classname);
0520:
0521:                if (theClass == null) {
0522:                    theClass = findClass(classname);
0523:                }
0524:
0525:                return theClass;
0526:            }
0527:
0528:            /**
0529:             * Loads a class through this class loader but defer to the parent class
0530:             * loader.
0531:             *
0532:             * This ensures that instances of the returned class will be compatible
0533:             * with instances which which have already been loaded on the parent
0534:             * loader.
0535:             *
0536:             * @param classname The name of the class to be loaded.
0537:             *                  Must not be <code>null</code>.
0538:             *
0539:             * @return the required Class object
0540:             *
0541:             * @exception ClassNotFoundException if the requested class does not exist
0542:             * on this loader's classpath.
0543:             */
0544:            public Class forceLoadSystemClass(String classname)
0545:                    throws ClassNotFoundException {
0546:                log("force system loading " + classname);
0547:
0548:                Class theClass = findLoadedClass(classname);
0549:
0550:                if (theClass == null) {
0551:                    theClass = findBaseClass(classname);
0552:                }
0553:
0554:                return theClass;
0555:            }
0556:
0557:            /**
0558:             * Returns a stream to read the requested resource name.
0559:             *
0560:             * @param name The name of the resource for which a stream is required.
0561:             *             Must not be <code>null</code>.
0562:             *
0563:             * @return a stream to the required resource or <code>null</code> if the
0564:             *         resource cannot be found on the loader's classpath.
0565:             */
0566:            public InputStream getResourceAsStream(String name) {
0567:
0568:                InputStream resourceStream = null;
0569:                if (isParentFirst(name)) {
0570:                    resourceStream = loadBaseResource(name);
0571:                    if (resourceStream != null) {
0572:                        log("ResourceStream for " + name
0573:                                + " loaded from parent loader");
0574:
0575:                    } else {
0576:                        resourceStream = loadResource(name);
0577:                        if (resourceStream != null) {
0578:                            log("ResourceStream for " + name
0579:                                    + " loaded from ant loader");
0580:                        }
0581:                    }
0582:                } else {
0583:                    resourceStream = loadResource(name);
0584:                    if (resourceStream != null) {
0585:                        log("ResourceStream for " + name
0586:                                + " loaded from ant loader");
0587:
0588:                    } else {
0589:                        resourceStream = loadBaseResource(name);
0590:                        if (resourceStream != null) {
0591:                            log("ResourceStream for " + name
0592:                                    + " loaded from parent loader");
0593:                        }
0594:                    }
0595:                }
0596:
0597:                if (resourceStream == null) {
0598:                    log("Couldn't load ResourceStream for " + name);
0599:                }
0600:
0601:                return resourceStream;
0602:            }
0603:
0604:            /**
0605:             * Returns a stream to read the requested resource name from this loader.
0606:             *
0607:             * @param name The name of the resource for which a stream is required.
0608:             *             Must not be <code>null</code>.
0609:             *
0610:             * @return a stream to the required resource or <code>null</code> if
0611:             *         the resource cannot be found on the loader's classpath.
0612:             */
0613:            private InputStream loadResource(String name) {
0614:                // we need to search the components of the path to see if we can
0615:                // find the class we want.
0616:                InputStream stream = null;
0617:
0618:                Enumeration e = pathComponents.elements();
0619:                while (e.hasMoreElements() && stream == null) {
0620:                    File pathComponent = (File) e.nextElement();
0621:                    stream = getResourceStream(pathComponent, name);
0622:                }
0623:                return stream;
0624:            }
0625:
0626:            /**
0627:             * Finds a system resource (which should be loaded from the parent
0628:             * classloader).
0629:             *
0630:             * @param name The name of the system resource to load.
0631:             *             Must not be <code>null</code>.
0632:             *
0633:             * @return a stream to the named resource, or <code>null</code> if
0634:             *         the resource cannot be found.
0635:             */
0636:            private InputStream loadBaseResource(String name) {
0637:                if (parent == null) {
0638:                    return getSystemResourceAsStream(name);
0639:                } else {
0640:                    return parent.getResourceAsStream(name);
0641:                }
0642:            }
0643:
0644:            /**
0645:             * Returns an inputstream to a given resource in the given file which may
0646:             * either be a directory or a zip file.
0647:             *
0648:             * @param file the file (directory or jar) in which to search for the
0649:             *             resource. Must not be <code>null</code>.
0650:             * @param resourceName The name of the resource for which a stream is
0651:             *                     required. Must not be <code>null</code>.
0652:             *
0653:             * @return a stream to the required resource or <code>null</code> if
0654:             *         the resource cannot be found in the given file.
0655:             */
0656:            private InputStream getResourceStream(File file, String resourceName) {
0657:                try {
0658:                    if (!file.exists()) {
0659:                        return null;
0660:                    }
0661:
0662:                    if (file.isDirectory()) {
0663:                        File resource = new File(file, resourceName);
0664:
0665:                        if (resource.exists()) {
0666:                            return new FileInputStream(resource);
0667:                        }
0668:                    } else {
0669:                        // is the zip file in the cache
0670:                        ZipFile zipFile = (ZipFile) zipFiles.get(file);
0671:                        if (zipFile == null) {
0672:                            zipFile = new ZipFile(file);
0673:                            zipFiles.put(file, zipFile);
0674:                        }
0675:                        ZipEntry entry = zipFile.getEntry(resourceName);
0676:                        if (entry != null) {
0677:                            return zipFile.getInputStream(entry);
0678:                        }
0679:                    }
0680:                } catch (Exception e) {
0681:                    log("Ignoring Exception " + e.getClass().getName() + ": "
0682:                            + e.getMessage() + " reading resource "
0683:                            + resourceName + " from " + file);
0684:                }
0685:
0686:                return null;
0687:            }
0688:
0689:            /**
0690:             * Tests whether or not the parent classloader should be checked for
0691:             * a resource before this one. If the resource matches both the
0692:             * "use parent classloader first" and the "use this classloader first"
0693:             * lists, the latter takes priority.
0694:             *
0695:             * @param resourceName The name of the resource to check.
0696:             *                     Must not be <code>null</code>.
0697:             *
0698:             * @return whether or not the parent classloader should be checked for a
0699:             *         resource before this one is.
0700:             */
0701:            private boolean isParentFirst(String resourceName) {
0702:                // default to the global setting and then see
0703:                // if this class belongs to a package which has been
0704:                // designated to use a specific loader first
0705:                // (this one or the parent one)
0706:
0707:                // XXX - shouldn't this always return false in isolated mode?
0708:
0709:                boolean useParentFirst = parentFirst;
0710:
0711:                for (Enumeration e = systemPackages.elements(); e
0712:                        .hasMoreElements();) {
0713:                    String packageName = (String) e.nextElement();
0714:                    if (resourceName.startsWith(packageName)) {
0715:                        useParentFirst = true;
0716:                        break;
0717:                    }
0718:                }
0719:
0720:                for (Enumeration e = loaderPackages.elements(); e
0721:                        .hasMoreElements();) {
0722:                    String packageName = (String) e.nextElement();
0723:                    if (resourceName.startsWith(packageName)) {
0724:                        useParentFirst = false;
0725:                        break;
0726:                    }
0727:                }
0728:
0729:                return useParentFirst;
0730:            }
0731:
0732:            /**
0733:             * Finds the resource with the given name. A resource is
0734:             * some data (images, audio, text, etc) that can be accessed by class
0735:             * code in a way that is independent of the location of the code.
0736:             *
0737:             * @param name The name of the resource for which a stream is required.
0738:             *             Must not be <code>null</code>.
0739:             *
0740:             * @return a URL for reading the resource, or <code>null</code> if the
0741:             *         resource could not be found or the caller doesn't have
0742:             *         adequate privileges to get the resource.
0743:             */
0744:            public URL getResource(String name) {
0745:                // we need to search the components of the path to see if
0746:                // we can find the class we want.
0747:                URL url = null;
0748:                if (isParentFirst(name)) {
0749:                    url = (parent == null) ? super .getResource(name) : parent
0750:                            .getResource(name);
0751:                }
0752:
0753:                if (url != null) {
0754:                    log("Resource " + name + " loaded from parent loader");
0755:
0756:                } else {
0757:                    // try and load from this loader if the parent either didn't find
0758:                    // it or wasn't consulted.
0759:                    Enumeration e = pathComponents.elements();
0760:                    while (e.hasMoreElements() && url == null) {
0761:                        File pathComponent = (File) e.nextElement();
0762:                        url = getResourceURL(pathComponent, name);
0763:                        if (url != null) {
0764:                            log("Resource " + name + " loaded from ant loader");
0765:                        }
0766:                    }
0767:                }
0768:
0769:                if (url == null && !isParentFirst(name)) {
0770:                    // this loader was first but it didn't find it - try the parent
0771:
0772:                    url = (parent == null) ? super .getResource(name) : parent
0773:                            .getResource(name);
0774:                    if (url != null) {
0775:                        log("Resource " + name + " loaded from parent loader");
0776:                    }
0777:                }
0778:
0779:                if (url == null) {
0780:                    log("Couldn't load Resource " + name);
0781:                }
0782:
0783:                return url;
0784:            }
0785:
0786:            /**
0787:             * Returns an enumeration of URLs representing all the resources with the
0788:             * given name by searching the class loader's classpath.
0789:             *
0790:             * @param name The resource name to search for.
0791:             *             Must not be <code>null</code>.
0792:             * @return an enumeration of URLs for the resources
0793:             * @exception IOException if I/O errors occurs (can't happen)
0794:             */
0795:            protected Enumeration findResources(String name) throws IOException {
0796:                return new ResourceEnumeration(name);
0797:            }
0798:
0799:            /**
0800:             * Returns an inputstream to a given resource in the given file which may
0801:             * either be a directory or a zip file.
0802:             *
0803:             * @param file The file (directory or jar) in which to search for
0804:             *             the resource. Must not be <code>null</code>.
0805:             * @param resourceName The name of the resource for which a stream
0806:             *                     is required. Must not be <code>null</code>.
0807:             *
0808:             * @return a stream to the required resource or <code>null</code> if the
0809:             *         resource cannot be found in the given file object.
0810:             */
0811:            private URL getResourceURL(File file, String resourceName) {
0812:                try {
0813:                    if (!file.exists()) {
0814:                        return null;
0815:                    }
0816:
0817:                    if (file.isDirectory()) {
0818:                        File resource = new File(file, resourceName);
0819:
0820:                        if (resource.exists()) {
0821:                            try {
0822:                                return new URL("file:" + resource.toString());
0823:                            } catch (MalformedURLException ex) {
0824:                                return null;
0825:                            }
0826:                        }
0827:                    } else {
0828:                        ZipFile zipFile = (ZipFile) zipFiles.get(file);
0829:                        if (zipFile == null) {
0830:                            zipFile = new ZipFile(file);
0831:                            zipFiles.put(file, zipFile);
0832:                        }
0833:
0834:                        ZipEntry entry = zipFile.getEntry(resourceName);
0835:                        if (entry != null) {
0836:                            try {
0837:                                return new URL("jar:file:" + file.toString()
0838:                                        + "!/" + entry);
0839:                            } catch (MalformedURLException ex) {
0840:                                return null;
0841:                            }
0842:                        }
0843:                    }
0844:                } catch (Exception e) {
0845:                    e.printStackTrace();
0846:                }
0847:
0848:                return null;
0849:            }
0850:
0851:            /**
0852:             * Loads a class with this class loader.
0853:             *
0854:             * This class attempts to load the class in an order determined by whether
0855:             * or not the class matches the system/loader package lists, with the
0856:             * loader package list taking priority. If the classloader is in isolated
0857:             * mode, failure to load the class in this loader will result in a
0858:             * ClassNotFoundException.
0859:             *
0860:             * @param classname The name of the class to be loaded.
0861:             *                  Must not be <code>null</code>.
0862:             * @param resolve <code>true</code> if all classes upon which this class
0863:             *                depends are to be loaded.
0864:             *
0865:             * @return the required Class object
0866:             *
0867:             * @exception ClassNotFoundException if the requested class does not exist
0868:             * on the system classpath (when not in isolated mode) or this loader's
0869:             * classpath.
0870:             */
0871:            protected synchronized Class loadClass(String classname,
0872:                    boolean resolve) throws ClassNotFoundException {
0873:                // 'sync' is needed - otherwise 2 threads can load the same class
0874:                // twice, resulting in LinkageError: duplicated class definition.
0875:                // findLoadedClass avoids that, but without sync it won't work.
0876:
0877:                Class theClass = findLoadedClass(classname);
0878:                if (theClass != null) {
0879:                    return theClass;
0880:                }
0881:
0882:                if (isParentFirst(classname)) {
0883:                    try {
0884:                        theClass = findBaseClass(classname);
0885:                        log("Class " + classname + " loaded from parent loader");
0886:                    } catch (ClassNotFoundException cnfe) {
0887:                        theClass = findClass(classname);
0888:                        log("Class " + classname + " loaded from ant loader");
0889:                    }
0890:                } else {
0891:                    try {
0892:                        theClass = findClass(classname);
0893:                        log("Class " + classname + " loaded from ant loader");
0894:                    } catch (ClassNotFoundException cnfe) {
0895:                        if (ignoreBase) {
0896:                            throw cnfe;
0897:                        }
0898:                        theClass = findBaseClass(classname);
0899:                        log("Class " + classname + " loaded from parent loader");
0900:                    }
0901:                }
0902:
0903:                if (resolve) {
0904:                    resolveClass(theClass);
0905:                }
0906:
0907:                return theClass;
0908:            }
0909:
0910:            /**
0911:             * Converts the class dot notation to a filesystem equivalent for
0912:             * searching purposes.
0913:             *
0914:             * @param classname The class name in dot format (eg java.lang.Integer).
0915:             *                  Must not be <code>null</code>.
0916:             *
0917:             * @return the classname in filesystem format (eg java/lang/Integer.class)
0918:             */
0919:            private String getClassFilename(String classname) {
0920:                return classname.replace('.', '/') + ".class";
0921:            }
0922:
0923:            /**
0924:             * Reads a class definition from a stream.
0925:             *
0926:             * @param stream The stream from which the class is to be read.
0927:             *               Must not be <code>null</code>.
0928:             * @param classname The name of the class in the stream.
0929:             *                  Must not be <code>null</code>.
0930:             *
0931:             * @return the Class object read from the stream.
0932:             *
0933:             * @exception IOException if there is a problem reading the class from the
0934:             * stream.
0935:             * @exception SecurityException if there is a security problem while
0936:             * reading the class from the stream.
0937:             */
0938:            private Class getClassFromStream(InputStream stream,
0939:                    String classname) throws IOException, SecurityException {
0940:                ByteArrayOutputStream baos = new ByteArrayOutputStream();
0941:                int bytesRead = -1;
0942:                byte[] buffer = new byte[BUFFER_SIZE];
0943:
0944:                while ((bytesRead = stream.read(buffer, 0, BUFFER_SIZE)) != -1) {
0945:                    baos.write(buffer, 0, bytesRead);
0946:                }
0947:
0948:                byte[] classData = baos.toByteArray();
0949:                return defineClass(classname, classData, 0, classData.length);
0950:            }
0951:
0952:            /**
0953:             * Searches for and load a class on the classpath of this class loader.
0954:             *
0955:             * @param name The name of the class to be loaded. Must not be
0956:             *             <code>null</code>.
0957:             *
0958:             * @return the required Class object
0959:             *
0960:             * @exception ClassNotFoundException if the requested class does not exist
0961:             *                                   on this loader's classpath.
0962:             */
0963:            public Class findClass(String name) throws ClassNotFoundException {
0964:                log("Finding class " + name);
0965:
0966:                return findClassInComponents(name);
0967:            }
0968:
0969:            /**
0970:             * Finds a class on the given classpath.
0971:             *
0972:             * @param name The name of the class to be loaded. Must not be
0973:             *             <code>null</code>.
0974:             *
0975:             * @return the required Class object
0976:             *
0977:             * @exception ClassNotFoundException if the requested class does not exist
0978:             * on this loader's classpath.
0979:             */
0980:            private Class findClassInComponents(String name)
0981:                    throws ClassNotFoundException {
0982:                // we need to search the components of the path to see if
0983:                // we can find the class we want.
0984:                InputStream stream = null;
0985:                String classFilename = getClassFilename(name);
0986:                try {
0987:                    Enumeration e = pathComponents.elements();
0988:                    while (e.hasMoreElements()) {
0989:                        File pathComponent = (File) e.nextElement();
0990:                        try {
0991:                            stream = getResourceStream(pathComponent,
0992:                                    classFilename);
0993:                            if (stream != null) {
0994:                                return getClassFromStream(stream, name);
0995:                            }
0996:                        } catch (SecurityException se) {
0997:                            throw se;
0998:                        } catch (IOException ioe) {
0999:                            // ioe.printStackTrace();
1000:                            log("Exception reading component " + pathComponent);
1001:                        }
1002:                    }
1003:
1004:                    throw new ClassNotFoundException(name);
1005:                } finally {
1006:                    try {
1007:                        if (stream != null) {
1008:                            stream.close();
1009:                        }
1010:                    } catch (IOException e) {
1011:                    }
1012:                }
1013:            }
1014:
1015:            /**
1016:             * Finds a system class (which should be loaded from the same classloader
1017:             * as the Ant core).
1018:             *
1019:             * For JDK 1.1 compatability, this uses the findSystemClass method if
1020:             * no parent classloader has been specified.
1021:             *
1022:             * @param name The name of the class to be loaded.
1023:             *             Must not be <code>null</code>.
1024:             *
1025:             * @return the required Class object
1026:             *
1027:             * @exception ClassNotFoundException if the requested class does not exist
1028:             * on this loader's classpath.
1029:             */
1030:            private Class findBaseClass(String name)
1031:                    throws ClassNotFoundException {
1032:                if (parent == null) {
1033:                    return findSystemClass(name);
1034:                } else {
1035:                    return parent.loadClass(name);
1036:                }
1037:            }
1038:
1039:            /**
1040:             * Cleans up any resources held by this classloader. Any open archive
1041:             * files are closed.
1042:             */
1043:            public synchronized void cleanup() {
1044:                for (Enumeration e = zipFiles.elements(); e.hasMoreElements();) {
1045:                    ZipFile zipFile = (ZipFile) e.nextElement();
1046:                    try {
1047:                        zipFile.close();
1048:                    } catch (IOException ioe) {
1049:                        // ignore
1050:                    }
1051:                }
1052:                zipFiles = new Hashtable();
1053:            }
1054:
1055:            /**
1056:             * add any libraries that come with different java versions
1057:             * here
1058:             */
1059:            private void addJavaLibraries() {
1060:                Vector packages = new Vector(); //FIXME: JavaEnvUtils.getJrePackages();
1061:                Enumeration e = packages.elements();
1062:                while (e.hasMoreElements()) {
1063:                    String packageName = (String) e.nextElement();
1064:                    addSystemPackageRoot(packageName);
1065:                }
1066:            }
1067:
1068:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.