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 2010/08/12 10:27:37 UTC

svn commit: r984683 - in /incubator/river/jtsk/trunk: qa/ qa/src/com/sun/jini/qa/resources/ qa/src/com/sun/jini/test/resources/ qa/src/com/sun/jini/test/spec/loader/pref/preferredClassLoader/ qa/src/com/sun/jini/test/spec/loader/util/ src/net/jini/secu...

Author: peter_firmstone
Date: Thu Aug 12 08:27:37 2010
New Revision: 984683

URL: http://svn.apache.org/viewvc?rev=984683&view=rev
Log:
Changes to assist running qa ant run-tests for failling tests, continued refactoring of RevokableDynamicPolicy

Added:
    incubator/river/jtsk/trunk/src/org/apache/river/api/security/ExecutionContextManager.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/Controller.java   (with props)
Modified:
    incubator/river/jtsk/trunk/qa/build.xml
    incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/resources/qaDefaults.properties
    incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/resources/qa1.logging
    incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/pref/preferredClassLoader/GetPermissions.java
    incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/util/QATestPreferredClassLoader.java
    incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java
    incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java
    incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/ConcurrentPermissions.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollection.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyUtils.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/ConcurrentPermissionsTest.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollectionTest.java

Modified: incubator/river/jtsk/trunk/qa/build.xml
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/build.xml?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/build.xml (original)
+++ incubator/river/jtsk/trunk/qa/build.xml Thu Aug 12 08:27:37 2010
@@ -264,7 +264,7 @@
         <!--<property name="run.tests" value="com/sun/jini/test/spec/policyprovider/dynamicPolicyProvider/GrantPrincipal.td"/>-->
         <!--<property name="run.tests" value="com/sun/jini/test/spec/policyprovider/dynamicPolicyProvider/GrantNoPrincipalCase02.td"/>-->
         <property name="run.tests" value="com/sun/jini/test/spec/loader/pref/preferredClassLoader/GetPermissionsSecurityException.td"/>
-        <!--<property name="run.tests" value=""/>-->
+        <!--<property name="run.tests" value="com/sun/jini/test/spec/loader/pref/preferredClassProvider/LoadClassesSecurityExceptionHttpCann.td"/>-->
         <!--<property name="run.tests" value=""/>-->
         <!--<property name="run.tests" value=""/>-->
         <!--<property name="run.tests" value=""/>-->

Modified: incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/resources/qaDefaults.properties
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/resources/qaDefaults.properties?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/resources/qaDefaults.properties (original)
+++ incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/resources/qaDefaults.properties Thu Aug 12 08:27:37 2010
@@ -218,7 +218,6 @@ com.sun.jini.qa.harness.actdeathdelay=5
 
 # no cosmetic whitespace
 com.sun.jini.qa.harness.globalvmargs=\
--Djava.security.debug=access:failure,
 -Djava.ext.dirs=${java.ext.dirs},\
 -Dcom.sun.jini.jsk.port=${com.sun.jini.jsk.port},\
 -Dcom.sun.jini.qa.port=${com.sun.jini.qa.port},\

Modified: incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/resources/qa1.logging
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/resources/qa1.logging?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/resources/qa1.logging (original)
+++ incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/resources/qa1.logging Thu Aug 12 08:27:37 2010
@@ -162,15 +162,15 @@ net.jini.iiop.IiopExporter.level = INFO
 net.jini.loader.level = FINEST
 net.jini.loader.pref.PreferredClassLoader.level = FINEST
 net.jini.loader.pref.PreferredClassLoader.preferred.level = FINEST
-#net.jini.loader.pref.PreferredClassLoader.exception.level = INFO
-#net.jini.loader.pref.PreferredClassProvider.level = INFO
+net.jini.loader.pref.PreferredClassLoader.exception.level = FINEST
+net.jini.loader.pref.PreferredClassProvider.level = FINEST
 
 # For Security: trust, integrity, policy and permission granting,
 #               proxy trust verification
-net.jini.security.level = INFO
+net.jini.security.level = FINEST
 #net.jini.security.trust.level = INFO
 #net.jini.security.integrity.level = INFO
-#net.jini.security.policy.level = INFO
+net.jini.security.policy.level = FINEST
 
 # For HTTPMD
 net.jini.url.httpmd.level = INFO

Modified: incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/pref/preferredClassLoader/GetPermissions.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/pref/preferredClassLoader/GetPermissions.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/pref/preferredClassLoader/GetPermissions.java (original)
+++ incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/pref/preferredClassLoader/GetPermissions.java Thu Aug 12 08:27:37 2010
@@ -311,7 +311,8 @@ public class GetPermissions extends Abst
                          + name + ", false, loader)\n"
                          + "  returned:" + classLoaded.toString() + "\n"
                          + "  expected:throws SecurityException";
