You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by le...@apache.org on 2007/06/19 03:51:03 UTC

svn commit: r548552 - in /harmony/enhanced/classlib/branches/java6/modules/security/src: main/java/common/java/security/ main/java/common/org/apache/harmony/security/fortress/ main/java/common/org/apache/harmony/security/provider/ test/impl/java/org/ap...

Author: leoli
Date: Mon Jun 18 18:51:02 2007
New Revision: 548552

URL: http://svn.apache.org/viewvc?view=rev&rev=548552
Log:
Add Java 6 new APIs to java.security.Policy.

Added:
    harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/provider/PolicySpiImpl.java
Modified:
    harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/java/security/Policy.java
    harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicy.java
    harmony/enhanced/classlib/branches/java6/modules/security/src/test/impl/java/org/apache/harmony/security/tests/java/security/Policy_ImplTest.java

Modified: harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/java/security/Policy.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/java/security/Policy.java?view=diff&rev=548552&r1=548551&r2=548552
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/java/security/Policy.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/java/security/Policy.java Mon Jun 18 18:51:02 2007
@@ -25,6 +25,7 @@
 import java.util.Enumeration;
 
 import org.apache.harmony.security.fortress.DefaultPolicy;
+import org.apache.harmony.security.fortress.Engine;
 import org.apache.harmony.security.fortress.PolicyUtils;
 import org.apache.harmony.security.internal.nls.Messages;
 
