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/05/11 22:37:49 UTC

svn commit: r943285 [1/3] - in /incubator/river/jtsk/trunk: ./ qa/ qa/harness/trust/ qa/src/com/sun/jini/qa/harness/ qa/src/com/sun/jini/qa/resources/ src/com/sun/jini/tool/ src/net/jini/core/lookup/ src/net/jini/discovery/ src/net/jini/lease/ src/net/...

Author: peter_firmstone
Date: Tue May 11 20:37:47 2010
New Revision: 943285

URL: http://svn.apache.org/viewvc?rev=943285&view=rev
Log:
River-323 Significant refactoring and layout changes.

This will break some tests causing a failled Hudson build, however I think it best to get the code out there, so I can get some assistance.

By default the qa tests now utilise the ConcurrentDynamicPolicyProvider and DynamicPolicyProvider uses a pluggable SPI.

Added:
    incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPermissions.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPolicyFile.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/DynamicConcurrentPolicyProvider.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/MultiReadPermissionCollection.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/PermissionPendingResolution.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/PermissionPendingResolutionCollection.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/RevokeablePermissionCollection.java   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/spi/
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/spi/RevokeableDynamicPolicySpi.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/spi/RevokeableDynamicPolicySpi.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DefaultPolicyParser.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/util/DefaultPolicyParser.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/DefaultPolicyScanner.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/util/DefaultPolicyScanner.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/Messages.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/util/Messages.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/NullPolicyParser.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/util/NullPolicyParser.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyEntry.java
      - copied, changed from r941176, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/util/PolicyEntry.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyParser.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/util/PolicyParser.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/PolicyUtils.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/util/PolicyUtils.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/UnresolvedPrincipal.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/util/UnresolvedPrincipal.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/Util.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/src/org/apache/river/security/policy/util/Util.java
    incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/util/messages.properties   (with props)
    incubator/river/jtsk/trunk/src/org/apache/river/imp/util/
    incubator/river/jtsk/trunk/src/org/apache/river/imp/util/ConcurrentWeakIdentityMap.java   (with props)
    incubator/river/jtsk/trunk/test/src/org/apache/river/api/
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/ConcurrentPermissionsTest.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/test/src/org/apache/river/security/concurrent/ConcurrentPermissionsTest.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/ConcurrentPolicyFileTest.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/test/src/org/apache/river/security/concurrent/ConcurrentPolicyFileTest.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/MultiReadPermissionCollectionTest.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/test/src/org/apache/river/security/concurrent/MultiReadPermissionCollectionTest.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/PermissionCollectionTest.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/test/src/org/apache/river/security/concurrent/PermissionCollectionTest.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/se/Permissions_ImplTest.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/test/src/org/apache/river/security/concurrent/Permissions_ImplTest.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/DefaultPolicyParserTest.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/test/src/org/apache/river/security/policy/util/DefaultPolicyParserTest.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/PolicyEntryTest.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/test/src/org/apache/river/security/policy/util/PolicyEntryTest.java
    incubator/river/jtsk/trunk/test/src/org/apache/river/imp/security/policy/util/PolicyUtilsTest.java
      - copied, changed from r933907, incubator/river/jtsk/trunk/test/src/org/apache/river/security/policy/util/PolicyUtilsTest.java
Removed:
    incubator/river/jtsk/trunk/src/net/jini/core/lookup/ResultStream.java
    incubator/river/jtsk/trunk/src/net/jini/core/lookup/ServiceItemUnmarshaller.java
    incubator/river/jtsk/trunk/src/net/jini/discovery/Facade.java
    incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProviderImpl.java
Modified:
    incubator/river/jtsk/trunk/build.xml
    incubator/river/jtsk/trunk/common.xml
    incubator/river/jtsk/trunk/qa/build.xml
    incubator/river/jtsk/trunk/qa/harness/trust/dynamic-policy.properties
    incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/MasterTest.java
    incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
    incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QARunner.java
    incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/resources/qaDefaults.properties
    incubator/river/jtsk/trunk/src/com/sun/jini/tool/ProfilingSecurityManager.java
    incubator/river/jtsk/trunk/src/net/jini/core/lookup/StreamServiceRegistrar.java
    incubator/river/jtsk/trunk/src/net/jini/discovery/DiscMan2Facade.java
    incubator/river/jtsk/trunk/src/net/jini/discovery/DiscManFacade.java
    incubator/river/jtsk/trunk/src/net/jini/discovery/LookupDiscoveryManager.java
    incubator/river/jtsk/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java
    incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalService.java
    incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalSet.java
    incubator/river/jtsk/trunk/src/net/jini/lease/LeaseUnmarshalException.java
    incubator/river/jtsk/trunk/src/net/jini/loader/pref/PreferredClassLoader.java
    incubator/river/jtsk/trunk/src/net/jini/lookup/JoinManager.java
    incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java
    incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceRegistrarFacade.java
    incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamFilter.java
    incubator/river/jtsk/trunk/src/net/jini/lookup/StreamServiceRegistrarFacade.java
    incubator/river/jtsk/trunk/src/net/jini/security/policy/DynamicPolicyProvider.java
    incubator/river/jtsk/trunk/test/src/tests/support/FakePrincipal.java

Modified: incubator/river/jtsk/trunk/build.xml
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/build.xml?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/build.xml (original)
+++ incubator/river/jtsk/trunk/build.xml Tue May 11 20:37:47 2010
@@ -306,14 +306,20 @@
             <package name="net.jini.security.policy"/>
             <package name="net.jini.security.proxytrust"/>
             <package name="org.apache.river.security"/>
-            <package name="org.apache.river.security.concurrent"/>
-            <package name="org.apache.river.security.policy.spi"/>
-            <package name="org.apache.river.security.policy.util"/>    
-            <package name="org.apache.river.util.concurrent"/>
+            <package name="org.apache.river.imp.security.policy.se"/>
+            <package name="org.apache.river.imp.security.policy.cdc"/>
+            <package name="org.apache.river.imp.security.policy.spi"/>
+            <package name="org.apache.river.imp.security.policy.util"/>  
+            <package name="org.apache.river.imp.util"/>
             <package name="net.jini.space"/>
             <package name="net.jini.url.file"/>
             <package name="net.jini.url.httpmd"/>
             <package name="net.jini.url.https"/>
+            <package name="org.apache.river.api.security"/>
+            <package name="org.apache.river.api.services.lease"/>
+            <package name="org.apache.river.api.throwable.lease"/>
+            <package name="org.apache.river.api.throwable.rmi"/>
+            <package name="org.apache.river.api.util"/>
         </javadoc>
         <mkdir dir="${doc.api.dir}/doc-files"/>
         <copy file="NOTICE" tofile="${doc.api.dir}/doc-files/NOTICE"/>
@@ -345,6 +351,13 @@
             <package name="net.jini.config"/>
             <package name="net.jini.constraint"/>
             <package name="net.jini.core.constraint"/>
+            <package name="net.jini.core.discovery"/>
+            <package name="net.jini.core.entry"/>
+            <package name="net.jini.core.event"/>
+            <package name="net.jini.core.lease"/>
+            <package name="net.jini.core.lookup"/>
+            <package name="net.jini.core.transaction"/>
+            <package name="net.jini.core.transaction.server"/>
             <package name="net.jini.entry"/>
             <package name="net.jini.export"/>
             <package name="net.jini.id"/>
@@ -367,6 +380,12 @@
             <package name="net.jini.url.file"/>
             <package name="net.jini.url.httpmd"/>
             <package name="net.jini.url.https"/>
+            <package name="org.apache.river.api.security"/>
+            <package name="org.apache.river.api.services.lease"/>
+            <package name="org.apache.river.api.throwable.lease"/>
+            <package name="org.apache.river.api.throwable.rmi"/>
+            <package name="org.apache.river.api.util"/>
+            
         </javadoc>
         <mkdir dir="${doc.spec.api.dir}/doc-files"/>
         <copy file="NOTICE" tofile="${doc.spec.api.dir}/doc-files/NOTICE"/>
@@ -726,6 +745,12 @@
             <arg line="-in com.sun.jini"/>
             <arg line="-in net.jini"/>
             <arg line="-in org.apache.river"/>