-
+		ProtectionDomain pd = classLoaded.getProtectionDomain();
+		message += " Permissions: " + pd.getPermissions().toString();
                 // Fast fail approach
                 throw new TestException(message);
             } else if (expectSecurityException) {

Modified: incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/util/QATestPreferredClassLoader.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/util/QATestPreferredClassLoader.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/util/QATestPreferredClassLoader.java (original)
+++ incubator/river/jtsk/trunk/qa/src/com/sun/jini/test/spec/loader/util/QATestPreferredClassLoader.java Thu Aug 12 08:27:37 2010
@@ -53,13 +53,13 @@ import net.jini.loader.pref.PreferredCla
 public class QATestPreferredClassLoader extends PreferredClassLoader {
 
     /** Flag to indicate that loadClass is invoked */
-    public boolean loadClassIsInvoked;
+    public volatile boolean loadClassIsInvoked;
 
     /** Flag to indicate that findClass is invoked */
-    public boolean findClassIsInvoked;
+    public volatile boolean findClassIsInvoked;
 
     /** The URLs from which to load classes and resources */
-    public URL[] urls;
+    private URL[] urls;
 
     /** The parent class loader for delegation */
     private ClassLoader parent;

Modified: incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java Thu Aug 12 08:27:37 2010
@@ -7,6 +7,7 @@ package net.jini.security.policy;
 
 import java.util.List;
 import org.apache.river.api.security.Denied;
+import org.apache.river.api.security.ExecutionContextManager;
 import org.apache.river.api.security.PermissionGrantBuilder;
 import org.apache.river.imp.security.policy.cdc.DynamicPolicyProviderImpl;
 import java.security.AccessControlException;
@@ -324,16 +325,7 @@ public class DynamicPolicyProvider exten
         return instance.getPermissionGrants();
     }
 
-    public void add(List<Denied> denials) {
-        instance.add(denials);
+    public ExecutionContextManager getExecutionContextManager(Permission p) {
+	return instance.getExecutionContextManager(p);
     }
-
-    public void remove(List<Denied> denials) {
-        instance.remove(denials);
-    }
-
-    public List<Denied> getDenied() {
-        return instance.getDenied();
-    }
-   
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/api/security/Denied.java Thu Aug 12 08:27:37 2010
@@ -26,24 +26,10 @@ import java.security.ProtectionDomain;
  * code.  To be utilised the implementation must have the RuntimePermission
  * "getProtectionDomain"
  * 
- * The implementation may deny a Permission on any grounds, but it must be
+ * The implementation may deny a ProtectionDomain on any grounds, but it must be
  * consistent and return the same result on every occassion.
  * 
- * Denied must implement a robust implementation of equals() and hashCode()
- * 
- * Denied can only deny Permissions that are Revokeable, Permission's granted
- * by underlying Policy's cannot be denied, as the Permission's will become
- * merged within a ProtectionDomain's own Permissions collection.
- * 
- * Under certain circumstances it may be possible to deny any and all Permission
- * to ProtectionDomains if we have control of the creation of those
- * ProtectionDomain's, passing in a null PermissionCollection.
- * The underlying Policy also must not grant that ProtectionDomain any Permissions,
- * only under these circumstances is it possible to Denied any or all Permission.
- * 
- * Denied code must be kept to a minimum, as every implies() will be checked.
- * 
- * Denied may also be used in combination with a PermissionGrant based on
+ * Denied will be used in combination with a PermissionGrant based on
  * Code signer Certificate's to deny individual CodeSource's or URL's with
  * known vulnerabilities.
  * 
@@ -51,13 +37,13 @@ import java.security.ProtectionDomain;
  */
 public interface Denied {
     /**
-     * Denied is used by a RevokeableDynamicPolicy, to cut short permission checks
-     * or allow the Policy.implies method to continue to execute to its
-     * normal conclusion.
+     * Denied is used by a PermissionGrantBuilder, to filter out unwanted
+     * ProtectionDomain implies based on any set of conditions.  This is useful
+     * for a PermissionGrant that generically grant's for one 
      * 
      * @param pd
      * @param perm may be null;
      * @return
      */
-    public boolean allow(ProtectionDomain pd, Permission perm);
+    public boolean allow(ProtectionDomain pd);
 }

Added: incubator/river/jtsk/trunk/src/org/apache/river/api/security/ExecutionContextManager.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/api/security/ExecutionContextManager.java?rev=984683&view=auto
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/api/security/ExecutionContextManager.java (added)
+++ incubator/river/jtsk/trunk/src/org/apache/river/api/security/ExecutionContextManager.java Thu Aug 12 08:27:37 2010
@@ -0,0 +1,139 @@
+/*
+ * 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.api.security;
+
+import java.security.AccessControlException;
+import java.security.Permission;
+import java.util.Set;
+
+/**
+ * <p>
+ * An ExecutionContextManager is designed to be repeatedly called, where calling
+ * AccessController.checkPermission(Permission) is too great an overhead.
+ * </p><p>
+ * The ExecutionContextManager will only call 
+ * AccessControlContext.checkPermission(Permission) once, for each context.  This
+ * ensures that checkPermission isn't called again until the context changes, or
+ * the Permission checked by this ExecutionContextManager experiences a 
+ * revoke for any ProtectionDomain by the RevokeableDynamicPolicy.
+ * </p><p>
+ * A Runnable may be submitted to the ExecutionContextManager to be executed
+ * when a Permission Revocation matching the stored Permission occurs.
+ * </p><p>
+ * Use of this class is not limited to Revokeable Permission's.
+ * </p>
+ * @author Peter Firmstone
+ * @see RevokeableDynamicPolicy
+ * @see Permission
+ * @see AccessControlContext
+ */
+public interface ExecutionContextManager {
+
+    /**
+     * <p>
+     * This is a call made by a Security Delegate, or other Object used to
+     * control access to privileged methods or constructors, similar to the
+     * AccessControll.checkPermission(Permission) call, but with the Permission
+     * pre defined and unchanging.  The Permission check is optimised,
+     * typically a method may only be concerned with a single Permission check,
+     * but in many existing cases, the AccessController check is too expensive 
+     * to be called on every method invocation.  The ExecutionContextManager 
+     * should optimise this call by ensuring that checkPermission(Permission) is only
+     * called once per AccessControlContext.  In other words if the caller's
+     * AccessControlContext hasn't changed, then checkPermission(Permission)
+     * isn't called again as it would be assumed to succeed, unless the 
+     * RevokeableDynamicPolicy revokes a Permission with the same class,
+     * in which case the Permission must be checked again.
+     * </p><p>
+     * Typically where it is not feasable to call AccessController.checkPermission
+     * on every invocation, those objects are usually guarded or have the
+     * checkPermission method called in the constructor.
+     * </p><p>
+     * ExecutionContextManager provides a more thorough form of protection.
+     * </p><p>
+     * ExecutionContextManager should be used sparingly, the more generic
+     * or widely applicable the Permission, the more efficient the 
+     * ExecutionContextManager is in memory usage terms.
+     * </p><p>
+     * This method also add's the current context to the current execution 
+     * cache, it is not removed from that cache until after the addAction 
+     * Runnable has been run, or accessControlExit() has been called.
+     * </p>
+     * 
+     * @throws java.security.AccessControlException 
+     */
+    public void checkPermission() throws AccessControlException;
+    
+    /**
+     * <p>
+     * This method is to advise the ExecutionContextManager that the
+     * current method or protected region has returned, it must
+     * always follow the checkPermission() call, in response,
+     * the ECM removes the current context from the execution context cache.
+     * </p><p>
+     * If the execution context is still in the cache at the time of 
+     * revocation, the Runnable added by addAction will be run only if 
+     * affected directly by the revocation.  This is determined by
+     * AccessControlContext.checkPermission(Permission p) where p is the 
+     * Permission affected.
+     * </p><p>
+     * This should be executed in the finally{} block of a try catch statement,
+     * which always executes in the event of an exception or normal return.
+     * </p>
+     * <code>
+     * try{
+     *	    ecm.checkPermission();
+     *	    // do something
+     *	    return;
+     * } catch (AccessControlException e) {
+     *	    throw new SecurityException("Method blah caused an...", e);
+     * } finally {
+     *	    ecm.accessControlExit();
+     * }
+     * </code>
+     * <p>
+     * This should not be confused with AccessController.doPrivileged blocks
+     * </p>
+     */
+    public void accessControlExit();
+
+    /**
+     * Get the Permission monitored by this ExecutionContextManager.
+     * @return Permission monitored by the ExecutionContextManager
+     */
+    public Permission getPermission();
+
+    /**
+     * <p>
+     * Action to be taken in event that the Permission monitored by this
+     * ExecutionContextManager has experienced a revocation event.  This
+     * allows Sockets to be closed, or any clean up to occur or any other
+     * task that must be performed to reset state.
+     * </p><p>
+     * This may not be the only action performed, since the same
+     * ExecutionContextManager may be used by multiple clients, the Runnable
+     * is only weakly referenced, garbage collection is relied upon for its
+     * removal.
+     * </p><p>
+     * The implementer must have the Permission's required for
+     * execution, no privileges are assigned.
+     * </p>
+     * @param r - Clean up task to be performed.
+     */
+    public void addAction(Runnable r);
+}

Propchange: incubator/river/jtsk/trunk/src/org/apache/river/api/security/ExecutionContextManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/api/security/RevokeableDynamicPolicy.java Thu Aug 12 08:27:37 2010
@@ -1,7 +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.river.api.security;
 
+import java.security.Permission;
 import java.util.List;
 
 /**
@@ -19,38 +36,58 @@ import java.util.List;
  */
 public interface RevokeableDynamicPolicy {
     /**
+     * Grant Permission's as specified in a List of PermissionGrant's
+     * which can be added by concurrent threads.
      * 
      * @param grants
      */
     public void grant(List<PermissionGrant> grants);
     /**
+     * Revoke, only removes any PermissionGrant's that are identical, typically
+     * a List of Grant's is obtained by getPermssionGrant's which can be 
+     * manipulated and investigated, any that are undesirable should be passed
+     * to revoke.
+     * 
+     * Revokes can only be performed synchronuously with other Revokes.
      * 
      * @param grants
      */
     public void revoke(List<PermissionGrant> grants);
     /**
-     * 
+     * Get a List copy of the current PermissionGrant's in force.
      * @return
      */
     public List<PermissionGrant> getPermissionGrants();
     /**
+     * The Revocation of Permission's requires a new construct for controlling
+     * access.  Typically many objects that provide privileged functionality
+     * are guarded in their constructor by a checkPermission(Permission) call
+     * or by a GuardedObject, once this check has succeeded, the caller receives
+     * a reference to the guarded object.  These Permission's cannot be
+     * revoked completely, because the reference has escaped, the permission 
+     * check will not be called again.
+     * 
+     * Instead what is needed is a permission check that is efficient enough
+     * to allow the methods that provide the privileged functionality to be
+     * called for every method invocation.  What the ExecutionContextManager
+     * does is minimise the checkPermission calls by skipping checkPermission for
+     * any execution AccessControlContext that has already passed, unless
+     * a Permission related to the one being managed is revoked, in which case
+     * the cache of AccessControlContext's previously checked are cleared.
+     * 
+     * The ExecutionContextManager is specific only to one permission, this 
+     * is the enabler for the reduced checkPermission calls, since a
+     * Permission should behave in a persistent manner, once it passes, it
+     * should always pass, unless revoked.
      * 
-     * @param denials
-     */
-    public void add(List<Denied> denials);
-    /**
-     * 
-     * @param denials
-     */
-    public void remove(List<Denied> denials);
-    /**
      * 
-     * @return
+     * @param p Permission the ExecutionContextManager will check.
+     * @return a new ExecutionContextManager instance.
      */
-    public List<Denied> getDenied();
+    public ExecutionContextManager getExecutionContextManager(Permission p);
     /**
      * 
-     * @return
+     * @return true if Revoke supported.
      */
     public boolean revokeSupported();
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java Thu Aug 12 08:27:37 2010
@@ -49,6 +49,7 @@ import net.jini.security.GrantPermission
 import org.apache.river.api.security.Denied;
 import org.apache.river.api.security.PermissionGrant;
 import org.apache.river.api.security.PermissionGrantBuilder;
+import org.apache.river.api.security.ExecutionContextManager;
 import org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi;
 
 /**
@@ -582,16 +583,7 @@ public class DynamicPolicyProviderImpl e
         throw new UnsupportedOperationException("Not supported.");
     }
 
-    public void add(List<Denied> denials) {
-        throw new UnsupportedOperationException("Not supported yet.");
+    public ExecutionContextManager getExecutionContextManager(Permission p) {
+	throw new UnsupportedOperationException("Not supported yet.");
     }
-
-    public void remove(List<Denied> denials) {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
-    public List<Denied> getDenied() {
-        throw new UnsupportedOperationException("Not supported yet.");
-    }
-
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/ConcurrentPermissions.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/ConcurrentPermissions.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/ConcurrentPermissions.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/ConcurrentPermissions.java Thu Aug 12 08:27:37 2010
@@ -106,17 +106,15 @@ implements Serializable {
         }
         // this get saves unnecessary object creation.
         PermissionCollection pc = permsMap.get(permission.getClass());
-        if (pc != null){                       
-            pc.add(permission);
-            return;             
-        } else {
-            PermissionCollection fresh = new MultiReadPermissionCollection(permission);   
+        if (pc == null){                       
+            pc = new MultiReadPermissionCollection(permission);   
             PermissionCollection existed = 
-                    permsMap.putIfAbsent(permission.getClass(), fresh);
+                    permsMap.putIfAbsent(permission.getClass(), pc);
             if (existed != null) {
-                existed.add(permission);
+                pc = existed;
             }
-        }        
+        } 
+	pc.add(permission);
     }    
     
     /**

Added: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/Controller.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/Controller.java?rev=984683&view=auto
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/Controller.java (added)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/Controller.java Thu Aug 12 08:27:37 2010
@@ -0,0 +1,179 @@
+/*
+ * 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.imp.security.policy.se;
+
+import java.lang.ref.WeakReference;
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Permission;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import org.apache.river.api.security.ExecutionContextManager;
+import org.apache.river.imp.util.ConcurrentWeakIdentityMap;
+
+/**
+ * An implementation of ExecutionContextManager.
+ * 
+ * @author Peter Firmstone.
+ */
+class Controller implements ExecutionContextManager {
+    /* The class manages revoke for all it's objects. */
+    private static final ConcurrentMap<Permission, ExecutionContextManager> pool 
+	    = new ConcurrentWeakIdentityMap<Permission, ExecutionContextManager>();
+    
+    private static final List<WeakReference<Controller>> cont =
+	    new ArrayList<WeakReference<Controller>>(80);
+    /**
+     * This method is called by the RevokeableDynamicPolicy to get a List 
+     * of Runnable clean up jobs that must be performed to complete the
+     * revocation of Permissions.
+     * 
+     * A Thread pool can be used to perform the work, however the policy's
+     * revoke call must not return until after all the jobs are complete.
+     * 
+     * @param classes - A set of Permission Class object's for the Permission's
+     * being revoked.
+     * @return A List of Runnable clean up tasks to be performed to complete
+     * the revocation.
+     */
+    static List<Runnable> revoke(Set<Class> classes){
+	List<Runnable> cleanupJobs;
+	synchronized (cont){
+	    cleanupJobs = new ArrayList<Runnable>(cont.size());
+	    Iterator<WeakReference<Controller>> it =
+		    cont.iterator();
+	    while (it.hasNext()) {
+		WeakReference<Controller> wf = it.next();
+		Controller ecm = wf.get();
+		if ( ecm != null ){
+		    if (classes.contains(ecm.getPermission().getClass())){
+			ecm.clear();
+			cleanupJobs.addAll(ecm.getRunnable());
+		    }
+		} else {
+		    it.remove();
+		}
+	    }
+	}
+	return cleanupJobs;	
+    }
+    
+    static ExecutionContextManager getECManager(Permission p){
+	ExecutionContextManager exm = pool.get(p);
+	if ( exm != null ){
+	    return exm;
+	} 
+	exm = new Controller(p);
+	ExecutionContextManager existed = pool.putIfAbsent(p, exm);
+	if ( existed != null){
+	    exm = existed;
+	}
+	return exm;	
+    }
+    
+    /* Object state and methods */
+    private final Permission perm;
+    private final List<WeakReference<Runnable>> cleanup;
+    private final Set<AccessControlContext> checkedExecutionContext;
+    
+    /* A Revocation in progress will delay construction of a new Controller */
+    private Controller(Permission p){
+	perm = p;
+	WeakReference<Controller> mac = 
+		new WeakReference<Controller>(this);
+	cleanup = new ArrayList<WeakReference<Runnable>>();
+	checkedExecutionContext = new HashSet<AccessControlContext>(80);
+	// this must be done last.
+	synchronized (cont){
+	    cont.add(mac);
+	}
+    } 
+
+    public void checkPermission() throws AccessControlException {
+	AccessControlContext executionContext = AccessController.getContext();
+	synchronized (checkedExecutionContext){
+	    if (checkedExecutionContext.contains(executionContext)) {
+		return;
+	    }
+	}
+	executionContext.checkPermission(perm);
+	/* If we get to here without exception we can add it.
+	 * The RevokeablyDynamicPolicy will revoke the Permission prior to
+	 * clearing the current checked execution context as part of the revoke
+	 * process, this means
+	 * that while the revocation isn't yet complete, the checked context
+	 * will still return true, but the actual permission check would return
+	 * false, however at the completion of the revocation process, the
+	 * Runnable provided will be executed to perform any necessary cleanupJobs
+	 * to fully revoke.
+	 * 
+	 * This prevents invalid execution context's from finding their way
+	 * into the checked Execution Context which would be a security breach.
+	 * 
+	 * Revoke's happen synchronuously to ensure that this contract is honored.
+	 */ 
+	synchronized (checkedExecutionContext){
+	    checkedExecutionContext.add(executionContext);
+	}
+    }
+
+    public Permission getPermission() {
+	return perm;
+    }
+
+    public void addAction(Runnable r) {
+	synchronized (cleanup){
+	    cleanup.add(new WeakReference<Runnable>(r));
+	}
+    }
+    
+    private List<Runnable> getRunnable(){
+	List<Runnable> tasks;
+	synchronized (cleanup){
+	    tasks = new ArrayList<Runnable>(cleanup.size());
+	    Iterator<WeakReference<Runnable>> it = cleanup.iterator();
+	    while (it.hasNext()){
+		WeakReference<Runnable> wr = it.next();
+		Runnable r = wr.get();
+		if (r != null){
+		    tasks.add(r);
+		}else {
+		    cleanup.remove(wr);
+		}
+	    }
+	}
+	return tasks;
+    }
+    
+    private void clear(){
+	synchronized (checkedExecutionContext){
+	    checkedExecutionContext.clear();
+	}
+    }
+
+    public void accessControlExit() {
+	throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+}

Propchange: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/Controller.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/DynamicConcurrentPolicyProvider.java Thu Aug 12 08:27:37 2010
@@ -22,7 +22,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
@@ -35,6 +34,7 @@ import net.jini.security.policy.PolicyIn
 import net.jini.security.policy.UmbrellaGrantPermission;
 import org.apache.river.api.security.Denied;
 import org.apache.river.api.security.PermissionGrant;
+import org.apache.river.api.security.ExecutionContextManager;
 import org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi;
 import org.apache.river.api.security.PermissionGrantBuilder;
 import org.apache.river.api.security.RevokePermission;
@@ -158,10 +158,10 @@ public class DynamicConcurrentPolicyProv
     // avoid dead locks due to bug 4911907
     /* This lock Protects denied */
     private final ReentrantReadWriteLock drwl;
-    private final ReadLock drl;
-    private final WriteLock dwl;
-    private final Set<Denied> denied;
-    private volatile boolean checkDenied;
+//    private final ReadLock drl;
+//    private final WriteLock dwl;
+//    private final Set<Denied> denied;
+//    private volatile boolean checkDenied;
     
     
     public DynamicConcurrentPolicyProvider(){
@@ -174,10 +174,10 @@ public class DynamicConcurrentPolicyProv
         logger = Logger.getLogger("net.jini.security.policy");
         loggable = logger.isLoggable(Level.FINEST);
         drwl = new ReentrantReadWriteLock();
-        drl = drwl.readLock();
-        dwl = drwl.writeLock();
-        denied = new HashSet<Denied>(30);
-        checkDenied = false;
+//        drl = drwl.readLock();
+//        dwl = drwl.writeLock();
+//        denied = new HashSet<Denied>(30);
+//        checkDenied = false;
 	grantLock = new Object();
     }
     
@@ -225,15 +225,15 @@ public class DynamicConcurrentPolicyProv
         if (initialized == false) throw new RuntimeException("Object not initialized");
         // Investigate bug 4911907, do we need to do anything more here? Is this sufficient.
         if (sysDomain == null ) System.out.println("System Domain is null");
-        basePolicy.implies(sysDomain, new AllPermission());
-        PermissionCollection pc = getPermissions(sysDomain);
-        pc = PolicyUtils.toConcurrentPermissionsCopy(pc);
-        cache.putIfAbsent(sysDomain, pc);
+        implies(sysDomain, new AllPermission());
+        //PermissionCollection pc = getPermissions(sysDomain);
+        //pc = PolicyUtils.toConcurrentPermissionsCopy(pc);
+        //cache.putIfAbsent(sysDomain, pc);
         ProtectionDomain own = this.getClass().getProtectionDomain();
-        basePolicy.implies(own, new AllPermission());
-        PermissionCollection mypc = getPermissions(own);
-        mypc = PolicyUtils.toConcurrentPermissionsCopy(mypc);
-        cache.putIfAbsent(own, mypc);
+        implies(own, new AllPermission());
+        //PermissionCollection mypc = getPermissions(own);
+        //mypc = PolicyUtils.toConcurrentPermissionsCopy(mypc);
+        //cache.putIfAbsent(own, mypc);
         new GrantPermission(new UmbrellaGrantPermission());
     }
 
@@ -279,21 +279,21 @@ public class DynamicConcurrentPolicyProv
     public boolean implies(ProtectionDomain domain, Permission permission) {
         if (initialized == false) throw new RuntimeException("Object not initialized");
         if (basePolicyIsDynamic){
-            // Total delegation revoke and deny not supported.
+            // Total delegation revoke and deny supported only by underlying policy.
             return basePolicy.implies(domain, permission);
         }
-        // Will this ProtectionDomain and Permission be denied?
-        if (checkDenied){
-            try {
-                drl.lock();
-                Iterator<Denied> itr = denied.iterator();
-                while (itr.hasNext()){
-                    if ( !itr.next().allow(domain, permission)){
-                        return false;
-                    }
-                }
-            } finally { drl.unlock(); }
-        }
+//        // Will this ProtectionDomain and Permission be denied?
+//        if (checkDenied){
+//            try {
+//                drl.lock();
+//                Iterator<Denied> itr = denied.iterator();
+//                while (itr.hasNext()){
+//                    if ( !itr.next().allow(domain, permission)){
+//                        return false;
+//                    }
+//                }
+//            } finally { drl.unlock(); }
+//        }
         // First check our cache if the basePolicy is not dynamic.
         PermissionCollection pc = cache.get(domain);
         if ( pc != null ) {
@@ -321,10 +321,10 @@ public class DynamicConcurrentPolicyProv
 	}
         // Once we get to here pc is definitely not null and we have the
         // copy referenced in the cache.
-        if (loggable){
-            logger.log(Level.FINEST, domain + permission.toString() + 
-                    ": Base policy is not dynamic and returned false" );
-        }
+//        if (loggable){
+//            logger.log(Level.FINEST, domain + permission.toString() + 
+//                    ": Base policy is not dynamic and returned false" );
+//        }
         // If the base policy doesn't imply a Permission then we should check for dynamic grants
         Collection<Permission> dynamicallyGrantedPermissions = new HashSet<Permission>(pGrants.length);
 	PermissionGrant[] grantsRefCopy = pGrants; // In case the grants volatile reference is updated.
@@ -336,9 +336,9 @@ public class DynamicConcurrentPolicyProv
 		dynamicallyGrantedPermissions.addAll(Arrays.asList(perms));
 	    }
 	}
-        if (loggable) {
-            logger.log(Level.FINEST, "Grants: " + dynamicallyGrantedPermissions.toString());
-        }
+//        if (loggable) {
+//            logger.log(Level.FINEST, "Grants: " + dynamicallyGrantedPermissions.toString());
+//        }
         if (dynamicallyGrantedPermissions.isEmpty()) {
             // We have no dynamic grants
             return false;
@@ -349,9 +349,9 @@ public class DynamicConcurrentPolicyProv
         }
         // If we get refreshed the cache could be empty, which is more pedantic
         // however the result may still be true so we'll return it anyway.
-        if (loggable) {
-            logger.log(Level.FINEST, "PermissionCollection: " + pc.toString());
-        }
+//        if (loggable) {
+//            logger.log(Level.FINEST, "PermissionCollection: " + pc.toString());
+//        }
         // We have added dynamic grants, lets expand them
 	// But UmbrellaGrant's are to enable easy dynamic GrantPermission's?
         expandUmbrella(pc);
@@ -548,6 +548,8 @@ public class DynamicConcurrentPolicyProv
             return;
         }
         AccessController.checkPermission(new RevokePermission());
+	HashSet<Class> removed = new HashSet<Class>();
+	List<Runnable> jobs = null;
 	HashSet<PermissionGrant> holder = new HashSet<PermissionGrant>(pGrants.length);
 	synchronized (grantLock){
 	    int l = pGrants.length;
@@ -555,13 +557,21 @@ public class DynamicConcurrentPolicyProv
 		if (pGrants[i].isVoid() || grants.contains(pGrants[i])) {
 		    // should we consider removing from grantCache?
 		    // For now we just let GC clean it up.
+		    Permission [] perms = grantCache.get(pGrants[i]);
+		    int len = perms.length;
+		    for ( int c =0; c < len ; c++ ){
+			removed.add(perms[c].getClass());
+		    }
 		    continue;
 		}
 		holder.add(pGrants[i]);
 	    }
 	    PermissionGrant[] updated = new PermissionGrant[holder.size()];
 	    pGrants = holder.toArray(updated);
-	}	
+	    jobs = Controller.revoke(removed);
+	}
+	//TODO jobs to tidy up after revocation.
+	
     }
 
     public List<PermissionGrant> getPermissionGrants() {
@@ -578,35 +588,9 @@ public class DynamicConcurrentPolicyProv
 	return grants;
     }
 
