GNU Classpath (0.95) | |
Frames | No Frames |
1: /* MBeanServerPermission.java -- Permissions controlling server creation. 2: Copyright (C) 2006 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: package javax.management; 39: 40: import java.security.BasicPermission; 41: import java.security.Permission; 42: import java.security.PermissionCollection; 43: 44: import java.util.Enumeration; 45: import java.util.NoSuchElementException; 46: 47: /** 48: * <p> 49: * Represents the permissions required to perform 50: * operations provided by the {@link MBeanServerFactory}. 51: * As with all {@link java.security.Permission} objects, an 52: * instance of this class either represents a permission 53: * already held or one that is required to access a 54: * particular service. In the case of {@link MBeanServerPermission}s, 55: * implication checks are made using an instance of this class 56: * when a user requests an operation from the factory, and a 57: * {@link SecurityManager} is in place. 58: * </p> 59: * <p> 60: * The permission is defined by its name, which may be 61: * either a <code>'*'</code> (to allow all) or one or 62: * more of the following, separated by a <code>','</code>: 63: * </p> 64: * <ul> 65: * <li><code>createMBeanServer</code> -- allows a registered 66: * instance of a server to be obtained from the factory.</li> 67: * <li><code>findMBeanServer</code> -- allows all or one 68: * particular server instance to be retrieved from the factory.</li> 69: * <li><code>newMBeanServer</code> -- allows an unregistered 70: * instance of a server to be obtained from the factory.</li> 71: * <li><code>releaseMBeanServer</code> -- allows a reference to 72: * a server instance to be removed from the factory.</li> 73: * </ul> 74: * <p> 75: * The names may be surrounded by arbitrary amounts of whitespace. 76: * <code>createMBeanServer</code> implies <code>newMBeanServer</code>. 77: * </p> 78: * 79: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 80: * @since 1.5 81: */ 82: public class MBeanServerPermission 83: extends BasicPermission 84: { 85: 86: /** 87: * Compatible with JDK 1.5 88: */ 89: private static final long serialVersionUID = -5661980843569388590L; 90: 91: /** 92: * <p> 93: * Constructs a new {@link MBeanServerPermission} with 94: * the given name. The name must not be <code>null</code> 95: * and must be equal to either <code>"*"</code> or a 96: * comma-separated list of valid permissions. The four 97: * valid constraints are: 98: * </p> 99: * <ol> 100: * <li><code>createMBeanServer</code></li> 101: * <li><code>findMBeanServer</code></li> 102: * <li><code>newMBeanServer</code></li> 103: * <li><code>releaseMBeanServer</code></li> 104: * </ol> 105: * <p> 106: * Calling this constructor is equivalent to calling 107: * <code>MBeanPermission(name, null)</code>. 108: * </p> 109: * 110: * @param name the name of this permission. 111: * @throws NullPointerException if <code>name</code> 112: * is <code>null</code>. 113: * @throws IllegalArgumentException if <code>name</code> 114: * is not either equal to 115: * <code>"*"</code> or forms 116: * a comma-separated list of 117: * valid constraints. 118: * @see #MBeanServerPermission(String,String) 119: */ 120: public MBeanServerPermission(String name) 121: { 122: this(name, null); 123: } 124: 125: /** 126: * <p> 127: * Constructs a new {@link MBeanServerPermission} with 128: * the given name and actions. The actions are unused, 129: * and must be either <code>null</code> or the empty 130: * string. The name must not be <code>null</code> 131: * and must be equal to either <code>"*"</code> or a 132: * comma-separated list of valid permissions. The four 133: * valid constraints are: 134: * </p> 135: * <ol> 136: * <li><code>createMBeanServer</code></li> 137: * <li><code>findMBeanServer</code></li> 138: * <li><code>newMBeanServer</code></li> 139: * <li><code>releaseMBeanServer</code></li> 140: * </ol> 141: * <p> 142: * Calling this constructor is equivalent to calling 143: * <code>MBeanPermission(name, null)</code>. 144: * </p> 145: * 146: * @param name the name of this permission. 147: * @throws NullPointerException if <code>name</code> 148: * is <code>null</code>. 149: * @throws IllegalArgumentException if <code>name</code> 150: * is not either equal to 151: * <code>"*"</code> or forms 152: * a comma-separated list of 153: * valid constraints, or if 154: * <code>actions</code> is not 155: * <code>null</code> or the 156: * empty string. 157: * @see #MBeanServerPermission(String,String) 158: */ 159: public MBeanServerPermission(String name, String actions) 160: { 161: super(checkName(name), actions); 162: if (actions != null && actions.length() > 0) 163: throw new IllegalArgumentException("The supplied action list " + 164: "was not equal to null or the " + 165: "empty string."); 166: } 167: 168: /** 169: * Returns true if the given object is also an {@link MBeanServerPermission} 170: * with the same name. 171: * 172: * @param obj the object to compare with this one. 173: * @return true if the object is an {@link MBeanPermission} 174: * with the same name. 175: */ 176: public boolean equals(Object obj) 177: { 178: if (obj instanceof MBeanServerPermission) 179: { 180: MBeanServerPermission o = (MBeanServerPermission) obj; 181: return o.getName().equals(getName()); 182: } 183: return false; 184: } 185: 186: /** 187: * Returns a unique hash code for this permission. 188: * This is simply the hashcode of {@link BasicPermission#getName()}. 189: * 190: * @return the hashcode of this permission. 191: */ 192: public int hashCode() 193: { 194: return getName().hashCode(); 195: } 196: 197: /** 198: * Returns true if this {@link MBeanServerPermission} implies 199: * the given permission. This occurs if the given permission 200: * is also an {@link MBeanServerPermission} and its target names 201: * are a subset of the target names of this permission. Note that 202: * the name <code>createMBeanServer</code> implies 203: * <code>newMBeanServer</code>. 204: * 205: * @param p the permission to check for implication. 206: * @return true if this permission implies <code>p</code>. 207: */ 208: public boolean implies(Permission p) 209: { 210: if (p instanceof MBeanServerPermission) 211: { 212: if (getName().equals("*")) 213: return true; 214: MBeanServerPermission msp = (MBeanServerPermission) p; 215: String[] thisCaps = getName().split(","); 216: String[] mspCaps = msp.getName().split(","); 217: for (int a = 0; a < mspCaps.length; ++a) 218: { 219: boolean found = false; 220: String mc = mspCaps[a].trim(); 221: for (int b = 0; b < thisCaps.length; ++b) 222: { 223: String tc = thisCaps[b].trim(); 224: if (tc.equals(mc)) 225: found = true; 226: if (tc.equals("createMBeanServer") && 227: mc.equals("newMBeanServer")) 228: found = true; 229: } 230: if (!found) 231: return false; 232: } 233: return true; 234: } 235: return false; 236: } 237: 238: /** 239: * Returns a {@link PermissionCollection} which stores 240: * a series of {@link MBeanServerPermission}s as the union 241: * of their capabilities. 242: * 243: * @return a collection for {@link MBeanServerPermission}s. 244: */ 245: public PermissionCollection newPermissionCollection() 246: { 247: return new MBeanServerPermissionCollection(); 248: } 249: 250: /** 251: * A collection of {@link MBeanServerPermission}s, stored 252: * as a single permission with the union of the capabilities 253: * as its capabilities. 254: * 255: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 256: * @since 1.5 257: */ 258: private class MBeanServerPermissionCollection 259: extends PermissionCollection 260: { 261: 262: /** 263: * Compatible with JDK 1.5 264: */ 265: private static final long serialVersionUID = -5661980843569388590L; 266: 267: /** 268: * The collected permission. This is <code>null</code> or 269: * the union of the permissions held by all the collected 270: * permissions. 271: */ 272: private MBeanServerPermission collectionPermission; 273: 274: /** 275: * Adds a new permission by unifying it with the existing 276: * collection permission. 277: * 278: * @param p the permission to add. 279: * @throws SecurityException if the collection is read only. 280: * @see #isReadOnly() 281: * @see #setReadOnly(boolean) 282: */ 283: public void add(Permission p) 284: { 285: if (isReadOnly()) 286: throw new SecurityException("This collection is read only."); 287: if (p instanceof MBeanServerPermission) 288: { 289: MBeanServerPermission msp = (MBeanServerPermission) p; 290: if (collectionPermission == null) 291: collectionPermission = msp; 292: else 293: { 294: String finalString = collectionPermission.getName(); 295: String[] cp = finalString.split(","); 296: String[] np = msp.getName().split(","); 297: int createms = finalString.indexOf("createMBeanServer"); 298: int newms = finalString.indexOf("newMBeanServer"); 299: for (int a = 0; a < np.length; ++a) 300: { 301: boolean found = false; 302: String nps = np[a].trim(); 303: for (int b = 0; b < cp.length; ++b) 304: { 305: String cps = cp[b].trim(); 306: if (cps.equals(nps)) 307: found = true; 308: if (np.equals("newMBeanServer") 309: && createms != -1) 310: found = true; 311: if (np.equals("createMBeanServer") 312: && newms != -1) 313: finalString.replace("newMBeanServer", 314: "createMBeanServer"); 315: } 316: if (!found) 317: finalString += "," + nps; 318: } 319: collectionPermission = 320: new MBeanServerPermission(finalString); 321: } 322: } 323: } 324: 325: /** 326: * Returns an enumeration over the single permission. 327: * 328: * @return an enumeration over the collection permission. 329: */ 330: public Enumeration elements() 331: { 332: return new 333: MBeanServerPermissionEnumeration(collectionPermission); 334: } 335: 336: /** 337: * Provides an enumeration over a comma-separated list 338: * of capabilities. 339: * 340: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 341: * @since 1.5 342: */ 343: private class MBeanServerPermissionEnumeration 344: implements Enumeration 345: { 346: 347: /** 348: * The collected permission. 349: */ 350: private MBeanServerPermission p; 351: 352: /** 353: * True if we have returned the permission. 354: */ 355: private boolean done; 356: 357: /** 358: * Constructs a new {@link MBeanServerPermissionEnumeration} 359: * using the given collected permission. 360: * 361: * @param p the collected permission. 362: */ 363: public MBeanServerPermissionEnumeration(MBeanServerPermission p) 364: { 365: this.p = p; 366: done = false; 367: } 368: 369: /** 370: * Returns true if there are more capabilities to return. 371: * 372: * @return true if there are more capabilities available. 373: */ 374: public boolean hasMoreElements() 375: { 376: return !done; 377: } 378: 379: /** 380: * Returns the next capability. 381: * 382: * @return the next capability. 383: */ 384: public Object nextElement() 385: { 386: if (hasMoreElements()) 387: { 388: done = true; 389: return p; 390: } 391: else 392: throw new NoSuchElementException("No more elements are available."); 393: } 394: 395: } 396: 397: /** 398: * Returns true if the collected {@link MBeanServerPermission} 399: * implies the given permission. This occurs if the given permission 400: * is also an {@link MBeanServerPermission} and its target names 401: * are a subset of the target names of this permission. Note that 402: * the name <code>createMBeanServer</code> implies 403: * <code>newMBeanServer</code>. 404: * 405: * @param p the permission to check for implication. 406: * @return true if this permission implies <code>p</code>. 407: */ 408: public boolean implies(Permission p) 409: { 410: return collectionPermission.implies(p); 411: } 412: } 413: 414: /** 415: * Checks the name is valid, including removing 416: * the <code>newMBeanServer</code> permission when 417: * <code>createMBeanServer</code> is present. 418: * 419: * @param name the name to check. 420: * @throws NullPointerException if <code>name</code> 421: * is <code>null</code>. 422: * @throws IllegalArgumentException if <code>name</code> 423: * is not either equal to 424: * <code>"*"</code> or forms 425: * a comma-separated list of 426: * valid constraints. 427: */ 428: private static String checkName(String name) 429: { 430: if (!(name.equals("*"))) 431: { 432: String[] constraints = name.split(","); 433: name = ""; 434: boolean seenCreate = false; 435: boolean seenNew = false; 436: boolean start = true; 437: for (int a = 0; a < constraints.length; ++a) 438: { 439: String next = constraints[a].trim(); 440: if (!(next.equals("createMBeanServer") || 441: next.equals("findMBeanServer") || 442: next.equals("newMBeanServer") || 443: next.equals("releaseMBeanServer"))) 444: throw new IllegalArgumentException("An invalid constraint, " + 445: next + ", was specified."); 446: if (next.equals("newMBeanServer")) 447: seenNew = true; 448: else if (next.equals("createMBeanServer")) 449: seenCreate = true; 450: else 451: { 452: if (!start) 453: name += ","; 454: name += next; 455: start = false; 456: } 457: } 458: if (seenNew && !seenCreate) 459: name += (start ? "" : ",") + "newMBeanServer"; 460: else if (seenCreate) 461: name += (start ? "" : ",") + "createMBeanServer"; 462: } 463: return name; 464: } 465: 466: } 467: 468: 469:
GNU Classpath (0.95) |