+            <!--The following is left out to avoid multiple classes visible on
+            the classpath, if the wrong jar is selected, it may not have
+            the appropriate permission if it is outside the jre/lib/ext 
+            directory where AllPermission is granted-->
+            <arg line="-out org.apache.river.imp.security.policy.se"/>
+            <arg line="-out org.apache.river.imp.security.policy.util"/>
             <arg path="${build.classes.dir}/net/jini/activation"/>
             <arg path="${build.classes.dir}/net/jini/config"/>
             <arg path="${build.classes.dir}/net/jini/constraint"/>
@@ -741,6 +766,7 @@
             <arg path="${build.classes.dir}/net/jini/url"/>
             <arg value="net.jini.discovery.ConstrainableLookupLocator"/>
             <arg value="net.jini.discovery.ConstrainableLookupLocatorTrustVerifier"/>
+            <arg value="org.apache.river.api.security.RevokePermission"/>
             <arg path="${build.classes.dir}/com/sun/jini/discovery"/>
             <arg value="com.sun.jini.config.ConfigUtil"/>
             <arg value="com.sun.jini.config.KeyStores"/>
@@ -782,6 +808,7 @@
             <arg line="-api com.sun.jini.config.ConfigUtil"/>
             <arg line="-api com.sun.jini.config.KeyStores"/>
             <arg line="-api com.sun.jini.logging.LogManager"/>
+            <arg line="-api org/apache/river/api/-"/>
             <classpath refid="river.classes"/>
         </preferredlistgen>
     </target>
@@ -795,6 +822,7 @@
             <arg value="-files"/>
             <arg value="net.jini.security.policy.DynamicPolicyProvider"/>
             <arg value="net.jini.security.policy.PolicyFileProvider"/>
+            <arg value="org.apache.river.api.security.RevokePermission"/>
             <arg line="-in com.sun.jini"/>
             <arg line="-in net.jini"/>
             <arg line="-in org.apache.river"/>
@@ -814,16 +842,19 @@
             <arg value="-cp"/>
             <arg path="${build.classes.dir}"/>
             <arg value="-files"/>
-            <arg value="org.apache.river.security.concurrent.ConcurrentPolicyFile"/>
-            <arg line="-in com.sun.jini"/>
-            <arg line="-in net.jini"/>
+            <arg value="org.apache.river.imp.security.policy.se.ConcurrentPolicyFile"/>
+            <arg value="org.apache.river.imp.security.policy.se.DynamicConcurrentPolicyProvider"/>
             <arg line="-in org.apache.river"/>
+            <arg line="-out org.apache.river.api"/>
+            <arg line="-out org.apache.river.imp.security.policy.spi"/>
         </classdep>
         <delete file="${lib-ext.dir}/concurrent-policy-util.jar" quiet="true"/>
         <jar destfile="${lib-ext.dir}/concurrent-policy-util.jar"
 		     index="false">
             <fileset dir="${build.classes.dir}" 
                 includesfile="${concurrent-policy-util.deps}"/>
+            <fileset dir="${src.manifest.dir}/concurrent-policy-util"
+				 includes="META-INF/services/org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi"/>
         </jar>
     </target>
 

Modified: incubator/river/jtsk/trunk/common.xml
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/common.xml?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/common.xml (original)
+++ incubator/river/jtsk/trunk/common.xml Tue May 11 20:37:47 2010
@@ -78,7 +78,7 @@
         ## classes in these packages are both not part of the JSK
         ## platform and not public (have generated javadoc).
         ## The -skip for logging classes is because LogManager is in
-        ## jsk-pllatform.jar and Levels is in jsk-lib.jar.
+        ## jsk-platform.jar and Levels is in jsk-lib.jar.
         ## The -in com.sun.jini.outrigger is there in order to catch
         ## any use of the following deprecated APIs:
         ##       com.sun.jini.outrigger.AdminIterator
@@ -88,7 +88,7 @@
         ## can be removed -->
     <property name="jskprivate.include" value="-in com.sun.jini.action -in com.sun.jini.collection -in com.sun.jini.constants -in com.sun.jini.system -in com.sun.jini.logging -skip com.sun.jini.logging.LogManager -skip com.sun.jini.logging.Levels -in com.sun.jini.outrigger"/>
     <!-- Common packages to exclude within ClassDep -->
-    <property name="jskplatform.exclude" value="-out com.sun.jini.discovery -out net.jini.activation -out net.jini.config -out net.jini.constraint -out net.jini.core -out net.jini.export -out net.jini.id -out net.jini.iiop -out net.jini.io -out net.jini.jeri -out net.jini.jrmp -out net.jini.loader -out net.jini.security -out net.jini.url -skip net.jini.discovery.ConstrainableLookupLocator -skip net.jini.discovery.ConstrainableLookupLocatorTrustVerifier -skip com.sun.jini.config.ConfigUtil -skip com.sun.jini.config.KeyStores -skip com.sun.jini.logging.LogManager"/>
+    <property name="jskplatform.exclude" value="-out com.sun.jini.discovery -out net.jini.activation -out net.jini.config -out net.jini.constraint -out net.jini.core -out net.jini.export -out net.jini.id -out net.jini.iiop -out net.jini.io -out net.jini.jeri -out net.jini.jrmp -out net.jini.loader -out net.jini.security -out net.jini.url -out org.apache.river -skip net.jini.discovery.ConstrainableLookupLocator -skip net.jini.discovery.ConstrainableLookupLocatorTrustVerifier -skip com.sun.jini.config.ConfigUtil -skip com.sun.jini.config.KeyStores -skip com.sun.jini.logging.LogManager"/>
 
     <property name="river.home" location="${root}"/>
     <property name="river.lib.dir" location="${river.home}/${lib}"/>

Modified: incubator/river/jtsk/trunk/qa/build.xml
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/build.xml?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/build.xml (original)
+++ incubator/river/jtsk/trunk/qa/build.xml Tue May 11 20:37:47 2010
@@ -149,6 +149,7 @@
             </filelist>
         </move>
         <move file="${river.lib-ext.dir}/jsk-policy.jar" todir="${jtreg.dir}/JTlib-tmp"/>
+        <move file="${river.lib-ext.dir}/concurrent-policy-util.jar" todir="${jtreg.dir}/JTlib-tmp"/>
         <jtreg  dir="${jtreg.dir}" verbose="all,nopass" failonerror="false"
                 errorproperty="jtreg.fail" failureproperty="jtreg.fail"
                 reportdir="${jtreg.dir}/JTreport" workdir="${jtreg.dir}/JTwork"
@@ -173,6 +174,7 @@
             </filelist>
         </move>
         <move file="${jtreg.dir}/JTlib-tmp/jsk-policy.jar" todir="${river.lib-ext.dir}"/>
+        <move file="${jtreg.dir}/JTlib-tmp/concurrent-policy-util.jar" todir="${river.lib-ext.dir}"/>
         <delete dir="${jtreg.dir}/JTlib-tmp"/>
         <delete file="${jtreg.dir}/test.props"/>
         <fail if="jtreg.fail"/>
@@ -189,6 +191,7 @@
             </filelist>
         </move>
         <move file="${jtreg.dir}/JTlib-tmp/jsk-policy.jar" todir="${river.lib-ext.dir}"/>
+        <move file="${jtreg.dir}/JTlib-tmp/concurrent-policy-util.jar" todir="${river.lib-ext.dir}"/>
         <delete dir="${jtreg.dir}/JTlib-tmp"/>
         <delete file="${jtreg.dir}/test.props"/>
     </target>
@@ -208,10 +211,10 @@
                 file requires a particular permission, note this only works for the harness here -->
                 <!--<jvmarg value="-Djava.security.manager=com.sun.jini.tool.ProfilingSecurityManager"/>-->
                 <!--<jvmarg value="-Dpolicy.provider=net.jini.security.policy.DynamicPolicyProvider"/>-->
-                <!--Enable the following if you don't want to use any other policy's -->
+                <!--Enable the following if you don't want to use any other policy's note == -->
                 <!--<jvmarg value="-Djava.security.policy==${security.policy}" />-->
                 <jvmarg value="-Djava.security.policy=${security.policy}" />
-                <jvmarg value="-Djava.security.debug=access" />
+                <!--<jvmarg value="-Djava.security.debug=access" />-->
                 <jvmarg value="-Djava.util.logging.config.file=${log.config}" />
                 <jvmarg value="-Dcom.sun.jini.jsk.home=${river.home}" />
                 <jvmarg value="-Dcom.sun.jini.qa.home=${basedir}" />
