[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