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()).append(" (\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 }