KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > web > tomcat > tc5 > WebCtxLoader


1 /*
2 * JBoss, the OpenSource J2EE webOS
3 *
4 * Distributable under LGPL license.
5 * See terms of license at gnu.org.
6 */

7 package org.jboss.web.tomcat.tc5;
8
9 import java.beans.PropertyChangeListener JavaDoc;
10 import java.net.URL JavaDoc;
11 import java.net.MalformedURLException JavaDoc;
12 import java.net.URLClassLoader JavaDoc;
13 import java.io.File JavaDoc;
14 import java.io.IOException JavaDoc;
15 import java.lang.reflect.Method JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.Enumeration JavaDoc;
18 import javax.servlet.ServletContext JavaDoc;
19
20 import org.apache.catalina.Lifecycle;
21 import org.apache.catalina.Loader;
22 import org.apache.catalina.LifecycleListener;
23 import org.apache.catalina.LifecycleException;
24 import org.apache.catalina.Container;
25 import org.apache.catalina.Context;
26 import org.apache.catalina.Globals;
27 import org.apache.naming.resources.DirContextURLStreamHandler;
28
29 import org.jboss.mx.loading.RepositoryClassLoader;
30
31 /**
32  * Initial version of a JBoss implementation of the Tomcat Loader.
33  *
34  * @author Scott.Stark@jboss.org
35  * @version $Revision: 1.6.2.2 $
36  */

37 public class WebCtxLoader
38    implements Lifecycle, Loader JavaDoc
39 {
40    /**
41     * The ClassLoader used to scope the ENC
42     */

43    protected ClassLoader JavaDoc encLoader;
44    /**
45     * The ClassLoader returned from getClassLoader
46     */

47    protected ENCLoader ctxLoader;
48    /**
49     * The war UCL used to load the war classes
50     */

51    protected RepositoryClassLoader delegate;
52    protected Container webContainer;
53    protected URL JavaDoc warURL;
54
55    /**
56     * The set of repositories associated with this class loader.
57     */

58    private ArrayList JavaDoc repositories = new ArrayList JavaDoc();
59
60    /**
61     * Create a WebCtxLoader given the ENC scoping class loader.
62     *
63     * @param encLoader
64     */

65    WebCtxLoader(ClassLoader JavaDoc encLoader)
66    {
67       this.encLoader = encLoader;
68       this.ctxLoader = new ENCLoader(encLoader);
69       ClassLoader JavaDoc parent = encLoader;
70       while ((parent instanceof RepositoryClassLoader) == false && parent != null)
71          parent = parent.getParent();
72       this.delegate = (RepositoryClassLoader) parent;
73    }
74
75    public void setWarURL(URL JavaDoc warURL) throws MalformedURLException JavaDoc
76    {
77       this.warURL = warURL;
78       String JavaDoc path = warURL.getFile();
79       File JavaDoc classesDir = new File JavaDoc(path, "WEB-INF/classes");
80       if (classesDir.exists())
81       {
82          delegate.addURL(classesDir.toURL());
83          ctxLoader.addURLInternal(classesDir.toURL());
84       }
85       File JavaDoc libDir = new File JavaDoc(path, "WEB-INF/lib");
86       if (libDir.exists())
87       {
88          File JavaDoc[] jars = libDir.listFiles();
89          int length = jars != null ? jars.length : 0;
90          for (int j = 0; j < length; j++)
91          {
92             delegate.addURL(jars[j].toURL());
93             ctxLoader.addURLInternal(jars[j].toURL());
94          }
95       }
96    }
97
98    public void addLifecycleListener(LifecycleListener listener)
99    {
100    }
101
102    public LifecycleListener[] findLifecycleListeners()
103    {
104       return new LifecycleListener[0];
105    }
106
107    public void removeLifecycleListener(LifecycleListener listener)
108    {
109    }
110
111    public void start() throws LifecycleException
112    {
113       setClassPath();
114       ServletContext JavaDoc servletContext = ((Context JavaDoc) webContainer).getServletContext();
115       if (servletContext == null)
116          return;
117    }
118
119    public void stop() throws LifecycleException
120    {
121       // Remove the ctxLoader mapping kept by the DirContextURLStreamHandler
122
DirContextURLStreamHandler.unbind(ctxLoader);
123       org.apache.commons.logging.LogFactory.release(ctxLoader);
124       org.apache.commons.logging.LogFactory.release(encLoader);
125       this.encLoader = null;
126       this.ctxLoader = null;
127       this.delegate = null;
128       this.repositories.clear();
129       this.warURL = null;
130       this.webContainer = null;
131    }
132
133    public void backgroundProcess()
134    {
135       //To change body of implemented methods use File | Settings | File Templates.
136
}
137
138    /**
139     * We must pass the wrapped encLoader as tomcat needs to see a unique
140     * class loader that is distinct from the thread context class loader seen
141     * to be in effect when the web app is started. This is due to how it
142     * binds contexts using the DirContextURLStreamHandler class.
143     *
144     * @return The ENC scoping class loader
145     * @see org.apache.naming.resources.DirContextURLStreamHandler
146     */

147    public ClassLoader JavaDoc getClassLoader()
148    {
149       return ctxLoader;
150    }
151
152    public Container getContainer()
153    {
154       return webContainer;
155    }
156
157    public void setContainer(Container container)
158    {
159       webContainer = container;
160
161    }
162
163    public boolean getDelegate()
164    {
165       return false;
166    }
167
168    public void setDelegate(boolean delegate)
169    {
170    }
171
172    public String JavaDoc getInfo()
173    {
174       return null;
175    }
176
177    public boolean getReloadable()
178    {
179       return false;
180    }
181
182    public void setReloadable(boolean reloadable)
183    {
184    }
185
186    public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener)
187    {
188    }
189
190    public void addRepository(String JavaDoc repository)
191    {
192       if (repositories.contains(repository) == true)
193          return;
194       repositories.add(repository);
195       setClassPath();
196    }
197
198    public String JavaDoc[] findRepositories()
199    {
200       String JavaDoc[] tmp = new String JavaDoc[repositories.size()];
201       repositories.toArray(tmp);
202       return tmp;
203    }
204
205    public boolean modified()
206    {
207       return false;
208    }
209
210    public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener)
211    {
212    }
213
214    /**
215     * Set the appropriate context attribute for our class path. This
216     * is required only because Jasper depends on it.
217     */

