User: starksm
Date: 02/02/19 22:42:09
Modified: src/main/org/jboss/web AbstractWebContainer.java
Log:
Add common support for obtaining the JSP compile path given the web
context class loader.
Add support for specifying the root context name at the war level using
the jboss-web/context-root element.
Revision Changes Path
1.29 +244 -68 jboss/src/main/org/jboss/web/AbstractWebContainer.java
Index: AbstractWebContainer.java
===================================================================
RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/web/AbstractWebContainer.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- AbstractWebContainer.java 17 Feb 2002 03:04:31 -0000 1.28
+++ AbstractWebContainer.java 20 Feb 2002 06:42:09 -0000 1.29
@@ -10,7 +10,9 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.io.File;
import java.io.InputStream;
@@ -18,7 +20,9 @@
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.IOException;
+import java.lang.reflect.Method;
import java.net.JarURLConnection;
+import java.net.URL;
import java.util.jar.JarFile;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
@@ -31,7 +35,9 @@
import javax.naming.NameNotFoundException;
import javax.management.ObjectName;
+import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
import org.jboss.deployment.DeploymentInfo;
import org.jboss.deployment.DeploymentException;
@@ -43,6 +49,7 @@
import org.jboss.metadata.ResourceEnvRefMetaData;
import org.jboss.metadata.ResourceRefMetaData;
import org.jboss.metadata.WebMetaData;
+import org.jboss.metadata.XmlFileLoader;
import org.jboss.naming.ENCFactory;
import org.jboss.naming.Util;
import org.jboss.security.plugins.NullSecurityManager;
@@ -139,7 +146,7 @@
@see org.jboss.security.SecurityAssociation;
@author [EMAIL PROTECTED]
-@version $Revision: 1.28 $
+@version $Revision: 1.29 $
*/
public abstract class AbstractWebContainer
extends ServiceMBeanSupport
@@ -174,7 +181,8 @@
/** A mapping of deployed warUrl strings to the WebApplication object */
protected HashMap deploymentMap = new HashMap();
-
+
+
public AbstractWebContainer()
{
}
@@ -203,28 +211,13 @@
{
// iterate the war modules
mod = (J2eeModuleMetaData) it.next();
-
- if (mod.isWeb())
+ if( mod.isWeb() )
{
- //only pick up the context for our war, the names should match
- // The wars come from packages and thus are unpackaged under
/tmp/deploy/<intNumber>.myweb.war
- if (di.shortName.lastIndexOf(mod.getFileName()) != -1)
- di.webContext = mod.getWebContext();
- }
+ di.webContext = mod.getWebContext();
+ }
}
}
-
- if (di.webContext == null)
- {
- di.webContext = di.shortName;
- }
-
- // if it is not a sub-deployment get the context from the name of the
deployment
- // FIXME marcf: I can't believe there is no way to specify the context in
web.xml
-
- // make sure the context starts with a slash
- if (!di.webContext.startsWith("/")) di.webContext = "/"+di.webContext;
-
+
// resolve the watch
if (di.url.getProtocol().startsWith("http"))
{
@@ -374,8 +367,20 @@
URLClassLoader warLoader = URLClassLoader.newInstance(empty,
appClassLoader);
thread.setContextClassLoader(warLoader);
WebDescriptorParser webAppParser = new DescriptorParser(di);
- WebApplication warInfo = performDeploy(di.webContext,
di.localUrl.toString(), webAppParser);
- deploymentMap.put(di.localUrl.toString(), warInfo);
+ // If there is no di.webContext build it from the war or jboss-web.xml
+ String webContext = di.webContext;
+ if( webContext != null )
+ {
+ if( webContext.length() > 0 && webContext.charAt(0) != '/' )
+ webContext = "/" + webContext;
+ }
+ // Get the war URL
+ URL warURL = di.localUrl != null ? di.localUrl : di.url;
+ // If there is no webContext build one
+ if( webContext == null )
+ webContext = buildWebContext(di);
+ WebApplication warInfo = performDeploy(webContext, warURL.toString(),
webAppParser);
+ deploymentMap.put(warURL.toString(), warInfo);
}
catch(DeploymentException e)
{
@@ -383,7 +388,7 @@
}
catch(Exception e)
{
- e.printStackTrace();
+ log.error("Error during deploy", e);
throw new DeploymentException("Error during deploy", e);
}
finally
@@ -396,7 +401,9 @@
subclasses to perform the web container specific deployment steps.
@param ctxPath, The context-root element value from the J2EE
application/module/web application.xml descriptor. This may be null
- if war was is not being deployed as part of an enterprise application.
+ if war was is not being deployed as part of an enterprise application. If it
+ is null, you should check the jboss-web.xml descriptor for a context-root
+ element.
@param warUrl, The string for the URL of the web application war.
@param webAppParser, The callback interface the web container should use to
setup the web app JNDI environment for use by the web app components. This
@@ -407,7 +414,7 @@
*/
protected abstract WebApplication performDeploy(String ctxPath, String warUrl,
WebDescriptorParser webAppParser) throws Exception;
-
+
/** A template pattern implementation of the undeploy() method. This method
calls the {@link #performUndeploy(String) performUndeploy()} method to
perform the container specific undeployment steps and unregisters the
@@ -483,6 +490,42 @@
{
}
+ public void startService() throws Exception
+ {
+ try
+ {
+ // Register with the main deployer
+ server.invoke(
+ org.jboss.deployment.MainDeployerMBean.OBJECT_NAME,
+ "addDeployer",
+ new Object[] {this},
+ new String[] {"org.jboss.deployment.DeployerMBean"});
+ }
+ catch (Exception e)
+ {
+ log.error("Could not register with MainDeployer", e);
+ }
+ }
+
+ /**
+ * Implements the template method in superclass. This method stops all the
+ * applications in this server.
+ */
+ public void stopService()
+ {
+ try
+ {
+ // Register with the main deployer
+ server.invoke(
+ org.jboss.deployment.MainDeployerMBean.OBJECT_NAME,
+ "removeDeployer",
+ new Object[] {this},
+ new String[] {"org.jboss.deployment.DeployerMBean"});
+ }
+ catch (Exception e) {log.error("Could not register with MainDeployer", e);}
+
+ }
+
/** This method is invoked from within subclass performDeploy() method
implementations when they invoke WebDescriptorParser.parseWebAppDescriptors().
@@ -547,7 +590,7 @@
linkSecurityDomain(securityDomain, envCtx);
log.debug("AbstractWebContainer.parseWebAppDescriptors, End");
}
-
+
protected void addEnvEntries(Iterator envEntries, Context envCtx)
throws ClassNotFoundException, NamingException
{
@@ -650,53 +693,15 @@
EjbLocalRefMetaData ejb = (EjbLocalRefMetaData) ejbRefs.next();
String name = ejb.getName();
String linkName = ejb.getLink();
- String jndiName = di.findEjbLink(linkName);
+ String jndiName = di.findEjbLocalLink(linkName);
if( jndiName == null )
- throw new NamingException("ejb-ref: "+name+", target not found, add
valid ejb-link");
- // The local home location is "local/"+jndiName
- jndiName = "local/" + jndiName;
+ throw new NamingException("ejb-local-ref: "+name+", target not found,
add valid ejb-link");
log.debug("Linking ejb-local-ref: "+name+" to JNDI name: "+jndiName);
Util.bind(envCtx, name, new LinkRef(jndiName));
}
}
- public void startService() throws Exception
- {
- try
- {
- // Register with the main deployer
- server.invoke(
- org.jboss.deployment.MainDeployerMBean.OBJECT_NAME,
- "addDeployer",
- new Object[] {this},
- new String[] {"org.jboss.deployment.DeployerMBean"});
- }
- catch (Exception e)
- {
- log.error("Could not register with MainDeployer", e);
- }
- }
-
- /**
- * Implements the template method in superclass. This method stops all the
- * applications in this server.
- */
- public void stopService()
- {
- try
- {
- // Register with the main deployer
- server.invoke(
- org.jboss.deployment.MainDeployerMBean.OBJECT_NAME,
- "removeDeployer",
- new Object[] {this},
- new String[] {"org.jboss.deployment.DeployerMBean"});
- }
- catch (Exception e) {log.error("Could not register with MainDeployer", e);}
-
- }
-
/** This creates a java:comp/env/security context that contains a
securityMgr binding pointing to an AuthenticationManager implementation
and a realmMapping binding pointing to a RealmMapping implementation.
@@ -727,7 +732,178 @@
Util.bind(envCtx, "security/subject", new
LinkRef(securityDomain+"/subject"));
}
}
-
+
+ /** A utility method that searches the given loader for the
+ resources: "javax/servlet/resources/web-app_2_3.dtd",
+ "org/apache/jasper/resources/jsp12.dtd", and "javax/ejb/EJBHome.class"
+ and returns an array of URL strings. Any jar: urls are reduced to the
+ underlying <url> portion of the 'jar:<url>!/{entry}' construct.
+ */
+ public String[] getStandardCompileClasspath(ClassLoader loader)
+ {
+ String[] jspResources = {
+ "javax/servlet/resources/web-app_2_3.dtd",
+ "org/apache/jasper/resources/jsp12.dtd",
+ "javax/ejb/EJBHome.class"
+ };
+ ArrayList tmp = new ArrayList();
+ for(int j = 0; j < jspResources.length; j ++)
+ {
+ URL rsrcURL = loader.getResource(jspResources[j]);
+ if( rsrcURL != null )
+ {
+ String url = rsrcURL.toExternalForm();
+ if( rsrcURL.getProtocol().equals("jar") )
+ {
+ // Parse the jar:<url>!/{entry} URL
+ url = url.substring(4);
+ int seperator = url.indexOf('!');
+ url = url.substring(0, seperator);
+ }
+ tmp.add(url);
+ }
+ else
+ {
+ log.warn("Failed to fin jsp rsrc: "+jspResources[j]);
+ }
+ }
+ log.trace("JSP StandardCompileClasspath: " + tmp);
+ String[] cp = new String[tmp.size()];
+ tmp.toArray(cp);
+ return cp;
+ }
+
+ /** A utility method that walks up the ClassLoader chain starting at
+ the given loader and queries each ClassLoader for a 'URL[] getURLs()'
+ method from which a complete classpath of URL strings is built.
+ */
+ public String[] getCompileClasspath(ClassLoader loader)
+ {
+ HashSet tmp = new HashSet();
+ ClassLoader cl = loader;
+ while( cl != null )
+ {
+ URL[] urls = getClassLoaderURLs(cl);
+ for(int u = 0; u < urls.length; u ++)
+ {
+ URL url = urls[u];
+ tmp.add(url.toExternalForm());
+ }
+ cl = cl.getParent();
+ }
+
+ log.trace("JSP CompileClasspath: " + tmp);
+ String[] cp = new String[tmp.size()];
+ tmp.toArray(cp);
+ return cp;
+ }
+
+ /** Use reflection to access a URL[] getURLs method so that non-URLClassLoader
+ *class loaders that support this method can provide info.
+ */
+ private URL[] getClassLoaderURLs(ClassLoader cl)
+ {
+ URL[] urls = {};
+ try
+ {
+ Class returnType = urls.getClass();
+ Class[] parameterTypes = {};
+ Method getURLs = cl.getClass().getMethod("getURLs", parameterTypes);
+ if( returnType.isAssignableFrom(getURLs.getReturnType()) )
+ {
+ Object[] args = {};
+ urls = (URL[]) getURLs.invoke(cl, args);
+ }
+ }
+ catch(Exception ignore)
+ {
+ }
+ return urls;
+ }
+
+ /** This method creates a context-root string from either the
+ WEB-INF/jboss-web.xml context-root element is one exists, or the
+ filename portion of the warURL. It is called if the DeploymentInfo
+ webContext value is null which indicates a standalone war deployment.
+ A war name of ROOT.war is handled as a special case of a war that
+ should be installed as the default web context.
+ */
+ protected String buildWebContext(DeploymentInfo di)
+ {
+ String webContext = null;
+ String warName = di.shortName;
+ URL warURL = di.url;
+
+ try
+ {
+ // First check for a WEB-INF/jboss-web.xml context-root element
+ InputStream warIS = warURL.openStream();
+ java.util.zip.ZipInputStream zipIS = new
java.util.zip.ZipInputStream(warIS);
+ java.io.FilterInputStream wrapperIS = new java.io.FilterInputStream(zipIS)
+ {
+ public void close()
+ {
+ }
+ };
+ java.util.zip.ZipEntry entry;
+ while( (entry = zipIS.getNextEntry()) != null )
+ {
+ if( entry.getName().equals("WEB-INF/jboss-web.xml") )
+ {
+ try
+ {
+ XmlFileLoader xmlLoader = new XmlFileLoader();
+ Document jbossWebDoc = xmlLoader.getDocument(wrapperIS,
"WEB-INF/jboss-web.xml");
+ Element jbossWeb = jbossWebDoc.getDocumentElement();
+ NodeList contextRoot = jbossWeb.getElementsByTagName("context-root");
+ if( contextRoot.getLength() > 0 )
+ {
+ webContext = contextRoot.item(0).getFirstChild().getNodeValue();
+ webContext = webContext.trim();
+ log.trace("Found jboss-web/context-root="+webContext);
+ }
+ }
+ catch(Exception e)
+ {
+ }
+ break;
+ }
+ }
+ zipIS.close();
+ }
+ catch(Exception e)
+ {
+ log.trace("Failed to parse warURL("+warURL+") WEB-INF/jboss-web.xml", e);
+ }
+
+ if( webContext == null )
+ {
+ // Build the context from the war name, strip the .war suffix
+ webContext = warName;
+ int suffix = webContext.indexOf(".war");
+ if( suffix > 0 )
+ webContext = webContext.substring(0, suffix);
+ // Strip any '<int-value>.' prefix
+ int index = 0;
+ for(; index < webContext.length(); index ++)
+ {
+ char c = webContext.charAt(index);
+ if( Character.isDigit(c) == false && c != '.' )
+ break;
+ }
+ webContext = webContext.substring(index);
+ // Special hanling for a war file named ROOT
+ if( webContext.equals("ROOT") )
+ webContext = "";
+ }
+
+ // Servlet containers are anal about the web context starting with '/'
+ if( webContext.length() > 0 && webContext.charAt(0) != '/' )
+ webContext = "/" + webContext;
+
+ return webContext;
+ }
+
/** An inner class that maps the WebDescriptorParser.parseWebAppDescriptors()
onto the protected parseWebAppDescriptors() AbstractWebContainer method.
*/
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development