You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2011/09/19 10:59:18 UTC

svn commit: r1172526 - in /openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader: ./ filter/

Author: dblevins
Date: Mon Sep 19 08:59:17 2011
New Revision: 1172526

URL: http://svn.apache.org/viewvc?rev=1172526&view=rev
Log:
severely improve the scanning speed in embedded mode
full start/deploy/test/undeploy/stop is now about 3-4 seconds

Added:
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/EmbeddedJarScanner.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/UrlSet.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ClassFilter.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ContainsFilter.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ExcludeIncludeFilter.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filter.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/FilterList.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filters.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/IncludeExcludeFilter.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PackageFilter.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PatternFilter.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PrefixFilter.java
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/SuffixFilter.java
Modified:
    openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/TomEEJarScanner.java

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/EmbeddedJarScanner.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/EmbeddedJarScanner.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/EmbeddedJarScanner.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/EmbeddedJarScanner.java Mon Sep 19 08:59:17 2011
@@ -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.openejb.tomcat.loader;
+
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.JarScanner;
+import org.apache.tomcat.JarScannerCallback;
+import org.apache.tomcat.util.file.Matcher;
+import org.apache.tomcat.util.res.StringManager;
+import org.apache.tomcat.util.scan.Constants;
+
+import javax.servlet.ServletContext;
+import java.io.File;
+import java.io.IOException;
+import java.net.JarURLConnection;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class EmbeddedJarScanner implements JarScanner {
+
+    private static final Log log = LogFactory.getLog(EmbeddedJarScanner.class);
+
+    /**
+     * The string resources for this package.
+     */
+    private static final StringManager sm = StringManager.getManager(Constants.Package);
+
+    /**
+     * Scan the provided ServletContext and classloader for JAR files. Each JAR
+     * file found will be passed to the callback handler to be processed.
+     *
+     * @param context       The ServletContext - used to locate and access
+     *                      WEB-INF/lib
+     * @param classloader   The classloader - used to access JARs not in
+     *                      WEB-INF/lib
+     * @param callback      The handler to process any JARs found
+     * @param jarsToSkip    List of JARs to ignore. If this list is null, a
+     *                      default list will be read from the system property
+     *                      defined by {@link Constants#SKIP_JARS_PROPERTY}
+     */
+    @Override
+    public void scan(ServletContext context, ClassLoader classloader, JarScannerCallback callback, Set<String> jarsToSkip) {
+
+        try {
+            final UrlSet classpath = new UrlSet(classloader);
+            final UrlSet excluded = classpath.exclude(".*/WEB-INF/lib/.*");
+
+            final UrlSet scan = classpath.exclude(excluded);
+
+            for (URL url : scan) {
+                // Need to scan this JAR
+                if (log.isDebugEnabled()) {
+                    log.debug(sm.getString("jarScan.webinflibJarScan", url.toExternalForm()));
+                }
+
+                try {
+                    process(callback, url);
+                } catch (IOException e) {
+                    log.warn(sm.getString("jarScan.webinflibFail", url), e);
+                }
+            }
+        } catch (IOException e) {
+            log.warn(sm.getString("jarScan.classloaderFail", new URL[]{}), e);
+        }
+    }
+
+    /*
+     * Scan a URL for JARs with the optional extensions to look at all files
+     * and all directories.
+     */
+    private void process(JarScannerCallback callback, URL url)
+            throws IOException {
+
+        if (log.isTraceEnabled()) {
+            log.trace(sm.getString("jarScan.jarUrlStart", url));
+        }
+
+        final URLConnection conn = url.openConnection();
+
+        if (conn instanceof JarURLConnection) {
+
+            callback.scan((JarURLConnection) conn);
+
+        } else {
+
+            final String urlStr = url.toString();
+
+            if (urlStr.startsWith("file:") || urlStr.startsWith("jndi:")) {
+
+                if (urlStr.endsWith(Constants.JAR_EXT)) {
+
+                    final URL jarURL = new URL("jar:" + urlStr + "!/");
+                    callback.scan((JarURLConnection) jarURL.openConnection());
+
+                } else {
+
+                    try {
+
+                        final File f = new File(url.toURI());
+
+                        if (f.isFile()) {
+                            // Treat this file as a JAR
+                            final URL jarURL = new URL("jar:" + urlStr + "!/");
+                            callback.scan((JarURLConnection) jarURL.openConnection());
+
+                        } else if (f.isDirectory()) {
+
+                            final File metainf = new File(f.getAbsoluteFile() + File.separator + "META-INF");
+
+                            if (metainf.isDirectory()) {
+                                callback.scan(f);
+                            }
+                        }
+                    } catch (URISyntaxException e) {
+                        // Wrap the exception and re-throw
+                        IOException ioe = new IOException();
+                        ioe.initCause(e);
+                        throw ioe;
+                    }
+                }
+            }
+        }
+
+    }
+
+}

Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/TomEEJarScanner.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/TomEEJarScanner.java?rev=1172526&r1=1172525&r2=1172526&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/TomEEJarScanner.java (original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/TomEEJarScanner.java Mon Sep 19 08:59:17 2011
@@ -18,23 +18,39 @@
  */
 
 package org.apache.openejb.tomcat.loader;
-import java.io.File; 
-import java.util.HashSet; 
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 import javax.servlet.ServletContext;
-import org.apache.tomcat.JarScannerCallback; 
+
+import org.apache.openejb.tomcat.loader.filter.Filter;
+import org.apache.openejb.tomcat.loader.filter.Filters;
+import org.apache.tomcat.JarScannerCallback;
 import org.apache.tomcat.util.scan.StandardJarScanner;
 
 public class TomEEJarScanner extends StandardJarScanner {
 
 	public void scan(ServletContext context, ClassLoader classLoader, JarScannerCallback callback, Set<String> jarsToIgnore) {
 		String openejbWar = System.getProperty("openejb.war");
-		
+
+        if (openejbWar == null) {
+            EmbeddedJarScanner embeddedJarScanner = new EmbeddedJarScanner();
+            embeddedJarScanner.scan(context, classLoader, callback, jarsToIgnore);
+            return;
+        }
+
 		Set<String> newIgnores = new HashSet<String>();
 		if (jarsToIgnore != null) {
 			newIgnores.addAll(jarsToIgnore);
 		}
-		
+
 		if (openejbWar != null && "FragmentJarScannerCallback".equals(callback.getClass().getSimpleName())) {
 			File openejbApp = new File(openejbWar);
 			File libFolder = new File(openejbApp, "lib");
@@ -47,4 +63,280 @@ public class TomEEJarScanner extends Sta
 		
 		super.scan(context, classLoader, callback, newIgnores);
 	}
+
+    public static UrlSet applyBuiltinExcludes(UrlSet urlSet) throws MalformedURLException {
+
+        Filter filter = Filters.prefixes(
+                "XmlSchema-",
+                "activeio-",
+                "activemq-",
+                "antlr-",
+                "aopalliance-",
+                "avalon-framework-",
+                "axis-",
+                "axis2-",
+                "bcprov-",
+                "bsh-",
+                "bval-core",
+                "bval-jsr",
+                "catalina-",
+                "cglib-",
+                "commons-beanutils",
+                "commons-cli-",
+                "commons-codec-",
+                "commons-collections-",
+                "commons-dbcp",
+                "commons-dbcp-all-1.3-",
+                "commons-discovery-",
+                "commons-httpclient-",
+                "commons-io-",
+                "commons-lang-",
+                "commons-logging-",
+                "commons-logging-api-",
+                "commons-net-",
+                "commons-pool-",
+                "cssparser-",
+                "cxf-",
+                "deploy.jar",
+                "derby-",
+                "dom4j-",
+                "geronimo-",
+                "gragent.jar",
+                "guice-",
+                "hibernate-",
+                "howl-",
+                "hsqldb-",
+                "htmlunit-",
+                "icu4j-",
+                "idb-",
+                "idea_rt.jar",
+                "jasypt-",
+                "javaee-",
+                "javaee-api",
+                "javassist-",
+                "javaws.jar",
+                "javax.",
+                "jaxb-",
+                "jaxp-",
+                "jboss-",
+                "jbossall-",
+                "jbosscx-",
+                "jbossjts-",
+                "jbosssx-",
+                "jcommander-",
+                "jetty-",
+                "jmdns-",
+                "jsp-api-",
+                "jsr299-",
+                "jsr311-",
+                "juli-",
+                "junit-",
+                "kahadb-",
+                "log4j-",
+                "logkit-",
+                "myfaces-",
+                "neethi-",
+                "nekohtml-",
+                "openejb-api",
+                "openejb-javaagent",
+                "openejb-jee",
+                "openejb-loader",
+                "openjpa-",
+                "opensaml-",
+                "openwebbeans-",
+                "org.eclipse.",
+                "org.junit.",
+                "org.osgi.core-",
+                "quartz-",
+                "rmock-",
+                "saaj-",
+                "sac-",
+                "scannotation-",
+                "serializer-",
+                "serp-",
+                "servlet-api-",
+                "slf4j-",
+                "spring-",
+                "stax-api-",
+                "swizzle-",
+                "testng-",
+                "webbeans-ee",
+                "webbeans-ejb",
+                "webbeans-impl",
+                "webbeans-spi",
+                "wsdl4j-",
+                "wss4j-",
+                "wstx-asl-",
+                "xalan-",
+                "xbean-",
+                "xercesImpl-",
+                "xml-apis-",
+                "xml-resolver-",
+                "xmlrpc-",
+                "xmlsec-",
+                "xmlunit-",
+                "aether-api-",
+                "aether-connector-wagon-",
+                "aether-impl-",
+                "aether-spi-",
+                "aether-util-",
+                "arquillian-api-",
+                "arquillian-impl-base-",
+                "arquillian-junit-",
+                "arquillian-protocol-servlet-",
+                "arquillian-spi-",
+                "arquillian-testenricher-cdi-",
+                "arquillian-testenricher-ejb-",
+                "arquillian-testenricher-resource-",
+                "cdi-api-",
+                "commons-digester-",
+                "ecj-",
+                "google-collections-",
+                "jettison-",
+                "joda-time-",
+                "jsr250-api-",
+                "jstl-",
+                "maven-aether-provider-",
+                "maven-model-",
+                "maven-model-builder-",
+                "maven-repository-metadata-",
+                "maven-settings-",
+                "maven-settings-builder-",
+                "openws-",
+                "oro-",
+                "plexus-cipher-",
+                "plexus-classworlds-",
+                "plexus-component-annotations-",
+                "plexus-container-default-",
+                "plexus-interpolation-",
+                "plexus-sec-dispatcher-",
+                "plexus-utils-",
+                "shrinkwrap-api-",
+                "shrinkwrap-descriptors-api-",
+                "shrinkwrap-impl-base-",
+                "shrinkwrap-resolver-api-",
+                "shrinkwrap-resolver-api-maven-",
+                "shrinkwrap-resolver-impl-maven-",
+                "shrinkwrap-spi-",
+                "tomcat-annotations-api-",
+                "tomcat-api-",
+                "tomcat-catalina-",
+                "tomcat-coyote-",
+                "tomcat-el-api-",
+                "tomcat-jasper-",
+                "tomcat-jasper-el-",
+                "tomcat-jsp-api-",
+                "tomcat-juli-",
+                "tomcat-servlet-api-",
+                "tomcat-util-",
+                "velocity-",
+                "wagon-file-",
+                "wagon-http-lightweight-",
+                "wagon-http-shared-",
+                "wagon-provider-api-",
+                "woodstox-core-asl-",
+                "xmlschema-core-",
+                "xmltooling-"
+        );
+
+//        filter = Filters.optimize(filter, new PatternFilter(".*/openejb-.*"));
+        List<URL> urls = urlSet.getUrls();
+        Iterator<URL> iterator = urls.iterator();
+        while (iterator.hasNext()) {
+            URL url = iterator.next();
+            File file = toFile(url);
+
+            String name = filter(file).getName();
+//            System.out.println("JAR "+name);
+            if (filter.accept(name)) iterator.remove();
+        }
+
+
+
+        return new UrlSet(urls);
+    }
+
+    private static File filter(File location) {
+        List<String> invalid = new ArrayList<String>();
+        invalid.add("classes");
+        invalid.add("test-classes");
+        invalid.add("target");
+        invalid.add("build");
+        invalid.add("dist");
+        invalid.add("bin");
+
+        while (invalid.contains(location.getName())) {
+            location = location.getParentFile();
+        }
+        return location;
+    }
+
+        public static File toFile(URL url) {
+        if ("jar".equals(url.getProtocol())) {
+            try {
+                String spec = url.getFile();
+
+                int separator = spec.indexOf('!');
+                /*
+                 * REMIND: we don't handle nested JAR URLs
+                 */
+                if (separator == -1) throw new MalformedURLException("no ! found in jar url spec:" + spec);
+
+                return toFile(new URL(spec.substring(0, separator++)));
+            } catch (MalformedURLException e) {
+                throw new IllegalStateException(e);
+            }
+        } else if ("file".equals(url.getProtocol())) {
+            return new File(importme(url));
+        } else {
+            throw new IllegalArgumentException("Unsupported URL scheme: " + url.toExternalForm());
+        }
+    }
+
+    private static String importme(URL url) {
+        String fileName = url.getFile();
+        if (fileName.indexOf('%') == -1) return fileName;
+
+        StringBuilder result = new StringBuilder(fileName.length());
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        for (int i = 0; i < fileName.length();) {
+            char c = fileName.charAt(i);
+
+            if (c == '%') {
+                out.reset();
+                do {
+                    if (i + 2 >= fileName.length()) {
+                        throw new IllegalArgumentException("Incomplete % sequence at: " + i);
+                    }
+
+                    int d1 = Character.digit(fileName.charAt(i + 1), 16);
+                    int d2 = Character.digit(fileName.charAt(i + 2), 16);
+
+                    if (d1 == -1 || d2 == -1) {
+                        throw new IllegalArgumentException("Invalid % sequence (" + fileName.substring(i, i + 3) + ") at: " + String.valueOf(i));
+                    }
+
+                    out.write((byte) ((d1 << 4) + d2));
+
+                    i += 3;
+
+                } while (i < fileName.length() && fileName.charAt(i) == '%');
+
+
+                result.append(out.toString());
+
+                continue;
+            } else {
+                result.append(c);
+            }
+
+            i++;
+        }
+        return result.toString();
+    }
+
+    public static String toFilePath(URL url) {
+        return toFile(url).getAbsolutePath();
+    }
 }

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/UrlSet.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/UrlSet.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/UrlSet.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/UrlSet.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,220 @@
+/**
+ * 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.openejb.tomcat.loader;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.openejb.tomcat.loader.filter.Filter;
+import static org.apache.openejb.tomcat.loader.filter.Filters.invert;
+import static org.apache.openejb.tomcat.loader.filter.Filters.patterns;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class UrlSet implements Iterable<URL> {
+
+    private final Map<String,URL> urls;
+
+    public UrlSet(ClassLoader classLoader) throws IOException {
+        this(getUrls(classLoader));
+    }
+
+    public UrlSet(URL... urls){
+        this(Arrays.asList(urls));
+    }
+    /**
+     * Ignores all URLs that are not "jar" or "file"
+     * @param urls
+     */
+    public UrlSet(Collection<URL> urls){
+        this.urls = new HashMap<String,URL>();
+        for (URL location : urls) {
+            try {
+//                if (location.getProtocol().equals("file")) {
+//                    try {
+//                        // See if it's actually a jar
+//                        URL jarUrl = new URL("jar", "", location.toExternalForm() + "!/");
+//                        JarURLConnection juc = (JarURLConnection) jarUrl.openConnection();
+//                        juc.getJarFile();
+//                        location = jarUrl;
+//                    } catch (IOException e) {
+//                    }
+//                    this.urls.put(location.toExternalForm(), location);
+//                }
+                this.urls.put(location.toExternalForm(), location);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private UrlSet(Map<String, URL> urls) {
+        this.urls = urls;
+    }
+
+    public UrlSet include(UrlSet urlSet){
+        Map<String, URL> urls = new HashMap<String, URL>(this.urls);
+        urls.putAll(urlSet.urls);
+        return new UrlSet(urls);
+    }
+
+
+    public UrlSet include(URL url){
+        Map<String, URL> urls = new HashMap<String, URL>(this.urls);
+        urls.put(url.toExternalForm(), url);
+        return new UrlSet(urls);
+    }
+
+    public UrlSet exclude(UrlSet urlSet) {
+        Map<String, URL> urls = new HashMap<String, URL>(this.urls);
+        Map<String, URL> parentUrls = urlSet.urls;
+        for (String url : parentUrls.keySet()) {
+            urls.remove(url);
+        }
+        return new UrlSet(urls);
+    }
+
+    public UrlSet exclude(URL url) {
+        Map<String, URL> urls = new HashMap<String, URL>(this.urls);
+        urls.remove(url.toExternalForm());
+        return new UrlSet(urls);
+    }
+
+    public UrlSet exclude(ClassLoader parent) throws IOException {
+        return exclude(new UrlSet(parent));
+    }
+
+    public UrlSet exclude(File file) throws MalformedURLException {
+        return exclude(relative(file));
+    }
+
+    public UrlSet exclude(String pattern) throws MalformedURLException {
+        return filter(invert(patterns(pattern)));
+    }
+
+    /**
+     * Calls excludePaths(System.getProperty("java.ext.dirs"))
+     * @return
+     * @throws MalformedURLException
+     */
+    public UrlSet excludeJavaExtDirs() throws MalformedURLException {
+        String extDirs = System.getProperty("java.ext.dirs");
+        return extDirs == null ? this : excludePaths(extDirs);
+    }
+
+    /**
+     * Calls excludePaths(System.getProperty("java.endorsed.dirs"))
+     *
+     * @return
+     * @throws MalformedURLException
+     */
+    public UrlSet excludeJavaEndorsedDirs() throws MalformedURLException {
+        String endorsedDirs = System.getProperty("java.endorsed.dirs");
+        return endorsedDirs == null ? this : excludePaths(endorsedDirs);
+    }
+
+    public UrlSet excludeJavaHome() throws MalformedURLException {
+        String path = System.getProperty("java.home");
+
+        File java = new File(path);
+
+        if (path.matches("/System/Library/Frameworks/JavaVM.framework/Versions/[^/]+/Home")){
+            java = java.getParentFile();
+        }
+
+        return exclude(java);
+    }
+
+    public UrlSet excludePaths(String pathString) throws MalformedURLException {
+        String[] paths = pathString.split(File.pathSeparator);
+        UrlSet urlSet = this;
+        for (String path : paths) {
+            File file = new File(path);
+            urlSet = urlSet.exclude(file);
+        }
+        return urlSet;
+    }
+
+    public UrlSet filter(Filter filter) {
+        Map<String, URL> urls = new HashMap<String, URL>();
+        for (Map.Entry<String, URL> entry : this.urls.entrySet()) {
+            String url = entry.getKey();
+            if (filter.accept(url)){
+                urls.put(url, entry.getValue());
+            }
+        }
+        return new UrlSet(urls);
+    }
+
+    public UrlSet matching(String pattern) {
+        return filter(patterns(pattern));
+    }
+
+    public UrlSet relative(File file) throws MalformedURLException {
+        String urlPath = file.toURI().toURL().toExternalForm();
+        Map<String, URL> urls = new HashMap<String, URL>();
+        for (Map.Entry<String, URL> entry : this.urls.entrySet()) {
+            String url = entry.getKey();
+            if (url.startsWith(urlPath) || url.startsWith("jar:"+urlPath)){
+                urls.put(url, entry.getValue());
+            }
+        }
+        return new UrlSet(urls);
+    }
+
+    public List<URL> getUrls() {
+        return new ArrayList<URL>(urls.values());
+    }
+
+    public int size() {
+        return urls.size();
+    }
+
+    public Iterator<URL> iterator() {
+        return getUrls().iterator();
+    }
+
+    private static List<URL> getUrls(ClassLoader classLoader) throws IOException {
+        List<URL> list = new ArrayList<URL>();
+        ArrayList<URL> urls = Collections.list(classLoader.getResources("META-INF"));
+        for (URL url : urls) {
+            String externalForm = url.toExternalForm();
+            int i = externalForm.lastIndexOf("META-INF");
+            externalForm = externalForm.substring(0, i);
+            url = new URL(externalForm);
+            list.add(url);
+        }
+        list.addAll(Collections.list(classLoader.getResources("")));
+        return list;
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + "[" + urls.size() + "]";
+    }
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ClassFilter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ClassFilter.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ClassFilter.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ClassFilter.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,60 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ClassFilter implements Filter {
+
+    private final String name;
+
+    public ClassFilter(String name) {
+        assert name != null;
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean accept(String name) {
+        return this.name.equals(name);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ClassFilter that = (ClassFilter) o;
+
+        return name.equals(that.name);
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "ClassFilter{" +
+                "name='" + name + '\'' +
+                '}';
+    }
+}
\ No newline at end of file

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ContainsFilter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ContainsFilter.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ContainsFilter.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ContainsFilter.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,60 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ContainsFilter implements Filter {
+
+    private final String token;
+
+    public ContainsFilter(String token) {
+        assert token != null;
+        this.token = token;
+    }
+
+    public String getToken() {
+        return token;
+    }
+
+    public boolean accept(String name) {
+        return name.contains(token);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ContainsFilter that = (ContainsFilter) o;
+
+        return token.equals(that.token);
+    }
+
+    @Override
+    public int hashCode() {
+        return token.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "ContainsFilter{" +
+                "token='" + token + '\'' +
+                '}';
+    }
+}
\ No newline at end of file

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ExcludeIncludeFilter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ExcludeIncludeFilter.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ExcludeIncludeFilter.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/ExcludeIncludeFilter.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,43 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+/**
+ * First, all Exclude directives are evaluated; if any match, the className is denied unless it also matches an Include directive.
+ * Any classNames which do not match any Include or Exclude directives are permitted.
+ */
+public class ExcludeIncludeFilter implements Filter {
+
+    private final Filter include;
+    private final Filter exclude;
+
+    public ExcludeIncludeFilter(Filter include, Filter exclude) {
+        this.include = include;
+        this.exclude = exclude;
+    }
+
+    public boolean accept(String name) {
+        if (exclude.accept(name)) return include.accept(name);
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "Exclude." + exclude +
+                " Include." + include;
+    }
+}
\ No newline at end of file

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filter.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filter.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filter.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,24 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+/**
+* @version $Rev$ $Date$
+*/
+public interface Filter {
+    boolean accept(String name);
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/FilterList.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/FilterList.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/FilterList.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/FilterList.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,58 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class FilterList implements Filter {
+
+    private final List<Filter> filters = new ArrayList<Filter>();
+
+    public FilterList(Filter... filters) {
+        this(Arrays.asList(filters));
+    }
+
+    public FilterList(Iterable<Filter> filters) {
+        for (Filter filter : filters) {
+            this.filters.add(filter);
+        }
+    }
+
+    public boolean accept(String name) {
+        for (Filter filter : filters) {
+            if (filter.accept(name)) return true;
+        }
+
+        return false;
+    }
+
+    public List<Filter> getFilters() {
+        return filters;
+    }
+
+    @Override
+    public String toString() {
+        return "FilterList{" +
+                "filters=" + filters +
+                '}';
+    }
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filters.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filters.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filters.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/Filters.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,162 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class Filters {
+    private static final Filter NONE = new Filter() {
+        public boolean accept(String name) {
+            return false;
+        }
+    };
+
+    public static Filter packages(String... packages) {
+        List<Filter> filters = new ArrayList<Filter>();
+        for (String s : packages) {
+            filters.add(new PackageFilter(s));
+        }
+
+        return optimize(filters);
+    }
+
+    public static Filter classes(String... classes) {
+        List<Filter> filters = new ArrayList<Filter>();
+        for (String s : classes) {
+            filters.add(new ClassFilter(s));
+        }
+
+        return optimize(filters);
+    }
+
+    public static Filter prefixes(String... prefixes) {
+        List<Filter> filters = new ArrayList<Filter>();
+        for (String s : prefixes) {
+            filters.add(new PrefixFilter(s));
+        }
+
+        return optimize(filters);
+    }
+
+    public static Filter tokens(String... tokens) {
+        List<Filter> filters = new ArrayList<Filter>();
+        for (String s : tokens) {
+            filters.add(new ContainsFilter(s));
+        }
+
+        return optimize(filters);
+    }
+
+    public static Filter suffixes(String... suffixes) {
+        List<Filter> filters = new ArrayList<Filter>();
+        for (String s : suffixes) {
+            filters.add(new SuffixFilter(s));
+        }
+
+        return optimize(filters);
+    }
+
+    public static Filter patterns(String... patterns) {
+        List<Filter> filters = new ArrayList<Filter>();
+        for (String s : patterns) {
+            filters.add(new PatternFilter(s));
+        }
+
+        return optimize(filters);
+    }
+
+
+    public static Filter optimize(Filter... filters) {
+        return optimize(Arrays.asList(filters));
+    }
+
+    public static Filter optimize(List<Filter>... filterss) {
+        Set<Filter> unwrapped = new LinkedHashSet<Filter>();
+
+        for (List<Filter> filters : filterss) {
+            unwrap(filters, unwrapped);
+        }
+
+        if (unwrapped.size() > 1) {
+            Iterator<Filter> iterator = unwrapped.iterator();
+            while (iterator.hasNext()) {
+                Filter filter = iterator.next();
+                if (filter == NONE) iterator.remove();
+            }
+        }
+
+        if (unwrapped.size() == 0) return NONE;
+        if (unwrapped.size() == 1) return unwrapped.iterator().next();
+        return new FilterList(unwrapped);
+    }
+
+    /**
+     * Will invert the meaning of this filter by wrapping it with
+     * a filter that negates the return of the accept method.
+     *
+     * If the passed in filter is already wrapped, it will be
+     * unwrapped and returned.  This is to prevent endless wrapping
+     * if the invert method is called many times.
+     * 
+     * @param filter
+     * @return
+     */
+    public static Filter invert(Filter filter) {
+        if (filter instanceof NegativeFilter) {
+            NegativeFilter negativeFilter = (NegativeFilter) filter;
+            return negativeFilter.getFilter();
+        }
+
+        return new NegativeFilter(filter);
+    }
+
+    private static void unwrap(List<Filter> filters, Set<Filter> unwrapped) {
+        for (Filter filter : filters) {
+            if (filter instanceof FilterList) {
+                FilterList filterList = (FilterList) filter;
+                unwrap(filterList.getFilters(), unwrapped);
+            } else {
+                unwrapped.add(filter);
+            }
+        }
+    }
+
+    private static final class NegativeFilter implements Filter {
+        private final Filter filter;
+
+        public NegativeFilter(Filter filter) {
+            this.filter = filter;
+        }
+
+        public boolean accept(String name) {
+            return !filter.accept(name);
+        }
+
+        public Filter getFilter() {
+            return filter;
+        }
+    }
+
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/IncludeExcludeFilter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/IncludeExcludeFilter.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/IncludeExcludeFilter.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/IncludeExcludeFilter.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,44 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+/**
+ * First, all Include directives are evaluated; at least one must match, or the className is rejected.
+ * Next, all Exclude directives are evaluated. If any matches, the className is rejected.
+ * Last, any classNames which do not match an Include or a Exclude directive are denied by default.
+ */
+public class IncludeExcludeFilter implements Filter {
+
+    private Filter include;
+    private Filter exclude;
+
+    public IncludeExcludeFilter(Filter include, Filter exclude) {
+        this.include = include;
+        this.exclude = exclude;
+    }
+
+    public boolean accept(String name) {
+        if (include.accept(name)) return !exclude.accept(name);
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "Include." + include +
+                " Exclude." + exclude;
+    }
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PackageFilter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PackageFilter.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PackageFilter.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PackageFilter.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,61 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PackageFilter implements Filter {
+
+    private final String packageName;
+
+    public PackageFilter(String packageName) {
+        assert packageName != null;
+        if (!packageName.endsWith(".")) packageName += ".";
+        this.packageName = packageName;
+    }
+
+    public String getPackageName() {
+        return packageName;
+    }
+
+    public boolean accept(String name) {
+        return name.startsWith(packageName);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        PackageFilter that = (PackageFilter) o;
+
+        return packageName.equals(that.packageName);
+    }
+
+    @Override
+    public int hashCode() {
+        return packageName.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "PackageFilter{" +
+                "package='" + packageName + '\'' +
+                '}';
+    }
+}
\ No newline at end of file

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PatternFilter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PatternFilter.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PatternFilter.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PatternFilter.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,66 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+import java.util.regex.Pattern;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PatternFilter implements Filter {
+
+    private final Pattern pattern;
+
+    public PatternFilter(String expression) {
+        this(Pattern.compile(expression));
+    }
+
+    public PatternFilter(Pattern pattern) {
+        assert pattern != null;
+        this.pattern = pattern;
+    }
+
+    public Pattern getPattern() {
+        return pattern;
+    }
+
+    public boolean accept(String name) {
+        return pattern.matcher(name).matches();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        PatternFilter that = (PatternFilter) o;
+
+        return pattern.pattern().equals(that.pattern.pattern());
+    }
+
+    @Override
+    public int hashCode() {
+        return pattern.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "PatternFilter{" +
+                "pattern=" + pattern +
+                '}';
+    }
+}

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PrefixFilter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PrefixFilter.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PrefixFilter.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/PrefixFilter.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,60 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PrefixFilter implements Filter {
+
+    private final String prefix;
+
+    public PrefixFilter(String prefix) {
+        assert prefix != null;
+        this.prefix = prefix;
+    }
+
+    public String getPrefix() {
+        return prefix;
+    }
+
+    public boolean accept(String name) {
+        return name.startsWith(prefix);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        PrefixFilter that = (PrefixFilter) o;
+
+        return prefix.equals(that.prefix);
+    }
+
+    @Override
+    public int hashCode() {
+        return prefix.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "PrefixFilter{" +
+                "prefix='" + prefix + '\'' +
+                '}';
+    }
+}
\ No newline at end of file

Added: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/SuffixFilter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/SuffixFilter.java?rev=1172526&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/SuffixFilter.java (added)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-loader/src/main/java/org/apache/openejb/tomcat/loader/filter/SuffixFilter.java Mon Sep 19 08:59:17 2011
@@ -0,0 +1,60 @@
+/**
+ * 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.openejb.tomcat.loader.filter;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class SuffixFilter implements Filter {
+
+    private final String suffix;
+
+    public SuffixFilter(String suffix) {
+        assert suffix != null;
+        this.suffix = suffix;
+    }
+
+    public String getSuffix() {
+        return suffix;
+    }
+
+    public boolean accept(String name) {
+        return name.endsWith(suffix);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        SuffixFilter that = (SuffixFilter) o;
+
+        return suffix.equals(that.suffix);
+    }
+
+    @Override
+    public int hashCode() {
+        return suffix.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "SuffixFilter{" +
+                "suffix='" + suffix + '\'' +
+                '}';
+    }
+}
\ No newline at end of file