From 4667ffc681a5258edeb454b38b39651c40b4bb90 Mon Sep 17 00:00:00 2001 From: Luck Date: Tue, 20 Aug 2019 21:44:43 +0100 Subject: [PATCH] Allow data query order to be specified via the API --- .../api/context/DefaultContextKeys.java | 6 +- .../luckperms/api/model/PermissionHolder.java | 66 ++++-- .../me/lucko/luckperms/api/node/Node.java | 9 +- .../lucko/luckperms/api/node/NodeBuilder.java | 3 +- .../api/node/metadata/NodeMetadataKey.java | 6 +- .../node/metadata/SimpleNodeMetadataKey.java | 2 +- .../types/InheritanceOriginMetadata.java | 9 +- .../api/query/DefaultQueryOptions.java | 6 +- .../api/query/dataorder/DataQueryOrder.java | 121 +++++++++++ .../dataorder/DataQueryOrderFunction.java | 27 ++- .../permissible/LPPermissionAttachment.java | 3 +- .../common/api/ApiRegistrationUtil.java | 2 +- .../common/api/implementation/ApiGroup.java | 3 +- .../implementation/ApiPermissionHolder.java | 4 +- .../common/api/implementation/ApiUser.java | 3 +- .../lucko/luckperms/common/model/Group.java | 3 +- .../common/model/PermissionHolder.java | 39 +++- .../model/PermissionHolderIdentifier.java | 49 ++++- .../luckperms/common/node/AbstractNode.java | 7 +- .../common/node/AbstractNodeBuilder.java | 7 +- .../common/node/types/DisplayName.java | 5 +- .../common/node/types/Inheritance.java | 5 +- .../luckperms/common/node/types/Meta.java | 5 +- .../common/node/types/Permission.java | 5 +- .../luckperms/common/node/types/Prefix.java | 5 +- .../common/node/types/RegexPermission.java | 5 +- .../luckperms/common/node/types/Suffix.java | 5 +- .../luckperms/common/node/types/Weight.java | 5 +- .../permissible/LPPermissionAttachment.java | 3 +- .../service/model/LPSubjectCollection.java | 7 +- .../PermissionHolderSubjectData.java | 200 +++--------------- 31 files changed, 345 insertions(+), 280 deletions(-) create mode 100644 api/src/main/java/me/lucko/luckperms/api/query/dataorder/DataQueryOrder.java rename sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ResolutionOrder.java => api/src/main/java/me/lucko/luckperms/api/query/dataorder/DataQueryOrderFunction.java (57%) rename api/src/main/java/me/lucko/luckperms/api/node/metadata/NodeMetadata.java => common/src/main/java/me/lucko/luckperms/common/model/PermissionHolderIdentifier.java (50%) diff --git a/api/src/main/java/me/lucko/luckperms/api/context/DefaultContextKeys.java b/api/src/main/java/me/lucko/luckperms/api/context/DefaultContextKeys.java index 16506a6c1..49afdac6e 100644 --- a/api/src/main/java/me/lucko/luckperms/api/context/DefaultContextKeys.java +++ b/api/src/main/java/me/lucko/luckperms/api/context/DefaultContextKeys.java @@ -28,8 +28,10 @@ package me.lucko.luckperms.api.context; /** * Some default context keys used by the plugin. */ -public enum DefaultContextKeys { - ; +public final class DefaultContextKeys { + private DefaultContextKeys() { + throw new AssertionError(); + } /** * The context key used to denote the subjects server. diff --git a/api/src/main/java/me/lucko/luckperms/api/model/PermissionHolder.java b/api/src/main/java/me/lucko/luckperms/api/model/PermissionHolder.java index b87705169..c6e739cfa 100644 --- a/api/src/main/java/me/lucko/luckperms/api/model/PermissionHolder.java +++ b/api/src/main/java/me/lucko/luckperms/api/model/PermissionHolder.java @@ -57,34 +57,64 @@ import java.util.function.Predicate; public interface PermissionHolder { /** - * Gets the objects generic name. - * - *

The result of this method is guaranteed to be a unique identifier for distinct instances - * of the same type of object.

- * - *

For {@link User}s, this method returns a {@link UUID#toString() string} representation of - * the users {@link User#getUniqueId() unique id}.

- * - *

For {@link Group}s, this method returns the {@link Group#getName() group name}.

- * - *

The {@link User#getUniqueId()}, {@link User#getUsername()} and {@link Group#getName()} methods - * define a "tighter" specification for obtaining object identifiers.

- * - * @return the identifier for this object. Either a uuid string or name. + * Represents a way to identify distinct {@link PermissionHolder}s. */ - @NonNull String getObjectName(); + interface Identifier { + + /** + * The {@link #getType() type} of {@link User} permission holders. + */ + String USER_TYPE = "user"; + + /** + * The {@link #getType() type} of {@link Group} permission holders. + */ + String GROUP_TYPE = "group"; + + /** + * Gets the {@link PermissionHolder}s generic name. + * + *

The result of this method is guaranteed to be a unique identifier for distinct instances + * of the same type of object.

+ * + *

For {@link User}s, this method returns a {@link UUID#toString() string} representation of + * the users {@link User#getUniqueId() unique id}.

+ * + *

For {@link Group}s, this method returns the {@link Group#getName() group name}.

+ * + *

The {@link User#getUniqueId()}, {@link User#getUsername()} and {@link Group#getName()} methods + * define a "tighter" specification for obtaining object identifiers.

+ * + * @return the identifier for this object. Either a uuid string or name. + */ + @NonNull String getName(); + + /** + * Gets the type of the {@link PermissionHolder}. + * + * @return the type + */ + @NonNull String getType(); + } + + /** + * Gets the identifier of the holder. + * + * @return the identifier + */ + @NonNull Identifier getIdentifier(); /** * Gets a friendly name for this holder, to be displayed in command output, etc. * *

This will always return a value, eventually falling back to - * {@link #getObjectName()} if no other "friendlier" identifiers are present.

+ * {@link Identifier#getName()} if no other "friendlier" identifiers are present.

* *

For {@link User}s, this method will attempt to return the {@link User#getUsername() username}, - * before falling back to {@link #getObjectName()}.

+ * before falling back to {@link Identifier#getName()}.

* *

For {@link Group}s, this method will attempt to return the groups display name, before - * falling back to {@link #getObjectName()}.

+ * falling back to {@link Identifier#getName()}.

* * @return a friendly identifier for this holder */ diff --git a/api/src/main/java/me/lucko/luckperms/api/node/Node.java b/api/src/main/java/me/lucko/luckperms/api/node/Node.java index 07186c0c2..a0d5de855 100644 --- a/api/src/main/java/me/lucko/luckperms/api/node/Node.java +++ b/api/src/main/java/me/lucko/luckperms/api/node/Node.java @@ -28,7 +28,6 @@ package me.lucko.luckperms.api.node; import me.lucko.luckperms.api.LuckPermsProvider; import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ImmutableContextSet; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.DisplayNameNode; import me.lucko.luckperms.api.node.types.InheritanceNode; @@ -188,21 +187,21 @@ public interface Node { * Gets the metadata corresponding to the given key, if present. * * @param key the key - * @param the {@link NodeMetadata} type + * @param the metadata type * @return the data, if present */ - Optional getMetadata(NodeMetadataKey key); + Optional getMetadata(NodeMetadataKey key); /** * Gets the metadata corresponding to the given key, throwing an exception * if no data is present. * * @param key the key - * @param the {@link NodeMetadata} type + * @param the metadata type * @return the data * @throws IllegalStateException if data isn't present */ - default T metadata(NodeMetadataKey key) throws IllegalStateException { + default T metadata(NodeMetadataKey key) throws IllegalStateException { return getMetadata(key).orElseThrow(() -> new IllegalStateException("Node '" + getKey() + "' does not have '" + key.name() + "' attached.")); } diff --git a/api/src/main/java/me/lucko/luckperms/api/node/NodeBuilder.java b/api/src/main/java/me/lucko/luckperms/api/node/NodeBuilder.java index 71e622848..791d93b09 100644 --- a/api/src/main/java/me/lucko/luckperms/api/node/NodeBuilder.java +++ b/api/src/main/java/me/lucko/luckperms/api/node/NodeBuilder.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.api.node; import me.lucko.luckperms.api.context.ContextSet; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import org.checkerframework.checker.nullness.qual.NonNull; @@ -138,7 +137,7 @@ public interface NodeBuilder, B extends NodeBuilder the metadata type * @return the builder */ - @NonNull B withMetadata(@NonNull NodeMetadataKey key, @Nullable T metadata); + @NonNull B withMetadata(@NonNull NodeMetadataKey key, @Nullable T metadata); /** * Creates a {@link Node} instance from the builder. diff --git a/api/src/main/java/me/lucko/luckperms/api/node/metadata/NodeMetadataKey.java b/api/src/main/java/me/lucko/luckperms/api/node/metadata/NodeMetadataKey.java index 9ddd18089..bd596bef1 100644 --- a/api/src/main/java/me/lucko/luckperms/api/node/metadata/NodeMetadataKey.java +++ b/api/src/main/java/me/lucko/luckperms/api/node/metadata/NodeMetadataKey.java @@ -30,7 +30,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; import java.util.Objects; /** - * Represents a key for a specific type of {@link NodeMetadata}. + * Represents a key for a specific type of node metadata. * *

Metadata keys are compared using reference equality, the * {@link #equals(Object)} method should not be implemented.

@@ -43,7 +43,7 @@ import java.util.Objects; * * @param the metadata type */ -public interface NodeMetadataKey { +public interface NodeMetadataKey { /** * Creates a new {@link NodeMetadataKey} for the given name and type. @@ -55,7 +55,7 @@ public interface NodeMetadataKey { * @param the type parameter * @return the key */ - static @NonNull NodeMetadataKey of(@NonNull String name, @NonNull Class type) { + static @NonNull NodeMetadataKey of(@NonNull String name, @NonNull Class type) { Objects.requireNonNull(name, "name"); Objects.requireNonNull(type, "type"); return new SimpleNodeMetadataKey<>(name, type); diff --git a/api/src/main/java/me/lucko/luckperms/api/node/metadata/SimpleNodeMetadataKey.java b/api/src/main/java/me/lucko/luckperms/api/node/metadata/SimpleNodeMetadataKey.java index 2f771fdff..8da2405b7 100644 --- a/api/src/main/java/me/lucko/luckperms/api/node/metadata/SimpleNodeMetadataKey.java +++ b/api/src/main/java/me/lucko/luckperms/api/node/metadata/SimpleNodeMetadataKey.java @@ -27,7 +27,7 @@ package me.lucko.luckperms.api.node.metadata; import org.checkerframework.checker.nullness.qual.NonNull; -final class SimpleNodeMetadataKey implements NodeMetadataKey { +final class SimpleNodeMetadataKey implements NodeMetadataKey { private final String name; private final Class type; diff --git a/api/src/main/java/me/lucko/luckperms/api/node/metadata/types/InheritanceOriginMetadata.java b/api/src/main/java/me/lucko/luckperms/api/node/metadata/types/InheritanceOriginMetadata.java index 0db8be19c..8b2717768 100644 --- a/api/src/main/java/me/lucko/luckperms/api/node/metadata/types/InheritanceOriginMetadata.java +++ b/api/src/main/java/me/lucko/luckperms/api/node/metadata/types/InheritanceOriginMetadata.java @@ -27,15 +27,14 @@ package me.lucko.luckperms.api.node.metadata.types; import me.lucko.luckperms.api.model.PermissionHolder; import me.lucko.luckperms.api.node.Node; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import org.checkerframework.checker.nullness.qual.NonNull; /** - * {@link NodeMetadata} indicating where a node was inherited from. + * Node metadata indicating where a node was inherited from. */ -public interface InheritanceOriginMetadata extends NodeMetadata { +public interface InheritanceOriginMetadata { /** * The {@link NodeMetadataKey} for {@link InheritanceOriginMetadata}. @@ -45,10 +44,10 @@ public interface InheritanceOriginMetadata extends NodeMetadata { /** * Gets the location where the {@link Node} is inherited from. * - *

The resultant string is the {@link PermissionHolder#getObjectName() object name} of the + *

The resultant string is the {@link PermissionHolder.Identifier#getName() object name} of the * permission holder the node was inherited from.

* - *

If the node was not inherited, the {@link PermissionHolder#getObjectName() object name} + *

If the node was not inherited, the {@link PermissionHolder.Identifier#getName() object name} * of the permission holder itself (the one that defined the node) will be returned.

* * @return where the node was inherited from. diff --git a/api/src/main/java/me/lucko/luckperms/api/query/DefaultQueryOptions.java b/api/src/main/java/me/lucko/luckperms/api/query/DefaultQueryOptions.java index 628ce7769..00525bd25 100644 --- a/api/src/main/java/me/lucko/luckperms/api/query/DefaultQueryOptions.java +++ b/api/src/main/java/me/lucko/luckperms/api/query/DefaultQueryOptions.java @@ -32,8 +32,10 @@ import java.util.EnumSet; /** * Some default {@link QueryOptions} instances. */ -enum DefaultQueryOptions { - ; +final class DefaultQueryOptions { + private DefaultQueryOptions() { + throw new AssertionError(); + } private static final EnumSet DEFAULT_FLAGS = EnumSet.allOf(Flag.class); diff --git a/api/src/main/java/me/lucko/luckperms/api/query/dataorder/DataQueryOrder.java b/api/src/main/java/me/lucko/luckperms/api/query/dataorder/DataQueryOrder.java new file mode 100644 index 000000000..1f4481de2 --- /dev/null +++ b/api/src/main/java/me/lucko/luckperms/api/query/dataorder/DataQueryOrder.java @@ -0,0 +1,121 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.api.query.dataorder; + +import me.lucko.luckperms.api.model.DataType; +import me.lucko.luckperms.api.query.QueryOptions; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.function.Consumer; + +/** + * Represents the order in which to query different {@link DataType}s. + * + *

The {@link DataQueryOrder} enum simply represents some default + * implementations of the {@link Comparator} required by {@link QueryOptions} + * and the {@link #queryInOrder(Comparator, Consumer)} or + * {@link #order(Comparator)} methods.

+ * + *

Users are free to implement their own comparator. However, be aware that + * it is possible that more {@link DataType}s may be added in the future. + * Ideally the {@link Comparator} implementations should be able to handle these + * smoothly.

+ */ +public enum DataQueryOrder implements Comparator { + + /** + * A data query order indicating that {@link DataType#TRANSIENT} should be queried first. + */ + TRANSIENT_FIRST { + @Override + public int compare(DataType o1, DataType o2) { + if (o1 == o2) { + return 0; + } + return Boolean.compare( + o1 == DataType.TRANSIENT, + o2 == DataType.TRANSIENT + ); + } + }, + + /** + * A data query order indicating that {@link DataType#TRANSIENT} should be queried last. + */ + TRANSIENT_LAST { + @Override + public int compare(DataType o1, DataType o2) { + if (o1 == o2) { + return 0; + } + return -Boolean.compare( + o1 == DataType.TRANSIENT, + o2 == DataType.TRANSIENT + ); + } + }; + + private static final List TRANSIENT_FIRST_LIST = Collections.unmodifiableList(Arrays.asList(DataType.TRANSIENT, DataType.NORMAL)); + private static final List TRANSIENT_LAST_LIST = Collections.unmodifiableList(Arrays.asList(DataType.NORMAL, DataType.TRANSIENT)); + + /** + * Gets a {@link List} of all {@link DataType}s, in the order defined by + * the {@code comparator}. + * + * @param comparator the comparator + * @return the ordered data types + */ + public static List order(@NonNull Comparator comparator) { + int compare = comparator.compare(DataType.TRANSIENT, DataType.NORMAL); + if (compare > 0) { + // transient first + return TRANSIENT_FIRST_LIST; + } else if (compare < 0) { + // transient last + return TRANSIENT_LAST_LIST; + } else { + // ??? - no defined order + throw new IllegalStateException("Comparator " + comparator + " does not define an order between DataType.NORMAL and DataType.TRANSIENT!"); + } + } + + /** + * Calls the {@code action} {@link Consumer} for each {@link DataType}, in + * the order defined by the {@code comparator}. + * + * @param comparator the comparator + * @param action the action + */ + public static void queryInOrder(@NonNull Comparator comparator, @NonNull Consumer action) { + order(comparator).forEach(action); + } + +} diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ResolutionOrder.java b/api/src/main/java/me/lucko/luckperms/api/query/dataorder/DataQueryOrderFunction.java similarity index 57% rename from sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ResolutionOrder.java rename to api/src/main/java/me/lucko/luckperms/api/query/dataorder/DataQueryOrderFunction.java index b033517c1..1de59b479 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/ResolutionOrder.java +++ b/api/src/main/java/me/lucko/luckperms/api/query/dataorder/DataQueryOrderFunction.java @@ -23,21 +23,34 @@ * SOFTWARE. */ -package me.lucko.luckperms.sponge.service.model; +package me.lucko.luckperms.api.query.dataorder; + +import me.lucko.luckperms.api.model.DataType; +import me.lucko.luckperms.api.model.PermissionHolder; +import me.lucko.luckperms.api.query.OptionKey; + +import org.checkerframework.checker.nullness.qual.NonNull; + +import java.util.Comparator; /** - * Defines in what order data should be resolved. + * A function that generates a {@link DataQueryOrder} comparator for + * {@link PermissionHolder}s as required during inheritance. */ -public enum ResolutionOrder { +public interface DataQueryOrderFunction { /** - * Marks that transient data should be considered before enduring data + * The {@link OptionKey} for {@link DataQueryOrderFunction}. */ - TRANSIENT_FIRST, + OptionKey KEY = new OptionKey(){}; /** - * Marks that transient data should be considered after enduring data + * Gets the {@link DataQueryOrder} comparator for the given + * {@link PermissionHolder.Identifier holder identifier}. + * + * @param holderIdentifier the holder identifier + * @return the comparator to use */ - TRANSIENT_LAST + @NonNull Comparator getOrderComparator(PermissionHolder.@NonNull Identifier holderIdentifier); } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LPPermissionAttachment.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LPPermissionAttachment.java index 0eb8e375e..a7751d68a 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LPPermissionAttachment.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/inject/permissible/LPPermissionAttachment.java @@ -29,7 +29,6 @@ import com.google.common.base.Preconditions; import me.lucko.luckperms.api.model.DataType; import me.lucko.luckperms.api.node.Node; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.bukkit.inject.dummy.DummyPlugin; import me.lucko.luckperms.common.config.ConfigKeys; @@ -53,7 +52,7 @@ import java.util.Set; * * Applies all permissions directly to the backing user instance via transient nodes. */ -public class LPPermissionAttachment extends PermissionAttachment implements NodeMetadata { +public class LPPermissionAttachment extends PermissionAttachment { public static final NodeMetadataKey TRANSIENT_SOURCE_KEY = NodeMetadataKey.of("TransientSource", LPPermissionAttachment.class); diff --git a/common/src/main/java/me/lucko/luckperms/common/api/ApiRegistrationUtil.java b/common/src/main/java/me/lucko/luckperms/common/api/ApiRegistrationUtil.java index 418372837..9f19896ee 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/ApiRegistrationUtil.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/ApiRegistrationUtil.java @@ -25,8 +25,8 @@ package me.lucko.luckperms.common.api; -import me.lucko.luckperms.api.LuckPermsProvider; import me.lucko.luckperms.api.LuckPerms; +import me.lucko.luckperms.api.LuckPermsProvider; import java.lang.reflect.Method; diff --git a/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiGroup.java b/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiGroup.java index bc58ce3e3..8a33b4e7e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiGroup.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiGroup.java @@ -76,9 +76,8 @@ public class ApiGroup extends ApiPermissionHolder implements me.lucko.luckperms. return this.handle.getWeight(); } - @NonNull @Override - public GroupCachedDataManager getCachedData() { + public @NonNull GroupCachedDataManager getCachedData() { return this.handle.getCachedData(); } diff --git a/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiPermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiPermissionHolder.java index c304f9b0a..3dd5f540f 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiPermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiPermissionHolder.java @@ -72,8 +72,8 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.model.Permiss } @Override - public @NonNull String getObjectName() { - return this.handle.getObjectName(); + public @NonNull Identifier getIdentifier() { + return this.handle.getIdentifier(); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiUser.java b/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiUser.java index 79fe7f877..d63cabb35 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiUser.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/implementation/ApiUser.java @@ -87,9 +87,8 @@ public class ApiUser extends ApiPermissionHolder implements me.lucko.luckperms.a return DataMutateResult.SUCCESS; } - @NonNull @Override - public UserCachedDataManager getCachedData() { + public @NonNull UserCachedDataManager getCachedData() { return this.handle.getCachedData(); } diff --git a/common/src/main/java/me/lucko/luckperms/common/model/Group.java b/common/src/main/java/me/lucko/luckperms/common/model/Group.java index ae92fc58f..e8c5cde06 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/Group.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/Group.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.common.model; import me.lucko.luckperms.api.context.ContextSet; -import me.lucko.luckperms.api.model.DataType; import me.lucko.luckperms.api.node.Node; import me.lucko.luckperms.api.node.types.DisplayNameNode; import me.lucko.luckperms.common.api.implementation.ApiGroup; @@ -116,7 +115,7 @@ public class Group extends PermissionHolder implements Identifiable { * @return the display name */ public Optional getDisplayName(ContextSet contextSet) { - for (Node n : getData(DataType.NORMAL).immutable().get(contextSet.immutableCopy())) { + for (Node n : normalData().immutable().get(contextSet.immutableCopy())) { if (n instanceof DisplayNameNode) { return Optional.of(((DisplayNameNode) n).getDisplayName()); } diff --git a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java index 5bb470a64..5ec87dabc 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java @@ -43,6 +43,8 @@ import me.lucko.luckperms.api.node.Tristate; import me.lucko.luckperms.api.node.types.InheritanceNode; import me.lucko.luckperms.api.query.Flag; import me.lucko.luckperms.api.query.QueryOptions; +import me.lucko.luckperms.api.query.dataorder.DataQueryOrder; +import me.lucko.luckperms.api.query.dataorder.DataQueryOrderFunction; import me.lucko.luckperms.common.cacheddata.HolderCachedDataManager; import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator; import me.lucko.luckperms.common.inheritance.InheritanceComparator; @@ -175,6 +177,10 @@ public abstract class PermissionHolder { return this.transientNodes; } + public PermissionHolderIdentifier getIdentifier() { + return new PermissionHolderIdentifier(getType(), getObjectName()); + } + /** * Gets the unique name of this holder object. * @@ -234,22 +240,43 @@ public abstract class PermissionHolder { public List getOwnNodes(QueryOptions queryOptions) { List ret = new ArrayList<>(); - this.transientNodes.copyTo(ret, queryOptions); - this.normalNodes.copyTo(ret, queryOptions); + + Comparator comparator = queryOptions.option(DataQueryOrderFunction.KEY) + .map(func -> func.getOrderComparator(getIdentifier())) + .orElse(DataQueryOrder.TRANSIENT_FIRST); + + for (DataType dataType : DataQueryOrder.order(comparator)) { + getData(dataType).copyTo(ret, queryOptions); + } + return ret; } public SortedSet getOwnNodesSorted(QueryOptions queryOptions) { SortedSet ret = new TreeSet<>(NodeWithContextComparator.reverse()); - this.transientNodes.copyTo(ret, queryOptions); - this.normalNodes.copyTo(ret, queryOptions); + + Comparator comparator = queryOptions.option(DataQueryOrderFunction.KEY) + .map(func -> func.getOrderComparator(getIdentifier())) + .orElse(DataQueryOrder.TRANSIENT_FIRST); + + for (DataType dataType : DataQueryOrder.order(comparator)) { + getData(dataType).copyTo(ret, queryOptions); + } + return ret; } public List getOwnGroupNodes(QueryOptions queryOptions) { List ret = new ArrayList<>(); - this.transientNodes.copyInheritanceNodesTo(ret, queryOptions); - this.normalNodes.copyInheritanceNodesTo(ret, queryOptions); + + Comparator comparator = queryOptions.option(DataQueryOrderFunction.KEY) + .map(func -> func.getOrderComparator(getIdentifier())) + .orElse(DataQueryOrder.TRANSIENT_FIRST); + + for (DataType dataType : DataQueryOrder.order(comparator)) { + getData(dataType).copyInheritanceNodesTo(ret, queryOptions); + } + return ret; } diff --git a/api/src/main/java/me/lucko/luckperms/api/node/metadata/NodeMetadata.java b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolderIdentifier.java similarity index 50% rename from api/src/main/java/me/lucko/luckperms/api/node/metadata/NodeMetadata.java rename to common/src/main/java/me/lucko/luckperms/common/model/PermissionHolderIdentifier.java index f46cf0aa5..49d435874 100644 --- a/api/src/main/java/me/lucko/luckperms/api/node/metadata/NodeMetadata.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolderIdentifier.java @@ -23,14 +23,49 @@ * SOFTWARE. */ -package me.lucko.luckperms.api.node.metadata; +package me.lucko.luckperms.common.model; -import me.lucko.luckperms.api.node.Node; +import me.lucko.luckperms.api.model.PermissionHolder.Identifier; -/** - * Generic interface for an {@link Object} which can be attached to a - * {@link Node} as metadata. - */ -public interface NodeMetadata { +import org.checkerframework.checker.nullness.qual.NonNull; +import java.util.Objects; + +public final class PermissionHolderIdentifier implements Identifier { + private final String type; + private final String name; + + public PermissionHolderIdentifier(String type, String name) { + this.type = type; + this.name = name; + } + + public PermissionHolderIdentifier(HolderType type, String name) { + this.type = type == HolderType.USER ? Identifier.USER_TYPE : Identifier.GROUP_TYPE; + this.name = name; + } + + @Override + public @NonNull String getName() { + return this.name; + } + + @Override + public @NonNull String getType() { + return this.type; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Identifier)) return false; + Identifier that = (Identifier) o; + return getType().equals(that.getType()) && + getName().equals(that.getName()); + } + + @Override + public int hashCode() { + return Objects.hash(getType(), getName()); + } } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/AbstractNode.java b/common/src/main/java/me/lucko/luckperms/common/node/AbstractNode.java index b55059cc3..b332e5e23 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/AbstractNode.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/AbstractNode.java @@ -33,7 +33,6 @@ import me.lucko.luckperms.api.node.Node; import me.lucko.luckperms.api.node.NodeBuilder; import me.lucko.luckperms.api.node.NodeEqualityPredicate; import me.lucko.luckperms.api.node.ScopedNode; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.RegexPermissionNode; import me.lucko.luckperms.common.node.utils.ShorthandParser; @@ -63,14 +62,14 @@ public abstract class AbstractNode, B extends NodeBui protected final boolean value; protected final long expireAt; // 0L for no expiry protected final ImmutableContextSet contexts; - protected final Map, NodeMetadata> metadata; + protected final Map, Object> metadata; private final List resolvedShorthand; // this class is immutable, so we can cache the hashcode calculation private final int hashCode; - protected AbstractNode(String key, boolean value, long expireAt, ImmutableContextSet contexts, Map, NodeMetadata> metadata) { + protected AbstractNode(String key, boolean value, long expireAt, ImmutableContextSet contexts, Map, Object> metadata) { this.key = key; this.value = value; this.expireAt = expireAt; @@ -98,7 +97,7 @@ public abstract class AbstractNode, B extends NodeBui } @Override - public Optional getMetadata(NodeMetadataKey key) { + public Optional getMetadata(NodeMetadataKey key) { //noinspection unchecked T value = (T) this.metadata.get(key); return Optional.ofNullable(value); diff --git a/common/src/main/java/me/lucko/luckperms/common/node/AbstractNodeBuilder.java b/common/src/main/java/me/lucko/luckperms/common/node/AbstractNodeBuilder.java index f5e5b4634..e2a2bf510 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/AbstractNodeBuilder.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/AbstractNodeBuilder.java @@ -30,7 +30,6 @@ import me.lucko.luckperms.api.context.DefaultContextKeys; import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.node.NodeBuilder; import me.lucko.luckperms.api.node.ScopedNode; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import org.checkerframework.checker.nullness.qual.NonNull; @@ -44,7 +43,7 @@ public abstract class AbstractNodeBuilder, B extends protected boolean value; protected long expireAt; protected ImmutableContextSet.Builder context; - protected Map, NodeMetadata> metadata; + protected Map, Object> metadata; protected AbstractNodeBuilder() { this.value = true; @@ -53,7 +52,7 @@ public abstract class AbstractNodeBuilder, B extends this.metadata = new IdentityHashMap<>(); } - protected AbstractNodeBuilder(boolean value, long expireAt, ImmutableContextSet context, Map, NodeMetadata> metadata) { + protected AbstractNodeBuilder(boolean value, long expireAt, ImmutableContextSet context, Map, Object> metadata) { this.value = value; this.expireAt = expireAt; this.context = ImmutableContextSet.builder().addAll(context); @@ -108,7 +107,7 @@ public abstract class AbstractNodeBuilder, B extends } @Override - public @NonNull B withMetadata(@NonNull NodeMetadataKey key, @Nullable T metadata) { + public @NonNull B withMetadata(@NonNull NodeMetadataKey key, @Nullable T metadata) { Objects.requireNonNull(key, "key"); if (metadata == null) { this.metadata.remove(key); diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/DisplayName.java b/common/src/main/java/me/lucko/luckperms/common/node/types/DisplayName.java index 11480e734..6554111e8 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/DisplayName.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/DisplayName.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.common.node.types; import me.lucko.luckperms.api.context.ImmutableContextSet; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.DisplayNameNode; import me.lucko.luckperms.common.node.AbstractNode; @@ -41,7 +40,7 @@ import java.util.Objects; public class DisplayName extends AbstractNode implements DisplayNameNode { private final String displayName; - public DisplayName(String displayName, boolean value, long expireAt, ImmutableContextSet contexts, Map, NodeMetadata> metadata) { + public DisplayName(String displayName, boolean value, long expireAt, ImmutableContextSet contexts, Map, Object> metadata) { super(NodeFactory.displayName(displayName), value, expireAt, contexts, metadata); this.displayName = displayName; } @@ -63,7 +62,7 @@ public class DisplayName extends AbstractNode, NodeMetadata> metadata) { + public Builder(String displayName, boolean value, long expireAt, ImmutableContextSet context, Map, Object> metadata) { super(value, expireAt, context, metadata); this.displayName = displayName; } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/Inheritance.java b/common/src/main/java/me/lucko/luckperms/common/node/types/Inheritance.java index f84ca37e2..0bfc33c1a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/Inheritance.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/Inheritance.java @@ -27,7 +27,6 @@ package me.lucko.luckperms.common.node.types; import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.model.group.Group; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.InheritanceNode; import me.lucko.luckperms.common.node.AbstractNode; @@ -42,7 +41,7 @@ import java.util.Objects; public class Inheritance extends AbstractNode implements InheritanceNode { private final String groupName; - public Inheritance(String groupName, boolean value, long expireAt, ImmutableContextSet contexts, Map, NodeMetadata> metadata) { + public Inheritance(String groupName, boolean value, long expireAt, ImmutableContextSet contexts, Map, Object> metadata) { super(NodeFactory.groupNode(groupName), value, expireAt, contexts, metadata); this.groupName = groupName; } @@ -64,7 +63,7 @@ public class Inheritance extends AbstractNode, NodeMetadata> metadata) { + public Builder(String groupName, boolean value, long expireAt, ImmutableContextSet context, Map, Object> metadata) { super(value, expireAt, context, metadata); this.groupName = groupName; } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/Meta.java b/common/src/main/java/me/lucko/luckperms/common/node/types/Meta.java index b9238de1a..83b6f9955 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/Meta.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/Meta.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.common.node.types; import me.lucko.luckperms.api.context.ImmutableContextSet; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.MetaNode; import me.lucko.luckperms.common.node.AbstractNode; @@ -42,7 +41,7 @@ public class Meta extends AbstractNode implements Me private final String metaKey; private final String metaValue; - public Meta(String metaKey, String metaValue, boolean value, long expireAt, ImmutableContextSet contexts, Map, NodeMetadata> metadata) { + public Meta(String metaKey, String metaValue, boolean value, long expireAt, ImmutableContextSet contexts, Map, Object> metadata) { super(NodeFactory.metaNode(metaKey, metaValue), value, expireAt, contexts, metadata); this.metaKey = metaKey; this.metaValue = metaValue; @@ -72,7 +71,7 @@ public class Meta extends AbstractNode implements Me this.metaValue = null; } - public Builder(String metaKey, String metaValue, boolean value, long expireAt, ImmutableContextSet context, Map, NodeMetadata> metadata) { + public Builder(String metaKey, String metaValue, boolean value, long expireAt, ImmutableContextSet context, Map, Object> metadata) { super(value, expireAt, context, metadata); this.metaKey = metaKey; this.metaValue = metaValue; diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/Permission.java b/common/src/main/java/me/lucko/luckperms/common/node/types/Permission.java index f0491581e..a5032898c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/Permission.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/Permission.java @@ -27,7 +27,6 @@ package me.lucko.luckperms.common.node.types; import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.node.NodeBuilder; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.PermissionNode; import me.lucko.luckperms.common.calculator.processor.WildcardProcessor; @@ -44,7 +43,7 @@ import java.util.OptionalInt; public class Permission extends AbstractNode implements PermissionNode { private final int wildcardLevel; - public Permission(String permission, boolean value, long expireAt, ImmutableContextSet contexts, Map, NodeMetadata> metadata) { + public Permission(String permission, boolean value, long expireAt, ImmutableContextSet contexts, Map, Object> metadata) { super(permission, value, expireAt, contexts, metadata); this.wildcardLevel = permission.endsWith(WildcardProcessor.WILDCARD_SUFFIX) ? permission.chars().filter(num -> num == NODE_SEPARATOR_CODE).sum() : -1; } @@ -76,7 +75,7 @@ public class Permission extends AbstractNode, NodeMetadata> metadata) { + public Builder(String permission, boolean value, long expireAt, ImmutableContextSet context, Map, Object> metadata) { super(value, expireAt, context, metadata); this.permission = permission; } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/Prefix.java b/common/src/main/java/me/lucko/luckperms/common/node/types/Prefix.java index a0c5a5622..a49200c3a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/Prefix.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/Prefix.java @@ -27,7 +27,6 @@ package me.lucko.luckperms.common.node.types; import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.node.ChatMetaType; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.PrefixNode; import me.lucko.luckperms.common.node.AbstractNode; @@ -43,7 +42,7 @@ public class Prefix extends AbstractNode impleme private final String prefix; private final int priority; - public Prefix(String prefix, int priority, boolean value, long expireAt, ImmutableContextSet contexts, Map, NodeMetadata> metadata) { + public Prefix(String prefix, int priority, boolean value, long expireAt, ImmutableContextSet contexts, Map, Object> metadata) { super(NodeFactory.prefixNode(priority, prefix), value, expireAt, contexts, metadata); this.prefix = prefix; this.priority = priority; @@ -78,7 +77,7 @@ public class Prefix extends AbstractNode impleme this.priority = null; } - public Builder(String prefix, int priority, boolean value, long expireAt, ImmutableContextSet context, Map, NodeMetadata> metadata) { + public Builder(String prefix, int priority, boolean value, long expireAt, ImmutableContextSet context, Map, Object> metadata) { super(value, expireAt, context, metadata); this.prefix = prefix; this.priority = priority; diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/RegexPermission.java b/common/src/main/java/me/lucko/luckperms/common/node/types/RegexPermission.java index a4fed047d..dda4b4d3e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/RegexPermission.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/RegexPermission.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.common.node.types; import me.lucko.luckperms.api.context.ImmutableContextSet; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.RegexPermissionNode; import me.lucko.luckperms.common.cache.Cache; @@ -52,7 +51,7 @@ public class RegexPermission extends AbstractNode, NodeMetadata> metadata) { + public RegexPermission(String pattern, boolean value, long expireAt, ImmutableContextSet contexts, Map, Object> metadata) { super(NodeFactory.regexNode(pattern), value, expireAt, contexts, metadata); this.pattern = pattern; } @@ -79,7 +78,7 @@ public class RegexPermission extends AbstractNode, NodeMetadata> metadata) { + public Builder(String pattern, boolean value, long expireAt, ImmutableContextSet context, Map, Object> metadata) { super(value, expireAt, context, metadata); this.pattern = pattern; } diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/Suffix.java b/common/src/main/java/me/lucko/luckperms/common/node/types/Suffix.java index 800625af5..7d96a5594 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/Suffix.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/Suffix.java @@ -27,7 +27,6 @@ package me.lucko.luckperms.common.node.types; import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.node.ChatMetaType; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.SuffixNode; import me.lucko.luckperms.common.node.AbstractNode; @@ -43,7 +42,7 @@ public class Suffix extends AbstractNode impleme private final String suffix; private final int priority; - public Suffix(String suffix, int priority, boolean value, long expireAt, ImmutableContextSet contexts, Map, NodeMetadata> metadata) { + public Suffix(String suffix, int priority, boolean value, long expireAt, ImmutableContextSet contexts, Map, Object> metadata) { super(NodeFactory.suffixNode(priority, suffix), value, expireAt, contexts, metadata); this.suffix = suffix; this.priority = priority; @@ -78,7 +77,7 @@ public class Suffix extends AbstractNode impleme this.priority = null; } - public Builder(String suffix, int priority, boolean value, long expireAt, ImmutableContextSet context, Map, NodeMetadata> metadata) { + public Builder(String suffix, int priority, boolean value, long expireAt, ImmutableContextSet context, Map, Object> metadata) { super(value, expireAt, context, metadata); this.suffix = suffix; this.priority = priority; diff --git a/common/src/main/java/me/lucko/luckperms/common/node/types/Weight.java b/common/src/main/java/me/lucko/luckperms/common/node/types/Weight.java index 84a989395..8b4eb2de4 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/types/Weight.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/types/Weight.java @@ -26,7 +26,6 @@ package me.lucko.luckperms.common.node.types; import me.lucko.luckperms.api.context.ImmutableContextSet; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.node.types.WeightNode; import me.lucko.luckperms.common.node.AbstractNode; @@ -41,7 +40,7 @@ import java.util.Objects; public class Weight extends AbstractNode implements WeightNode { private final int weight; - public Weight(int weight, boolean value, long expireAt, ImmutableContextSet contexts, Map, NodeMetadata> metadata) { + public Weight(int weight, boolean value, long expireAt, ImmutableContextSet contexts, Map, Object> metadata) { super(NodeFactory.weightNode(weight), value, expireAt, contexts, metadata); this.weight = weight; } @@ -63,7 +62,7 @@ public class Weight extends AbstractNode impleme this.weight = null; } - public Builder(int weight, boolean value, long expireAt, ImmutableContextSet context, Map, NodeMetadata> metadata) { + public Builder(int weight, boolean value, long expireAt, ImmutableContextSet context, Map, Object> metadata) { super(value, expireAt, context, metadata); this.weight = weight; } diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LPPermissionAttachment.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LPPermissionAttachment.java index 19a1b77ff..a0dff759e 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LPPermissionAttachment.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/inject/permissible/LPPermissionAttachment.java @@ -29,7 +29,6 @@ import com.google.common.base.Preconditions; import me.lucko.luckperms.api.model.DataType; import me.lucko.luckperms.api.node.Node; -import me.lucko.luckperms.api.node.metadata.NodeMetadata; import me.lucko.luckperms.api.node.metadata.NodeMetadataKey; import me.lucko.luckperms.api.util.Result; import me.lucko.luckperms.common.config.ConfigKeys; @@ -56,7 +55,7 @@ import java.util.Set; * * Applies all permissions directly to the backing user instance via transient nodes. */ -public class LPPermissionAttachment extends PermissionAttachment implements NodeMetadata { +public class LPPermissionAttachment extends PermissionAttachment { public static final NodeMetadataKey TRANSIENT_SOURCE_KEY = NodeMetadataKey.of("TransientSource", LPPermissionAttachment.class); diff --git a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectCollection.java b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectCollection.java index cac1e073c..3eaad59ab 100644 --- a/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectCollection.java +++ b/sponge/sponge-service/src/main/java/me/lucko/luckperms/sponge/service/model/LPSubjectCollection.java @@ -30,6 +30,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import me.lucko.luckperms.api.context.ImmutableContextSet; +import me.lucko.luckperms.api.query.dataorder.DataQueryOrder; import org.spongepowered.api.service.permission.SubjectCollection; @@ -52,11 +53,11 @@ public interface LPSubjectCollection { Predicate getIdentifierValidityPredicate(); // transient has priority for all collections except default - default ResolutionOrder getResolutionOrder() { + default DataQueryOrder getResolutionOrder() { if (isDefaultsCollection()) { - return ResolutionOrder.TRANSIENT_LAST; + return DataQueryOrder.TRANSIENT_LAST; } else { - return ResolutionOrder.TRANSIENT_FIRST; + return DataQueryOrder.TRANSIENT_FIRST; } } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubjectData.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubjectData.java index 945579000..cc82d5a24 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubjectData.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/model/permissionholder/PermissionHolderSubjectData.java @@ -29,7 +29,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import me.lucko.luckperms.api.context.ImmutableContextSet; -import me.lucko.luckperms.api.model.DataMutateResult; import me.lucko.luckperms.api.model.DataType; import me.lucko.luckperms.api.node.ChatMetaType; import me.lucko.luckperms.api.node.Node; @@ -58,11 +57,9 @@ import org.spongepowered.api.service.permission.SubjectData; import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; import java.util.stream.Stream; public class PermissionHolderSubjectData implements LPSubjectData { @@ -129,54 +126,20 @@ public class PermissionHolderSubjectData implements LPSubjectData { if (tristate == Tristate.UNDEFINED) { // Unset Node node = NodeFactory.builder(permission).withContext(contexts).build(); - switch (this.type) { - case NORMAL: - this.holder.unsetPermission(DataType.NORMAL, node); - break; - case TRANSIENT: - this.holder.unsetPermission(DataType.TRANSIENT, node); - break; - default: - throw new AssertionError(); - } + this.holder.unsetPermission(this.type, node); return save(this.holder).thenApply(v -> true); } Node node = NodeFactory.builder(permission).value(tristate.asBoolean()).withContext(contexts).build(); // unset the inverse, to allow false -> true, true -> false overrides. - // unset the inverse, to allow false -> true, true -> false overrides. - switch (this.type) { - case NORMAL: - // unset the inverse, to allow false -> true, true -> false overrides. - this.holder.unsetPermission(DataType.NORMAL, node); - this.holder.setPermission(DataType.NORMAL, node, true); - break; - case TRANSIENT: - // unset the inverse, to allow false -> true, true -> false overrides. - this.holder.unsetPermission(DataType.TRANSIENT, node); - this.holder.setPermission(DataType.TRANSIENT, node, true); - break; - default: - throw new AssertionError(); - } + this.holder.unsetPermission(this.type, node); + this.holder.setPermission(this.type, node, true); return save(this.holder).thenApply(v -> true); } @Override public CompletableFuture clearPermissions() { - boolean ret; - switch (this.type) { - case NORMAL: - ret = this.holder.clearNodes(DataType.NORMAL, null); - break; - case TRANSIENT: - ret = this.holder.clearNodes(DataType.TRANSIENT, null); - break; - default: - throw new AssertionError(); - } - - if (!ret) { + if (!this.holder.clearNodes(this.type, null)) { return CompletableFuture.completedFuture(false); } @@ -190,24 +153,7 @@ public class PermissionHolderSubjectData implements LPSubjectData { @Override public CompletableFuture clearPermissions(ImmutableContextSet contexts) { Objects.requireNonNull(contexts, "contexts"); - boolean ret; - switch (this.type) { - case NORMAL: - ret = this.holder.clearNodes(DataType.NORMAL, contexts); - break; - case TRANSIENT: - List toRemove = streamNodes() - .filter(n -> n.getContexts().equals(contexts)) - .collect(Collectors.toList()); - - toRemove.forEach(node -> this.holder.unsetPermission(DataType.TRANSIENT, node)); - ret = !toRemove.isEmpty(); - break; - default: - throw new AssertionError(); - } - - if (!ret) { + if (!this.holder.clearNodes(this.type, contexts)) { return CompletableFuture.completedFuture(false); } @@ -257,19 +203,7 @@ public class PermissionHolderSubjectData implements LPSubjectData { .withContext(contexts) .build(); - DataMutateResult result; - switch (this.type) { - case NORMAL: - result = this.holder.setPermission(DataType.NORMAL, node, true); - break; - case TRANSIENT: - result = this.holder.setPermission(DataType.TRANSIENT, node, true); - break; - default: - throw new AssertionError(); - } - - if (!result.wasSuccessful()) { + if (!this.holder.setPermission(this.type, node, true).wasSuccessful()) { return CompletableFuture.completedFuture(false); } @@ -289,19 +223,7 @@ public class PermissionHolderSubjectData implements LPSubjectData { .withContext(contexts) .build(); - DataMutateResult result; - switch (this.type) { - case NORMAL: - result = this.holder.unsetPermission(DataType.NORMAL, node); - break; - case TRANSIENT: - result = this.holder.unsetPermission(DataType.TRANSIENT, node); - break; - default: - throw new AssertionError(); - } - - if (!result.wasSuccessful()) { + if (!this.holder.unsetPermission(this.type, node).wasSuccessful()) { return CompletableFuture.completedFuture(false); } @@ -316,12 +238,10 @@ public class PermissionHolderSubjectData implements LPSubjectData { ret = this.holder.clearNormalParents(null, true); break; case TRANSIENT: - List toRemove = streamNodes() + ret = streamNodes() .filter(n -> n instanceof InheritanceNode) - .collect(Collectors.toList()); - - toRemove.forEach(node -> this.holder.unsetPermission(DataType.TRANSIENT, node)); - ret = !toRemove.isEmpty(); + .peek(n -> this.holder.unsetPermission(DataType.TRANSIENT, n)) + .findAny().isPresent(); break; default: throw new AssertionError(); @@ -343,13 +263,11 @@ public class PermissionHolderSubjectData implements LPSubjectData { ret = this.holder.clearNormalParents(contexts, true); break; case TRANSIENT: - List toRemove = streamNodes() + ret = streamNodes() .filter(n -> n instanceof InheritanceNode) .filter(n -> n.getContexts().equals(contexts)) - .collect(Collectors.toList()); - - toRemove.forEach(node -> this.holder.unsetPermission(DataType.TRANSIENT, node)); - ret = !toRemove.isEmpty(); + .peek(n -> this.holder.unsetPermission(DataType.TRANSIENT, n)) + .findAny().isPresent(); break; default: throw new AssertionError(); @@ -425,20 +343,9 @@ public class PermissionHolderSubjectData implements LPSubjectData { // remove all prefixes/suffixes from the user streamNodes() - .filter(node1 -> type.nodeType().matches(node1)) + .filter(n -> type.nodeType().matches(n)) .filter(n -> n.getContexts().equals(contexts)) - .forEach(n -> { - switch (this.type) { - case NORMAL: - this.holder.unsetPermission(DataType.NORMAL, n); - break; - case TRANSIENT: - this.holder.unsetPermission(DataType.TRANSIENT, n); - break; - default: - throw new AssertionError(); - } - }); + .forEach(n -> this.holder.unsetPermission(this.type, n)); MetaAccumulator metaAccumulator = this.holder.accumulateMeta(null, QueryOptions.defaultContextualOptions().toBuilder().context(contexts).build()); metaAccumulator.complete(); @@ -451,32 +358,12 @@ public class PermissionHolderSubjectData implements LPSubjectData { streamNodes() .filter(n -> n instanceof MetaNode && ((MetaNode) n).getMetaKey().equals(key)) .filter(n -> n.getContexts().equals(contexts)) - .forEach(n -> { - switch (this.type) { - case NORMAL: - this.holder.unsetPermission(DataType.NORMAL, n); - break; - case TRANSIENT: - this.holder.unsetPermission(DataType.TRANSIENT, n); - break; - default: - throw new AssertionError(); - } - }); + .forEach(n -> this.holder.unsetPermission(this.type, n)); node = NodeFactory.buildMetaNode(key, value).withContext(contexts).build(); } - switch (this.type) { - case NORMAL: - this.holder.setPermission(DataType.NORMAL, node, true); - break; - case TRANSIENT: - this.holder.setPermission(DataType.TRANSIENT, node, true); - break; - default: - throw new AssertionError(); - } + this.holder.setPermission(this.type, node, true); return save(this.holder).thenApply(v -> true); } @@ -496,18 +383,7 @@ public class PermissionHolderSubjectData implements LPSubjectData { } }) .filter(n -> n.getContexts().equals(contexts)) - .forEach(node -> { - switch (this.type) { - case NORMAL: - this.holder.unsetPermission(DataType.NORMAL, node); - break; - case TRANSIENT: - this.holder.unsetPermission(DataType.TRANSIENT, node); - break; - default: - throw new AssertionError(); - } - }); + .forEach(n -> this.holder.unsetPermission(this.type, n)); return save(this.holder).thenApply(v -> true); } @@ -516,25 +392,13 @@ public class PermissionHolderSubjectData implements LPSubjectData { public CompletableFuture clearOptions(ImmutableContextSet contexts) { Objects.requireNonNull(contexts, "contexts"); - List toRemove = streamNodes() + boolean success = streamNodes() .filter(NodeType.META_OR_CHAT_META::matches) .filter(n -> n.getContexts().equals(contexts)) - .collect(Collectors.toList()); + .peek(n -> this.holder.unsetPermission(this.type, n)) + .findAny().isPresent(); - toRemove.forEach(node -> { - switch (this.type) { - case NORMAL: - this.holder.unsetPermission(DataType.NORMAL, node); - break; - case TRANSIENT: - this.holder.unsetPermission(DataType.TRANSIENT, node); - break; - default: - throw new AssertionError(); - } - }); - - if (toRemove.isEmpty()) { + if (!success) { return CompletableFuture.completedFuture(false); } @@ -543,24 +407,12 @@ public class PermissionHolderSubjectData implements LPSubjectData { @Override public CompletableFuture clearOptions() { - List toRemove = streamNodes() + boolean success = streamNodes() .filter(NodeType.META_OR_CHAT_META::matches) - .collect(Collectors.toList()); + .peek(n -> this.holder.unsetPermission(this.type, n)) + .findAny().isPresent(); - toRemove.forEach(node -> { - switch (this.type) { - case NORMAL: - this.holder.unsetPermission(DataType.NORMAL, node); - break; - case TRANSIENT: - this.holder.unsetPermission(DataType.TRANSIENT, node); - break; - default: - throw new AssertionError(); - } - }); - - if (toRemove.isEmpty()) { + if (!success) { return CompletableFuture.completedFuture(false); }