@@ -34,20 +35,319 @@
  * 
  */
 public abstract class Policy {
-    
-    // Key to security properties, defining default policy provider.
-    private static final String POLICY_PROVIDER = "policy.provider"; //$NON-NLS-1$
-
-    // The SecurityPermission required to set custom Policy.
-    private static final SecurityPermission SET_POLICY = new SecurityPermission(
-            "setPolicy"); //$NON-NLS-1$
-
-    // The SecurityPermission required to get current Policy.
-    private static final SecurityPermission GET_POLICY = new SecurityPermission(
-            "getPolicy"); //$NON-NLS-1$
 
-    // The policy currently in effect. 
-    private static Policy activePolicy;
+	// Key to security properties, defining default policy provider.
+	private static final String POLICY_PROVIDER = "policy.provider"; //$NON-NLS-1$
+
+	// The SecurityPermission required to set custom Policy.
+	private static final SecurityPermission SET_POLICY = new SecurityPermission(
+			"setPolicy"); //$NON-NLS-1$
+
+	// The SecurityPermission required to get current Policy.
+	private static final SecurityPermission GET_POLICY = new SecurityPermission(
+			"getPolicy"); //$NON-NLS-1$
+
+	// The policy currently in effect.
+	private static Policy activePolicy;
+
+	// Store spi implementation service name
+	private static final String POLICYSERVICE = "Policy"; //$NON-NLS-1$
+
+	// Used to access common engine functionality
+	private static Engine engine = new Engine(POLICYSERVICE);
+
+	private String type;
+
+	private Policy.Parameters params;
+
+	private Provider provider;
+
+	// Store used spi implementation
+	private PolicySpi spiImpl;
+	
+	private static final String CREATE_POLICY = "createPolicy."; //$NON-NLS-1$
+
+	public Policy() {
+		// default constructor
+	}
+
+	private Policy(PolicySpi spi, Provider p, String t, Policy.Parameters para) {
+		this.spiImpl = spi;
+		this.provider = p;
+		this.type = t;
+		this.params = para;
+	}
+
+	private static class PolicyDelegate extends Policy {
+
+		public PolicyDelegate(PolicySpi spi, Provider p, String t,
+				Policy.Parameters para) {
+			super(spi, p, t, para);
+		}
+	}
+
+	/**
+	 * Answers a Policy object with the specified type and the specified
+	 * parameter.
+	 * 
+	 * Traverses the list of registered security providers, beginning with the
+	 * most preferred Provider. A new Policy object encapsulating the PolicySpi
+	 * implementation from the first Provider that supports the specified type
+	 * is returned.
+	 * 
+	 * Note that the list of registered providers may be retrieved via the
+	 * Security.getProviders() method.
+	 * 
+	 * @param type -
+	 *            the specified Policy type. See Appendix A in the Java
+	 *            Cryptography Architecture API Specification & Reference for a
+	 *            list of standard Policy types.
+	 * @param params -
+	 *            parameters for the Policy, which may be null.
+	 * @return the new Policy object.
+	 * @throws NoSuchAlgorithmException -
+	 *             if no Provider supports a PolicySpi implementation for the
+	 *             specified type.
+	 * @throws SecurityException -
+	 *             if the caller does not have permission to get a Policy
+	 *             instance for the specified type.
+	 * @throws NullPointerException -
+	 *             if the specified type is null.
+	 * @throws IllegalArgumentException -
+	 *             if the specified parameters' type are not allowed by the
+	 *             PolicySpi implementation from the selected Provider.
+	 * 
+	 * @since 1.6
+	 */
+	public static Policy getInstance(String type, Policy.Parameters params)
+			throws NoSuchAlgorithmException {
+		checkSecurityPermission(new SecurityPermission(CREATE_POLICY + type));
+		
+		if (type == null) {
+			throw new NullPointerException();
+		}
+
+		try {
+            synchronized (engine) {
+                engine.getInstance(type, params);
+                return new PolicyDelegate((PolicySpi) engine.spi,
+                        engine.provider, type, params);
+            }
+
+        } catch (NoSuchAlgorithmException e) {
+            if (e.getCause() == null) {
+                throw e;
+            }
+            throw new IllegalArgumentException(Messages.getString(
+                    "security.1A7", params.toString())); //$NON-NLS-1$
+        }
+	}
+
+	/**
+	 * Answers a Policy object of the specified type.
+	 * 
+	 * A new Policy object encapsulating the PolicySpi implementation from the
+	 * specified provider is returned. The specified provider must be registered
+	 * in the provider list via the Security.getProviders() method, otherwise
+	 * NoSuchProviderException will be thrown.
+	 * 
+	 * @param type -
+	 *            the specified Policy type. So far in Java 6, only 'JavaPolicy'
+	 *            supported.
+	 * @param params -
+	 *            the Policy.Parameter object, which may be null.
+	 * @param provider -
+	 *            the provider.
+	 * @return the new Policy object.
+	 * 
+	 * @throws NoSuchProviderException -
+	 *             if the specified provider is not registered in the security
+	 *             provider list.
+	 * @throws NoSuchAlgorithmException -
+	 *             if the specified provider does not support a PolicySpi
+	 *             implementation for the specified type.
+	 * @throws SecurityException -
+	 *             if the caller does not have permission to get a Policy
+	 *             instance for the specified type.
+	 * @throws NullPointerException -
+	 *             if the specified type is null.
+	 * @throws IllegalArgumentException -
+	 *             if the specified Provider is null, or if the specified
+	 *             parameters' type are not allowed by the PolicySpi
+	 *             implementation from the specified Provider.
+	 * 
+	 * @since 1.6
+	 */
+	public static Policy getInstance(String type, Policy.Parameters params,
+			String provider) throws NoSuchProviderException,
+			NoSuchAlgorithmException {
+		if ((provider == null) || provider.isEmpty()) {
+			throw new IllegalArgumentException(Messages
+					.getString("security.02")); //$NON-NLS-1$
+		}
+		checkSecurityPermission(new SecurityPermission(CREATE_POLICY + type));
+		
+		Provider impProvider = Security.getProvider(provider);
+		if (impProvider == null) {
+			throw new NoSuchProviderException(Messages.getString("security.03", //$NON-NLS-1$
+					provider));
+		}
+		
+		return getInstanceImpl(type, params, impProvider);
+	}
+
+	/**
+	 * Answers a Policy object of the specified type.
+	 * 
+	 * A new Policy object encapsulating the PolicySpi implementation from the
+	 * specified Provider object is returned. Note that the specified Provider
+	 * object does not have to be registered in the provider list.
+	 * 
+	 * @param type -
+	 *            the specified Policy type. So far in Java 6, only 'JavaPolicy'
+	 *            supported.
+	 * @param params -
+	 *            the Policy.Parameter object, which may be null.
+	 * @param provider -
+	 *            the Policy service Provider.
+	 * @return the new Policy object.
+	 * 
+	 * @throws NoSuchAlgorithmException -
+	 *             if the specified Provider does not support a PolicySpi
+	 *             implementation for the specified type.
+	 * @throws IllegalArgumentException -
+	 *             if the specified Provider is null, or if the specified
+	 *             parameters' type are not allowed by the PolicySpi
+	 *             implementation from the specified Provider.
+	 * @throws NullPointerException -
+	 *             if the specified type is null.
+	 * @throws SecurityException -
+	 *             if the caller does not have permission to get a Policy
+	 *             instance for the specified type.
+	 * @since 1.6
+	 */
+	public static Policy getInstance(String type, Policy.Parameters params,
+			Provider provider) throws NoSuchAlgorithmException {
+		if (provider == null) {
+			throw new IllegalArgumentException("security.04"); //$NON-NLS-1$
+		}
+		checkSecurityPermission(new SecurityPermission(CREATE_POLICY + type));
+
+		return getInstanceImpl(type, params, provider);
+	}
+
+	private static void checkSecurityPermission(SecurityPermission permission) {
+		SecurityManager sm = System.getSecurityManager();
+		if (sm != null) {
+			sm.checkPermission(permission); 
+		}
+	}
+
+	private static Policy getInstanceImpl(String type, Policy.Parameters params, Provider provider) throws NoSuchAlgorithmException {
+		if (type == null) {
+			throw new NullPointerException();
+		}
+
+		try {
+            synchronized (engine) {
+                engine.getInstance(type, provider, params);
+                return new PolicyDelegate((PolicySpi) engine.spi, provider,
+                        type, params);
+            }
+        } catch (NoSuchAlgorithmException e) {
+            if (e.getCause() == null) {
+                throw e;
+            }
+            throw new IllegalArgumentException(Messages.getString(
+                    "security.1A7", params.toString())); //$NON-NLS-1$
+        }
+	}
+
+	/**
+	 * Answers Policy parameters.
+	 * 
+	 * This method will only answer non-null parameters if it was obtained via a
+	 * call to Policy.getInstance. Otherwise this method returns null.
+	 * 
+	 * @return Policy parameters, or null.
+	 * 
+	 * @since 1.6
+	 */
+	public Policy.Parameters getParameters() {
+		return params;
+	}
+
+	/**
+	 * Answers the Provider of this Policy.
+	 * 
+	 * This method will only answer non-null Provider if it was obtained via a
+	 * call to Policy.getInstance. Otherwise this method returns null.
+	 * 
+	 * @return the Provider of this Policy, or null.
+	 * 
+	 * @since 1.6
+	 */
+	public Provider getProvider() {
+		return provider;
+	}
+
+	/**
+	 * Answers the type of this Policy.
+	 * 
+	 * This method will only answer non-null type if it was obtained via a call
+	 * to Policy.getInstance. Otherwise this method returns null.
+	 * 
+	 * @return the type of this Policy, or null.
+	 * 
+	 * @since 1.6
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * A read-only empty PermissionCollection instance.
+	 * 
+	 * @since 1.6
+	 */
+	public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION = new PermissionCollection() {
+
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void add(Permission permission) {
+			throw new SecurityException(Messages.getString("security.1A5")); //$NON-NLS-1$
+		}
+
+		@Override
+		public Enumeration<Permission> elements() {
+			return new Permissions().elements();
+		}
+
+		@Override
+		public boolean implies(Permission permission) {
+			if (permission == null) {
+				throw new NullPointerException();
+			}
+			return false;
+		}
+
+		@Override
+		public boolean isReadOnly() {
+			// always returns true since it is a read-only instance.
+			// RI does not override this method.
+			return true;
+		}
+	};
+
+	/**
+	 * A marker interface for Policy parameters.
+	 * 
+	 * @since 1.6
+	 */
+	public static interface Parameters {
+		// a marker interface
+	}
 
 	/**
 	 * Answers a PermissionCollection describing what permissions are available
@@ -63,7 +363,10 @@
 	 *            CodeSource the code source to compute the permissions for.
 	 * @return PermissionCollection the permissions the code source should have.
 	 */
-    public abstract PermissionCollection getPermissions(CodeSource cs);
+	public PermissionCollection getPermissions(CodeSource cs) {
+		return spiImpl == null ? Policy.UNSUPPORTED_EMPTY_COLLECTION : spiImpl
+				.engineGetPermissions(cs);
+	}
 
 	/**
 	 * Reloads the policy configuration, depending on how the type of source
@@ -71,7 +374,11 @@
 	 * 
 	 * 
 	 */
-    public abstract void refresh();
+	public void refresh() {
+		if (spiImpl != null) {
+			spiImpl.engineRefresh();			
+		}
+	}
 
 	/**
 	 * Answers a PermissionCollection describing what permissions are available
@@ -83,12 +390,32 @@
 	 *            permissions for.
 	 * @return PermissionCollection the permissions the code source should have.
 	 */
-    public PermissionCollection getPermissions(ProtectionDomain domain) {
-        if (domain != null) {
-            return getPermissions(domain.getCodeSource());
-        }
-        return new Permissions();
-    }
+	public PermissionCollection getPermissions(ProtectionDomain domain) {		
+		Permissions permissions = new Permissions();
+		if (domain != null) {
+			try {
+				PermissionCollection cds = getPermissions(domain
+						.getCodeSource());
+				if (cds != Policy.UNSUPPORTED_EMPTY_COLLECTION) {
+					Enumeration<Permission> elements = cds.elements();
+					while (elements.hasMoreElements()) {
+						permissions.add(elements.nextElement());
+					}
+				}
+			} catch (NullPointerException e) {
+				// ignore the exception, just add nothing to the result set
+			}
+
+			PermissionCollection pds = domain.getPermissions();
+			if (pds != null) {
+				Enumeration<Permission> pdElements = pds.elements();
+				while (pdElements.hasMoreElements()) {
+					permissions.add(pdElements.nextElement());
+				}
+			}
+		}
+		return permissions;		
+	}
 
 	/**
 	 * Answers whether the Permission is implied by the PermissionCollection of
@@ -100,23 +427,34 @@
 	 *            Permission for which authorization is to be verified
 	 * @return boolean Permission implied by ProtectionDomain
 	 */
-    public boolean implies(ProtectionDomain domain, Permission permission) {
-        if (domain != null) {
-            PermissionCollection total = getPermissions(domain);
-            PermissionCollection inherent = domain.getPermissions();
-            if (total == null) {
-                total = inherent;
-            } else if (inherent != null) {
-                for (Enumeration en = inherent.elements(); en.hasMoreElements();) {
-                    total.add((Permission)en.nextElement());
-                }
-            }
-            if (total != null && total.implies(permission)) {
-                return true;
-            }
-        }
-        return false;
-    }
+	public boolean implies(ProtectionDomain domain, Permission permission) {
+		return spiImpl == null ? defaultImplies(domain, permission) : spiImpl
+				.engineImplies(domain, permission);
+	}
+
+	private boolean defaultImplies(ProtectionDomain domain, Permission permission) {
+		if (domain == null && permission == null) {
+			throw new NullPointerException();
+		}
+		boolean implies = false;
+		if (domain != null) {
+			PermissionCollection total = getPermissions(domain);
+			PermissionCollection inherent = domain.getPermissions();
+			if (inherent != null) {
+				Enumeration<Permission> en = inherent.elements();
+				while (en.hasMoreElements()) {
+					total.add(en.nextElement());
+				}
+			}
+			try {
+				implies = total.implies(permission);
+			} catch (NullPointerException e) {
+				// return false instead of throwing the NullPointerException
+				implies = false;
+			}
+		}
+		return implies;
+	}
 
 	/**
 	 * Answers the current system security policy. If no policy has been
@@ -125,28 +463,25 @@
 	 * 
 	 * @return Policy the current system security policy.
 	 */
-    public static Policy getPolicy() {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(GET_POLICY);
-        }
-        return getAccessiblePolicy();
-    }
-
-     // Reads name of default policy provider from security.properties,
-     // loads the class and instantiates the provider.<br> 
-     // In case of any error, including undefined provider name, 
-     // returns new instance of org.apache.harmony.security.FilePolicy provider. 
-    private static Policy getDefaultProvider() {
-        final String defaultClass = (String) AccessController
-                .doPrivileged(new PolicyUtils.SecurityPropertyAccessor(
-                        POLICY_PROVIDER));
-        if (defaultClass == null) {
-            //TODO log warning
-            //System.err.println("No policy provider specified. Loading the " 
-            //           + DefaultPolicy.class.getName());
-            return new DefaultPolicy();
-        }
+	public static Policy getPolicy() {
+		checkSecurityPermission(GET_POLICY);		
+		return getAccessiblePolicy();
+	}
+
+	// Reads name of default policy provider from security.properties,
+	// loads the class and instantiates the provider.<br>
+	// In case of any error, including undefined provider name,
+	// returns new instance of org.apache.harmony.security.FilePolicy provider.
+	private static Policy getDefaultProvider() {
+		final String defaultClass = AccessController
+				.doPrivileged(new PolicyUtils.SecurityPropertyAccessor(
+						POLICY_PROVIDER));
+		if (defaultClass == null) {
+			// TODO log warning
+			// System.err.println("No policy provider specified. Loading the "
+			// + DefaultPolicy.class.getName());
+			return new DefaultPolicy();
+		}
 
         // TODO accurate classloading
         return AccessController.doPrivileged(new PrivilegedAction<Policy>() {
@@ -167,34 +502,26 @@
             }
         });
 
-    }
-    
-    /**
-     * Returns true if system policy provider is instantiated.
-     */
-    static boolean isSet() {
-        return activePolicy != null;
-    }
+	}
 
