You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2006/11/17 18:34:36 UTC

svn commit: r476226 - in /cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin: ./ src/main/java/org/apache/cocoon/maven/deployer/ src/main/java/org/apache/cocoon/maven/deployer/servlet/ src/main/java/org/apache/cocoon/maven/deployer/utils/

Author: cziegeler
Date: Fri Nov 17 09:34:35 2006
New Revision: 476226

URL: http://svn.apache.org/viewvc?view=rev&rev=476226
Log:
Use simplified shielded classloading - this is the same version as recently contributed as a patch to the maven war plugin
No dependency on bootstrap anymore

Added:
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java   (with props)
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java   (with props)
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java   (with props)
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java   (with props)
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java   (with props)
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java   (with props)
Removed:
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/WebApplicationRewriter.java
Modified:
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/pom.xml
    cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java

Modified: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/pom.xml
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/pom.xml?view=diff&rev=476226&r1=476225&r2=476226
==============================================================================
--- cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/pom.xml (original)
+++ cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/pom.xml Fri Nov 17 09:34:35 2006
@@ -91,6 +91,12 @@
       <artifactId>xml-apis</artifactId>
       <version>1.3.02</version>
     </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.4</version>
+      <scope>compile</scope>
+    </dependency>
     <!-- test libs -->
     <dependency>
       <groupId>junit</groupId>

Modified: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java?view=diff&rev=476226&r1=476225&r2=476226
==============================================================================
--- cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java (original)
+++ cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/AbstractDeployMojo.java Fri Nov 17 09:34:35 2006
@@ -16,13 +16,9 @@
  */
 package org.apache.cocoon.maven.deployer;
 
-import java.io.BufferedInputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -31,10 +27,6 @@
 import org.apache.cocoon.maven.deployer.monolithic.DevelopmentBlock;
 import org.apache.cocoon.maven.deployer.monolithic.DevelopmentProperty;
 import org.apache.cocoon.maven.deployer.monolithic.MonolithicCocoonDeployer;
-import org.apache.cocoon.maven.deployer.utils.CopyUtils;
-import org.apache.cocoon.maven.deployer.utils.WebApplicationRewriter;
-import org.apache.cocoon.maven.deployer.utils.XMLUtils;
-import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.SystemUtils;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.factory.ArtifactFactory;
@@ -46,7 +38,6 @@
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.artifact.MavenMetadataSource;
 import org.codehaus.plexus.util.FileUtils;
