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
|