-    public void add(List<Denied> denials) {
-        if (initialized == false) throw new RuntimeException("Object not initialized");
-        AccessController.checkPermission(new RuntimePermission("getProtectionDomain"));
-        AccessController.checkPermission(new RevokePermission());
-        checkDenied = true;
-        try{
-            dwl.lock();
-            denied.addAll(denials);
-        } finally { dwl.unlock();}
-    }
-
-    public void remove(List<Denied> denials) {
-        if (initialized == false) throw new RuntimeException("Object not initialized");
-        try{
-            dwl.lock();
-            denied.removeAll(denials);
-            if ( denied.isEmpty()) { checkDenied = false; }
-        } finally { dwl.unlock();}
-    }
-
-    public List<Denied> getDenied() {
-        if (initialized == false) throw new RuntimeException("Object not initialized");
-        List<Denied> denials;
-        try{
-            drl.lock();
-            denials = new ArrayList<Denied>(denied.size());
-            denials.addAll(denied);
-            return denials;
-        } finally { dwl.unlock();}
+
+    public ExecutionContextManager getExecutionContextManager(Permission p) {
+	return Controller.getECManager(p);
     }
 
 }

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollection.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollection.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollection.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollection.java Thu Aug 12 08:27:37 2010
@@ -60,8 +60,8 @@ public final class MultiReadPermissionCo
     private final transient ReadWriteLock rwl;
     private final transient Lock rl;
     private final transient Lock wl;