-import org.w3c.dom.Document;
 
 /**
  * Create a Cocoon web application based on a block deployment descriptor.
@@ -55,10 +46,6 @@
  */
 abstract class AbstractDeployMojo extends AbstractWarMojo {
 
-    private static final String COCOON_CLASSES = "shielded" + File.separator + "classes";
-
-    private static final String COCOON_LIB = "shielded" + File.separator + "lib";
-
     /**
      * Artifact factory, needed to download source jars for inclusion in
      * classpath.
@@ -163,7 +150,7 @@
      * 
      * @parameter expression="${maven.war.shieldingclassloader}"
      */
-    private boolean useShieldingClassloader = true;
+    private boolean useShieldingClassLoader = true;
 
     /**
      * Move jars for shielded classloading
@@ -199,9 +186,9 @@
 
         // TODO XPatch web.xml here!
 
-        // take care of paranoid classloading
-        if (this.useShieldingClassloader) {
-            shieldCocoonWebapp();
+        // take care of shielded classloading
+        if (this.useShieldingClassLoader) {
+            WebApplicationRewriter.shieldWebapp(new File(getWebappDirectory(), "WEB-INF"), getLog(), this.useShieldingRepository);
         }
     }
 
@@ -238,8 +225,10 @@
         MonolithicCocoonDeployer deployer = new MonolithicCocoonDeployer(this.getLog());
         deployer.deploy(getBlockArtifactsAsMap(blocks), getWebappDirectory(), blocksdir, extBlocks, properties, useConsoleAppender);
 
-        if (useShieldingClassloader)
-            shieldCocoonWebapp();
+        // take care of shielded classloading
+        if (this.useShieldingClassLoader) {
+            WebApplicationRewriter.shieldWebapp(new File(getWebappDirectory(), "WEB-INF"), getLog(), this.useShieldingRepository);
+        }
     }
 
     /**
@@ -307,116 +296,5 @@
             }
         }
         return false;
-    }
-
-    // ~~~~~~~~~~ utility methods ~~~~~~~~~~~
-    /**
-     * Make a Cocoon webapp using the ShieldingClassloader. This method rewrites
-     * the web.xml and moves all libs from WEB-INF/lib to WEB-INF/cocoon/lib,
-     * except cocoon-bootstrap which remains in WEB-INF/lib.
-     */
-    private void shieldCocoonWebapp() throws MojoExecutionException {
-        String webInfSlashWebXml = "WEB-INF" + File.separatorChar + "web.xml";
-
-        File webXmlLocationFile = super.getWebXml();
-        String webXmlLocation = null;
-        if (webXmlLocationFile == null) {
-            webXmlLocation = getWarSourceDirectory().getAbsolutePath() + File.separatorChar + webInfSlashWebXml;
-        } else {
-            webXmlLocation = webXmlLocationFile.getAbsolutePath();
-        }
-
-        String targetWebXmlLocation = getWebappDirectory().getAbsolutePath() + File.separatorChar + webInfSlashWebXml;
-        if (!new File(webXmlLocation).exists()) {
-            getLog().debug("no web.xml in source location. checking for generated web.xml in target location.");
-            if (!new File(targetWebXmlLocation).exists()) {
-                this.getLog().info("No web.xml supplied. Will install default web.xml");
-                File outFile = org.apache.cocoon.maven.deployer.utils.FileUtils.createPath(new File(
-                        getWebappDirectory(), webInfSlashWebXml));
-
-                try {
-                    CopyUtils.copy(readResourceFromClassloader("WEB-INF/web.xml"), new FileOutputStream(outFile));
-                } catch (IOException ioex) {
-                    throw new MojoExecutionException("cannot copy resource " + webXml, ioex);
-                }
-            }
-            webXmlLocation = targetWebXmlLocation;
-        } else {
-            this.getLog().info("web.xml present");
-        }
-        this.getLog().info("Adding shielded classloader configuration to webapp configuration.");
-        this.getLog().debug("Reading web.xml: " + webXmlLocation);
-
-        InputStream is = null;
-        final Document webAppDoc;
-        try {
-            is = new BufferedInputStream(new FileInputStream(new File(webXmlLocation)));
-            webAppDoc = XMLUtils.parseXml(is);
-        } catch (Exception e) {
-            throw new MojoExecutionException("Unable to read web.xml from " + webXmlLocation, e);
-        } finally {
-            IOUtils.closeQuietly(is);
-        }
-
-        WebApplicationRewriter.rewrite(webAppDoc);
-        this.getLog().debug("Writing web.xml: " + targetWebXmlLocation);
-
-        try {
-            XMLUtils.write(webAppDoc, new FileOutputStream(targetWebXmlLocation));
-        } catch (Exception e) {
-            throw new MojoExecutionException("Unable to write web.xml to " + targetWebXmlLocation, e);
-        }
-
-        if (this.useShieldingRepository) {
-            this.getLog().info("Moving classes and libs to shielded location.");
-            final String webInfDir = getWebappDirectory().getAbsolutePath() + File.separatorChar + "WEB-INF";
-            try {
-                this.move(webInfDir, "lib", COCOON_LIB);
-                this.move(webInfDir, "classes", COCOON_CLASSES);
-            } catch (IOException e) {
-                throw new MojoExecutionException("unable to shield classes/libs", e);
-            }
-        }
-    }
-
-    private InputStream readResourceFromClassloader(String fileName) {
-        return MonolithicCocoonDeployer.class.getClassLoader().getResourceAsStream(
-                "org/apache/cocoon/maven/deployer/monolithic/" + fileName);
-    }
-
-    private void move(String parentDir, String srcDir, String destDir) throws IOException {
-        final File srcDirectory = new File(parentDir, srcDir);
-        if (srcDirectory.exists() && srcDirectory.isDirectory()) {
-            File destDirectory = new File(parentDir, destDir);
-            if (this.getLog().isDebugEnabled()) {
-                this.getLog().debug("Deleting directory " + destDirectory);
-            }
-            FileUtils.deleteDirectory(destDirectory);
-            destDirectory = new File(parentDir, destDir);
-            if (this.getLog().isDebugEnabled()) {
-                this.getLog().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++) {
-                    // TODO - replace this hard-coded exlclude with something
-                    // configurable
-                    boolean exclude = false;
-                    if ("lib".equals(srcDir) && files[i].getName().startsWith("cocoon-bootstrap")) {
-                        exclude = true;
-                        if (this.getLog().isDebugEnabled()) {
-                            this.getLog().debug("Excluding " + files[i] + " from moving.");
-                        }
-                    }
-                    if (!exclude) {
-                        if (this.getLog().isDebugEnabled()) {
-                            this.getLog().debug("Moving " + files[i] + " to " + destDirectory);
-                        }
-                        files[i].renameTo(new File(destDirectory, files[i].getName()));
-                    }
-                }
-            }
-        }
     }
 }

