GNU Classpath (0.95) | |
Frames | No Frames |
1: /* PropertyPermission.java -- permission to get and set System properties 2: Copyright (C) 1999, 2000, 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.util; 40: 41: import java.io.IOException; 42: import java.io.ObjectInputStream; 43: import java.io.ObjectOutputStream; 44: import java.io.ObjectStreamField; 45: import java.security.BasicPermission; 46: import java.security.Permission; 47: import java.security.PermissionCollection; 48: 49: /** 50: * This class represents the permission to access and modify a property.<br> 51: * 52: * The name is the name of the property, e.g. xxx. You can also 53: * use an asterisk "*" as described in BasicPermission.<br> 54: * 55: * The action string is a comma-separated list of keywords. There are 56: * two possible actions: 57: * <dl> 58: * <dt>read</dt> 59: * <dd>Allows to read the property via <code>System.getProperty</code>.</dd> 60: * <dt>write</dt> 61: * <dd>Allows to write the property via <code>System.setProperty</code>.</dd> 62: * </dl> 63: * 64: * The action string is case insensitive (it is converted to lower case). 65: * 66: * @see Permission 67: * @see BasicPermission 68: * @see SecurityManager 69: * @author Jochen Hoenicke 70: * @since 1.2 71: * @status updated to 1.4 72: */ 73: public final class PropertyPermission extends BasicPermission 74: { 75: /** 76: * PropertyPermission uses a more efficient representation than the 77: * serialized form; this documents the difference. 78: * 79: * @serialField action String the action string 80: */ 81: private static final ObjectStreamField[] serialPersistentFields = 82: { 83: new ObjectStreamField("action", String.class) 84: }; 85: 86: /** 87: * Compatible with JDK 1.2+. 88: */ 89: private static final long serialVersionUID = 885438825399942851L; 90: 91: /** Permission to read. */ 92: private static final int READ = 1; 93: /** Permission to write. */ 94: private static final int WRITE = 2; 95: 96: /** The set of actions permitted. */ 97: // Package visible for use by PropertyPermissionCollection. 98: transient int actions; 99: 100: /** 101: * The String forms of the actions permitted. 102: */ 103: private static final String actionStrings[] = 104: { 105: "", "read", "write", "read,write" 106: }; 107: 108: /** 109: * Constructs a PropertyPermission with the specified property. Possible 110: * actions are read and write, comma-separated and case-insensitive. 111: * 112: * @param name the name of the property 113: * @param actions the action string 114: * @throws NullPointerException if name is null 115: * @throws IllegalArgumentException if name string contains an 116: * illegal wildcard or actions string contains an illegal action 117: * (this includes a null actions string) 118: */ 119: public PropertyPermission(String name, String actions) 120: { 121: super(name); 122: if (actions == null) 123: throw new IllegalArgumentException(); 124: setActions(actions); 125: } 126: 127: /** 128: * Parse the action string and convert actions from external to internal 129: * form. This will set the internal actions field. 130: * 131: * @param str the action string 132: * @throws IllegalArgumentException if actions string contains an 133: * illegal action 134: */ 135: private void setActions(String str) 136: { 137: // Initialising the class java.util.Locale ... 138: // tries to initialise the Locale.defaultLocale static 139: // which calls System.getProperty, 140: // which calls SecurityManager.checkPropertiesAccess, 141: // which creates a PropertyPermission with action "read,write", 142: // which calls setActions("read,write"). 143: // If we now were to call toLowerCase on 'str', 144: // this would call Locale.getDefault() which returns null 145: // because Locale.defaultLocale hasn't been set yet 146: // then toLowerCase will fail with a null pointer exception. 147: // 148: // The solution is to take a punt on 'str' being lower case, and 149: // test accordingly. If that fails, we convert 'str' to lower case 150: // and try the tests again. 151: if ("read".equals(str)) 152: actions = READ; 153: else if ("write".equals(str)) 154: actions = WRITE; 155: else if ("read,write".equals(str) || "write,read".equals(str)) 156: actions = READ | WRITE; 157: else 158: { 159: String lstr = str.toLowerCase(); 160: if ("read".equals(lstr)) 161: actions = READ; 162: else if ("write".equals(lstr)) 163: actions = WRITE; 164: else if ("read,write".equals(lstr) || "write,read".equals(lstr)) 165: actions = READ | WRITE; 166: else 167: throw new IllegalArgumentException("illegal action " + str); 168: } 169: } 170: 171: /** 172: * Reads an object from the stream. This converts the external to the 173: * internal representation. 174: * 175: * @param s the stream to read from 176: * @throws IOException if the stream fails 177: * @throws ClassNotFoundException if reserialization fails 178: */ 179: private void readObject(ObjectInputStream s) 180: throws IOException, ClassNotFoundException 181: { 182: ObjectInputStream.GetField fields = s.readFields(); 183: setActions((String) fields.get("actions", null)); 184: } 185: 186: /** 187: * Writes an object to the stream. This converts the internal to the 188: * external representation. 189: * 190: * @param s the stram to write to 191: * @throws IOException if the stream fails 192: */ 193: private void writeObject(ObjectOutputStream s) throws IOException 194: { 195: ObjectOutputStream.PutField fields = s.putFields(); 196: fields.put("actions", getActions()); 197: s.writeFields(); 198: } 199: 200: /** 201: * Check if this permission implies p. This returns true iff all of 202: * the following conditions are true: 203: * <ul> 204: * <li> p is a PropertyPermission </li> 205: * <li> this.getName() implies p.getName(), 206: * e.g. <code>java.*</code> implies <code>java.home</code> </li> 207: * <li> this.getActions is a subset of p.getActions </li> 208: * </ul> 209: * 210: * @param p the permission to check 211: * @return true if this permission implies p 212: */ 213: public boolean implies(Permission p) 214: { 215: // BasicPermission checks for name and type. 216: if (super.implies(p)) 217: { 218: // We have to check the actions. 219: PropertyPermission pp = (PropertyPermission) p; 220: return (pp.actions & ~actions) == 0; 221: } 222: return false; 223: } 224: 225: /** 226: * Check to see whether this object is the same as another 227: * PropertyPermission object; this is true if it has the same name and 228: * actions. 229: * 230: * @param obj the other object 231: * @return true if the two are equivalent 232: */ 233: public boolean equals(Object obj) 234: { 235: return super.equals(obj) && actions == ((PropertyPermission) obj).actions; 236: } 237: 238: /** 239: * Returns the hash code for this permission. It is equivalent to 240: * <code>getName().hashCode()</code>. 241: * 242: * @return the hash code 243: */ 244: public int hashCode() 245: { 246: return super.hashCode(); 247: } 248: 249: /** 250: * Returns the action string. Note that this may differ from the string 251: * given at the constructor: The actions are converted to lowercase and 252: * may be reordered. 253: * 254: * @return one of "read", "write", or "read,write" 255: */ 256: public String getActions() 257: { 258: return actionStrings[actions]; 259: } 260: 261: /** 262: * Returns a permission collection suitable to take 263: * PropertyPermission objects. 264: * 265: * @return a new empty PermissionCollection 266: */ 267: public PermissionCollection newPermissionCollection() 268: { 269: return new PropertyPermissionCollection(); 270: } 271: }
GNU Classpath (0.95) |