-    private boolean readOnly; // all access protected by rwl
-    private Permission[] permissions; //never instantiate for ide code completion
+    private boolean readOnly; // never instantiate for ide code completion of Serialization Proxy
+    private Permission[] permissions; //never instantiate for ide code completion of Serialization Proxy
     // Read only copy to prevent publication of internal PermissionCollection
     // state.  For generation of Enumeration<Permission>.
     // It is volatile because other read locks may update the cache reference
@@ -74,7 +74,6 @@ public final class MultiReadPermissionCo
         rwl = new ReentrantReadWriteLock();
         rl = rwl.readLock();
         wl = rwl.writeLock();
-        readOnly = false;
 	cache = null;
     }
     
@@ -82,7 +81,7 @@ public final class MultiReadPermissionCo
     public boolean isReadOnly(){
         rl.lock();
         try{  
-            return readOnly;
+            return permCl.isReadOnly();
         }finally {rl.unlock();}
     }
     
@@ -90,7 +89,8 @@ public final class MultiReadPermissionCo
     public void setReadOnly(){
         wl.lock();
         try{
-            readOnly = true;
+            super.setReadOnly();
+	    permCl.setReadOnly();
         }finally {wl.unlock();}
     }
     
@@ -125,9 +125,6 @@ public final class MultiReadPermissionCo
 
     @Override
     public void add(Permission permission) {
-        if (readOnly) {
-            throw new SecurityException("attempt to add a Permission to a readonly Permissions object");
-        } 
         wl.lock();
         try {
             permCl.add(permission);
@@ -178,7 +175,6 @@ public final class MultiReadPermissionCo
         if (pc == null){
             pc = new PermissionHash();
         }
-	pc.add(permission);
         return pc;                    
     }   
     
@@ -199,7 +195,10 @@ public final class MultiReadPermissionCo
     }
     
     private Object writeReplace(){
-        return new SerializationProxy(this);
+	rl.lock();
+        try {
+            return new SerializationProxy(permCl);
+        }finally {rl.unlock();}
     }
     
     private void readObject(ObjectInputStream stream) throws InvalidObjectException {

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/CertificateGrant.java Thu Aug 12 08:27:37 2010
@@ -75,7 +75,7 @@ class CertificateGrant extends CodeSourc
     
     @Override
     public boolean implies(ProtectionDomain pd) {
-        if ( denied.allow(pd, null)){
+        if ( denied.allow(pd)){
             Certificate[] c = null;
             Principal[] pals = null;
             if (pd != null){

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DenyImpl.java Thu Aug 12 08:27:37 2010
@@ -78,7 +78,7 @@ public class DenyImpl implements Denied 
         return code;
     }
     
-    public boolean allow(ProtectionDomain pd,java.security.Permission perm){
+    public boolean allow(ProtectionDomain pd){
         CodeSource cs = pd.getCodeSource();
         cs = normalizeCodeSource(cs);
         if (code.contains(cs)) return false;

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PermissionGrantBuilderImp.java Thu Aug 12 08:27:37 2010
@@ -129,7 +129,6 @@ public class PermissionGrantBuilderImp i
         }
     }
 
-    @Override
     public PermissionGrantBuilder deny(Denied denial) {
         deny = denial;
         return this;

Modified: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyUtils.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyUtils.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyUtils.java (original)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyUtils.java Thu Aug 12 08:27:37 2010
@@ -32,6 +32,7 @@ import java.net.URL;
 import java.security.AccessController;
 import java.security.Permission;
 import java.security.PermissionCollection;
+import java.security.Permissions;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
 import java.security.Security;

Modified: incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/ConcurrentPermissionsTest.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/ConcurrentPermissionsTest.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/ConcurrentPermissionsTest.java (original)
+++ incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/ConcurrentPermissionsTest.java Thu Aug 12 08:27:37 2010
@@ -16,6 +16,7 @@ import java.util.Enumeration;
 import java.util.List;
 import java.util.PropertyPermission;
 import java.util.logging.LoggingPermission;
+import net.jini.security.AccessPermission;
 import net.jini.security.AuthenticationPermission;
 import org.apache.river.imp.security.policy.se.ConcurrentPermissions;
 import org.junit.After;
@@ -110,6 +111,34 @@ public class ConcurrentPermissionsTest {
         assertEquals(expResult, result);
     }
     /**
+     * Test of implies method, of class ConcurrentPermissions, when there is
+     * no PermissionCollection, present it is created by ConcurrentPermissions,
+     * when it resolves an Unresolved Permission during an implies call,
+     * this check ensures that the Permission isn't added to the collection
+     * by mistake.
+     * 
+     * This occurred during a refactoring of ConcurrentPermission's and
+     * MultiReadPermissionCollection, relating to the addition of 
+     * UmbrellaPermissionGrant's to the RevokeableDynamicPolicy when 
+     * elements() returned a ConcurrentModificationException.  This test
+     * case was proven to fail on 12th August 2010 - Peter Firmstone.
+     */
+    @Test
+    public void doubleImpliesUnresolved() {
+        System.out.println("doubleImplies - consistent results");
+        Permission permission = new AccessPermission("unlucky");
+	Permission unresolved = 
+		new UnresolvedPermission("net.jini.security.AccessPermission", 
+		"lucky", null, null);
+        ConcurrentPermissions instance = new ConcurrentPermissions();
+	instance.add(unresolved);
+        boolean expResult = false;
+        boolean result = instance.implies(permission);
+	result = instance.implies(permission);
+	assertEquals(expResult, result);
+    }
+    
+    /**
      * Test of elements method, of class ConcurrentPermissions.
      * TODO Concurrent adds.
      */
@@ -165,7 +194,7 @@ public class ConcurrentPermissionsTest {
         while (en.hasMoreElements()){
             result.add(en.nextElement());
         }
-        assertTrue(expectedResult.equals(result));
+        assertTrue(result.containsAll(expectedResult));
         assertTrue(instance.implies(permission0));
         assertTrue(instance.implies(permission1));
         assertTrue(instance.implies(permission2));

Modified: incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollectionTest.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollectionTest.java?rev=984683&r1=984682&r2=984683&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollectionTest.java (original)
+++ incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollectionTest.java Thu Aug 12 08:27:37 2010
@@ -52,9 +52,9 @@ public class MultiReadPermissionCollecti
         Permission permission0 = new RuntimePermission("getClassLoader");
         MultiReadPermissionCollection instance = new MultiReadPermissionCollection(permission0);
         instance.setReadOnly();
-        SecurityException exp = new SecurityException("attempt to add a Permission to a readonly Permissions object");
+        SecurityException exp = new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
         String result = null;
-        Permission permission1 = new AuthenticationPermission("javax.security.auth.x500.X500Principal \"CN=serverRSA\"", "listen");
+        Permission permission1 = new RuntimePermission("getProtectionDomain");
         try {
             instance.add(permission1);
         }catch (SecurityException e) {