Frames | No Frames |
1: /* Permissions.java -- a collection of permission collections 2: Copyright (C) 1998, 2001, 2002, 2004, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.security; 40: 41: import java.io.Serializable; 42: import java.util.Enumeration; 43: import java.util.Hashtable; 44: import java.util.NoSuchElementException; 45: 46: /** 47: * This class is a heterogeneous collection of permissions. It is 48: * organized as a collection of <code>PermissionCollection</code>'s stored 49: * in a hashtable. Each individual <code>PermissionCollection</code> 50: * contains permissions of a single type. If a specific type of 51: * <code>Permission</code> does not provide a collection type to use 52: * via its <code>newPermissionCollection</code> method, then a default 53: * collection type which stores its permissions in a hash table will be 54: * used. 55: * 56: * @author Aaron M. Renn (arenn@urbanophile.com) 57: * @author Eric Blake (ebb9@email.byu.edu) 58: * @since 1.1 59: */ 60: public final class Permissions extends PermissionCollection 61: implements Serializable 62: { 63: /** 64: * Compatible with JDK 1.1+. 65: */ 66: private static final long serialVersionUID = 4858622370623524688L; 67: 68: /** 69: * Holds instances of <code>AllPermission</code>. 70: * 71: * @serial the permission collection for AllPermission 72: */ 73: private PermissionCollection allPermission; 74: 75: // Package-private to avoid a trampoline. 76: /** 77: * This is the <code>Hashtable</code> that contains our collections. 78: * 79: * @serial maps Class to PermissionCollection 80: */ 81: final Hashtable perms = new Hashtable(); 82: 83: /** 84: * This method initializes a new instance of <code>Permissions</code>. 85: */ 86: public Permissions() 87: { 88: } 89: 90: /** 91: * This method adds a new <code>Permission</code> to this collection. It 92: * will be stored in a <code>PermissionCollection</code> of the appropriate 93: * type, as determined by calling <code>newPermissionCollection</code> on 94: * the specified permission (if an appropriate collection does not already 95: * exist). If this object does not specify a particular type of collection, 96: * a default collection, which stores in permissions in a hash table, will 97: * be used. 98: * 99: * @param perm the <code>Permission</code> to add 100: * @throws SecurityException if this collection is marked as read only 101: */ 102: public void add(Permission perm) 103: { 104: if (isReadOnly()) 105: throw new SecurityException("PermissionCollection is read only"); 106: if (perm instanceof AllPermission) 107: { 108: if (allPermission == null) 109: { 110: allPermission = perm.newPermissionCollection(); 111: allPermission.add(perm); 112: perms.put(perm.getClass(), allPermission); 113: } 114: } 115: else 116: { 117: PermissionCollection pc 118: = (PermissionCollection) perms.get(perm.getClass()); 119: if (pc == null) 120: { 121: pc = perm.newPermissionCollection(); 122: if (pc == null) 123: pc = new PermissionsHash(); 124: perms.put(perm.getClass(), pc); 125: } 126: pc.add(perm); 127: } 128: } 129: 130: /** 131: * This method tests whether or not the specified <code>Permission</code> 132: * is implied by this <code>PermissionCollection</code>. 133: * 134: * @param perm the <code>Permission</code> to test 135: * @return true if the specified permission is implied by this 136: */ 137: public boolean implies(Permission perm) 138: { 139: if (allPermission != null) 140: return true; 141: PermissionCollection pc 142: = (PermissionCollection) perms.get(perm.getClass()); 143: return pc == null ? false : pc.implies(perm); 144: } 145: 146: /** 147: * This method returns an <code>Enumeration</code> which contains a 148: * list of all <code>Permission</code> objects contained in this 149: * collection. 150: * 151: * @return an <code>Enumeration</code> of this collection's elements 152: */ 153: public Enumeration<Permission> elements() 154: { 155: return new Enumeration() 156: { 157: Enumeration main_enum = perms.elements(); 158: Enumeration sub_enum; 159: 160: public boolean hasMoreElements() 161: { 162: if (sub_enum == null) 163: { 164: if (main_enum == null) 165: return false; 166: if (! main_enum.hasMoreElements()) 167: { 168: main_enum = null; 169: return false; 170: } 171: PermissionCollection pc = 172: (PermissionCollection) main_enum.nextElement(); 173: sub_enum = pc.elements(); 174: } 175: if (! sub_enum.hasMoreElements()) 176: { 177: sub_enum = null; 178: return hasMoreElements(); 179: } 180: return true; 181: } 182: 183: public Object nextElement() 184: { 185: if (! hasMoreElements()) 186: throw new NoSuchElementException(); 187: return sub_enum.nextElement(); 188: } 189: }; 190: } 191: 192: /** 193: * Implements the permission collection for all permissions without one of 194: * their own, and obeys serialization of JDK. 195: * 196: * @author Eric Blake (ebb9@email.byu.edu) 197: */ 198: private static final class PermissionsHash extends PermissionCollection 199: { 200: /** 201: * Compatible with JDK 1.1+. 202: */ 203: private static final long serialVersionUID = -8491988220802933440L; 204: 205: /** 206: * Hashtable where we store permissions. 207: * 208: * @serial the stored permissions, both as key and value 209: */ 210: private final Hashtable perms = new Hashtable(); 211: 212: /** 213: * Add a permission. We don't need to check for read-only, as this 214: * collection is never exposed outside of Permissions, which has already 215: * done that check. 216: * 217: * @param perm the permission to add 218: */ 219: public void add(Permission perm) 220: { 221: perms.put(perm, perm); 222: } 223: 224: /** 225: * Returns true if perm is in the collection. 226: * 227: * @param perm the permission to check 228: * @return true if it is implied 229: */ 230: // FIXME: Should this method be synchronized? 231: public boolean implies(Permission perm) 232: { 233: Enumeration elements = elements(); 234: 235: while (elements.hasMoreElements()) 236: { 237: Permission p = (Permission)elements.nextElement(); 238: if (p.implies(perm)) 239: return true; 240: } 241: return false; 242: } 243: 244: /** 245: * Return the elements. 246: * 247: * @return the elements 248: */ 249: public Enumeration elements() 250: { 251: return perms.elements(); 252: } 253: } // class PermissionsHash 254: } // class Permissions