Frames | No Frames |
1: /* BasicPermission.java -- implements a simple named permission 2: Copyright (C) 1998, 1999, 2002, 2003, 2004, 2005, 2006 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: 40: package java.security; 41: 42: import java.io.Serializable; 43: import java.util.Enumeration; 44: import java.util.Hashtable; 45: 46: /** 47: * This class implements a simple model for named permissions without an 48: * associated action list. That is, either the named permission is granted 49: * or it is not. 50: * 51: * <p>It also supports trailing wildcards to allow the easy granting of 52: * permissions in a hierarchical fashion. (For example, the name "org.gnu.*" 53: * might grant all permissions under the "org.gnu" permissions hierarchy). 54: * The only valid wildcard character is a '*' which matches anything. It 55: * must be the rightmost element in the permission name and must follow a 56: * '.' or else the Permission name must consist of only a '*'. Any other 57: * occurrence of a '*' is not valid. 58: * 59: * <p>This class ignores the action list. Subclasses can choose to implement 60: * actions on top of this class if desired. 61: * 62: * @author Aaron M. Renn (arenn@urbanophile.com) 63: * @author Eric Blake (ebb9@email.byu.edu) 64: * @see Permission 65: * @see Permissions 66: * @see PermissionCollection 67: * @see RuntimePermission 68: * @see SecurityPermission 69: * @see PropertyPermission 70: * @see AWTPermission 71: * @see NetPermission 72: * @see SecurityManager 73: * @since 1.1 74: * @status updated to 1.4 75: */ 76: public abstract class BasicPermission extends java.security.Permission 77: implements Serializable 78: // FIXME extends with fully qualified classname as workaround for gcj 3.3. 79: { 80: /** 81: * Compatible with JDK 1.1+. 82: */ 83: private static final long serialVersionUID = 6279438298436773498L; 84: 85: /** 86: * Create a new instance with the specified permission name. If the 87: * name is empty an exception is thrown. 88: * 89: * @param name the name of this permission 90: * @throws NullPointerException if name is null 91: * @throws IllegalArgumentException if name is invalid 92: */ 93: public BasicPermission(String name) 94: { 95: super(name); 96: 97: // This routine used to check for illegal wildcards, but no such 98: // requirement exists in the specification and Sun's runtime 99: // doesn't appear to do it. 100: 101: if (name.equals("")) 102: throw new IllegalArgumentException("Empty name"); 103: } 104: 105: /** 106: * Create a new instance with the specified permission name. If the name 107: * is empty, or contains an illegal wildcard character, an exception is 108: * thrown. The actions parameter is ignored. 109: * 110: * @param name the name of this permission 111: * @param actions ignored 112: * @throws NullPointerException if name is null 113: * @throws IllegalArgumentException if name is invalid 114: */ 115: public BasicPermission(String name, String actions) 116: { 117: this(name); 118: } 119: 120: /** 121: * This method tests to see if the specified permission is implied by this 122: * permission. This will be true if the following conditions are met:<ul> 123: * <li>The specified object is an instance of the same class as this 124: * object.</li> 125: * <li>The name of the specified permission is implied by this permission's 126: * name based on wildcard matching. For example, "a.*" implies "a.b".</li> 127: * </ul> 128: * 129: * @param perm the <code>Permission</code> object to test against 130: * @return true if the specified permission is implied 131: */ 132: public boolean implies(Permission perm) 133: { 134: if (! getClass().isInstance(perm)) 135: return false; 136: 137: String otherName = perm.getName(); 138: String name = getName(); 139: 140: if (name.equals(otherName)) 141: return true; 142: 143: int last = name.length() - 1; 144: return name.charAt(last) == '*' 145: && otherName.startsWith(name.substring(0, last)); 146: } 147: 148: /** 149: * This method tests to see if this object is equal to the specified 150: * <code>Object</code>. This will be true if and only if the specified 151: * object meets the following conditions:<ul> 152: * <li>It is an instance of the same class as this.</li> 153: * <li>It has the same name as this permission.</li> 154: * </ul> 155: * 156: * @param obj the <code>Object</code> to test for equality 157: * @return true if obj is semantically equal to this 158: */ 159: public boolean equals(Object obj) 160: { 161: return getClass().isInstance(obj) 162: && getName().equals(((BasicPermission) obj).getName()); 163: } 164: 165: /** 166: * This method returns a hash code for this permission object. The hash 167: * code returned is the value returned by calling the <code>hashCode</code> 168: * method on the <code>String</code> that is the name of this permission. 169: * 170: * @return a hash value for this object 171: */ 172: public int hashCode() 173: { 174: return getName().hashCode(); 175: } 176: 177: /** 178: * This method returns a list of the actions associated with this 179: * permission. This method always returns the empty string ("") since 180: * this class ignores actions. 181: * 182: * @return the action list 183: */ 184: public String getActions() 185: { 186: return ""; 187: } 188: 189: /** 190: * This method returns an instance of <code>PermissionCollection</code> 191: * suitable for storing <code>BasicPermission</code> objects. The 192: * collection returned can only store objects of the same type as this. 193: * Subclasses which use actions must override this method; but a class with 194: * no actions will work fine with this. 195: * 196: * @return a new empty <code>PermissionCollection</code> object 197: */ 198: public PermissionCollection newPermissionCollection() 199: { 200: return new BasicPermissionCollection(getClass()); 201: } 202: 203: /** 204: * Implements AllPermission.newPermissionCollection, and obeys serialization 205: * of JDK. 206: * 207: * @author Eric Blake (ebb9@email.byu.edu) 208: */ 209: private static final class BasicPermissionCollection extends PermissionCollection 210: { 211: /** 212: * Compatible with JDK 1.1+. 213: */ 214: private static final long serialVersionUID = 739301742472979399L; 215: 216: /** 217: * The permissions in the collection. 218: * 219: * @serial a hash mapping name to permissions, all of type permClass 220: */ 221: private final Hashtable permissions = new Hashtable(); 222: 223: /** 224: * If "*" is in the collection. 225: * 226: * @serial true if a permission named "*" is in the collection 227: */ 228: private boolean all_allowed; 229: 230: /** 231: * The runtime class which all entries in the table must belong to. 232: * 233: * @serial the limiting subclass of this collection 234: */ 235: private final Class permClass; 236: 237: /** 238: * Construct a collection over the given runtime class. 239: * 240: * @param c the class 241: */ 242: BasicPermissionCollection(Class c) 243: { 244: permClass = c; 245: } 246: 247: /** 248: * Add a Permission. It must be of the same type as the permission which 249: * created this collection. 250: * 251: * @param perm the permission to add 252: * @throws IllegalArgumentException if perm is not the correct type 253: * @throws SecurityException if the collection is read-only 254: */ 255: public void add(Permission perm) 256: { 257: if (isReadOnly()) 258: throw new SecurityException("readonly"); 259: if (! permClass.isInstance(perm)) 260: throw new IllegalArgumentException("Expecting instance of " + permClass); 261: BasicPermission bp = (BasicPermission) perm; 262: String name = bp.getName(); 263: if (name.equals("*")) 264: all_allowed = true; 265: permissions.put(name, bp); 266: } 267: 268: /** 269: * Returns true if this collection implies the given permission. 270: * 271: * @param permission the permission to check 272: * @return true if it is implied by this 273: */ 274: public boolean implies(Permission permission) 275: { 276: if (! permClass.isInstance(permission)) 277: return false; 278: if (all_allowed) 279: return true; 280: BasicPermission toImply = (BasicPermission) permission; 281: String name = toImply.getName(); 282: if (name.equals("*")) 283: return false; 284: int prefixLength = name.length(); 285: if (name.endsWith("*")) 286: prefixLength -= 2; 287: 288: while (true) 289: { 290: if (permissions.get(name) != null) 291: return true; 292: prefixLength = name.lastIndexOf('.', prefixLength); 293: if (prefixLength < 0) 294: return false; 295: name = name.substring(0, prefixLength + 1) + '*'; 296: } 297: } 298: 299: /** 300: * Enumerate over the collection. 301: * 302: * @return an enumeration of the collection contents 303: */ 304: public Enumeration elements() 305: { 306: return permissions.elements(); 307: } 308: } // class BasicPermissionCollection 309: } // class BasicPermission