001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.security.impl.jacc;
023:
024: import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
025:
026: import java.security.Permission;
027: import java.security.PermissionCollection;
028: import java.util.Map;
029:
030: /** @author <a href="mailto:sshah@redhat.com">Sohil Shah</a> */
031: public final class Permissions {
032: /**
033: * Key is permissions Class, value is PermissionCollection for that class. Not serialized; see serialization section
034: * at end of class.
035: */
036: private transient Map permsMap = null;
037:
038: /** Creates a new Permissions object containing no PermissionCollections. */
039: public Permissions() {
040: this .permsMap = new ConcurrentHashMap();
041: }
042:
043: /**
044: * Adds a permission object to the PermissionCollection for the class the permission belongs to. For example, if
045: * <i>permission</i> is a FilePermission, it is added to the FilePermissionCollection stored in this Permissions
046: * object.
047: * <p/>
048: * This method creates a new PermissionCollection object (and adds the permission to it) if an appropriate collection
049: * does not yet exist.
050: * <p/>
051: *
052: * @param permission the Permission object to add.
053: * @throws SecurityException if this Permissions object is marked as readonly.
054: * @see PermissionCollection#isReadOnly()
055: */
056: public void add(Permission permission) {
057: PermissionCollection pc;
058: pc = getPermissionCollection(permission, true);
059: pc.add(permission);
060: }
061:
062: /**
063: * Checks to see if this object's PermissionCollection for permissions of the specified permission's type implies the
064: * permissions expressed in the <i>permission</i> object. Returns true if the combination of permissions in the
065: * appropriate PermissionCollection (e.g., a FilePermissionCollection for a FilePermission) together imply the
066: * specified permission.
067: * <p/>
068: * <p/>
069: * For example, suppose there is a FilePermissionCollection in this Permissions object, and it contains one
070: * FilePermission that specifies "read" access for all files in all subdirectories of the "/tmp" directory, and
071: * another FilePermission that specifies "write" access for all files in the "/tmp/scratch/foo" directory. Then if
072: * the <code>implies</code> method is called with a permission specifying both "read" and "write" access to files in
073: * the "/tmp/scratch/foo" directory, <code>true</code> is returned.
074: * <p/>
075: * <p/>
076: * Additionally, if this PermissionCollection contains the AllPermission, this method will always return true.
077: * <p/>
078: *
079: * @param permission the Permission object to check.
080: * @return true if "permission" is implied by the permissions in the PermissionCollection it belongs to, false if
081: * not.
082: */
083: public boolean implies(Permission permission) {
084: PermissionCollection pc = getPermissionCollection(permission,
085: false);
086: if (pc != null) {
087: return pc.implies(permission);
088: } else {
089: // none found
090: return false;
091: }
092: }
093:
094: /**
095: * Gets the PermissionCollection in this Permissions object for permissions whose type is the same as that of
096: * <i>p</i>. For example, if <i>p</i> is a FilePermission, the FilePermissionCollection stored in this Permissions
097: * object will be returned.
098: * <p/>
099: * If createEmpty is true, this method creates a new PermissionCollection object for the specified type of permission
100: * objects if one does not yet exist. To do so, it first calls the <code>newPermissionCollection</code> method on
101: * <i>p</i>. Subclasses of class Permission override that method if they need to store their permissions in a
102: * particular PermissionCollection object in order to provide the correct semantics when the
103: * <code>PermissionCollection.implies</code> method is called. If the call returns a PermissionCollection, that
104: * collection is stored in this Permissions object. If the call returns null and createEmpty is true, then this
105: * method instantiates and stores a default PermissionCollection that uses a hashtable to store its permission
106: * objects.
107: * <p/>
108: * createEmpty is ignored when creating empty PermissionCollection for unresolved permissions because of the overhead
109: * of determining the PermissionCollection to use.
110: * <p/>
111: * createEmpty should be set to false when this method is invoked from implies() because it incurs the additional
112: * overhead of creating and adding an empty PermissionCollection that will just return false. It should be set to
113: * true when invoked from add().
114: */
115: private PermissionCollection getPermissionCollection(Permission p,
116: boolean createEmpty) {
117: Class c = p.getClass();
118:
119: PermissionCollection pc = (PermissionCollection) permsMap
120: .get(c);
121: if (!createEmpty) {
122: return pc;
123: } else if (pc == null) {
124: pc = p.newPermissionCollection();
125: if (pc != null) {
126: permsMap.put(c, pc);
127: }
128: }
129: return pc;
130: }
131: }
|