Index: D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/XMLUtils.java =================================================================== --- D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/XMLUtils.java (revision 0) +++ D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/XMLUtils.java (revision 0) @@ -0,0 +1,147 @@ +/* + * 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.apache.maven.plugin.war; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +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.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * @version $Id$ + */ +public class XMLUtils { + + public static Document parseXml(InputStream source) throws IOException, SAXException { + try { + DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance(); + documentFactory.setNamespaceAware(true); + documentFactory.setValidating(false); + DocumentBuilder docBuilder = documentFactory.newDocumentBuilder(); + // Parse using the local dtds instead of remote dtds. This + // allows to deploy the application offline + docBuilder.setEntityResolver(new EntityResolver() { + public InputSource resolveEntity(String publicId, String systemId) throws SAXException, + java.io.IOException { + if (systemId.equals("http://java.sun.com/dtd/web-app_2_3.dtd")) { + return new InputSource(getClass().getResourceAsStream("web-app_2_3.dtd")); + } + return null; + } + }); + + return docBuilder.parse(source); + } catch (ParserConfigurationException pce) { + throw new IOException("Creating document failed:" + pce.getMessage()); + } + } + + public static void write(Document node, OutputStream out) throws TransformerFactoryConfigurationError, TransformerException { + final Properties format = new Properties(); + format.put(OutputKeys.METHOD, "xml"); + format.put(OutputKeys.OMIT_XML_DECLARATION, "no"); + format.put(OutputKeys.INDENT, "yes"); + if (node.getDoctype() != null) { + if (node.getDoctype().getPublicId() != null) { + format.put(OutputKeys.DOCTYPE_PUBLIC, node.getDoctype().getPublicId()); + } + if (node.getDoctype().getSystemId() != null) { + format.put(OutputKeys.DOCTYPE_SYSTEM, node.getDoctype().getSystemId()); + } + } + Transformer transformer; + transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperties(format); + transformer.transform(new DOMSource(node), new StreamResult(out)); + } + + public static List getChildNodes(Element parent, String nodeName) { + final List nodes = new ArrayList(); + if (parent != null && nodeName != null) { + final NodeList children = parent.getChildNodes(); + if (children != null) { + for (int i = 0; i < children.getLength(); i++) { + if (nodeName.equals(children.item(i).getLocalName())) { + nodes.add(children.item(i)); + } + } + } + } + return nodes; + } + + public static Element getChildNode(Element parent, String nodeName) { + final List children = getChildNodes(parent, nodeName); + if (children.size() > 0) { + return (Element) children.get(0); + } + + return null; + } + + public static String getValue(Element node) { + if (node != null) { + if (node.getNodeType() == Node.ATTRIBUTE_NODE) { + return node.getNodeValue(); + } else { + node.normalize(); + NodeList childs = node.getChildNodes(); + int i = 0; + int length = childs.getLength(); + while (i < length) { + if (childs.item(i).getNodeType() == Node.TEXT_NODE) { + return childs.item(i).getNodeValue().trim(); + } else { + i++; + } + } + } + } + return null; + } + + public static void setValue(Element node, String value) { + if (node != null) { + // remove all children + while (node.hasChildNodes()) { + node.removeChild(node.getFirstChild()); + } + node.appendChild(node.getOwnerDocument().createTextNode(value)); + } + } +} \ No newline at end of file Property changes on: D:\dev\workspace\maven-war-plugin\src\main\java\org\apache\maven\plugin\war\XMLUtils.java ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Index: D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/AbstractWarMojo.java =================================================================== --- D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/AbstractWarMojo.java (revision 471031) +++ D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/AbstractWarMojo.java (working copy) @@ -153,6 +153,20 @@ */ protected ArchiverManager archiverManager; + /** + * Use shielded classloading + * + * @parameter expression="${maven.war.shieldingclassloader}" + */ + private boolean useShieldingClassLoader = false; + + /** + * Move jars for shielded classloading + * + * @parameter expression="${maven.war.shieldingrepository}" + */ + private boolean useShieldingRepository = true; + private static final String WEB_INF = "WEB-INF"; private static final String META_INF = "META-INF"; @@ -626,6 +640,12 @@ copyDependentWarContents( (File) iter.next(), webappDirectory ); } } + + // check for shielded class loading + if ( this.useShieldingClassLoader ) + { + WebApplicationRewriter.shieldWebapp(webinfDir, this.getLog(), this.useShieldingRepository); + } } /** @@ -1025,9 +1045,16 @@ */ private String getDefaultFinalName( Artifact artifact ) { - return artifact.getArtifactId() + "-" + artifact.getVersion() + "." + - artifact.getArtifactHandler().getExtension(); + String finalName = artifact.getArtifactId() + "-" + artifact.getVersion(); + + String classifier = artifact.getClassifier(); + if ( ( classifier != null ) && ! ( "".equals( classifier.trim() ) ) ) + { + finalName += "-" + classifier; + } + + finalName = finalName + "." + artifact.getArtifactHandler().getExtension(); + return finalName; } - } Index: D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/servlet/ShieldingServletFilter.java =================================================================== --- D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/servlet/ShieldingServletFilter.java (revision 0) +++ D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/servlet/ShieldingServletFilter.java (revision 0) @@ -0,0 +1,106 @@ +/* + * 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.apache.maven.plugin.war.servlet; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +/** + * This filter can be used as a wrapper around a "real" filter to + * support the shielded class loader. + * + * @version $Id$ + */ +public class ShieldingServletFilter implements Filter { + + protected Filter filter; + + protected ClassLoader classloader; + + /** + * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) + */ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + if ( this.filter != null ) { + final ClassLoader old = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(this.classloader); + + this.filter.doFilter(request, response, chain); + } finally { + Thread.currentThread().setContextClassLoader(old); + } + } + } + + /** + * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) + */ + public void init(FilterConfig config) throws ServletException { + // Get the classloader + this.classloader = ShieldedClassLoaderManager.getClassLoader(config.getServletContext()); + + String filterName = config.getInitParameter("filter-class"); + if (filterName == null) { + throw new ServletException("ShieldingServletFilter: 'filter-class' parameter is missing."); + } + ShieldedClassLoaderManager.logDebug(config.getServletContext(), + "ShieldingServletFilter: Loading filter class " + filterName); + + // Create the filter + try { + + Class filterClass = this.classloader.loadClass(filterName); + this.filter = (Filter) filterClass.newInstance(); + + } catch (Exception e) { + throw new ServletException("Cannot load filter " + filterName, e); + } + + final ClassLoader old = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(this.classloader); + + // Inlitialize the actual filter + this.filter.init(config); + } finally { + Thread.currentThread().setContextClassLoader(old); + } + } + + /** + * @see javax.servlet.Filter#destroy() + */ + public void destroy() { + if (this.filter != null) { + final ClassLoader old = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(this.classloader); + this.filter.destroy(); + } finally { + Thread.currentThread().setContextClassLoader(old); + } + } + } +} \ No newline at end of file Property changes on: D:\dev\workspace\maven-war-plugin\src\main\java\org\apache\maven\plugin\war\servlet\ShieldingServletFilter.java ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Index: D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/servlet/ShieldedClassLoaderManager.java =================================================================== --- D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/servlet/ShieldedClassLoaderManager.java (revision 0) +++ D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/servlet/ShieldedClassLoaderManager.java (revision 0) @@ -0,0 +1,150 @@ +/* + * 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.apache.maven.plugin.war.servlet; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; + + +/** + * This class creates a singleton instance of the shielded class loader. + * + * It can be configured through context paramters: + *
shielded-classloader-debug Can be used to turn debug messages on.
+ * This servlet propagates all initialisation parameters to the sandboxed
+ * servlet, and requires the parameter servlet-class.
+ *
servlet-class defines the sandboxed servlet class.URLs.
+ */
+ public ShieldedClassLoader(URL[] urls, final ClassLoader parent) {
+ this(urls, parent, null);
+ }
+
+ /**
+ * Alternate constructor to define a parent, initial URLs,
+ * and a default URLStreamHandlerFactory.
+ */
+ public ShieldedClassLoader(final URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) {
+ super(urls, parent, factory);
+ }
+
+ protected boolean tryClassHere(String name) {
+ // don't include classes in the java or javax.servlet package
+ if ( name != null && (name.startsWith("java.") || name.startsWith("javax.servlet") ) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ protected Class getClass(String name)
+ throws ClassNotFoundException {
+ return findClass(name);
+ }
+
+ /**
+ * Loads the class from this ClassLoader. If the
+ * class does not exist in this one, we check the parent. Please
+ * note that this is the exact opposite of the
+ * ClassLoader spec. We use it to work around
+ * inconsistent class loaders from third party vendors.
+ *
+ * @param name the name of the class
+ * @param resolve if true then resolve the class
+ * @return the resulting Class object
+ * @exception ClassNotFoundException if the class could not be found
+ */
+ public final Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ // First check if it's already loaded
+ Class clazz = findLoadedClass(name);
+
+ if (clazz == null) {
+
+ final ClassLoader parent = getParent();
+
+ if (tryClassHere(name)) {
+ try {
+ clazz = this.getClass(name);
+ } catch (ClassNotFoundException cnfe) {
+ if (parent == null) {
+ // Propagate exception
+ throw cnfe;
+ }
+ }
+ }
+
+ if (clazz == null) {
+ if (parent == null) {
+ throw new ClassNotFoundException(name);
+ } else {
+ // Will throw a CFNE if not found in parent
+ clazz = parent.loadClass(name);
+ }
+ }
+ }
+
+ if (resolve) {
+ resolveClass(clazz);
+ }
+
+ return clazz;
+ }
+
+ /**
+ * Gets a resource from this ClassLoader. If the
+ * resource does not exist in this one, we check the parent.
+ * Please note that this is the exact opposite of the
+ * ClassLoader spec. We use it to work around
+ * inconsistent class loaders from third party vendors.
+ *
+ * @param name of resource
+ */
+ public final URL getResource(final String name) {
+ URL resource = findResource(name);
+ ClassLoader parent = this.getParent();
+ if (resource == null && parent != null) {
+ resource = parent.getResource(name);
+ }
+
+ return resource;
+ }
+}
+
Property changes on: D:\dev\workspace\maven-war-plugin\src\main\java\org\apache\maven\plugin\war\servlet\ShieldedClassLoader.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Index: D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/WebApplicationRewriter.java
===================================================================
--- D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/WebApplicationRewriter.java (revision 0)
+++ D:/dev/workspace/maven-war-plugin/src/main/java/org/apache/maven/plugin/war/WebApplicationRewriter.java (revision 0)
@@ -0,0 +1,344 @@
+/*
+ * 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.apache.maven.plugin.war;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.war.servlet.ShieldedClassLoaderManager;
+import org.apache.maven.plugin.war.servlet.ShieldingListener;
+import org.apache.maven.plugin.war.servlet.ShieldingServlet;
+import org.apache.maven.plugin.war.servlet.ShieldingServletFilter;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @version $Id$
+ */
+public class WebApplicationRewriter {
+
+ protected static final String SERVLET_CLASS = ShieldingServlet.class.getName();
+
+ protected static final String LISTENER_CLASS = ShieldingListener.class.getName();
+
+ protected static final String FILTER_CLASS = ShieldingServletFilter.class.getName();
+
+ protected static final String CLASSLOADER_JAR = "maven-war-plugin-classloading.jar";
+
+ protected static final String JAR_ENTRY_PREFIX = ShieldedClassLoaderManager.class.getPackage().getName().replace('.', '/');
+
+ /**
+ * Prepare the web application to use the shielded class loader.
+ * The web.xml will be rewritten: all servlets, filters etc. are wrapped
+ * by a wrapper which uses the shielded class loader.
+ * In addition all libs are moved from WEB-INF/lib to WEB-INF/shielded/lib
+ * and all files from WEB-INF/classes are moved to WEB-INF/shielded/classes.
+ */
+ public static void shieldWebapp(File webInfDir, Log log, boolean useShieldingRepository)
+ throws MojoExecutionException {
+ final String webInfSlashWebXml = webInfDir.getPath() + File.separatorChar + "web.xml";
+
+ if (!new File(webInfSlashWebXml).exists()) {
+ throw new MojoExecutionException("No web.xml present - can't add shielded class loading");
+ }
+ log.info("Adding shielded classloader configuration to web application configuration.");
+ if ( log.isDebugEnabled() ) {
+ log.debug("Reading web.xml: " + webInfSlashWebXml);
+ }
+
+ // load web.xml
+ InputStream is = null;
+ final Document webAppDoc;
+ try {
+ is = new BufferedInputStream(new FileInputStream(new File(webInfSlashWebXml)));
+ webAppDoc = XMLUtils.parseXml(is);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to read web.xml from " + webInfSlashWebXml, e);
+ } finally {
+ if ( is != null ) {
+ try {
+ is.close();
+ } catch (IOException ignore) {
+ // ignore
+ }
+ }
+ }
+
+ // rewrite
+ if ( WebApplicationRewriter.rewrite(webAppDoc, useShieldingRepository) ) {
+
+ // save web.xml
+ try {
+ if ( log.isDebugEnabled() ) {
+ log.debug("Writing web.xml: " + webInfSlashWebXml);
+ }
+ XMLUtils.write(webAppDoc, new FileOutputStream(webInfSlashWebXml));
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to write web.xml to " + webInfSlashWebXml, e);
+ }
+ }
+
+ // move classes and libs
+ if (useShieldingRepository) {
+ log.info("Moving classes and libs to shielded location.");
+ try {
+ move(webInfDir, "lib", ShieldedClassLoaderManager.WEB_INF_SHIELDED_LIB, log);
+ move(webInfDir, "classes", ShieldedClassLoaderManager.WEB_INF_SHIELDED_CLASSES, log);
+ } catch (IOException e) {
+ throw new MojoExecutionException("unable to shield classes/libs", e);
+ }
+ }
+
+ // add classloading stuff to WEB-INF/lib
+ // let's search our jar
+ final String rsrc = ShieldedClassLoaderManager.class.getName().replace('.', '/') + ".class";
+ if ( log.isDebugEnabled() ) {
+ log.debug("Searching class file for: " + rsrc);
+ }
+ try {
+ final Enumeration e = WebApplicationRewriter.class.getClassLoader().getResources(rsrc);
+ boolean found = false;
+ while ( e.hasMoreElements() ) {
+ final URL url = (URL)e.nextElement();
+ if ( log.isDebugEnabled() ) {
+ log.debug("Found class in " + url);
+ }
+ if ( url.getProtocol().equals("jar")) {
+ String jarUrlString = url.toExternalForm();
+ int pos = jarUrlString.indexOf('!');
+ // include !/
+ jarUrlString = jarUrlString.substring(0, pos + 2);
+ final URL jarUrl = new URL(jarUrlString);
+ final JarURLConnection connection = (JarURLConnection)jarUrl.openConnection();
+ final JarFile jarFile = connection.getJarFile();
+ final File destFile = new File(webInfDir, "lib" + File.separator + CLASSLOADER_JAR);
+ final JarOutputStream jos = new JarOutputStream(new FileOutputStream(destFile));
+ final Enumeration entries = jarFile.entries();
+ while ( entries.hasMoreElements() ) {
+ final JarEntry current = (JarEntry)entries.nextElement();
+ // only include classes from the shielded class loader package
+ if ( current.getName().startsWith(JAR_ENTRY_PREFIX) ) {
+ jos.putNextEntry(current);
+ IOUtil.copy(jarFile.getInputStream(current), jos);
+ jos.closeEntry();
+ }
+ }
+ jos.close();
+ found = true;
+ }
+ }
+ if (!found) {
+ throw new MojoExecutionException("Unable to find jar file for shielded class loading classes.");
+ }
+ } catch (IOException ioe) {
+ throw new MojoExecutionException("unable to find classes for shielded class loading.", ioe);
+ }
+ }
+
+ private static void move(File parentDir, String srcDir, String destDirOrig, Log log) throws IOException {
+ String destDir = destDirOrig;
+ // use correct separators on windows
+ if ( File.separatorChar != '/' ) {
+ destDir = destDir.replace('/', File.separatorChar);
+ }
+ final File srcDirectory = new File(parentDir, srcDir);
+ if (srcDirectory.exists() && srcDirectory.isDirectory()) {
+ File destDirectory = new File(parentDir, destDir);
+ if (log.isDebugEnabled()) {
+ log.debug("Deleting directory " + destDirectory);
+ }
+ FileUtils.deleteDirectory(destDirectory);
+ destDirectory = new File(parentDir, destDir);
+ if (log.isDebugEnabled()) {
+ log.debug("Recreating directory " + destDirectory);
+ }
+ destDirectory.mkdirs();
+ final File[] files = srcDirectory.listFiles();
+ if (files != null && files.length > 0) {
+ for (int i = 0; i < files.length; i++) {
+ // move everything but our own jar
+ if ( !files[i].getName().equals(CLASSLOADER_JAR) ) {
+ if (log.isDebugEnabled()) {
+ log.debug("Moving " + files[i] + " to " + destDirectory);
+ }
+ files[i].renameTo(new File(destDirectory, files[i].getName()));
+ }
+ }
+ }
+ }
+ }
+
+ public static boolean rewrite(Document webAppDoc, boolean useShieldingRepository) {
+ boolean rewritten = false;
+ final Element rootElement = webAppDoc.getDocumentElement();
+ // first rewrite servlets
+ final List servlets = XMLUtils.getChildNodes(rootElement, "servlet");
+ Iterator i = servlets.iterator();
+ while ( i.hasNext() ) {
+ final Element servletElement = (Element)i.next();
+ final Element servletClassElement = XMLUtils.getChildNode(servletElement, "servlet-class");
+ if ( servletClassElement != null ) {
+ final String className = XMLUtils.getValue(servletClassElement);
+ XMLUtils.setValue(servletClassElement, SERVLET_CLASS);
+ // create init-param with real servlet class
+ final Element initParamElem = webAppDoc.createElementNS(null, "init-param");
+ final Element initParamNameElem = webAppDoc.createElementNS(null, "param-name");
+ final Element initParamValueElem = webAppDoc.createElementNS(null, "param-value");
+ initParamElem.appendChild(initParamNameElem);
+ initParamElem.appendChild(initParamValueElem);
+ XMLUtils.setValue(initParamNameElem, "servlet-class");
+ XMLUtils.setValue(initParamValueElem, className);
+ Element beforeElement = XMLUtils.getChildNode(servletElement, "load-on-startup");
+ if ( beforeElement == null ) {
+ beforeElement = XMLUtils.getChildNode(servletElement, "run-as");
+ if ( beforeElement == null ) {
+ beforeElement = XMLUtils.getChildNode(servletElement, "security-role-ref");
+ }
+ }
+ if ( beforeElement == null ) {
+ servletElement.appendChild(initParamElem);
+ } else {
+ servletElement.insertBefore(initParamElem, beforeElement);
+ }
+ rewritten = true;
+ }
+ }
+
+ // now rewrite listeners
+ final List listeners = XMLUtils.getChildNodes(rootElement, "listener");
+ i = listeners.iterator();
+ boolean hasListener = false;
+ final StringBuffer rewrittenListeners = new StringBuffer();
+ while ( i.hasNext() ) {
+ final Element listenerElement = (Element)i.next();
+ final Element listenerClassElement = XMLUtils.getChildNode(listenerElement, "listener-class");
+ if ( listenerClassElement != null ) {
+ final String className = XMLUtils.getValue(listenerClassElement);
+ if ( rewrittenListeners.length() > 0 ) {
+ rewrittenListeners.append(',');
+ }
+ rewrittenListeners.append(className);
+ if ( hasListener ) {
+ rootElement.removeChild(listenerElement);
+ } else {
+ XMLUtils.setValue(listenerClassElement, LISTENER_CLASS);
+ hasListener = true;
+ }
+ rewritten = true;
+ }
+ }
+ // remove old parameter
+ i = XMLUtils.getChildNodes(rootElement, "context-param").iterator();
+ while ( i.hasNext() ) {
+ final Element child = (Element)i.next();
+ if ( LISTENER_CLASS.equals(XMLUtils.getValue(XMLUtils.getChildNode(child, "param-name")))) {
+ rootElement.removeChild(child);
+ }
+ }
+ if ( hasListener ) {
+ addContextParameter(rootElement, LISTENER_CLASS, rewrittenListeners.toString());
+ }
+
+ // and now filters
+ i = XMLUtils.getChildNodes(rootElement, "filter").iterator();
+ while ( i.hasNext() ) {
+ final Element filterElement = (Element)i.next();
+ final Element filterClassElement = XMLUtils.getChildNode(filterElement, "filter-class");
+ if ( filterClassElement != null ) {
+ final String className = XMLUtils.getValue(filterClassElement);
+ XMLUtils.setValue(filterClassElement, FILTER_CLASS);
+ // create init-param with real servlet class
+ final Element initParamElem = webAppDoc.createElementNS(null, "init-param");
+ final Element initParamNameElem = webAppDoc.createElementNS(null, "param-name");
+ final Element initParamValueElem = webAppDoc.createElementNS(null, "param-value");
+ initParamElem.appendChild(initParamNameElem);
+ initParamElem.appendChild(initParamValueElem);
+ XMLUtils.setValue(initParamNameElem, "filter-class");
+ XMLUtils.setValue(initParamValueElem, className);
+ filterElement.appendChild(initParamElem);
+ rewritten = true;
+ }
+ }
+
+ if ( !useShieldingRepository ) {
+ addContextParameter(rootElement,
+ ShieldedClassLoaderManager.SHIELDED_CLASSLOADER_USE_REPOSITORY,
+ "false");
+ rewritten = true;
+ } else {
+ if ( removeContextParameter(rootElement, ShieldedClassLoaderManager.SHIELDED_CLASSLOADER_USE_REPOSITORY) ) {
+ rewritten = true;
+ }
+ }
+
+ return rewritten;
+ }
+
+ protected static boolean removeContextParameter(Element root, String name) {
+ boolean removed = false;
+ final Iterator i = XMLUtils.getChildNodes(root, "context-param").iterator();
+ while ( !removed && i.hasNext() ) {
+ final Element parameterElement = (Element)i.next();
+ final String paramName = XMLUtils.getValue(XMLUtils.getChildNode(parameterElement, "param-name"));
+ if ( name.equals(paramName) ) {
+ parameterElement.getParentNode().removeChild(parameterElement);
+ removed = true;
+ }
+ }
+ return removed;
+ }
+
+ protected static void addContextParameter(Element root, String name, String value) {
+ removeContextParameter(root, name);
+ // search the element where we have to put the new context parameter before!
+ // we know that we have listeners so this is the last element to search for
+ Element searchElement = XMLUtils.getChildNode(root, "context-param");
+ if ( searchElement == null ) {
+ searchElement = XMLUtils.getChildNode(root, "filter");
+ if ( searchElement == null ) {
+ searchElement = XMLUtils.getChildNode(root, "filter-mapping");
+ if ( searchElement == null ) {
+ searchElement = XMLUtils.getChildNode(root, "listener");
+ }
+ }
+ }
+ final Element contextParamElement = root.getOwnerDocument().createElementNS(null, "context-param");
+ final Element contextParamNameElement = root.getOwnerDocument().createElementNS(null, "param-name");
+ final Element contextParamValueElement = root.getOwnerDocument().createElementNS(null, "param-value");
+ contextParamElement.appendChild(contextParamNameElement);
+ contextParamElement.appendChild(contextParamValueElement);
+ XMLUtils.setValue(contextParamNameElement, name);
+ XMLUtils.setValue(contextParamValueElement, value);
+ root.insertBefore(contextParamElement, searchElement);
+ }
+}
\ No newline at end of file
Property changes on: D:\dev\workspace\maven-war-plugin\src\main\java\org\apache\maven\plugin\war\WebApplicationRewriter.java
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Index: D:/dev/workspace/maven-war-plugin/pom.xml
===================================================================
--- D:/dev/workspace/maven-war-plugin/pom.xml (revision 471031)
+++ D:/dev/workspace/maven-war-plugin/pom.xml (working copy)
@@ -38,6 +38,12 @@
2.0.1
+ javax.servlet
+ servlet-api
+ 2.4
+ compile
+
+
junit
junit
3.8.1