Home | History | Annotate | Download | only in security
      1 /*
      2  * Copyright (c) 1997, 2011, 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 import java.io.ObjectStreamField;
     30 import java.io.ObjectOutputStream;
     31 import java.io.ObjectInputStream;
     32 import java.io.IOException;
     33 
     34 /**
     35  * A UnresolvedPermissionCollection stores a collection
     36  * of UnresolvedPermission permissions.
     37  *
     38  * @see java.security.Permission
     39  * @see java.security.Permissions
     40  * @see java.security.UnresolvedPermission
     41  *
     42  *
     43  * @author Roland Schemers
     44  *
     45  * @serial include
     46  */
     47 
     48 final class UnresolvedPermissionCollection
     49 extends PermissionCollection
     50 implements java.io.Serializable
     51 {
     52     /**
     53      * Key is permission type, value is a list of the UnresolvedPermissions
     54      * of the same type.
     55      * Not serialized; see serialization section at end of class.
     56      */
     57     private transient Map<String, List<UnresolvedPermission>> perms;
     58 
     59     /**
     60      * Create an empty UnresolvedPermissionCollection object.
     61      *
     62      */
     63     public UnresolvedPermissionCollection() {
     64         perms = new HashMap<String, List<UnresolvedPermission>>(11);
     65     }
     66 
     67     /**
     68      * Adds a permission to this UnresolvedPermissionCollection.
     69      * The key for the hash is the unresolved permission's type (class) name.
     70      *
     71      * @param permission the Permission object to add.
     72      */
     73 
     74     public void add(Permission permission)
     75     {
     76         if (! (permission instanceof UnresolvedPermission))
     77             throw new IllegalArgumentException("invalid permission: "+
     78                                                permission);
     79         UnresolvedPermission up = (UnresolvedPermission) permission;
     80 
     81         List<UnresolvedPermission> v;
     82         synchronized (this) {
     83             v = perms.get(up.getName());
     84             if (v == null) {
     85                 v = new ArrayList<UnresolvedPermission>();
     86                 perms.put(up.getName(), v);
     87             }
     88         }
     89         synchronized (v) {
     90             v.add(up);
     91         }
     92     }
     93 
     94     /**
     95      * get any unresolved permissions of the same type as p,
     96      * and return the List containing them.
     97      */
     98     List<UnresolvedPermission> getUnresolvedPermissions(Permission p) {
     99         synchronized (this) {
    100             return perms.get(p.getClass().getName());
    101         }
    102     }
    103 
    104     /**
    105      * always returns false for unresolved permissions
    106      *
    107      */
    108     public boolean implies(Permission permission)
    109     {
    110         return false;
    111     }
    112 
    113     /**
    114      * Returns an enumeration of all the UnresolvedPermission lists in the
    115      * container.
    116      *
    117      * @return an enumeration of all the UnresolvedPermission objects.
    118      */
    119 
    120     public Enumeration<Permission> elements() {
    121         List<Permission> results =
    122             new ArrayList<>(); // where results are stored
    123 
    124         // Get iterator of Map values (which are lists of permissions)
    125         synchronized (this) {
    126             for (List<UnresolvedPermission> l : perms.values()) {
    127                 synchronized (l) {
    128                     results.addAll(l);
    129                 }
    130             }
    131         }
    132 
    133         return Collections.enumeration(results);
    134     }
    135 
    136     private static final long serialVersionUID = -7176153071733132400L;
    137 
    138     // Need to maintain serialization interoperability with earlier releases,
    139     // which had the serializable field:
    140     // private Hashtable permissions; // keyed on type
    141 
    142     /**
    143      * @serialField permissions java.util.Hashtable
    144      *     A table of the UnresolvedPermissions keyed on type, value is Vector
    145      *     of permissions
    146      */
    147     private static final ObjectStreamField[] serialPersistentFields = {
    148         new ObjectStreamField("permissions", Hashtable.class),
    149     };
    150 
    151     /**
    152      * @serialData Default field.
    153      */
    154     /*
    155      * Writes the contents of the perms field out as a Hashtable
    156      * in which the values are Vectors for
    157      * serialization compatibility with earlier releases.
    158      */
    159     private void writeObject(ObjectOutputStream out) throws IOException {
    160         // Don't call out.defaultWriteObject()
    161 
    162         // Copy perms into a Hashtable
    163         Hashtable<String, Vector<UnresolvedPermission>> permissions =
    164             new Hashtable<>(perms.size()*2);
    165 
    166         // Convert each entry (List) into a Vector
    167         synchronized (this) {
    168             Set<Map.Entry<String, List<UnresolvedPermission>>> set = perms.entrySet();
    169             for (Map.Entry<String, List<UnresolvedPermission>> e : set) {
    170                 // Convert list into Vector
    171                 List<UnresolvedPermission> list = e.getValue();
    172                 Vector<UnresolvedPermission> vec = new Vector<>(list.size());
    173                 synchronized (list) {
    174                     vec.addAll(list);
    175                 }
    176 
    177                 // Add to Hashtable being serialized
    178                 permissions.put(e.getKey(), vec);
    179             }
    180         }
    181 
    182         // Write out serializable fields
    183         ObjectOutputStream.PutField pfields = out.putFields();
    184         pfields.put("permissions", permissions);
    185         out.writeFields();
    186     }
    187 
    188     /*
    189      * Reads in a Hashtable in which the values are Vectors of
    190      * UnresolvedPermissions and saves them in the perms field.
    191      */
    192     private void readObject(ObjectInputStream in) throws IOException,
    193     ClassNotFoundException {
    194         // Don't call defaultReadObject()
    195 
    196         // Read in serialized fields
    197         ObjectInputStream.GetField gfields = in.readFields();
    198 
    199         // Get permissions
    200         @SuppressWarnings("unchecked")
    201         // writeObject writes a Hashtable<String, Vector<UnresolvedPermission>>
    202         // for the permissions key, so this cast is safe, unless the data is corrupt.
    203         Hashtable<String, Vector<UnresolvedPermission>> permissions =
    204                 (Hashtable<String, Vector<UnresolvedPermission>>)
    205                 gfields.get("permissions", null);
    206         perms = new HashMap<String, List<UnresolvedPermission>>(permissions.size()*2);
    207 
    208         // Convert each entry (Vector) into a List
    209         Set<Map.Entry<String, Vector<UnresolvedPermission>>> set = permissions.entrySet();
    210         for (Map.Entry<String, Vector<UnresolvedPermission>> e : set) {
    211             // Convert Vector into ArrayList
    212             Vector<UnresolvedPermission> vec = e.getValue();
    213             List<UnresolvedPermission> list = new ArrayList<>(vec.size());
    214             list.addAll(vec);
    215 
    216             // Add to Hashtable being serialized
    217             perms.put(e.getKey(), list);
    218         }
    219     }
    220 }
    221