-    /**
-     * Shortcut accessor for friendly classes, to skip security checks.
-     * If active policy was set to <code>null</code>, loads default provider, 
-     * so this method never returns <code>null</code>. <br>
-     * This method is synchronized with setPolicy()
-     */
-    static Policy getAccessiblePolicy() {
-        Policy current = activePolicy;
-        if (current == null) {
-            synchronized (Policy.class) {
-                // double check in case value has been reassigned 
-                // while we've been awaiting monitor
-                if (activePolicy == null) {
-                    activePolicy = getDefaultProvider();
-                }
-                return activePolicy;
-            }
+	/**
+	 * Returns true if system policy provider is instantiated.
+	 */
+	static boolean isSet() {
+		return activePolicy != null;
+	}
+
+	/**
+	 * Shortcut accessor for friendly classes, to skip security checks. If
+	 * active policy was set to <code>null</code>, loads default provider, so
+	 * this method never returns <code>null</code>. <br>
+	 * This method is synchronized with setPolicy()
+	 */
+	static synchronized Policy getAccessiblePolicy() {
+        if (activePolicy == null) {
+            activePolicy = getDefaultProvider();
         }
-        return current;
+        return activePolicy;
     }
 
 	/**
@@ -204,57 +531,10 @@
 	 * @param policy
 	 *            Policy the policy object that needs to be set.
 	 */
-    public static void setPolicy(Policy policy) {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(SET_POLICY);
-        }
-        synchronized (Policy.class) {
-            activePolicy = policy;
-        }
-    }
-    
-    /**
-     * A marker interface for Policy parameters.
-     * 
-     * @since 1.6
-     */
-    public static interface Parameters {
-        // a marker interface
-    }
-    
-    /**
-     * A read-only empty PermissionCollection instance.
-     * 
-     * @since 1.6
-     */
-    public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION = new PermissionCollection() {
-
-        private static final long serialVersionUID = 1L;
-
-        @Override
-        public void add(Permission permission) {
-            throw new SecurityException(Messages.getString("security.1A5")); //$NON-NLS-1$
-        }
-
-        @Override
-        public Enumeration<Permission> elements() {
-            return new Permissions().elements();
-        }
-
-        @Override
-        public boolean implies(Permission permission) {
-            if (permission == null) {
-                throw new NullPointerException();
-            }
-            return false;
-        }
-
-        @Override
-        public boolean isReadOnly() {
-            // always returns true since it is a read-only instance.
-            // RI does not override this method.
-            return true;
-        }
-    };
+	public static void setPolicy(Policy policy) {
+		checkSecurityPermission(SET_POLICY);		
+		synchronized (Policy.class) {
+			activePolicy = policy;
+		}
+	}
 }

