jdk/src/java.base/share/classes/java/security/BasicPermission.java
changeset 31080 00a25f4c4d44
parent 30033 b9c86c17164a
child 45434 4582657c7260
equal deleted inserted replaced
31062:a6b5f444cb68 31080:00a25f4c4d44
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package java.security;
    26 package java.security;
    27 
    27 
       
    28 import java.io.IOException;
       
    29 import java.io.ObjectInputStream;
       
    30 import java.io.ObjectOutputStream;
       
    31 import java.io.ObjectStreamField;
    28 import java.util.Enumeration;
    32 import java.util.Enumeration;
    29 import java.util.Map;
       
    30 import java.util.HashMap;
       
    31 import java.util.Hashtable;
    33 import java.util.Hashtable;
    32 import java.util.Collections;
    34 import java.util.concurrent.ConcurrentHashMap;
    33 import java.io.ObjectStreamField;
       
    34 import java.io.ObjectOutputStream;
       
    35 import java.io.ObjectInputStream;
       
    36 import java.io.IOException;
       
    37 
    35 
    38 /**
    36 /**
    39  * The BasicPermission class extends the Permission class, and
    37  * The BasicPermission class extends the Permission class, and
    40  * can be used as the base class for permissions that want to
    38  * can be used as the base class for permissions that want to
    41  * follow the same naming convention as BasicPermission.
    39  * follow the same naming convention as BasicPermission.
   163      * @param p the permission to check against.
   161      * @param p the permission to check against.
   164      *
   162      *
   165      * @return true if the passed permission is equal to or
   163      * @return true if the passed permission is equal to or
   166      * implied by this permission, false otherwise.
   164      * implied by this permission, false otherwise.
   167      */
   165      */
       
   166     @Override
   168     public boolean implies(Permission p) {
   167     public boolean implies(Permission p) {
   169         if ((p == null) || (p.getClass() != getClass()))
   168         if ((p == null) || (p.getClass() != getClass()))
   170             return false;
   169             return false;
   171 
   170 
   172         BasicPermission that = (BasicPermission) p;
   171         BasicPermission that = (BasicPermission) p;
   198      *
   197      *
   199      * @param obj the object we are testing for equality with this object.
   198      * @param obj the object we are testing for equality with this object.
   200      * @return true if {@code obj}'s class is the same as this object's class
   199      * @return true if {@code obj}'s class is the same as this object's class
   201      *  and has the same name as this BasicPermission object, false otherwise.
   200      *  and has the same name as this BasicPermission object, false otherwise.
   202      */
   201      */
       
   202     @Override
   203     public boolean equals(Object obj) {
   203     public boolean equals(Object obj) {
   204         if (obj == this)
   204         if (obj == this)
   205             return true;
   205             return true;
   206 
   206 
   207         if ((obj == null) || (obj.getClass() != getClass()))
   207         if ((obj == null) || (obj.getClass() != getClass()))
   219      * {@code getName().hashCode()}, where {@code getName} is
   219      * {@code getName().hashCode()}, where {@code getName} is
   220      * from the Permission superclass.
   220      * from the Permission superclass.
   221      *
   221      *
   222      * @return a hash code value for this object.
   222      * @return a hash code value for this object.
   223      */
   223      */
       
   224     @Override
   224     public int hashCode() {
   225     public int hashCode() {
   225         return this.getName().hashCode();
   226         return this.getName().hashCode();
   226     }
   227     }
   227 
   228 
   228     /**
   229     /**
   230      * which currently is the empty string "", since there are no actions for
   231      * which currently is the empty string "", since there are no actions for
   231      * a BasicPermission.
   232      * a BasicPermission.
   232      *
   233      *
   233      * @return the empty string "".
   234      * @return the empty string "".
   234      */
   235      */
       
   236     @Override
   235     public String getActions() {
   237     public String getActions() {
   236         return "";
   238         return "";
   237     }
   239     }
   238 
   240 
   239     /**
   241     /**
   246      * to be implemented in an efficient (and consistent) manner.
   248      * to be implemented in an efficient (and consistent) manner.
   247      *
   249      *
   248      * @return a new PermissionCollection object suitable for
   250      * @return a new PermissionCollection object suitable for
   249      * storing BasicPermissions.
   251      * storing BasicPermissions.
   250      */
   252      */
       
   253     @Override
   251     public PermissionCollection newPermissionCollection() {
   254     public PermissionCollection newPermissionCollection() {
   252         return new BasicPermissionCollection(this.getClass());
   255         return new BasicPermissionCollection(this.getClass());
   253     }
   256     }
   254 
   257 
   255     /**
   258     /**
   306     /**
   309     /**
   307       * Key is name, value is permission. All permission objects in
   310       * Key is name, value is permission. All permission objects in
   308       * collection must be of the same type.
   311       * collection must be of the same type.
   309       * Not serialized; see serialization section at end of class.
   312       * Not serialized; see serialization section at end of class.
   310       */
   313       */
   311     private transient Map<String, Permission> perms;
   314     private transient ConcurrentHashMap<String, Permission> perms;
   312 
   315 
   313     /**
   316     /**
   314      * This is set to {@code true} if this BasicPermissionCollection
   317      * This is set to {@code true} if this BasicPermissionCollection
   315      * contains a BasicPermission with '*' as its permission name.
   318      * contains a BasicPermission with '*' as its permission name.
   316      *
   319      *
   318      */
   321      */
   319     private boolean all_allowed;
   322     private boolean all_allowed;
   320 
   323 
   321     /**
   324     /**
   322      * The class to which all BasicPermissions in this
   325      * The class to which all BasicPermissions in this
   323      * BasicPermissionCollection belongs.
   326      * BasicPermissionCollection belong.
   324      *
   327      *
   325      * @see #serialPersistentFields
   328      * @see #serialPersistentFields
   326      */
   329      */
   327     private Class<?> permClass;
   330     private Class<?> permClass;
   328 
   331 
   329     /**
   332     /**
   330      * Create an empty BasicPermissionCollection object.
   333      * Create an empty BasicPermissionCollection object.
   331      *
   334      *
   332      */
   335      */
   333 
       
   334     public BasicPermissionCollection(Class<?> clazz) {
   336     public BasicPermissionCollection(Class<?> clazz) {
   335         perms = new HashMap<>(11);
   337         perms = new ConcurrentHashMap<>(11);
   336         all_allowed = false;
   338         all_allowed = false;
   337         permClass = clazz;
   339         permClass = clazz;
   338     }
   340     }
   339 
   341 
   340     /**
   342     /**
   350      *                                       permissions in this collection.
   352      *                                       permissions in this collection.
   351      *
   353      *
   352      * @exception SecurityException - if this BasicPermissionCollection object
   354      * @exception SecurityException - if this BasicPermissionCollection object
   353      *                                has been marked readonly
   355      *                                has been marked readonly
   354      */
   356      */
       
   357     @Override
   355     public void add(Permission permission) {
   358     public void add(Permission permission) {
   356         if (! (permission instanceof BasicPermission))
   359         if (! (permission instanceof BasicPermission))
   357             throw new IllegalArgumentException("invalid permission: "+
   360             throw new IllegalArgumentException("invalid permission: "+
   358                                                permission);
   361                                                permission);
   359         if (isReadOnly())
   362         if (isReadOnly())
   371             if (bp.getClass() != permClass)
   374             if (bp.getClass() != permClass)
   372                 throw new IllegalArgumentException("invalid permission: " +
   375                 throw new IllegalArgumentException("invalid permission: " +
   373                                                 permission);
   376                                                 permission);
   374         }
   377         }
   375 
   378 
   376         synchronized (this) {
   379         String canonName = bp.getCanonicalName();
   377             perms.put(bp.getCanonicalName(), permission);
   380         perms.put(canonName, permission);
   378         }
       
   379 
   381 
   380         // No sync on all_allowed; staleness OK
   382         // No sync on all_allowed; staleness OK
   381         if (!all_allowed) {
   383         if (!all_allowed) {
   382             if (bp.getCanonicalName().equals("*"))
   384             if (canonName.equals("*"))
   383                 all_allowed = true;
   385                 all_allowed = true;
   384         }
   386         }
   385     }
   387     }
   386 
   388 
   387     /**
   389     /**
   391      * @param permission the Permission object to compare
   393      * @param permission the Permission object to compare
   392      *
   394      *
   393      * @return true if "permission" is a proper subset of a permission in
   395      * @return true if "permission" is a proper subset of a permission in
   394      * the set, false if not.
   396      * the set, false if not.
   395      */
   397      */
       
   398     @Override
   396     public boolean implies(Permission permission) {
   399     public boolean implies(Permission permission) {
   397         if (! (permission instanceof BasicPermission))
   400         if (! (permission instanceof BasicPermission))
   398             return false;
   401             return false;
   399 
   402 
   400         BasicPermission bp = (BasicPermission) permission;
   403         BasicPermission bp = (BasicPermission) permission;
   412         // path looking for matches on a.b..*
   415         // path looking for matches on a.b..*
   413 
   416 
   414         String path = bp.getCanonicalName();
   417         String path = bp.getCanonicalName();
   415         //System.out.println("check "+path);
   418         //System.out.println("check "+path);
   416 
   419 
   417         Permission x;
   420         Permission x = perms.get(path);
   418 
       
   419         synchronized (this) {
       
   420             x = perms.get(path);
       
   421         }
       
   422 
   421 
   423         if (x != null) {
   422         if (x != null) {
   424             // we have a direct hit!
   423             // we have a direct hit!
   425             return x.implies(permission);
   424             return x.implies(permission);
   426         }
   425         }
   433         while ((last = path.lastIndexOf('.', offset)) != -1) {
   432         while ((last = path.lastIndexOf('.', offset)) != -1) {
   434 
   433 
   435             path = path.substring(0, last+1) + "*";
   434             path = path.substring(0, last+1) + "*";
   436             //System.out.println("check "+path);
   435             //System.out.println("check "+path);
   437 
   436 
   438             synchronized (this) {
   437             x = perms.get(path);
   439                 x = perms.get(path);
       
   440             }
       
   441 
   438 
   442             if (x != null) {
   439             if (x != null) {
   443                 return x.implies(permission);
   440                 return x.implies(permission);
   444             }
   441             }
   445             offset = last -1;
   442             offset = last -1;
   454      * Returns an enumeration of all the BasicPermission objects in the
   451      * Returns an enumeration of all the BasicPermission objects in the
   455      * container.
   452      * container.
   456      *
   453      *
   457      * @return an enumeration of all the BasicPermission objects.
   454      * @return an enumeration of all the BasicPermission objects.
   458      */
   455      */
       
   456     @Override
   459     public Enumeration<Permission> elements() {
   457     public Enumeration<Permission> elements() {
   460         // Convert Iterator of Map values into an Enumeration
   458         return perms.elements();
   461         synchronized (this) {
       
   462             return Collections.enumeration(perms.values());
       
   463         }
       
   464     }
   459     }
   465 
   460 
   466     // Need to maintain serialization interoperability with earlier releases,
   461     // Need to maintain serialization interoperability with earlier releases,
   467     // which had the serializable field:
   462     // which had the serializable field:
   468     //
   463     //
   501 
   496 
   502         // Copy perms into a Hashtable
   497         // Copy perms into a Hashtable
   503         Hashtable<String, Permission> permissions =
   498         Hashtable<String, Permission> permissions =
   504                 new Hashtable<>(perms.size()*2);
   499                 new Hashtable<>(perms.size()*2);
   505 
   500 
   506         synchronized (this) {
   501         permissions.putAll(perms);
   507             permissions.putAll(perms);
       
   508         }
       
   509 
   502 
   510         // Write out serializable fields
   503         // Write out serializable fields
   511         ObjectOutputStream.PutField pfields = out.putFields();
   504         ObjectOutputStream.PutField pfields = out.putFields();
   512         pfields.put("all_allowed", all_allowed);
   505         pfields.put("all_allowed", all_allowed);
   513         pfields.put("permissions", permissions);
   506         pfields.put("permissions", permissions);
   531         // writeObject writes a Hashtable<String, Permission> for the
   524         // writeObject writes a Hashtable<String, Permission> for the
   532         // permissions key, so this cast is safe, unless the data is corrupt.
   525         // permissions key, so this cast is safe, unless the data is corrupt.
   533         @SuppressWarnings("unchecked")
   526         @SuppressWarnings("unchecked")
   534         Hashtable<String, Permission> permissions =
   527         Hashtable<String, Permission> permissions =
   535                 (Hashtable<String, Permission>)gfields.get("permissions", null);
   528                 (Hashtable<String, Permission>)gfields.get("permissions", null);
   536         perms = new HashMap<>(permissions.size()*2);
   529         perms = new ConcurrentHashMap<>(permissions.size()*2);
   537         perms.putAll(permissions);
   530         perms.putAll(permissions);
   538 
   531 
   539         // Get all_allowed
   532         // Get all_allowed
   540         all_allowed = gfields.get("all_allowed", false);
   533         all_allowed = gfields.get("all_allowed", false);
   541 
   534