001: /*
002: * Copyright (C) The MX4J Contributors.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the MX4J License version 1.0.
006: * See the terms of the MX4J License in the documentation provided with this software.
007: */
008:
009: package javax.management;
010:
011: import java.io.IOException;
012: import java.io.ObjectInputStream;
013: import java.security.BasicPermission;
014: import java.security.Permission;
015: import java.security.PermissionCollection;
016: import java.util.ArrayList;
017: import java.util.Collections;
018: import java.util.StringTokenizer;
019:
020: /**
021: * The permission that guards access to MBeanServerFactory methods.
022: * It has no actions, only target names can be provided.
023: * The wildcard "*" means all names, and "createMBeanServer" implies "newMBeanServer", and the names
024: * can be specified as a comma separated list.
025: * The list of target names is the following:
026: * <ul>
027: * <li>newMBeanServer</li>
028: * <li>createMBeanServer</li>
029: * <li>findMBeanServer</li>
030: * <li>releaseMBeanServer</li>
031: * </ul>
032: *
033: * @version $Revision: 1.14 $
034: */
035: public class MBeanServerPermission extends BasicPermission {
036: private static final long serialVersionUID = 0xb16c9a6bd5fae3d2L;
037:
038: private transient ArrayList targets;
039: private transient boolean wildcard;
040:
041: /**
042: * Creates a new MBeanServerPermission with the specified name and no actions
043: *
044: * @param name The comma separated list of target names
045: */
046: public MBeanServerPermission(String name) {
047: this (name, null);
048: }
049:
050: /**
051: * Creates a new MBeanServerPermission with the specified name and actions, but the actions will be ignored
052: *
053: * @param name The comma separated list of target names
054: * @param actions Ignored
055: */
056: public MBeanServerPermission(String name, String actions) {
057: super (name);
058: parseName(name);
059: if (actions != null && actions.length() != 0)
060: throw new IllegalArgumentException(
061: "Actions must be null or an empty string");
062: }
063:
064: /**
065: * Returns null, as this permission does not have actions
066: */
067: public String getActions() {
068: return null;
069: }
070:
071: public int hashCode() {
072: return targets.hashCode();
073: }
074:
075: public boolean equals(Object obj) {
076: if (obj == null)
077: return false;
078: if (obj == this )
079: return true;
080:
081: try {
082: MBeanServerPermission other = (MBeanServerPermission) obj;
083: // We don't check wildcard: if targets is empty, means we have a wildcard (see parseName)
084: return targets.equals(other.targets);
085: } catch (ClassCastException x) {
086: }
087: return false;
088: }
089:
090: public boolean implies(Permission p) {
091: if (p == null)
092: return false;
093: if (getClass() != p.getClass())
094: return false;
095:
096: MBeanServerPermission other = (MBeanServerPermission) p;
097: if (wildcard)
098: return true;
099: if (other.wildcard)
100: return false;
101:
102: if (targets.containsAll(other.targets))
103: return true;
104:
105: // We have to manage the case where this contains createMBeanServer and other contains newMBeanServer
106: if (other.targets.contains("newMBeanServer")
107: && targets.contains("createMBeanServer")) {
108: // Beware the case where we have MBeanServerPermission "createMBeanServer" and
109: // MBeanServerPermission "newMBeanServer, findMBeanServer": the first should not imply the second.
110: for (int i = 0; i < other.targets.size(); ++i) {
111: Object perm = other.targets.get(i);
112: if ("newMBeanServer".equals(perm))
113: continue;
114: if (!targets.contains(perm))
115: return false;
116: }
117: return true;
118: }
119:
120: return false;
121: }
122:
123: private void parseName(String name) {
124: if (name == null)
125: throw new IllegalArgumentException(
126: "Permission name cannot be null");
127: name = name.trim();
128: if (name.length() == 0)
129: throw new IllegalArgumentException(
130: "Permission name cannot be empty");
131:
132: targets = new ArrayList();
133: StringTokenizer tokenizer = new StringTokenizer(name, ",");
134: while (tokenizer.hasMoreTokens()) {
135: String target = tokenizer.nextToken().trim();
136: if (target.length() == 0)
137: continue;
138: if ("*".equals(target)) {
139: targets.clear();
140: wildcard = true;
141: return;
142: } else if ("newMBeanServer".equals(target)
143: || "createMBeanServer".equals(target)
144: || "findMBeanServer".equals(target)
145: || "releaseMBeanServer".equals(target)) {
146: targets.add(target);
147: } else {
148: throw new IllegalArgumentException(
149: "Invalid permission name: " + target);
150: }
151: }
152:
153: if (targets.size() < 1)
154: throw new IllegalArgumentException(
155: "Permission name does not contain targets");
156:
157: // Important to provide same hashcode and equals to permission with names in different order
158: Collections.sort(targets);
159: }
160:
161: public PermissionCollection newPermissionCollection() {
162: return null;
163: }
164:
165: private void readObject(ObjectInputStream stream)
166: throws IOException, ClassNotFoundException {
167: stream.defaultReadObject();
168: parseName(getName());
169: }
170: }
|