package org.jboss.web.tomcat.tc5;
import java.beans.PropertyChangeListener;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URLClassLoader;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.Loader;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
import org.apache.naming.resources.DirContextURLStreamHandler;
import org.jboss.mx.loading.RepositoryClassLoader;
public class WebCtxLoader
implements Lifecycle, Loader
{
protected ClassLoader encLoader;
protected ENCLoader ctxLoader;
protected RepositoryClassLoader delegate;
protected Container webContainer;
protected URL warURL;
private ArrayList repositories = new ArrayList();
WebCtxLoader(ClassLoader encLoader)
{
this.encLoader = encLoader;
this.ctxLoader = new ENCLoader(encLoader);
ClassLoader parent = encLoader;
while ((parent instanceof RepositoryClassLoader) == false && parent != null)
parent = parent.getParent();
this.delegate = (RepositoryClassLoader) parent;
}
public void setWarURL(URL warURL) throws MalformedURLException
{
this.warURL = warURL;
String path = warURL.getFile();
File classesDir = new File(path, "WEB-INF/classes");
if (classesDir.exists())
{
delegate.addURL(classesDir.toURL());
ctxLoader.addURLInternal(classesDir.toURL());
}
File libDir = new File(path, "WEB-INF/lib");
if (libDir.exists())
{
File[] jars = libDir.listFiles();
int length = jars != null ? jars.length : 0;
for (int j = 0; j < length; j++)
{
delegate.addURL(jars[j].toURL());
ctxLoader.addURLInternal(jars[j].toURL());
}
}
}
public void addLifecycleListener(LifecycleListener listener)
{
}
public LifecycleListener[] findLifecycleListeners()
{
return new LifecycleListener[0];
}
public void removeLifecycleListener(LifecycleListener listener)
{
}
public void start() throws LifecycleException
{
setClassPath();
ServletContext servletContext = ((Context) webContainer).getServletContext();
if (servletContext == null)
return;
}
public void stop() throws LifecycleException
{
DirContextURLStreamHandler.unbind(ctxLoader);
org.apache.commons.logging.LogFactory.release(ctxLoader);
org.apache.commons.logging.LogFactory.release(encLoader);
this.encLoader = null;
this.ctxLoader = null;
this.delegate = null;
this.repositories.clear();
this.warURL = null;
this.webContainer = null;
}
public void backgroundProcess()
{
}
public ClassLoader getClassLoader()
{
return ctxLoader;
}
public Container getContainer()
{
return webContainer;
}
public void setContainer(Container container)
{
webContainer = container;
}
public boolean getDelegate()
{
return false;
}
public void setDelegate(boolean delegate)
{
}
public String getInfo()
{
return null;
}
public boolean getReloadable()
{
return false;
}
public void setReloadable(boolean reloadable)
{
}
public void addPropertyChangeListener(PropertyChangeListener listener)
{
}
public void addRepository(String repository)
{
if (repositories.contains(repository) == true)
return;
repositories.add(repository);
setClassPath();
}
public String[] findRepositories()
{
String[] tmp = new String[repositories.size()];
repositories.toArray(tmp);
return tmp;
}
public boolean modified()
{
return false;
}
public void removePropertyChangeListener(PropertyChangeListener listener)
{
}
private void setClassPath()
{
if (!(webContainer instanceof Context))
return;
ServletContext servletContext = ((Context) webContainer).getServletContext();
if (servletContext == null)
return;
try
{
Method method =
webContainer.getClass().getMethod("getCompilerClasspath", null);
Object baseClasspath = method.invoke(webContainer, null);
if (baseClasspath != null)
{
servletContext.setAttribute(Globals.CLASS_PATH_ATTR,
baseClasspath.toString());
return;
}
}
catch (Exception e)
{
e.printStackTrace();
}
StringBuffer classpath = new StringBuffer();
for (int i = 0; i < repositories.size(); i++)
{
String repository = repositories.get(i).toString();
if (repository.startsWith("file://"))
repository = repository.substring(7);
else if (repository.startsWith("file:"))
repository = repository.substring(5);
else if (repository.startsWith("jndi:"))
repository = servletContext.getRealPath(repository.substring(5));
else
continue;
if (repository == null)
continue;
if (i > 0)
classpath.append(File.pathSeparator);
classpath.append(repository);
}
servletContext.setAttribute(Globals.CLASS_PATH_ATTR,
classpath.toString());
}
static class ENCLoader extends URLClassLoader
{
private URL[] urllist = new URL[0];
ENCLoader(ClassLoader parent)
{
super(new URL[0], parent);
}
void addURLInternal(URL url)
{
URL[] result = new URL[urllist.length + 1];
for (int i = 0; i < urllist.length; i++)
result[i] = urllist[i];
result[urllist.length] = url;
urllist = result;
}
public URL[] getURLs()
{
return urllist;
}
}
}