Added: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java?view=auto&rev=476226
==============================================================================
--- cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java (added)
+++ cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java Fri Nov 17 09:34:35 2006
@@ -0,0 +1,348 @@
+/*
+ * 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.cocoon.maven.deployer;
+
+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.cocoon.maven.deployer.servlet.ShieldedClassLoaderManager;
+import org.apache.cocoon.maven.deployer.servlet.ShieldingListener;
+import org.apache.cocoon.maven.deployer.servlet.ShieldingServlet;
+import org.apache.cocoon.maven.deployer.servlet.ShieldingServletFilter;
+import org.apache.cocoon.maven.deployer.utils.XMLUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+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 = "cocoon-deployer-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 {
+        if ( log.isDebugEnabled() ) {
+            log.debug("Shielding web application in " + webInfDir);
+        }
+        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

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/WebApplicationRewriter.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java?view=auto&rev=476226
==============================================================================
--- cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java (added)
+++ cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java Fri Nov 17 09:34:35 2006
@@ -0,0 +1,128 @@
+/*
+ * 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.cocoon.maven.deployer.servlet;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLStreamHandlerFactory;
+
+
+/**
+ * This class loader reverses the search order for classes.  It checks this classloader
+ * before it checks its parent.
+ *
+ * @version $Id$
+ */
+public class ShieldedClassLoader extends URLClassLoader {
+
+    /**
+     * Alternate constructor to define a parent and initial <code>URL</code>s.
+     */
+    public ShieldedClassLoader(URL[] urls, final ClassLoader parent) {
+        this(urls, parent, null);
+    }
+
+    /**
+     * Alternate constructor to define a parent, initial <code>URL</code>s,
+     * and a default <code>URLStreamHandlerFactory</code>.
+     */
+    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 <code>ClassLoader</class>.  If the
+     * class does not exist in this one, we check the parent.  Please
+     * note that this is the exact opposite of the
+     * <code>ClassLoader</code> spec.  We use it to work around
+     * inconsistent class loaders from third party vendors.
+     *
+     * @param     name the name of the class
+     * @param     resolve if <code>true</code> then resolve the class
+     * @return    the resulting <code>Class</code> 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 <code>ClassLoader</class>.  If the
+     * resource does not exist in this one, we check the parent.
+     * Please note that this is the exact opposite of the
+     * <code>ClassLoader</code> 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;
+    }
+}
+

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java?view=auto&rev=476226
==============================================================================
--- cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java (added)
+++ cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java Fri Nov 17 09:34:35 2006
@@ -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.cocoon.maven.deployer.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:
+ * <ul>
+ * <li><code>shielded-classloader-debug</code> Can be used to turn debug messages on.</li>
+ * </ul>
+ *
+ * @version $Id$
+ */
+public class ShieldedClassLoaderManager {
+
+
+    public static final String SHIELDED_CLASSLOADER_DEBUG = "shielded-classloader-debug";
+
+    public static final String SHIELDED_CLASSLOADER_USE_REPOSITORY = "shieled-classloader-use-repository";
+
+    public static final String WEB_INF_SHIELDED_LIB = "shielded/lib";
+
+    public static final String WEB_INF_SHIELDED_CLASSES = "shielded/classes";
+
+    protected static final String SHIELDED_LIB = "/WEB-INF/" + WEB_INF_SHIELDED_LIB;
+
+    protected static final String SHIELDED_CLASSES = "/WEB-INF/" + WEB_INF_SHIELDED_CLASSES;
+
+    protected static ClassLoader shieldedClassLoader;
+
+    /**
+     * Create the class loader.
+     * @param servletContext
+     * @return
+     * @throws ServletException
+     */
+    public static synchronized ClassLoader getClassLoader(ServletContext servletContext)
+    throws ServletException {
+        if ( shieldedClassLoader == null ) {
+            try {
+                shieldedClassLoader = createClassLoader(ShieldedClassLoaderManager.class.getClassLoader(), servletContext);
+            } catch (IOException ioe) {
+                throw new ServletException("Unable to create shielded class loader.", ioe);                
+            }
+        }
+        return shieldedClassLoader;
+    }
+
+    /**
+     * Log a debug message to the log of the servlet context.
+     * This method first checks if the init parameter "shielded-classloader-debug" has the value
+     * true before it logs.
+     * @param servletContext The servlet context.
+     * @param message        The message to log.
+     */
+    public static void logDebug(ServletContext servletContext, String message) {
+        if ( servletContext.getInitParameter(SHIELDED_CLASSLOADER_DEBUG) != null
+             && servletContext.getInitParameter(SHIELDED_CLASSLOADER_DEBUG).equalsIgnoreCase("true") ) { 
+            servletContext.log(message);
+        }
+    }
+
+    /**
+     * Create the shielded class loader.
+     */
+    protected static ClassLoader createClassLoader(ClassLoader    parent,
+                                                   ServletContext servletContext)
+    throws IOException {
+        String classesDirectory = ShieldedClassLoaderManager.SHIELDED_CLASSES;
+        String jarDirectory = ShieldedClassLoaderManager.SHIELDED_LIB;
+        if ( servletContext.getInitParameter(SHIELDED_CLASSLOADER_USE_REPOSITORY) != null ) {
+            boolean useShieldedRepository = Boolean.valueOf(servletContext.getInitParameter(SHIELDED_CLASSLOADER_USE_REPOSITORY)).booleanValue();
+            if ( !useShieldedRepository ) {
+                classesDirectory = "/WEB-INF/classes";
+                jarDirectory = "/WEB-INF/libs";
+            }
+        }
+        final List urlList = new ArrayList();
+        // add url for classes dir
+        if (servletContext.getResource(classesDirectory) != null) {
+            urlList.add(servletContext.getResource(classesDirectory));
+        }
+
+        // add url for lib dir
+        if (servletContext.getResource(jarDirectory) != null) {
+            final Set resources = servletContext.getResourcePaths(jarDirectory + '/');
+            if (resources != null) {
+                // we add all urls into a temporary list first to sort them
+                // before we add them
+                final List temporaryList = new ArrayList();
+                final Iterator iter = resources.iterator();
+                while (iter.hasNext()) {
+                    final String path = (String) iter.next();
+                    if (path.endsWith(".jar") || path.endsWith(".zip")) {
+                        temporaryList.add(servletContext.getResource(path));
+                    }
+                }
+                // let's sort before adding
+                Collections.sort(temporaryList, new UrlComparator());
+                urlList.addAll(temporaryList);
+            }
+        }
+
+        URL[] urls = (URL[]) urlList.toArray(new URL[urlList.size()]);
+
+        return new ShieldedClassLoader(urls, parent);
+    }
+
+    /**
+     * Simple comparator for comparing url objects.
+     */
+    protected final static class UrlComparator implements Comparator {
+
+        public int compare(Object o1, Object o2) {
+            if (o1 instanceof URL && o2 instanceof URL) {
+                return ((URL) o1).toExternalForm().compareTo(
+                        ((URL) o2).toExternalForm());
+            }
+            return 0;
+        }
+    }
+}

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java?view=auto&rev=476226
==============================================================================
--- cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java (added)
+++ cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java Fri Nov 17 09:34:35 2006
@@ -0,0 +1,290 @@
+/*
+ * 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.cocoon.maven.deployer.servlet;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextAttributeEvent;
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSessionActivationListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+/**
+ * This listener can be used as a wrapper around "real" listeners to
+ * support the shielded class loader.
+ *
+ * @version $Id$
+ */
+public class ShieldingListener
+    implements HttpSessionListener,
+               ServletContextListener,
+               HttpSessionActivationListener,
+               HttpSessionAttributeListener,
+               HttpSessionBindingListener,
+               ServletContextAttributeListener {
+
+    private static final String SERVLET_CONTEXT_CREATED = "CLC";
+
+    private static final String SERVLET_CONTEXT_DESTROYED = "CLD";
+
+    private static final String SESSION_CREATED = "SEC";
+
+    private static final String SESSION_DESTROYED = "SED";
+
+    private static final String SESSION_ACTIVATED = "SEAC";
+
+    private static final String SESSION_PASSIVATE = "SEDE";
+
+    private static final String VALUE_BOUND = "VB";
+
+    private static final String VALUE_UNBOUND = "VUB";
+
+    private static final String ATTR_REPLACED = "ARE";
+
+    private static final String ATTR_REMOVED = "ADE";
+
+    private static final String ATTR_ADDED = "AAD";
+
+    private static final String CONTEXT_ATTR_REPLACED = "CARE";
+
+    private static final String CONTEXT_ATTR_REMOVED = "CADE";
+
+    private static final String CONTEXT_ATTR_ADDED = "CAAD";
+
+    protected ClassLoader classloader;
+
+    protected List httpSessionListeners = new ArrayList();
+
+    protected List servletContextListeners = new ArrayList();
+
+    protected List httpSessionActivationListeners = new ArrayList();
+
+    protected List httpSessionBindingListeners = new ArrayList();
+
+    protected List servletContextAttributeListeners = new ArrayList();
+
+    protected List httpSessionAttributeListeners = new ArrayList();
+
+    protected void init(ServletContext context) {
+        // Get the classloader
+        try {
+            this.classloader = ShieldedClassLoaderManager.getClassLoader(context);
+        } catch (ServletException se) {
+            throw new RuntimeException("Unable to create bootstrap classloader.", se);
+        }
+
+        // Create the listeners
+        final ClassLoader old = Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(this.classloader);
+            final String listenersConfig = context.getInitParameter(ShieldingListener.class.getName());
+            if ( listenersConfig != null ) {
+                final StringTokenizer st = new StringTokenizer(listenersConfig, " \t\r\n\f;,", false);
+                while ( st.hasMoreTokens() ) {
+                    final String className = st.nextToken();
+                    try {
+                        ShieldedClassLoaderManager.logDebug(context, "ShieldingListener: Loading listener class " + className);
+                        Class listenerClass = this.classloader.loadClass(className);
+                        final Object listener = listenerClass.newInstance();
+                        if ( listener instanceof HttpSessionListener ) {
+                            this.httpSessionListeners.add(listener);
+                        }
+                        if ( listener instanceof ServletContextListener ) {
+                            this.servletContextListeners.add(listener);
+                        }
+                        if ( listener instanceof HttpSessionActivationListener ) {
+                            this.httpSessionActivationListeners.add(listener);
+                        }
+                        if ( listener instanceof HttpSessionAttributeListener ) {
+                            this.httpSessionAttributeListeners.add(listener);
+                        }
+                        if ( listener instanceof HttpSessionBindingListener ) {
+                            this.httpSessionBindingListeners.add(listener);
+                        }
+                        if ( listener instanceof ServletContextAttributeListener ) {
+                            this.servletContextAttributeListeners.add(listener);
+                        }
+                    } catch (Exception e) {
+                        throw new RuntimeException("Cannot load listener " + className, e);
+                    }
+                }
+            }
+        } finally {
+            Thread.currentThread().setContextClassLoader(old);
+        }
+    }
+
+    protected void invoke(List listeners, String identifier, Object event) {
+        if ( this.classloader != null ) {
+            final ClassLoader old = Thread.currentThread().getContextClassLoader();
+            try {
+                Thread.currentThread().setContextClassLoader(this.classloader);
+                final Iterator i = listeners.iterator();
+                while ( i.hasNext() ) {
+                    final Object listener = i.next();
+                    try {
+                        if ( ShieldingListener.SERVLET_CONTEXT_CREATED.equals(identifier) ) {
+                            ((ServletContextListener)listener).contextInitialized((ServletContextEvent)event);
+                        } else if ( ShieldingListener.SERVLET_CONTEXT_DESTROYED.equals(identifier) ) {
+                            ((ServletContextListener)listener).contextDestroyed((ServletContextEvent)event);                            
+                        } else if ( ShieldingListener.SESSION_CREATED.equals(identifier) ) {
+                            ((HttpSessionListener)listener).sessionCreated((HttpSessionEvent)event);                            
+                        } else if ( ShieldingListener.SESSION_DESTROYED.equals(identifier) ) {
+                            ((HttpSessionListener)listener).sessionDestroyed((HttpSessionEvent)event);                            
+                        } else if ( ShieldingListener.VALUE_BOUND.equals(identifier) ) {
+                            ((HttpSessionBindingListener)listener).valueBound((HttpSessionBindingEvent)event);                            
+                        } else if ( ShieldingListener.VALUE_UNBOUND.equals(identifier) ) {
+                            ((HttpSessionBindingListener)listener).valueUnbound((HttpSessionBindingEvent)event);                            
+                        } else if ( ShieldingListener.ATTR_ADDED.equals(identifier) ) {
+                            ((HttpSessionAttributeListener)listener).attributeAdded((HttpSessionBindingEvent)event);                            
+                        } else if ( ShieldingListener.ATTR_REMOVED.equals(identifier) ) {
+                            ((HttpSessionAttributeListener)listener).attributeRemoved((HttpSessionBindingEvent)event);                            
+                        } else if ( ShieldingListener.ATTR_REPLACED.equals(identifier) ) {
+                            ((HttpSessionAttributeListener)listener).attributeReplaced((HttpSessionBindingEvent)event);                            
+                        } else if ( ShieldingListener.CONTEXT_ATTR_ADDED.equals(identifier) ) {
+                            ((ServletContextAttributeListener)listener).attributeAdded((ServletContextAttributeEvent)event);                            
+                        } else if ( ShieldingListener.CONTEXT_ATTR_REMOVED.equals(identifier) ) {
+                            ((ServletContextAttributeListener)listener).attributeRemoved((ServletContextAttributeEvent)event);                            
+                        } else if ( ShieldingListener.CONTEXT_ATTR_REPLACED.equals(identifier) ) {
+                            ((ServletContextAttributeListener)listener).attributeReplaced((ServletContextAttributeEvent)event);                            
+                        } else if ( ShieldingListener.SESSION_ACTIVATED.equals(identifier) ) {
+                            ((HttpSessionActivationListener)listener).sessionDidActivate((HttpSessionEvent)event);                            
+                        } else if ( ShieldingListener.SESSION_PASSIVATE.equals(identifier) ) {
+                            ((HttpSessionActivationListener)listener).sessionWillPassivate((HttpSessionEvent)event);                            
+                        }
+                    } catch (Exception e) {
+                        throw new RuntimeException("Cannot invoke listener " + listener, e);
+                    }
+                }
+            } finally {
+                Thread.currentThread().setContextClassLoader(old);
+            }
+        }
+    }
+
+    /**
+     * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
+     */
+    public void contextDestroyed(ServletContextEvent contextEvent) {
+        this.invoke(this.servletContextListeners, ShieldingListener.SERVLET_CONTEXT_DESTROYED, contextEvent);
+    }
+
+    /**
+     * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
+     */
+    public void contextInitialized(ServletContextEvent contextEvent) {
+        final ServletContext context = contextEvent.getServletContext();
+        this.init(context);
+
+        this.invoke(this.servletContextListeners, ShieldingListener.SERVLET_CONTEXT_CREATED, contextEvent);
+    }
+    
+    /**
+     * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent)
+     */
+    public void sessionCreated(HttpSessionEvent event) {
+        this.invoke(this.httpSessionListeners, ShieldingListener.SESSION_CREATED, event);
+    }
+
+    /**
+     * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent)
+     */
+    public void sessionDestroyed(HttpSessionEvent event) {
+        this.invoke(this.httpSessionListeners, ShieldingListener.SESSION_DESTROYED, event);
+    }
+
+    /**
+     * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)
+     */
+    public void valueBound(HttpSessionBindingEvent event) {
+        this.invoke(this.httpSessionBindingListeners, ShieldingListener.VALUE_BOUND, event);
+    }
+
+    /**
+     * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)
+     */
+    public void valueUnbound(HttpSessionBindingEvent event) {
+        this.invoke(this.httpSessionBindingListeners, ShieldingListener.VALUE_UNBOUND, event);
+    }
+
+    /**
+     * @see javax.servlet.http.HttpSessionAttributeListener#attributeAdded(javax.servlet.http.HttpSessionBindingEvent)
+     */
+    public void attributeAdded(HttpSessionBindingEvent event) {
+        this.invoke(this.httpSessionAttributeListeners, ShieldingListener.ATTR_ADDED, event);
+    }
+
+    /**
+     * @see javax.servlet.http.HttpSessionAttributeListener#attributeRemoved(javax.servlet.http.HttpSessionBindingEvent)
+     */
+    public void attributeRemoved(HttpSessionBindingEvent event) {
+        this.invoke(this.httpSessionAttributeListeners, ShieldingListener.ATTR_REMOVED, event);
+    }
+
+    /**
+     * @see javax.servlet.http.HttpSessionAttributeListener#attributeReplaced(javax.servlet.http.HttpSessionBindingEvent)
+     */
+    public void attributeReplaced(HttpSessionBindingEvent event) {
+        this.invoke(this.httpSessionAttributeListeners, ShieldingListener.ATTR_REPLACED, event);
+    }
+
+    /**
+     * @see javax.servlet.http.HttpSessionActivationListener#sessionDidActivate(javax.servlet.http.HttpSessionEvent)
+     */
+    public void sessionDidActivate(HttpSessionEvent event) {
+        this.invoke(this.httpSessionActivationListeners, ShieldingListener.SESSION_ACTIVATED, event);
+    }
+
+    /**
+     * @see javax.servlet.http.HttpSessionActivationListener#sessionWillPassivate(javax.servlet.http.HttpSessionEvent)
+     */
+    public void sessionWillPassivate(HttpSessionEvent event) {
+        this.invoke(this.httpSessionActivationListeners, ShieldingListener.SESSION_PASSIVATE, event);
+    }
+
+    /**
+     * @see javax.servlet.ServletContextAttributeListener#attributeAdded(javax.servlet.ServletContextAttributeEvent)
+     */
+    public void attributeAdded(ServletContextAttributeEvent event) {
+        this.invoke(this.servletContextAttributeListeners, ShieldingListener.CONTEXT_ATTR_ADDED, event);
+    }
+
+    /**
+     * @see javax.servlet.ServletContextAttributeListener#attributeRemoved(javax.servlet.ServletContextAttributeEvent)
+     */
+    public void attributeRemoved(ServletContextAttributeEvent event) {
+        this.invoke(this.servletContextAttributeListeners, ShieldingListener.CONTEXT_ATTR_REMOVED, event);
+    }
+
+    /**
+     * @see javax.servlet.ServletContextAttributeListener#attributeReplaced(javax.servlet.ServletContextAttributeEvent)
+     */
+    public void attributeReplaced(ServletContextAttributeEvent event) {
+        this.invoke(this.servletContextAttributeListeners, ShieldingListener.CONTEXT_ATTR_REPLACED, event);
+    }
+}
\ No newline at end of file

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java?view=auto&rev=476226
==============================================================================
--- cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java (added)
+++ cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java Fri Nov 17 09:34:35 2006
@@ -0,0 +1,116 @@
+/*
+ * 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.cocoon.maven.deployer.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+
+/**
+ * This servlet builds a classloading sandbox and runs another servlet inside
+ * that sandbox. The purpose is to shield the libraries and classes shipped with
+ * the web application from any other classes with the same name that may exist
+ * in the system, such as Xerces and Xalan versions included in JDK 1.4.
+ * <p>
+ * This servlet propagates all initialisation parameters to the sandboxed
+ * servlet, and requires the parameter <code>servlet-class</code>.
+ * <ul>
+ * <li><code>servlet-class</code> defines the sandboxed servlet class.</li>
+ * </ul>
+ *
+ * @version $Id$
+ */
+public class ShieldingServlet extends HttpServlet {
+
+    protected Servlet servlet;
+
+    protected ClassLoader classloader;
+
+    /**
+     * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
+     */
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        // Get the classloader
+        this.classloader = ShieldedClassLoaderManager.getClassLoader(config.getServletContext());
+
+        String servletName = config.getInitParameter("servlet-class");
+        if (servletName == null) {
+            throw new ServletException("ShieldingServlet: Init-Parameter 'servlet-class' is missing.");
+        }
+        ShieldedClassLoaderManager.logDebug(config.getServletContext(),
+                                             "ShieldingServlet: Loading servlet class " + servletName);
+
+        // Create the servlet
+        try {
+
+            Class servletClass = this.classloader.loadClass(servletName);
+            this.servlet = (Servlet) servletClass.newInstance();
+
+        } catch (Exception e) {
+            throw new ServletException("Cannot load servlet " + servletName, e);
+        }
+
+        // Always set the context classloader. JAXP uses it to find a
+        // ParserFactory,
+        // and thus fails if it's not set to the webapp classloader.
+        final ClassLoader old = Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(this.classloader);
+
+            // Inlitialize the actual servlet
+            this.servlet.init(this.getServletConfig());
+        } finally {
+            Thread.currentThread().setContextClassLoader(old);
+        }
+
+    }
+
+    /**
+     * Service the request by delegating the call to the real servlet
+     */
+    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+        final ClassLoader old = Thread.currentThread().getContextClassLoader();
+        try {
+            Thread.currentThread().setContextClassLoader(this.classloader);
+            this.servlet.service(request, response);
+        } finally {
+            Thread.currentThread().setContextClassLoader(old);
+        }
+    }
+
+    /**
+     * Destroy the actual servlet
+     */
+    public void destroy() {
+        if (this.servlet != null) {
+            final ClassLoader old = Thread.currentThread().getContextClassLoader();
+            try {
+                Thread.currentThread().setContextClassLoader(this.classloader);
+                this.servlet.destroy();
+            } finally {
+                Thread.currentThread().setContextClassLoader(old);
+            }
+        }
+        super.destroy();
+    }
+}
\ No newline at end of file

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java?view=auto&rev=476226
==============================================================================
--- cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java (added)
+++ cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java Fri Nov 17 09:34:35 2006
@@ -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.cocoon.maven.deployer.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

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/tools/cocoon-block-deployer/cocoon-deployer-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java
------------------------------------------------------------------------------
    svn:keywords = Id