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

svn commit: r1187214 - in /river/jtsk/skunk/peterConcurrentPolicy: src/net/jini/security/policy/ src/org/apache/river/api/security/ src/org/apache/river/impl/security/policy/util/ test/src/org/apache/river/api/security/ test/src/org/apache/river/impl/s...

Author: peter_firmstone
Date: Fri Oct 21 08:32:35 2011
New Revision: 1187214

URL: http://svn.apache.org/viewvc?rev=1187214&view=rev
Log:
Added inversion to PermissionGrant interface, removed Exclusion interface and Deny implementation.  Inversion allows implementation of Denial in policy provider, rather than directly by the PermissionGrant.  Added CodeSourceSetGrant, which allows grant's to apply to a number of CodeSource's, to assist implementation of undocumented java policy file features.

Added:
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java
      - copied, changed from r1178328, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java
Removed:
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/Deny.java
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/Exclusion.java
Modified:
    river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/ConcurrentPolicyFile.java
    river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/DynamicPolicyProvider.java
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CertificateGrant.java
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilderImp.java
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ProtectionDomainGrant.java
    river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java
    river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/CodeSourceGrantTest.java
    river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/PrincipalGrantTest.java
    river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/ConcurrentPolicyFile.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/ConcurrentPolicyFile.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/ConcurrentPolicyFile.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/ConcurrentPolicyFile.java Fri Oct 21 08:32:35 2011
@@ -258,13 +258,14 @@ public class ConcurrentPolicyFile extend
          * will be current and copy them, but the Enumeration returned
          * by Permissions will instead throw a ConcurrentModificationException.
          */
-        if (pd == null) return new Permissions();
+        //if (pd == null) return new Permissions();
         /* When write lock holds thread it will already have this lock
          * allowing priviledged domain security checks to be performed.
          */
         rl.lock();
         try {
-            PermissionCollection perms = impliesCache.get(pd);
+            PermissionCollection perms = 
+                    pd != null ? impliesCache.get(pd): null;
             if (perms != null) return perms;
             perms = new ConcurrentPermissions();
                 Iterator<PermissionGrant> it = grants.iterator();
@@ -289,7 +290,7 @@ public class ConcurrentPolicyFile extend
                     }
                 }
             }
-            impliesCache.put(pd, perms); //Overwrite older.
+            if (pd != null) impliesCache.put(pd, perms); //Overwrite older.
             return perms;
         }finally{
             rl.unlock();

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/DynamicPolicyProvider.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/DynamicPolicyProvider.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/DynamicPolicyProvider.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/net/jini/security/policy/DynamicPolicyProvider.java Fri Oct 21 08:32:35 2011
@@ -511,7 +511,7 @@ Put the policy providers and all referen
         }
 	if (permission == null) throw new NullPointerException("permission not allowed to be null");
         // First check our cache if the basePolicy is not dynamic.