218    private void setClassPath()
219    {
220       // Validate our current state information
221
if (!(webContainer instanceof Context JavaDoc))
222          return;
223       ServletContext JavaDoc servletContext = ((Context JavaDoc) webContainer).getServletContext();
224       if (servletContext == null)
225          return;
226
227       try
228       {
229          Method JavaDoc method =
230             webContainer.getClass().getMethod("getCompilerClasspath", null);
231          Object JavaDoc baseClasspath = method.invoke(webContainer, null);
232          if (baseClasspath != null)
233          {
234             servletContext.setAttribute(Globals.CLASS_PATH_ATTR,
235                baseClasspath.toString());
236             return;
237          }
238       }
239       catch (Exception JavaDoc e)
240       {
241          // Ignore
242
e.printStackTrace();
243       }
244
245       StringBuffer JavaDoc classpath = new StringBuffer JavaDoc();
246
247       // Assemble the class path information from our repositories
248
for (int i = 0; i < repositories.size(); i++)
249       {
250          String JavaDoc repository = repositories.get(i).toString();
251          if (repository.startsWith("file://"))
252             repository = repository.substring(7);
253          else if (repository.startsWith("file:"))
254             repository = repository.substring(5);
255          else if (repository.startsWith("jndi:"))
256             repository = servletContext.getRealPath(repository.substring(5));
257          else
258             continue;
259          if (repository == null)
260             continue;
261          if (i > 0)
262             classpath.append(File.pathSeparator);
263          classpath.append(repository);
264       }
265
266       // Store the assembled class path as a servlet context attribute
267
servletContext.setAttribute(Globals.CLASS_PATH_ATTR,
268          classpath.toString());
269
270    }
271
272    /**
273     * A trival extension of URLClassLoader that uses an empty URL[] as its
274     * classpath so that all work is delegated to its parent.
275     */

276    static class ENCLoader extends URLClassLoader JavaDoc
277    {
278       private URL JavaDoc[] urllist = new URL JavaDoc[0];
279
280       ENCLoader(ClassLoader JavaDoc parent)
281       {
282          super(new URL JavaDoc[0], parent);
283       }
284
285       void addURLInternal(URL JavaDoc url)
286       {
287          URL JavaDoc[] result = new URL JavaDoc[urllist.length + 1];
288          for (int i = 0; i < urllist.length; i++)
289             result[i] = urllist[i];
290          result[urllist.length] = url;
291          urllist = result;
292       }
293
294       public URL JavaDoc[] getURLs()
295       {
296          return urllist;
297       }
298    }
299 }
300
Popular Tags