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