9 changed files with 325 additions and 178 deletions
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
package org.springframework.security.acls.domain; |
||||
|
||||
import org.springframework.security.acls.AclFormattingUtils; |
||||
import org.springframework.security.acls.Permission; |
||||
|
||||
/** |
||||
* Provides an abstract superclass for {@link Permission} implementations. |
||||
* |
||||
* @author Ben Alex |
||||
* @since 2.0.3 |
||||
* @see AbstractRegisteredPermission |
||||
* |
||||
*/ |
||||
public abstract class AbstractPermission implements Permission { |
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected char code; |
||||
protected int mask; |
||||
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
protected AbstractPermission(int mask, char code) { |
||||
this.mask = mask; |
||||
this.code = code; |
||||
} |
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public final boolean equals(Object arg0) { |
||||
if (arg0 == null) { |
||||
return false; |
||||
} |
||||
|
||||
if (!(arg0 instanceof Permission)) { |
||||
return false; |
||||
} |
||||
|
||||
Permission rhs = (Permission) arg0; |
||||
|
||||
return (this.mask == rhs.getMask()); |
||||
} |
||||
|
||||
public final int getMask() { |
||||
return mask; |
||||
} |
||||
|
||||
public String getPattern() { |
||||
return AclFormattingUtils.printBinary(mask, code); |
||||
} |
||||
|
||||
public final String toString() { |
||||
return this.getClass().getSimpleName() + "[" + getPattern() + "=" + mask + "]"; |
||||
} |
||||
|
||||
public final int hashCode() { |
||||
return this.mask; |
||||
} |
||||
} |
||||
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
package org.springframework.security.acls.domain; |
||||
|
||||
import org.springframework.security.acls.Permission; |
||||
|
||||
/** |
||||
* Provides an abstract base for standard {@link Permission} instances that wish to offer static convenience |
||||
* methods to callers via delegation to {@link DefaultPermissionFactory}. |
||||
* |
||||
* @author Ben Alex |
||||
* @since 2.0.3 |
||||
* |
||||
*/ |
||||
public abstract class AbstractRegisteredPermission extends AbstractPermission { |
||||
protected static DefaultPermissionFactory defaultPermissionFactory = new DefaultPermissionFactory(); |
||||
|
||||
protected AbstractRegisteredPermission(int mask, char code) { |
||||
super(mask, code); |
||||
} |
||||
|
||||
protected final static void registerPermissionsFor(Class subClass) { |
||||
defaultPermissionFactory.registerPublicPermissions(subClass); |
||||
} |
||||
|
||||
public final static Permission buildFromMask(int mask) { |
||||
return defaultPermissionFactory.buildFromMask(mask); |
||||
} |
||||
|
||||
public final static Permission[] buildFromMask(int[] masks) { |
||||
return defaultPermissionFactory.buildFromMask(masks); |
||||
} |
||||
|
||||
public final static Permission buildFromName(String name) { |
||||
return defaultPermissionFactory.buildFromName(name); |
||||
} |
||||
|
||||
public final static Permission[] buildFromName(String[] names) { |
||||
return defaultPermissionFactory.buildFromName(names); |
||||
} |
||||
} |
||||
@ -0,0 +1,127 @@
@@ -0,0 +1,127 @@
|
||||
package org.springframework.security.acls.domain; |
||||
|
||||
import java.lang.reflect.Field; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.security.acls.Permission; |
||||
import org.springframework.security.acls.jdbc.LookupStrategy; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* Default implementation of {@link PermissionFactory}. |
||||
* |
||||
* <p> |
||||
* Generally this class will be used by a {@link Permission} instance, as opposed to being dependency |
||||
* injected into a {@link LookupStrategy} or similar. Nevertheless, the latter mode of operation is |
||||
* fully supported (in which case your {@link Permission} implementations probably should extend |
||||
* {@link AbstractPermission} instead of {@link AbstractRegisteredPermission}). |
||||
* </p> |
||||
* |
||||
* @author Ben Alex |
||||
* @since 2.0.3 |
||||
* |
||||
*/ |
||||
public class DefaultPermissionFactory implements PermissionFactory { |
||||
private Map registeredPermissionsByInteger = new HashMap(); |
||||
private Map registeredPermissionsByName = new HashMap(); |
||||
|
||||
/** |
||||
* Permit registration of a {@link DefaultPermissionFactory} class. The class must provide |
||||
* public static fields of type {@link Permission} to represent the possible permissions. |
||||
* |
||||
* @param clazz a {@link Permission} class with public static fields to register |
||||
*/ |
||||
public void registerPublicPermissions(Class clazz) { |
||||
Assert.notNull(clazz, "Class required"); |
||||
Assert.isAssignable(Permission.class, clazz); |
||||
|
||||
Field[] fields = clazz.getFields(); |
||||
|
||||
for (int i = 0; i < fields.length; i++) { |
||||
try { |
||||
Object fieldValue = fields[i].get(null); |
||||
|
||||
if (Permission.class.isAssignableFrom(fieldValue.getClass())) { |
||||
// Found a Permission static field
|
||||
Permission perm = (Permission) fieldValue; |
||||
String permissionName = fields[i].getName(); |
||||
|
||||
registerPermission(perm, permissionName); |
||||
} |
||||
} catch (Exception ignore) {} |
||||
} |
||||
} |
||||
|
||||
public void registerPermission(Permission perm, String permissionName) { |
||||
Assert.notNull(perm, "Permission required"); |
||||
Assert.hasText(permissionName, "Permission name required"); |
||||
|
||||
Integer mask = new Integer(perm.getMask()); |
||||
|
||||
// Ensure no existing Permission uses this integer or code
|
||||
Assert.isTrue(!registeredPermissionsByInteger.containsKey(mask), "An existing Permission already provides mask " + mask); |
||||
Assert.isTrue(!registeredPermissionsByName.containsKey(permissionName), "An existing Permission already provides name '" + permissionName + "'"); |
||||
|
||||
// Register the new Permission
|
||||
registeredPermissionsByInteger.put(mask, perm); |
||||
registeredPermissionsByName.put(permissionName, perm); |
||||
} |
||||
|
||||
public Permission buildFromMask(int mask) { |
||||
if (registeredPermissionsByInteger.containsKey(new Integer(mask))) { |
||||
// The requested mask has an exactly match against a statically-defined Permission, so return it
|
||||
return (Permission) registeredPermissionsByInteger.get(new Integer(mask)); |
||||
} |
||||
|
||||
// To get this far, we have to use a CumulativePermission
|
||||
CumulativePermission permission = new CumulativePermission(); |
||||
|
||||
for (int i = 0; i < 32; i++) { |
||||
int permissionToCheck = 1 << i; |
||||
|
||||
if ((mask & permissionToCheck) == permissionToCheck) { |
||||
Permission p = (Permission) registeredPermissionsByInteger.get(new Integer(permissionToCheck)); |
||||
Assert.state(p != null, "Mask " + permissionToCheck + " does not have a corresponding static Permission"); |
||||
permission.set(p); |
||||
} |
||||
} |
||||
|
||||
return permission; |
||||
} |
||||
|
||||
public Permission[] buildFromMask(int[] masks) { |
||||
if ((masks == null) || (masks.length == 0)) { |
||||
return new Permission[0]; |
||||
} |
||||
|
||||
Permission[] permissions = new Permission[masks.length]; |
||||
|
||||
for (int i = 0; i < masks.length; i++) { |
||||
permissions[i] = buildFromMask(masks[i]); |
||||
} |
||||
|
||||
return permissions; |
||||
} |
||||
|
||||
public Permission buildFromName(String name) { |
||||
Assert.isTrue(registeredPermissionsByName.containsKey(name), "Unknown permission '" + name + "'"); |
||||
|
||||
return (Permission) registeredPermissionsByName.get(name); |
||||
} |
||||
|
||||
public Permission[] buildFromName(String[] names) { |
||||
if ((names == null) || (names.length == 0)) { |
||||
return new Permission[0]; |
||||
} |
||||
|
||||
Permission[] permissions = new Permission[names.length]; |
||||
|
||||
for (int i = 0; i < names.length; i++) { |
||||
permissions[i] = buildFromName(names[i]); |
||||
} |
||||
|
||||
return permissions; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
package org.springframework.security.acls.domain; |
||||
|
||||
import org.springframework.security.acls.Permission; |
||||
|
||||
/** |
||||
* Provides a simple mechanism to retrieve {@link Permission} instances from integer masks. |
||||
* |
||||
* @author Ben Alex |
||||
* @since 2.0.3 |
||||
* |
||||
*/ |
||||
public interface PermissionFactory { |
||||
|
||||
/** |
||||
* Dynamically creates a <code>CumulativePermission</code> or <code>BasePermission</code> representing the |
||||
* active bits in the passed mask. |
||||
* |
||||
* @param mask to build |
||||
* |
||||
* @return a Permission representing the requested object |
||||
*/ |
||||
public abstract Permission buildFromMask(int mask); |
||||
|
||||
} |
||||
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package org.springframework.security.acls.domain; |
||||
|
||||
import org.springframework.security.acls.Permission; |
||||
|
||||
|
||||
/** |
||||
* A test permission. |
||||
* |
||||
* @author Ben Alex |
||||
* @version $Id$ |
||||
*/ |
||||
public class SpecialPermission extends BasePermission { |
||||
public static final Permission ENTER = new SpecialPermission(1 << 5, 'E'); // 32
|
||||
|
||||
/** |
||||
* Registers the public static permissions defined on this class. This is mandatory so |
||||
* that the static methods will operate correctly. |
||||
*/ |
||||
static { |
||||
registerPermissionsFor(SpecialPermission.class); |
||||
} |
||||
|
||||
protected SpecialPermission(int mask, char code) { |
||||
super(mask, code); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue