8056179: Store permissions in concurrent collections in PermissionCollection subclasses
8065942: Store PermissionCollection entries in a ConcurrentHashMap instead of a HashMap in Permissions class
Reviewed-by: weijun
--- a/jdk/src/java.base/share/classes/java/io/FilePermission.java Mon Jun 08 16:17:37 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/io/FilePermission.java Tue Jun 09 09:18:07 2015 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,11 +27,9 @@
import java.security.*;
import java.util.Enumeration;
-import java.util.List;
-import java.util.ArrayList;
+import java.util.StringJoiner;
import java.util.Vector;
-import java.util.Collections;
-import java.util.StringJoiner;
+import java.util.concurrent.ConcurrentHashMap;
import sun.security.util.SecurityConstants;
/**
@@ -288,7 +286,6 @@
* @param path the pathname of the file/directory.
* @param mask the action mask to use.
*/
-
// package private for use by the FilePermissionCollection add method
FilePermission(String path, int mask) {
super(path);
@@ -315,6 +312,7 @@
* <code>null</code> and is implied by this object,
* <code>false</code> otherwise.
*/
+ @Override
public boolean implies(Permission p) {
if (!(p instanceof FilePermission))
return false;
@@ -387,6 +385,7 @@
* pathname and actions as this FilePermission object,
* <code>false</code> otherwise.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -407,6 +406,7 @@
*
* @return a hash code value for this object.
*/
+ @Override
public int hashCode() {
return 0;
}
@@ -587,6 +587,7 @@
*
* @return the canonical string representation of the actions.
*/
+ @Override
public String getActions() {
if (actions == null)
actions = getActions(this.mask);
@@ -625,6 +626,7 @@
* @return a new PermissionCollection object suitable for storing
* FilePermissions.
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new FilePermissionCollection();
}
@@ -689,13 +691,13 @@
implements Serializable
{
// Not serialized; see serialization section at end of class
- private transient List<Permission> perms;
+ private transient ConcurrentHashMap<String, Permission> perms;
/**
* Create an empty FilePermissionCollection object.
*/
public FilePermissionCollection() {
- perms = new ArrayList<>();
+ perms = new ConcurrentHashMap<>();
}
/**
@@ -710,6 +712,7 @@
* @exception SecurityException - if this FilePermissionCollection object
* has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof FilePermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -718,9 +721,31 @@
throw new SecurityException(
"attempt to add a Permission to a readonly PermissionCollection");
- synchronized (this) {
- perms.add(permission);
- }
+ FilePermission fp = (FilePermission)permission;
+
+ // Add permission to map if it is absent, or replace with new
+ // permission if applicable. NOTE: cannot use lambda for
+ // remappingFunction parameter until JDK-8076596 is fixed.
+ perms.merge(fp.getName(), fp,
+ new java.util.function.BiFunction<>() {
+ @Override
+ public Permission apply(Permission existingVal,
+ Permission newVal) {
+ int oldMask = ((FilePermission)existingVal).getMask();
+ int newMask = ((FilePermission)newVal).getMask();
+ if (oldMask != newMask) {
+ int effective = oldMask | newMask;
+ if (effective == newMask) {
+ return newVal;
+ }
+ if (effective != oldMask) {
+ return new FilePermission(fp.getName(), effective);
+ }
+ }
+ return existingVal;
+ }
+ }
+ );
}
/**
@@ -732,26 +757,25 @@
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
+ @Override
public boolean implies(Permission permission) {
if (! (permission instanceof FilePermission))
return false;
- FilePermission fp = (FilePermission) permission;
+ FilePermission fperm = (FilePermission) permission;
- int desired = fp.getMask();
+ int desired = fperm.getMask();
int effective = 0;
int needed = desired;
- synchronized (this) {
- int len = perms.size();
- for (int i = 0; i < len; i++) {
- FilePermission x = (FilePermission) perms.get(i);
- if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(fp)) {
- effective |= x.getMask();
- if ((effective & desired) == desired)
- return true;
- needed = (desired ^ effective);
+ for (Permission perm : perms.values()) {
+ FilePermission fp = (FilePermission)perm;
+ if (((needed & fp.getMask()) != 0) && fp.impliesIgnoreMask(fperm)) {
+ effective |= fp.getMask();
+ if ((effective & desired) == desired) {
+ return true;
}
+ needed = (desired ^ effective);
}
}
return false;
@@ -763,11 +787,9 @@
*
* @return an enumeration of all the FilePermission objects.
*/
+ @Override
public Enumeration<Permission> elements() {
- // Convert Iterator into Enumeration
- synchronized (this) {
- return Collections.enumeration(perms);
- }
+ return perms.elements();
}
private static final long serialVersionUID = 2202956749081564585L;
@@ -795,10 +817,7 @@
// Don't call out.defaultWriteObject()
// Write out Vector
- Vector<Permission> permissions = new Vector<>(perms.size());
- synchronized (this) {
- permissions.addAll(perms);
- }
+ Vector<Permission> permissions = new Vector<>(perms.values());
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", permissions);
@@ -819,7 +838,9 @@
// Get the one we want
@SuppressWarnings("unchecked")
Vector<Permission> permissions = (Vector<Permission>)gfields.get("permissions", null);
- perms = new ArrayList<>(permissions.size());
- perms.addAll(permissions);
+ perms = new ConcurrentHashMap<>(permissions.size());
+ for (Permission perm : permissions) {
+ perms.put(perm.getName(), perm);
+ }
}
}
--- a/jdk/src/java.base/share/classes/java/net/SocketPermission.java Mon Jun 08 16:17:37 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/net/SocketPermission.java Tue Jun 09 09:18:07 2015 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,24 +25,24 @@
package java.net;
-import java.util.Enumeration;
-import java.util.Vector;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.StringJoiner;
-import java.util.StringTokenizer;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.io.Serializable;
import java.net.InetAddress;
+import java.security.AccessController;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
-import java.security.AccessController;
import java.security.Security;
-import java.io.Serializable;
-import java.io.ObjectStreamField;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.StringJoiner;
+import java.util.StringTokenizer;
+import java.util.concurrent.ConcurrentSkipListMap;
import sun.net.util.IPAddressUtil;
import sun.net.RegisteredDomain;
import sun.net.PortConfig;
@@ -832,6 +832,7 @@
* @return true if the specified permission is implied by this object,
* false if not.
*/
+ @Override
public boolean implies(Permission p) {
int i,j;
@@ -1010,6 +1011,7 @@
* SocketPermission object. However, port range will be ignored
* in the comparison if <i>obj</i> only contains the action, 'resolve'.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -1069,7 +1071,7 @@
*
* @return a hash code value for this object.
*/
-
+ @Override
public int hashCode() {
/*
* If this SocketPermission was initialized with an IP address
@@ -1137,6 +1139,7 @@
*
* @return the canonical string representation of the actions.
*/
+ @Override
public String getActions()
{
if (actions == null)
@@ -1156,7 +1159,7 @@
*
* @return a new PermissionCollection object suitable for storing SocketPermissions.
*/
-
+ @Override
public PermissionCollection newPermissionCollection() {
return new SocketPermissionCollection();
}
@@ -1320,15 +1323,16 @@
implements Serializable
{
// Not serialized; see serialization section at end of class
- private transient List<SocketPermission> perms;
+ // A ConcurrentSkipListMap is used to preserve order, so that most
+ // recently added permissions are checked first (see JDK-4301064).
+ private transient ConcurrentSkipListMap<String, SocketPermission> perms;
/**
* Create an empty SocketPermissions object.
*
*/
-
public SocketPermissionCollection() {
- perms = new ArrayList<>();
+ perms = new ConcurrentSkipListMap<>(new SPCComparator());
}
/**
@@ -1343,6 +1347,7 @@
* @exception SecurityException - if this SocketPermissionCollection object
* has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof SocketPermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -1351,11 +1356,32 @@
throw new SecurityException(
"attempt to add a Permission to a readonly PermissionCollection");
- // optimization to ensure perms most likely to be tested
- // show up early (4301064)
- synchronized (this) {
- perms.add(0, (SocketPermission)permission);
- }
+ SocketPermission sp = (SocketPermission)permission;
+
+ // Add permission to map if it is absent, or replace with new
+ // permission if applicable. NOTE: cannot use lambda for
+ // remappingFunction parameter until JDK-8076596 is fixed.
+ perms.merge(sp.getName(), sp,
+ new java.util.function.BiFunction<>() {
+ @Override
+ public SocketPermission apply(SocketPermission existingVal,
+ SocketPermission newVal) {
+ int oldMask = existingVal.getMask();
+ int newMask = newVal.getMask();
+ if (oldMask != newMask) {
+ int effective = oldMask | newMask;
+ if (effective == newMask) {
+ return newVal;
+ }
+ if (effective != oldMask) {
+ return new SocketPermission(sp.getName(),
+ effective);
+ }
+ }
+ return existingVal;
+ }
+ }
+ );
}
/**
@@ -1367,7 +1393,7 @@
* @return true if "permission" is a proper subset of a permission in
* the collection, false if not.
*/
-
+ @Override
public boolean implies(Permission permission)
{
if (! (permission instanceof SocketPermission))
@@ -1379,18 +1405,15 @@
int effective = 0;
int needed = desired;
- synchronized (this) {
- int len = perms.size();
- //System.out.println("implies "+np);
- for (int i = 0; i < len; i++) {
- SocketPermission x = perms.get(i);
- //System.out.println(" trying "+x);
- if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(np)) {
- effective |= x.getMask();
- if ((effective & desired) == desired)
- return true;
- needed = (desired ^ effective);
+ //System.out.println("implies "+np);
+ for (SocketPermission x : perms.values()) {
+ //System.out.println(" trying "+x);
+ if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(np)) {
+ effective |= x.getMask();
+ if ((effective & desired) == desired) {
+ return true;
}
+ needed = (desired ^ effective);
}
}
return false;
@@ -1402,13 +1425,10 @@
*
* @return an enumeration of all the SocketPermission objects.
*/
-
+ @Override
@SuppressWarnings("unchecked")
public Enumeration<Permission> elements() {
- // Convert Iterator into Enumeration
- synchronized (this) {
- return Collections.enumeration((List<Permission>)(List)perms);
- }
+ return (Enumeration)Collections.enumeration(perms.values());
}
private static final long serialVersionUID = 2787186408602843674L;
@@ -1441,11 +1461,7 @@
// Don't call out.defaultWriteObject()
// Write out Vector
- Vector<SocketPermission> permissions = new Vector<>(perms.size());
-
- synchronized (this) {
- permissions.addAll(perms);
- }
+ Vector<SocketPermission> permissions = new Vector<>(perms.values());
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", permissions);
@@ -1466,7 +1482,22 @@
// Get the one we want
@SuppressWarnings("unchecked")
Vector<SocketPermission> permissions = (Vector<SocketPermission>)gfields.get("permissions", null);
- perms = new ArrayList<>(permissions.size());
- perms.addAll(permissions);
+ perms = new ConcurrentSkipListMap<>(new SPCComparator());
+ for (SocketPermission sp : permissions) {
+ perms.put(sp.getName(), sp);
+ }
+ }
+
+ /**
+ * A simple comparator that orders new non-equal entries at the beginning.
+ */
+ private static class SPCComparator implements Comparator<String> {
+ @Override
+ public int compare(String s1, String s2) {
+ if (s1.equals(s2)) {
+ return 0;
+ }
+ return -1;
+ }
}
}
--- a/jdk/src/java.base/share/classes/java/security/BasicPermission.java Mon Jun 08 16:17:37 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/security/BasicPermission.java Tue Jun 09 09:18:07 2015 -0400
@@ -25,15 +25,13 @@
package java.security;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
import java.util.Enumeration;
-import java.util.Map;
-import java.util.HashMap;
import java.util.Hashtable;
-import java.util.Collections;
-import java.io.ObjectStreamField;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
/**
* The BasicPermission class extends the Permission class, and
@@ -165,6 +163,7 @@
* @return true if the passed permission is equal to or
* implied by this permission, false otherwise.
*/
+ @Override
public boolean implies(Permission p) {
if ((p == null) || (p.getClass() != getClass()))
return false;
@@ -200,6 +199,7 @@
* @return true if {@code obj}'s class is the same as this object's class
* and has the same name as this BasicPermission object, false otherwise.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -221,6 +221,7 @@
*
* @return a hash code value for this object.
*/
+ @Override
public int hashCode() {
return this.getName().hashCode();
}
@@ -232,6 +233,7 @@
*
* @return the empty string "".
*/
+ @Override
public String getActions() {
return "";
}
@@ -248,6 +250,7 @@
* @return a new PermissionCollection object suitable for
* storing BasicPermissions.
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new BasicPermissionCollection(this.getClass());
}
@@ -308,7 +311,7 @@
* collection must be of the same type.
* Not serialized; see serialization section at end of class.
*/
- private transient Map<String, Permission> perms;
+ private transient ConcurrentHashMap<String, Permission> perms;
/**
* This is set to {@code true} if this BasicPermissionCollection
@@ -320,7 +323,7 @@
/**
* The class to which all BasicPermissions in this
- * BasicPermissionCollection belongs.
+ * BasicPermissionCollection belong.
*
* @see #serialPersistentFields
*/
@@ -330,9 +333,8 @@
* Create an empty BasicPermissionCollection object.
*
*/
-
public BasicPermissionCollection(Class<?> clazz) {
- perms = new HashMap<>(11);
+ perms = new ConcurrentHashMap<>(11);
all_allowed = false;
permClass = clazz;
}
@@ -352,6 +354,7 @@
* @exception SecurityException - if this BasicPermissionCollection object
* has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof BasicPermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -373,13 +376,12 @@
permission);
}
- synchronized (this) {
- perms.put(bp.getCanonicalName(), permission);
- }
+ String canonName = bp.getCanonicalName();
+ perms.put(canonName, permission);
// No sync on all_allowed; staleness OK
if (!all_allowed) {
- if (bp.getCanonicalName().equals("*"))
+ if (canonName.equals("*"))
all_allowed = true;
}
}
@@ -393,6 +395,7 @@
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
+ @Override
public boolean implies(Permission permission) {
if (! (permission instanceof BasicPermission))
return false;
@@ -414,11 +417,7 @@
String path = bp.getCanonicalName();
//System.out.println("check "+path);
- Permission x;
-
- synchronized (this) {
- x = perms.get(path);
- }
+ Permission x = perms.get(path);
if (x != null) {
// we have a direct hit!
@@ -435,9 +434,7 @@
path = path.substring(0, last+1) + "*";
//System.out.println("check "+path);
- synchronized (this) {
- x = perms.get(path);
- }
+ x = perms.get(path);
if (x != null) {
return x.implies(permission);
@@ -456,11 +453,9 @@
*
* @return an enumeration of all the BasicPermission objects.
*/
+ @Override
public Enumeration<Permission> elements() {
- // Convert Iterator of Map values into an Enumeration
- synchronized (this) {
- return Collections.enumeration(perms.values());
- }
+ return perms.elements();
}
// Need to maintain serialization interoperability with earlier releases,
@@ -503,9 +498,7 @@
Hashtable<String, Permission> permissions =
new Hashtable<>(perms.size()*2);
- synchronized (this) {
- permissions.putAll(perms);
- }
+ permissions.putAll(perms);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
@@ -533,7 +526,7 @@
@SuppressWarnings("unchecked")
Hashtable<String, Permission> permissions =
(Hashtable<String, Permission>)gfields.get("permissions", null);
- perms = new HashMap<>(permissions.size()*2);
+ perms = new ConcurrentHashMap<>(permissions.size()*2);
perms.putAll(permissions);
// Get all_allowed
--- a/jdk/src/java.base/share/classes/java/security/Permissions.java Mon Jun 08 16:17:37 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/security/Permissions.java Tue Jun 09 09:18:07 2015 -0400
@@ -33,6 +33,7 @@
import java.util.List;
import java.util.Iterator;
import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
import java.io.Serializable;
import java.io.ObjectStreamField;
import java.io.ObjectOutputStream;
@@ -85,7 +86,7 @@
* Key is permissions Class, value is PermissionCollection for that class.
* Not serialized; see serialization section at end of class.
*/
- private transient Map<Class<?>, PermissionCollection> permsMap;
+ private transient ConcurrentHashMap<Class<?>, PermissionCollection> permsMap;
// optimization. keep track of whether unresolved permissions need to be
// checked
@@ -99,7 +100,7 @@
* Creates a new Permissions object containing no PermissionCollections.
*/
public Permissions() {
- permsMap = new HashMap<>(11);
+ permsMap = new ConcurrentHashMap<>(11);
allPermission = null;
}
@@ -120,18 +121,14 @@
*
* @see PermissionCollection#isReadOnly()
*/
-
+ @Override
public void add(Permission permission) {
if (isReadOnly())
throw new SecurityException(
"attempt to add a Permission to a readonly Permissions object");
- PermissionCollection pc;
-
- synchronized (this) {
- pc = getPermissionCollection(permission, true);
- pc.add(permission);
- }
+ PermissionCollection pc = getPermissionCollection(permission, true);
+ pc.add(permission);
// No sync; staleness -> optimizations delayed, which is OK
if (permission instanceof AllPermission) {
@@ -169,21 +166,19 @@
* PermissionCollection it
* belongs to, false if not.
*/
-
+ @Override
public boolean implies(Permission permission) {
// No sync; staleness -> skip optimization, which is OK
if (allPermission != null) {
return true; // AllPermission has already been added
} else {
- synchronized (this) {
- PermissionCollection pc = getPermissionCollection(permission,
- false);
- if (pc != null) {
- return pc.implies(permission);
- } else {
- // none found
- return false;
- }
+ PermissionCollection pc = getPermissionCollection(permission,
+ false);
+ if (pc != null) {
+ return pc.implies(permission);
+ } else {
+ // none found
+ return false;
}
}
}
@@ -194,14 +189,12 @@
*
* @return an enumeration of all the Permissions.
*/
-
+ @Override
public Enumeration<Permission> elements() {
// go through each Permissions in the hash table
// and call their elements() function.
- synchronized (this) {
- return new PermissionsEnumerator(permsMap.values().iterator());
- }
+ return new PermissionsEnumerator(permsMap.values().iterator());
}
/**
@@ -236,34 +229,39 @@
* It should be set to true when invoked from add().
*/
private PermissionCollection getPermissionCollection(Permission p,
- boolean createEmpty) {
+ boolean createEmpty) {
Class<?> c = p.getClass();
- PermissionCollection pc = permsMap.get(c);
-
if (!hasUnresolved && !createEmpty) {
- return pc;
- } else if (pc == null) {
+ return permsMap.get(c);
+ }
- // Check for unresolved permissions
- pc = (hasUnresolved ? getUnresolvedPermissions(p) : null);
-
- // if still null, create a new collection
- if (pc == null && createEmpty) {
-
- pc = p.newPermissionCollection();
+ // Create and add permission collection to map if it is absent.
+ // NOTE: cannot use lambda for mappingFunction parameter until
+ // JDK-8076596 is fixed.
+ return permsMap.computeIfAbsent(c,
+ new java.util.function.Function<>() {
+ @Override
+ public PermissionCollection apply(Class<?> k) {
+ // Check for unresolved permissions
+ PermissionCollection pc =
+ (hasUnresolved ? getUnresolvedPermissions(p) : null);
- // still no PermissionCollection?
- // We'll give them a PermissionsHash.
- if (pc == null)
- pc = new PermissionsHash();
- }
+ // if still null, create a new collection
+ if (pc == null && createEmpty) {
+
+ pc = p.newPermissionCollection();
- if (pc != null) {
- permsMap.put(c, pc);
+ // still no PermissionCollection?
+ // We'll give them a PermissionsHash.
+ if (pc == null) {
+ pc = new PermissionsHash();
+ }
+ }
+ return pc;
+ }
}
- }
- return pc;
+ );
}
/**
@@ -277,8 +275,6 @@
*/
private PermissionCollection getUnresolvedPermissions(Permission p)
{
- // Called from within synchronized method so permsMap doesn't need lock
-
UnresolvedPermissionCollection uc =
(UnresolvedPermissionCollection) permsMap.get(UnresolvedPermission.class);
@@ -362,9 +358,7 @@
// Copy perms into a Hashtable
Hashtable<Class<?>, PermissionCollection> perms =
new Hashtable<>(permsMap.size()*2); // no sync; estimate
- synchronized (this) {
- perms.putAll(permsMap);
- }
+ perms.putAll(permsMap);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
@@ -394,7 +388,7 @@
@SuppressWarnings("unchecked")
Hashtable<Class<?>, PermissionCollection> perms =
(Hashtable<Class<?>, PermissionCollection>)gfields.get("perms", null);
- permsMap = new HashMap<>(perms.size()*2);
+ permsMap = new ConcurrentHashMap<>(perms.size()*2);
permsMap.putAll(perms);
// Set hasUnresolved
@@ -481,14 +475,13 @@
* Key and value are (same) permissions objects.
* Not serialized; see serialization section at end of class.
*/
- private transient Map<Permission, Permission> permsMap;
+ private transient ConcurrentHashMap<Permission, Permission> permsMap;
/**
* Create an empty PermissionsHash object.
*/
-
PermissionsHash() {
- permsMap = new HashMap<>(11);
+ permsMap = new ConcurrentHashMap<>(11);
}
/**
@@ -496,11 +489,9 @@
*
* @param permission the Permission object to add.
*/
-
+ @Override
public void add(Permission permission) {
- synchronized (this) {
- permsMap.put(permission, permission);
- }
+ permsMap.put(permission, permission);
}
/**
@@ -512,23 +503,21 @@
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
-
+ @Override
public boolean implies(Permission permission) {
// attempt a fast lookup and implies. If that fails
// then enumerate through all the permissions.
- synchronized (this) {
- Permission p = permsMap.get(permission);
+ Permission p = permsMap.get(permission);
- // If permission is found, then p.equals(permission)
- if (p == null) {
- for (Permission p_ : permsMap.values()) {
- if (p_.implies(permission))
- return true;
- }
- return false;
- } else {
- return true;
+ // If permission is found, then p.equals(permission)
+ if (p == null) {
+ for (Permission p_ : permsMap.values()) {
+ if (p_.implies(permission))
+ return true;
}
+ return false;
+ } else {
+ return true;
}
}
@@ -537,12 +526,9 @@
*
* @return an enumeration of all the Permissions.
*/
-
+ @Override
public Enumeration<Permission> elements() {
- // Convert Iterator of Map values into an Enumeration
- synchronized (this) {
- return Collections.enumeration(permsMap.values());
- }
+ return permsMap.elements();
}
private static final long serialVersionUID = -8491988220802933440L;
@@ -570,9 +556,7 @@
// Copy perms into a Hashtable
Hashtable<Permission, Permission> perms =
new Hashtable<>(permsMap.size()*2);
- synchronized (this) {
- perms.putAll(permsMap);
- }
+ perms.putAll(permsMap);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
@@ -597,7 +581,7 @@
@SuppressWarnings("unchecked")
Hashtable<Permission, Permission> perms =
(Hashtable<Permission, Permission>)gfields.get("perms", null);
- permsMap = new HashMap<>(perms.size()*2);
+ permsMap = new ConcurrentHashMap<>(perms.size()*2);
permsMap.putAll(perms);
}
}
--- a/jdk/src/java.base/share/classes/java/security/UnresolvedPermissionCollection.java Mon Jun 08 16:17:37 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/security/UnresolvedPermissionCollection.java Tue Jun 09 09:18:07 2015 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,13 @@
package java.security;
-import java.util.*;
-import java.io.ObjectStreamField;
+import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.io.ObjectStreamField;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* A UnresolvedPermissionCollection stores a collection
@@ -54,14 +56,14 @@
* of the same type.
* Not serialized; see serialization section at end of class.
*/
- private transient Map<String, List<UnresolvedPermission>> perms;
+ private transient ConcurrentHashMap<String, List<UnresolvedPermission>> perms;
/**
* Create an empty UnresolvedPermissionCollection object.
*
*/
public UnresolvedPermissionCollection() {
- perms = new HashMap<>(11);
+ perms = new ConcurrentHashMap<>(11);
}
/**
@@ -70,25 +72,32 @@
*
* @param permission the Permission object to add.
*/
-
- public void add(Permission permission)
- {
+ @Override
+ public void add(Permission permission) {
if (! (permission instanceof UnresolvedPermission))
throw new IllegalArgumentException("invalid permission: "+
permission);
UnresolvedPermission up = (UnresolvedPermission) permission;
- List<UnresolvedPermission> v;
- synchronized (this) {
- v = perms.get(up.getName());
- if (v == null) {
- v = new ArrayList<>();
- perms.put(up.getName(), v);
+ // Add permission to map. NOTE: cannot use lambda for
+ // remappingFunction parameter until JDK-8076596 is fixed.
+ perms.compute(up.getName(),
+ new java.util.function.BiFunction<>() {
+ @Override
+ public List<UnresolvedPermission> apply(String key,
+ List<UnresolvedPermission> oldValue) {
+ if (oldValue == null) {
+ List<UnresolvedPermission> v =
+ new CopyOnWriteArrayList<>();
+ v.add(up);
+ return v;
+ } else {
+ oldValue.add(up);
+ return oldValue;
+ }
+ }
}
- }
- synchronized (v) {
- v.add(up);
- }
+ );
}
/**
@@ -96,17 +105,15 @@
* and return the List containing them.
*/
List<UnresolvedPermission> getUnresolvedPermissions(Permission p) {
- synchronized (this) {
- return perms.get(p.getClass().getName());
- }
+ return perms.get(p.getClass().getName());
}
/**
* always returns false for unresolved permissions
*
*/
- public boolean implies(Permission permission)
- {
+ @Override
+ public boolean implies(Permission permission) {
return false;
}
@@ -116,18 +123,14 @@
*
* @return an enumeration of all the UnresolvedPermission objects.
*/
-
+ @Override
public Enumeration<Permission> elements() {
List<Permission> results =
new ArrayList<>(); // where results are stored
// Get iterator of Map values (which are lists of permissions)
- synchronized (this) {
- for (List<UnresolvedPermission> l : perms.values()) {
- synchronized (l) {
- results.addAll(l);
- }
- }
+ for (List<UnresolvedPermission> l : perms.values()) {
+ results.addAll(l);
}
return Collections.enumeration(results);
@@ -164,19 +167,14 @@
new Hashtable<>(perms.size()*2);
// Convert each entry (List) into a Vector
- synchronized (this) {
- Set<Map.Entry<String, List<UnresolvedPermission>>> set = perms.entrySet();
- for (Map.Entry<String, List<UnresolvedPermission>> e : set) {
- // Convert list into Vector
- List<UnresolvedPermission> list = e.getValue();
- Vector<UnresolvedPermission> vec = new Vector<>(list.size());
- synchronized (list) {
- vec.addAll(list);
- }
+ Set<Map.Entry<String, List<UnresolvedPermission>>> set = perms.entrySet();
+ for (Map.Entry<String, List<UnresolvedPermission>> e : set) {
+ // Convert list into Vector
+ List<UnresolvedPermission> list = e.getValue();
+ Vector<UnresolvedPermission> vec = new Vector<>(list);
- // Add to Hashtable being serialized
- permissions.put(e.getKey(), vec);
- }
+ // Add to Hashtable being serialized
+ permissions.put(e.getKey(), vec);
}
// Write out serializable fields
@@ -203,15 +201,14 @@
Hashtable<String, Vector<UnresolvedPermission>> permissions =
(Hashtable<String, Vector<UnresolvedPermission>>)
gfields.get("permissions", null);
- perms = new HashMap<>(permissions.size()*2);
+ perms = new ConcurrentHashMap<>(permissions.size()*2);
// Convert each entry (Vector) into a List
Set<Map.Entry<String, Vector<UnresolvedPermission>>> set = permissions.entrySet();
for (Map.Entry<String, Vector<UnresolvedPermission>> e : set) {
// Convert Vector into ArrayList
Vector<UnresolvedPermission> vec = e.getValue();
- List<UnresolvedPermission> list = new ArrayList<>(vec.size());
- list.addAll(vec);
+ List<UnresolvedPermission> list = new CopyOnWriteArrayList<>(vec);
// Add to Hashtable being serialized
perms.put(e.getKey(), list);
--- a/jdk/src/java.base/share/classes/java/util/PropertyPermission.java Mon Jun 08 16:17:37 2015 +0300
+++ b/jdk/src/java.base/share/classes/java/util/PropertyPermission.java Tue Jun 09 09:18:07 2015 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,15 @@
package java.util;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
import java.io.Serializable;
-import java.io.IOException;
import java.security.*;
-import java.util.Map;
-import java.util.HashMap;
import java.util.Enumeration;
import java.util.Hashtable;
-import java.util.Collections;
-import java.io.ObjectStreamField;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.util.concurrent.ConcurrentHashMap;
import sun.security.util.SecurityConstants;
/**
@@ -162,6 +159,16 @@
}
/**
+ * Creates a PropertyPermission object with the specified name and
+ * a pre-calculated mask. Avoids the overhead of re-computing the mask.
+ * Called by PropertyPermissionCollection.
+ */
+ PropertyPermission(String name, int mask) {
+ super(name, getActions(mask));
+ this.mask = mask;
+ }
+
+ /**
* Checks if this PropertyPermission object "implies" the specified
* permission.
* <P>
@@ -178,6 +185,7 @@
* @return true if the specified permission is implied by this object,
* false if not.
*/
+ @Override
public boolean implies(Permission p) {
if (!(p instanceof PropertyPermission))
return false;
@@ -198,6 +206,7 @@
* @return true if obj is a PropertyPermission, and has the same name and
* actions as this PropertyPermission object.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -219,6 +228,7 @@
*
* @return a hash code value for this object.
*/
+ @Override
public int hashCode() {
return this.getName().hashCode();
}
@@ -345,6 +355,7 @@
*
* @return the canonical string representation of the actions.
*/
+ @Override
public String getActions() {
if (actions == null)
actions = getActions(this.mask);
@@ -369,6 +380,7 @@
* @return a new PermissionCollection object suitable for storing
* PropertyPermissions.
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new PropertyPermissionCollection();
}
@@ -425,7 +437,7 @@
* Key is property name; value is PropertyPermission.
* Not serialized; see serialization section at end of class.
*/
- private transient Map<String, PropertyPermission> perms;
+ private transient ConcurrentHashMap<String, PropertyPermission> perms;
/**
* Boolean saying if "*" is in the collection.
@@ -439,7 +451,7 @@
* Create an empty PropertyPermissionCollection object.
*/
public PropertyPermissionCollection() {
- perms = new HashMap<>(32); // Capacity for default policy
+ perms = new ConcurrentHashMap<>(32); // Capacity for default policy
all_allowed = false;
}
@@ -455,6 +467,7 @@
* @exception SecurityException - if this PropertyPermissionCollection
* object has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof PropertyPermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -466,21 +479,30 @@
PropertyPermission pp = (PropertyPermission) permission;
String propName = pp.getName();
- synchronized (this) {
- PropertyPermission existing = perms.get(propName);
+ // Add permission to map if it is absent, or replace with new
+ // permission if applicable. NOTE: cannot use lambda for
+ // remappingFunction parameter until JDK-8076596 is fixed.
+ perms.merge(propName, pp,
+ new java.util.function.BiFunction<>() {
+ @Override
+ public PropertyPermission apply(PropertyPermission existingVal,
+ PropertyPermission newVal) {
- if (existing != null) {
- int oldMask = existing.getMask();
- int newMask = pp.getMask();
- if (oldMask != newMask) {
- int effective = oldMask | newMask;
- String actions = PropertyPermission.getActions(effective);
- perms.put(propName, new PropertyPermission(propName, actions));
+ int oldMask = existingVal.getMask();
+ int newMask = newVal.getMask();
+ if (oldMask != newMask) {
+ int effective = oldMask | newMask;
+ if (effective == newMask) {
+ return newVal;
+ }
+ if (effective != oldMask) {
+ return new PropertyPermission(propName, effective);
+ }
+ }
+ return existingVal;
}
- } else {
- perms.put(propName, pp);
}
- }
+ );
if (!all_allowed) {
if (propName.equals("*"))
@@ -497,9 +519,10 @@
* @return true if "permission" is a proper subset of a permission in
* the set, false if not.
*/
+ @Override
public boolean implies(Permission permission) {
if (! (permission instanceof PropertyPermission))
- return false;
+ return false;
PropertyPermission pp = (PropertyPermission) permission;
PropertyPermission x;
@@ -509,9 +532,7 @@
// short circuit if the "*" Permission was added
if (all_allowed) {
- synchronized (this) {
- x = perms.get("*");
- }
+ x = perms.get("*");
if (x != null) {
effective |= x.getMask();
if ((effective & desired) == desired)
@@ -526,9 +547,7 @@
String name = pp.getName();
//System.out.println("check "+name);
- synchronized (this) {
- x = perms.get(name);
- }
+ x = perms.get(name);
if (x != null) {
// we have a direct hit!
@@ -546,9 +565,7 @@
name = name.substring(0, last+1) + "*";
//System.out.println("check "+name);
- synchronized (this) {
- x = perms.get(name);
- }
+ x = perms.get(name);
if (x != null) {
effective |= x.getMask();
@@ -569,16 +586,14 @@
*
* @return an enumeration of all the PropertyPermission objects.
*/
+ @Override
@SuppressWarnings("unchecked")
public Enumeration<Permission> elements() {
- // Convert Iterator of Map values into an Enumeration
- synchronized (this) {
- /**
- * Casting to rawtype since Enumeration<PropertyPermission>
- * cannot be directly cast to Enumeration<Permission>
- */
- return (Enumeration)Collections.enumeration(perms.values());
- }
+ /**
+ * Casting to rawtype since Enumeration<PropertyPermission>
+ * cannot be directly cast to Enumeration<Permission>
+ */
+ return (Enumeration)perms.elements();
}
private static final long serialVersionUID = 7015263904581634791L;
@@ -616,9 +631,7 @@
// Copy perms into a Hashtable
Hashtable<String, Permission> permissions =
new Hashtable<>(perms.size()*2);
- synchronized (this) {
- permissions.putAll(perms);
- }
+ permissions.putAll(perms);
// Write out serializable fields
ObjectOutputStream.PutField pfields = out.putFields();
@@ -646,7 +659,7 @@
@SuppressWarnings("unchecked")
Hashtable<String, PropertyPermission> permissions =
(Hashtable<String, PropertyPermission>)gfields.get("permissions", null);
- perms = new HashMap<>(permissions.size()*2);
+ perms = new ConcurrentHashMap<>(permissions.size()*2);
perms.putAll(permissions);
}
}
--- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/DelegationPermission.java Mon Jun 08 16:17:37 2015 +0300
+++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/DelegationPermission.java Tue Jun 09 09:18:07 2015 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,15 @@
package javax.security.auth.kerberos;
-import java.util.*;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.BasicPermission;
import java.security.Permission;
-import java.security.BasicPermission;
import java.security.PermissionCollection;
-import java.io.ObjectStreamField;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
/**
* This class is used to restrict the usage of the Kerberos
@@ -137,6 +138,7 @@
* @return true if the specified permission is implied by this object,
* false if not.
*/
+ @Override
public boolean implies(Permission p) {
if (!(p instanceof DelegationPermission))
return false;
@@ -159,6 +161,7 @@
* has the same subordinate and service principal as this.
* DelegationPermission object.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -175,11 +178,11 @@
*
* @return a hash code value for this object.
*/
+ @Override
public int hashCode() {
return getName().hashCode();
}
-
/**
* Returns a PermissionCollection object for storing
* DelegationPermission objects.
@@ -192,7 +195,7 @@
* @return a new PermissionCollection object suitable for storing
* DelegationPermissions.
*/
-
+ @Override
public PermissionCollection newPermissionCollection() {
return new KrbDelegationPermissionCollection();
}
@@ -263,13 +266,12 @@
implements java.io.Serializable {
// Not serialized; see serialization section at end of class.
- private transient List<Permission> perms;
+ private transient ConcurrentHashMap<Permission, Boolean> perms;
public KrbDelegationPermissionCollection() {
- perms = new ArrayList<Permission>();
+ perms = new ConcurrentHashMap<>();
}
-
/**
* Check and see if this collection of permissions implies the permissions
* expressed in "permission".
@@ -279,18 +281,13 @@
* @return true if "permission" is a proper subset of a permission in
* the collection, false if not.
*/
+ @Override
public boolean implies(Permission permission) {
if (! (permission instanceof DelegationPermission))
- return false;
+ return false;
- synchronized (this) {
- for (Permission x : perms) {
- if (x.implies(permission))
- return true;
- }
- }
- return false;
-
+ // if map contains key, then it automatically implies it
+ return perms.containsKey(permission);
}
/**
@@ -305,6 +302,7 @@
* @exception SecurityException - if this PermissionCollection object
* has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof DelegationPermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -312,9 +310,7 @@
if (isReadOnly())
throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
- synchronized (this) {
- perms.add(0, permission);
- }
+ perms.put(permission, Boolean.TRUE);
}
/**
@@ -323,11 +319,9 @@
*
* @return an enumeration of all the DelegationPermission objects.
*/
+ @Override
public Enumeration<Permission> elements() {
- // Convert Iterator into Enumeration
- synchronized (this) {
- return Collections.enumeration(perms);
- }
+ return perms.keys();
}
private static final long serialVersionUID = -3383936936589966948L;
@@ -354,11 +348,7 @@
// Don't call out.defaultWriteObject()
// Write out Vector
- Vector<Permission> permissions = new Vector<>(perms.size());
-
- synchronized (this) {
- permissions.addAll(perms);
- }
+ Vector<Permission> permissions = new Vector<>(perms.keySet());
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", permissions);
@@ -379,8 +369,10 @@
// Get the one we want
Vector<Permission> permissions =
- (Vector<Permission>)gfields.get("permissions", null);
- perms = new ArrayList<Permission>(permissions.size());
- perms.addAll(permissions);
+ (Vector<Permission>)gfields.get("permissions", null);
+ perms = new ConcurrentHashMap<>(permissions.size());
+ for (Permission perm : permissions) {
+ perms.put(perm, Boolean.TRUE);
+ }
}
}
--- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/ServicePermission.java Mon Jun 08 16:17:37 2015 +0300
+++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/ServicePermission.java Tue Jun 09 09:18:07 2015 -0400
@@ -25,13 +25,14 @@
package javax.security.auth.kerberos;
-import java.util.*;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
import java.security.Permission;
import java.security.PermissionCollection;
-import java.io.ObjectStreamField;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
/**
* This class is used to protect Kerberos services and the
@@ -149,6 +150,15 @@
init(servicePrincipal, getMask(action));
}
+ /**
+ * Creates a ServicePermission object with the specified servicePrincipal
+ * and a pre-calculated mask. Avoids the overhead of re-computing the mask.
+ * Called by ServicePermissionCollection.
+ */
+ ServicePermission(String servicePrincipal, int mask) {
+ super(servicePrincipal);
+ init(servicePrincipal, mask);
+ }
/**
* Initialize the ServicePermission object.
@@ -175,6 +185,7 @@
* @return true if the specified permission is implied by this object,
* false if not.
*/
+ @Override
public boolean implies(Permission p) {
if (!(p instanceof ServicePermission))
return false;
@@ -200,6 +211,7 @@
* same service principal, and actions as this
* ServicePermission object.
*/
+ @Override
public boolean equals(Object obj) {
if (obj == this)
return true;
@@ -219,7 +231,7 @@
*
* @return a hash code value for this object.
*/
-
+ @Override
public int hashCode() {
return (getName().hashCode() ^ mask);
}
@@ -234,7 +246,7 @@
* @param mask a specific integer action mask to translate into a string
* @return the canonical string representation of the actions
*/
- private static String getActions(int mask)
+ static String getActions(int mask)
{
StringBuilder sb = new StringBuilder();
boolean comma = false;
@@ -259,6 +271,7 @@
* Always returns present actions in the following order:
* initiate, accept.
*/
+ @Override
public String getActions() {
if (actions == null)
actions = getActions(this.mask);
@@ -279,6 +292,7 @@
* @return a new PermissionCollection object suitable for storing
* ServicePermissions.
*/
+ @Override
public PermissionCollection newPermissionCollection() {
return new KrbServicePermissionCollection();
}
@@ -453,11 +467,12 @@
final class KrbServicePermissionCollection extends PermissionCollection
implements java.io.Serializable {
+ // Key is the service principal, value is the ServicePermission.
// Not serialized; see serialization section at end of class
- private transient List<Permission> perms;
+ private transient ConcurrentHashMap<String, Permission> perms;
public KrbServicePermissionCollection() {
- perms = new ArrayList<Permission>();
+ perms = new ConcurrentHashMap<>();
}
/**
@@ -469,32 +484,28 @@
* @return true if "permission" is a proper subset of a permission in
* the collection, false if not.
*/
+ @Override
public boolean implies(Permission permission) {
if (! (permission instanceof ServicePermission))
- return false;
+ return false;
ServicePermission np = (ServicePermission) permission;
int desired = np.getMask();
- int effective = 0;
- int needed = desired;
-
- synchronized (this) {
- int len = perms.size();
-
- // need to deal with the case where the needed permission has
- // more than one action and the collection has individual permissions
- // that sum up to the needed.
- for (int i = 0; i < len; i++) {
- ServicePermission x = (ServicePermission) perms.get(i);
+ // first, check for wildcard principal
+ ServicePermission x = (ServicePermission)perms.get("*");
+ if (x != null) {
+ if ((x.getMask() & desired) == desired) {
+ return true;
+ }
+ }
- //System.out.println(" trying "+x);
- if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(np)) {
- effective |= x.getMask();
- if ((effective & desired) == desired)
- return true;
- needed = (desired ^ effective);
- }
+ // otherwise, check for match on principal
+ x = (ServicePermission)perms.get(np.getName());
+ if (x != null) {
+ //System.out.println(" trying "+x);
+ if ((x.getMask() & desired) == desired) {
+ return true;
}
}
return false;
@@ -512,6 +523,7 @@
* @exception SecurityException - if this PermissionCollection object
* has been marked readonly
*/
+ @Override
public void add(Permission permission) {
if (! (permission instanceof ServicePermission))
throw new IllegalArgumentException("invalid permission: "+
@@ -519,9 +531,32 @@
if (isReadOnly())
throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
- synchronized (this) {
- perms.add(0, permission);
- }
+ ServicePermission sp = (ServicePermission)permission;
+ String princName = sp.getName();
+
+ // Add permission to map if it is absent, or replace with new
+ // permission if applicable. NOTE: cannot use lambda for
+ // remappingFunction parameter until JDK-8076596 is fixed.
+ perms.merge(princName, sp,
+ new java.util.function.BiFunction<>() {
+ @Override
+ public Permission apply(Permission existingVal,
+ Permission newVal) {
+ int oldMask = ((ServicePermission)existingVal).getMask();
+ int newMask = ((ServicePermission)newVal).getMask();
+ if (oldMask != newMask) {
+ int effective = oldMask | newMask;
+ if (effective == newMask) {
+ return newVal;
+ }
+ if (effective != oldMask) {
+ return new ServicePermission(princName, effective);
+ }
+ }
+ return existingVal;
+ }
+ }
+ );
}
/**
@@ -530,12 +565,9 @@
*
* @return an enumeration of all the ServicePermission objects.
*/
-
+ @Override
public Enumeration<Permission> elements() {
- // Convert Iterator into Enumeration
- synchronized (this) {
- return Collections.enumeration(perms);
- }
+ return perms.elements();
}
private static final long serialVersionUID = -4118834211490102011L;
@@ -563,11 +595,7 @@
// Don't call out.defaultWriteObject()
// Write out Vector
- Vector<Permission> permissions = new Vector<>(perms.size());
-
- synchronized (this) {
- permissions.addAll(perms);
- }
+ Vector<Permission> permissions = new Vector<>(perms.values());
ObjectOutputStream.PutField pfields = out.putFields();
pfields.put("permissions", permissions);
@@ -589,7 +617,9 @@
// Get the one we want
Vector<Permission> permissions =
(Vector<Permission>)gfields.get("permissions", null);
- perms = new ArrayList<Permission>(permissions.size());
- perms.addAll(permissions);
+ perms = new ConcurrentHashMap<>(permissions.size());
+ for (Permission perm : permissions) {
+ perms.put(perm.getName(), perm);
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/io/FilePermission/FilePermissionCollection.java Tue Jun 09 09:18:07 2015 -0400
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for FilePermissionCollection subclass
+ */
+
+import java.io.FilePermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+
+public class FilePermissionCollection {
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ FilePermission perm = new FilePermission("/tmp/foo", "read");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgExc for wrong perm type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println("test 3: implies returns true for match on " +
+ "name and action");
+ perms.add(new FilePermission("/tmp/foo", "read"));
+ if (!perms.implies(new FilePermission("/tmp/foo", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println("test 4: implies returns false for match on " +
+ "name but not action");
+ if (perms.implies(new FilePermission("/tmp/foo", "write"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: implies returns true for match on " +
+ "name and subset of actions");
+ perms.add(new FilePermission("/tmp/bar", "read, write"));
+ if (!perms.implies(new FilePermission("/tmp/bar", "write"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println("test 6: implies returns true for aggregate " +
+ "match on name and action");
+ perms.add(new FilePermission("/tmp/baz", "read"));
+ perms.add(new FilePermission("/tmp/baz", "write"));
+ if (!perms.implies(new FilePermission("/tmp/baz", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+ if (!perms.implies(new FilePermission("/tmp/baz", "write,read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println("test 7: implies returns true for wildcard " +
+ "and match on action");
+ perms.add(new FilePermission("/usr/tmp/*", "read"));
+ if (!perms.implies(new FilePermission("/usr/tmp/foo", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println
+ ("test 8: implies returns false for non-match on wildcard");
+ if (perms.implies(new FilePermission("/usr/tmp/bar/foo", "read"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 9
+ System.out.println
+ ("test 9: implies returns true for deep wildcard match");
+ perms.add(new FilePermission("/usr/tmp/-", "read"));
+ if (!perms.implies(new FilePermission("/usr/tmp/bar/foo", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 10
+ System.out.println("test 10: implies returns true for relative match");
+ perms.add(new FilePermission(".", "read"));
+ if (!perms.implies(new FilePermission(System.getProperty("user.dir"),
+ "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 11
+ System.out.println("test 11: implies returns true for all " +
+ "wildcard and match on action");
+ perms.add(new FilePermission("<<ALL FILES>>", "read"));
+ if (!perms.implies(new FilePermission("/tmp/foobar", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 12
+ System.out.println("test 12: implies returns false for wildcard " +
+ "and non-match on action");
+ if (perms.implies(new FilePermission("/tmp/foobar", "write"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 13
+ System.out.println("test 13: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration<Permission> e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ // the two "/tmp/baz" entries were combined into one
+ if (numPerms != 7) {
+ System.err.println("Expected 7, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/SocketPermission/SocketPermissionCollection.java Tue Jun 09 09:18:07 2015 -0400
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for PermissionCollection subclasses
+ */
+
+import java.net.SocketPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+
+public class SocketPermissionCollection {
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ SocketPermission perm = new SocketPermission("www.example.com",
+ "connect");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgExc for wrong perm type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println
+ ("test 3: implies returns true for match on name and action");
+ perms.add(new SocketPermission("www.example.com", "connect"));
+ if (!perms.implies(new SocketPermission("www.example.com", "connect"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println
+ ("test 4: implies returns false for match on name but not action");
+ if (perms.implies(new SocketPermission("www.example.com", "accept"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: implies returns true for match on " +
+ "name and subset of actions");
+ perms.add(new SocketPermission("www.example.org", "accept, connect"));
+ if (!perms.implies(new SocketPermission("www.example.org", "connect"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println("test 6: implies returns true for aggregate " +
+ "match on name and action");
+ perms.add(new SocketPermission("www.example.us", "accept"));
+ perms.add(new SocketPermission("www.example.us", "connect"));
+ if (!perms.implies(new SocketPermission("www.example.us", "accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+ if (!perms.implies(new SocketPermission("www.example.us",
+ "connect,accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println("test 7: implies returns true for wildcard " +
+ "and match on action");
+ perms.add(new SocketPermission("*.example.edu", "resolve"));
+ if (!perms.implies(new SocketPermission("foo.example.edu", "resolve"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println("test 8: implies returns false for non-match " +
+ "on wildcard");
+ if (perms.implies(new SocketPermission("foo.example.edu", "connect"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 9
+ System.out.println("test 9: implies returns true for matching " +
+ "port range and action");
+ perms.add(new SocketPermission("204.160.241.0:1024-65535", "connect"));
+ if (!perms.implies(new SocketPermission("204.160.241.0:1025", "connect"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 13
+ System.out.println("test 13: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration<Permission> e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ // the two "/tmp/baz" entries were combined into one
+ if (numPerms != 5) {
+ System.err.println("Expected 5, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/BasicPermission/BasicPermissionCollection.java Tue Jun 09 09:18:07 2015 -0400
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for BasicPermissionCollection subclass
+ */
+
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+
+public class BasicPermissionCollection {
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ TestPermission perm = new TestPermission("foo");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println("test 1: add throws IllegalArgumentExc");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong class");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println("test 3: implies returns true for match on name");
+ perms.add(new TestPermission("foo"));
+ if (!perms.implies(new TestPermission("foo"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println("test 4: implies returns true for wildcard match");
+ perms.add(new TestPermission("bar.*"));
+ if (!perms.implies(new TestPermission("bar.foo"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println
+ ("test 5: implies returns false for invalid wildcard");
+ perms.add(new TestPermission("baz*"));
+ if (perms.implies(new TestPermission("baz.foo"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println
+ ("test 6: implies returns true for deep wildcard match");
+ if (!perms.implies(new TestPermission("bar.foo.baz"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println
+ ("test 7: implies returns true for all wildcard match");
+ perms.add(new TestPermission("*"));
+ if (!perms.implies(new TestPermission("yes"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println("test 8: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration<Permission> e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ if (numPerms != 4) {
+ System.err.println("Expected 4, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+
+ private static class TestPermission extends BasicPermission {
+ TestPermission(String name) {
+ super(name);
+ }
+ }
+}
--- a/jdk/test/java/security/PermissionCollection/Concurrent.java Mon Jun 08 16:17:37 2015 +0300
+++ b/jdk/test/java/security/PermissionCollection/Concurrent.java Tue Jun 09 09:18:07 2015 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -104,13 +104,11 @@
System.out.println(perm[perm.length-1] + " implies " + result);
}
- synchronized (pc) {
- Enumeration en = pc.elements();
- while (en.hasMoreElements()) {
- Object obj = en.nextElement();
- if (debug) {
- System.out.println(obj);
- }
+ Enumeration en = pc.elements();
+ while (en.hasMoreElements()) {
+ Object obj = en.nextElement();
+ if (debug) {
+ System.out.println(obj);
}
}
}
@@ -151,13 +149,11 @@
}
}
- synchronized (pc) {
- Enumeration en = pc.elements();
- while (en.hasMoreElements()) {
- Object obj = en.nextElement();
- if (debug) {
- System.out.println(obj);
- }
+ Enumeration en = pc.elements();
+ while (en.hasMoreElements()) {
+ Object obj = en.nextElement();
+ if (debug) {
+ System.out.println(obj);
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PropertyPermission/PropertyPermissionCollection.java Tue Jun 09 09:18:07 2015 -0400
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for PropertyPermissionCollection subclass
+ */
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+import java.util.PropertyPermission;
+
+public class PropertyPermissionCollection {
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ PropertyPermission perm = new PropertyPermission("user.home", "read");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgExc for wrong perm type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println
+ ("test 3: implies returns true for match on name and action");
+ perms.add(new PropertyPermission("user.home", "read"));
+ if (!perms.implies(new PropertyPermission("user.home", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println
+ ("test 4: implies returns false for match on name but not action");
+ if (perms.implies(new PropertyPermission("user.home", "write"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: implies returns true for match " +
+ "on name and subset of actions");
+ perms.add(new PropertyPermission("java.home", "read, write"));
+ if (!perms.implies(new PropertyPermission("java.home", "write"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println("test 6: implies returns true for aggregate " +
+ "match on name and action");
+ perms.add(new PropertyPermission("user.name", "read"));
+ perms.add(new PropertyPermission("user.name", "write"));
+ if (!perms.implies(new PropertyPermission("user.name", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+ if (!perms.implies(new PropertyPermission("user.name", "write,read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println("test 7: implies returns true for wildcard " +
+ "and match on action");
+ perms.add(new PropertyPermission("foo.*", "read"));
+ if (!perms.implies(new PropertyPermission("foo.bar", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println("test 8: implies returns true for deep " +
+ "wildcard and match on action");
+ if (!perms.implies(new PropertyPermission("foo.bar.baz", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println
+ ("test 8: implies returns false for invalid wildcard");
+ perms.add(new PropertyPermission("baz*", "read"));
+ if (perms.implies(new PropertyPermission("baz.foo", "read"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 9
+ System.out.println("test 9: implies returns true for all " +
+ "wildcard and match on action");
+ perms.add(new PropertyPermission("*", "read"));
+ if (!perms.implies(new PropertyPermission("java.version", "read"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 10
+ System.out.println("test 10: implies returns false for wildcard " +
+ "and non-match on action");
+ if (perms.implies(new PropertyPermission("java.version", "write"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 11
+ System.out.println("test 11: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration<Permission> e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ // the 2 user.name permissions added were combined into one
+ if (numPerms != 6) {
+ System.err.println("Expected 6, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/kerberos/DelegationPermissionCollection.java Tue Jun 09 09:18:07 2015 -0400
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for DelegationPermissionCollection subclass
+ */
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+import javax.security.auth.kerberos.DelegationPermission;
+
+public class DelegationPermissionCollection {
+
+ private static final String FOO = "\"host/foo.example.com@EXAMPLE.COM\"";
+ private static final String BAR = "\"host/bar.example.com@EXAMPLE.COM\"";
+ private static final String TGT = "\"krbtgt/EXAMPLE.COM@EXAMPLE.COM\"";
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ DelegationPermission perm = new DelegationPermission(FOO + " " + TGT);
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgException for wrong perm type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println("test 3: implies returns true for match on name");
+ perms.add(new DelegationPermission(FOO + " " + TGT));
+ if (!perms.implies(new DelegationPermission(FOO + " " + TGT))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println
+ ("test 4: implies returns false for non-match on name");
+ if (perms.implies(new DelegationPermission(BAR + " " + TGT))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration<Permission> e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ if (numPerms != 1) {
+ System.err.println("Expected 1, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/security/auth/kerberos/ServicePermissionCollection.java Tue Jun 09 09:18:07 2015 -0400
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8056179
+ * @summary Unit test for ServicePermissionCollection subclass
+ */
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.SecurityPermission;
+import java.util.Enumeration;
+import javax.security.auth.kerberos.ServicePermission;
+
+public class ServicePermissionCollection {
+
+ private static final String FOO = "host/foo.example.com@EXAMPLE.COM";
+ private static final String BAR = "host/bar.example.com@EXAMPLE.COM";
+ private static final String BAZ = "host/baz.example.com@EXAMPLE.COM";
+
+ public static void main(String[] args) throws Exception {
+
+ int testFail = 0;
+
+ ServicePermission perm = new ServicePermission(FOO, "accept");
+ PermissionCollection perms = perm.newPermissionCollection();
+
+ // test 1
+ System.out.println
+ ("test 1: add throws IllegalArgExc for wrong permission type");
+ try {
+ perms.add(new SecurityPermission("createAccessControlContext"));
+ System.err.println("Expected IllegalArgumentException");
+ testFail++;
+ } catch (IllegalArgumentException iae) {}
+
+ // test 2
+ System.out.println("test 2: implies returns false for wrong perm type");
+ if (perms.implies(new SecurityPermission("getPolicy"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 3
+ System.out.println
+ ("test 3: implies returns true for match on name and action");
+ perms.add(new ServicePermission(FOO, "accept"));
+ if (!perms.implies(new ServicePermission(FOO, "accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 4
+ System.out.println
+ ("test 4: implies returns false for match on name but not action");
+ if (perms.implies(new ServicePermission(FOO, "initiate"))) {
+ System.err.println("Expected false, returned true");
+ testFail++;
+ }
+
+ // test 5
+ System.out.println("test 5: implies returns true for match on " +
+ "name and subset of actions");
+ perms.add(new ServicePermission(BAR, "accept, initiate"));
+ if (!perms.implies(new ServicePermission(BAR, "accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 6
+ System.out.println("test 6: implies returns false for aggregate " +
+ "match on name and action");
+ perms.add(new ServicePermission(BAZ, "accept"));
+ perms.add(new ServicePermission(BAZ, "initiate"));
+ if (!perms.implies(new ServicePermission(BAZ, "initiate"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+ if (!perms.implies(new ServicePermission(BAZ, "initiate, accept"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 7
+ System.out.println("test 7: implies returns true for wildcard " +
+ "match on name and action");
+ perms.add(new ServicePermission("*", "initiate"));
+ if (!perms.implies(new ServicePermission("Duke", "initiate"))) {
+ System.err.println("Expected true, returned false");
+ testFail++;
+ }
+
+ // test 8
+ System.out.println("test 8: elements returns correct number of perms");
+ int numPerms = 0;
+ Enumeration<Permission> e = perms.elements();
+ while (e.hasMoreElements()) {
+ numPerms++;
+ System.out.println(e.nextElement());
+ }
+ // the 2 FOO permissions and the 2 BAZ permisssions
+ // are combined into one
+ if (numPerms != 4) {
+ System.err.println("Expected 4, got " + numPerms);
+ testFail++;
+ }
+
+ if (testFail > 0) {
+ throw new Exception(testFail + " test(s) failed");
+ }
+ }
+}