1//
2//  ========================================================================
3//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4//  ------------------------------------------------------------------------
5//  All rights reserved. This program and the accompanying materials
6//  are made available under the terms of the Eclipse Public License v1.0
7//  and Apache License v2.0 which accompanies this distribution.
8//
9//      The Eclipse Public License is available at
10//      http://www.eclipse.org/legal/epl-v10.html
11//
12//      The Apache License v2.0 is available at
13//      http://www.opensource.org/licenses/apache2.0.php
14//
15//  You may elect to redistribute this code under either of these licenses.
16//  ========================================================================
17//
18
19package org.eclipse.jetty.util;
20
21import java.io.File;
22import java.net.URL;
23import java.net.URLClassLoader;
24import java.util.Locale;
25import java.util.MissingResourceException;
26import java.util.ResourceBundle;
27
28import org.eclipse.jetty.util.resource.Resource;
29
30/* ------------------------------------------------------------ */
31/** ClassLoader Helper.
32 * This helper class allows classes to be loaded either from the
33 * Thread's ContextClassLoader, the classloader of the derived class
34 * or the system ClassLoader.
35 *
36 * <B>Usage:</B><PRE>
37 * public class MyClass {
38 *     void myMethod() {
39 *          ...
40 *          Class c=Loader.loadClass(this.getClass(),classname);
41 *          ...
42 *     }
43 * </PRE>
44 *
45 */
46public class Loader
47{
48    /* ------------------------------------------------------------ */
49    public static URL getResource(Class<?> loadClass,String name, boolean checkParents)
50    {
51        URL url =null;
52        ClassLoader loader=Thread.currentThread().getContextClassLoader();
53        while (url==null && loader!=null )
54        {
55            url=loader.getResource(name);
56            loader=(url==null&&checkParents)?loader.getParent():null;
57        }
58
59        loader=loadClass==null?null:loadClass.getClassLoader();
60        while (url==null && loader!=null )
61        {
62            url=loader.getResource(name);
63            loader=(url==null&&checkParents)?loader.getParent():null;
64        }
65
66        if (url==null)
67        {
68            url=ClassLoader.getSystemResource(name);
69        }
70
71        return url;
72    }
73
74    /* ------------------------------------------------------------ */
75    @SuppressWarnings("rawtypes")
76    public static Class loadClass(Class loadClass,String name)
77        throws ClassNotFoundException
78    {
79        return loadClass(loadClass,name,false);
80    }
81
82    /* ------------------------------------------------------------ */
83    /** Load a class.
84     *
85     * @param loadClass
86     * @param name
87     * @param checkParents If true, try loading directly from parent classloaders.
88     * @return Class
89     * @throws ClassNotFoundException
90     */
91    @SuppressWarnings("rawtypes")
92    public static Class loadClass(Class loadClass,String name,boolean checkParents)
93        throws ClassNotFoundException
94    {
95        ClassNotFoundException ex=null;
96        Class<?> c =null;
97        ClassLoader loader=Thread.currentThread().getContextClassLoader();
98        while (c==null && loader!=null )
99        {
100            try { c=loader.loadClass(name); }
101            catch (ClassNotFoundException e) {if(ex==null)ex=e;}
102            loader=(c==null&&checkParents)?loader.getParent():null;
103        }
104
105        loader=loadClass==null?null:loadClass.getClassLoader();
106        while (c==null && loader!=null )
107        {
108            try { c=loader.loadClass(name); }
109            catch (ClassNotFoundException e) {if(ex==null)ex=e;}
110            loader=(c==null&&checkParents)?loader.getParent():null;
111        }
112
113        if (c==null)
114        {
115            try { c=Class.forName(name); }
116            catch (ClassNotFoundException e) {if(ex==null)ex=e;}
117        }
118
119        if (c!=null)
120            return c;
121        throw ex;
122    }
123
124
125
126    /* ------------------------------------------------------------ */
127    public static ResourceBundle getResourceBundle(Class<?> loadClass,String name,boolean checkParents, Locale locale)
128        throws MissingResourceException
129    {
130        MissingResourceException ex=null;
131        ResourceBundle bundle =null;
132        ClassLoader loader=Thread.currentThread().getContextClassLoader();
133        while (bundle==null && loader!=null )
134        {
135            try { bundle=ResourceBundle.getBundle(name, locale, loader); }
136            catch (MissingResourceException e) {if(ex==null)ex=e;}
137            loader=(bundle==null&&checkParents)?loader.getParent():null;
138        }
139
140        loader=loadClass==null?null:loadClass.getClassLoader();
141        while (bundle==null && loader!=null )
142        {
143            try { bundle=ResourceBundle.getBundle(name, locale, loader); }
144            catch (MissingResourceException e) {if(ex==null)ex=e;}
145            loader=(bundle==null&&checkParents)?loader.getParent():null;
146        }
147
148        if (bundle==null)
149        {
150            try { bundle=ResourceBundle.getBundle(name, locale); }
151            catch (MissingResourceException e) {if(ex==null)ex=e;}
152        }
153
154        if (bundle!=null)
155            return bundle;
156        throw ex;
157    }
158
159
160    /* ------------------------------------------------------------ */
161    /**
162     * Generate the classpath (as a string) of all classloaders
163     * above the given classloader.
164     *
165     * This is primarily used for jasper.
166     * @return the system class path
167     */
168    public static String getClassPath(ClassLoader loader) throws Exception
169    {
170        StringBuilder classpath=new StringBuilder();
171        while (loader != null && (loader instanceof URLClassLoader))
172        {
173            URL[] urls = ((URLClassLoader)loader).getURLs();
174            if (urls != null)
175            {
176                for (int i=0;i<urls.length;i++)
177                {
178                    Resource resource = Resource.newResource(urls[i]);
179                    File file=resource.getFile();
180                    if (file!=null && file.exists())
181                    {
182                        if (classpath.length()>0)
183                            classpath.append(File.pathSeparatorChar);
184                        classpath.append(file.getAbsolutePath());
185                    }
186                }
187            }
188            loader = loader.getParent();
189        }
190        return classpath.toString();
191    }
192}
193
194