View Javadoc
1   /*
2    * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package java.security;
27  
28  import java.util.*;
29  
30  /**
31   * Abstract class representing a collection of Permission objects.
32   *
33   * <p>With a PermissionCollection, you can:
34   * <UL>
35   * <LI> add a permission to the collection using the {@code add} method.
36   * <LI> check to see if a particular permission is implied in the
37   *      collection, using the {@code implies} method.
38   * <LI> enumerate all the permissions, using the {@code elements} method.
39   * </UL>
40   *
41   * <p>When it is desirable to group together a number of Permission objects
42   * of the same type, the {@code newPermissionCollection} method on that
43   * particular type of Permission object should first be called. The default
44   * behavior (from the Permission class) is to simply return null.
45   * Subclasses of class Permission override the method if they need to store
46   * their permissions in a particular PermissionCollection object in order
47   * to provide the correct semantics when the
48   * {@code PermissionCollection.implies} method is called.
49   * If a non-null value is returned, that PermissionCollection must be used.
50   * If null is returned, then the caller of {@code newPermissionCollection}
51   * is free to store permissions of the
52   * given type in any PermissionCollection they choose
53   * (one that uses a Hashtable, one that uses a Vector, etc).
54   *
55   * <p>The PermissionCollection returned by the
56   * {@code Permission.newPermissionCollection}
57   * method is a homogeneous collection, which stores only Permission objects
58   * for a given Permission type.  A PermissionCollection may also be
59   * heterogeneous.  For example, Permissions is a PermissionCollection
60   * subclass that represents a collection of PermissionCollections.
61   * That is, its members are each a homogeneous PermissionCollection.
62   * For example, a Permissions object might have a FilePermissionCollection
63   * for all the FilePermission objects, a SocketPermissionCollection for all the
64   * SocketPermission objects, and so on. Its {@code add} method adds a
65   * permission to the appropriate collection.
66   *
67   * <p>Whenever a permission is added to a heterogeneous PermissionCollection
68   * such as Permissions, and the PermissionCollection doesn't yet contain a
69   * PermissionCollection of the specified permission's type, the
70   * PermissionCollection should call
71   * the {@code newPermissionCollection} method on the permission's class
72   * to see if it requires a special PermissionCollection. If
73   * {@code newPermissionCollection}
74   * returns null, the PermissionCollection
75   * is free to store the permission in any type of PermissionCollection it
76   * desires (one using a Hashtable, one using a Vector, etc.). For example,
77   * the Permissions object uses a default PermissionCollection implementation
78   * that stores the permission objects in a Hashtable.
79   *
80   * <p> Subclass implementations of PermissionCollection should assume
81   * that they may be called simultaneously from multiple threads,
82   * and therefore should be synchronized properly.  Furthermore,
83   * Enumerations returned via the {@code elements} method are
84   * not <em>fail-fast</em>.  Modifications to a collection should not be
85   * performed while enumerating over that collection.
86   *
87   * @see Permission
88   * @see Permissions
89   *
90   *
91   * @author Roland Schemers
92   */
93  
94  public abstract class PermissionCollection implements java.io.Serializable {
95  
96      private static final long serialVersionUID = -6727011328946861783L;
97  
98      // when set, add will throw an exception.
99      private volatile boolean readOnly;
100 
101     /**
102      * Adds a permission object to the current collection of permission objects.
103      *
104      * @param permission the Permission object to add.
105      *
106      * @exception SecurityException -  if this PermissionCollection object
107      *                                 has been marked readonly
108      * @exception IllegalArgumentException - if this PermissionCollection
109      *                object is a homogeneous collection and the permission
110      *                is not of the correct type.
111      */
112     public abstract void add(Permission permission);
113 
114     /**
115      * Checks to see if the specified permission is implied by
116      * the collection of Permission objects held in this PermissionCollection.
117      *
118      * @param permission the Permission object to compare.
119      *
120      * @return true if "permission" is implied by the  permissions in
121      * the collection, false if not.
122      */
123     public abstract boolean implies(Permission permission);
124 
125     /**
126      * Returns an enumeration of all the Permission objects in the collection.
127      *
128      * @return an enumeration of all the Permissions.
129      */
130     public abstract Enumeration<Permission> elements();
131 
132     /**
133      * Marks this PermissionCollection object as "readonly". After
134      * a PermissionCollection object
135      * is marked as readonly, no new Permission objects can be added to it
136      * using {@code add}.
137      */
138     public void setReadOnly() {
139         readOnly = true;
140     }
141 
142     /**
143      * Returns true if this PermissionCollection object is marked as readonly.
144      * If it is readonly, no new Permission objects can be added to it
145      * using {@code add}.
146      *
147      * <p>By default, the object is <i>not</i> readonly. It can be set to
148      * readonly by a call to {@code setReadOnly}.
149      *
150      * @return true if this PermissionCollection object is marked as readonly,
151      * false otherwise.
152      */
153     public boolean isReadOnly() {
154         return readOnly;
155     }
156 
157     /**
158      * Returns a string describing this PermissionCollection object,
159      * providing information about all the permissions it contains.
160      * The format is:
161      * <pre>
162      * super.toString() (
163      *   // enumerate all the Permission
164      *   // objects and call toString() on them,
165      *   // one per line..
166      * )</pre>
167      *
168      * {@code super.toString} is a call to the {@code toString}
169      * method of this
170      * object's superclass, which is Object. The result is
171      * this PermissionCollection's type name followed by this object's
172      * hashcode, thus enabling clients to differentiate different
173      * PermissionCollections object, even if they contain the same permissions.
174      *
175      * @return information about this PermissionCollection object,
176      *         as described above.
177      *
178      */
179     public String toString() {
180         Enumeration<Permission> enum_ = elements();
181         StringBuilder sb = new StringBuilder();
182         sb.append(super.toString()+" (\n");
183         while (enum_.hasMoreElements()) {
184             try {
185                 sb.append(" ");
186                 sb.append(enum_.nextElement().toString());
187                 sb.append("\n");
188             } catch (NoSuchElementException e){
189                 // ignore
190             }
191         }
192         sb.append(")\n");
193         return sb.toString();
194     }
195 }