@@ -252,7 +255,21 @@
         <!--<property name="run.tests" value="com/sun/jini/test/impl/discoverymanager/RemoveGroupsLocsDiscard.td"/>-->
         <!--<property name="run.tests" value="com/sun/jini/test/impl/locatordiscovery/DelayDiscoveryAfterDiscard.td,com/sun/jini/test/spec/policyprovider/dynamicPolicyProvider/SecurityExceptionConstructorNoGetProperty.td,com/sun/jini/test/spec/policyprovider/dynamicPolicyProvider/SecurityExceptionConstructorNoAccessClass.td,com/sun/jini/test/spec/policyprovider/dynamicPolicyProvider/SecurityExceptionConstructorNoAccessClass.td,com/sun/jini/test/spec/policyprovider/dynamicPolicyProvider/SecurityExceptionConstructorNoGetProperty.td"/>-->
         <!--<property name="run.tests" value="com/sun/jini/test/impl/joinmanager/LeaseRenewDurRFE.td"/>-->
-        <property name="run.tests" value="com/sun/jini/test/spec/policyprovider/policyFileProvider/NullPolicy.td"/>
+        <!--<property name="run.tests" value="com/sun/jini/test/spec/policyprovider/policyFileProvider/NullPolicy.td"/>-->
+        <!--<property name="run.tests" value="com/sun/jini/test/spec/joinmanager/GetDiscoveryManager.td"/>-->
+        <!--<property name="run.tests" value="com/sun/jini/test/spec/joinmanager/TerminateDiscovery.td"/>-->
+        <!--<property name="run.tests" value="com/sun/jini/test/impl/joinmanager/ZRegisterStorm.td"/>-->
+        <!--<property name="run.tests" value="com/sun/jini/test/impl/joinmanager/LeaseRenewDurRFE.td"/>-->
+        <!--<property name="run.tests" value="com/sun/jini/test/spec/policyprovider/dynamicPolicyProvider/GrantPrincipalSame.td"/>-->
+        <!--<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=""/>-->
+        <!--<property name="run.tests" value=""/>-->
+        <!--<property name="run.tests" value=""/>-->
+        <!--<property name="run.tests" value=""/>-->
+        <!--<property name="run.tests" value=""/>-->
+        <!--<property name="run.tests" value=""/>-->
+        <!--<property name="run.tests" value=""/>-->
         <testrun>
             <!-- Run specific test(s) -->
             <arg value="-tests"/>
@@ -265,7 +282,7 @@
         <!--<property name="test.categories" value="id,loader,policyprovider,locatordiscovery,activation,
         config,constraint,discoverymanager,discoveryservice,joinmanager,url,
         eventmailbox,jeri,iiop,jrmp,reliability,scalability,thread,renewalservice"/>-->
-        <property name="run.categories" value="joinmanager"/>
+        <property name="run.categories" value="policyprovider"/>
         <testrun>
              <!-- Run one or more test categories -->
             <arg value="-categories"/>

Modified: incubator/river/jtsk/trunk/qa/harness/trust/dynamic-policy.properties
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/harness/trust/dynamic-policy.properties?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/harness/trust/dynamic-policy.properties (original)
+++ incubator/river/jtsk/trunk/qa/harness/trust/dynamic-policy.properties Tue May 11 20:37:47 2010
@@ -2,4 +2,8 @@
 # provider
 
 policy.provider=net.jini.security.policy.DynamicPolicyProvider
+#net.jini.security.policy.DynamicPolicyProvider.basePolicyClass=net.jini.security.policy.PolicyFileProvider
+#net.jini.security.policy.PolicyFileProvider.basePolicyClass=com.sun.jini.qa.harness.MergedPolicyProvider
 net.jini.security.policy.DynamicPolicyProvider.basePolicyClass=com.sun.jini.qa.harness.MergedPolicyProvider
+#net.jini.security.policy.DynamicPolicyProvider.basePolicyClass=net.jini.security.policy.PolicyFileProvider
+#net.jini.security.policy.PolicyFileProvider.basePolicyClass=org.apache.river.security.concurrent.ConcurrentPolicyFile

Modified: incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/MasterTest.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/MasterTest.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/MasterTest.java (original)
+++ incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/MasterTest.java Tue May 11 20:37:47 2010
@@ -17,6 +17,7 @@
  */
 package com.sun.jini.qa.harness;
 
