Ace.java
/*
* Copyright 2019 the original author or authors.
*
* 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.bremersee.acl;
import static java.util.Collections.unmodifiableSortedSet;
import static java.util.Objects.nonNull;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.SortedSet;
import java.util.TreeSet;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* The access control entry.
*
* @author Christian Bremer
*/
public interface Ace {
/**
* The constant GUEST.
*/
String GUEST = "guest";
/**
* The constant USERS.
*/
String USERS = "users";
/**
* The constant ROLES.
*/
String ROLES = "roles";
/**
* The constant GROUPS.
*/
String GROUPS = "groups";
/**
* Builder ace builder.
*
* @return the ace builder
*/
static AceBuilder builder() {
return new AceBuilder();
}
/**
* Empty ace.
*
* @return the ace
*/
static Ace empty() {
return builder().build();
}
/**
* Determines whether guests have access.
*
* @return {@code true} if guests have access, otherwise {@code false}
*/
boolean isGuest();
/**
* Gets users.
*
* @return the users
*/
SortedSet<String> getUsers();
/**
* Gets roles.
*
* @return the roles
*/
SortedSet<String> getRoles();
/**
* Gets groups.
*
* @return the groups
*/
SortedSet<String> getGroups();
/**
* The ace builder.
*
* @author Christian Bremer
*/
@ToString
@EqualsAndHashCode
class AceBuilder {
private boolean guest;
private final TreeSet<String> users = new TreeSet<>(String::compareToIgnoreCase);
private final TreeSet<String> roles = new TreeSet<>(String::compareToIgnoreCase);
private final TreeSet<String> groups = new TreeSet<>(String::compareToIgnoreCase);
/**
* From ace builder.
*
* @param ace the ace
* @return the ace builder
*/
public AceBuilder from(Ace ace) {
if (nonNull(ace)) {
guest(ace.isGuest());
users(ace.getUsers());
roles(ace.getRoles());
groups(ace.getGroups());
}
return this;
}
/**
* Guest ace builder.
*
* @param isGuest the is guest
* @return the ace builder
*/
public AceBuilder guest(boolean isGuest) {
this.guest = isGuest;
return this;
}
/**
* Users ace builder.
*
* @param users the users
* @return the ace builder
*/
public AceBuilder users(Collection<String> users) {
this.users.clear();
return addUsers(nonNull(users) ? users : List.of());
}
/**
* Add users ace builder.
*
* @param users the users
* @return the ace builder
*/
public AceBuilder addUsers(Collection<String> users) {
if (nonNull(users)) {
users.stream()
.filter(entry -> nonNull(entry) && !entry.isBlank())
.forEach(this.users::add);
}
return this;
}
/**
* Remove users ace builder.
*
* @param users the users
* @return the ace builder
*/
public AceBuilder removeUsers(Collection<String> users) {
if (nonNull(users)) {
users.stream()
.filter(Objects::nonNull)
.forEach(this.users::remove);
}
return this;
}
/**
* Roles ace builder.
*
* @param roles the roles
* @return the ace builder
*/
public AceBuilder roles(Collection<String> roles) {
this.roles.clear();
return addRoles(nonNull(roles) ? roles : List.of());
}
/**
* Add roles ace builder.
*
* @param roles the roles
* @return the ace builder
*/
public AceBuilder addRoles(Collection<String> roles) {
if (nonNull(roles)) {
roles.stream()
.filter(entry -> nonNull(entry) && !entry.isBlank())
.forEach(this.roles::add);
}
return this;
}
/**
* Remove roles ace builder.
*
* @param roles the roles
* @return the ace builder
*/
public AceBuilder removeRoles(Collection<String> roles) {
if (nonNull(roles)) {
roles.stream()
.filter(Objects::nonNull)
.forEach(this.roles::remove);
}
return this;
}
/**
* Groups ace builder.
*
* @param groups the groups
* @return the ace builder
*/
public AceBuilder groups(Collection<String> groups) {
this.groups.clear();
return addGroups(nonNull(groups) ? groups : List.of());
}
/**
* Add groups ace builder.
*
* @param groups the groups
* @return the ace builder
*/
public AceBuilder addGroups(Collection<String> groups) {
if (nonNull(groups)) {
groups.stream()
.filter(entry -> nonNull(entry) && !entry.isBlank())
.forEach(this.groups::add);
}
return this;
}
/**
* Remove groups ace builder.
*
* @param groups the groups
* @return the ace builder
*/
public AceBuilder removeGroups(Collection<String> groups) {
if (nonNull(groups)) {
groups.stream()
.filter(Objects::nonNull)
.forEach(this.groups::remove);
}
return this;
}
/**
* Build ace.
*
* @return the ace
*/
public Ace build() {
return new AceImpl(guest, users, roles, groups);
}
}
/**
* The ace implementation.
*
* @author Christian Bremer
*/
@ToString
@EqualsAndHashCode
class AceImpl implements Ace {
private final boolean guestFlag;
private final SortedSet<String> userSet;
private final SortedSet<String> roleSet;
private final SortedSet<String> groupSet;
private AceImpl(
boolean guest,
SortedSet<String> users,
SortedSet<String> roles,
SortedSet<String> groups) {
this.guestFlag = guest;
this.userSet = unmodifiableSortedSet(users);
this.roleSet = unmodifiableSortedSet(roles);
this.groupSet = unmodifiableSortedSet(groups);
}
@Override
public boolean isGuest() {
return guestFlag;
}
@Override
public SortedSet<String> getUsers() {
return userSet;
}
@Override
public SortedSet<String> getRoles() {
return roleSet;
}
@Override
public SortedSet<String> getGroups() {
return groupSet;
}
}
}