Modified: harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicy.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicy.java?view=diff&rev=548552&r1=548551&r2=548552
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicy.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/fortress/DefaultPolicy.java Mon Jun 18 18:51:02 2007
@@ -23,6 +23,7 @@
 package org.apache.harmony.security.fortress;
 
 import java.io.File;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.security.AccessController;
 import java.security.CodeSource;
@@ -30,7 +31,9 @@
 import java.security.PermissionCollection;
 import java.security.Policy;
 import java.security.ProtectionDomain;
+import java.security.URIParameter;
 import java.util.Collection;
+import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
@@ -172,6 +175,10 @@
     public DefaultPolicy() {
         this(new DefaultPolicyParser());
     }
+    
+    public DefaultPolicy(boolean needRefresh) {
+        this(new DefaultPolicyParser(), needRefresh);
+    }
 
     /**
      * Extension constructor for plugging-in a custom parser. Defers policy data
@@ -179,9 +186,15 @@
      * (though policy may be refreshed explicitly, as well).
      */
     public DefaultPolicy(DefaultPolicyParser dpr) {
+        this(dpr, true);
+    }
+    
+    public DefaultPolicy(DefaultPolicyParser dpr, boolean needRefresh) {
         parser = dpr;
         initialized = false;
-        refresh();
+        if (needRefresh) {
+        	refreshImpl(null);      	
+        }        
     }
 
     /**
@@ -270,42 +283,85 @@
      * 
      * @see PolicyUtils#getPolicyURLs(Properties, String, String)
      */
