You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by re...@apache.org on 2007/05/01 13:35:27 UTC
svn commit: r534014 [2/3] - in /cocoon/trunk/tools/cocoon-maven-plugin: ./
src/ src/changes/ src/main/java/org/apache/cocoon/maven/deployer/
src/main/java/org/apache/cocoon/maven/deployer/monolithic/
src/main/java/org/apache/cocoon/maven/deployer/servl...
Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java?view=auto&rev=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java (added)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java Tue May 1 04:35:26 2007
@@ -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-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoader.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java?view=auto&rev=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java (added)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java Tue May 1 04:35:26 2007
@@ -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-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldedClassLoaderManager.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java?view=auto&rev=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java (added)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java Tue May 1 04:35:26 2007
@@ -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-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingListener.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java?view=auto&rev=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java (added)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java Tue May 1 04:35:26 2007
@@ -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-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServlet.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java?view=auto&rev=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java (added)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java Tue May 1 04:35:26 2007
@@ -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-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/servlet/ShieldingServletFilter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/CopyUtils.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/CopyUtils.java?view=auto&rev=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/CopyUtils.java (added)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/CopyUtils.java Tue May 1 04:35:26 2007
@@ -0,0 +1,39 @@
+/*
+ * 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.utils;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.io.IOUtils;
+
+/**
+ * @version $Id$
+ */
+public class CopyUtils {
+ public static void copy( InputStream is, OutputStream os ) throws IOException {
+ try {
+ IOUtils.copy(is, os);
+ } finally {
+ IOUtils.closeQuietly(is);
+ IOUtils.closeQuietly(os);
+ }
+ }
+}
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/CopyUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/CopyUtils.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/CopyUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/FileUtils.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/FileUtils.java?view=auto&rev=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/FileUtils.java (added)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/FileUtils.java Tue May 1 04:35:26 2007
@@ -0,0 +1,38 @@
+/*
+ * 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.utils;
+
+import java.io.File;
+
+/**
+ * Utitily class to handle ZIP archives.
+ *
+ * @version $Id$
+ */
+public class FileUtils {
+ /**
+ * Prepare directory structure for non-existing file
+ */
+ public static File createPath(File file) {
+ if ( file.getParentFile() != null && !file.getParentFile().exists())
+ file.getParentFile().mkdirs();
+ return file;
+ }
+
+
+
+}
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/FileUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/FileUtils.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/FileUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/WildcardHelper.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/WildcardHelper.java?view=auto&rev=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/WildcardHelper.java (added)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/WildcardHelper.java Tue May 1 04:35:26 2007
@@ -0,0 +1,383 @@
+/*
+ * 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.utils;
+
+import java.util.HashMap;
+
+/**
+ * This class is an utility class that perform wilcard-patterns matching and
+ * isolation.
+ *
+ * Copy from cocoon-core.
+ *
+ * @version $Id$
+ */
+public class WildcardHelper {
+
+ /** The int representing '*' in the pattern <code>int []</code>. */
+ protected static final int MATCH_FILE = -1;
+ /** The int representing '**' in the pattern <code>int []</code>. */
+ protected static final int MATCH_PATH = -2;
+ /** The int representing begin in the pattern <code>int []</code>. */
+ protected static final int MATCH_BEGIN = -4;
+ /** The int representing end in pattern <code>int []</code>. */
+ protected static final int MATCH_THEEND = -5;
+ /** The int value that terminates the pattern <code>int []</code>. */
+ protected static final int MATCH_END = -3;
+
+
+ /**
+ * Translate the given <code>String</code> into a <code>int []</code>
+ * representing the pattern matchable by this class.
+ * <br>
+ * This function translates a <code>String</code> into an int array
+ * converting the special '*' and '\' characters.
+ * <br>
+ * Here is how the conversion algorithm works:
+ * <ul>
+ * <li>The '*' character is converted to MATCH_FILE, meaning that zero
+ * or more characters (excluding the path separator '/') are to
+ * be matched.</li>
+ * <li>The '**' sequence is converted to MATCH_PATH, meaning that zero
+ * or more characters (including the path separator '/') are to
+ * be matched.</li>
+ * <li>The '\' character is used as an escape sequence ('\*' is
+ * translated in '*', not in MATCH_FILE). If an exact '\' character
+ * is to be matched the source string must contain a '\\'.
+ * sequence.</li>
+ * </ul>
+ * When more than two '*' characters, not separated by another character,
+ * are found their value is considered as '**' (MATCH_PATH).
+ * <br>
+ * The array is always terminated by a special value (MATCH_END).
+ * <br>
+ * All MATCH* values are less than zero, while normal characters are equal
+ * or greater.
+ *
+ * @param data The string to translate.
+ * @return The encoded string as an int array, terminated by the MATCH_END
+ * value (don't consider the array length).
+ * @exception NullPointerException If data is null.
+ */
+ public static int[] compilePattern(String data)
+ throws NullPointerException {
+
+ // Prepare the arrays
+ int expr[] = new int[data.length() + 2];
+ char buff[] = data.toCharArray();
+
+ // Prepare variables for the translation loop
+ int y = 0;
+ boolean slash = false;
+
+ // Must start from beginning
+ expr[y++] = MATCH_BEGIN;
+
+ if (buff.length > 0) {
+ if (buff[0]=='\\') {
+ slash = true;
+ } else if (buff[0] == '*') {
+ expr[y++] = MATCH_FILE;
+ } else {
+ expr[y++] = buff[0];
+ }
+
+ // Main translation loop
+ for (int x = 1; x < buff.length; x++) {
+ // If the previous char was '\' simply copy this char.
+ if (slash) {
+ expr[y++] = buff[x];
+ slash = false;
+ // If the previous char was not '\' we have to do a bunch of checks
+ } else {
+ // If this char is '\' declare that and continue
+ if (buff[x] == '\\') {
+ slash = true;
+ // If this char is '*' check the previous one
+ } else if (buff[x] == '*') {
+ // If the previous character als was '*' match a path
+ if (expr[y-1] <= MATCH_FILE) {
+ expr[y-1] = MATCH_PATH;
+ } else {
+ expr[y++] = MATCH_FILE;
+ }
+ } else {
+ expr[y++]=buff[x];
+ }
+ }
+ }
+ }
+
+ // Must match end at the end
+ expr[y] = MATCH_THEEND;
+ return expr;
+ }
+
+ /**
+ * match a pattern agains a string and isolates wildcard replacement into a
+ * <code>Stack</code>.
+ */
+ public static boolean match (HashMap map, String data, int[] expr)
+ throws NullPointerException {
+ if (data == null) {
+ throw new NullPointerException ("No data provided");
+ }
+ if (expr == null) {
+ throw new NullPointerException ("No pattern expression provided");
+ }
+
+
+ char buff[] = data.toCharArray();
+ // Allocate the result buffer
+ char rslt[] = new char[expr.length + buff.length];
+
+
+ // The previous and current position of the expression character
+ // (MATCH_*)
+ int charpos = 0;
+
+ // The position in the expression, input, translation and result arrays
+ int exprpos = 0;
+ int buffpos = 0;
+ int rsltpos = 0;
+ int offset = -1;
+
+ // The matching count
+ int mcount = 0;
+
+ if ( map != null ) {
+ // We want the complete data be in {0}
+ map.put(Integer.toString(mcount),data);
+ }
+
+ // First check for MATCH_BEGIN
+ boolean matchBegin = false;
+ if (expr[charpos] == MATCH_BEGIN) {
+ matchBegin = true;
+ exprpos = ++charpos;
+ }
+
+ // Search the fist expression character (except MATCH_BEGIN - already skipped)
+ while (expr[charpos] >= 0)
+ charpos++;
+
+ // The expression charater (MATCH_*)
+ int exprchr = expr[charpos];
+
+ while (true) {
+ // Check if the data in the expression array before the current
+ // expression character matches the data in the input buffer
+ if (matchBegin) {
+ if (!matchArray(expr, exprpos, charpos, buff, buffpos))
+ return (false);
+ matchBegin = false;
+ } else {
+ offset = indexOfArray (expr, exprpos, charpos, buff,
+ buffpos);
+ if (offset < 0)
+ return (false);
+ }
+
+ // Check for MATCH_BEGIN
+ if (matchBegin) {
+ if (offset != 0)
+ return (false);
+ matchBegin = false;
+ }
+
+ // Advance buffpos
+ buffpos += (charpos - exprpos);
+
+ // Check for END's
+ if (exprchr == MATCH_END) {
+ if (rsltpos > 0 && map != null) {
+ map.put(Integer.toString(++mcount),new String(rslt, 0, rsltpos));
+ }
+ // Don't care about rest of input buffer
+ return (true);
+ } else if (exprchr == MATCH_THEEND) {
+ if (rsltpos > 0 && map != null ) {
+ map.put (Integer.toString(++mcount),new String(rslt, 0, rsltpos));
+ }
+ // Check that we reach buffer's end
+ return (buffpos == buff.length);
+ }
+
+ // Search the next expression character
+ exprpos = ++charpos;
+ while (expr[charpos] >= 0)
+ charpos++;
+ int prevchr = exprchr;
+ exprchr = expr[charpos];
+
+ // We have here prevchr == * or **.
+ offset = (prevchr == MATCH_FILE) ?
+ indexOfArray (expr, exprpos, charpos, buff, buffpos) :
+ lastIndexOfArray (expr, exprpos, charpos, buff,
+ buffpos);
+
+ if (offset < 0)
+ return (false);
+
+ // Copy the data from the source buffer into the result buffer
+ // to substitute the expression character
+ if (prevchr == MATCH_PATH) {
+ while (buffpos < offset)
+ rslt[rsltpos++] = buff[buffpos++];
+ } else {
+ // Matching file, don't copy '/'
+ while (buffpos < offset) {
+ if (buff[buffpos] == '/')
+ return (false);
+ rslt[rsltpos++] = buff[buffpos++];
+ }
+ }
+
+ if ( map != null ) {
+ map.put(Integer.toString(++mcount),new String (rslt, 0, rsltpos));
+ }
+ rsltpos = 0;
+ }
+ }
+
+ /**
+ * Get the offset of a part of an int array within a char array.
+ * <br>
+ * This method return the index in d of the first occurrence after dpos of
+ * that part of array specified by r, starting at rpos and terminating at
+ * rend.
+ *
+ * @param r The array containing the data that need to be matched in d.
+ * @param rpos The index of the first character in r to look for.
+ * @param rend The index of the last character in r to look for plus 1.
+ * @param d The array of char that should contain a part of r.
+ * @param dpos The starting offset in d for the matching.
+ * @return The offset in d of the part of r matched in d or -1 if that was
+ * not found.
+ */
+ protected static int indexOfArray (int r[], int rpos, int rend,
+ char d[], int dpos) {
+ // Check if pos and len are legal
+ if (rend < rpos)
+ throw new IllegalArgumentException ("rend < rpos");
+ // If we need to match a zero length string return current dpos
+ if (rend == rpos)
+ return (d.length); //?? dpos?
+ // If we need to match a 1 char length string do it simply
+ if ((rend - rpos) == 1) {
+ // Search for the specified character
+ for (int x = dpos; x < d.length; x++)
+ if (r[rpos] == d[x])
+ return (x);
+ }
+ // Main string matching loop. It gets executed if the characters to
+ // match are less then the characters left in the d buffer
+ while ((dpos + rend - rpos) <= d.length) {
+ // Set current startpoint in d
+ int y = dpos;
+ // Check every character in d for equity. If the string is matched
+ // return dpos
+ for (int x = rpos; x <= rend; x++) {
+ if (x == rend)
+ return (dpos);
+ if (r[x] != d[y++])
+ break;
+ }
+ // Increase dpos to search for the same string at next offset
+ dpos++;
+ }
+ // The remaining chars in d buffer were not enough or the string
+ // wasn't matched
+ return (-1);
+ }
+
+ /**
+ * Get the offset of a last occurance of an int array within a char array.
+ * <br>
+ * This method return the index in d of the last occurrence after dpos of
+ * that part of array specified by r, starting at rpos and terminating at
+ * rend.
+ *
+ * @param r The array containing the data that need to be matched in d.
+ * @param rpos The index of the first character in r to look for.
+ * @param rend The index of the last character in r to look for plus 1.
+ * @param d The array of char that should contain a part of r.
+ * @param dpos The starting offset in d for the matching.
+ * @return The offset in d of the last part of r matched in d or -1 if that was
+ * not found.
+ */
+ protected static int lastIndexOfArray (int r[], int rpos, int rend,
+ char d[], int dpos) {
+ // Check if pos and len are legal
+ if (rend < rpos)
+ throw new IllegalArgumentException ("rend < rpos");
+ // If we need to match a zero length string return current dpos
+ if (rend == rpos)
+ return (d.length); //?? dpos?
+
+ // If we need to match a 1 char length string do it simply
+ if ((rend - rpos) == 1) {
+ // Search for the specified character
+ for (int x = d.length - 1; x > dpos; x--)
+ if (r[rpos] == d[x])
+ return (x);
+ }
+
+ // Main string matching loop. It gets executed if the characters to
+ // match are less then the characters left in the d buffer
+ int l = d.length - (rend - rpos);
+ while (l >= dpos) {
+ // Set current startpoint in d
+ int y = l;
+ // Check every character in d for equity. If the string is matched
+ // return dpos
+ for (int x = rpos; x <= rend; x++) {
+ if (x == rend)
+ return (l);
+ if (r[x] != d[y++])
+ break;
+ }
+ // Decrease l to search for the same string at next offset
+ l--;
+ }
+ // The remaining chars in d buffer were not enough or the string
+ // wasn't matched
+ return (-1);
+ }
+
+ /**
+ * Matches elements of array r from rpos to rend with array d, starting from dpos.
+ * <br>
+ * This method return true if elements of array r from rpos to rend
+ * equals elements of array d starting from dpos to dpos+(rend-rpos).
+ *
+ * @param r The array containing the data that need to be matched in d.
+ * @param rpos The index of the first character in r to look for.
+ * @param d The array of char that should start from a part of r.
+ * @param dpos The starting offset in d for the matching.
+ * @return true if array d starts from portion of array r.
+ */
+ protected static boolean matchArray (int r[], int rpos, int rend,
+ char d[], int dpos) {
+ if (d.length - dpos < rend - rpos)
+ return (false);
+ for (int i = rpos; i < rend; i++)
+ if (r[i] != d[dpos++])
+ return (false);
+ return (true);
+ }
+}
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/WildcardHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/WildcardHelper.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/WildcardHelper.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/XMLUtils.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/XMLUtils.java?view=auto&rev=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/XMLUtils.java (added)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/XMLUtils.java Tue May 1 04:35:26 2007
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.maven.deployer.utils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * @version $Id$
+ */
+public class XMLUtils {
+
+ public static Document parseXml(InputStream source) throws IOException, SAXException {
+ try {
+ DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
+ documentFactory.setNamespaceAware(true);
+ documentFactory.setValidating(false);
+ DocumentBuilder docBuilder = documentFactory.newDocumentBuilder();
+ // Parse using the local dtds instead of remote dtds. This
+ // allows to deploy the application offline
+ docBuilder.setEntityResolver(new EntityResolver() {
+ public InputSource resolveEntity(String publicId, String systemId) throws SAXException,
+ java.io.IOException {
+ if (systemId.equals("http://java.sun.com/dtd/web-app_2_3.dtd")) {
+ return new InputSource(getClass().getResourceAsStream("web-app_2_3.dtd"));
+ }
+ return null;
+ }
+ });
+
+ return docBuilder.parse(source);
+ } catch (ParserConfigurationException pce) {
+ throw new IOException("Creating document failed:" + pce.getMessage());
+ }
+ }
+
+ public static void write(Document node, OutputStream out) throws TransformerFactoryConfigurationError, TransformerException {
+ final Properties format = new Properties();
+ format.put(OutputKeys.METHOD, "xml");
+ format.put(OutputKeys.OMIT_XML_DECLARATION, "no");
+ format.put(OutputKeys.INDENT, "yes");
+ if (node.getDoctype() != null) {
+ if (node.getDoctype().getPublicId() != null) {
+ format.put(OutputKeys.DOCTYPE_PUBLIC, node.getDoctype().getPublicId());
+ }
+ if (node.getDoctype().getSystemId() != null) {
+ format.put(OutputKeys.DOCTYPE_SYSTEM, node.getDoctype().getSystemId());
+ }
+ }
+ Transformer transformer;
+ transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperties(format);
+ transformer.transform(new DOMSource(node), new StreamResult(out));
+ }
+
+ public static List getChildNodes(Element parent, String nodeName) {
+ final List nodes = new ArrayList();
+ if (parent != null && nodeName != null) {
+ final NodeList children = parent.getChildNodes();
+ if (children != null) {
+ for (int i = 0; i < children.getLength(); i++) {
+ if (nodeName.equals(children.item(i).getLocalName())) {
+ nodes.add(children.item(i));
+ }
+ }
+ }
+ }
+ return nodes;
+ }
+
+ public static Element getChildNode(Element parent, String nodeName) {
+ final List children = getChildNodes(parent, nodeName);
+ if (children.size() > 0) {
+ return (Element) children.get(0);
+ }
+
+ return null;
+ }
+
+ public static String getValue(Element node) {
+ if (node != null) {
+ if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+ return node.getNodeValue();
+ } else {
+ node.normalize();
+ NodeList childs = node.getChildNodes();
+ int i = 0;
+ int length = childs.getLength();
+ while (i < length) {
+ if (childs.item(i).getNodeType() == Node.TEXT_NODE) {
+ return childs.item(i).getNodeValue().trim();
+ } else {
+ i++;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public static void setValue(Element node, String value) {
+ if (node != null) {
+ // remove all children
+ while (node.hasChildNodes()) {
+ node.removeChild(node.getFirstChild());
+ }
+ node.appendChild(node.getOwnerDocument().createTextNode(value));
+ }
+ }
+}
\ No newline at end of file
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/XMLUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/XMLUtils.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/deployer/utils/XMLUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/ReloadingWebappMojo.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/ReloadingWebappMojo.java?view=diff&rev=534014&r1=533959&r2=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/ReloadingWebappMojo.java (original)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/ReloadingWebappMojo.java Tue May 1 04:35:26 2007
@@ -23,9 +23,12 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
+import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -36,6 +39,7 @@
import java.util.Set;
import org.antlr.stringtemplate.StringTemplate;
+import org.apache.cocoon.maven.deployer.AbstractDeployMojo;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
@@ -56,7 +60,7 @@
import org.apache.maven.project.artifact.MavenMetadataSource;
/**
- * @goal webapp
+ * @goal rcl
* @requiresProject true
* @requiresDependencyResolution runtime
* @execute phase="process-classes"
@@ -210,7 +214,10 @@
createSpringProperties(webAppBaseDir, props);
// based on the RCL configuration file, create a Cocoon properties file
- createCocoonProperties(webAppBaseDir, props);
+ createCocoonProperties(webAppBaseDir, props);
+
+ // apply xpatch files
+ applyXpatchFiles(webAppBaseDir, props);
}
@@ -318,6 +325,36 @@
log4jTemplateMap.put("useSocketAppender", new Boolean(this.useSocketAppender));
writeStringTemplateToFile(webAppBaseDir, WEB_INF_LOG4J, customLog4jXconf, log4jTemplateMap);
}
+
+
+ private void applyXpatchFiles(File webAppBaseDir, RwmProperties props) throws MojoExecutionException {
+ // find all xpatch files in all configured blocks
+ Set classesDirs = props.getClassesDirs();
+ File[] allXPatchFiles = new File[0];
+ for(Iterator it = classesDirs.iterator(); it.hasNext();) {
+ String f = RwmProperties.calcRootDir((String) it.next());
+ try {
+ File f1 = new File(new File(new URI(f)), "src/main/resources/META-INF/cocoon/xpatch");
+ File[] xmlFiles = f1.listFiles(new FilenameFilter() {
+ public boolean accept(File d, String name) {
+ return name.toLowerCase().endsWith(".xweb");
+ }
+ });
+ if(xmlFiles != null) {
+ File[] mergedArray = new File[allXPatchFiles.length + xmlFiles.length];
+ System.arraycopy(allXPatchFiles, 0, mergedArray, 0, allXPatchFiles.length);
+ System.arraycopy(xmlFiles, 0, mergedArray, allXPatchFiles.length, xmlFiles.length);
+ allXPatchFiles = mergedArray;
+ }
+ } catch (URISyntaxException e) {
+ }
+ }
+
+ Map libs = AbstractDeployMojo.getBlockArtifactsAsMap(this.project, this.getLog());
+ AbstractDeployMojo.xpatch(libs, allXPatchFiles, webAppBaseDir, this.getLog());
+ }
+
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ utility methods ~~~~~~~~~~
protected Set getDependencies(final String groupId, final String artifactId, final String version,
final String packaging) throws MojoExecutionException {
@@ -398,7 +435,6 @@
protected InputStream readResourceFromClassloader(String fileName) {
String resource = ReloadingWebappMojo.class.getPackage().getName().replace('.', '/') + "/" + fileName;
- System.out.println("Reading resource from classpath: " + resource);
return ReloadingWebappMojo.class.getClassLoader().getResourceAsStream(resource);
}
Modified: cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/RwmProperties.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/RwmProperties.java?view=diff&rev=534014&r1=533959&r2=534014
==============================================================================
--- cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/RwmProperties.java (original)
+++ cocoon/trunk/tools/cocoon-maven-plugin/src/main/java/org/apache/cocoon/maven/rcl/RwmProperties.java Tue May 1 04:35:26 2007
@@ -113,11 +113,7 @@
" property can only point to a directory that ends with " + TARGET_CLASSES_DIR + ".");
}
- // path calculation
- if(path.endsWith("/")) {
- path = path.substring(0, path.length() - 1);
- }
- path = path.substring(0, path.length() - "target/classes".length());
+ path = calcRootDir(path);
String newKey = key.substring(0, key.length() - CLASSES_DIR.length()) + BLOCK_CONTEXT_URL_PARAM;
springProps.put(newKey, path + COB_INF_DIR);
@@ -130,6 +126,15 @@
}
return springProps;
+ }
+
+ public static String calcRootDir(String path) {
+ // path calculation
+ if(path.endsWith("/")) {
+ path = path.substring(0, path.length() - 1);
+ }
+ path = path.substring(0, path.length() - "target/classes".length());
+ return path;
}
public Properties getCocoonProperties() {