[jboss-cvs] JBossAS SVN: r58678 - trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Sun Nov 26 20:40:12 EST 2006
Author: remy.maucherat at jboss.com
Date: 2006-11-26 20:40:09 -0500 (Sun, 26 Nov 2006)
New Revision: 58678
Added:
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/JBossContextConfig.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/TomcatDeployment2.java
trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/VFSDirContext.java
Log:
- Implementation (not complete) of a new deployer using WebMetaData. There are some missing fields in WebMetaData at the
moment, so replacing Tomcat's parsing is not possible yet.
- Add a placeholder for a DirContext VFS implementation. It uses the WAR DirContext since the VirtualFile API structure
seems extremely similar to the zip API.
Added: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/JBossContextConfig.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/JBossContextConfig.java 2006-11-26 01:28:14 UTC (rev 58677)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/JBossContextConfig.java 2006-11-27 01:40:09 UTC (rev 58678)
@@ -0,0 +1,152 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.tc6.deployers;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.startup.ContextConfig;
+import org.jboss.metadata.Listener;
+import org.jboss.metadata.NameValuePair;
+import org.jboss.metadata.WebMetaData;
+import org.jboss.metadata.WebSecurityMetaData;
+import org.jboss.metadata.web.ErrorPage;
+import org.jboss.metadata.web.Filter;
+import org.jboss.metadata.web.FilterMapping;
+import org.jboss.metadata.web.LoginConfig;
+import org.jboss.metadata.web.ParamValue;
+import org.jboss.metadata.web.Servlet;
+
+public class JBossContextConfig extends ContextConfig {
+
+ public static ThreadLocal<WebMetaData> metaDataLocal = new ThreadLocal<WebMetaData>();
+
+ @Override
+ protected void applicationWebConfig() {
+
+ // FIXME: also do parsing in Tomcat, as JBoss web.xml parsing is missing certain things
+ super.applicationWebConfig();
+
+ WebMetaData metaData = metaDataLocal.get();
+
+ // FIXME: metadata-complete attribute
+
+ // Context params
+ Iterator<ParamValue> iterator = metaData.getContextParams().iterator();
+ while (iterator.hasNext()) {
+ ParamValue paramValue = iterator.next();
+ context.addParameter(paramValue.getName(), paramValue.getValue());
+ }
+
+ // Display name
+ context.setDisplayName(metaData.getDisplayName());
+
+ // Distributable
+ context.setDistributable(metaData.getDistributable());
+
+ // Error pages
+ // FIXME: Exception type ?
+ Iterator iterator2 = metaData.getErrorPages().iterator();
+ while (iterator2.hasNext()) {
+ ErrorPage value = (ErrorPage) iterator2.next();
+ org.apache.catalina.deploy.ErrorPage errorPage =
+ new org.apache.catalina.deploy.ErrorPage();
+ errorPage.setErrorCode(value.getErrorCode());
+ if (errorPage.getErrorCode() == 0) {
+ errorPage.setExceptionType(value.getErrorCode());
+ }
+ errorPage.setLocation(value.getLocation());
+ context.addErrorPage(errorPage);
+ }
+
+ // Filter definitions
+ Iterator<Filter> iterator3 = metaData.getFilters().iterator();
+ while (iterator3.hasNext()) {
+ Filter value = iterator3.next();
+ org.apache.catalina.deploy.FilterDef filterDef =
+ new org.apache.catalina.deploy.FilterDef();
+ filterDef.setFilterName(value.getName());
+ filterDef.setFilterClass(value.getFilterClass());
+ Iterator params = value.getInitParams().iterator();
+ while (params.hasNext()) {
+ NameValuePair nvp = (NameValuePair) params.next();
+ filterDef.addInitParameter(nvp.getName(), nvp.getValue());
+ }
+ context.addFilterDef(filterDef);
+ }
+
+ // Filter mappings
+ // FIXME: No dispatcher mapping
+ Iterator<FilterMapping> iterator4 = metaData.getFilterMappings().iterator();
+ while (iterator4.hasNext()) {
+ FilterMapping value = iterator4.next();
+ org.apache.catalina.deploy.FilterMap filterMap =
+ new org.apache.catalina.deploy.FilterMap();
+ filterMap.setFilterName(value.getFilterName());
+ filterMap.addServletName(value.getServletName());
+ filterMap.addURLPattern(value.getUrlPattern());
+ context.addFilterMap(filterMap);
+ }
+
+ // Listeners
+ Iterator iterator5 = metaData.getListeners().iterator();
+ while (iterator5.hasNext()) {
+ Listener value = (Listener) iterator5.next();
+ context.addApplicationListener(value.getListenerClass());
+ }
+
+ // FIXME: handling jsp-config for jsp-property-group/url-pattern and listener-class is needed
+
+ // Login configuration
+ LoginConfig loginConfig = metaData.getLoginConfig();
+ org.apache.catalina.deploy.LoginConfig loginConfig2 =
+ new org.apache.catalina.deploy.LoginConfig();
+ loginConfig2.setAuthMethod(loginConfig.getAuthMethod());
+ loginConfig2.setRealmName(loginConfig.getRealmName());
+ if (loginConfig.getFormLoginConfig() != null) {
+ loginConfig2.setLoginPage(loginConfig.getFormLoginConfig().getLoginPage());
+ loginConfig2.setErrorPage(loginConfig.getFormLoginConfig().getErrorPage());
+ }
+
+ // FIXME: mime mappings parsing
+
+ // Security constraints
+ Iterator<WebSecurityMetaData> iterator6 = metaData.getSecurityContraints();
+ // FIXME: compatibility with everything should be checked
+
+ // Servlet
+ Iterator<Servlet> iterator7 = metaData.getServlets().iterator();
+ while (iterator7.hasNext()) {
+ Servlet value = iterator7.next();
+ org.apache.catalina.Wrapper wrapper = context.createWrapper();
+
+ }
+
+ // Servlet mapping
+
+ // FIXME: locale encoding mapping
+
+ }
+
+}
Property changes on: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/JBossContextConfig.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/TomcatDeployment2.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/TomcatDeployment2.java 2006-11-26 01:28:14 UTC (rev 58677)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/TomcatDeployment2.java 2006-11-27 01:40:09 UTC (rev 58678)
@@ -0,0 +1,626 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.web.tomcat.tc6.deployers;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.security.CodeSource;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import javax.management.Attribute;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.Loader;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.startup.ContextConfig;
+import org.apache.tomcat.util.modeler.Registry;
+import org.jboss.deployers.spi.deployer.DeploymentUnit;
+import org.jboss.logging.Logger;
+import org.jboss.metadata.WebMetaData;
+import org.jboss.mx.util.MBeanServerLocator;
+import org.jboss.security.AuthorizationManager;
+import org.jboss.security.authorization.PolicyRegistration;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.web.WebApplication;
+import org.jboss.web.deployers.AbstractWarDeployment;
+import org.jboss.web.tomcat.security.JaccContextValve;
+import org.jboss.web.tomcat.security.RunAsListener;
+import org.jboss.web.tomcat.security.SecurityAssociationValve;
+import org.jboss.web.tomcat.tc6.TomcatInjectionContainer;
+import org.jboss.web.tomcat.tc6.WebAppLoader;
+import org.jboss.web.tomcat.tc6.WebCtxLoader;
+import org.jboss.web.tomcat.tc6.session.AbstractJBossManager;
+import org.jboss.web.tomcat.tc6.session.ClusteringNotSupportedException;
+import org.jboss.web.tomcat.tc6.session.JBossCacheManager;
+import org.omg.CORBA.ORB;
+
+/**
+ * A tomcat web application deployment.
+ *
+ * @author Scott.Stark at jboss.org
+ * @author Costin Manolache
+ * @version $Revision: 56605 $
+ */
+public class TomcatDeployment2 extends AbstractWarDeployment
+{
+ private static final Logger log = Logger.getLogger(TomcatDeployment2.class);
+
+ /**
+ * The name of the war level context configuration descriptor
+ */
+ private static final String CONTEXT_CONFIG_FILE = "WEB-INF/context.xml";
+
+ private DeployerConfig config;
+ private String[] javaVMs = { " jboss.management.local:J2EEServer=Local,j2eeType=JVM,name=localhost" };
+ private String serverName = "jboss";
+ private HashMap vhostToHostNames = new HashMap();
+ private ORB orb = null;
+ private TomcatInjectionContainer injectionContainer;
+
+ public ORB getORB()
+ {
+ return orb;
+ }
+ public void setORB(ORB orb)
+ {
+ this.orb = orb;
+ }
+
+ @Override
+ public void init(Object containerConfig) throws Exception
+ {
+ this.config = (DeployerConfig)containerConfig;
+ super.setJava2ClassLoadingCompliance(config.isJava2ClassLoadingCompliance());
+ super.setUnpackWars(config.isUnpackWars());
+ super.setLenientEjbLink(config.isLenientEjbLink());
+ super.setDefaultSecurityDomain(config.getDefaultSecurityDomain());
+ }
+
+ @Override
+ protected void performDeploy(WebApplication webApp, String warUrl)
+ throws Exception
+ {
+ // Decode the URL as tomcat can't deal with paths with escape chars
+ warUrl = URLDecoder.decode(warUrl, "UTF-8");
+ webApp.setDomain(config.getCatalinaDomain());
+ WebMetaData metaData = webApp.getMetaData();
+ String hostName = null;
+ // Get any jboss-web/virtual-hosts
+ Iterator vhostNames = metaData.getVirtualHosts();
+ // Map the virtual hosts onto the configured hosts
+ Iterator hostNames = mapVirtualHosts(vhostNames);
+ if (hostNames.hasNext())
+ {
+ hostName = hostNames.next().toString();
+ }
+ performDeployInternal(hostName, webApp, warUrl);
+ while (hostNames.hasNext())
+ {
+ String additionalHostName = hostNames.next().toString();
+ performDeployInternal(additionalHostName, webApp, warUrl);
+ }
+ }
+
+ protected void performDeployInternal(String hostName,
+ WebApplication webApp, String warUrl) throws Exception
+ {
+
+ WebMetaData metaData = webApp.getMetaData();
+ String ctxPath = metaData.getContextRoot();
+ if (ctxPath.equals("/") || ctxPath.equals("/ROOT") || ctxPath.equals(""))
+ {
+ log.debug("deploy root context=" + ctxPath);
+ ctxPath = "/";
+ metaData.setContextRoot(ctxPath);
+ }
+
+ log.info("deploy, ctxPath=" + ctxPath + ", warUrl="
+ + shortWarUrlFromServerHome(warUrl));
+
+ URL url = new URL(warUrl);
+
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ metaData.setContextLoader(loader);
+
+ injectionContainer = new TomcatInjectionContainer(webApp, webApp.getDeploymentUnit());
+
+ Loader webLoader = webApp.getDeploymentUnit().getAttachment(Loader.class);
+ if( webLoader == null )
+ webLoader = getWebLoader(webApp.getDeploymentUnit(), loader, url);
+
+ webApp.setName(url.getPath());
+ webApp.setClassLoader(loader);
+ webApp.setURL(url);
+
+ String objectNameS = config.getCatalinaDomain() + ":j2eeType=WebModule,name=//"
+ + ((hostName == null) ? "localhost" : hostName) + ctxPath
+ + ",J2EEApplication=none,J2EEServer=none";
+
+ ObjectName objectName = new ObjectName(objectNameS);
+
+ StandardContext context = (StandardContext) Class.forName(config.getContextClassName()).newInstance();
+ Registry.getRegistry().registerComponent(context, objectName,
+ config.getContextClassName());
+
+ // Find and set warInfo file on the context
+ // If WAR is packed, expand warInfo file to temp folder
+ String ctxConfig = null;
+ try
+ {
+ // TODO: this should be input metadata
+ ctxConfig = findConfig(url);
+ } catch (IOException e)
+ {
+ log.debug("No " + CONTEXT_CONFIG_FILE + " in " + url, e);
+ }
+
+ if (injectionContainer != null)
+ {
+ context.setAnnotationProcessor(injectionContainer);
+ }
+ context.setDocBase(url.getFile());
+ context.setConfigFile(ctxConfig);
+ context.setDefaultContextXml("context.xml");
+ context.setDefaultWebXml("conf/web.xml");
+ // If there is an alt-dd set it
+ if( metaData.getAltDDPath() != null )
+ {
+ log.debug("Setting altDDName to: "+metaData.getAltDDPath());
+ context.setAltDDName(metaData.getAltDDPath());
+ }
+ context.setJavaVMs(javaVMs);
+ context.setServer(serverName);
+ context.setSaveConfig(false);
+
+ if (webLoader != null)
+ {
+ context.setLoader(webLoader);
+ } else
+ {
+ context.setParentClassLoader(loader);
+ }
+ context.setDelegate(webApp.getJava2ClassLoadingCompliance());
+
+ String[] jspCP = getCompileClasspath(loader);
+ StringBuffer classpath = new StringBuffer();
+ for (int u = 0; u < jspCP.length; u++)
+ {
+ String repository = jspCP[u];
+ if (repository == null)
+ continue;
+ if (repository.startsWith("file://"))
+ repository = repository.substring(7);
+ else if (repository.startsWith("file:"))
+ repository = repository.substring(5);
+ else
+ continue;
+ if (repository == null)
+ continue;
+ // ok it is a file. Make sure that is is a directory or jar file
+ File fp = new File(repository);
+ if (!fp.isDirectory())
+ {
+ // if it is not a directory, try to open it as a zipfile.
+ try
+ {
+ // avoid opening .xml files
+ if (fp.getName().toLowerCase().endsWith(".xml"))
+ continue;
+
+ ZipFile zip = new ZipFile(fp);
+ zip.close();
+ } catch (IOException e)
+ {
+ continue;
+ }
+
+ }
+ if (u > 0)
+ classpath.append(File.pathSeparator);
+ classpath.append(repository);
+ }
+
+ context.setCompilerClasspath(classpath.toString());
+
+ // Set the session cookies flag according to metadata
+ switch (metaData.getSessionCookies())
+ {
+ case WebMetaData.SESSION_COOKIES_ENABLED:
+ context.setCookies(true);
+ log.debug("Enabling session cookies");
+ break;
+ case WebMetaData.SESSION_COOKIES_DISABLED:
+ context.setCookies(false);
+ log.debug("Disabling session cookies");
+ break;
+ default:
+ log.debug("Using session cookies default setting");
+ }
+
+ // Add a valve to estalish the JACC context before authorization valves
+ Certificate[] certs = null;
+ CodeSource cs = new CodeSource(url, certs);
+ JaccContextValve jaccValve = new JaccContextValve(metaData, cs);
+ context.addValve(jaccValve);
+
+ // Set listener
+ // FIXME: New binaries needed
+ // context.setConfigClass("org.jboss.web.tomcat.tc6.deployers.JBossContextConfig");
+
+ // Pass the metadata to the RunAsListener via a thread local
+ RunAsListener.metaDataLocal.set(metaData);
+ JBossContextConfig.metaDataLocal.set(metaData);
+ try
+ {
+ // Init the container; this will also start it
+ context.init();
+ }
+ finally
+ {
+ RunAsListener.metaDataLocal.set(null);
+ JBossContextConfig.metaDataLocal.set(null);
+ }
+
+ // make the context class loader known to the WebMetaData, ws4ee needs it
+ // to instanciate service endpoint pojos that live in this webapp
+ Loader ctxLoader = context.getLoader();
+ metaData.setContextLoader(ctxLoader.getClassLoader());
+
+ // Start it
+ context.start();
+ // Build the ENC
+
+ if (injectionContainer == null)
+ super.processEnc(webLoader.getClassLoader(), webApp);
+ else
+ {
+ Thread currentThread = Thread.currentThread();
+ ClassLoader currentLoader = loader;
+ try
+ {
+ // Create a java:comp/env environment unique for the web application
+ log.debug("Creating ENC using ClassLoader: " + loader);
+ ClassLoader parent = loader.getParent();
+ while (parent != null)
+ {
+ log.debug(".." + parent);
+ parent = parent.getParent();
+ }
+ // TODO: The enc should be an input?
+ currentThread.setContextClassLoader(webLoader.getClassLoader());
+ metaData.setENCLoader(webLoader.getClassLoader());
+ InitialContext iniCtx = new InitialContext();
+ Context envCtx = (Context) iniCtx.lookup("java:comp");
+ envCtx = envCtx.createSubcontext("env");
+ injectionContainer.populateEnc(webLoader.getClassLoader());
+ // TODO: this should be bindings in the metadata
+ currentThread.setContextClassLoader(webLoader.getClassLoader());
+ String securityDomain = metaData.getSecurityDomain();
+ log.debug("linkSecurityDomain");
+ linkSecurityDomain(securityDomain, envCtx);
+ }
+ finally
+ {
+ currentThread.setContextClassLoader(currentLoader);
+ }
+ }
+
+ // Clustering
+ if (metaData.getDistributable())
+ {
+ // Try to initate clustering, fallback to standard if no clustering is
+ // available
+ try
+ {
+ AbstractJBossManager manager = null;
+ String managerClassName = config.getManagerClass();
+ Class managerClass = Thread.currentThread().getContextClassLoader()
+ .loadClass(managerClassName);
+ manager = (AbstractJBossManager) managerClass.newInstance();
+ String name = "//" + ((hostName == null) ? "localhost" : hostName)
+ + ctxPath;
+ manager.init(name, metaData, config.isUseJK(), config
+ .isUseLocalCache());
+
+ if (manager instanceof JBossCacheManager)
+ {
+ String snapshotMode = config.getSnapshotMode();
+ int snapshotInterval = config.getSnapshotInterval();
+ JBossCacheManager jbcm = (JBossCacheManager) manager;
+ jbcm.setSnapshotMode(snapshotMode);
+ jbcm.setSnapshotInterval(snapshotInterval);
+ }
+
+ server.setAttribute(objectName, new Attribute("manager", manager));
+
+ log.debug("Enabled clustering support for ctxPath=" + ctxPath);
+ }
+ catch (ClusteringNotSupportedException e)
+ {
+ // JBAS-3513 Just log a WARN, not an ERROR
+ log.warn("Failed to setup clustering, clustering disabled. ClusteringNotSupportedException: "
+ + e.getMessage());
+ }
+ catch (NoClassDefFoundError ncdf)
+ {
+ // JBAS-3513 Just log a WARN, not an ERROR
+ log.debug("Classes needed for clustered webapp unavailable", ncdf);
+ log.warn("Failed to setup clustering, clustering disabled. NoClassDefFoundError: "
+ + ncdf.getMessage());
+ }
+ catch (Throwable t)
+ {
+ // TODO consider letting this through and fail the deployment
+ log.error("Failed to setup clustering, clustering disabled. Exception: ", t);
+ }
+ }
+
+ /*
+ * Add security association valve after the authorization valves so that
+ * the authenticated user may be associated with the request
+ * thread/session.
+ */
+ SecurityAssociationValve valve = new SecurityAssociationValve(metaData,
+ config.getSecurityManagerService());
+ valve.setSubjectAttributeName(config.getSubjectAttributeName());
+ server.invoke(objectName, "addValve", new Object[] { valve },
+ new String[] { "org.apache.catalina.Valve" });
+
+ /* TODO: Retrieve the state, and throw an exception in case of a failure
+ Integer state = (Integer) server.getAttribute(objectName, "state");
+ if (state.intValue() != 1)
+ {
+ throw new DeploymentException("URL " + warUrl + " deployment failed");
+ }
+ */
+
+ webApp.setAppData(objectName);
+
+ /*
+ * TODO: Create mbeans for the servlets ObjectName servletQuery = new
+ * ObjectName (config.getCatalinaDomain() + ":j2eeType=Servlet,WebModule=" +
+ * objectName.getKeyProperty("name") + ",*"); Iterator iterator =
+ * server.queryMBeans(servletQuery, null).iterator(); while
+ * (iterator.hasNext()) {
+ * di.mbeans.add(((ObjectInstance)iterator.next()).getObjectName()); }
+ */
+
+ if (metaData.getSecurityDomain() != null)
+ {
+ String secDomain = org.jboss.security.Util
+ .unprefixSecurityDomain(metaData.getSecurityDomain());
+ // Associate the Context Id with the Security Domain
+ String contextID = metaData.getJaccContextID();
+
+ //Check if an xacml policy file is present
+ URL xacmlPolicyFile = this.config.getXacmlPolicyURL();
+ if (xacmlPolicyFile != null)
+ {
+ AuthorizationManager authzmgr = org.jboss.security.Util
+ .getAuthorizationManager(secDomain);
+ if (authzmgr instanceof PolicyRegistration)
+ {
+ PolicyRegistration xam = (PolicyRegistration) authzmgr;
+ xam.registerPolicy(contextID, xacmlPolicyFile);
+ }
+ }
+ }
+
+ log.debug("Initialized: " + webApp + " " + objectName);
+ }
+
+ public Loader getWebLoader(DeploymentUnit unit, ClassLoader loader, URL url)
+ throws MalformedURLException
+ {
+ Loader webLoader = null;
+
+ /*
+ * If we are using the jboss class loader we need to augment its path to
+ * include the WEB-INF/{lib,classes} dirs or else scoped class loading
+ * does not see the war level overrides. The call to setWarURL adds these
+ * paths to the deployment UCL.
+ */
+ ArrayList<URL> classpath = (ArrayList<URL>) unit.getAttachment("org.jboss.web.expandedWarClasspath");
+ if (config.isUseJBossWebLoader())
+ {
+ WebCtxLoader jbossLoader = new WebCtxLoader(loader, injectionContainer);
+ if( classpath != null )
+ jbossLoader.setClasspath(classpath);
+ webLoader = jbossLoader;
+ }
+ else
+ {
+ String[] pkgs = config.getFilteredPackages();
+ WebAppLoader jbossLoader = new WebAppLoader(loader, pkgs, injectionContainer);
+ jbossLoader.setDelegate(getJava2ClassLoadingCompliance());
+ if( classpath != null )
+ jbossLoader.setClasspath(classpath);
+ webLoader = jbossLoader;
+ }
+ return webLoader;
+ }
+
+ public void setInjectionContainer(TomcatInjectionContainer container)
+ {
+ this.injectionContainer = container;
+ }
+
+ /**
+ * Called as part of the undeploy() method template to ask the subclass for
+ * perform the web container specific undeployment steps.
+ */
+ protected void performUndeploy(WebApplication warInfo, String warUrl)
+ throws Exception
+ {
+ if (warInfo == null)
+ {
+ log.debug("performUndeploy, no WebApplication found for URL "+ warUrl);
+ return;
+ }
+
+ log.info("undeploy, ctxPath=" + warInfo.getMetaData().getContextRoot()
+ + ", warUrl=" + shortWarUrlFromServerHome(warUrl));
+
+ WebMetaData metaData = warInfo.getMetaData();
+ String hostName = null;
+ Iterator hostNames = metaData.getVirtualHosts();
+ if (hostNames.hasNext())
+ {
+ hostName = hostNames.next().toString();
+ }
+ performUndeployInternal(hostName, warUrl, warInfo);
+ while (hostNames.hasNext())
+ {
+ String additionalHostName = hostNames.next().toString();
+ performUndeployInternal(additionalHostName, warUrl, warInfo);
+ }
+
+ }
+
+ protected void performUndeployInternal(String hostName, String warUrl,
+ WebApplication warInfo) throws Exception
+ {
+
+ WebMetaData metaData = warInfo.getMetaData();
+ String ctxPath = metaData.getContextRoot();
+
+ // TODO: Need to remove the dependency on MBeanServer
+ MBeanServer server = MBeanServerLocator.locateJBoss();
+ // If the server is gone, all apps were stopped already
+ if (server == null)
+ return;
+
+ ObjectName objectName = new ObjectName(config.getCatalinaDomain()
+ + ":j2eeType=WebModule,name=//"
+ + ((hostName == null) ? "localhost" : hostName) + ctxPath
+ + ",J2EEApplication=none,J2EEServer=none");
+
+ if (server.isRegistered(objectName))
+ {
+ // Contexts should be stopped by the host already
+ server.invoke(objectName, "destroy", new Object[] {}, new String[] {});
+ }
+
+ }
+
+ /**
+ * Resolve the input virtual host names to the names of the configured Hosts
+ * @param vhostNames Iterator<String> for the jboss-web/virtual-host elements
+ * @return Iterator<String> of the unique Host names
+ * @throws Exception
+ */
+ protected synchronized Iterator mapVirtualHosts(Iterator vhostNames)
+ throws Exception
+ {
+ if (vhostToHostNames.size() == 0)
+ {
+ // Query the configured Host mbeans
+ String hostQuery = config.getCatalinaDomain() + ":type=Host,*";
+ ObjectName query = new ObjectName(hostQuery);
+ Set hosts = server.queryNames(query, null);
+ Iterator iter = hosts.iterator();
+ while (iter.hasNext())
+ {
+ ObjectName host = (ObjectName)iter.next();
+ String name = host.getKeyProperty("host");
+ if (name != null)
+ {
+ vhostToHostNames.put(name, name);
+ String[] aliases = (String[])
+ server.invoke(host, "findAliases", null, null);
+ int count = aliases != null ? aliases.length : 0;
+ for (int n = 0; n < count; n++)
+ {
+ vhostToHostNames.put(aliases[n], name);
+ }
+ }
+ }
+ }
+
+ // Map the virtual host names to the hosts
+ HashSet hosts = new HashSet();
+ while (vhostNames.hasNext())
+ {
+ String vhost = (String)vhostNames.next();
+ String host = (String)vhostToHostNames.get(vhost);
+ if (host == null)
+ {
+ log.warn("Failed to map vhost: " + vhost);
+ // This will cause a new host to be created
+ host = vhost;
+ }
+ hosts.add(host);
+ }
+ return hosts.iterator();
+ }
+
+ private String findConfig(URL warURL) throws IOException
+ {
+ String result = null;
+ // See if the warUrl is a dir or a file
+ File warFile = new File(warURL.getFile());
+ if (warURL.getProtocol().equals("file") && warFile.isDirectory() == true)
+ {
+ File webDD = new File(warFile, CONTEXT_CONFIG_FILE);
+ if (webDD.exists() == true)
+ result = webDD.getAbsolutePath();
+ } else
+ {
+ ZipFile zipFile = new ZipFile(warFile);
+ ZipEntry entry = zipFile.getEntry(CONTEXT_CONFIG_FILE);
+ if (entry != null)
+ {
+ InputStream zipIS = zipFile.getInputStream(entry);
+ byte[] buffer = new byte[512];
+ int bytes;
+ result = warFile.getAbsolutePath() + "-context.xml";
+ FileOutputStream fos = new FileOutputStream(result);
+ while ((bytes = zipIS.read(buffer)) > 0)
+ {
+ fos.write(buffer, 0, bytes);
+ }
+ zipIS.close();
+ fos.close();
+ }
+ zipFile.close();
+ }
+ return result;
+ }
+
+}
Property changes on: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/TomcatDeployment2.java
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/VFSDirContext.java
===================================================================
--- trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/VFSDirContext.java 2006-11-26 01:28:14 UTC (rev 58677)
+++ trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/VFSDirContext.java 2006-11-27 01:40:09 UTC (rev 58678)
@@ -0,0 +1,957 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.jboss.web.tomcat.tc6.deployers;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+import javax.naming.CompositeName;
+import javax.naming.Name;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchControls;
+
+import org.apache.naming.NamingContextBindingsEnumeration;
+import org.apache.naming.NamingContextEnumeration;
+import org.apache.naming.NamingEntry;
+import org.apache.naming.resources.BaseDirContext;
+import org.apache.naming.resources.Resource;
+import org.apache.naming.resources.ResourceAttributes;
+import org.jboss.logging.Logger;
+
+/**
+ * VFS Directory Context implementation.
+ *
+ * @author Remy Maucherat
+ * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
+ */
+
+public class VFSDirContext extends BaseDirContext {
+
+ private static final Logger log = Logger.getLogger(VFSDirContext.class);
+
+ // ----------------------------------------------------------- Constructors
+
+
+ /**
+ * Builds a WAR directory context using the given environment.
+ */
+ public VFSDirContext() {
+ super();
+ }
+
+
+ /**
+ * Builds a WAR directory context using the given environment.
+ */
+ public VFSDirContext(Hashtable env) {
+ super(env);
+ }
+
+
+ /**
+ * Constructor used for returning fake subcontexts.
+ */
+ protected VFSDirContext(ZipFile base, Entry entries) {
+ this.base = base;
+ this.entries = entries;
+ }
+
+
+ // ----------------------------------------------------- Instance Variables
+
+
+ /**
+ * The WAR file.
+ */
+ protected ZipFile base = null;
+
+
+ /**
+ * WAR entries.
+ */
+ protected Entry entries = null;
+
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * Set the document root.
+ *
+ * @param docBase The new document root
+ *
+ * @exception IllegalArgumentException if the specified value is not
+ * supported by this implementation
+ * @exception IllegalArgumentException if this would create a
+ * malformed URL
+ */
+ public void setDocBase(String docBase) {
+
+ // Validate the format of the proposed document root
+ if (docBase == null)
+ throw new IllegalArgumentException
+ (sm.getString("resources.null"));
+ if (!(docBase.endsWith(".war")))
+ throw new IllegalArgumentException
+ (sm.getString("warResources.notWar"));
+
+ // Calculate a File object referencing this document base directory
+ File base = new File(docBase);
+
+ // Validate that the document base is an existing directory
+ if (!base.exists() || !base.canRead() || base.isDirectory())
+ throw new IllegalArgumentException
+ (sm.getString("warResources.invalidWar", docBase));
+ try {
+ this.base = new ZipFile(base);
+ } catch (Exception e) {
+ throw new IllegalArgumentException
+ (sm.getString("warResources.invalidWar", e.getMessage()));
+ }
+ super.setDocBase(docBase);
+
+ loadEntries();
+
+ }
+
+
+ // --------------------------------------------------------- Public Methods
+
+
+ /**
+ * Release any resources allocated for this directory context.
+ */
+ public void release() {
+
+ entries = null;
+ if (base != null) {
+ try {
+ base.close();
+ } catch (IOException e) {
+ log.warn
+ ("Exception closing WAR File " + base.getName(), e);
+ }
+ }
+ base = null;
+ super.release();
+
+ }
+
+
+ // -------------------------------------------------------- Context Methods
+
+
+ /**
+ * Retrieves the named object.
+ *
+ * @param name the name of the object to look up
+ * @return the object bound to name
+ * @exception NamingException if a naming exception is encountered
+ */
+ public Object lookup(String name)
+ throws NamingException {
+ return lookup(new CompositeName(name));
+ }
+
+
+ /**
+ * Retrieves the named object. If name is empty, returns a new instance
+ * of this context (which represents the same naming context as this
+ * context, but its environment may be modified independently and it may
+ * be accessed concurrently).
+ *
+ * @param name the name of the object to look up
+ * @return the object bound to name
+ * @exception NamingException if a naming exception is encountered
+ */
+ public Object lookup(Name name)
+ throws NamingException {
+ if (name.isEmpty())
+ return this;
+ Entry entry = treeLookup(name);
+ if (entry == null)
+ throw new NamingException
+ (sm.getString("resources.notFound", name));
+ ZipEntry zipEntry = entry.getEntry();
+ if (zipEntry.isDirectory())
+ return new VFSDirContext(base, entry);
+ else
+ return new WARResource(entry.getEntry());
+ }
+
+
+ /**
+ * Unbinds the named object. Removes the terminal atomic name in name
+ * from the target context--that named by all but the terminal atomic
+ * part of name.
+ * <p>
+ * This method is idempotent. It succeeds even if the terminal atomic
+ * name is not bound in the target context, but throws
+ * NameNotFoundException if any of the intermediate contexts do not exist.
+ *
+ * @param name the name to bind; may not be empty
+ * @exception NameNotFoundException if an intermediate context does not
+ * exist
+ * @exception NamingException if a naming exception is encountered
+ */
+ public void unbind(String name)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Binds a new name to the object bound to an old name, and unbinds the
+ * old name. Both names are relative to this context. Any attributes
+ * associated with the old name become associated with the new name.
+ * Intermediate contexts of the old name are not changed.
+ *
+ * @param oldName the name of the existing binding; may not be empty
+ * @param newName the name of the new binding; may not be empty
+ * @exception NameAlreadyBoundException if newName is already bound
+ * @exception NamingException if a naming exception is encountered
+ */
+ public void rename(String oldName, String newName)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Enumerates the names bound in the named context, along with the class
+ * names of objects bound to them. The contents of any subcontexts are
+ * not included.
+ * <p>
+ * If a binding is added to or removed from this context, its effect on
+ * an enumeration previously returned is undefined.
+ *
+ * @param name the name of the context to list
+ * @return an enumeration of the names and class names of the bindings in
+ * this context. Each element of the enumeration is of type NameClassPair.
+ * @exception NamingException if a naming exception is encountered
+ */
+ public NamingEnumeration list(String name)
+ throws NamingException {
+ return list(new CompositeName(name));
+ }
+
+
+ /**
+ * Enumerates the names bound in the named context, along with the class
+ * names of objects bound to them. The contents of any subcontexts are
+ * not included.
+ * <p>
+ * If a binding is added to or removed from this context, its effect on
+ * an enumeration previously returned is undefined.
+ *
+ * @param name the name of the context to list
+ * @return an enumeration of the names and class names of the bindings in
+ * this context. Each element of the enumeration is of type NameClassPair.
+ * @exception NamingException if a naming exception is encountered
+ */
+ public NamingEnumeration list(Name name)
+ throws NamingException {
+ if (name.isEmpty())
+ return new NamingContextEnumeration(list(entries).iterator());
+ Entry entry = treeLookup(name);
+ if (entry == null)
+ throw new NamingException
+ (sm.getString("resources.notFound", name));
+ return new NamingContextEnumeration(list(entry).iterator());
+ }
+
+
+ /**
+ * Enumerates the names bound in the named context, along with the
+ * objects bound to them. The contents of any subcontexts are not
+ * included.
+ * <p>
+ * If a binding is added to or removed from this context, its effect on
+ * an enumeration previously returned is undefined.
+ *
+ * @param name the name of the context to list
+ * @return an enumeration of the bindings in this context.
+ * Each element of the enumeration is of type Binding.
+ * @exception NamingException if a naming exception is encountered
+ */
+ public NamingEnumeration listBindings(String name)
+ throws NamingException {
+ return listBindings(new CompositeName(name));
+ }
+
+
+ /**
+ * Enumerates the names bound in the named context, along with the
+ * objects bound to them. The contents of any subcontexts are not
+ * included.
+ * <p>
+ * If a binding is added to or removed from this context, its effect on
+ * an enumeration previously returned is undefined.
+ *
+ * @param name the name of the context to list
+ * @return an enumeration of the bindings in this context.
+ * Each element of the enumeration is of type Binding.
+ * @exception NamingException if a naming exception is encountered
+ */
+ public NamingEnumeration listBindings(Name name)
+ throws NamingException {
+ if (name.isEmpty())
+ return new NamingContextBindingsEnumeration(list(entries).iterator(),
+ this);
+ Entry entry = treeLookup(name);
+ if (entry == null)
+ throw new NamingException
+ (sm.getString("resources.notFound", name));
+ return new NamingContextBindingsEnumeration(list(entry).iterator(),
+ this);
+ }
+
+
+ /**
+ * Destroys the named context and removes it from the namespace. Any
+ * attributes associated with the name are also removed. Intermediate
+ * contexts are not destroyed.
+ * <p>
+ * This method is idempotent. It succeeds even if the terminal atomic
+ * name is not bound in the target context, but throws
+ * NameNotFoundException if any of the intermediate contexts do not exist.
+ *
+ * In a federated naming system, a context from one naming system may be
+ * bound to a name in another. One can subsequently look up and perform
+ * operations on the foreign context using a composite name. However, an
+ * attempt destroy the context using this composite name will fail with
+ * NotContextException, because the foreign context is not a "subcontext"
+ * of the context in which it is bound. Instead, use unbind() to remove
+ * the binding of the foreign context. Destroying the foreign context
+ * requires that the destroySubcontext() be performed on a context from
+ * the foreign context's "native" naming system.
+ *
+ * @param name the name of the context to be destroyed; may not be empty
+ * @exception NameNotFoundException if an intermediate context does not
+ * exist
+ * @exception NotContextException if the name is bound but does not name
+ * a context, or does not name a context of the appropriate type
+ */
+ public void destroySubcontext(String name)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Retrieves the named object, following links except for the terminal
+ * atomic component of the name. If the object bound to name is not a
+ * link, returns the object itself.
+ *
+ * @param name the name of the object to look up
+ * @return the object bound to name, not following the terminal link
+ * (if any).
+ * @exception NamingException if a naming exception is encountered
+ */
+ public Object lookupLink(String name)
+ throws NamingException {
+ // Note : Links are not supported
+ return lookup(name);
+ }
+
+
+ /**
+ * Retrieves the full name of this context within its own namespace.
+ * <p>
+ * Many naming services have a notion of a "full name" for objects in
+ * their respective namespaces. For example, an LDAP entry has a
+ * distinguished name, and a DNS record has a fully qualified name. This
+ * method allows the client application to retrieve this name. The string
+ * returned by this method is not a JNDI composite name and should not be
+ * passed directly to context methods. In naming systems for which the
+ * notion of full name does not make sense,
+ * OperationNotSupportedException is thrown.
+ *
+ * @return this context's name in its own namespace; never null
+ * @exception OperationNotSupportedException if the naming system does
+ * not have the notion of a full name
+ * @exception NamingException if a naming exception is encountered
+ */
+ public String getNameInNamespace()
+ throws NamingException {
+ return docBase;
+ }
+
+
+ // ----------------------------------------------------- DirContext Methods
+
+
+ /**
+ * Retrieves selected attributes associated with a named object.
+ * See the class description regarding attribute models, attribute type
+ * names, and operational attributes.
+ *
+ * @return the requested attributes; never null
+ * @param name the name of the object from which to retrieve attributes
+ * @param attrIds the identifiers of the attributes to retrieve. null
+ * indicates that all attributes should be retrieved; an empty array
+ * indicates that none should be retrieved
+ * @exception NamingException if a naming exception is encountered
+ */
+ public Attributes getAttributes(String name, String[] attrIds)
+ throws NamingException {
+ return getAttributes(new CompositeName(name), attrIds);
+ }
+
+
+ /**
+ * Retrieves all of the attributes associated with a named object.
+ *
+ * @return the set of attributes associated with name.
+ * Returns an empty attribute set if name has no attributes; never null.
+ * @param name the name of the object from which to retrieve attributes
+ * @exception NamingException if a naming exception is encountered
+ */
+ public Attributes getAttributes(Name name, String[] attrIds)
+ throws NamingException {
+
+ Entry entry = null;
+ if (name.isEmpty())
+ entry = entries;
+ else
+ entry = treeLookup(name);
+ if (entry == null)
+ throw new NamingException
+ (sm.getString("resources.notFound", name));
+
+ ZipEntry zipEntry = entry.getEntry();
+
+ ResourceAttributes attrs = new ResourceAttributes();
+ attrs.setCreationDate(new Date(zipEntry.getTime()));
+ attrs.setName(entry.getName());
+ if (!zipEntry.isDirectory())
+ attrs.setResourceType("");
+ attrs.setContentLength(zipEntry.getSize());
+ attrs.setLastModified(zipEntry.getTime());
+
+ return attrs;
+
+ }
+
+
+ /**
+ * Modifies the attributes associated with a named object. The order of
+ * the modifications is not specified. Where possible, the modifications
+ * are performed atomically.
+ *
+ * @param name the name of the object whose attributes will be updated
+ * @param mod_op the modification operation, one of: ADD_ATTRIBUTE,
+ * REPLACE_ATTRIBUTE, REMOVE_ATTRIBUTE
+ * @param attrs the attributes to be used for the modification; may not
+ * be null
+ * @exception AttributeModificationException if the modification cannot be
+ * completed successfully
+ * @exception NamingException if a naming exception is encountered
+ */
+ public void modifyAttributes(String name, int mod_op, Attributes attrs)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Modifies the attributes associated with a named object using an an
+ * ordered list of modifications. The modifications are performed in the
+ * order specified. Each modification specifies a modification operation
+ * code and an attribute on which to operate. Where possible, the
+ * modifications are performed atomically.
+ *
+ * @param name the name of the object whose attributes will be updated
+ * @param mods an ordered sequence of modifications to be performed; may
+ * not be null
+ * @exception AttributeModificationException if the modification cannot be
+ * completed successfully
+ * @exception NamingException if a naming exception is encountered
+ */
+ public void modifyAttributes(String name, ModificationItem[] mods)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Binds a name to an object, along with associated attributes. If attrs
+ * is null, the resulting binding will have the attributes associated
+ * with obj if obj is a DirContext, and no attributes otherwise. If attrs
+ * is non-null, the resulting binding will have attrs as its attributes;
+ * any attributes associated with obj are ignored.
+ *
+ * @param name the name to bind; may not be empty
+ * @param obj the object to bind; possibly null
+ * @param attrs the attributes to associate with the binding
+ * @exception NameAlreadyBoundException if name is already bound
+ * @exception InvalidAttributesException if some "mandatory" attributes
+ * of the binding are not supplied
+ * @exception NamingException if a naming exception is encountered
+ */
+ public void bind(String name, Object obj, Attributes attrs)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Binds a name to an object, along with associated attributes,
+ * overwriting any existing binding. If attrs is null and obj is a
+ * DirContext, the attributes from obj are used. If attrs is null and obj
+ * is not a DirContext, any existing attributes associated with the object
+ * already bound in the directory remain unchanged. If attrs is non-null,
+ * any existing attributes associated with the object already bound in
+ * the directory are removed and attrs is associated with the named
+ * object. If obj is a DirContext and attrs is non-null, the attributes
+ * of obj are ignored.
+ *
+ * @param name the name to bind; may not be empty
+ * @param obj the object to bind; possibly null
+ * @param attrs the attributes to associate with the binding
+ * @exception InvalidAttributesException if some "mandatory" attributes
+ * of the binding are not supplied
+ * @exception NamingException if a naming exception is encountered
+ */
+ public void rebind(String name, Object obj, Attributes attrs)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Creates and binds a new context, along with associated attributes.
+ * This method creates a new subcontext with the given name, binds it in
+ * the target context (that named by all but terminal atomic component of
+ * the name), and associates the supplied attributes with the newly
+ * created object. All intermediate and target contexts must already
+ * exist. If attrs is null, this method is equivalent to
+ * Context.createSubcontext().
+ *
+ * @param name the name of the context to create; may not be empty
+ * @param attrs the attributes to associate with the newly created context
+ * @return the newly created context
+ * @exception NameAlreadyBoundException if the name is already bound
+ * @exception InvalidAttributesException if attrs does not contain all
+ * the mandatory attributes required for creation
+ * @exception NamingException if a naming exception is encountered
+ */
+ public DirContext createSubcontext(String name, Attributes attrs)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Retrieves the schema associated with the named object. The schema
+ * describes rules regarding the structure of the namespace and the
+ * attributes stored within it. The schema specifies what types of
+ * objects can be added to the directory and where they can be added;
+ * what mandatory and optional attributes an object can have. The range
+ * of support for schemas is directory-specific.
+ *
+ * @param name the name of the object whose schema is to be retrieved
+ * @return the schema associated with the context; never null
+ * @exception OperationNotSupportedException if schema not supported
+ * @exception NamingException if a naming exception is encountered
+ */
+ public DirContext getSchema(String name)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Retrieves a context containing the schema objects of the named
+ * object's class definitions.
+ *
+ * @param name the name of the object whose object class definition is to
+ * be retrieved
+ * @return the DirContext containing the named object's class
+ * definitions; never null
+ * @exception OperationNotSupportedException if schema not supported
+ * @exception NamingException if a naming exception is encountered
+ */
+ public DirContext getSchemaClassDefinition(String name)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Searches in a single context for objects that contain a specified set
+ * of attributes, and retrieves selected attributes. The search is
+ * performed using the default SearchControls settings.
+ *
+ * @param name the name of the context to search
+ * @param matchingAttributes the attributes to search for. If empty or
+ * null, all objects in the target context are returned.
+ * @param attributesToReturn the attributes to return. null indicates
+ * that all attributes are to be returned; an empty array indicates that
+ * none are to be returned.
+ * @return a non-null enumeration of SearchResult objects. Each
+ * SearchResult contains the attributes identified by attributesToReturn
+ * and the name of the corresponding object, named relative to the
+ * context named by name.
+ * @exception NamingException if a naming exception is encountered
+ */
+ public NamingEnumeration search(String name, Attributes matchingAttributes,
+ String[] attributesToReturn)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Searches in a single context for objects that contain a specified set
+ * of attributes. This method returns all the attributes of such objects.
+ * It is equivalent to supplying null as the atributesToReturn parameter
+ * to the method search(Name, Attributes, String[]).
+ *
+ * @param name the name of the context to search
+ * @param matchingAttributes the attributes to search for. If empty or
+ * null, all objects in the target context are returned.
+ * @return a non-null enumeration of SearchResult objects. Each
+ * SearchResult contains the attributes identified by attributesToReturn
+ * and the name of the corresponding object, named relative to the
+ * context named by name.
+ * @exception NamingException if a naming exception is encountered
+ */
+ public NamingEnumeration search(String name, Attributes matchingAttributes)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Searches in the named context or object for entries that satisfy the
+ * given search filter. Performs the search as specified by the search
+ * controls.
+ *
+ * @param name the name of the context or object to search
+ * @param filter the filter expression to use for the search; may not be
+ * null
+ * @param cons the search controls that control the search. If null,
+ * the default search controls are used (equivalent to
+ * (new SearchControls())).
+ * @return an enumeration of SearchResults of the objects that satisfy
+ * the filter; never null
+ * @exception InvalidSearchFilterException if the search filter specified
+ * is not supported or understood by the underlying directory
+ * @exception InvalidSearchControlsException if the search controls
+ * contain invalid settings
+ * @exception NamingException if a naming exception is encountered
+ */
+ public NamingEnumeration search(String name, String filter,
+ SearchControls cons)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ /**
+ * Searches in the named context or object for entries that satisfy the
+ * given search filter. Performs the search as specified by the search
+ * controls.
+ *
+ * @param name the name of the context or object to search
+ * @param filterExpr the filter expression to use for the search.
+ * The expression may contain variables of the form "{i}" where i is a
+ * nonnegative integer. May not be null.
+ * @param filterArgs the array of arguments to substitute for the
+ * variables in filterExpr. The value of filterArgs[i] will replace each
+ * occurrence of "{i}". If null, equivalent to an empty array.
+ * @param cons the search controls that control the search. If null, the
+ * default search controls are used (equivalent to (new SearchControls())).
+ * @return an enumeration of SearchResults of the objects that satisy the
+ * filter; never null
+ * @exception ArrayIndexOutOfBoundsException if filterExpr contains {i}
+ * expressions where i is outside the bounds of the array filterArgs
+ * @exception InvalidSearchControlsException if cons contains invalid
+ * settings
+ * @exception InvalidSearchFilterException if filterExpr with filterArgs
+ * represents an invalid search filter
+ * @exception NamingException if a naming exception is encountered
+ */
+ public NamingEnumeration search(String name, String filterExpr,
+ Object[] filterArgs, SearchControls cons)
+ throws NamingException {
+ throw new OperationNotSupportedException();
+ }
+
+
+ // ------------------------------------------------------ Protected Methods
+
+
+ /**
+ * Normalize the name of an entry read from the Zip.
+ */
+ protected String normalize(ZipEntry entry) {
+
+ String result = "/" + entry.getName();
+ if (entry.isDirectory()) {
+ result = result.substring(0, result.length() - 1);
+ }
+ return result;
+
+ }
+
+
+ /**
+ * Constructs a tree of the entries contained in a WAR file.
+ */
+ protected void loadEntries() {
+
+ try {
+
+ Enumeration entryList = base.entries();
+ entries = new Entry("/", new ZipEntry("/"));
+
+ while (entryList.hasMoreElements()) {
+
+ ZipEntry entry = (ZipEntry) entryList.nextElement();
+ String name = normalize(entry);
+ int pos = name.lastIndexOf('/');
+ // Check that parent entries exist and, if not, create them.
+ // This fixes a bug for war files that don't record separate
+ // zip entries for the directories.
+ int currentPos = -1;
+ int lastPos = 0;
+ while ((currentPos = name.indexOf('/', lastPos)) != -1) {
+ Name parentName = new CompositeName(name.substring(0, lastPos));
+ Name childName = new CompositeName(name.substring(0, currentPos));
+ String entryName = name.substring(lastPos, currentPos);
+ // Parent should have been created in last cycle through
+ // this loop
+ Entry parent = treeLookup(parentName);
+ Entry child = treeLookup(childName);
+ if (child == null) {
+ // Create a new entry for missing entry and strip off
+ // the leading '/' character and appended on by the
+ // normalize method and add '/' character to end to
+ // signify that it is a directory entry
+ String zipName = name.substring(1, currentPos) + "/";
+ child = new Entry(entryName, new ZipEntry(zipName));
+ if (parent != null)
+ parent.addChild(child);
+ }
+ // Increment lastPos
+ lastPos = currentPos + 1;
+ }
+ String entryName = name.substring(pos + 1, name.length());
+ Name compositeName = new CompositeName(name.substring(0, pos));
+ Entry parent = treeLookup(compositeName);
+ Entry child = new Entry(entryName, entry);
+ if (parent != null)
+ parent.addChild(child);
+
+ }
+
+ } catch (Exception e) {
+ }
+
+ }
+
+
+ /**
+ * Entry tree lookup.
+ */
+ protected Entry treeLookup(Name name) {
+ if (name.isEmpty())
+ return entries;
+ Entry currentEntry = entries;
+ for (int i = 0; i < name.size(); i++) {
+ if (name.get(i).length() == 0)
+ continue;
+ currentEntry = currentEntry.getChild(name.get(i));
+ if (currentEntry == null)
+ return null;
+ }
+ return currentEntry;
+ }
+
+
+ /**
+ * List children as objects.
+ */
+ protected ArrayList list(Entry entry) {
+
+ ArrayList entries = new ArrayList();
+ Entry[] children = entry.getChildren();
+ Arrays.sort(children);
+ NamingEntry namingEntry = null;
+
+ for (int i = 0; i < children.length; i++) {
+ ZipEntry current = children[i].getEntry();
+ Object object = null;
+ if (current.isDirectory()) {
+ object = new VFSDirContext(base, children[i]);
+ } else {
+ object = new WARResource(current);
+ }
+ namingEntry = new NamingEntry
+ (children[i].getName(), object, NamingEntry.ENTRY);
+ entries.add(namingEntry);
+ }
+
+ return entries;
+
+ }
+
+
+ // ---------------------------------------------------- Entries Inner Class
+
+
+ /**
+ * Entries structure.
+ */
+ protected class Entry implements Comparable {
+
+
+ // -------------------------------------------------------- Constructor
+
+
+ public Entry(String name, ZipEntry entry) {
+ this.name = name;
+ this.entry = entry;
+ }
+
+
+ // --------------------------------------------------- Member Variables
+
+
+ protected String name = null;
+
+
+ protected ZipEntry entry = null;
+
+
+ protected Entry children[] = new Entry[0];
+
+
+ // ----------------------------------------------------- Public Methods
+
+
+ public int compareTo(Object o) {
+ if (!(o instanceof Entry))
+ return (+1);
+ return (name.compareTo(((Entry) o).getName()));
+ }
+
+ public ZipEntry getEntry() {
+ return entry;
+ }
+
+
+ public String getName() {
+ return name;
+ }
+
+
+ public void addChild(Entry entry) {
+ Entry[] newChildren = new Entry[children.length + 1];
+ for (int i = 0; i < children.length; i++)
+ newChildren[i] = children[i];
+ newChildren[children.length] = entry;
+ children = newChildren;
+ }
+
+
+ public Entry[] getChildren() {
+ return children;
+ }
+
+
+ public Entry getChild(String name) {
+ for (int i = 0; i < children.length; i++) {
+ if (children[i].name.equals(name)) {
+ return children[i];
+ }
+ }
+ return null;
+ }
+
+
+ }
+
+
+ // ------------------------------------------------ WARResource Inner Class
+
+
+ /**
+ * This specialized resource implementation avoids opening the IputStream
+ * to the WAR right away.
+ */
+ protected class WARResource extends Resource {
+
+
+ // -------------------------------------------------------- Constructor
+
+
+ public WARResource(ZipEntry entry) {
+ this.entry = entry;
+ }
+
+
+ // --------------------------------------------------- Member Variables
+
+
+ protected ZipEntry entry;
+
+
+ // ----------------------------------------------------- Public Methods
+
+
+ /**
+ * Content accessor.
+ *
+ * @return InputStream
+ */
+ public InputStream streamContent()
+ throws IOException {
+ try {
+ if (binaryContent == null) {
+ inputStream = base.getInputStream(entry);
+ }
+ } catch (ZipException e) {
+ throw new IOException(e.getMessage());
+ }
+ return super.streamContent();
+ }
+
+
+ }
+
+
+}
+
Property changes on: trunk/tomcat/src/main/org/jboss/web/tomcat/tc6/deployers/VFSDirContext.java
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the jboss-cvs-commits
mailing list