src/java.base/share/classes/java/security/PermissionCollection.java
changeset 47216 71c04702a3d5
parent 45434 4582657c7260
child 57950 4612a3cfb927
child 58678 9cf78a70fa4f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/security/PermissionCollection.java	Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.security;
+
+import java.util.*;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+/**
+ * Abstract class representing a collection of Permission objects.
+ *
+ * <p>With a PermissionCollection, you can:
+ * <UL>
+ * <LI> add a permission to the collection using the {@code add} method.
+ * <LI> check to see if a particular permission is implied in the
+ *      collection, using the {@code implies} method.
+ * <LI> enumerate all the permissions, using the {@code elements} method.
+ * </UL>
+ *
+ * <p>When it is desirable to group together a number of Permission objects
+ * of the same type, the {@code newPermissionCollection} method on that
+ * particular type of Permission object should first be called. The default
+ * behavior (from the Permission class) is to simply return null.
+ * Subclasses of class Permission override the method if they need to store
+ * their permissions in a particular PermissionCollection object in order
+ * to provide the correct semantics when the
+ * {@code PermissionCollection.implies} method is called.
+ * If a non-null value is returned, that PermissionCollection must be used.
+ * If null is returned, then the caller of {@code newPermissionCollection}
+ * is free to store permissions of the
+ * given type in any PermissionCollection they choose
+ * (one that uses a Hashtable, one that uses a Vector, etc).
+ *
+ * <p>The PermissionCollection returned by the
+ * {@code Permission.newPermissionCollection}
+ * method is a homogeneous collection, which stores only Permission objects
+ * for a given Permission type.  A PermissionCollection may also be
+ * heterogeneous.  For example, Permissions is a PermissionCollection
+ * subclass that represents a collection of PermissionCollections.
+ * That is, its members are each a homogeneous PermissionCollection.
+ * For example, a Permissions object might have a FilePermissionCollection
+ * for all the FilePermission objects, a SocketPermissionCollection for all the
+ * SocketPermission objects, and so on. Its {@code add} method adds a
+ * permission to the appropriate collection.
+ *
+ * <p>Whenever a permission is added to a heterogeneous PermissionCollection
+ * such as Permissions, and the PermissionCollection doesn't yet contain a
+ * PermissionCollection of the specified permission's type, the
+ * PermissionCollection should call
+ * the {@code newPermissionCollection} method on the permission's class
+ * to see if it requires a special PermissionCollection. If
+ * {@code newPermissionCollection}
+ * returns null, the PermissionCollection
+ * is free to store the permission in any type of PermissionCollection it
+ * desires (one using a Hashtable, one using a Vector, etc.). For example,
+ * the Permissions object uses a default PermissionCollection implementation
+ * that stores the permission objects in a Hashtable.
+ *
+ * <p> Subclass implementations of PermissionCollection should assume
+ * that they may be called simultaneously from multiple threads,
+ * and therefore should be synchronized properly.  Furthermore,
+ * Enumerations returned via the {@code elements} method are
+ * not <em>fail-fast</em>.  Modifications to a collection should not be
+ * performed while enumerating over that collection.
+ *
+ * @see Permission
+ * @see Permissions
+ *
+ *
+ * @author Roland Schemers
+ * @since 1.2
+ */
+
+public abstract class PermissionCollection implements java.io.Serializable {
+
+    private static final long serialVersionUID = -6727011328946861783L;
+
+    // when set, add will throw an exception.
+    private volatile boolean readOnly;
+
+    /**
+     * Adds a permission object to the current collection of permission objects.
+     *
+     * @param permission the Permission object to add.
+     *
+     * @exception SecurityException -  if this PermissionCollection object
+     *                                 has been marked readonly
+     * @exception IllegalArgumentException - if this PermissionCollection
+     *                object is a homogeneous collection and the permission
+     *                is not of the correct type.
+     */
+    public abstract void add(Permission permission);
+
+    /**
+     * Checks to see if the specified permission is implied by
+     * the collection of Permission objects held in this PermissionCollection.
+     *
+     * @param permission the Permission object to compare.
+     *
+     * @return true if "permission" is implied by the  permissions in
+     * the collection, false if not.
+     */
+    public abstract boolean implies(Permission permission);
+
+    /**
+     * Returns an enumeration of all the Permission objects in the collection.
+     *
+     * @return an enumeration of all the Permissions.
+     * @see #elementsAsStream()
+     */
+    public abstract Enumeration<Permission> elements();
+
+    /**
+     * Returns a stream of all the Permission objects in the collection.
+     *
+     * <p> The collection should not be modified (see {@link #add}) during the
+     * execution of the terminal stream operation. Otherwise, the result of the
+     * terminal stream operation is undefined.
+     *
+     * @implSpec
+     * The default implementation creates a stream whose source is derived from
+     * the enumeration returned from a call to {@link #elements()}.
+     *
+     * @return a stream of all the Permissions.
+     * @since 9
+     */
+    public Stream<Permission> elementsAsStream() {
+        int characteristics = isReadOnly()
+                ? Spliterator.NONNULL | Spliterator.IMMUTABLE
+                : Spliterator.NONNULL;
+        return StreamSupport.stream(
+                Spliterators.spliteratorUnknownSize(
+                        elements().asIterator(), characteristics),
+                false);
+    }
+
+    /**
+     * Marks this PermissionCollection object as "readonly". After
+     * a PermissionCollection object
+     * is marked as readonly, no new Permission objects can be added to it
+     * using {@code add}.
+     */
+    public void setReadOnly() {
+        readOnly = true;
+    }
+
+    /**
+     * Returns true if this PermissionCollection object is marked as readonly.
+     * If it is readonly, no new Permission objects can be added to it
+     * using {@code add}.
+     *
+     * <p>By default, the object is <i>not</i> readonly. It can be set to
+     * readonly by a call to {@code setReadOnly}.
+     *
+     * @return true if this PermissionCollection object is marked as readonly,
+     * false otherwise.
+     */
+    public boolean isReadOnly() {
+        return readOnly;
+    }
+
+    /**
+     * Returns a string describing this PermissionCollection object,
+     * providing information about all the permissions it contains.
+     * The format is:
+     * <pre>
+     * super.toString() (
+     *   // enumerate all the Permission
+     *   // objects and call toString() on them,
+     *   // one per line..
+     * )</pre>
+     *
+     * {@code super.toString} is a call to the {@code toString}
+     * method of this
+     * object's superclass, which is Object. The result is
+     * this PermissionCollection's type name followed by this object's
+     * hashcode, thus enabling clients to differentiate different
+     * PermissionCollections object, even if they contain the same permissions.
+     *
+     * @return information about this PermissionCollection object,
+     *         as described above.
+     *
+     */
+    public String toString() {
+        Enumeration<Permission> enum_ = elements();
+        StringBuilder sb = new StringBuilder();
+        sb.append(super.toString()+" (\n");
+        while (enum_.hasMoreElements()) {
+            try {
+                sb.append(" ");
+                sb.append(enum_.nextElement().toString());
+                sb.append("\n");
+            } catch (NoSuchElementException e){
+                // ignore
+            }
+        }
+        sb.append(")\n");
+        return sb.toString();
+    }
+}