src/share/classes/java/security/BasicPermission.java

Print this page




  51  * <P>
  52  * The action string (inherited from Permission) is unused.
  53  * Thus, BasicPermission is commonly used as the base class for
  54  * "named" permissions
  55  * (ones that contain a name but no actions list; you either have the
  56  * named permission or you don't.)
  57  * Subclasses may implement actions on top of BasicPermission,
  58  * if desired.
  59  * <p>
  60  * <P>
  61  * @see java.security.Permission
  62  * @see java.security.Permissions
  63  * @see java.security.PermissionCollection
  64  * @see java.lang.SecurityManager
  65  *
  66  * @author Marianne Mueller
  67  * @author Roland Schemers
  68  */
  69 
  70 public abstract class BasicPermission extends Permission
  71 implements java.io.Serializable
  72 {
  73 
  74     private static final long serialVersionUID = 6279438298436773498L;
  75 
  76     // does this permission have a wildcard at the end?
  77     private transient boolean wildcard;
  78 
  79     // the name without the wildcard on the end
  80     private transient String path;
  81 
  82     // is this permission the old-style exitVM permission (pre JDK 1.6)?
  83     private transient boolean exitVM;
  84 
  85     /**
  86      * initialize a BasicPermission object. Common to all constructors.
  87      *
  88      */
  89     private void init(String name)
  90     {
  91         if (name == null)
  92             throw new NullPointerException("name can't be null");
  93 
  94         int len = name.length();
  95 
  96         if (len == 0) {
  97             throw new IllegalArgumentException("name can't be empty");
  98         }
  99 
 100         char last = name.charAt(len - 1);
 101 
 102         // Is wildcard or ends with ".*"?
 103         if (last == '*' && (len == 1 || name.charAt(len - 2) == '.')) {
 104             wildcard = true;
 105             if (len == 1) {
 106                 path = "";
 107             } else {
 108                 path = name.substring(0, len - 1);
 109             }
 110         } else {


 112                 wildcard = true;
 113                 path = "exitVM.";
 114                 exitVM = true;
 115             } else {
 116                 path = name;
 117             }
 118         }
 119     }
 120 
 121     /**
 122      * Creates a new BasicPermission with the specified name.
 123      * Name is the symbolic name of the permission, such as
 124      * "setFactory",
 125      * "print.queueJob", or "topLevelWindow", etc.
 126      *
 127      * @param name the name of the BasicPermission.
 128      *
 129      * @throws NullPointerException if <code>name</code> is <code>null</code>.
 130      * @throws IllegalArgumentException if <code>name</code> is empty.
 131      */
 132 
 133     public BasicPermission(String name)
 134     {
 135         super(name);
 136         init(name);
 137     }
 138 
 139 
 140     /**
 141      * Creates a new BasicPermission object with the specified name.
 142      * The name is the symbolic name of the BasicPermission, and the
 143      * actions String is currently unused.
 144      *
 145      * @param name the name of the BasicPermission.
 146      * @param actions ignored.
 147      *
 148      * @throws NullPointerException if <code>name</code> is <code>null</code>.
 149      * @throws IllegalArgumentException if <code>name</code> is empty.
 150      */
 151     public BasicPermission(String name, String actions)
 152     {
 153         super(name);
 154         init(name);
 155     }
 156 
 157     /**
 158      * Checks if the specified permission is "implied" by
 159      * this object.
 160      * <P>
 161      * More specifically, this method returns true if:<p>
 162      * <ul>
 163      * <li> <i>p</i>'s class is the same as this object's class, and<p>
 164      * <li> <i>p</i>'s name equals or (in the case of wildcards)
 165      *      is implied by this object's
 166      *      name. For example, "a.b.*" implies "a.b.c".
 167      * </ul>
 168      *
 169      * @param p the permission to check against.
 170      *
 171      * @return true if the passed permission is equal to or
 172      * implied by this permission, false otherwise.


 221 
 222     /**
 223      * Returns the hash code value for this object.
 224      * The hash code used is the hash code of the name, that is,
 225      * <code>getName().hashCode()</code>, where <code>getName</code> is
 226      * from the Permission superclass.
 227      *
 228      * @return a hash code value for this object.
 229      */
 230     public int hashCode() {
 231         return this.getName().hashCode();
 232     }
 233 
 234     /**
 235      * Returns the canonical string representation of the actions,
 236      * which currently is the empty string "", since there are no actions for
 237      * a BasicPermission.
 238      *
 239      * @return the empty string "".
 240      */
 241     public String getActions()
 242     {
 243         return "";
 244     }
 245 
 246     /**
 247      * Returns a new PermissionCollection object for storing BasicPermission
 248      * objects.
 249      *
 250      * <p>BasicPermission objects must be stored in a manner that allows them
 251      * to be inserted in any order, but that also enables the
 252      * PermissionCollection <code>implies</code> method
 253      * to be implemented in an efficient (and consistent) manner.
 254      *
 255      * @return a new PermissionCollection object suitable for
 256      * storing BasicPermissions.
 257      */
 258     public PermissionCollection newPermissionCollection() {
 259         return new BasicPermissionCollection(this.getClass());
 260     }
 261 
 262     /**


 279      *
 280      * @return the canonical name of this BasicPermission.
 281      */
 282     final String getCanonicalName() {
 283         return exitVM ? "exitVM.*" : getName();
 284     }
 285 }
 286 
 287 /**
 288  * A BasicPermissionCollection stores a collection
 289  * of BasicPermission permissions. BasicPermission objects
 290  * must be stored in a manner that allows them to be inserted in any
 291  * order, but enable the implies function to evaluate the implies
 292  * method in an efficient (and consistent) manner.
 293  *
 294  * A BasicPermissionCollection handles comparing a permission like "a.b.c.d.e"
 295  * with a Permission such as "a.b.*", or "*".
 296  *
 297  * @see java.security.Permission
 298  * @see java.security.Permissions
 299  * @see java.security.PermissionsImpl
 300  *
 301  *
 302  * @author Roland Schemers
 303  *
 304  * @serial include
 305  */
 306 
 307 final class BasicPermissionCollection
 308 extends PermissionCollection
 309 implements java.io.Serializable
 310 {
 311 
 312     private static final long serialVersionUID = 739301742472979399L;
 313 
 314     /**
 315       * Key is name, value is permission. All permission objects in
 316       * collection must be of the same type.
 317       * Not serialized; see serialization section at end of class.
 318       */
 319     private transient Map<String, Permission> perms;
 320 
 321     /**
 322      * This is set to <code>true</code> if this BasicPermissionCollection
 323      * contains a BasicPermission with '*' as its permission name.
 324      *
 325      * @see #serialPersistentFields
 326      */
 327     private boolean all_allowed;
 328 
 329     /**


 343         perms = new HashMap<String, Permission>(11);
 344         all_allowed = false;
 345         permClass = clazz;
 346     }
 347 
 348     /**
 349      * Adds a permission to the BasicPermissions. The key for the hash is
 350      * permission.path.
 351      *
 352      * @param permission the Permission object to add.
 353      *
 354      * @exception IllegalArgumentException - if the permission is not a
 355      *                                       BasicPermission, or if
 356      *                                       the permission is not of the
 357      *                                       same Class as the other
 358      *                                       permissions in this collection.
 359      *
 360      * @exception SecurityException - if this BasicPermissionCollection object
 361      *                                has been marked readonly
 362      */
 363 
 364     public void add(Permission permission)
 365     {
 366         if (! (permission instanceof BasicPermission))
 367             throw new IllegalArgumentException("invalid permission: "+
 368                                                permission);
 369         if (isReadOnly())
 370             throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
 371 
 372         BasicPermission bp = (BasicPermission) permission;
 373 
 374         // make sure we only add new BasicPermissions of the same class
 375         // Also check null for compatibility with deserialized form from
 376         // previous versions.
 377         if (permClass == null) {
 378             // adding first permission
 379             permClass = bp.getClass();
 380         } else {
 381             if (bp.getClass() != permClass)
 382                 throw new IllegalArgumentException("invalid permission: " +
 383                                                 permission);
 384         }
 385 
 386         synchronized (this) {
 387             perms.put(bp.getCanonicalName(), permission);
 388         }
 389 
 390         // No sync on all_allowed; staleness OK
 391         if (!all_allowed) {
 392             if (bp.getCanonicalName().equals("*"))
 393                 all_allowed = true;
 394         }
 395     }
 396 
 397     /**
 398      * Check and see if this set of permissions implies the permissions
 399      * expressed in "permission".
 400      *
 401      * @param p the Permission object to compare
 402      *
 403      * @return true if "permission" is a proper subset of a permission in
 404      * the set, false if not.
 405      */
 406 
 407     public boolean implies(Permission permission)
 408     {
 409         if (! (permission instanceof BasicPermission))
 410                 return false;
 411 
 412         BasicPermission bp = (BasicPermission) permission;
 413 
 414         // random subclasses of BasicPermission do not imply each other
 415         if (bp.getClass() != permClass)
 416             return false;
 417 
 418         // short circuit if the "*" Permission was added
 419         if (all_allowed)
 420             return true;
 421 
 422         // strategy:
 423         // Check for full match first. Then work our way up the
 424         // path looking for matches on a.b..*
 425 
 426         String path = bp.getCanonicalName();
 427         //System.out.println("check "+path);
 428 


 451                 x = perms.get(path);
 452             }
 453 
 454             if (x != null) {
 455                 return x.implies(permission);
 456             }
 457             offset = last -1;
 458         }
 459 
 460         // we don't have to check for "*" as it was already checked
 461         // at the top (all_allowed), so we just return false
 462         return false;
 463     }
 464 
 465     /**
 466      * Returns an enumeration of all the BasicPermission objects in the
 467      * container.
 468      *
 469      * @return an enumeration of all the BasicPermission objects.
 470      */
 471 
 472     public Enumeration<Permission> elements() {
 473         // Convert Iterator of Map values into an Enumeration
 474         synchronized (this) {
 475             return Collections.enumeration(perms.values());
 476         }
 477     }
 478 
 479     // Need to maintain serialization interoperability with earlier releases,
 480     // which had the serializable field:
 481     //
 482     // @serial the Hashtable is indexed by the BasicPermission name
 483     //
 484     // private Hashtable permissions;
 485     /**
 486      * @serialField permissions java.util.Hashtable
 487      *    The BasicPermissions in this BasicPermissionCollection.
 488      *    All BasicPermissions in the collection must belong to the same class.
 489      *    The Hashtable is indexed by the BasicPermission name; the value
 490      *    of the Hashtable entry is the permission.
 491      * @serialField all_allowed boolean




  51  * <P>
  52  * The action string (inherited from Permission) is unused.
  53  * Thus, BasicPermission is commonly used as the base class for
  54  * "named" permissions
  55  * (ones that contain a name but no actions list; you either have the
  56  * named permission or you don't.)
  57  * Subclasses may implement actions on top of BasicPermission,
  58  * if desired.
  59  * <p>
  60  * <P>
  61  * @see java.security.Permission
  62  * @see java.security.Permissions
  63  * @see java.security.PermissionCollection
  64  * @see java.lang.SecurityManager
  65  *
  66  * @author Marianne Mueller
  67  * @author Roland Schemers
  68  */
  69 
  70 public abstract class BasicPermission extends Permission
  71     implements java.io.Serializable
  72 {
  73 
  74     private static final long serialVersionUID = 6279438298436773498L;
  75 
  76     // does this permission have a wildcard at the end?
  77     private transient boolean wildcard;
  78 
  79     // the name without the wildcard on the end
  80     private transient String path;
  81 
  82     // is this permission the old-style exitVM permission (pre JDK 1.6)?
  83     private transient boolean exitVM;
  84 
  85     /**
  86      * initialize a BasicPermission object. Common to all constructors.

  87      */
  88     private void init(String name) {

  89         if (name == null)
  90             throw new NullPointerException("name can't be null");
  91 
  92         int len = name.length();
  93 
  94         if (len == 0) {
  95             throw new IllegalArgumentException("name can't be empty");
  96         }
  97 
  98         char last = name.charAt(len - 1);
  99 
 100         // Is wildcard or ends with ".*"?
 101         if (last == '*' && (len == 1 || name.charAt(len - 2) == '.')) {
 102             wildcard = true;
 103             if (len == 1) {
 104                 path = "";
 105             } else {
 106                 path = name.substring(0, len - 1);
 107             }
 108         } else {


 110                 wildcard = true;
 111                 path = "exitVM.";
 112                 exitVM = true;
 113             } else {
 114                 path = name;
 115             }
 116         }
 117     }
 118 
 119     /**
 120      * Creates a new BasicPermission with the specified name.
 121      * Name is the symbolic name of the permission, such as
 122      * "setFactory",
 123      * "print.queueJob", or "topLevelWindow", etc.
 124      *
 125      * @param name the name of the BasicPermission.
 126      *
 127      * @throws NullPointerException if <code>name</code> is <code>null</code>.
 128      * @throws IllegalArgumentException if <code>name</code> is empty.
 129      */
 130     public BasicPermission(String name) {


 131         super(name);
 132         init(name);
 133     }
 134 
 135 
 136     /**
 137      * Creates a new BasicPermission object with the specified name.
 138      * The name is the symbolic name of the BasicPermission, and the
 139      * actions String is currently unused.
 140      *
 141      * @param name the name of the BasicPermission.
 142      * @param actions ignored.
 143      *
 144      * @throws NullPointerException if <code>name</code> is <code>null</code>.
 145      * @throws IllegalArgumentException if <code>name</code> is empty.
 146      */
 147     public BasicPermission(String name, String actions) {

 148         super(name);
 149         init(name);
 150     }
 151 
 152     /**
 153      * Checks if the specified permission is "implied" by
 154      * this object.
 155      * <P>
 156      * More specifically, this method returns true if:<p>
 157      * <ul>
 158      * <li> <i>p</i>'s class is the same as this object's class, and<p>
 159      * <li> <i>p</i>'s name equals or (in the case of wildcards)
 160      *      is implied by this object's
 161      *      name. For example, "a.b.*" implies "a.b.c".
 162      * </ul>
 163      *
 164      * @param p the permission to check against.
 165      *
 166      * @return true if the passed permission is equal to or
 167      * implied by this permission, false otherwise.


 216 
 217     /**
 218      * Returns the hash code value for this object.
 219      * The hash code used is the hash code of the name, that is,
 220      * <code>getName().hashCode()</code>, where <code>getName</code> is
 221      * from the Permission superclass.
 222      *
 223      * @return a hash code value for this object.
 224      */
 225     public int hashCode() {
 226         return this.getName().hashCode();
 227     }
 228 
 229     /**
 230      * Returns the canonical string representation of the actions,
 231      * which currently is the empty string "", since there are no actions for
 232      * a BasicPermission.
 233      *
 234      * @return the empty string "".
 235      */
 236     public String getActions() {

 237         return "";
 238     }
 239 
 240     /**
 241      * Returns a new PermissionCollection object for storing BasicPermission
 242      * objects.
 243      *
 244      * <p>BasicPermission objects must be stored in a manner that allows them
 245      * to be inserted in any order, but that also enables the
 246      * PermissionCollection <code>implies</code> method
 247      * to be implemented in an efficient (and consistent) manner.
 248      *
 249      * @return a new PermissionCollection object suitable for
 250      * storing BasicPermissions.
 251      */
 252     public PermissionCollection newPermissionCollection() {
 253         return new BasicPermissionCollection(this.getClass());
 254     }
 255 
 256     /**


 273      *
 274      * @return the canonical name of this BasicPermission.
 275      */
 276     final String getCanonicalName() {
 277         return exitVM ? "exitVM.*" : getName();
 278     }
 279 }
 280 
 281 /**
 282  * A BasicPermissionCollection stores a collection
 283  * of BasicPermission permissions. BasicPermission objects
 284  * must be stored in a manner that allows them to be inserted in any
 285  * order, but enable the implies function to evaluate the implies
 286  * method in an efficient (and consistent) manner.
 287  *
 288  * A BasicPermissionCollection handles comparing a permission like "a.b.c.d.e"
 289  * with a Permission such as "a.b.*", or "*".
 290  *
 291  * @see java.security.Permission
 292  * @see java.security.Permissions

 293  *
 294  *
 295  * @author Roland Schemers
 296  *
 297  * @serial include
 298  */
 299 
 300 final class BasicPermissionCollection
 301     extends PermissionCollection
 302     implements java.io.Serializable
 303 {
 304 
 305     private static final long serialVersionUID = 739301742472979399L;
 306 
 307     /**
 308       * Key is name, value is permission. All permission objects in
 309       * collection must be of the same type.
 310       * Not serialized; see serialization section at end of class.
 311       */
 312     private transient Map<String, Permission> perms;
 313 
 314     /**
 315      * This is set to <code>true</code> if this BasicPermissionCollection
 316      * contains a BasicPermission with '*' as its permission name.
 317      *
 318      * @see #serialPersistentFields
 319      */
 320     private boolean all_allowed;
 321 
 322     /**


 336         perms = new HashMap<String, Permission>(11);
 337         all_allowed = false;
 338         permClass = clazz;
 339     }
 340 
 341     /**
 342      * Adds a permission to the BasicPermissions. The key for the hash is
 343      * permission.path.
 344      *
 345      * @param permission the Permission object to add.
 346      *
 347      * @exception IllegalArgumentException - if the permission is not a
 348      *                                       BasicPermission, or if
 349      *                                       the permission is not of the
 350      *                                       same Class as the other
 351      *                                       permissions in this collection.
 352      *
 353      * @exception SecurityException - if this BasicPermissionCollection object
 354      *                                has been marked readonly
 355      */
 356     public void add(Permission permission) {


 357         if (! (permission instanceof BasicPermission))
 358             throw new IllegalArgumentException("invalid permission: "+
 359                                                permission);
 360         if (isReadOnly())
 361             throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection");
 362 
 363         BasicPermission bp = (BasicPermission) permission;
 364 
 365         // make sure we only add new BasicPermissions of the same class
 366         // Also check null for compatibility with deserialized form from
 367         // previous versions.
 368         if (permClass == null) {
 369             // adding first permission
 370             permClass = bp.getClass();
 371         } else {
 372             if (bp.getClass() != permClass)
 373                 throw new IllegalArgumentException("invalid permission: " +
 374                                                 permission);
 375         }
 376 
 377         synchronized (this) {
 378             perms.put(bp.getCanonicalName(), permission);
 379         }
 380 
 381         // No sync on all_allowed; staleness OK
 382         if (!all_allowed) {
 383             if (bp.getCanonicalName().equals("*"))
 384                 all_allowed = true;
 385         }
 386     }
 387 
 388     /**
 389      * Check and see if this set of permissions implies the permissions
 390      * expressed in "permission".
 391      *
 392      * @param permission the Permission object to compare
 393      *
 394      * @return true if "permission" is a proper subset of a permission in
 395      * the set, false if not.
 396      */
 397     public boolean implies(Permission permission) {


 398         if (! (permission instanceof BasicPermission))
 399             return false;
 400 
 401         BasicPermission bp = (BasicPermission) permission;
 402 
 403         // random subclasses of BasicPermission do not imply each other
 404         if (bp.getClass() != permClass)
 405             return false;
 406 
 407         // short circuit if the "*" Permission was added
 408         if (all_allowed)
 409             return true;
 410 
 411         // strategy:
 412         // Check for full match first. Then work our way up the
 413         // path looking for matches on a.b..*
 414 
 415         String path = bp.getCanonicalName();
 416         //System.out.println("check "+path);
 417 


 440                 x = perms.get(path);
 441             }
 442 
 443             if (x != null) {
 444                 return x.implies(permission);
 445             }
 446             offset = last -1;
 447         }
 448 
 449         // we don't have to check for "*" as it was already checked
 450         // at the top (all_allowed), so we just return false
 451         return false;
 452     }
 453 
 454     /**
 455      * Returns an enumeration of all the BasicPermission objects in the
 456      * container.
 457      *
 458      * @return an enumeration of all the BasicPermission objects.
 459      */

 460     public Enumeration<Permission> elements() {
 461         // Convert Iterator of Map values into an Enumeration
 462         synchronized (this) {
 463             return Collections.enumeration(perms.values());
 464         }
 465     }
 466 
 467     // Need to maintain serialization interoperability with earlier releases,
 468     // which had the serializable field:
 469     //
 470     // @serial the Hashtable is indexed by the BasicPermission name
 471     //
 472     // private Hashtable permissions;
 473     /**
 474      * @serialField permissions java.util.Hashtable
 475      *    The BasicPermissions in this BasicPermissionCollection.
 476      *    All BasicPermissions in the collection must belong to the same class.
 477      *    The Hashtable is indexed by the BasicPermission name; the value
 478      *    of the Hashtable entry is the permission.
 479      * @serialField all_allowed boolean