You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by gt...@apache.org on 2011/07/21 22:32:06 UTC

svn commit: r1149346 - in /river/jtsk/skunk/surrogate: src/org/apache/river/container/classloading/ test/org/apache/river/container/classloading/

Author: gtrasuk
Date: Thu Jul 21 20:32:02 2011
New Revision: 1149346

URL: http://svn.apache.org/viewvc?rev=1149346&view=rev
Log:
Surrogate classloading work - Finished writing a VirtualFileSystemClassLoader that can:
1 - Use jar files that are packed inside another archive (jar-within-jar)
2 - Filter those jar files so that only certain resources are available from them, e.g.
 container.jar(org.apache.container.liaison.ContainerLiaison) would serve only the ContainerLiaison class from that jar file.  This prevents having to create a whole other jar
when we want to allow one or two 'container' classes to be in a child classloader, e.g. to
simplify configuration.

Added:
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Acceptor.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/AllAcceptor.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathEntry.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ResourceAcceptor.java
Modified:
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ASTNode.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathExpressionParser.jjt
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilter.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilterBuilder.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Strings.java
    river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/VirtualFileSystemClassLoader.java
    river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/ClasspathFilterParserTest.java
    river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/VFSClassLoaderTest.java

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ASTNode.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ASTNode.java?rev=1149346&r1=1149345&r2=1149346&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ASTNode.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ASTNode.java Thu Jul 21 20:32:02 2011
@@ -48,7 +48,8 @@ public class ASTNode extends SimpleNode 
     }
 
     public String toString() {
-        if (id==ClasspathExpressionParserTreeConstants.JJTSYMBOL) {
+        if (id==ClasspathExpressionParserTreeConstants.JJTSYMBOL
+                || id==ClasspathExpressionParserTreeConstants.JJTSTRINGLITERAL) {
             return getValue().toString();
         }
         String childList = childList();

Added: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Acceptor.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Acceptor.java?rev=1149346&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Acceptor.java (added)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Acceptor.java Thu Jul 21 20:32:02 2011
@@ -0,0 +1,27 @@
+/*
+ * 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.river.container.classloading;
+
+/**
+ *
+ * @author trasukg
+ */
+public interface Acceptor {
+    public boolean acceptsResource(String resourcePath);
+}

Added: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/AllAcceptor.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/AllAcceptor.java?rev=1149346&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/AllAcceptor.java (added)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/AllAcceptor.java Thu Jul 21 20:32:02 2011
@@ -0,0 +1,35 @@
+/*
+ * 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.river.container.classloading;
+
+/**
+ *
+ * @author trasukg
+ */
+public class AllAcceptor implements Acceptor {
+
+    public boolean acceptsClass(String className) {
+        return true;
+    }
+
+    public boolean acceptsResource(String resourcePath) {
+        return true;
+    }
+
+}

Added: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathEntry.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathEntry.java?rev=1149346&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathEntry.java (added)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathEntry.java Thu Jul 21 20:32:02 2011
@@ -0,0 +1,49 @@
+/*
+ * 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.river.container.classloading;
+
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystemException;
+
+/**
+ * A ClassPathEntry is used by the VirtualFileSystemClassLoader, and is a
+ combination of a ClasspathFilter and the fileObject that points to the entry's
+ jar file.  It effectively represents an entry like 'container.jar(org.apache.ABC)',
+ which would mean 'the class org.apache.ABC contained inside the jar file
+ container.jar'.  The idea is to include selected packages from a jar file on the
+ classpath,
+ * @author trasukg
+ */
+public class ClasspathEntry {
+    private ClasspathFilter classpathFilter=null;
+
+    private FileObject fileObject=null;
+
+    public ClasspathEntry(ClasspathFilter filter, FileObject fileObject) {
+        this.fileObject=fileObject;
+        this.classpathFilter=filter;
+    }
+
+    public FileObject resolveFile(String name) throws FileSystemException {
+        if ((classpathFilter.acceptsResource(name))) {
+            return fileObject.resolveFile(name);
+        }
+        return null;
+    }
+}

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathExpressionParser.jjt
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathExpressionParser.jjt?rev=1149346&r1=1149345&r2=1149346&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathExpressionParser.jjt (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathExpressionParser.jjt Thu Jul 21 20:32:02 2011
@@ -57,6 +57,33 @@ TOKEN :
 {
   	< SYMBOL:
 		["A"-"Z", "a"-"z", "_"] (["0"-"9", "A"-"Z", "a"-"z", ".", "_"])*>
+|	< STRING_LITERAL:
+ 	("\""
+    (   (~["\"","\\","\n","\r"])
+        | ("\\"
+            ( ["n","t","b","r","f","\\","'","\""]
+            | ["0"-"7"] ( ["0"-"7"] )?
+            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+            )
+          )
+      )*
+      "\"" )
+	| ("\'"
+    	(   (~["'","\\","\n","\r"])
+        | ("\\"
+            ( ["n","t","b","r","f","\\","'","\""]
+            | ["0"-"7"] ( ["0"-"7"] )?
+            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+            )
+          )
+      )*
+      "\'") >
+		{
+			/* Remove the leading and trailing quotes. */
+			image.deleteCharAt(image.length() -1);
+			image.deleteCharAt(0);
+			matchedToken.image=image.toString();
+		}
 |  	< COMMA: "," >
 |       < LPAREN: "(" >
 |       < RPAREN: ")" >
@@ -83,7 +110,7 @@ void filterClause():
     log.fine("filterClause()");
 }
 {
-    symbol()
+    symbol() | stringLiteral()
 }
 
 
@@ -98,4 +125,15 @@ void symbol() #symbol:
         }
 }
 
+void stringLiteral() #stringLiteral:
+{
+        log.fine("stringLiteral()");
+        Token t=null;
+}
+{
+        t=<STRING_LITERAL> {
+            jjtThis.setValue(t.image);
+        }
+}
+
 

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilter.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilter.java?rev=1149346&r1=1149345&r2=1149346&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilter.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilter.java Thu Jul 21 20:32:02 2011
@@ -15,7 +15,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.river.container.classloading;
 
 import java.util.ArrayList;
@@ -26,25 +25,32 @@ import java.util.List;
  * @author trasukg
  */
 public class ClasspathFilter {
-    private String jarName=null;
+
+    private String jarName = null;
 
     void setJarName(String s) {
-        jarName=s;
+        jarName = s;
     }
 
     public String getJarName() {
         return jarName;
     }
+    List<Acceptor> acceptors = new ArrayList<Acceptor>();
 
-    List<String> acceptConditions=new ArrayList<String>();
-
-    public List<String> getAcceptConditions() {
-        return acceptConditions;
+    public List<Acceptor> getAcceptors() {
+        return acceptors;
     }
 
-    public boolean acceptsClass(String className) {
-        for (String s:acceptConditions ) {
-            if (s.equals(className)) {
+    /**
+    Returns true if this filter accepts the given resource path.
+    Resource path is in the form '/META-INF/ABC.xyz'
+    @param resourcePath
+    @return
+     */
+    public boolean acceptsResource(String resourcePath) {
+
+        for (Acceptor a : getAcceptors()) {
+            if (a.acceptsResource(resourcePath)) {
                 return true;
             }
         }

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilterBuilder.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilterBuilder.java?rev=1149346&r1=1149345&r2=1149346&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilterBuilder.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ClasspathFilterBuilder.java Thu Jul 21 20:32:02 2011
@@ -19,6 +19,7 @@ package org.apache.river.container.class
 
 import java.io.Reader;
 import java.io.StringReader;
+import java.util.logging.Logger;
 import org.apache.river.container.LocalizedRuntimeException;
 import org.apache.river.container.MessageNames;
 
@@ -27,6 +28,7 @@ import org.apache.river.container.Messag
  * @author trasukg
  */
 public class ClasspathFilterBuilder {
+    private static final Logger log=Logger.getLogger(ClasspathFilterBuilder.class.getName());
 
     public ClasspathFilter parseToFilter(String input) {
         try {
@@ -40,7 +42,24 @@ public class ClasspathFilterBuilder {
             ClasspathFilter cpf = new ClasspathFilter();
             cpf.setJarName(expression.jjtGetChild(0).toString());
             for (int i=1; i<expression.jjtGetNumChildren(); i++) {
-                cpf.getAcceptConditions().add(expression.jjtGetChild(i).toString());
+                Node node=expression.jjtGetChild(i);
+                if (node instanceof ASTsymbol) {
+                    String resourceName=VirtualFileSystemClassLoader.classToResourceName(node.toString());
+                    log.info("Building ResourceAcceptor with string '" + resourceName + "'");
+                    Acceptor acc=new ResourceAcceptor(resourceName);
+                    cpf.getAcceptors().add(acc);
+                }
+                if (node instanceof ASTstringLiteral) {
+                    log.info("Building ResourceAcceptor with string '" + node.toString() + "'");
+                    Acceptor acc=new ResourceAcceptor(node.toString());
+                    cpf.getAcceptors().add(acc);
+                }
+            }
+            /* If there were no filter clauses, hence no acceptors, allow all
+             patterns.
+             */
+            if (cpf.getAcceptors().isEmpty()) {
+                cpf.getAcceptors().add(new AllAcceptor());
             }
             return cpf;
         } catch (ParseException ex) {

Added: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ResourceAcceptor.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ResourceAcceptor.java?rev=1149346&view=auto
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ResourceAcceptor.java (added)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/ResourceAcceptor.java Thu Jul 21 20:32:02 2011
@@ -0,0 +1,92 @@
+/*
+ * 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.river.container.classloading;
+
+import java.util.Arrays;
+import org.apache.river.container.Utils;
+
+/**
+ *
+ * @author trasukg
+ */
+public class ResourceAcceptor implements Acceptor {
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final ResourceAcceptor other = (ResourceAcceptor) obj;
+        if (!Arrays.deepEquals(this.pathSteps, other.pathSteps)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 7;
+        hash = 37 * hash + Arrays.deepHashCode(this.pathSteps);
+        return hash;
+    }
+
+    String[] pathSteps=null;
+
+    public ResourceAcceptor(String resourcePath) {
+        pathSteps=resourcePath.split(Strings.SLASH);
+    }
+
+    public boolean acceptsResource(String resourcePath) {
+        /* A better programmer would use regular expressions here.
+         But then he would have two problems...
+         */
+        String[] inputPathSteps=resourcePath.split(Strings.SLASH);
+        int inputIndex=0, pathStepIndex=0;
+        for (;;) {
+            /* Hit the end of both paths at the same time. */
+            if (inputIndex==inputPathSteps.length && pathStepIndex==pathSteps.length) {
+                return true;
+            }
+            /* End of one path but not the other. */
+            if (inputIndex==inputPathSteps.length || pathStepIndex==pathSteps.length) {
+                return false;
+            }
+            if (pathSteps[pathStepIndex].equals(inputPathSteps[inputIndex])) {
+                pathStepIndex++;
+                inputIndex++;
+                continue;
+            }
+            if (Strings.STAR.equals(pathSteps[pathStepIndex])) {
+                pathStepIndex++;
+                inputIndex++;
+                continue;
+            }
+            else {
+                return false;
+            }
+        }
+    }
+
+    public String toString() {
+        return "ResourceAcceptor(" + Utils.format(pathSteps) + ")";
+    }
+}

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Strings.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Strings.java?rev=1149346&r1=1149345&r2=1149346&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Strings.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/Strings.java Thu Jul 21 20:32:02 2011
@@ -24,6 +24,8 @@ package org.apache.river.container.class
  */
 public class Strings {
     public static final String
+            DOT=".",
+            DOT_CLASS=".class",
             EMPTY="",
             GET_NAME="getName",
             GET_VALUE="getValue",
@@ -34,5 +36,7 @@ public class Strings {
             JJTSYMBOL="JJTSYMBOL",
             LPAREN="(",
             RPAREN=")",
-            SPACE=" ";
+            SLASH="/",
+            SPACE=" ",
+            STAR="*";
 }

Modified: river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/VirtualFileSystemClassLoader.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/VirtualFileSystemClassLoader.java?rev=1149346&r1=1149345&r2=1149346&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/VirtualFileSystemClassLoader.java (original)
+++ river/jtsk/skunk/surrogate/src/org/apache/river/container/classloading/VirtualFileSystemClassLoader.java Thu Jul 21 20:32:02 2011
@@ -30,7 +30,7 @@ import org.apache.commons.vfs.FileSystem
 import org.apache.commons.vfs.FileUtil;
 import org.apache.river.container.LocalizedRuntimeException;
 import org.apache.river.container.MessageNames;
-import org.apache.river.container.Strings;
+
 
 /**
  *
@@ -40,23 +40,31 @@ public class VirtualFileSystemClassLoade
 
     private FileObject fileSystemRoot=null;
 
-    private List<FileObject> classpathFileObjects=new ArrayList<FileObject>();
+    private List<ClasspathEntry> classpathEntries=new ArrayList<ClasspathEntry>();
 
     public VirtualFileSystemClassLoader(FileObject fileSystemRoot, ClassLoader parent) {
         super(new URL[0], parent);
         this.fileSystemRoot=fileSystemRoot;
     }
 
+    public static String classToResourceName(String name) {
+        String resourceName = name.replace(Strings.DOT, Strings.SLASH).concat(Strings.DOT_CLASS);
+        return resourceName;
+    }
+
     void addClassPathEntry(String fileName) {
         try {
-            /* Classpath entry is a jar file. */
+            /* Classpath entry is a jar file with filter expressions that can
+             be understood by ClasspathFilterBuilder. */
             /* Create a nested file system from it and add it to the file objects.
              */
-            FileObject entryObject = fileSystemRoot.resolveFile(fileName);
+            ClasspathFilter filter=new ClasspathFilterBuilder().parseToFilter(fileName);
+
+            FileObject entryObject = fileSystemRoot.resolveFile(filter.getJarName());
             FileObject entryFileSystem=
                     fileSystemRoot.getFileSystem().getFileSystemManager()
                     .createFileSystem(entryObject);
-            classpathFileObjects.add(entryFileSystem);
+            classpathEntries.add(new ClasspathEntry(filter, entryFileSystem));
         } catch (FileSystemException ex) {
             throw new LocalizedRuntimeException(ex, MessageNames.BUNDLE_NAME, MessageNames.INVALID_CLASSPATH_ENTRY, fileName);
         }
@@ -85,9 +93,9 @@ public class VirtualFileSystemClassLoade
      @return
      */
     public FileObject findResourceFileObject(String name) {
-        for (FileObject cpFileSys:classpathFileObjects) {
+        for (ClasspathEntry cpEntry:classpathEntries) {
             try {
-                FileObject fo = cpFileSys.resolveFile(name);
+                FileObject fo = cpEntry.resolveFile(name);
                 if (fo!=null &&fo.isReadable()) {
                     return fo;
                 }
@@ -100,7 +108,7 @@ public class VirtualFileSystemClassLoade
 
     @Override
     protected Class<?> findClass(String name) throws ClassNotFoundException {
-        String resourceName=name.replace(Strings.DOT, Strings.SLASH).concat(Strings.DOT_CLASS);
+        String resourceName=classToResourceName(name);
         FileObject resourceFileObject=findResourceFileObject(resourceName);
         if (resourceFileObject==null) {
             throw new ClassNotFoundException(name+"(" + resourceName + ")");

Modified: river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/ClasspathFilterParserTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/ClasspathFilterParserTest.java?rev=1149346&r1=1149345&r2=1149346&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/ClasspathFilterParserTest.java (original)
+++ river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/ClasspathFilterParserTest.java Thu Jul 21 20:32:02 2011
@@ -17,7 +17,9 @@
  */
 package org.apache.river.container.classloading;
 
+import java.util.logging.Logger;
 import java.util.List;
+import java.util.logging.Level;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -36,6 +38,7 @@ public class ClasspathFilterParserTest {
 
     @BeforeClass
     public static void setUpClass() throws Exception {
+        Logger.getLogger(ClasspathFilterBuilder.class.getName()).setLevel(Level.ALL);
     }
 
     @AfterClass
@@ -60,9 +63,9 @@ public class ClasspathFilterParserTest {
         ClasspathFilterBuilder UUT = new ClasspathFilterBuilder();
         ClasspathFilter cpf = UUT.parseToFilter("reggie.jar(org.apache.Abc)");
         assertEquals("reggie.jar", cpf.getJarName());
-        List<String> actual = cpf.getAcceptConditions();
+        List<Acceptor> actual = cpf.getAcceptors();
         assertEquals("Wrong number of filter clauses.", 1, actual.size());
-        assertEquals("Filter condition", "org.apache.Abc", actual.get(0));
+        assertEquals("Filter condition", new ResourceAcceptor("org/apache/Abc.class"), actual.get(0));
     }
 
     /**
@@ -76,26 +79,30 @@ public class ClasspathFilterParserTest {
         String jarSpec = "reggie.jar(org.apache.ABC, org.apache.DEF)";
         ClasspathFilter cpf = UUT.parseToFilter(jarSpec);
         assertEquals("reggie.jar", cpf.getJarName());
-        List<String> actual = cpf.getAcceptConditions();
+        List<Acceptor> actual = cpf.getAcceptors();
         assertEquals("Wrong number of filter clauses.", 2, actual.size());
-        assertEquals("Filter condition", "org.apache.ABC", actual.get(0));
-        assertEquals("Filter condition", "org.apache.DEF", actual.get(1));
+        assertEquals("Filter condition", new ResourceAcceptor("org/apache/ABC.class"), actual.get(0));
+        assertEquals("Filter condition", new ResourceAcceptor("org/apache/DEF.class"), actual.get(1));
     }
 
     /**
     Does basic test on parsing of the jar specification.
-    Syntax is name.jar(classToServe).
+    Syntax is name.jar(classToServe[,filter]*).
+     If the filter clause is a double-quoted string, then it represents
+     a resource filter rather than a class filter (i.e. it specifies an actual
+     resource in the jar file rather than a class description.
     @throws Exception
      */
     @Test
     public void testFilterAcceptance() throws Exception {
         ClasspathFilterBuilder UUT = new ClasspathFilterBuilder();
-        String jarSpec = "reggie.jar(org.apache.ABC, org.apache.DEF)";
+        String jarSpec = "reggie.jar(org.apache.ABC, org.apache.DEF, \"META-INF/*\")";
         ClasspathFilter cpf = UUT.parseToFilter(jarSpec);
         assertEquals("reggie.jar", cpf.getJarName());
-        assertTrue(cpf.acceptsClass("org.apache.ABC"));
-        assertFalse(cpf.acceptsClass("org.apache.XYZ"));
-        assertTrue(cpf.acceptsClass("org.apache.DEF"));
+        assertTrue(cpf.acceptsResource("org/apache/ABC.class"));
+        assertFalse(cpf.acceptsResource("org/apache/XYZ.class"));
+        assertTrue(cpf.acceptsResource("org/apache/DEF.class"));
+        assertTrue(cpf.acceptsResource("META-INF/start.properties"));
     }
 
     /**
@@ -108,8 +115,8 @@ public class ClasspathFilterParserTest {
         String jarSpec = "reggie.jar";
         ClasspathFilter cpf = UUT.parseToFilter(jarSpec);
         assertEquals("reggie.jar", cpf.getJarName());
-        assertTrue(cpf.acceptsClass("org.apache.ABC"));
-        assertTrue(cpf.acceptsClass("org.apache.XYZ"));
-        assertTrue(cpf.acceptsClass("org.apache.DEF"));
-    }
+        assertTrue(cpf.acceptsResource("org/apache/ABC.class"));
+        assertTrue(cpf.acceptsResource("org/apache/XYZ.class"));
+        assertTrue(cpf.acceptsResource("org/apache/DEF.class"));
+     }
 }

Modified: river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/VFSClassLoaderTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/VFSClassLoaderTest.java?rev=1149346&r1=1149345&r2=1149346&view=diff
==============================================================================
--- river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/VFSClassLoaderTest.java (original)
+++ river/jtsk/skunk/surrogate/test/org/apache/river/container/classloading/VFSClassLoaderTest.java Thu Jul 21 20:32:02 2011
@@ -192,6 +192,13 @@ public class VFSClassLoaderTest {
         Class classMapperClass=UUT.loadClass("com.sun.jini.reggie.ClassMapper");
         assertNotNull("loaded class was null", classMapperClass);
 
-        fail("Finish writing the can'tload case");
+        try {
+
+            Class eventLeaseClass=UUT.loadClass("com.sun.jini.reggie.EventLease");
+            assertNull("loaded class was null", eventLeaseClass);
+            fail("Really shouldn't have gotten to here!");
+        } catch(Exception ex) {
+            
+        }
     }
 }