-    public synchronized void refresh() {
-        Set<PolicyEntry> fresh = new HashSet<PolicyEntry>();
-        Properties system = new Properties(AccessController
-                .doPrivileged(new PolicyUtils.SystemKit()));
-        system.setProperty("/", File.separator); //$NON-NLS-1$
-        URL[] policyLocations = PolicyUtils.getPolicyURLs(system,
-                                                          JAVA_SECURITY_POLICY,
-                                                          POLICY_URL_PREFIX);
-        for (int i = 0; i < policyLocations.length; i++) {
-            try {
-                //TODO debug log
-                //System.err.println("Parsing policy file: " + policyLocations[i]);
-                fresh.addAll(parser.parse(policyLocations[i], system));
-            } catch (Exception e) {
-                // TODO log warning
-                //System.err.println("Ignoring policy file: " 
-                //                 + policyLocations[i] + ". Reason:\n"+ e);
-            }
-        }
-        // XXX: what if new policy is empty - provide some default??
-
-        // we could safely replace references instead of
-        // synchronizing access:
-        // <pre>
-        // grants = fresh;
-        // cache = new WeakHashMap();
-        // </pre>
-        // but there is possibility that concurrent thread will put
-        // old data to cache right after we finish refresh(),
-        // thus synchronization is added in getPermissions() methods...
-        synchronized (cache) {
-            grants.clear();
-            grants.addAll(fresh);
-
-            cache.clear();
-        }
-        initialized = true;
+    @Override
+	public synchronized void refresh() {
+    	refreshImpl(null);
     }
+    
+    public synchronized void refresh(URIParameter para) {
+    	refreshImpl(para);
+    }
+
+	private void refreshImpl(URIParameter para) {
+		Set<PolicyEntry> fresh = new HashSet<PolicyEntry>();
+		Properties system = new Properties(AccessController
+				.doPrivileged(new PolicyUtils.SystemKit()));
+		system.setProperty("/", File.separator); //$NON-NLS-1$
+		URL[] policyLocations = PolicyUtils.getPolicyURLs(system,
+				JAVA_SECURITY_POLICY, POLICY_URL_PREFIX);
+		boolean needLoadSysProp = true;
+		if (para != null) {			
+			try {
+				URL paramURL = para.getURI().toURL();
+				fresh.addAll(parser.parse(paramURL, system));
+				needLoadSysProp = false;
+			} catch (MalformedURLException e) {
+				throw new IllegalArgumentException(e);				
+			} catch (Exception e) {
+				// ignore
+			}
+		}
+		
+		if (needLoadSysProp) {
+			for (int i = 0; i < policyLocations.length; i++) {
+				try {
+					fresh.addAll(parser.parse(policyLocations[i], system));
+					//System.out.println(policyLocations[i]);
+				} catch (Exception e) {										
+					// just ignore the invalid policy file
+				}
+			}
+		}
+				
+		// XXX: what if new policy is empty - provide some default??
+
+		// we could safely replace references instead of
+		// synchronizing access:
+		// <pre>
+		// grants = fresh;
+		// cache = new WeakHashMap();
+		// </pre>
+		// but there is possibility that concurrent thread will put
+		// old data to cache right after we finish refresh(),
+		// thus synchronization is added in getPermissions() methods...
+		synchronized (cache) {
+			grants.clear();
+			grants.addAll(fresh);
+
+			cache.clear();
+		}
+		initialized = true;
+	}
+    
+	@Override
+	public boolean implies(ProtectionDomain domain, Permission permission) {
+		if (permission == null) {
+			throw new NullPointerException();
+		}
+		boolean implies = false;
+		if (domain != null) {
+			PermissionCollection total = getPermissions(domain);
+			PermissionCollection inherent = domain.getPermissions();
+			if (inherent != null) {
+				Enumeration<Permission> en = inherent.elements();
+				while (en.hasMoreElements()) {
+					total.add(en.nextElement());
+				}
+			}
+			implies = total.implies(permission);
+		}
+		return implies;
+	}
+    
+    
 }

