/* * JBoss, Home of Professional Open Source * Copyright 2010, Red Hat Middleware LLC, and individual contributors * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * Licensed 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.arquillian.container.tomcat.embedded_6; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import javax.servlet.ServletContext; import org.apache.catalina.startup.Constants; import org.apache.catalina.startup.ContextConfig; import org.xml.sax.InputSource; /** * A custom {@link ContextConfig} for use in the Embedded Tomcat * container integration for Arquillian. * * <p>This configuration adds processing of the META-INF/context.xml * descriptor in the web application root when the context is started. * This implementation also marks an unpacked WAR for deletion when * the context is stopped.</p> * * @author Dan Allen */ public class EmbeddedContextConfig extends ContextConfig { /** * Override as a hook to process the application context configuration. */ @Override protected void defaultWebConfig() { applicationContextConfig(); super.defaultWebConfig(); } /** * Process the META-INF/context.xml descriptor in the web application root. * This descriptor is not processed when a webapp is added programmatically through a StandardContext */ protected void applicationContextConfig() { ServletContext servletContext = context.getServletContext(); InputStream stream = servletContext.getResourceAsStream("/" + Constants.ApplicationContextXml); if (stream == null) { return; } // this bad-practice synchronization is inherited synchronized (contextDigester) { URL url = null; try { url = servletContext.getResource("/" + Constants.ApplicationContextXml); } catch (MalformedURLException e) { throw new AssertionError("/" + Constants.ApplicationContextXml + " should not be considered a malformed URL"); } InputSource is = new InputSource(url.toExternalForm()); is.setByteStream(stream); contextDigester.push(context); try { contextDigester.parse(is); } catch (Exception e) { ok = false; log.error("Parse error in context.xml for " + context.getName(), e); } finally { contextDigester.reset(); try { if (stream != null) { stream.close(); } } catch (IOException e) { log.error("Error closing context.xml for " + context.getName(), e); } } } log.debug("Done processing " + Constants.ApplicationContextXml + " descriptor"); } /** * Overridde to assign an internal field that will trigger the removal * of the unpacked WAR when the context is closed. */ @Override protected void fixDocBase() throws IOException { super.fixDocBase(); // If this field is not null, the unpacked WAR is removed when // the context is closed. This is normally used by the antiLocking // feature, though it should have been the normal behavior, at // least for an embedded container. originalDocBase = context.getDocBase(); } }