elements = collection.elements();
while (elements.hasMoreElements()) {
consumer.accept(elements.nextElement());
}
}
/**
* Perform an action for each permission in the given collection.
*
* @param collection the collection (must not be {@code null})
* @param parameter the parameter to pass to the consumer
* @param consumer the consumer to which each permission should be passed (must not be {@code null})
* @param the type of the parameter
* @return the {@code parameter} that was passed in
*/
public static
P forEachIn(PermissionCollection collection, BiConsumer
consumer, P parameter) {
Assert.checkNotNullParam("collection", collection);
Assert.checkNotNullParam("consumer", consumer);
final Enumeration elements = collection.elements();
while (elements.hasMoreElements()) {
consumer.accept(parameter, elements.nextElement());
}
return parameter;
}
/**
* Run a test for each permission in the given collection. If the predicate returns {@code false} for any element,
* {@code false} is returned; otherwise, {@code true} is returned.
*
* @param collection the collection (must not be {@code null})
* @param predicate the predicate to apply to each element (must not be {@code null})
* @return {@code true} if the predicate matched all the permissions in the collection, {@code false} otherwise
*/
public static boolean forEachIn(PermissionCollection collection, Predicate predicate) {
Assert.checkNotNullParam("collection", collection);
Assert.checkNotNullParam("predicate", predicate);
final Enumeration elements = collection.elements();
while (elements.hasMoreElements()) {
if (! predicate.test(elements.nextElement())) {
return false;
}
}
return true;
}
/**
* Run a test for each permission in the given collection. If the predicate returns {@code false} for any element,
* {@code false} is returned; otherwise, {@code true} is returned.
*
* @param collection the collection (must not be {@code null})
* @param parameter the parameter to pass to the consumer
* @param predicate the predicate to apply to each element (must not be {@code null})
* @param the type of the parameter
* @return {@code true} if the predicate matched all the permissions in the collection, {@code false} otherwise
*/
public static
boolean forEachIn(PermissionCollection collection, BiPredicate
predicate, P parameter) {
Assert.checkNotNullParam("collection", collection);
Assert.checkNotNullParam("predicate", predicate);
final Enumeration elements = collection.elements();
while (elements.hasMoreElements()) {
if (! predicate.test(parameter, elements.nextElement())) {
return false;
}
}
return true;
}
/**
* Create a permission collection that is the union of two permission collections. The permission
* collections must be read-only.
*
* @param pc1 the first permission collection (must not be {@code null})
* @param pc2 the second permission collection (must not be {@code null})
* @return a new permission collection that is the union of the two collections (not {@code null})
*/
public static PermissionCollection union(PermissionCollection pc1, PermissionCollection pc2) {
Assert.checkNotNullParam("pc1", pc1);
Assert.checkNotNullParam("pc2", pc2);
if (! pc1.isReadOnly() || ! pc2.isReadOnly()) {
throw ElytronMessages.log.permissionCollectionMustBeReadOnly();
}
if (pc1.implies(ALL_PERMISSION) || pc2.implies(ALL_PERMISSION)) {
return ALL_PERMISSIONS;
} else {
return new UnionPermissionCollection(pc1, pc2);
}
}
/**
* Create a permission collection that is the intersection of two permission collections. The permission
* collections must be read-only.
*
* @param pc1 the first permission collection (must not be {@code null})
* @param pc2 the second permission collection (must not be {@code null})
* @return a new permission collection that is the intersection of the two collections (not {@code null})
*/
public static PermissionCollection intersection(PermissionCollection pc1, PermissionCollection pc2) {
Assert.checkNotNullParam("pc1", pc1);
Assert.checkNotNullParam("pc2", pc2);
if (! pc1.isReadOnly() || ! pc2.isReadOnly()) {
throw ElytronMessages.log.permissionCollectionMustBeReadOnly();
}
if (pc1.implies(ALL_PERMISSION)) {
return pc2;
} else if (pc2.implies(ALL_PERMISSION)) {
return pc1;
} else {
return new IntersectionPermissionCollection(pc1, pc2);
}
}
/**
* Determine if one collection implies all the permissions in the other collection.
*
* @param collection the collection to check against (must not be {@code null})
* @param testCollection the collection whose permissions are to be tested (must not be {@code null})
* @return {@code true} if {@code collection} implies all of the permissions in {@code testCollection}, {@code false} otherwise
*/
public static boolean impliesAll(PermissionCollection collection, PermissionCollection testCollection) {
return forEachIn(collection, PermissionCollection::implies, testCollection);
}
/**
* Determine if two permission collections are equal, that is, each collection implies all of the permissions in the
* other collection.
*
* @param pc1 the first collection (must not be {@code null})
* @param pc2 the second collection (must not be {@code null})
* @return {@code true} if the collections imply one another, {@code false} otherwise
*/
public static boolean equals(PermissionCollection pc1, PermissionCollection pc2) {
return impliesAll(pc1, pc2) && impliesAll(pc2, pc1);
}
/**
* Add all of the permissions from the source collection to the target collection.
*
* @param target the target collection (must not be {@code null})
* @param source the source collection (must not be {@code null})
* @return the target collection (not {@code null})
*/
public static PermissionCollection addAll(PermissionCollection target, PermissionCollection source) {
return forEachIn(source, PermissionCollection::add, target);
}
/**
* Add all of the permissions from the source collection to the target collection.
*
* @param target the target collection (must not be {@code null})
* @param source the source collection (must not be {@code null})
* @return the target collection (not {@code null})
*/
public static PermissionCollection addAll(PermissionCollection target, Collection source) {
source.forEach(target::add);
return target;
}
/**
* Add a permission to a collection, returning the target collection. If the permission is {@code null}, it is
* not added.
*
* @param target the target collection (must not be {@code null})
* @param source the permission to add
* @return the target collection (not {@code null})
*/
public static PermissionCollection add(PermissionCollection target, Permission source) {
Assert.checkNotNullParam("target", target);
if (source != null) target.add(source);
return target;
}
/**
* Instantiate a permission with the given class name, permission name, and actions.
*
* @param classLoader the class loader to search in ({@code null} indicates the system class loader)
* @param className the name of the permission class to instantiate (must not be {@code null})
* @param name the permission name (may be {@code null} if allowed by the permission class)
* @param actions the permission actions (may be {@code null} if allowed by the permission class)
* @return the permission object (not {@code null})
* @throws InvalidPermissionClassException if the permission class does not exist or is not valid
* @throws ClassCastException if the class name does not refer to a subclass of {@link Permission}
*/
public static Permission createPermission(final ClassLoader classLoader, final String className, final String name, final String actions) {
Assert.checkNotNullParam("className", className);
final Class extends Permission> permissionClass;
try {
permissionClass = Class.forName(className, true, classLoader).asSubclass(Permission.class);
} catch (ClassNotFoundException e) {
throw ElytronMessages.log.permissionClassMissing(className, e);
}
return createPermission(permissionClass, name, actions);
}
/**
* Instantiate a permission with the given class, permission name, and actions.
*
* @param permissionClass the permission class to instantiate (must not be {@code null})
* @param name the permission name (may be {@code null} if allowed by the permission class)
* @param actions the permission actions (may be {@code null} if allowed by the permission class)
* @return the permission object (not {@code null})
* @throws InvalidPermissionClassException if the permission class does not exist or is not valid
*/
public static Permission createPermission(final Class extends Permission> permissionClass, final String name, final String actions) {
Assert.checkNotNullParam("permissionClass", permissionClass);
Constructor extends Permission> noArgs = null;
Constructor extends Permission> oneArg = null;
Constructor extends Permission> twoArg = null;
for (Constructor> raw : permissionClass.getConstructors()) {
@SuppressWarnings("unchecked")
Constructor extends Permission> ctor = (Constructor extends Permission>) raw;
final Class>[] parameterTypes = ctor.getParameterTypes();
if (parameterTypes.length == 2 && parameterTypes[0] == String.class && parameterTypes[1] == String.class) {
twoArg = ctor;
} else if (parameterTypes.length == 1 && parameterTypes[0] == String.class) {
oneArg = ctor;
} else if (parameterTypes.length == 0) {
noArgs = ctor;
}
}
try {
if (twoArg != null) {
return twoArg.newInstance(name, actions);
} else if (oneArg != null) {
return oneArg.newInstance(name);
} else if (noArgs != null) {
return noArgs.newInstance();
} else {
throw ElytronMessages.log.noPermissionConstructor(permissionClass.getName());
}
} catch (IllegalAccessException e) {
throw new IllegalAccessError(e.getMessage());
} catch (InstantiationException e) {
throw ElytronMessages.log.permissionInstantiation(permissionClass.getName(), e);
} catch (InvocationTargetException e) {
try {
throw e.getCause();
} catch (Error | RuntimeException cause) {
throw cause;
} catch (Throwable cause) {
throw new UndeclaredThrowableException(cause);
}
}
}
/**
* Get a read-only collection of the given permissions.
*
* @param permissions the permissions to assign
* @return the read-only collection
*/
public static PermissionCollection readOnlyCollectionOf(Permission... permissions) {
final int length = permissions.length;
if (length == 0) {
return EMPTY_PERMISSION_COLLECTION;
} else {
Permissions collection = new Permissions();
addAll(collection, Arrays.asList(permissions));
collection.setReadOnly();
return collection;
}
}
}