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