All the cleanup

This commit is contained in:
Luck 2019-11-09 22:34:12 +00:00
parent dc52807a46
commit 287c0f7f7a
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
30 changed files with 193 additions and 415 deletions

View File

@ -35,9 +35,6 @@ import net.luckperms.api.model.user.UserManager;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.NodeEqualityPredicate;
import net.luckperms.api.node.Tristate;
import net.luckperms.api.node.types.MetaNode;
import net.luckperms.api.node.types.PrefixNode;
import net.luckperms.api.node.types.SuffixNode;
import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull;
@ -159,232 +156,105 @@ public interface PermissionHolder {
*/
@NonNull Data transientData();
/**
* Encapsulates a store of data ({@link Node}s) within a {@link PermissionHolder}.
*
* <p>The effect of any mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*/
interface Data {
/**
* Gets the backing map containing every permission this holder has.
* Gets a map of the {@link Node}s contained within this instance,
* mapped to their defined {@link Node#getContexts() context}.
*
* <p>This method <b>does not</b> resolve inheritance rules, and returns a
* view of what's 'in the file'.</p>
*
* @return the holders own nodes
* @return a map of nodes
*/
@NonNull Map<ImmutableContextSet, Collection<Node>> getNodes();
@NonNull Map<ImmutableContextSet, Collection<Node>> toMap();
/**
* Gets a flattened set of {@link Node}s the holder has.
* Gets a flattened set of {@link Node}s contained within this instance.
*
* <p>Effectively combines the value collections of the map returned by
* {@link #getNodes()}.</p>
* {@link #toMap()}.</p>
*
* @return a flattened set of the holders own nodes
*/
@NonNull Set<Node> getFlattenedNodes();
@NonNull Set<Node> toSet();
/**
* Checks to see if the object has a certain permission.
* Gets if this instance contains a given {@link Node}.
*
* <p>Returns {@link Tristate#UNDEFINED} if the instance does not contain the node,
* and the {@link Node#getValue() assigned value} of the node as a {@link Tristate}
* if it is present.</p>
*
* @param node the node to check for
* @param equalityPredicate how to determine if a node matches
* @return a Tristate for the holders permission status for the node
* @return a Tristate relating to the assigned state of the node
* @throws NullPointerException if the node is null
*/
@NonNull Tristate containsNode(@NonNull Node node, @NonNull NodeEqualityPredicate equalityPredicate);
@NonNull Tristate contains(@NonNull Node node, @NonNull NodeEqualityPredicate equalityPredicate);
/**
* Sets a permission node for the permission holder.
* Adds a node.
*
* <p>Although this method is named setPermission, it can be used for all node types.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param node The node to be set
* @param node the node to be add
* @return the result of the operation
* @throws NullPointerException if the node is null
*/
@NonNull DataMutateResult addNode(@NonNull Node node);
@NonNull DataMutateResult add(@NonNull Node node);
/**
* Sets a permission node for the permission holder.
* Adds a node.
*
* <p>Although this method is named setPermission, it can be used for all node types.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param node The node to be set
* @param temporaryMergeBehaviour The behaviour used to merge temporary permission entries
* @param node the node to add
* @param temporaryMergeBehaviour the behaviour used to merge temporary permission entries
* @return the result of the operation
* @throws NullPointerException if the node is null
*/
@NonNull TemporaryDataMutateResult addNode(@NonNull Node node, @NonNull TemporaryMergeBehaviour temporaryMergeBehaviour);
@NonNull TemporaryDataMutateResult add(@NonNull Node node, @NonNull TemporaryMergeBehaviour temporaryMergeBehaviour);
/**
* Unsets a permission for the permission holder.
* Removes a node.
*
* <p>Although this method is named unsetPermission, it can be used for all node types.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param node The node to be unset
* @param node the node to remove
* @return the result of the operation
* @throws NullPointerException if the node is null
*/
@NonNull DataMutateResult removeNode(@NonNull Node node);
@NonNull DataMutateResult remove(@NonNull Node node);
/**
* Clears any nodes from the holder which pass the predicate.
*
* <p>This method only targets enduring data.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* Clears all nodes.
*/
void clear();
/**
* Clears any nodes which pass the predicate.
*
* @param test the predicate to test for nodes which should be removed
*/
void clearMatching(@NonNull Predicate<? super Node> test);
void clear(@NonNull Predicate<? super Node> test);
/**
* Clears all nodes held by the permission holder.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*/
void clearNodes();
/**
* Clears all nodes held by the permission holder in a specific context.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* Clears all nodes in a specific context.
*
* @param contextSet the contexts to filter by
*/
void clearNodes(@NonNull ContextSet contextSet);
void clear(@NonNull ContextSet contextSet);
/**
* Clears all parent groups.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*/
void clearParents();
/**
* Clears all parent groups in a specific context.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
* Clears all nodes in a specific context which pass the predicate.
*
* @param contextSet the contexts to filter by
* @param test the predicate to test for nodes which should be removed
*/
void clearParents(@NonNull ContextSet contextSet);
/**
* Clears all meta held by the permission holder.
*
* <p>Meta nodes in this case, are any nodes which have a {@link MetaNode}, {@link PrefixNode}
* or {@link SuffixNode} type.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*/
void clearMeta();
/**
* Clears all meta held by the permission holder in a specific context.
*
* <p>Meta nodes in this case, are any nodes which have a {@link MetaNode}, {@link PrefixNode}
* or {@link SuffixNode} type.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param contextSet the contexts to filter by
*/
void clearMeta(@NonNull ContextSet contextSet);
void clear(@NonNull ContextSet contextSet, @NonNull Predicate<? super Node> test);
}

View File

@ -31,11 +31,11 @@ import net.luckperms.api.node.Node;
* Controls how the implementation should behave when new temporary nodes are set
* that would otherwise conflict with existing entries.
*
* <p>The default behaviour of {@link PermissionHolder.Data#addNode(Node)} is
* <p>The default behaviour of {@link PermissionHolder.Data#add(Node)} is
* to return a result of {@link DataMutateResult#ALREADY_HAS} when an equivalent
* node is found. This can be replicated using {@link #FAIL_WITH_ALREADY_HAS}.</p>
*
* <p>However, the {@link PermissionHolder.Data#addNode(Node, TemporaryMergeBehaviour)}
* <p>However, the {@link PermissionHolder.Data#add(Node, TemporaryMergeBehaviour)}
* method allows this behaviour to be customized for temporary permissions.</p>
*/
public enum TemporaryMergeBehaviour {

View File

@ -201,13 +201,13 @@ public class LPPermissionAttachment extends PermissionAttachment {
// remove transient permissions from the holder which were added by this attachment & equal the permission
User user = this.permissible.getUser();
user.removeIf(DataType.TRANSIENT, null, n -> n.getMetadata(TRANSIENT_SOURCE_KEY).orElse(null) == this && n.getKey().equals(name), null);
user.removeIf(DataType.TRANSIENT, null, n -> n.getMetadata(TRANSIENT_SOURCE_KEY).orElse(null) == this && n.getKey().equals(name));
}
private void clearInternal() {
// remove all transient permissions added by this attachment
User user = this.permissible.getUser();
user.removeIf(DataType.TRANSIENT, null, n -> n.getMetadata(TRANSIENT_SOURCE_KEY).orElse(null) == this, null);
user.removeIf(DataType.TRANSIENT, null, n -> n.getMetadata(TRANSIENT_SOURCE_KEY).orElse(null) == this);
}
@Override

View File

@ -266,7 +266,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
}
// remove all prefixes/suffixes directly set on the user/group
holder.removeIf(DataType.NORMAL, null, node -> type.nodeType().matches(node), null);
holder.removeIf(DataType.NORMAL, null, node -> type.nodeType().matches(node));
if (value == null) {
this.vaultPermission.holderSave(holder);
@ -292,7 +292,7 @@ public class LuckPermsVaultChat extends AbstractVaultChat {
logMsg("#setMeta: %s - %s - %s - %s", holder.getPlainDisplayName(), key, value, world);
}
holder.removeIf(DataType.NORMAL, null, n -> n instanceof MetaNode && ((MetaNode) n).getMetaKey().equals(key), null);
holder.removeIf(DataType.NORMAL, null, n -> n instanceof MetaNode && ((MetaNode) n).getMetaKey().equals(key));
if (value == null) {
this.vaultPermission.holderSave(holder);

View File

@ -18,9 +18,9 @@ dependencies {
}
compile 'com.google.code.gson:gson:2.7'
compile 'com.google.guava:guava:19.0'
compile 'com.github.ben-manes.caffeine:caffeine:2.7.0'
compile 'com.squareup.okhttp3:okhttp:3.14.1'
compile 'com.squareup.okio:okio:1.17.3'
compile 'com.github.ben-manes.caffeine:caffeine:2.8.0'
compile 'com.squareup.okhttp3:okhttp:4.2.2'
compile 'com.squareup.okio:okio:2.2.2'
compile('me.lucko.configurate:configurate-core:3.5') {
exclude(module: 'guava')
}
@ -34,8 +34,8 @@ dependencies {
compile('me.lucko.configurate:configurate-toml:3.5') {
exclude(module: 'toml4j')
}
compile 'com.zaxxer:HikariCP:3.3.1'
compile 'com.zaxxer:HikariCP:3.4.1'
compile 'redis.clients:jedis:2.10.2'
compile 'org.mongodb:mongo-java-driver:3.10.1'
compile 'org.mongodb:mongo-java-driver:3.11.1'
compile 'org.yaml:snakeyaml:1.23'
}

View File

@ -36,7 +36,6 @@ import net.luckperms.api.model.TemporaryDataMutateResult;
import net.luckperms.api.model.TemporaryMergeBehaviour;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.NodeEqualityPredicate;
import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.Tristate;
import net.luckperms.api.query.QueryOptions;
@ -53,13 +52,13 @@ import java.util.function.Predicate;
public class ApiPermissionHolder implements net.luckperms.api.model.PermissionHolder {
private final PermissionHolder handle;
private final Normal normalData;
private final Transient transientData;
private final DataImpl normalData;
private final DataImpl transientData;
ApiPermissionHolder(PermissionHolder handle) {
this.handle = Objects.requireNonNull(handle, "handle");
this.normalData = new Normal();
this.transientData = new Transient();
this.normalData = new DataImpl(DataType.NORMAL);
this.transientData = new DataImpl(DataType.TRANSIENT);
}
PermissionHolder getHandle() {
@ -128,99 +127,62 @@ public class ApiPermissionHolder implements net.luckperms.api.model.PermissionHo
this.handle.auditTemporaryNodes();
}
private abstract class AbstractData implements Data {
private class DataImpl implements Data {
private final DataType dataType;
private AbstractData(DataType dataType) {
DataImpl(DataType dataType) {
this.dataType = dataType;
}
@Override
public @NonNull Map<ImmutableContextSet, Collection<Node>> getNodes() {
public @NonNull Map<ImmutableContextSet, Collection<Node>> toMap() {
return ApiPermissionHolder.this.handle.getData(this.dataType).immutable().asMap();
}
@Override
public @NonNull Set<Node> getFlattenedNodes() {
public @NonNull Set<Node> toSet() {
return ApiPermissionHolder.this.handle.getData(this.dataType).asSet();
}
@Override
public @NonNull Tristate containsNode(@NonNull Node node, @NonNull NodeEqualityPredicate equalityPredicate) {
public @NonNull Tristate contains(@NonNull Node node, @NonNull NodeEqualityPredicate equalityPredicate) {
return ApiPermissionHolder.this.handle.hasNode(this.dataType, node, equalityPredicate);
}
@Override
public @NonNull DataMutateResult addNode(@NonNull Node node) {
public @NonNull DataMutateResult add(@NonNull Node node) {
return ApiPermissionHolder.this.handle.setNode(this.dataType, node, true);
}
@Override
public @NonNull TemporaryDataMutateResult addNode(@NonNull Node node, @NonNull TemporaryMergeBehaviour temporaryMergeBehaviour) {
public @NonNull TemporaryDataMutateResult add(@NonNull Node node, @NonNull TemporaryMergeBehaviour temporaryMergeBehaviour) {
return ApiPermissionHolder.this.handle.setNode(this.dataType, node, temporaryMergeBehaviour);
}
@Override
public @NonNull DataMutateResult removeNode(@NonNull Node node) {
public @NonNull DataMutateResult remove(@NonNull Node node) {
return ApiPermissionHolder.this.handle.unsetNode(this.dataType, node);
}
@Override
public void clearMatching(@NonNull Predicate<? super Node> test) {
ApiPermissionHolder.this.handle.removeIf(this.dataType, null, test, null);
public void clear() {
ApiPermissionHolder.this.handle.clearNodes(this.dataType, null, true);
}
@Override
public void clearNodes() {
ApiPermissionHolder.this.handle.clearNodes(this.dataType, null, false);
public void clear(@NonNull Predicate<? super Node> test) {
ApiPermissionHolder.this.handle.removeIf(this.dataType, null, test, true);
}
@Override
public void clear(@NonNull ContextSet contextSet) {
ApiPermissionHolder.this.handle.clearNodes(this.dataType, contextSet, true);
}
@Override
public void clearNodes(@NonNull ContextSet contextSet) {
ApiPermissionHolder.this.handle.clearNodes(this.dataType, contextSet, false);
}
@Override
public void clearMeta() {
ApiPermissionHolder.this.handle.removeIf(this.dataType, null, NodeType.META_OR_CHAT_META::matches, null);
}
@Override
public void clearMeta(@NonNull ContextSet contextSet) {
ApiPermissionHolder.this.handle.removeIf(this.dataType, contextSet, NodeType.META_OR_CHAT_META::matches, null);
}
}
private final class Normal extends AbstractData implements Data {
private Normal() {
super(DataType.NORMAL);
}
@Override
public void clearParents() {
ApiPermissionHolder.this.handle.clearNormalParents(null, true);
}
@Override
public void clearParents(@NonNull ContextSet contextSet) {
ApiPermissionHolder.this.handle.clearNormalParents(contextSet, true);
}
}
private final class Transient extends AbstractData implements Data {
private Transient() {
super(DataType.TRANSIENT);
}
@Override
public void clearParents() {
ApiPermissionHolder.this.handle.removeIf(DataType.TRANSIENT, null, NodeType.INHERITANCE::matches, null);
}
@Override
public void clearParents(@NonNull ContextSet contextSet) {
ApiPermissionHolder.this.handle.removeIf(DataType.TRANSIENT, contextSet, NodeType.INHERITANCE::matches, null);
public void clear(@NonNull ContextSet contextSet, @NonNull Predicate<? super Node> test) {
ApiPermissionHolder.this.handle.removeIf(this.dataType, contextSet, test, true);
}
}

View File

@ -101,9 +101,9 @@ public class MetaClear extends SharedSubCommand {
}
if (context.isEmpty()) {
holder.removeIf(DataType.NORMAL, null, type::matches, null);
holder.removeIf(DataType.NORMAL, null, type::matches);
} else {
holder.removeIf(DataType.NORMAL, context, type::matches, null);
holder.removeIf(DataType.NORMAL, context, type::matches);
}
int changed = before - holder.normalData().immutable().size();

View File

@ -92,7 +92,7 @@ public class MetaRemoveChatMeta extends SharedSubCommand {
holder.removeIf(DataType.NORMAL, null, n -> this.type.nodeType().matches(n) &&
this.type.nodeType().cast(n).getPriority() == priority &&
!n.hasExpiry() &&
n.getContexts().equals(context), null);
n.getContexts().equals(context));
Message.BULK_REMOVE_CHATMETA_SUCCESS.send(sender, holder.getFormattedDisplayName(), this.type.name().toLowerCase(), priority, MessageUtils.contextSetToString(plugin.getLocaleManager(), context));
LoggedAction.build().source(sender).target(holder)

View File

@ -92,7 +92,7 @@ public class MetaRemoveTempChatMeta extends SharedSubCommand {
holder.removeIf(DataType.NORMAL, null, n -> this.type.nodeType().matches(n) &&
this.type.nodeType().cast(n).getPriority() == priority &&
n.hasExpiry() &&
n.getContexts().equals(context), null);
n.getContexts().equals(context));
Message.BULK_REMOVE_TEMP_CHATMETA_SUCCESS.send(sender, holder.getFormattedDisplayName(), this.type.name().toLowerCase(), priority, MessageUtils.contextSetToString(plugin.getLocaleManager(), context));
LoggedAction.build().source(sender).target(holder)

View File

@ -86,7 +86,7 @@ public class MetaSet extends SharedSubCommand {
return CommandResult.STATE_ERROR;
}
holder.removeIf(DataType.NORMAL, context, n -> n instanceof MetaNode && !n.hasExpiry() && ((MetaNode) n).getMetaKey().equalsIgnoreCase(key), null);
holder.removeIf(DataType.NORMAL, context, n -> n instanceof MetaNode && !n.hasExpiry() && ((MetaNode) n).getMetaKey().equalsIgnoreCase(key));
holder.setNode(DataType.NORMAL, node, true);
TextComponent.Builder builder = Message.SET_META_SUCCESS.asComponent(plugin.getLocaleManager(), key, value, holder.getFormattedDisplayName(), MessageUtils.contextSetToString(plugin.getLocaleManager(), context)).toBuilder();

View File

@ -107,7 +107,7 @@ public class MetaSetChatMeta extends SharedSubCommand {
}
// remove all other prefixes/suffixes set in these contexts
holder.removeIf(DataType.NORMAL, context, node -> this.type.nodeType().matches(node), null);
holder.removeIf(DataType.NORMAL, context, node -> this.type.nodeType().matches(node));
// determine the priority to set at
if (priority == Integer.MIN_VALUE) {

View File

@ -91,7 +91,7 @@ public class MetaSetTemp extends SharedSubCommand {
return CommandResult.STATE_ERROR;
}
holder.removeIf(DataType.NORMAL, context, n -> n instanceof MetaNode && n.hasExpiry() && ((MetaNode) n).getMetaKey().equalsIgnoreCase(key), null);
holder.removeIf(DataType.NORMAL, context, n -> n instanceof MetaNode && n.hasExpiry() && ((MetaNode) n).getMetaKey().equalsIgnoreCase(key));
duration = holder.setNode(DataType.NORMAL, node, modifier).getMergedNode().getExpiry().getEpochSecond();
TextComponent.Builder builder = Message.SET_META_TEMP_SUCCESS.asComponent(plugin.getLocaleManager(), key, value, holder.getFormattedDisplayName(), DurationFormatter.LONG.formatDateDiff(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context)).toBuilder();

View File

@ -117,7 +117,7 @@ public class MetaSetTempChatMeta extends SharedSubCommand {
}
// remove all other prefixes/suffixes set in these contexts
holder.removeIf(DataType.NORMAL, context, node -> this.type.nodeType().matches(node), null);
holder.removeIf(DataType.NORMAL, context, node -> this.type.nodeType().matches(node));
// determine the priority to set at
if (priority == Integer.MIN_VALUE) {

View File

@ -72,7 +72,7 @@ public class MetaUnset extends SharedSubCommand {
return CommandResult.NO_PERMISSION;
}
if (holder.removeIf(DataType.NORMAL, context, n -> n instanceof MetaNode && !n.hasExpiry() && ((MetaNode) n).getMetaKey().equalsIgnoreCase(key), null)) {
if (holder.removeIf(DataType.NORMAL, context, n -> n instanceof MetaNode && !n.hasExpiry() && ((MetaNode) n).getMetaKey().equalsIgnoreCase(key))) {
Message.UNSET_META_SUCCESS.send(sender, key, holder.getFormattedDisplayName(), MessageUtils.contextSetToString(plugin.getLocaleManager(), context));
LoggedAction.build().source(sender).target(holder)

View File

@ -72,7 +72,7 @@ public class MetaUnsetTemp extends SharedSubCommand {
return CommandResult.NO_PERMISSION;
}
if (holder.removeIf(DataType.NORMAL, context, n -> n instanceof MetaNode && n.hasExpiry() && ((MetaNode) n).getMetaKey().equalsIgnoreCase(key), null)) {
if (holder.removeIf(DataType.NORMAL, context, n -> n instanceof MetaNode && n.hasExpiry() && ((MetaNode) n).getMetaKey().equalsIgnoreCase(key))) {
Message.UNSET_META_TEMP_SUCCESS.send(sender, key, holder.getFormattedDisplayName(), MessageUtils.contextSetToString(plugin.getLocaleManager(), context));
LoggedAction.build().source(sender).target(holder)

View File

@ -45,6 +45,8 @@ import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import net.luckperms.api.context.MutableContextSet;
import net.luckperms.api.model.DataType;
import net.luckperms.api.node.NodeType;
import java.util.List;
@ -70,9 +72,9 @@ public class ParentClear extends SharedSubCommand {
}
if (context.isEmpty()) {
holder.clearNormalParents(null, true);
holder.removeIf(DataType.NORMAL, null, NodeType.INHERITANCE::matches, true);
} else {
holder.clearNormalParents(context, true);
holder.removeIf(DataType.NORMAL, context, NodeType.INHERITANCE::matches, true);
}
int changed = before - holder.normalData().immutable().size();

View File

@ -94,9 +94,9 @@ public class ParentClearTrack extends SharedSubCommand {
}
if (context.isEmpty()) {
holder.removeIf(DataType.NORMAL, null, NodeType.INHERITANCE.predicate(n -> track.containsGroup(n.getGroupName())), null);
holder.removeIf(DataType.NORMAL, null, NodeType.INHERITANCE.predicate(n -> track.containsGroup(n.getGroupName())));
} else {
holder.removeIf(DataType.NORMAL, null, NodeType.INHERITANCE.predicate(n -> n.getContexts().equals(context) && track.containsGroup(n.getGroupName())), null);
holder.removeIf(DataType.NORMAL, null, NodeType.INHERITANCE.predicate(n -> n.getContexts().equals(context) && track.containsGroup(n.getGroupName())));
}
if (holder.getType() == HolderType.USER) {

View File

@ -50,6 +50,7 @@ import me.lucko.luckperms.common.util.Predicates;
import net.luckperms.api.context.MutableContextSet;
import net.luckperms.api.model.DataType;
import net.luckperms.api.node.NodeType;
import java.util.List;
@ -81,7 +82,7 @@ public class ParentSet extends SharedSubCommand {
return CommandResult.NO_PERMISSION;
}
holder.clearNormalParents(context, false);
holder.removeIf(DataType.NORMAL, context, NodeType.INHERITANCE::matches, false);
holder.setNode(DataType.NORMAL, Inheritance.builder(group.getName()).withContext(context).build(), true);
if (holder.getType() == HolderType.USER) {
((User) holder).getPrimaryGroup().setStoredValue(group.getName());

View File

@ -114,7 +114,7 @@ public class ParentSetTrack extends SharedSubCommand {
return CommandResult.NO_PERMISSION;
}
holder.removeIf(DataType.NORMAL, null, NodeType.INHERITANCE.predicate(n -> n.getContexts().equals(context) && track.containsGroup(n.getGroupName())), null);
holder.removeIf(DataType.NORMAL, null, NodeType.INHERITANCE.predicate(n -> n.getContexts().equals(context) && track.containsGroup(n.getGroupName())));
holder.setNode(DataType.NORMAL, Inheritance.builder(group.getName()).withContext(context).build(), true);
Message.SET_TRACK_PARENT_SUCCESS.send(sender, holder.getFormattedDisplayName(), track.getName(), group.getFormattedDisplayName(), MessageUtils.contextSetToString(plugin.getLocaleManager(), context));

View File

@ -73,9 +73,9 @@ public class PermissionClear extends SharedSubCommand {
}
if (context.isEmpty()) {
holder.removeIf(DataType.NORMAL, null, node -> node instanceof PermissionNode, null);
holder.removeIf(DataType.NORMAL, null, node -> node instanceof PermissionNode);
} else {
holder.removeIf(DataType.NORMAL, context, node -> node instanceof PermissionNode, null);
holder.removeIf(DataType.NORMAL, context, node -> node instanceof PermissionNode);
}
int changed = before - holder.normalData().immutable().size();

View File

@ -90,7 +90,7 @@ public class GroupSetDisplayName extends SubCommand<Group> {
return CommandResult.STATE_ERROR;
}
group.removeIf(DataType.NORMAL, context, n -> n instanceof DisplayNameNode, null);
group.removeIf(DataType.NORMAL, context, n -> n instanceof DisplayNameNode);
if (name.equals(group.getName())) {
Message.GROUP_SET_DISPLAY_NAME_REMOVED.send(sender, group.getName(), MessageUtils.contextSetToString(plugin.getLocaleManager(), context));

View File

@ -43,7 +43,7 @@ import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Predicates;
import net.luckperms.api.model.DataType;
import net.luckperms.api.node.types.WeightNode;
import net.luckperms.api.node.NodeType;
import java.util.List;
@ -61,7 +61,7 @@ public class GroupSetWeight extends SubCommand<Group> {
int weight = ArgumentParser.parsePriority(0, args);
group.removeIf(DataType.NORMAL, null, n -> n instanceof WeightNode, null);
group.removeIf(DataType.NORMAL, null, NodeType.WEIGHT::matches);
group.setNode(DataType.NORMAL, Weight.builder(weight).build(), true);
Message.GROUP_SET_WEIGHT.send(sender, weight, group.getFormattedDisplayName());

View File

@ -79,7 +79,7 @@ public class LogNotify extends SubCommand<Log> {
user.setNode(DataType.NORMAL, NodeBuilders.determineMostApplicable(IGNORE_NODE).build(), true);
} else {
// remove the perm
user.removeIf(DataType.NORMAL, ImmutableContextSetImpl.EMPTY, n -> n.getKey().equalsIgnoreCase(IGNORE_NODE), null);
user.removeIf(DataType.NORMAL, ImmutableContextSetImpl.EMPTY, n -> n.getKey().equalsIgnoreCase(IGNORE_NODE));
}
plugin.getStorage().saveUser(user).join();

View File

@ -57,7 +57,7 @@ public final class MigrationUtils {
}
public static void setGroupWeight(Group group, int weight) {
group.removeIf(DataType.NORMAL, null, NodeType.WEIGHT::matches, null);
group.removeIf(DataType.NORMAL, null, NodeType.WEIGHT::matches);
group.setNode(DataType.NORMAL, Weight.builder(weight).build(), true);
}

View File

@ -46,20 +46,20 @@ public enum Dependency {
ASM(
"org.ow2.asm",
"asm",
"6.2.1",
"FGDbbDPMmchOXLMORrAX5NHMmn+8F0EB1vhIKbtkwIU="
"7.1",
"SrL6K20sycyx6qBeoynEB7R7E+0pFfYvjEuMyWJY1N4="
),
ASM_COMMONS(
"org.ow2.asm",
"asm-commons",
"6.2.1",
"P1eNMe8w+UttH0SBL0H+T5inzUKvNTNfXUhmqzuQGGU="
"7.1",
"5VkEidjxmE2Fv+q9Oxc3TFnCiuCdSOxKDrvQGVns01g="
),
JAR_RELOCATOR(
"me.lucko",
"jar-relocator",
"1.3",
"mmz3ltQbS8xXGA2scM0ZH6raISlt4nukjCiU2l9Jxfs="
"1.4",
"1RsiF3BiVztjlfTA+svDCuoDSGFuSpTZYHvUK8yBx8I="
),
TEXT(
@ -114,22 +114,22 @@ public enum Dependency {
CAFFEINE(
"com{}github{}ben-manes{}caffeine",
"caffeine",
"2.7.0",
"Fw8phtcHwN+UIo9X1SV7fxH4hv1CtTthMWp0mKx+B/8=",
"2.8.0",
"sRB6QJe+RRWpI6Vbxj2gTkEeaWSqBFvs4bx6y4SHLtc=",
Relocation.of("caffeine", "com{}github{}benmanes{}caffeine")
),
OKIO(
"com{}squareup{}" + RelocationHelper.OKIO_STRING,
RelocationHelper.OKIO_STRING,
"1.17.3",
"yxja86IIrjirnYJUP/uT4fGF6GPIoOUsw3L/46WPVUk=",
"2.2.2",
"5YyXQGprsROIk3UCmaxjxqoEs4trSerhv8rRpj75uhs=",
Relocation.of(RelocationHelper.OKIO_STRING, RelocationHelper.OKIO_STRING)
),
OKHTTP(
"com{}squareup{}" + RelocationHelper.OKHTTP3_STRING,
"okhttp",
"3.14.1",
"WmvmkWUwdqpk3NNh0uRF5AYLS13IgrH2uknnnd/D5WM=",
"4.2.2",
"UGQYLP9AsQDOV/vzzpheEuOM9EM3JOgbF1wYQ+rsu3U=",
Relocation.of(RelocationHelper.OKHTTP3_STRING, RelocationHelper.OKHTTP3_STRING),
Relocation.of(RelocationHelper.OKIO_STRING, RelocationHelper.OKIO_STRING)
),
@ -143,15 +143,15 @@ public enum Dependency {
MARIADB_DRIVER(
"org{}mariadb{}jdbc",
"mariadb-java-client",
"2.4.0",
"G346tblA35aJS8q1a3dQVZdU7Q7isGMzhwftoz6MZqU=",
"2.5.1",
"/AxG0o0JnIme7hnDTO2WEUxgF1yXPiWPhMKermXAzZE=",
Relocation.of("mariadb", "org{}mariadb{}jdbc")
),
MYSQL_DRIVER(
"mysql",
"mysql-connector-java",
"5.1.47",
"5PhASPOSsrN7r0ao1QjkuN2uKG0gnvmVueEYhSAcGSM=",
"5.1.48",
"VuJsqqOCH1rkr0T5x09mz4uE6gFRatOAPLsOkEm27Kg=",
Relocation.of("mysql", "com{}mysql")
),
POSTGRESQL_DRIVER(
@ -164,43 +164,43 @@ public enum Dependency {
H2_DRIVER(
"com.h2database",
"h2",
"1.4.198",
"Mt1rFJy3IqpMLdTUCnSpzUHjKsWaTnVaZuV1NmDWHUY="
"1.4.200",
"OtmsS2qunNnTrBxEdGXh7QYBm4UbiT3WqNdt222FvKY="
// we don't apply relocations to h2 - it gets loaded via
// an isolated classloader
),
SQLITE_DRIVER(
"org.xerial",
"sqlite-jdbc",
"3.25.2",
"pF2mGr7WFWilM/3s4SUJMYCCjt6w1Lb21XLgz0V0ZfY="
"3.28.0",
"k3hOVtv1RiXgbJks+D9w6cG93Vxq0dPwEwjIex2WG2A="
// we don't apply relocations to sqlite - it gets loaded via
// an isolated classloader
),
HIKARI(
"com{}zaxxer",
"HikariCP",
"3.3.1",
"SIaA1yzGHOZNpZNoIt903f5ScJrIB3u8CT2cNkaLcy0=",
"3.4.1",
"uCbLTp8iz699ZJS3TxSAf4j9UfrikmgxvTHT0+N/Bck=",
Relocation.of("hikari", "com{}zaxxer{}hikari")
),
SLF4J_SIMPLE(
"org.slf4j",
"slf4j-simple",
"1.7.25",
"CWbob/+lvlLT2ee4ndZ02YoD7tCkVPuvfBvZSTvZ2HQ="
"1.7.28",
"YO863GwYR8RuGr16gGIlWqPizh2ywI37H9Q/GkYgdzY="
),
SLF4J_API(
"org.slf4j",
"slf4j-api",
"1.7.25",
"GMSgCV1cHaa4F1kudnuyPSndL1YK1033X/OWHb3iW3k="
"1.7.28",
"+25PZ6KkaJ4+cTWE2xel0QkMHr5u7DDp4DSabuEYFB4="
),
MONGODB_DRIVER(
"org.mongodb",
"mongo-java-driver",
"3.10.1",
"IGjdjTH4VjqnqGUdVe8u+dKfzKkpCG1NR11TE8ieCdU=",
"3.11.1",
"tIWEOrQegZK3TT7mNV4ZnjkpW4ViwPiFEpD6yYPyFmE=",
Relocation.of("mongodb", "com{}mongodb"),
Relocation.of("bson", "org{}bson")
),
@ -216,8 +216,8 @@ public enum Dependency {
COMMONS_POOL_2(
"org.apache.commons",
"commons-pool2",
"2.6.1",
"4tb0CE+KGA3mbHcAND/orToKqE8ssFYe20F/4f1BqhU=",
"2.7.0",
"a1TGdcc4fhV9KMcJiHPy53LCI8ejW8mxNxc2fJdToeQ=",
Relocation.of("commonspool2", "org{}apache{}commons{}pool2")
),
CONFIGURATE_CORE(

View File

@ -42,8 +42,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
@ -51,6 +49,8 @@ import java.nio.file.Path;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -67,13 +67,11 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
for (LoadedExtension extension : this.extensions) {
try {
extension.instance.unload();
if (extension.classLoader != null) {
extension.classLoader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
this.extensions.clear();
}
@Override
@ -82,7 +80,7 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
return;
}
this.plugin.getLogger().info("Loading extension: " + extension.getClass().getName());
this.extensions.add(new LoadedExtension(extension, null, null));
this.extensions.add(new LoadedExtension(extension, null));
extension.load();
this.plugin.getEventFactory().handleExtensionLoad(extension);
}
@ -117,16 +115,20 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
throw new NoSuchFileException("No file at " + path);
}
URLClassLoader classLoader = new URLClassLoader(new URL[]{path.toUri().toURL()}, getClass().getClassLoader());
String className;
try (InputStream in = classLoader.getResourceAsStream("extension.json")) {
if (in == null) {
try (JarFile jar = new JarFile(path.toFile())) {
JarEntry extensionJarEntry = jar.getJarEntry("extension.json");
if (extensionJarEntry == null) {
throw new IllegalStateException("extension.json not present");
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
JsonElement parsed = GsonProvider.parser().parse(reader);
className = parsed.getAsJsonObject().get("class").getAsString();
try (InputStream in = jar.getInputStream(extensionJarEntry)) {
if (in == null) {
throw new IllegalStateException("extension.json not present");
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
JsonElement parsed = GsonProvider.parser().parse(reader);
className = parsed.getAsJsonObject().get("class").getAsString();
}
}
}
@ -134,9 +136,11 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
throw new IllegalArgumentException("class is null");
}
this.plugin.getBootstrap().getPluginClassLoader().loadJar(path);
Class<? extends Extension> extensionClass;
try {
extensionClass = classLoader.loadClass(className).asSubclass(Extension.class);
extensionClass = Class.forName(className).asSubclass(Extension.class);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
@ -165,7 +169,7 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
}
}
this.extensions.add(new LoadedExtension(extension, classLoader, path));
this.extensions.add(new LoadedExtension(extension, path));
extension.load();
this.plugin.getEventFactory().handleExtensionLoad(extension);
return extension;
@ -178,12 +182,10 @@ public class SimpleExtensionManager implements ExtensionManager, AutoCloseable {
private static final class LoadedExtension {
private final Extension instance;
private final URLClassLoader classLoader;
private final Path path;
private LoadedExtension(Extension instance, URLClassLoader classLoader, Path path) {
private LoadedExtension(Extension instance, Path path) {
this.instance = instance;
this.classLoader = classLoader;
this.path = path;
}
}

View File

@ -478,7 +478,11 @@ public abstract class PermissionHolder {
return DataMutateResult.SUCCESS;
}
public boolean removeIf(DataType dataType, @Nullable ContextSet contextSet, Predicate<? super Node> predicate, @Nullable Runnable taskIfSuccess) {
public boolean removeIf(DataType dataType, @Nullable ContextSet contextSet, Predicate<? super Node> predicate) {
return removeIf(dataType, contextSet, predicate, false);
}
public boolean removeIf(DataType dataType, @Nullable ContextSet contextSet, Predicate<? super Node> predicate, boolean giveDefault) {
NodeMap data = getData(dataType);
ImmutableCollection<? extends Node> before = data.immutable().values();
@ -492,8 +496,8 @@ public abstract class PermissionHolder {
}
}
if (taskIfSuccess != null) {
taskIfSuccess.run();
if (getType() == HolderType.USER && giveDefault) {
getPlugin().getUserManager().giveDefaultIfNeeded((User) this, false);
}
invalidateCache();
@ -530,14 +534,6 @@ public abstract class PermissionHolder {
return true;
}
public boolean clearNormalParents(ContextSet contextSet, boolean giveDefault) {
return removeIf(DataType.NORMAL, contextSet, n -> n instanceof InheritanceNode, () -> {
if (this.getType() == HolderType.USER && giveDefault) {
this.plugin.getUserManager().giveDefaultIfNeeded((User) this, false);
}
});
}
public OptionalInt getWeight() {
return OptionalInt.empty();
}

View File

@ -79,7 +79,7 @@ public class BytebinClient extends AbstractHttpClient {
* @throws IOException if an error occurs
*/
public Content postContent(byte[] buf, MediaType contentType, boolean allowModification) throws IOException {
RequestBody body = RequestBody.create(contentType, buf);
RequestBody body = RequestBody.create(buf, contentType);
Request.Builder requestBuilder = new Request.Builder()
.url(this.url + "post")
@ -122,7 +122,7 @@ public class BytebinClient extends AbstractHttpClient {
throw new IllegalArgumentException("Existing content is not modifiable");
}
RequestBody body = RequestBody.create(contentType, buf);
RequestBody body = RequestBody.create(buf, contentType);
Request.Builder requestBuilder = new Request.Builder()
.url(this.url + existingContent.key())

View File

@ -202,13 +202,13 @@ public class LPPermissionAttachment extends PermissionAttachment {
// remove transient permissions from the holder which were added by this attachment & equal the permission
User user = this.permissible.getUser();
user.removeIf(DataType.TRANSIENT, null, n -> n.getMetadata(TRANSIENT_SOURCE_KEY).orElse(null) == this && n.getKey().equals(name), null);
user.removeIf(DataType.TRANSIENT, null, n -> n.getMetadata(TRANSIENT_SOURCE_KEY).orElse(null) == this && n.getKey().equals(name));
}
private void clearInternal() {
// remove all transient permissions added by this attachment
User user = this.permissible.getUser();
user.removeIf(DataType.TRANSIENT, null, n -> n.getMetadata(TRANSIENT_SOURCE_KEY).orElse(null) == this, null);
user.removeIf(DataType.TRANSIENT, null, n -> n.getMetadata(TRANSIENT_SOURCE_KEY).orElse(null) == this);
}
@Override

View File

@ -65,6 +65,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class PermissionHolderSubjectData implements LPSubjectData {
@ -144,28 +145,20 @@ public class PermissionHolderSubjectData implements LPSubjectData {
@Override
public CompletableFuture<Boolean> clearPermissions() {
if (!this.holder.clearNodes(this.type, null, false)) {
if (!this.holder.clearNodes(this.type, null, true)) {
return CompletableFuture.completedFuture(false);
}
if (this.holder.getType() == HolderType.USER) {
this.service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) this.holder), false);
}
return save(this.holder).thenApply(v -> true);
}
@Override
public CompletableFuture<Boolean> clearPermissions(ImmutableContextSet contexts) {
Objects.requireNonNull(contexts, "contexts");
if (!this.holder.clearNodes(this.type, contexts, false)) {
if (!this.holder.clearNodes(this.type, contexts, true)) {
return CompletableFuture.completedFuture(false);
}
if (this.holder.getType() == HolderType.USER) {
this.service.getPlugin().getUserManager().giveDefaultIfNeeded(((User) this.holder), false);
}
return save(this.holder).thenApply(v -> true);
}
@ -233,22 +226,7 @@ public class PermissionHolderSubjectData implements LPSubjectData {
@Override
public CompletableFuture<Boolean> clearParents() {
boolean ret;
switch (this.type) {
case NORMAL:
ret = this.holder.clearNormalParents(null, true);
break;
case TRANSIENT:
ret = streamNodes()
.filter(n -> n instanceof InheritanceNode)
.peek(n -> this.holder.unsetNode(DataType.TRANSIENT, n))
.findAny().isPresent();
break;
default:
throw new AssertionError();
}
if (!ret) {
if (!this.holder.removeIf(this.type, null, NodeType.INHERITANCE::matches, true)) {
return CompletableFuture.completedFuture(false);
}
@ -258,23 +236,8 @@ public class PermissionHolderSubjectData implements LPSubjectData {
@Override
public CompletableFuture<Boolean> clearParents(ImmutableContextSet contexts) {
Objects.requireNonNull(contexts, "contexts");
boolean ret;
switch (this.type) {
case NORMAL:
ret = this.holder.clearNormalParents(contexts, true);
break;
case TRANSIENT:
ret = streamNodes()
.filter(n -> n instanceof InheritanceNode)
.filter(n -> n.getContexts().equals(contexts))
.peek(n -> this.holder.unsetNode(DataType.TRANSIENT, n))
.findAny().isPresent();
break;
default:
throw new AssertionError();
}
if (!ret) {
if (!this.holder.removeIf(this.type, contexts, NodeType.INHERITANCE::matches, true)) {
return CompletableFuture.completedFuture(false);
}
@ -343,10 +306,7 @@ public class PermissionHolderSubjectData implements LPSubjectData {
ChatMetaType type = ChatMetaType.valueOf(key.toUpperCase());
// remove all prefixes/suffixes from the user
streamNodes()
.filter(n -> type.nodeType().matches(n))
.filter(n -> n.getContexts().equals(contexts))
.forEach(n -> this.holder.unsetNode(this.type, n));
this.holder.removeIf(this.type, contexts, type.nodeType()::matches, false);
MetaAccumulator metaAccumulator = this.holder.accumulateMeta(null, QueryOptions.defaultContextualOptions().toBuilder().context(contexts).build());
metaAccumulator.complete();
@ -357,11 +317,7 @@ public class PermissionHolderSubjectData implements LPSubjectData {
node = builder.withContext(contexts).build();
} else {
// standard remove
streamNodes()
.filter(n -> n instanceof MetaNode && ((MetaNode) n).getMetaKey().equals(key))
.filter(n -> n.getContexts().equals(contexts))
.forEach(n -> this.holder.unsetNode(this.type, n));
this.holder.removeIf(this.type, contexts, NodeType.META.predicate(n -> n.getMetaKey().equals(key)), false);
node = Meta.builder(key, value).withContext(contexts).build();
}
@ -374,18 +330,18 @@ public class PermissionHolderSubjectData implements LPSubjectData {
Objects.requireNonNull(contexts, "contexts");
Objects.requireNonNull(key, "key");
streamNodes()
.filter(n -> {
if (key.equalsIgnoreCase(Prefix.NODE_KEY)) {
return n instanceof PrefixNode;
} else if (key.equalsIgnoreCase(Suffix.NODE_KEY)) {
return n instanceof SuffixNode;
} else {
return n instanceof MetaNode && ((MetaNode) n).getMetaKey().equals(key);
}
})
.filter(n -> n.getContexts().equals(contexts))
.forEach(n -> this.holder.unsetNode(this.type, n));
Predicate<? super Node> test;
if (key.equalsIgnoreCase(Prefix.NODE_KEY)) {
test = NodeType.PREFIX::matches;
} else if (key.equalsIgnoreCase(Suffix.NODE_KEY)) {
test = NodeType.SUFFIX::matches;
} else {
test = NodeType.META.predicate(mn -> mn.getMetaKey().equals(key));
}
if (!this.holder.removeIf(this.type, contexts, test, false)) {
return CompletableFuture.completedFuture(false);
}
return save(this.holder).thenApply(v -> true);
}
@ -394,13 +350,7 @@ public class PermissionHolderSubjectData implements LPSubjectData {
public CompletableFuture<Boolean> clearOptions(ImmutableContextSet contexts) {
Objects.requireNonNull(contexts, "contexts");
boolean success = streamNodes()
.filter(NodeType.META_OR_CHAT_META::matches)
.filter(n -> n.getContexts().equals(contexts))
.peek(n -> this.holder.unsetNode(this.type, n))
.findAny().isPresent();
if (!success) {
if (!this.holder.removeIf(this.type, contexts, NodeType.META_OR_CHAT_META::matches, false)) {
return CompletableFuture.completedFuture(false);
}
@ -409,12 +359,7 @@ public class PermissionHolderSubjectData implements LPSubjectData {
@Override
public CompletableFuture<Boolean> clearOptions() {
boolean success = streamNodes()
.filter(NodeType.META_OR_CHAT_META::matches)
.peek(n -> this.holder.unsetNode(this.type, n))
.findAny().isPresent();
if (!success) {
if (!this.holder.removeIf(this.type, null, NodeType.META_OR_CHAT_META::matches, false)) {
return CompletableFuture.completedFuture(false);
}