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 super DataType> 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 super DataType> comparator, @NonNull Consumer super DataType> 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);
}