Index: deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentContextImpl.java =================================================================== --- deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentContextImpl.java (revision 50165) +++ deployment/common/src/main/java/org/glassfish/deployment/common/DeploymentContextImpl.java (working copy) @@ -195,14 +195,16 @@ public void createDeploymentClassLoader(ClassLoaderHierarchy clh, ArchiveHandler handler) throws URISyntaxException, MalformedURLException { this.addTransientAppMetaData(ExtendedDeploymentContext.IS_TEMP_CLASSLOADER, Boolean.TRUE); - this.sharableTemp = createClassLoader(clh, handler, null); + this.sharableTemp = createClassLoader(clh, handler, null); } // this classloader will used to load and start the application public void createApplicationClassLoader(ClassLoaderHierarchy clh, ArchiveHandler handler) throws URISyntaxException, MalformedURLException { this.addTransientAppMetaData(ExtendedDeploymentContext.IS_TEMP_CLASSLOADER, Boolean.FALSE); - this.cloader = createClassLoader(clh, handler, parameters.name()); + if (this.cloader == null) { + this.cloader = createClassLoader(clh, handler, parameters.name()); + } } private ClassLoader createClassLoader(ClassLoaderHierarchy clh, ArchiveHandler handler, String appName) Index: web/web-embed/impl/src/main/java/org/glassfish/web/embed/impl/WebContainerImpl.java =================================================================== --- web/web-embed/impl/src/main/java/org/glassfish/web/embed/impl/WebContainerImpl.java (revision 50165) +++ web/web-embed/impl/src/main/java/org/glassfish/web/embed/impl/WebContainerImpl.java (working copy) @@ -658,7 +658,14 @@ throw new ConfigException("Context with contextRoot "+ contextRoot+" is already registered"); } - vs.addContext(context, contextRoot); + + if (!org.glassfish.api.web.Constants.ADMIN_VS.equals(vs.getID())) { + vs.addContext(context, contextRoot); + if (log.isLoggable(Level.INFO)) { + log.info("Added context with path " + contextRoot + + " from virtual server " + vs.getID()); + } + } } } @@ -677,16 +684,17 @@ String contextRoot = context.getPath(); for (VirtualServer vs : getVirtualServers()) { - if (vs.getContext(contextRoot)!=null) { - vs.removeContext(context); - if (log.isLoggable(Level.INFO)) { - log.info("Removed context with path " + contextRoot + - " from virtual server " + vs.getID()); + if (!org.glassfish.api.web.Constants.ADMIN_VS.equals(vs.getID())) { + if (vs.getContext(contextRoot)!=null) { + vs.removeContext(context); + if (log.isLoggable(Level.INFO)) { + log.info("Removed context with path " + contextRoot + + " from virtual server " + vs.getID()); + } + } else { + throw new GlassFishException("Context with context path " + + context.getPath() + " does not exist on virtual server " + vs.getID()); } - } else { - throw new GlassFishException(new ConfigException( - "Context with context path " + context.getContextPath() + - " does not exist on virtual server " + vs.getID())); } } Index: web/web-core/src/main/java/org/apache/catalina/core/DynamicFilterRegistrationImpl.java =================================================================== --- web/web-core/src/main/java/org/apache/catalina/core/DynamicFilterRegistrationImpl.java (revision 50165) +++ web/web-core/src/main/java/org/apache/catalina/core/DynamicFilterRegistrationImpl.java (working copy) @@ -51,7 +51,7 @@ /** * Constructor */ - DynamicFilterRegistrationImpl(FilterDef filterDef, + public DynamicFilterRegistrationImpl(FilterDef filterDef, StandardContext ctx) { super(filterDef, ctx); } Index: web/web-core/src/main/java/org/apache/catalina/core/StandardContext.java =================================================================== --- web/web-core/src/main/java/org/apache/catalina/core/StandardContext.java (revision 50165) +++ web/web-core/src/main/java/org/apache/catalina/core/StandardContext.java (working copy) @@ -710,7 +710,7 @@ protected ConcurrentHashMap servletRegisMap = new ConcurrentHashMap(); - private ConcurrentHashMap filterRegisMap = + protected ConcurrentHashMap filterRegisMap = new ConcurrentHashMap(); /** Index: web/web-glue/src/main/java/com/sun/enterprise/web/ContextFacade.java =================================================================== --- web/web-glue/src/main/java/com/sun/enterprise/web/ContextFacade.java (revision 50165) +++ web/web-glue/src/main/java/com/sun/enterprise/web/ContextFacade.java (working copy) @@ -43,19 +43,16 @@ import java.io.*; import java.net.*; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; import javax.servlet.*; import javax.servlet.descriptor.JspConfigDescriptor; -import com.sun.enterprise.deployment.*; -import com.sun.enterprise.deployment.web.LoginConfiguration; -import com.sun.enterprise.deployment.web.UserDataConstraint; -import com.sun.enterprise.web.deploy.LoginConfigDecorator; +import javax.servlet.http.HttpSessionAttributeListener; +import javax.servlet.http.HttpSessionListener; + import org.apache.catalina.core.*; +import org.apache.catalina.deploy.FilterDef; +import org.apache.catalina.deploy.FilterMap; import org.glassfish.embeddable.web.Context; -import org.glassfish.embeddable.web.config.FormLoginConfig; -import org.glassfish.embeddable.web.config.LoginConfig; import org.glassfish.embeddable.web.config.SecurityConfig; -import org.glassfish.embeddable.web.config.TransportGuarantee; /** * Facade object which masks the internal Context @@ -82,6 +79,14 @@ this.classLoader = classLoader; } + /** + * The name of the deployed application + */ + + private String appName = null; + + private transient SecurityConfig config = null; + /** * Wrapped web module. */ @@ -91,134 +96,176 @@ private String contextRoot; - private ClassLoader classLoader; + private transient ClassLoader classLoader; + private Map filters = new HashMap(); + + private Map servletNameFilterMappings = new HashMap(); + + private Map urlPatternFilterMappings = new HashMap(); + private Map servlets = new HashMap(); private Map servletMappings = new HashMap(); - protected Map wrappers = new HashMap(); + protected ArrayList listenerNames = new ArrayList(); // ------------------------------------------------------------- Properties + public String getAppName() { + return appName ; + } + + public void setAppName(String name) { + appName = name; + } public File getDocRoot() { return docRoot; } + @Override public String getContextRoot() { return contextRoot; } // ------------------------------------------------- ServletContext Methods - + @Override public String getContextPath() { return context.getContextPath(); } + @Override public ServletContext getContext(String uripath) { return context.getContext(uripath); } + @Override public int getMajorVersion() { return context.getMajorVersion(); } + @Override public int getMinorVersion() { return context.getMinorVersion(); } + @Override public int getEffectiveMajorVersion() { return context.getEffectiveMajorVersion(); } + @Override public int getEffectiveMinorVersion() { return context.getEffectiveMinorVersion(); } + @Override public String getMimeType(String file) { return context.getMimeType(file); } + @Override public Set getResourcePaths(String path) { return context.getResourcePaths(path); } + @Override public URL getResource(String path) throws MalformedURLException { return context.getResource(path); } + @Override public InputStream getResourceAsStream(String path) { return context.getResourceAsStream(path); } + @Override public RequestDispatcher getRequestDispatcher(final String path) { return context.getRequestDispatcher(path); } + @Override public RequestDispatcher getNamedDispatcher(String name) { return context.getNamedDispatcher(name); } + @Override public Servlet getServlet(String name) { return context.getServlet(name); } + @Override public Enumeration getServlets() { return context.getServlets(); } + @Override public Enumeration getServletNames() { return context.getServletNames(); - } + } + + @Override public void log(String msg) { context.log(msg); } + @Override public void log(Exception exception, String msg) { context.log(exception, msg); } + @Override public void log(String message, Throwable throwable) { context.log(message, throwable); } + @Override public String getRealPath(String path) { return context.getRealPath(path); } + @Override public String getServerInfo() { return context.getServerInfo(); } + @Override public String getInitParameter(String name) { return context.getInitParameter(name); } + @Override public Enumeration getInitParameterNames() { return context.getInitParameterNames(); } + @Override public boolean setInitParameter(String name, String value) { return context.setInitParameter(name, value); } + @Override public Object getAttribute(String name) { return context.getAttribute(name); - } + } + @Override public Enumeration getAttributeNames() { return context.getAttributeNames(); } + @Override public void setAttribute(String name, Object object) { context.setAttribute(name, object); } + @Override public void removeAttribute(String name) { context.removeAttribute(name); } + @Override public String getServletContextName() { return context.getServletContextName(); } @@ -236,7 +283,7 @@ if (context != null) { return context.addServlet(servletName, className); } else { - return addServletBefore(servletName, className); + return addServletFacade(servletName, className); } } @@ -249,7 +296,7 @@ } }*/ - public ServletRegistration.Dynamic addServletBefore(String servletName, + public ServletRegistration.Dynamic addServletFacade(String servletName, String className) { if (servletName == null || className == null) { throw new NullPointerException("Null servlet instance or name"); @@ -268,7 +315,6 @@ servletRegisMap.put(servletName, regis); servlets.put(servletName, className); - wrappers.put(servletName, wrapper); } return regis; @@ -292,7 +338,7 @@ if (context != null) { return context.addServlet(servletName, servletClass); } else { - return null; + return addServletFacade(servletName, servletClass.getName()); } } @@ -301,7 +347,7 @@ if (context != null) { return context.addServlet(servletName, servlet); } else { - return null; + return addServletFacade(servletName, servlet.getClass().getName()); } } @@ -309,44 +355,117 @@ public Set addServletMapping(String name, String[] urlPatterns) { servletMappings.put(name, urlPatterns); - return Collections.emptySet(); + return servletMappings.keySet(); } public T createServlet(Class clazz) throws ServletException { - return context.createServlet(clazz); + if (context != null) { + return context.createServlet(clazz); + } else { + try { + return createServletInstance(clazz); + } catch (Throwable t) { + throw new ServletException("Unable to create Servlet from " + + "class " + clazz.getName(), t); + } + } } public ServletRegistration getServletRegistration(String servletName) { - return context.getServletRegistration(servletName); + return servletRegisMap.get(servletName); } public Map getServletRegistrations() { return context.getServletRegistrations(); } + public Map getAddedFilters() { + return filters; + } + + public Map getServletNameFilterMappings() { + return servletNameFilterMappings; + } + + public Map getUrlPatternFilterMappings() { + return urlPatternFilterMappings; + } + + public FilterRegistration.Dynamic addFilterFacade( + String filterName, String className) { + DynamicFilterRegistrationImpl regis = + (DynamicFilterRegistrationImpl) filterRegisMap.get( + filterName); + FilterDef filterDef = null; + if (null == regis) { + filterDef = new FilterDef(); + } else { + filterDef = regis.getFilterDefinition(); + } + filterDef.setFilterName(filterName); + filterDef.setFilterClassName(className); + + regis = new DynamicFilterRegistrationImpl(filterDef, this); + filterRegisMap.put(filterDef.getFilterName(), regis); + filters.put(filterName, className); + + return regis; + } + + @Override public FilterRegistration.Dynamic addFilter( String filterName, String className) { - return context.addFilter(filterName, className); + if (context != null) { + return context.addFilter(filterName, className); + } else { + return addFilterFacade(filterName, className); + } } + @Override + public void addFilterMap(FilterMap filterMap, boolean isMatchAfter) { + if (filterMap.getServletName() != null) { + servletNameFilterMappings.put(filterMap.getFilterName(), filterMap.getServletName()); + } else if (filterMap.getURLPattern() != null) { + urlPatternFilterMappings.put(filterMap.getFilterName(), filterMap.getURLPattern()); + } + } + public FilterRegistration.Dynamic addFilter( String filterName, Filter filter) { - return context.addFilter(filterName, filter); + if (context != null) { + return context.addFilter(filterName, filter); + } else { + return addFilterFacade(filterName, filter.getClass().getName()); + } } public FilterRegistration.Dynamic addFilter(String filterName, Class filterClass) { - return context.addFilter(filterName, filterClass); + if (context != null) { + return context.addFilter(filterName, filterClass); + } else { + return addFilterFacade(filterName, filterClass.getName()); + } } public T createFilter(Class clazz) throws ServletException { - return context.createFilter(clazz); + if (context != null) { + return context.createFilter(clazz); + } else { + try { + return createFilterInstance(clazz); + } catch (Throwable t) { + throw new ServletException("Unable to create Filter from " + + "class " + clazz.getName(), t); + } + } } public FilterRegistration getFilterRegistration(String filterName) { - return context.getFilterRegistration(filterName); + return filterRegisMap.get(filterName); } public Map getFilterRegistrations() { @@ -370,20 +489,53 @@ } public void addListener(String className) { - context.addListener(className); + if (context != null) { + context.addListener(className); + } else { + listenerNames.add(className); + } } + public List getListeners() { + return listenerNames; + } + public void addListener(T t) { - context.addListener(t); + if (context != null) { + context.addListener(t); + } else { + listenerNames.add(t.getClass().getName()); + } } public void addListener(Class listenerClass) { - context.addListener(listenerClass); + if (context != null) { + context.addListener(listenerClass); + } else { + listenerNames.add(listenerClass.getName()); + } } public T createListener(Class clazz) throws ServletException { - return context.createListener(clazz); + if (context != null) { + return context.createListener(clazz); + } else { + if (!ServletContextListener.class.isAssignableFrom(clazz) && + !ServletContextAttributeListener.class.isAssignableFrom(clazz) && + !ServletRequestListener.class.isAssignableFrom(clazz) && + !ServletRequestAttributeListener.class.isAssignableFrom(clazz) && + !HttpSessionListener.class.isAssignableFrom(clazz) && + !HttpSessionAttributeListener.class.isAssignableFrom(clazz)) { + throw new IllegalArgumentException(sm.getString( + "standardContext.invalidListenerType", clazz.getName())); + } + try { + return createListenerInstance(clazz); + } catch (Throwable t) { + throw new ServletException(t); + } + } } public JspConfigDescriptor getJspConfigDescriptor() { @@ -401,7 +553,7 @@ } public void declareRoles(String... roleNames) { - // TBD + context.declareRoles(roleNames); } public String getPath() { @@ -436,8 +588,6 @@ // --------------------------------------------------------- embedded Methods - private SecurityConfig config; - /** * Enables or disables directory listings on this Context. */ Index: web/web-glue/src/main/java/com/sun/enterprise/web/VirtualServer.java =================================================================== --- web/web-glue/src/main/java/com/sun/enterprise/web/VirtualServer.java (revision 50165) +++ web/web-glue/src/main/java/com/sun/enterprise/web/VirtualServer.java (working copy) @@ -40,21 +40,17 @@ package com.sun.enterprise.web; -import com.sun.enterprise.config.serverbeans.ApplicationRef; -import com.sun.enterprise.config.serverbeans.Applications; -import com.sun.enterprise.config.serverbeans.AuthRealm; -import com.sun.enterprise.config.serverbeans.Config; -import com.sun.enterprise.config.serverbeans.ConfigBeansUtilities; -import com.sun.enterprise.config.serverbeans.Domain; -import com.sun.enterprise.config.serverbeans.HttpService; -import com.sun.enterprise.config.serverbeans.SecurityService; +import com.sun.enterprise.config.serverbeans.*; +import com.sun.enterprise.config.serverbeans.Node; import com.sun.enterprise.config.serverbeans.Server; +import com.sun.enterprise.deploy.shared.ArchiveFactory; import com.sun.enterprise.deployment.Application; import com.sun.enterprise.deployment.WebBundleDescriptor; import com.sun.enterprise.deployment.archivist.WebArchivist; import com.sun.enterprise.security.web.GlassFishSingleSignOn; import com.sun.enterprise.server.logging.GFFileHandler; import com.sun.enterprise.util.StringUtils; +import com.sun.enterprise.v3.common.PlainTextActionReporter; import com.sun.enterprise.v3.services.impl.GrizzlyListener; import com.sun.enterprise.v3.services.impl.GrizzlyProxy; import com.sun.enterprise.v3.services.impl.GrizzlyService; @@ -79,7 +75,15 @@ import org.apache.catalina.valves.RemoteAddrValve; import org.apache.catalina.valves.RemoteHostValve; +import org.glassfish.api.ActionReport; import org.glassfish.api.admin.ServerEnvironment; +import org.glassfish.api.deployment.DeployCommandParameters; +import org.glassfish.api.deployment.OpsParams; +import org.glassfish.api.deployment.UndeployCommandParameters; +import org.glassfish.api.deployment.archive.ArchiveHandler; +import org.glassfish.api.deployment.archive.ReadableArchive; +import org.glassfish.deployment.common.ApplicationConfigInfo; +import org.glassfish.deployment.common.DeploymentContextImpl; import org.glassfish.deployment.versioning.VersioningUtils; import org.glassfish.embeddable.*; import org.glassfish.embeddable.Deployer; @@ -88,14 +92,19 @@ import org.glassfish.embeddable.web.WebListener; import org.glassfish.embeddable.web.config.VirtualServerConfig; import org.glassfish.deployment.common.DeploymentUtils; +import org.glassfish.internal.api.ClassLoaderHierarchy; import org.glassfish.internal.api.ServerContext; import org.glassfish.internal.api.Globals; import org.glassfish.internal.data.ApplicationInfo; import org.glassfish.internal.data.ApplicationRegistry; +import org.glassfish.internal.deployment.Deployment; +import org.glassfish.internal.deployment.ExtendedDeploymentContext; import org.glassfish.web.loader.WebappClassLoader; import org.glassfish.web.valve.GlassFishValve; import org.jvnet.hk2.component.Habitat; +import org.jvnet.hk2.config.Transaction; +import org.jvnet.hk2.config.TransactionFailure; import org.jvnet.hk2.config.types.Property; import java.io.File; @@ -117,8 +126,7 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import org.w3c.dom.Document; -import org.w3c.dom.Element; +import org.w3c.dom.*; /** @@ -217,8 +225,12 @@ private String[] cacheControls; + private ClassLoaderHierarchy clh; + private Domain domain; + private Habitat habitat; + private ServerEnvironment instance; // Is this virtual server active? @@ -388,10 +400,18 @@ this.instance = instance; } + public void setClassLoaderHierarchy(ClassLoaderHierarchy clh) { + this.clh = clh; + } + public void setDomain(Domain domain) { this.domain = domain; } + public void setHabitat(Habitat habitat) { + this.habitat = habitat; + } + @Override public Container findChild(String contextRoot) { if (defaultContextPath != null && "/".equals(contextRoot)) { @@ -1993,6 +2013,10 @@ return listeners; } + private ArchiveFactory factory = null; + private ActionReport report = null; + private Deployment deployment = null; + /** * Registers the given Context with this VirtualServer * at the given context root. @@ -2004,88 +2028,238 @@ throws ConfigException, GlassFishException { if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "Virtual server "+getName()+" added context "+contextRoot); + _logger.log(Level.FINE, "Virtual server "+getName()+" adding context "+contextRoot); } - if (getContext(contextRoot)!=null) { - throw new ConfigException("Context with contextRoot "+ - contextRoot+" is already registered"); + if (!(context instanceof ContextFacade)) { + // embedded context should always be created via ContextFacade + return; } + if (!contextRoot.equals("/")) { + contextRoot = "/"+contextRoot; + } + ExtendedDeploymentContext deploymentContext = null; + try { + if (factory==null) + factory = habitat.getComponent(ArchiveFactory.class); + ContextFacade facade = (ContextFacade) context; File docRoot = facade.getDocRoot(); ClassLoader classLoader = facade.getClassLoader(); + ReadableArchive archive = factory.openArchive(docRoot); - Deployer deployer = Globals.getDefaultHabitat().getComponent(Deployer.class); - String appName = deployer.deploy(docRoot, "--name", contextRoot); - //String appName = deployer.deploy(docRoot, "--name", contextRoot, "--enabled", "false"); - String contextName = "/"+appName; + if (report==null) + report = new PlainTextActionReporter(); - Map servlets = facade.getAddedServlets(); - Map mappings = facade.getServletMappings(); - File webXml = null; + ServerEnvironment env = habitat.getComponent(ServerEnvironment.class); - if (!servlets.isEmpty()) { - Applications apps = domain.getApplications(); - com.sun.enterprise.config.serverbeans.Application app = apps.getApplication(contextRoot); - if (app != null) { - webXml = new File(app.application().getAbsolutePath(), "/WEB-INF/web.xml"); + DeployCommandParameters params = new DeployCommandParameters(); + params.contextroot = contextRoot; + params.enabled = Boolean.FALSE; + params.origin = OpsParams.Origin.deploy; + params.virtualservers = getName(); + + ExtendedDeploymentContext initialContext = + new DeploymentContextImpl(report, _logger, archive, params, env); + + if (deployment==null) + deployment = habitat.getComponent(Deployment.class); + + ArchiveHandler archiveHandler = deployment.getArchiveHandler(archive); + if (archiveHandler==null) { + throw new RuntimeException("Cannot find archive handler for source archive"); + } + + params.name = archiveHandler.getDefaultApplicationName(archive, initialContext); + + Applications apps = domain.getApplications(); + ApplicationInfo appInfo = deployment.get(params.name); + ApplicationRef appRef = domain.getApplicationRefInServer(params.target, params.name); + + if (appInfo != null) { + if (appRef!=null && appRef.getVirtualServers().contains(getName())) { + throw new ConfigException( + "Context with name "+params.name+" is already registered on virtual server "+getName()); + } else { + String virtualServers = appRef.getVirtualServers(); + virtualServers = virtualServers + ","+getName(); + params.virtualservers = virtualServers; + params.force = Boolean.TRUE; + if (_logger.isLoggable(Level.FINE)) { + _logger.log(Level.FINE, "Virtual server "+getName()+" added to context "+params.name); + } + return; } + } + + deploymentContext = deployment.getBuilder( + _logger, params, report).source(archive).archiveHandler( + archiveHandler).build(initialContext); + + Properties properties = new Properties(); + deploymentContext.getAppProps().putAll(properties); + + if (classLoader != null) { + ClassLoader parentCL = clh.createApplicationParentCL(classLoader, deploymentContext); + ClassLoader cl = archiveHandler.getClassLoader(parentCL, deploymentContext); + deploymentContext.setClassLoader(cl); + } + + ApplicationConfigInfo savedAppConfig = + new ApplicationConfigInfo(apps.getModule(com.sun.enterprise.config.serverbeans.Application.class, params.name)); + + Properties appProps = deploymentContext.getAppProps(); + String appLocation = DeploymentUtils.relativizeWithinDomainIfPossible(deploymentContext.getSource().getURI()); + + appProps.setProperty(ServerTags.LOCATION, appLocation); + appProps.setProperty(ServerTags.OBJECT_TYPE, "user"); + appProps.setProperty(ServerTags.CONTEXT_ROOT, contextRoot); + + savedAppConfig.store(appProps); + + Transaction t = deployment.prepareAppConfigChanges(deploymentContext); + appInfo = deployment.deploy(deploymentContext); + + if (appInfo!=null) { + facade.setAppName(appInfo.getName()); if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "Modifying web.xml "+webXml.getAbsolutePath()); + _logger.log(Level.FINE, "Virtual server "+getName()+" added context "+appInfo.getName()); } - updateWebXml(webXml, servlets, mappings); + deployment.registerAppInDomainXML(appInfo, deploymentContext, t); + } else { + if (report.getActionExitCode().equals(ActionReport.ExitCode.FAILURE)) { + throw new ConfigException(report.getMessage()); + } + } - String repositoryBitName = VersioningUtils.getRepositoryName(appName); - File webInf = new File(instance.getApplicationRepositoryPath(), repositoryBitName+"/WEB-INF"); - webInf.mkdirs(); - webXml = new File(webInf, "web.xml"); + // Update web.xml with programmatically added servlets, filters, and listeners + File file = null; + boolean delete = true; + com.sun.enterprise.config.serverbeans.Application appBean = apps.getApplication(params.name); + if (appBean != null) { + file = new File(deploymentContext.getSource().getURI().getPath(), "/WEB-INF/web.xml"); + if (file.exists()) { + delete = false; + } + updateWebXml(facade, file); + } else { + _logger.log(Level.SEVERE, "Application "+params.name+" not found"); + } - if (_logger.isLoggable(Level.FINE)) { - _logger.log(Level.FINE, "Modifying web.xml "+webXml.getAbsolutePath()); + // Enable the app using the modified web.xml + // We can't use Deployment.enable since it doesn't take DeploymentContext with custom class loader + deployment.updateAppEnabledAttributeInDomainXML(params.name, params.target, true); + + ReadableArchive source = appInfo.getSource(); + UndeployCommandParameters undeployParams = new UndeployCommandParameters(params.name); + undeployParams.origin = UndeployCommandParameters.Origin.undeploy; + ExtendedDeploymentContext undeploymentContext = + deployment.getBuilder(_logger, undeployParams, report).source(source).build(); + deployment.undeploy(params.name, undeploymentContext); + + params.origin = DeployCommandParameters.Origin.load; + params.enabled = Boolean.TRUE; + archive = factory.openArchive(docRoot); + deploymentContext = deployment.getBuilder(_logger, params, report).source(archive).build(); + + if (classLoader != null) { + ClassLoader parentCL = clh.createApplicationParentCL(classLoader, deploymentContext); + archiveHandler = deployment.getArchiveHandler(archive); + ClassLoader cl = archiveHandler.getClassLoader(parentCL, deploymentContext); + deploymentContext.setClassLoader(cl); + } + deployment.deploy(deploymentContext); + + if (_logger.isLoggable(Level.FINE)) { + _logger.log(Level.FINE, "Virtual server "+getName()+" enabled context "+params.name()); + } + + if (delete) { + if (file != null) { + if (file.exists() && !file.delete()) { + String path = file.toString(); + _logger.log(Level.WARNING, "webcontainer.unableToDelete", path); + } } } - // enable the deployapp - //((com.sun.enterprise.admin.cli.embeddable.DeployerImpl) deployer).enable(appName); - //webXml.delete(); - - WebModule wm = (WebModule) findChild(contextName); + if (contextRoot.equals("/")) { + contextRoot = ""; + } + WebModule wm = (WebModule) findChild(contextRoot); if (wm != null) { - if (classLoader != null) { - wm.setParentClassLoader(classLoader); - } else { - wm.setParentClassLoader(serverContext.getSharedClassLoader()); - } facade.setUnwrappedContext(wm); wm.setEmbedded(true); if (config != null) { wm.setDefaultWebXml(config.getDefaultWebXml()); } + } else { + throw new ConfigException("Deployed app not found "+contextRoot); } + if (deploymentContext != null) { + deploymentContext.postDeployClean(true); + } + } catch (Exception ex) { - ex.printStackTrace(); + if (deployment!=null && deploymentContext!=null) { + deploymentContext.clean(); + } + throw new GlassFishException(ex); } + } /** * Stops the given context and removes it from this * VirtualServer. */ - public void removeContext(Context context) - throws GlassFishException { + public void removeContext(Context context) throws GlassFishException { + ActionReport report = habitat.getComponent(ActionReport.class, "plain"); + Deployment deployment = habitat.getComponent(Deployment.class); + String name = ((ContextFacade)context).getAppName(); + ApplicationInfo appInfo = deployment.get(name); + + if (appInfo == null) { + report.setMessage("Cannot find deployed application of name " + name); + report.setActionExitCode(ActionReport.ExitCode.FAILURE); + throw new GlassFishException("Cannot find deployed application of name " + name); + } + + ReadableArchive source = appInfo.getSource(); + + if (source == null) { + report.setMessage("Cannot get source archive for undeployment"); + report.setActionExitCode(ActionReport.ExitCode.FAILURE); + throw new GlassFishException("Cannot get source archive for undeployment"); + } + + UndeployCommandParameters params = new UndeployCommandParameters(name); + params.origin = UndeployCommandParameters.Origin.undeploy; + ExtendedDeploymentContext deploymentContext = null; + try { - Deployer deployer = Globals.getDefaultHabitat().getComponent(Deployer.class); - deployer.undeploy(context.getContextPath()); - } catch (Exception ex) { - throw new GlassFishException(new ConfigException( - "Context with context path " + context.getContextPath() + - " cannot be removed from virtual server " + getID())); + deploymentContext = deployment.getBuilder(_logger, params, report).source(source).build(); + deployment.undeploy(name, deploymentContext); + deployment.unregisterAppFromDomainXML(name, "server"); + } catch (IOException e) { + _logger.log(Level.SEVERE, "Cannot create context for undeployment ", e); + report.setActionExitCode(ActionReport.ExitCode.FAILURE); + throw new GlassFishException("Cannot create context for undeployment ", e); + } catch (TransactionFailure e) { + throw new GlassFishException(e); + } finally { + deploymentContext.clean(); } + + if (_logger.isLoggable(Level.FINE)) { + _logger.log(Level.FINE, "Successfully removed context "+name); + } } + /** * Finds the Context registered at the given context root. */ @@ -2122,7 +2296,7 @@ this.config = config; configureSingleSignOn(config.isSsoEnabled(), - Globals.getDefaultHabitat().getComponent( + habitat.getComponent( PEWebContainerFeatureFactoryImpl.class), false); if (config.isAccessLoggingEnabled()) { @@ -2184,55 +2358,201 @@ } } - public static void updateWebXml(File file, Map servlets, Map mappings) { + public void updateWebXml(ContextFacade facade, File file) throws Exception { - try { + Map servlets = facade.getAddedServlets(); + Map mappings = facade.getServletMappings(); + List listeners = facade.getListeners(); + Map filters = facade.getAddedFilters(); + Map servletNameFilterMappings = facade.getServletNameFilterMappings(); + Map urlPatternFilterMappings = facade.getUrlPatternFilterMappings(); + if (!filters.isEmpty() || !listeners.isEmpty() || !servlets.isEmpty()) { + if (_logger.isLoggable(Level.FINE)) { + _logger.log(Level.FINE, "Modifying web.xml "+file.getAbsolutePath()); + } + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = null; Element webapp = null; if ((file != null) && (file.exists())) { - doc = dBuilder.parse(file); + doc = dBuilder.parse(file); webapp = doc.getDocumentElement(); - // doc.getDocumentElement().normalize(); } else { doc = dBuilder.newDocument(); webapp = doc.createElement("web-app"); - webapp.setAttribute("xmln", "http://java.sun.com/xml/ns/j2ee"); + webapp.setAttribute("xmln", "http://java.sun.com/xml/ns/javaee"); webapp.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); webapp.setAttribute("xsi:schemaLocation", - "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"); - webapp.setAttribute("version", "2.4"); + "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"); + webapp.setAttribute("version", "3.0"); doc.appendChild(webapp); } - for (String name : servlets.keySet()) { - Element servlet = doc.createElement("servlet"); - webapp.appendChild(servlet); + boolean entryFound = false; + + // Update + for (Map.Entry entry : filters.entrySet()) { + NodeList filterList = doc.getElementsByTagName("filter-name"); + for (int i=0; i initParams = + facade.getFilterRegistration(entry.getKey().toString()).getInitParameters(); + if ((initParams != null) && (!initParams.isEmpty())) { + Element initParam = doc.createElement("init-param"); + for (Map.Entry param : initParams.entrySet()) { + Element paramName = doc.createElement("param-name"); + paramName.setTextContent(param.getKey().toString()); + initParam.appendChild(paramName); + Element paramValue = doc.createElement("param-value"); + paramValue.setTextContent(param.getValue().toString()); + initParam.appendChild(paramValue); + } + filter.appendChild(initParam); + } + webapp.appendChild(filter); + } + } + + // Update + for (Map.Entry mapping : servletNameFilterMappings.entrySet()) { + Element filterMapping = doc.createElement("filter-mapping"); + Element filterName = doc.createElement("filter-name"); + filterName.setTextContent(mapping.getKey().toString()); + filterMapping.appendChild(filterName); Element servletName = doc.createElement("servlet-name"); - servletName.setTextContent(name); - servlet.appendChild(servletName); - Element servletClass = doc.createElement("servlet-class"); - servletClass.setTextContent(servlets.get(name)); - servlet.appendChild(servletClass); - } + servletName.setTextContent(mapping.getValue().toString()); + filterMapping.appendChild(servletName); + webapp.appendChild(filterMapping); + } - for (String mapping : mappings.keySet()) { - Element servletMapping = doc.createElement("servlet-mapping"); - webapp.appendChild(servletMapping); - for (String pattern : mappings.get(mapping)) { + for (Map.Entry mapping : urlPatternFilterMappings.entrySet()) { + Element filterMapping = doc.createElement("filter-mapping"); + Element filterName = doc.createElement("filter-name"); + filterName.setTextContent(mapping.getKey().toString()); + filterMapping.appendChild(filterName); + Element urlPattern = doc.createElement("url-pattern"); + urlPattern.setTextContent(mapping.getValue().toString()); + filterMapping.appendChild(urlPattern); + webapp.appendChild(filterMapping); + } + + entryFound = false; + + // Update + for (Map.Entry entry : servlets.entrySet()) { + NodeList servletList = doc.getElementsByTagName("servlet-name"); + for (int i=0; i initParams = + facade.getServletRegistration(entry.getKey().toString()).getInitParameters(); + if ((initParams != null) && (!initParams.isEmpty())) { + Element initParam = doc.createElement("init-param"); + for (Map.Entry param : initParams.entrySet()) { + Element paramName = doc.createElement("param-name"); + paramName.setTextContent(param.getKey().toString()); + initParam.appendChild(paramName); + Element paramValue = doc.createElement("param-value"); + paramValue.setTextContent(param.getValue().toString()); + initParam.appendChild(paramValue); + } + servlet.appendChild(initParam); + } + webapp.appendChild(servlet); } - webapp.appendChild(servletMapping); } + entryFound = false; + + // Update + for (Map.Entry mapping : mappings.entrySet()) { + NodeList servletList = doc.getElementsByTagName("servlet-name"); + for (int i=0; i