+import com.sun.jini.tool.ProfilingSecurityManager;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -84,6 +85,7 @@ class MasterTest {
 	logger.log(Level.FINE, "Starting MasterTest");
 	if (System.getSecurityManager() == null) {
 	    System.setSecurityManager(new java.rmi.RMISecurityManager());
+//            System.setSecurityManager(new ProfilingSecurityManager());
 	}
 	if (args.length < 1) {
 	    exit(false, Test.ENV, "Arguments missing");

Modified: incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java (original)
+++ incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java Tue May 11 20:37:47 2010
@@ -43,6 +43,8 @@ import java.rmi.activation.ActivationGro
 import java.rmi.activation.ActivationException;
 import java.rmi.RemoteException;
 
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -949,8 +951,17 @@ public class QAConfig implements Seriali
      */
     public static boolean isDistributed() {
         boolean distributed = false;
-        String hostList =
-            System.getProperty("com.sun.jini.qa.harness.testhosts");
+        String hostList = AccessController.doPrivileged(
+	    new PrivilegedAction<String>() {
+		public String run() {
+		    return 
+			System.getProperty(
+			    "com.sun.jini.qa.harness.testhosts");
+		}
+            }
+        );
+//        String hostList =
+//            System.getProperty("com.sun.jini.qa.harness.testhosts");
         if (hostList != null) {
             StringTokenizer tok = new StringTokenizer(hostList, "|");
             if (tok.countTokens() > 1) {

Modified: incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QARunner.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QARunner.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QARunner.java (original)
+++ incubator/river/jtsk/trunk/qa/src/com/sun/jini/qa/harness/QARunner.java Tue May 11 20:37:47 2010
@@ -19,6 +19,8 @@ package com.sun.jini.qa.harness;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.StringTokenizer;
 
 /**
@@ -48,7 +50,16 @@ public abstract class QARunner {
     public static void main(String[] args) 
 	throws UnknownHostException, TestException
     {
-	String hostList = System.getProperty("com.sun.jini.qa.harness.testhosts");
+        String hostList = AccessController.doPrivileged(
+	    new PrivilegedAction<String>() {
+		public String run() {
+		    return 
+			System.getProperty(
+			    "com.sun.jini.qa.harness.testhosts");
+		}
+            }
+        );
+//	String hostList = System.getProperty("com.sun.jini.qa.harness.testhosts");
 	if (isMasterHost(hostList)) {
 	    boolean allPass = (new MasterHarness(args)).runTests();
 	    System.exit(allPass ? 0 : 1);

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=943285&r1=943284&r2=943285&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 Tue May 11 20:37:47 2010
@@ -210,7 +210,12 @@ com.sun.jini.qa.harness.actdeathdelay=5
 #   system property if that property is defined. The '-OD' marker flags this
 #   property as optional. If the property is not defined as a system property
 #   or in any configuration file, then the property will not be set on the VM.
-#      -Djava.security.debug=access,\
+#
+#   You might find the following debugging options useful
+#       -Djava.security.debug=access:failure,\
+#       -Djava.security.manager=com.sun.jini.tool.ProfilingSecurityManager,\
+#       -Dpolicy.provider=net.jini.security.policy.DynamicPolicyProvider,\
+
 # no cosmetic whitespace
 com.sun.jini.qa.harness.globalvmargs=\
 -Djava.ext.dirs=${java.ext.dirs},\

Modified: incubator/river/jtsk/trunk/src/com/sun/jini/tool/ProfilingSecurityManager.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/com/sun/jini/tool/ProfilingSecurityManager.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/com/sun/jini/tool/ProfilingSecurityManager.java (original)
+++ incubator/river/jtsk/trunk/src/com/sun/jini/tool/ProfilingSecurityManager.java Tue May 11 20:37:47 2010
@@ -88,6 +88,7 @@ public class ProfilingSecurityManager ex
         if( !isRecur(stack) ) {
             buildRules(permission, AccessController.getContext());
         }
+        //super.checkPermission(permission);
     }
     
     // -----------------
@@ -95,6 +96,7 @@ public class ProfilingSecurityManager ex
     @Override
     public void checkPermission(final Permission permission, final Object context) {
         buildRules(permission, (AccessControlContext)context);
+        //super.checkPermission(permission, context);
     }
     
     // -----------------

Modified: incubator/river/jtsk/trunk/src/net/jini/core/lookup/StreamServiceRegistrar.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/core/lookup/StreamServiceRegistrar.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/core/lookup/StreamServiceRegistrar.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/core/lookup/StreamServiceRegistrar.java Tue May 11 20:37:47 2010
@@ -17,6 +17,7 @@
  */
 package net.jini.core.lookup;
 
+import org.apache.river.api.util.ResultStream;
 import java.rmi.RemoteException;
 import net.jini.core.entry.Entry;
 import net.jini.core.event.EventRegistration;

Modified: incubator/river/jtsk/trunk/src/net/jini/discovery/DiscMan2Facade.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/discovery/DiscMan2Facade.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/discovery/DiscMan2Facade.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/discovery/DiscMan2Facade.java Tue May 11 20:37:47 2010
@@ -5,6 +5,7 @@
 
 package net.jini.discovery;
 
+import org.apache.river.api.util.Facade;
 import net.jini.lookup.ServiceRegistrarFacade;
 import net.jini.core.lookup.PortableServiceRegistrar;
 import net.jini.core.lookup.ServiceRegistrar;

Modified: incubator/river/jtsk/trunk/src/net/jini/discovery/DiscManFacade.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/discovery/DiscManFacade.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/discovery/DiscManFacade.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/discovery/DiscManFacade.java Tue May 11 20:37:47 2010
@@ -5,6 +5,7 @@
 
 package net.jini.discovery;
 
+import org.apache.river.api.util.Facade;
 import net.jini.lookup.ServiceRegistrarFacade;
 import net.jini.core.lookup.PortableServiceRegistrar;
 import net.jini.core.lookup.ServiceRegistrar;

Modified: incubator/river/jtsk/trunk/src/net/jini/discovery/LookupDiscoveryManager.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/discovery/LookupDiscoveryManager.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/discovery/LookupDiscoveryManager.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/discovery/LookupDiscoveryManager.java Tue May 11 20:37:47 2010
@@ -18,6 +18,7 @@
 
 package net.jini.discovery;
 
+import org.apache.river.api.util.Facade;
 import net.jini.lookup.ServiceRegistrarFacade;
 import java.io.IOException;
 import java.util.ArrayList;

Modified: incubator/river/jtsk/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java Tue May 11 20:37:47 2010
@@ -17,6 +17,7 @@
  */
 package net.jini.discovery;
 
+import org.apache.river.api.util.Facade;
 import net.jini.lookup.StreamServiceRegistrarFacade;
 import net.jini.lookup.ServiceRegistrarFacade;
 import com.sun.jini.config.Config;

Modified: incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalService.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalService.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalService.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalService.java Tue May 11 20:37:47 2010
@@ -32,8 +32,9 @@ import java.rmi.RemoteException;
  * 
  * @author Sun Microsystems, Inc.
  * @see LeaseRenewalSet 
+ * @deprecated.
  */
-
+@Deprecated
 public interface LeaseRenewalService {
     /**
      * Create a new <code>LeaseRenewalSet</code> that the client can

Modified: incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalSet.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalSet.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalSet.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/lease/LeaseRenewalSet.java Tue May 11 20:37:47 2010
@@ -168,7 +168,9 @@ import net.jini.core.lease.Lease;
  * 
  * @author Sun Microsystems, Inc.
  * @see LeaseRenewalService
+ * @deprecated no replacement.
  */
+@Deprecated
 public interface LeaseRenewalSet {
     /**
      * The event id for all <code>RenewalFailureEvent</code> objects.

Modified: incubator/river/jtsk/trunk/src/net/jini/lease/LeaseUnmarshalException.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/lease/LeaseUnmarshalException.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/lease/LeaseUnmarshalException.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/lease/LeaseUnmarshalException.java Tue May 11 20:37:47 2010
@@ -67,7 +67,10 @@ import net.jini.core.lease.Lease;
  * 
  * @author Sun Microsystems, Inc.
  * @see Lease 
+ * @deprecated not replaced, only used by {@link LeaseRenewalSet} which is also 
+ * deprecated.
  */
+@Deprecated
 public class LeaseUnmarshalException extends Exception {
     private static final long serialVersionUID = -6736107321698417489L;
 

Modified: incubator/river/jtsk/trunk/src/net/jini/loader/pref/PreferredClassLoader.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/loader/pref/PreferredClassLoader.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/loader/pref/PreferredClassLoader.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/loader/pref/PreferredClassLoader.java Tue May 11 20:37:47 2010
@@ -41,6 +41,7 @@ import java.security.PermissionCollectio
 import java.security.Permissions;
 import java.security.ProtectionDomain;
 import java.security.Policy;
+import java.security.Principal;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
@@ -1141,10 +1142,21 @@ public class PreferredClassLoader extend
 	/*
 	 * Create an AccessControlContext that consists of a single
 	 * protection domain with only the permissions calculated above.
+         * Comment added 7th May 2010 by Peter Firmstone:
+         * This calls the pre java 1.4 constructor which causes the
+         * ProtectionDomain to not consult the Policy, this
+         * has the effect of not allowing Dynamic Permission changes to be
+         * effected by the Policy.  It doesn't affect the existing
+         * DynamicPolicy implementation as it returns the Permissions
+         * allowing the ProtectionDomain domain combiner to combine
+         * cached permissions with those from the Policy.
+         * ProtectionDomain(CodeSource, PermissionCollection)
+         * By utilising this earlier constructor it also prevents
+         * RevokeablePolicy, hence the constructor change.  
 	 */
 	ProtectionDomain pd = new ProtectionDomain(
 	    new CodeSource((urls.length > 0 ? urls[0] : null),
-			   (Certificate[]) null), perms);
+			   (Certificate[]) null), perms, null, null);
 	return new AccessControlContext(new ProtectionDomain[] { pd });
     }
 

Modified: incubator/river/jtsk/trunk/src/net/jini/lookup/JoinManager.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/lookup/JoinManager.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/lookup/JoinManager.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/lookup/JoinManager.java Tue May 11 20:37:47 2010
@@ -58,7 +58,7 @@ import net.jini.discovery.DiscManFacade;
 import net.jini.discovery.DiscoveryListenerManagement;
 import net.jini.discovery.DiscoveryManagement2;
 import net.jini.discovery.DiscMan2Facade;
-import net.jini.discovery.Facade;
+import org.apache.river.api.util.Facade;
 import net.jini.lookup.ServiceRegistrarFacade;
 
 /**

Modified: incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java Tue May 11 20:37:47 2010
@@ -73,7 +73,7 @@ import net.jini.core.lookup.StreamServic
 import net.jini.discovery.DiscMan2Facade;
 import net.jini.discovery.DiscManFacade;
 import net.jini.discovery.DiscoveryManagement2;
-import net.jini.discovery.Facade;
+import org.apache.river.api.util.Facade;
 
 /**
  * The <code>ServiceDiscoveryManager</code> class is a helper utility class

Modified: incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceRegistrarFacade.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceRegistrarFacade.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceRegistrarFacade.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceRegistrarFacade.java Tue May 11 20:37:47 2010
@@ -18,7 +18,7 @@ import net.jini.core.lookup.ServiceRegis
 import net.jini.core.lookup.ServiceRegistration;
 import net.jini.core.lookup.ServiceTemplate;
 import net.jini.core.lookup.StreamServiceRegistrar;
-import net.jini.discovery.Facade;
+import org.apache.river.api.util.Facade;
 import net.jini.io.Convert;
 import net.jini.io.MarshalledInstance;
 

Modified: incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamFilter.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamFilter.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamFilter.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamFilter.java Tue May 11 20:37:47 2010
@@ -5,7 +5,7 @@
 
 package net.jini.lookup;
 
-import net.jini.core.lookup.ResultStream;
+import org.apache.river.api.util.ResultStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;

Added: incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java?rev=943285&view=auto
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java (added)
+++ incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java Tue May 11 20:37:47 2010
@@ -0,0 +1,46 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package net.jini.lookup;
+
+import org.apache.river.api.util.ResultStream;
+import net.jini.core.lookup.*;
+
+/**
+ * Add this to the ResultStream filter chain
+ * {@link StreamServiceRegistrar#lookup(ServiceTemplate, Class[], int)}
+ * to unmarshall any MarshalledServiceItem's in the stream, prior to 
+ * proxy verification, or applying constraints.
+ * 
+ * @author Peter Firmstone.
+ * @see MarshalledServiceItem.
+ * @see StreamServiceRegistrar
+ */
+public class ServiceResultStreamUnmarshaller implements ResultStream<ServiceItem> {
+    ResultStream<ServiceItem> input;
+    
+    public ServiceResultStreamUnmarshaller(ResultStream<ServiceItem> rs){
+        input = rs;
+    }
+
+    public ServiceItem get() {
+        for(ServiceItem item = input.get(); item != null; 
+                item = input.get()) {
+            if (item instanceof MarshalledServiceItem){
+                MarshalledServiceItem msi = (MarshalledServiceItem) item;
+                ServiceItem it = new ServiceItem(msi.serviceID, msi.getService(),
+                        msi.getEntries());
+                item = it;
+            }
+            return item;
+        }//end item loop
+        return null; // Our stream terminated item was null;
+    }
+
+    public void close() {
+        input.close();
+    }
+
+}

Propchange: incubator/river/jtsk/trunk/src/net/jini/lookup/ServiceResultStreamUnmarshaller.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/river/jtsk/trunk/src/net/jini/lookup/StreamServiceRegistrarFacade.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/net/jini/lookup/StreamServiceRegistrarFacade.java?rev=943285&r1=943284&r2=943285&view=diff
==============================================================================
--- incubator/river/jtsk/trunk/src/net/jini/lookup/StreamServiceRegistrarFacade.java (original)
+++ incubator/river/jtsk/trunk/src/net/jini/lookup/StreamServiceRegistrarFacade.java Tue May 11 20:37:47 2010
@@ -5,7 +5,7 @@
 
 package net.jini.lookup;
 
-import net.jini.core.lookup.ResultStream;
+import org.apache.river.api.util.ResultStream;
 import java.rmi.RemoteException;
 import net.jini.core.discovery.LookupLocator;
 import net.jini.core.entry.Entry;
@@ -19,7 +19,7 @@ import net.jini.core.lookup.ServiceMatch
 import net.jini.core.lookup.ServiceRegistration;
 import net.jini.core.lookup.ServiceTemplate;
 import net.jini.core.lookup.StreamServiceRegistrar;
-import net.jini.discovery.Facade;
+import org.apache.river.api.util.Facade;
 import net.jini.io.Convert;
 import net.jini.io.MarshalledInstance;
 

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=943285&r1=943284&r2=943285&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 Tue May 11 20:37:47 2010
@@ -5,6 +5,7 @@
 
 package net.jini.security.policy;
 
+import org.apache.river.imp.security.policy.cdc.DynamicPolicyProviderImpl;
 import java.security.AccessControlException;
 import java.security.AccessController;
 import java.security.CodeSource;
@@ -20,8 +21,8 @@ import java.util.Iterator;
 import java.util.logging.Logger;
 import java.util.logging.Level;
 import sun.misc.Service;
-import org.apache.river.security.policy.spi.RevokeablePolicy;
-import org.apache.river.security.policy.spi.RevokeableDynamicPolicySpi;
+import org.apache.river.api.security.RevokeablePolicy;
+import org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi;
 
 /**
  * This class replaces the existing DynamicPolicyProvider, the existing 
@@ -165,6 +166,7 @@ public class DynamicPolicyProvider exten
      *          adequate permissions to access the base policy class
      */
     public DynamicPolicyProvider() throws PolicyInitializationException {
+        // Need to change this so implementer can choose their own base policy.
         this(getBasePolicy());
     }
     
@@ -195,7 +197,8 @@ public class DynamicPolicyProvider exten
             }
         }           
         if (instance == null) {            
-            instance = new DynamicPolicyProviderImpl();            
+            instance = new DynamicPolicyProviderImpl();
+            logger.log(Level.INFO, "Using DynamicPolicyProviderImpl");
         }
         try {
             instance.basePolicy(basePolicy);

Added: 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=943285&view=auto
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java (added)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/cdc/DynamicPolicyProviderImpl.java Tue May 11 20:37:47 2010
@@ -0,0 +1,575 @@
+/*
+ * 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.cdc;
+
+import net.jini.security.policy.*;
+import com.sun.jini.collection.WeakIdentityMap;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Principal;
+import java.security.Policy;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.security.Security;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import net.jini.security.GrantPermission;
+import org.apache.river.imp.security.policy.spi.RevokeableDynamicPolicySpi;
+
+/**
+ * Security policy provider that supports dynamic granting of permissions at
+ * run-time.  This provider is designed as a wrapper to layer dynamic grant
+ * functionality on top of an underlying policy provider.  If the underlying
+ * provider does not implement the {@link DynamicPolicy} interface, then its
+ * permission mappings are assumed to change only when its {@link
+ * Policy#refresh refresh} method is called.  Permissions are granted on the
+ * granularity of class loader; granting a permission requires (of the calling
+ * context) {@link GrantPermission} for that permission.
+ *
+ * @author Sun Microsystems, Inc.
+ * 
+ * @since 2.0
+ */
+public class DynamicPolicyProviderImpl extends Policy implements RevokeableDynamicPolicySpi {
+
+    private static final ProtectionDomain sysDomain = (ProtectionDomain)
+	AccessController.doPrivileged(new PrivilegedAction() {
+	    public Object run() { return Object.class.getProtectionDomain(); }
+	});
+
+    private volatile Policy basePolicy;
+    private volatile boolean cacheBasePerms;
+    private volatile boolean initialized;
+    // REMIND: do something with WeakIdentityMap and Concurrency, note
+    // this means different implementation methods not a drop in.
+    private final Map domainPerms;
+    private final Map loaderGrants;
+    private final Grants globalGrants;
+    private static final Logger logger = Logger.getLogger(
+            "net.jini.security.policy");
+
+    /**
+     * A new uninitialized instance.
+     */
+    public DynamicPolicyProviderImpl() {
+       domainPerms = new WeakIdentityMap();
+       loaderGrants = new WeakIdentityMap();
+       globalGrants = new Grants();
+       basePolicy = null;
+       cacheBasePerms = false;
+       initialized = false;
+    }
+    
+    /**
+     * This method is only called once, on an uninitialized instance
+     * further attempts will fail.
+     * @param basePolicy
+     * @return success
+     */
+    public boolean basePolicy(Policy basePolicy){
+        if (this.basePolicy == null){
+            this.basePolicy = basePolicy;
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * This method completes construction of the Implementation, considered
+     * safe since it is called through the Service Provider Interface 
+     * and cannot be accessed otherwise.
+     * @throws net.jini.security.policy.PolicyInitializationException
+     * @throws java.lang.InstantiationException
+     */
+    public void initialize() throws PolicyInitializationException {
+        if (initialized == true) {
+            return;
+        }
+        if (basePolicy == null) throw new PolicyInitializationException("Base Policy hasn't " +
+                "been set cannot initialize", new Exception("Failed to initialize"));      
+        cacheBasePerms = !(basePolicy instanceof DynamicPolicy);  
+        initialized = true;
+    }
+
+    /**
+     * Behaves as specified by {@link Policy#getPermissions(CodeSource)}.
+     */
+    @Override
+    public PermissionCollection getPermissions(CodeSource source) {
+	PermissionCollection pc = basePolicy.getPermissions(source);
+	Permission[] pa = globalGrants.get(null);
+	for (int i = 0; i < pa.length; i++) {
+	    Permission p = pa[i];
+	    if (!pc.implies(p)) {
+		pc.add(p);
+	    }
+	}
+	return pc;
+    }
+
+    /**
+     * Behaves as specified by {@link Policy#getPermissions(ProtectionDomain)}.
+     */
+    @Override
+    public PermissionCollection getPermissions(ProtectionDomain domain) {
+	return getDomainPermissions(domain).getPermissions(domain);
+    }
+
+    /**
+     * Behaves as specified by {@link Policy#implies}.
+     */
+    public boolean implies(ProtectionDomain domain, Permission permission) {
+	return getDomainPermissions(domain).implies(permission, domain);
+    }
+
+    /**
+     * Behaves as specified by {@link Policy#refresh}.
+     */
+    public void refresh() {
+	basePolicy.refresh();
+	if (cacheBasePerms) {
+	    synchronized (domainPerms) {
+		domainPerms.clear();
+	    }
+	}
+    }
+
+    // documentation inherited from DynamicPolicy.grantSupported
+    public boolean grantSupported() {
+	return true;
+    }
+
+    // documentation inherited from DynamicPolicy.grant
+    public void grant(Class cl, 
+		      Principal[] principals, 
+		      Permission[] permissions) 
+    {
+	if (cl != null) {
+	    checkDomain(cl);
+	}
+	if (principals != null && principals.length > 0) {
+	    principals = (Principal[]) principals.clone();
+	    checkNullElements(principals);
+	}
+	if (permissions == null || permissions.length == 0) {
+	    return;
+	}
+	permissions = (Permission[]) permissions.clone();
+	checkNullElements(permissions);
+
+	SecurityManager sm = System.getSecurityManager();
+	if (sm != null) {
+	    sm.checkPermission(new GrantPermission(permissions));
+	}
+
+	Grants g = (cl != null) ?
+	    getLoaderGrants(getClassLoader(cl)) : globalGrants;
+	g.add(principals, permissions);
+    }
+
+    // documentation inherited from DynamicPolicy.getGrants
+    public Permission[] getGrants(Class cl, Principal[] principals) {
+	if (cl != null) {
+	    checkDomain(cl);
+	}
+	if (principals != null && principals.length > 0) {
+	    principals = (Principal[]) principals.clone();
+	    checkNullElements(principals);
+	}
+
+	List l = Arrays.asList(globalGrants.get(principals));
+	if (cl != null) {
+	    l = new ArrayList(l);
+	    l.addAll(Arrays.asList(
+			 getLoaderGrants(getClassLoader(cl)).get(principals)));
+	}
+	PermissionCollection pc = new Permissions();
+	for (Iterator i = l.iterator(); i.hasNext(); ) {
+	    Permission p = (Permission) i.next();
+	    if (!pc.implies(p)) {
+		pc.add(p);
+	    }
+	}
+	l = Collections.list(pc.elements());
+	return (Permission[]) l.toArray(new Permission[l.size()]);
+    }
+
+    /**
+     * Ensures that any classes depended on by this policy provider are
+     * resolved.  This is to preclude lazy resolution of such classes during
+     * operation of the provider, which can result in deadlock as described by
+     * bug 4911907.
+     */
+    public void ensureDependenciesResolved() {
+	// force class resolution by pre-invoking method called by implies()
+	getDomainPermissions(sysDomain);
+    }
+
+    private DomainPermissions getDomainPermissions(ProtectionDomain pd) {
+	DomainPermissions dp;
+	synchronized (domainPerms) {
+	    dp = (DomainPermissions) domainPerms.get(pd);
+	}
+	if (dp == null) {
+	    dp = new DomainPermissions(pd);
+	    globalGrants.register(dp);
+	    if (pd != null) {
+		getLoaderGrants(pd.getClassLoader()).register(dp);
+	    }
+	    synchronized (domainPerms) {
+		domainPerms.put(pd, dp);
+	    }
+	}
+	return dp;
+    }
+
+    private Grants getLoaderGrants(ClassLoader ldr) {
+	synchronized (loaderGrants) {
+	    Grants g = (Grants) loaderGrants.get(ldr);
+	    if (g == null) {
+		loaderGrants.put(ldr, g = new Grants());
+	    }
+	    return g;
+	}
+    }
+
+    private static ClassLoader getClassLoader(final Class cl) {
+	return (ClassLoader) AccessController.doPrivileged(
+	    new PrivilegedAction() {
+		public Object run() { return cl.getClassLoader(); }
+	    });
+    }
+
+    private static void checkDomain(final Class cl) {
+	ProtectionDomain pd = (ProtectionDomain) AccessController.doPrivileged(
+	    new PrivilegedAction() {
+		public Object run() { return cl.getProtectionDomain(); }
+	    });
+	if (pd != sysDomain && pd.getClassLoader() == null) {
+	    throw new UnsupportedOperationException(
+		"ungrantable protection domain");
+	}
+    }
+
+    private static void checkNullElements(Object[] array) {
+	for (int i = 0; i < array.length; i++) {
+	    if (array[i] == null) {
+		throw new NullPointerException();
+	    }
+	}
+    }
+
+    /**
+     * Class which holds permissions and principals of a ProtectionDomain. The
+     * domainPerms map associates ProtectionDomain instances to instances of
+     * this class.
+     */
+    private class DomainPermissions {
+
+	private final Set principals;
+	private final PermissionCollection perms;
+	private final List grants = new ArrayList();
+
+	DomainPermissions(ProtectionDomain pd) {
+	    Principal[] pra;
+	    principals = (pd != null && (pra = pd.getPrincipals()).length > 0)
+		? new HashSet(Arrays.asList(pra)) : Collections.EMPTY_SET;
+	    perms = cacheBasePerms ? basePolicy.getPermissions(pd) : null;
+	}
+
+	Set getPrincipals() {
+	    return principals;
+	}
+
+	synchronized void add(Permission[] pa) {
+	    for (int i = 0; i < pa.length; i++) {
+		Permission p = pa[i];
+		grants.add(p);
+		if (perms != null) {
+		    perms.add(p);
+		}
+	    }
+	}
+
+	synchronized PermissionCollection getPermissions(ProtectionDomain d) {
+	    return getPermissions(true, d);
+	}
+
+	synchronized boolean implies(Permission p, ProtectionDomain domain) {
+//            System.out.println("Permission: " + p.toString() + 
+//                    " ProtectionDomain: " + domain.toString());
+	    if (perms != null) {
+		return perms.implies(p);
+	    }
+	    if (basePolicy.implies(domain, p)) {
+		return true;
+	    }
+	    if (grants.isEmpty()) {
+		return false;
+	    }
+	    return getPermissions(false, domain).implies(p);
+	}
+
+	private PermissionCollection getPermissions(boolean compact,
+						    ProtectionDomain domain)
+        {
+	    // base policy permission collection may not be enumerable
+	    assert Thread.holdsLock(this);
+	    PermissionCollection pc = basePolicy.getPermissions(domain);
+	    for (Iterator i = grants.iterator(); i.hasNext(); ) {
+		Permission p = (Permission) i.next();
+		if (!(compact && pc.implies(p))) {
+		    pc.add(p);
+		}
+	    }
+	    return pc;
+	}
+    }
+
+    /**
+     * Class which tracks dynamic permission grants.
+     */
+    private static class Grants {
+
+	private final Map principalGrants = new HashMap();
+	private final WeakGroup scope;
+
+	Grants() {
+	    PrincipalGrants pg = new PrincipalGrants();
+	    principalGrants.put(Collections.EMPTY_SET, pg);
+	    scope = pg.scope;
+	}
+
+	synchronized void add(Principal[] pra, Permission[] pa) {
+	    Set prs = (pra != null && pra.length > 0) ?
+		new HashSet(Arrays.asList(pra)) : Collections.EMPTY_SET;
+
+	    PrincipalGrants pg = (PrincipalGrants) principalGrants.get(prs);
+	    if (pg == null) {
+		pg = new PrincipalGrants();
+		for (Iterator i = scope.iterator(); i.hasNext();) {
+		    DomainPermissions dp = (DomainPermissions) i.next();
+		    if (containsAll(dp.getPrincipals(), prs)) {
+			pg.scope.add(dp);
+		    }
+		}
+		principalGrants.put(prs, pg);
+	    }
+	    
+	    ArrayList l = new ArrayList();
+	    for (int i = 0; i < pa.length; i++) {
+		Permission p = pa[i];
+		if (!pg.perms.implies(p)) {
+		    pg.perms.add(p);
+		    l.add(p);
+		}
+	    }
+	    
+	    if (l.size() > 0) {
+		pa = (Permission[]) l.toArray(new Permission[l.size()]);
+		for (Iterator i = pg.scope.iterator(); i.hasNext();) {
+		    ((DomainPermissions) i.next()).add(pa);
+		}
+	    }
+	}
+
+	synchronized Permission[] get(Principal[] pra) {
+	    Set prs = (pra != null && pra.length > 0) ?
+		new HashSet(Arrays.asList(pra)) : Collections.EMPTY_SET;
+	    List l = new ArrayList();
+
+	    for (Iterator i = principalGrants.entrySet().iterator();
+		 i.hasNext(); )
+	    {
+		Map.Entry me = (Map.Entry) i.next();
+		if (containsAll(prs, (Set) me.getKey())) {
+		    PrincipalGrants pg = (PrincipalGrants) me.getValue();
+		    l.addAll(Collections.list(pg.perms.elements()));
+		}
+	    }
+	    return (Permission[]) l.toArray(new Permission[l.size()]);
+	}
+
+	synchronized void register(DomainPermissions dp) {
+	    Set prs = dp.getPrincipals();
+	    for (Iterator i = principalGrants.entrySet().iterator(); 
+		 i.hasNext(); ) 
+	    {
+		Map.Entry me = (Map.Entry) i.next();
+		if (containsAll(prs, (Set) me.getKey())) {
+		    PrincipalGrants pg = (PrincipalGrants) me.getValue();
+		    pg.scope.add(dp);
+		    List l = Collections.list(pg.perms.elements());
+		    dp.add((Permission[]) l.toArray(new Permission[l.size()]));
+		}
+	    }
+	}
+
+	private static boolean containsAll(Set s1, Set s2) {
+	    return (s1.size() >= s2.size()) && s1.containsAll(s2);
+	}
+	
+	private static class PrincipalGrants {
+	    final WeakGroup scope = new WeakGroup();
+	    final PermissionCollection perms = new Permissions();
+	    PrincipalGrants() {}
+	}
+    }
+
+    /**
+     * Grouping of non-null, weakly-referenced objects. The structure is a
+     * doubly linked list. The resulting structure is not thread safe and
+     * must be synchronized externally.
+     */
+    private static class WeakGroup {
+	private final ReferenceQueue rq = new ReferenceQueue();
+	private final Node head;
+	private final Node tail;
+	
+	WeakGroup() {
+	    head = Node.createEmptyList();
+	    tail = head.getNext();
+	}
+	
+	void add(Object obj) {
+	    if (obj == null) {
+		throw new NullPointerException();
+	    }
+	    processQueue();
+	    Node newNode = new Node(obj, rq);
+	    newNode.insertAfter(head);
+	}
+	
+	Iterator iterator() {
+	    processQueue();
+	    return new Iterator() {
+		private Node curNode = head.getNext();
+		private Object nextObj = getNext();
+
+		public Object next() {
+		    if (nextObj == null) {
+			throw new NoSuchElementException();
+		    }
+		    Object obj = nextObj;
+		    nextObj = getNext();
+		    return obj;
+		}
+		
+		public boolean hasNext() {
+		    return nextObj != null;
+		}
+		
+		public void remove() {
+		    throw new UnsupportedOperationException();
+		}
+		
+		private Object getNext() {
+		    while (curNode != tail) {
+			Object obj = curNode.get();
+			if (obj != null) {
+			    curNode = curNode.getNext();
+			    return obj;
+			} else {
+			    curNode.enqueue();
+			    curNode = curNode.getNext();
+			}
+		    }
+		    return null;
+		}
+	    };
+	}
+	
+	private void processQueue() {
+	    Node n;
+	    while ((n = (Node) rq.poll()) != null) {
+		n.remove();
+	    }
+	}
+
+	private static class Node extends WeakReference {
+	    private Node next;
+	    private Node prev;
+	    
+	    static Node createEmptyList() {
+		Node head = new Node(null);
+		Node tail = new Node(null);
+		head.next = tail;
+		tail.prev = head;
+		return head;
+	    }
+	    
+	    // Constructor for initialization of head and tail nodes which
+	    // should never be enqueued. 
+	    private Node(Object obj) {
+		super(obj);
+	    }
+
+	    Node(Object obj, ReferenceQueue rq) {
+		super(obj, rq);
+	    }
+	    
+	    /**
+	     * Inserts this node between <code>pred</code> and its successor
+	     */
+	    void insertAfter(Node pred) {
+		Node succ = pred.next;
+		next = succ;
+		prev = pred;
+		pred.next = this;
+		succ.prev = this;
+	    }
+	    
+	    void remove() {
+		prev.next = next;
+		next.prev = prev;
+	    }
+	    
+	    Node getNext() {
+		return next;
+	    }
+	}
+    }
+
+    public void revoke(Class cl, Principal[] principals, Permission[] permissions) {
+        throw new UnsupportedOperationException("Revoke not supported.");
+    }
+
+    public boolean revokeSupported() {
+        return false;
+    }
+
+    public Object parameters() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+}

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

Added: incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPermissions.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPermissions.java?rev=943285&view=auto
==============================================================================
--- incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPermissions.java (added)
+++ incubator/river/jtsk/trunk/src/org/apache/river/imp/security/policy/concurrent/ConcurrentPermissions.java Tue May 11 20:37:47 2010
@@ -0,0 +1,331 @@
+/*
+ * 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.io.Serializable;
+import java.security.AllPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
+import java.security.UnresolvedPermission;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+/**
+ * Example Implementation alternative of Permissions implemented for concurrency, 
+ * note this couldn't extend Permissions as it is declared final.
+ * 
+ * Note that if there is heavy contention for one Permission class
+ * type, due to synchronization, concurrency will
+ * suffer.  This is due to the original PermissionsCollection spec requiring
+ * that all implementations do their own synchronization, this is a design
+ * mistake, similar to Vector. 
+ * 
+ * This is an example class without optimisation, it will be slower
+ * for single threaded applications and consume more memory.
+ * 
+ * It would also be possible to create an unlock method that permitted
+ * adding or revoking permissions to this collection while it is referenced
+ * from within a PermissionDomain, however that would break the contract of
+ * setReadOnly().  This might make sense if implementing a SecurityManager or
+ * it might not, it's just an observation that Permissions defined in policy
+ * files, which are not dynamically granted, are not revokeable as a
+ * Policy only augments the PermissionCollection associated with (referenced by)
+ * a PermissionDomain.  However it would probably be best to extend
+ * ProtectionDomain to alter this behaviour as it merges PermissionCollection's,
+ * so you would end up with the Permissions implementation again, unless using the
+ * constructor that sets the permissions as static, which is totally
+ * contradictory.  So the best way to make a Permission revokeable is to 
+ * grant it dynamically.
+ * 
+ * TODO: Serialization properly
+ * @version 0.4 2009/11/10
+ * 
+ * @author Peter Firmstone
+ * @serial permsMap
+ */
+public final class ConcurrentPermissions extends PermissionCollection 
+implements Serializable, RevokeablePermissionCollection  {
+
+    private static final long serialVersionUID=1L;
+    /* unresolved is never returned or allowed to escape, it's elements() method
+     * isn't used to return an Enumeration yet 
+     * Duplicate Permissions could potentially be returned if unresolved is
+     * enumerated first.
+     * For a ProtectionDomain object, duplicates are dropped by 
+     * java.security.AccessControlContext
+     * This creates issues with java.security.AccessControlContext and
+     * causes it to throw an exception.
+     */ 
+    private transient final PermissionPendingResolutionCollection unresolved;
+    private ConcurrentHashMap<Class<?>, PermissionCollection> permsMap;
+    private transient volatile boolean allPermission;
+    
+    /* Let Permissions, UnresolvedPermission and 
+     * UnresolvedPermissionCollection resolve all unresolved permission's
+     * it saves reimplementing package private methods.  This is done by adding
+     * a Permissions object instance to handle all UnresolvedPermissions.
+     */    
+    
+    public ConcurrentPermissions(){
+        permsMap = new ConcurrentHashMap<Class<?>, PermissionCollection>();
+        // Bite the bullet, get the pain out of the way in the beginning!
+        unresolved = new PermissionPendingResolutionCollection();
+        allPermission = false;      
+    }
+    
+    /**
+     * Threadsafe
+     * @param permission
+     */   
+    @Override
+    public void add(Permission permission) {
+        if (permission == null){return;}
+        if (super.isReadOnly()) {
+            throw new SecurityException("attempt to add a Permission to a readonly Permissions object");
+        } 
+        if (permission instanceof AllPermission) {allPermission = true;}
+        if (permission instanceof UnresolvedPermission) {          
+            unresolved.add(new PermissionPendingResolution((UnresolvedPermission)permission));            
+        }
+        // this get saves unnecessary object creation.
+        PermissionCollection pc = permsMap.get(permission.getClass());
+        if (pc != null){                       
+            pc.add(permission);
+            return;             
+        }
+        // A null instance occurs when a PermissionCollection was absent.
+        pc = permsMap.putIfAbsent(permission.getClass(), new MultiReadPermissionCollection(permission));                                  
+        // If This is the first time the PermissionCollection was added
+        // we must still add the permission, see Add the permission below.
+        // The putIfAbsent will succeed, and as a result pc is null, provided another
+        // thread doesn't add the permission between this put and the last get.
+        // Just in case, we check the return value of the putIfAbsent, if
+        // pc != null then another thread has alreaddy added a PermissionCollection
+        if (pc != null){            
+            pc.add(permission);
+            return;
+        }
+        // Add the permission if it missed out due to unlucky timing.
+        pc = permsMap.get(permission.getClass());
+        pc.add(permission);        
+    }    
+    
+    /**
+     * Returns true if Permission is implied for this PermissionDomain.
+     * Threadsafe this method is also a mutator method for internal state
+     * 
+     * @see Permission
+     * @param permission
+     * @return boolean
+     */
+    @Override
+    public boolean implies(Permission permission) {
+        if (permission == null){return false;}
+        if (allPermission == true){return true;}
+        if (permission instanceof UnresolvedPermission){return false;}        
+        PermissionCollection pc = permsMap.get(permission.getClass()); // To stop unnecessary object creation
+        if (pc != null && pc.implies(permission)) { return true;}
+        if (unresolved.awaitingResolution() == 0 ) { return false; }
+        PermissionCollection existed = null;
+        if (pc == null){
+            pc = new MultiReadPermissionCollection(permission); // once added it cannot be removed atomically.
+            existed = permsMap.putIfAbsent(permission.getClass(), pc);
+            if (existed != null) {
+                pc = existed;
+                }
+        }
+        unresolved.resolveCollection(permission, pc); // drop the returned collection its the same as the one passed in.
+        return pc.implies(permission);
+    }
+    
+    /**
+     * This Enumeration is not intended for concurrent access,
+     * PermissionCollection's underlying state is protected by defensive copying, 
+     * it wont affect the thread safety of ConcurrentPermission.
+     * 
+     * Any number of these Enumerations may be utilised , each accessed by 
+     * a separate thread.
+     * 
+     * This Enumeration may contain duplicates
+     * 
+     * @return Enumeration<Permission>
+     */
+    @Override
+    public Enumeration<Permission> elements() {
+        Enumeration<PermissionCollection> perms = permsMap.elements();
+        return new PermissionEnumerator(perms);                 
+    }
+    
+    /**
+     * Attempt to resolve any unresolved permissions whose class is visible
+     * from within this protection domain.
+     * @param pd 
+     */
+    public void resolve(ProtectionDomain pd){
+        if (unresolved.awaitingResolution() == 0){return;}
+        Enumeration<Permission> perms = unresolved.resolvePermissions(pd);
+        while (perms.hasMoreElements()){
+            add(perms.nextElement());
+        }
+    }
+    
+    /*
+     * This Enumeration is not intended for concurrent access,
+     * PermissionCollection's underlying state is protected by defensive copying, 
+     * it wont affect the thread safety of ConcurrentPermission.
+     * 
+     * This enumeration doesn't include unresolved permissions is that a problem?
+     * 
+     * Any number of these Enumerations may be utilised , each accessed by 
+     * a separate thread.
+     * 
+     * @author Peter Firmstone
+     */
+    private final static class PermissionEnumerator implements Enumeration<Permission> {
+        private final Enumeration<PermissionCollection> epc;
+        private volatile Enumeration<Permission> currentPermSet;
+
+        PermissionEnumerator(Enumeration<PermissionCollection> epc){
+            this.epc = epc;
+            currentPermSet = getNextPermSet();
+        }
+
+        private Enumeration<Permission> getNextPermSet(){
+            Set<Permission> permissionSet = new HashSet<Permission>();
+            if (epc.hasMoreElements()){
+                PermissionCollection pc = epc.nextElement();               
+                /* Local copy of the set containing a snapshot of 
+                 * references to Permission objects present at an instant in time,
+                 * we can Enumerate over, without contention or exception.  
+                 * We only take what we need as we need it, minimising memory.
+                 * Each object gets its own Enumeration.
+                 */
+                if ( pc instanceof Permissions){
+                    synchronized (pc){
+                        Enumeration<Permission> e = pc.elements();
+                        while (e.hasMoreElements()) {
+                            permissionSet.add(e.nextElement());
+                        }
+                    }
+                } else {
+                    Enumeration<Permission> e = pc.elements();
+                    while (e.hasMoreElements()) {
+                        permissionSet.add(e.nextElement());
+                    }
+                }
+            }
+            return Collections.enumeration(permissionSet);
+        }
+
+        public boolean hasMoreElements() {        
+            if (currentPermSet.hasMoreElements()){return true;}          
+            currentPermSet = getNextPermSet();
+            return currentPermSet.hasMoreElements();           
+        }
+
+        public Permission nextElement() {
+            if (hasMoreElements()){              
+                return currentPermSet.nextElement();               
+            } else {
+                throw new NoSuchElementException("PermissionEnumerator");
+            }
+        }
+    }
+
+    public int revoke(Permission ... permissions) {
+        
+        // build a hashmap to put all permissions into, grouped by class.
+        HashMap<Class<?>, Integer> results = new HashMap<Class<?>, Integer>();
+        HashMap<Class<?>, ArrayList<Permission>> groups = new HashMap<Class<?>, ArrayList<Permission>>();
+        int size = permissions.length;
+        for (int i = 0; i < size; i++ ){
+            Permission permission = permissions[i];
+            //Make sure that any unresolved permissions have been resolved first
+            //Don't bother revoking if it doesn't imply
+            if ( !implies(permission)){
+                continue;
+            }
+            ArrayList<Permission> permissionClassGroup = groups.get(permission.getClass());
+            if (permissionClassGroup == null){
+                permissionClassGroup = new ArrayList<Permission>();
+                groups.put(permissions[i].getClass(), permissionClassGroup);
+            }
+            permissionClassGroup.add(permission); // still holds a reference
+        }
+        // process each group by class, if all succeed return 1, if one or more has
+        // an issue with an intervening write return 0.
+        // If any fail, return -1
+        Set<Class<?>> classes = groups.keySet();
+        Iterator<Class<?>> itr = classes.iterator();
+        while (itr.hasNext()){
+            Class<?> permissionClass = itr.next();
+            RevokeablePermissionCollection current = 
+                    (RevokeablePermissionCollection) permsMap.get(permissionClass);
+            int result = 1; // If it doesn't exist then it must succeed.
+            if (current != null){
+                ArrayList<Permission> permissionGroupToRevoke = groups.get(permissionClass);
+                Permission permissionList[] = new Permission[permissionGroupToRevoke.size()];
+                permissionGroupToRevoke.toArray(permissionList);
+                result = current.revoke( permissionList );
+            }
+            results.put(permissionClass, result);
+        }
+        // Now determine the results and return
+        int result = 1;
+        Iterator<Integer> itresult = results.values().iterator();
+        while (itresult.hasNext()){
+            int thisResult = itresult.next();
+            if (thisResult < result) { result = thisResult; }
+        }
+        return result;
+    }
+    
+    
+    public void revokeAll(Permission permission) {
+        PermissionCollection pc = permsMap.get(permission.getClass());
+        if ( pc == null ){
+            pc = new MultiReadPermissionCollection(permission);
+            PermissionCollection exists = permsMap.putIfAbsent(permission.getClass(),pc);
+            if ( exists != null ){
+                pc = exists;
+            }
+        unresolved.resolveCollection(permission, pc);          
+        }
+        // Any permissions added by other threads in the interim will be
+        // revoked when this method completes.
+        // We won't avoid permission loss by only emptying the collection either,
+        // however since
+        // the intent will be probably to temporarily revoke a permission
+        // when a proxy is required to be refreshed, it should be more efficient.
+        //permsMap.remove(permission.getClass(), pc);
+        RevokeablePermissionCollection rpc = (RevokeablePermissionCollection) pc;
+        rpc.revokeAll(permission);
+    }
+
+}

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