Added: harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/provider/PolicySpiImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/provider/PolicySpiImpl.java?view=auto&rev=548552
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/provider/PolicySpiImpl.java (added)
+++ harmony/enhanced/classlib/branches/java6/modules/security/src/main/java/common/org/apache/harmony/security/provider/PolicySpiImpl.java Mon Jun 18 18:51:02 2007
@@ -0,0 +1,70 @@
+/*
+ *  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.harmony.security.provider;
+
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PolicySpi;
+import java.security.ProtectionDomain;
+import java.security.URIParameter;
+
+import org.apache.harmony.security.fortress.DefaultPolicy;
+
+public class PolicySpiImpl extends PolicySpi {
+	private DefaultPolicy defaultPolicy = null;
+	
+	private URIParameter para = null;
+
+	public PolicySpiImpl() {
+		defaultPolicy = new DefaultPolicy(false);
+		engineRefreshImpl();
+	}
+	
+	public PolicySpiImpl(URIParameter params) {
+		defaultPolicy = new DefaultPolicy(false);
+		para = params;
+		engineRefreshImpl();
+	}
+
+	@Override
+	protected boolean engineImplies(ProtectionDomain domain,
+			Permission permission) {
+		return defaultPolicy.implies(domain, permission);
+	}
+
+	@Override
+	protected PermissionCollection engineGetPermissions(CodeSource codesource) {
+		return defaultPolicy.getPermissions(codesource);
+	}
+
+	@Override
+	public PermissionCollection engineGetPermissions(ProtectionDomain pd) {
+		return defaultPolicy.getPermissions(pd);
+	}
+	
+	
+	@Override
+	public void engineRefresh() {
+		engineRefreshImpl();
+	}
+
+	private synchronized void engineRefreshImpl() {
+		defaultPolicy.refresh(para);
+	}
+}

Modified: harmony/enhanced/classlib/branches/java6/modules/security/src/test/impl/java/org/apache/harmony/security/tests/java/security/Policy_ImplTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/security/src/test/impl/java/org/apache/harmony/security/tests/java/security/Policy_ImplTest.java?view=diff&rev=548552&r1=548551&r2=548552
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/security/src/test/impl/java/org/apache/harmony/security/tests/java/security/Policy_ImplTest.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/security/src/test/impl/java/org/apache/harmony/security/tests/java/security/Policy_ImplTest.java Mon Jun 18 18:51:02 2007
@@ -90,7 +90,15 @@
         assertTrue(policy.implies(new ProtectionDomain(null, null), sp));
         assertFalse(policy.implies(null, sp));
         assertFalse(policy.implies(new ProtectionDomain(null, null), null));
-        assertFalse(policy.implies(null, null));
+        
+        //RI throws NullPointerException.
+        try {
+            policy.implies(null, null);
+            fail("should throw NullPointerException");
+        } catch (NullPointerException e) {
+            // expected.
+        }
+        
         
         ProtectionDomain pd = new ProtectionDomain(null, policy.pc);
         policy.pc = null;