Source Code Cross Referenced for PathableClassLoader.java in  » Library » apache-common-Logging » org » apache » commons » logging » 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 » Library » apache common Logging » org.apache.commons.logging 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2005 The Apache Software Foundation.
003:         * 
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         * 
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         * 
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:
017:        package org.apache.commons.logging;
018:
019:        import java.io.File;
020:        import java.io.IOException;
021:        import java.io.InputStream;
022:        import java.net.URL;
023:        import java.net.URLClassLoader;
024:        import java.util.ArrayList;
025:        import java.util.Collections;
026:        import java.util.Enumeration;
027:        import java.util.HashMap;
028:        import java.util.Iterator;
029:        import java.util.Map;
030:
031:        /**
032:         * A ClassLoader which sees only specified classes, and which can be
033:         * set to do parent-first or child-first path lookup.
034:         * <p>
035:         * Note that this classloader is not "industrial strength"; users
036:         * looking for such a class may wish to look at the Tomcat sourcecode
037:         * instead. In particular, this class may not be threadsafe.
038:         * <p>
039:         * Note that the ClassLoader.getResources method isn't overloaded here.
040:         * It would be nice to ensure that when child-first lookup is set the
041:         * resources from the child are returned earlier in the list than the
042:         * resources from the parent. However overriding this method isn't possible
043:         * as the java 1.4 version of ClassLoader declares this method final
044:         * (though the java 1.5 version has removed the final qualifier). As the
045:         * ClassLoader javadoc doesn't specify the order in which resources
046:         * are returned, it's valid to return the resources in any order (just
047:         * untidy) so the inherited implementation is technically ok.
048:         */
049:
050:        public class PathableClassLoader extends URLClassLoader {
051:
052:            private static final URL[] NO_URLS = new URL[0];
053:
054:            /**
055:             * A map of package-prefix to ClassLoader. Any class which is in
056:             * this map is looked up via the specified classloader instead of
057:             * the classpath associated with this classloader or its parents.
058:             * <p>
059:             * This is necessary in order for the rest of the world to communicate
060:             * with classes loaded via a custom classloader. As an example, junit
061:             * testcases which are loaded via a custom classloader needs to see
062:             * the same junit classes as the code invoking the testcase, otherwise
063:             * they can't pass result objects back. 
064:             * <p>
065:             * Normally, only a classloader created with a null parent needs to
066:             * have any lookasides defined.
067:             */
068:            private HashMap lookasides = null;
069:
070:            /**
071:             * See setParentFirst.
072:             */
073:            private boolean parentFirst = true;
074:
075:            /**
076:             * Constructor.
077:             */
078:            public PathableClassLoader(ClassLoader parent) {
079:                super (NO_URLS, parent);
080:            }
081:
082:            /**
083:             * Allow caller to explicitly add paths. Generally this not a good idea;
084:             * use addLogicalLib instead, then define the location for that logical
085:             * library in the build.xml file.
086:             */
087:            public void addURL(URL url) {
088:                super .addURL(url);
089:            }
090:
091:            /**
092:             * Specify whether this classloader should ask the parent classloader
093:             * to resolve a class first, before trying to resolve it via its own
094:             * classpath.
095:             * <p> 
096:             * Checking with the parent first is the normal approach for java, but
097:             * components within containers such as servlet engines can use 
098:             * child-first lookup instead, to allow the components to override libs
099:             * which are visible in shared classloaders provided by the container.
100:             * <p>
101:             * Note that the method getResources always behaves as if parentFirst=true,
102:             * because of limitations in java 1.4; see the javadoc for method
103:             * getResourcesInOrder for details.
104:             * <p>
105:             * This value defaults to true.
106:             */
107:            public void setParentFirst(boolean state) {
108:                parentFirst = state;
109:            }
110:
111:            /**
112:             * For classes with the specified prefix, get them from the system
113:             * classpath <i>which is active at the point this method is called</i>.
114:             * <p>
115:             * This method is just a shortcut for
116:             * <pre>
117:             * useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
118:             * </pre>
119:             */
120:            public void useSystemLoader(String prefix) {
121:                useExplicitLoader(prefix, ClassLoader.getSystemClassLoader());
122:
123:            }
124:
125:            /**
126:             * Specify a classloader to use for specific java packages.
127:             */
128:            public void useExplicitLoader(String prefix, ClassLoader loader) {
129:                if (lookasides == null) {
130:                    lookasides = new HashMap();
131:                }
132:                lookasides.put(prefix, loader);
133:            }
134:
135:            /**
136:             * Specify a collection of logical libraries. See addLogicalLib.
137:             */
138:            public void addLogicalLib(String[] logicalLibs) {
139:                for (int i = 0; i < logicalLibs.length; ++i) {
140:                    addLogicalLib(logicalLibs[i]);
141:                }
142:            }
143:
144:            /**
145:             * Specify a logical library to be included in the classpath used to
146:             * locate classes. 
147:             * <p>
148:             * The specified lib name is used as a key into the system properties;
149:             * there is expected to be a system property defined with that name
150:             * whose value is a url that indicates where that logical library can
151:             * be found. Typically this is the name of a jar file, or a directory
152:             * containing class files.
153:             * <p>
154:             * Using logical library names allows the calling code to specify its
155:             * desired classpath without knowing the exact location of the necessary
156:             * classes. 
157:             */
158:            public void addLogicalLib(String logicalLib) {
159:                String filename = System.getProperty(logicalLib);
160:                if (filename == null) {
161:                    throw new UnknownError("Logical lib [" + logicalLib
162:                            + "] is not defined" + " as a System property.");
163:                }
164:
165:                try {
166:                    URL url = new File(filename).toURL();
167:                    addURL(url);
168:                } catch (java.net.MalformedURLException e) {
169:                    throw new UnknownError("Invalid file [" + filename
170:                            + "] for logical lib [" + logicalLib + "]");
171:                }
172:            }
173:
174:            /**
175:             * Override ClassLoader method.
176:             * <p>
177:             * For each explicitly mapped package prefix, if the name matches the 
178:             * prefix associated with that entry then attempt to load the class via 
179:             * that entries' classloader.
180:             */
181:            protected Class loadClass(String name, boolean resolve)
182:                    throws ClassNotFoundException {
183:                // just for performance, check java and javax
184:                if (name.startsWith("java.") || name.startsWith("javax.")) {
185:                    return super .loadClass(name, resolve);
186:                }
187:
188:                if (lookasides != null) {
189:                    for (Iterator i = lookasides.entrySet().iterator(); i
190:                            .hasNext();) {
191:                        Map.Entry entry = (Map.Entry) i.next();
192:                        String prefix = (String) entry.getKey();
193:                        if (name.startsWith(prefix) == true) {
194:                            ClassLoader loader = (ClassLoader) entry.getValue();
195:                            Class clazz = Class.forName(name, resolve, loader);
196:                            return clazz;
197:                        }
198:                    }
199:                }
200:
201:                if (parentFirst) {
202:                    return super .loadClass(name, resolve);
203:                } else {
204:                    // Implement child-first. 
205:                    //
206:                    // It appears that the findClass method doesn't check whether the
207:                    // class has already been loaded. This seems odd to me, but without
208:                    // first checking via findLoadedClass we can get java.lang.LinkageError
209:                    // with message "duplicate class definition" which isn't good.
210:
211:                    try {
212:                        Class clazz = findLoadedClass(name);
213:                        if (clazz == null) {
214:                            clazz = super .findClass(name);
215:                        }
216:                        if (resolve) {
217:                            resolveClass(clazz);
218:                        }
219:                        return clazz;
220:                    } catch (ClassNotFoundException e) {
221:                        return super .loadClass(name, resolve);
222:                    }
223:                }
224:            }
225:
226:            /**
227:             * Same as parent class method except that when parentFirst is false
228:             * the resource is looked for in the local classpath before the parent
229:             * loader is consulted.
230:             */
231:            public URL getResource(String name) {
232:                if (parentFirst) {
233:                    return super .getResource(name);
234:                } else {
235:                    URL local = super .findResource(name);
236:                    if (local != null) {
237:                        return local;
238:                    }
239:                    return super .getResource(name);
240:                }
241:            }
242:
243:            /**
244:             * Emulate a proper implementation of getResources which respects the
245:             * setting for parentFirst.
246:             * <p>
247:             * Note that it's not possible to override the inherited getResources, as
248:             * it's declared final in java1.4 (thought that's been removed for 1.5).
249:             * The inherited implementation always behaves as if parentFirst=true.
250:             */
251:            public Enumeration getResourcesInOrder(String name)
252:                    throws IOException {
253:                if (parentFirst) {
254:                    return super .getResources(name);
255:                } else {
256:                    Enumeration localUrls = super .findResources(name);
257:
258:                    ClassLoader parent = getParent();
259:                    if (parent == null) {
260:                        // Alas, there is no method to get matching resources
261:                        // from a null (BOOT) parent classloader. Calling
262:                        // ClassLoader.getSystemClassLoader isn't right. Maybe
263:                        // calling Class.class.getResources(name) would do?
264:                        //
265:                        // However for the purposes of unit tests, we can
266:                        // simply assume that no relevant resources are
267:                        // loadable from the parent; unit tests will never be
268:                        // putting any of their resources in a "boot" classloader
269:                        // path!
270:                        return localUrls;
271:                    }
272:                    Enumeration parentUrls = parent.getResources(name);
273:
274:                    ArrayList localItems = toList(localUrls);
275:                    ArrayList parentItems = toList(parentUrls);
276:                    localItems.addAll(parentItems);
277:                    return Collections.enumeration(localItems);
278:                }
279:            }
280:
281:            /**
282:             * 
283:             * Clean implementation of list function of 
284:             * {@link java.utils.Collection} added in JDK 1.4 
285:             * @param en <code>Enumeration</code>, possibly null
286:             * @return <code>ArrayList</code> containing the enumerated
287:             * elements in the enumerated order, not null
288:             */
289:            private ArrayList toList(Enumeration en) {
290:                ArrayList results = new ArrayList();
291:                if (en != null) {
292:                    while (en.hasMoreElements()) {
293:                        Object element = en.nextElement();
294:                        results.add(element);
295:                    }
296:                }
297:                return results;
298:            }
299:
300:            /**
301:             * Same as parent class method except that when parentFirst is false
302:             * the resource is looked for in the local classpath before the parent
303:             * loader is consulted.
304:             */
305:            public InputStream getResourceAsStream(String name) {
306:                if (parentFirst) {
307:                    return super .getResourceAsStream(name);
308:                } else {
309:                    URL local = super .findResource(name);
310:                    if (local != null) {
311:                        try {
312:                            return local.openStream();
313:                        } catch (IOException e) {
314:                            // TODO: check if this is right or whether we should
315:                            // fall back to trying parent. The javadoc doesn't say...
316:                            return null;
317:                        }
318:                    }
319:                    return super.getResourceAsStream(name);
320:                }
321:            }
322:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.