-        PermissionCollection pc = cache.get(domain);
+        PermissionCollection pc = domain != null? cache.get(domain): null;
         if ( pc != null ) {
             if (pc.implies(permission)) return true;           
         } else {
@@ -544,7 +544,8 @@ Put the policy providers and all referen
 	    * PolicyUtils method defensively copies or creates new if null.
 	    */
             pc = PolicyUtils.asConcurrent(bpc);
-            PermissionCollection existed = cache.putIfAbsent(domain, pc); 
+            PermissionCollection existed = 
+                    domain != null ? cache.putIfAbsent(domain, pc): null; 
             if ( existed != null ){
                 pc = existed;
             }
@@ -615,7 +616,7 @@ Put the policy providers and all referen
 	Iterator<PermissionGrant> i = dynamicPolicyGrants.iterator();
         while (i.hasNext()){
             PermissionGrant p = i.next();
-            if (p.isVoid(null)){
+            if (p.isVoid()){
                 remove.add(p);
             }
         }

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CertificateGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CertificateGrant.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CertificateGrant.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CertificateGrant.java Fri Oct 21 08:32:35 2011
@@ -38,15 +38,12 @@ import java.util.List;
  */
 class CertificateGrant extends PrincipalGrant {
     private static final long serialVersionUID = 1L;
-    private static final Exclusion nullEx = new NullExclusion();
     private final Collection<Certificate> certs;
     private final int hashCode;
-    private final Exclusion exclusion;
     @SuppressWarnings("unchecked")
     CertificateGrant(Certificate[] codeSourceCerts, Principal[] pals, 
-                                    Permission[] perms, Exclusion deny){
-        super(pals, perms);
-        exclusion = deny != null ? deny : nullEx;
+                                    Permission[] perms, boolean inverse){
+        super(pals, perms, inverse);
          if (codeSourceCerts == null || codeSourceCerts.length == 0) {
             certs = Collections.EMPTY_SET;
         }else{
@@ -87,7 +84,6 @@ class CertificateGrant extends Principal
             sb.append(it.next().toString())
               .append("\n");
         }
-        sb.append(exclusion.toString());
         return sb.toString();
     }
     
@@ -95,7 +91,6 @@ class CertificateGrant extends Principal
     public boolean implies(ProtectionDomain pd) {
         // File policy grant compatibility, different behaviour to dynamic grants.
         if (pd == null) return false; 
-        if ( exclusion.excludes(pd)) return false;
 	CodeSource c = null;
 	Principal[] pals = null;
 	if (pd != null){
@@ -141,12 +136,5 @@ class CertificateGrant extends Principal
             throws InvalidObjectException{
         throw new InvalidObjectException("PermissionGrantBuilder required");
     }
-    
-    private static class NullExclusion implements Exclusion{
 
-        public boolean excludes(ProtectionDomain pd) {
-            return false;
-        }
-        
-    }
 }

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java Fri Oct 21 08:32:35 2011
@@ -34,8 +34,8 @@ class CodeSourceGrant extends Certificat
     private final int hashCode;
     
     @SuppressWarnings("unchecked")
-    CodeSourceGrant(CodeSource cs, Principal[] pals, Permission[] perm, Exclusion exclusion){
-        super( cs != null? cs.getCertificates(): null, pals, perm, exclusion);
+    CodeSourceGrant(CodeSource cs, Principal[] pals, Permission[] perm, boolean inverse ){
+        super( cs != null? cs.getCertificates(): null, pals, perm, inverse);
         this.cs = cs != null? normalizeCodeSource(cs) : null;
         int hash = 3;
         hash = 67 * hash + (this.cs != null ? this.cs.hashCode() : 0);
@@ -73,6 +73,15 @@ class CodeSourceGrant extends Certificat
                  .toString();
     }
     
+    @Override
+    public boolean implies(ClassLoader cl, Principal[] p){
+	if ( !implies(p)) return false;
+	if ( cs == null ) return true;
+	if ( cl == null ) return false;
+	return false;  //Indeterminate.
+    }
+    
+    
     /**
      * Checks if passed CodeSource matches this PermissionGrant. Null CodeSource of
      * PermissionGrant implies any CodeSource; non-null CodeSource forwards to its
@@ -86,7 +95,7 @@ class CodeSourceGrant extends Certificat
         if ( codeSource == null ) return false; 
 	if ( cs == null || nullCS.equals(cs)) return true;
 	return cs.implies(normalizeCodeSource(codeSource));
-    }
+        }
 
     @Override
     public PermissionGrantBuilder getBuilderTemplate() {

Copied: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java (from r1178328, river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java)
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java?p2=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java&p1=river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java&r1=1178328&r2=1187214&rev=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceGrant.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/CodeSourceSetGrant.java Fri Oct 21 08:32:35 2011
@@ -23,21 +23,32 @@ import java.io.ObjectInputStream;
 import java.security.CodeSource;
 import java.security.Permission;
 import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
 
 /**
  *
  * @author Peter Firmstone
  */
-class CodeSourceGrant extends CertificateGrant {
+class CodeSourceSetGrant extends CertificateGrant {
     private static final long serialVersionUID = 1L;
-    private final CodeSource cs;
+    private final Set<CodeSource> cs;
     private final int hashCode;
     
     @SuppressWarnings("unchecked")
-    CodeSourceGrant(CodeSource cs, Principal[] pals, Permission[] perm, Exclusion exclusion){
-        super( cs != null? cs.getCertificates(): null, pals, perm, exclusion);
-        this.cs = cs != null? normalizeCodeSource(cs) : null;
+    CodeSourceSetGrant(CodeSource[] csource, Principal[] pals, Permission[] perm, boolean inverse){
+        super( null, pals, perm, inverse);
+        int l = csource == null ? 0 : csource.length;
+        Set<CodeSource> set = new HashSet<CodeSource>(l);
         int hash = 3;
+        for (int i = 0 ; i < l ; i++ ){
+            if ( csource[i] == null) 
+                throw new NullPointerException("CodeSource array must not contain null values");
+            set.add(normalizeCodeSource(csource[i]));
+        }
+        cs = Collections.unmodifiableSet(set);
         hash = 67 * hash + (this.cs != null ? this.cs.hashCode() : 0);
         hash = 67 * hash + (super.hashCode());
         hashCode = hash;
@@ -53,8 +64,8 @@ class CodeSourceGrant extends Certificat
         if (o == null) return false;
         if (o == this) return true;
 	if (o.hashCode() != this.hashCode()) return false;
-        if (o instanceof CodeSourceGrant){
-            CodeSourceGrant c = (CodeSourceGrant) o;
+        if (o instanceof CodeSourceSetGrant){
+            CodeSourceSetGrant c = (CodeSourceSetGrant) o;
             if ( !super.equals(o)) return false;
 	    if ( cs == c.cs) return true;
 	    if ( cs != null ) {
@@ -73,6 +84,15 @@ class CodeSourceGrant extends Certificat
                  .toString();
     }
     
+    @Override
+    public boolean implies(ClassLoader cl, Principal[] p){
+	if ( !implies(p)) return false;
+	if ( cs == null || cs.isEmpty() ) return true;
+	if ( cl == null ) return false;
+	return false;  //Indeterminate.
+    }
+    
+    
     /**
      * Checks if passed CodeSource matches this PermissionGrant. Null CodeSource of
      * PermissionGrant implies any CodeSource; non-null CodeSource forwards to its
@@ -85,14 +105,22 @@ class CodeSourceGrant extends Certificat
         // see com.sun.jini.test.spec.policyprovider.dynamicPolicyProvider.GrantPrincipal test.
         if ( codeSource == null ) return false; 
 	if ( cs == null || nullCS.equals(cs)) return true;
-	return cs.implies(normalizeCodeSource(codeSource));
+        Iterator<CodeSource> it = cs.iterator();
+        while (it.hasNext()){
+            if  (it.next().implies(normalizeCodeSource(codeSource))) return true;
+        }
+        return false;
     }
 
     @Override
     public PermissionGrantBuilder getBuilderTemplate() {
         PermissionGrantBuilder pgb = super.getBuilderTemplate();
-        pgb.codeSource(cs)
-           .context(PermissionGrantBuilder.CODESOURCE);
+        pgb.multipleCodeSources();
+        Iterator<CodeSource> it = cs.iterator();
+        while (it.hasNext()){
+            pgb.codeSource(it.next());
+        }
+        pgb.context(PermissionGrantBuilder.CODESOURCE);
         return pgb;
     }
     

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrant.java Fri Oct 21 08:32:35 2011
@@ -35,6 +35,21 @@ import java.util.Collection;
  * @author Peter Firmstone
  */
 public interface PermissionGrant {
+    
+    /**
+     * If true, the PermissionGrant is said to be inverse, so if it implies
+     * a ProtectionDomain and is inverse then that ProtectionDomain must be
+     * denied any Permission implied by any inverse PermissionGrant.
+     * 
+     * Inverse PermissionGrant's must be checked first by the policy, before
+     * checking any normal PermissionGrant.
+     * 
+     * All Permissions contained by an inverse PermissionGrant's must be 
+     * grouped by implied ProtectionDomain's and stored in PermissionCollections.
+     * 
+     * @return
+     */
+    boolean inverse();
 
     /**
      * A DynamicPolicy implementation can use a PermissionGrant as a container
@@ -90,9 +105,9 @@ public interface PermissionGrant {
      * Returns true if this PermissionGrant defines no Permissions, or if
      * a PermissionGrant was made to a ProtectionDomain that no longer exists,
      * or if the Exclusion excludes the PermissionGrant.
-     * @param excl 
+     * 
      */
-    public boolean isVoid(Exclusion excl);
+    public boolean isVoid();
     
     /**
      * Provide a suitable PermissionGrantBuilder, the user can use to

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilder.java Fri Oct 21 08:32:35 2011
@@ -85,7 +85,17 @@ public abstract class PermissionGrantBui
      * resets the state for reuse, identical to a newly created 
      * PermissionGrantBuilder.
      */
-    public abstract void reset();
+    public abstract PermissionGrantBuilder reset();
+    
+    /**
+     * If supported, the grant created will be inverse, in other words a deny.
+     * 
+     * Any ProtectionDomain implied will be denied the contained permissions 
+     * and any other Permissions they imply.
+     * 
+     * @return
+     */
+    public abstract PermissionGrantBuilder inverse();
     /**
      * Sets the context of the PermissionGrant to on of the static final 
      * fields in this class.
@@ -101,6 +111,8 @@ public abstract class PermissionGrantBui
      * @return PermissionGrantBuilder
      */
     public abstract PermissionGrantBuilder codeSource(CodeSource cs);
+    
+    public abstract PermissionGrantBuilder multipleCodeSources();
     /**
      * Extracts the CodeSource, Certificates, ClassLoader and ProtectionDomain 
      * from the Class for use in the PermissionGrantBuilder.  The ClassLoader

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilderImp.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilderImp.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilderImp.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PermissionGrantBuilderImp.java Fri Oct 21 08:32:35 2011
@@ -23,8 +23,6 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Collection;
-import org.apache.river.api.security.Exclusion;
-import org.apache.river.api.security.PermissionGrantBuilder;
 import java.lang.ref.WeakReference;
 import java.security.CodeSource;
 import java.security.Permission;
@@ -32,7 +30,7 @@ import java.security.Principal;
 import java.security.ProtectionDomain;
 import java.security.cert.Certificate;
 import java.util.Collections;
-import org.apache.river.api.security.PermissionGrant;
+import java.util.HashSet;
 
 /**
  * PermissionGrantBuilderImp represents the serialized form of all
@@ -47,16 +45,24 @@ import org.apache.river.api.security.Per
  */
 class PermissionGrantBuilderImp extends PermissionGrantBuilder implements
         Serializable{
+    // Static fields
     private static final long serialVersionUID = 1L;
     private static final PermissionGrant nullGrant = new NullPermissionGrant();
+    
+    // Serial Form
     private CodeSource cs;
+    private CodeSource[] csources;
     private Certificate[] certs;
-    private transient WeakReference<ProtectionDomain> domain;
-    private boolean hasDomain;
     private Principal[] principals;
     private Permission[] permissions;
     private int context;
-    private Exclusion deny;
+    private boolean hasMultipleCodeSources;
+    private boolean hasDomain;
+    private boolean inverse;
+    
+    // Transient Fields
+    private transient Collection<CodeSource> multipleCodeSources;
+    private transient WeakReference<ProtectionDomain> domain;
     
     PermissionGrantBuilderImp() {
         super();
@@ -67,17 +73,29 @@ class PermissionGrantBuilderImp extends 
      * Resets builder back to initial state, ready to receive new information
      * for building a new PermissionGrant.
      */
-    public void reset() {
+    public PermissionGrantBuilder reset() {
         cs = null;
         certs = null;
         domain = null;
         hasDomain = false;
         principals = null;
         permissions = null;
-        deny = null;
         context = -1;
+        multipleCodeSources = null;
+        csources = null;
+        hasMultipleCodeSources = false;
+        inverse = false;
+        return this;
+    }
+    
+    @Override
+    public PermissionGrantBuilder inverse() {
+        inverse = true;
+        return this;
     }
 
+
+
     public PermissionGrantBuilder context(int context) {
         if (context < 0) {
             throw new IllegalStateException("context must be >= 0");
@@ -90,9 +108,23 @@ class PermissionGrantBuilderImp extends 
     }
 
     public PermissionGrantBuilder codeSource(CodeSource cs) {
-        this.cs = cs;
+        if (hasMultipleCodeSources){
+            multipleCodeSources.add(cs);
+        } else {
+            this.cs = cs;
+        }
         return this;
     }
+    
+        @Override
+    public PermissionGrantBuilder multipleCodeSources() {
+        hasMultipleCodeSources = true;
+        multipleCodeSources = new HashSet<CodeSource>();
+        csources = null;
+        cs = null;
+        return this;
+    }
+    
 
     public PermissionGrantBuilder clazz(Class cl) {
         if (cl != null) {
@@ -144,33 +176,31 @@ class PermissionGrantBuilderImp extends 
             case CLASSLOADER: //Dynamic grant
                 // Don't return principal grant if domain null, dynamic grant's
                 // are treated special.
+                if (inverse) throw new UnsupportedOperationException("Inverse ClassLoader permissions not implemented");
                 return new ClassLoaderGrant(domain, principals, permissions );
             case CODESOURCE:
-                return new CodeSourceGrant(cs, principals, permissions ,null );
+                if (hasMultipleCodeSources) {
+                    if (csources == null && multipleCodeSources != null) csources = 
+                            multipleCodeSources.toArray(new CodeSource[multipleCodeSources.size()]);
+                    return new CodeSourceSetGrant(csources, principals, permissions, inverse);
+                }
+                return new CodeSourceGrant(cs, principals, permissions, inverse);
             case CODESOURCE_CERTS:
-                return new CertificateGrant(certs, principals, permissions, deny );
+                return new CertificateGrant(certs, principals, permissions, inverse);
             case PROTECTIONDOMAIN: //Dynamic grant
+                if (inverse) throw new UnsupportedOperationException("Inverse ProtectionDomain permissions not implemented");
                 return new ProtectionDomainGrant(domain, principals, permissions );
             case PRINCIPAL:
-                return new PrincipalGrant(principals, permissions);
+                return new PrincipalGrant(principals, permissions, inverse);
             default:
                 return nullGrant;
         }
     }
-
-    public PermissionGrantBuilder exclude(Exclusion denial) {
-        deny = denial;
-        return this;
-    }
     
     private void readObject(ObjectInputStream in)
 	throws IOException, ClassNotFoundException
     {
 	in.defaultReadObject();
-    }
-    
-    private void writeObject(ObjectOutputStream out) throws IOException{
-        out.defaultWriteObject();
         if (hasDomain){
             // In the event that this is a PROTECTIONDOMAIN or CLASSLOADER grant
             // the PermissionGrant returned by the build method will be void.
@@ -180,6 +210,15 @@ class PermissionGrantBuilderImp extends 
         }
     }
     
+    private void writeObject(ObjectOutputStream out) throws IOException{
+        if (hasMultipleCodeSources) {
+            if (csources == null && multipleCodeSources != null) csources = 
+                    multipleCodeSources.toArray(new CodeSource[multipleCodeSources.size()]);
+            cs = null;
+        }
+        out.defaultWriteObject();
+    }
+    
     // readResolve method returns a PermissionGrant instance.
     private Object readResolve(){
         // Don't deserialize specific grant's, they will grant to any domain.
@@ -189,7 +228,8 @@ class PermissionGrantBuilderImp extends 
         // It's ok to return domainless dynamic grants.
         return build();
     }
-    
+
+
     // This is a singleton so we don't need to implement equals or hashCode.
     private static class NullPermissionGrant implements PermissionGrant, Serializable {
         private static final long serialVersionUID = 1L;
@@ -210,7 +250,7 @@ class PermissionGrantBuilderImp extends 
             return Collections.emptySet();
         }
 
-        public boolean isVoid(Exclusion excl) {
+        public boolean isVoid() {
             return true;
         }
 
@@ -225,6 +265,10 @@ class PermissionGrantBuilderImp extends 
         private Object readResolve(){
             return nullGrant;
         }
+
+        public boolean inverse() {
+            return false;
+        }
         
     }
 }

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/PrincipalGrant.java Fri Oct 21 08:32:35 2011
@@ -49,8 +49,9 @@ class PrincipalGrant implements Permissi
     protected final Set<Principal> pals;
     private final int hashCode;
     private final Set<Permission> perms;
+    private final boolean inverse;
     @SuppressWarnings("unchecked")
-    PrincipalGrant(Principal[] pals, Permission[] perm){
+    PrincipalGrant(Principal[] pals, Permission[] perm, boolean inverse){
         if ( pals != null ){
 	    Set<Principal> palCol = new HashSet<Principal>(pals.length);
             palCol.addAll(Arrays.asList(pals));
@@ -69,6 +70,7 @@ class PrincipalGrant implements Permissi
         hash = 97 * hash + (this.pals != null ? this.pals.hashCode() : 0);
         hash = 97 * hash + (this.perms != null ? this.perms.hashCode() : 0);
         hashCode = hash;
+        this.inverse = inverse;
     }
     
     @Override
@@ -220,7 +222,7 @@ class PrincipalGrant implements Permissi
         return perms;
     }
     
-    public boolean isVoid(Exclusion excl) {        
+    public boolean isVoid() {        
         if (perms.size() == 0 ) return true;
         return false;
     }
@@ -235,4 +237,8 @@ class PrincipalGrant implements Permissi
             throws InvalidObjectException{
         throw new InvalidObjectException("PermissionGrantBuilder required");
     }
+
+    public boolean inverse() {
+        return inverse;
+    }
 }

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ProtectionDomainGrant.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ProtectionDomainGrant.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ProtectionDomainGrant.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/api/security/ProtectionDomainGrant.java Fri Oct 21 08:32:35 2011
@@ -40,7 +40,7 @@ class ProtectionDomainGrant extends Prin
     @SuppressWarnings("unchecked")
     ProtectionDomainGrant(WeakReference<ProtectionDomain> domain, Principal[] groups, 
             Permission[] perm){
-        super(groups, perm);
+        super(groups, perm, false);
         this.domain = domain;
         int hash = 7;
         hash = 13 * hash + (this.domain != null ? this.domain.hashCode() : 0);
@@ -143,8 +143,8 @@ class ProtectionDomainGrant extends Prin
     }
 
     @Override
-    public boolean isVoid(Exclusion excl) {        
-        if ( super.isVoid(null)) return true;
+    public boolean isVoid() {        
+        if ( super.isVoid()) return true;
         if ( domain != null && domain.get() == null) return true;
         return false;
     }

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/org/apache/river/impl/security/policy/util/DefaultPolicyParser.java Fri Oct 21 08:32:35 2011
@@ -136,7 +136,7 @@ public class DefaultPolicyParser impleme
                     .next();
             try {
                 PermissionGrant pe = resolveGrant(ge, ks, system, resolve);
-                if (!pe.isVoid(null)) {
+                if (!pe.isVoid()) {
                     result.add(pe);
                 }
             }
@@ -187,6 +187,9 @@ public class DefaultPolicyParser impleme
         /*
          * Do we return multiple grants or do we allow a codebase array 
          * in a permission grant?
+         * 
+         * ANSWER: No we just make a CodeSourceSetGrant, that contains multiple
+         * CodeSource.
          */
         URL codebase = null;
         Certificate[] signers = null;

Modified: river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/CodeSourceGrantTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/CodeSourceGrantTest.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/CodeSourceGrantTest.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/CodeSourceGrantTest.java Fri Oct 21 08:32:35 2011
@@ -55,7 +55,7 @@ public class CodeSourceGrantTest {
         gpP = new GrantPermission(rpD);
         rpA = new RuntimePermission("A");
         Permission[] perms = { rpA, gpS };
-        instance = new CodeSourceGrant(null, null, perms, null);
+        instance = new CodeSourceGrant(null, null, perms, false);
         CodeSource cs = new CodeSource(new URL("file://foo.bar"), (Certificate[]) null);
         pd1 = new ProtectionDomain(cs, null);
        // CodeSource cs = 

Modified: river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/PrincipalGrantTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/PrincipalGrantTest.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/PrincipalGrantTest.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/api/security/PrincipalGrantTest.java Fri Oct 21 08:32:35 2011
@@ -69,7 +69,7 @@ public class PrincipalGrantTest {
         perms = new Permission[2];
         perms[0] = perm1;
         perms[1] = perm2;
-        instance = new PrincipalGrant(pals,perms);
+        instance = new PrincipalGrant(pals,perms, false);
     }
 
     /**

Modified: river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java?rev=1187214&r1=1187213&r2=1187214&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/test/src/org/apache/river/impl/security/policy/util/PolicyEntryTest.java Fri Oct 21 08:32:35 2011
@@ -56,7 +56,7 @@ public class PolicyEntryTest extends Tes
 //        PolicyEntry pe =
 //            new PolicyEntry((CodeSource) null, (Collection<Principal>) null,
 //                (Collection<Permission>)null);
-        assertTrue(pe.isVoid(null));
+        assertTrue(pe.isVoid());
         assertTrue(pe.getPermissions().isEmpty());
 
 //        pe = new PolicyEntry(new CodeSource(null, (Certificate[])null),
@@ -66,7 +66,7 @@ public class PolicyEntryTest extends Tes
                 .permissions(new Permission[0])
                 .context(PermissionGrantBuilder.CODESOURCE)
                 .build();
-        assertTrue(pe.isVoid(null));
+        assertTrue(pe.isVoid());
         assertTrue(pe.getPermissions().isEmpty());
 
         Permission[] perms = new Permission[] {
@@ -76,7 +76,7 @@ public class PolicyEntryTest extends Tes
                 .principals(null)
                 .permissions(perms)
                 .build();
-        assertFalse(pe.isVoid(null));
+        assertFalse(pe.isVoid());
         assertTrue(Arrays.asList(perms).containsAll(pe.getPermissions()));
     }