mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2026-11-12 23:37:28 +00:00
Allow data query order to be specified via the API
This commit is contained in:
31 files changed
+345
-280
No files matched your search
@@ -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.
|
||||
|
||||
@@ -57,34 +57,64 @@ import java.util.function.Predicate;
|
||||
public interface PermissionHolder {
|
||||
|
||||
/**
|
||||
* Gets the objects generic name.
|
||||
*
|
||||
* <p>The result of this method is guaranteed to be a unique identifier for distinct instances
|
||||
* of the same type of object.</p>
|
||||
*
|
||||
* <p>For {@link User}s, this method returns a {@link UUID#toString() string} representation of
|
||||
* the users {@link User#getUniqueId() unique id}.</p>
|
||||
*
|
||||
* <p>For {@link Group}s, this method returns the {@link Group#getName() group name}.</p>
|
||||
*
|
||||
* <p>The {@link User#getUniqueId()}, {@link User#getUsername()} and {@link Group#getName()} methods
|
||||
* define a "tighter" specification for obtaining object identifiers.</p>
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* <p>The result of this method is guaranteed to be a unique identifier for distinct instances
|
||||
* of the same type of object.</p>
|
||||
*
|
||||
* <p>For {@link User}s, this method returns a {@link UUID#toString() string} representation of
|
||||
* the users {@link User#getUniqueId() unique id}.</p>
|
||||
*
|
||||
* <p>For {@link Group}s, this method returns the {@link Group#getName() group name}.</p>
|
||||
*
|
||||
* <p>The {@link User#getUniqueId()}, {@link User#getUsername()} and {@link Group#getName()} methods
|
||||
* define a "tighter" specification for obtaining object identifiers.</p>
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* <p>This will <strong>always</strong> return a value, eventually falling back to
|
||||
* {@link #getObjectName()} if no other "friendlier" identifiers are present.</p>
|
||||
* {@link Identifier#getName()} if no other "friendlier" identifiers are present.</p>
|
||||
*
|
||||
* <p>For {@link User}s, this method will attempt to return the {@link User#getUsername() username},
|
||||
* before falling back to {@link #getObjectName()}.</p>
|
||||
* before falling back to {@link Identifier#getName()}.</p>
|
||||
*
|
||||
* <p>For {@link Group}s, this method will attempt to return the groups display name, before
|
||||
* falling back to {@link #getObjectName()}.</p>
|
||||
* falling back to {@link Identifier#getName()}.</p>
|
||||
*
|
||||
* @return a friendly identifier for this holder
|
||||
*/
|
||||
|
||||
@@ -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 <code>key</code>, if present.
|
||||
*
|
||||
* @param key the key
|
||||
* @param <T> the {@link NodeMetadata} type
|
||||
* @param <T> the metadata type
|
||||
* @return the data, if present
|
||||
*/
|
||||
<T extends NodeMetadata> Optional<T> getMetadata(NodeMetadataKey<T> key);
|
||||
<T> Optional<T> getMetadata(NodeMetadataKey<T> key);
|
||||
|
||||
/**
|
||||
* Gets the metadata corresponding to the given <code>key</code>, throwing an exception
|
||||
* if no data is present.
|
||||
*
|
||||
* @param key the key
|
||||
* @param <T> the {@link NodeMetadata} type
|
||||
* @param <T> the metadata type
|
||||
* @return the data
|
||||
* @throws IllegalStateException if data isn't present
|
||||
*/
|
||||
default <T extends NodeMetadata> T metadata(NodeMetadataKey<T> key) throws IllegalStateException {
|
||||
default <T> T metadata(NodeMetadataKey<T> key) throws IllegalStateException {
|
||||
return getMetadata(key).orElseThrow(() -> new IllegalStateException("Node '" + getKey() + "' does not have '" + key.name() + "' attached."));
|
||||
}
|
||||
|
||||
|
||||
@@ -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<N extends ScopedNode<N, B>, B extends NodeBuilder<N
|
||||
* @param <T> the metadata type
|
||||
* @return the builder
|
||||
*/
|
||||
@NonNull <T extends NodeMetadata> B withMetadata(@NonNull NodeMetadataKey<T> key, @Nullable T metadata);
|
||||
@NonNull <T> B withMetadata(@NonNull NodeMetadataKey<T> key, @Nullable T metadata);
|
||||
|
||||
/**
|
||||
* Creates a {@link Node} instance from the builder.
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <p>Metadata keys are compared using reference equality, the
|
||||
* {@link #equals(Object)} method should not be implemented.</p>
|
||||
@@ -43,7 +43,7 @@ import java.util.Objects;
|
||||
*
|
||||
* @param <T> the metadata type
|
||||
*/
|
||||
public interface NodeMetadataKey<T extends NodeMetadata> {
|
||||
public interface NodeMetadataKey<T> {
|
||||
|
||||
/**
|
||||
* Creates a new {@link NodeMetadataKey} for the given name and type.
|
||||
@@ -55,7 +55,7 @@ public interface NodeMetadataKey<T extends NodeMetadata> {
|
||||
* @param <T> the type parameter
|
||||
* @return the key
|
||||
*/
|
||||
static <T extends NodeMetadata> @NonNull NodeMetadataKey<T> of(@NonNull String name, @NonNull Class<T> type) {
|
||||
static <T> @NonNull NodeMetadataKey<T> of(@NonNull String name, @NonNull Class<T> type) {
|
||||
Objects.requireNonNull(name, "name");
|
||||
Objects.requireNonNull(type, "type");
|
||||
return new SimpleNodeMetadataKey<>(name, type);
|
||||
|
||||
@@ -27,7 +27,7 @@ package me.lucko.luckperms.api.node.metadata;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
final class SimpleNodeMetadataKey<T extends NodeMetadata> implements NodeMetadataKey<T> {
|
||||
final class SimpleNodeMetadataKey<T> implements NodeMetadataKey<T> {
|
||||
private final String name;
|
||||
private final Class<T> type;
|
||||
|
||||
|
||||
+4
-5
@@ -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.
|
||||
*
|
||||
* <p>The resultant string is the {@link PermissionHolder#getObjectName() object name} of the
|
||||
* <p>The resultant string is the {@link PermissionHolder.Identifier#getName() object name} of the
|
||||
* permission holder the node was inherited from.</p>
|
||||
*
|
||||
* <p>If the node was not inherited, the {@link PermissionHolder#getObjectName() object name}
|
||||
* <p>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.</p>
|
||||
*
|
||||
* @return where the node was inherited from.
|
||||
|
||||
@@ -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<Flag> DEFAULT_FLAGS = EnumSet.allOf(Flag.class);
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* 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.
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*/
|
||||
public enum DataQueryOrder implements Comparator<DataType> {
|
||||
|
||||
/**
|
||||
* 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<DataType> TRANSIENT_FIRST_LIST = Collections.unmodifiableList(Arrays.asList(DataType.TRANSIENT, DataType.NORMAL));
|
||||
private static final List<DataType> 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<DataType> 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);
|
||||
}
|
||||
|
||||
}
|
||||
+25
-5
@@ -23,14 +23,34 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.api.node.metadata;
|
||||
package me.lucko.luckperms.api.query.dataorder;
|
||||
|
||||
import me.lucko.luckperms.api.node.Node;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Generic interface for an {@link Object} which can be attached to a
|
||||
* {@link Node} as metadata.
|
||||
* A function that generates a {@link DataQueryOrder} comparator for
|
||||
* {@link PermissionHolder}s as required during inheritance.
|
||||
*/
|
||||
public interface NodeMetadata {
|
||||
public interface DataQueryOrderFunction {
|
||||
|
||||
/**
|
||||
* The {@link OptionKey} for {@link DataQueryOrderFunction}.
|
||||
*/
|
||||
OptionKey<DataQueryOrderFunction> KEY = new OptionKey<DataQueryOrderFunction>(){};
|
||||
|
||||
/**
|
||||
* Gets the {@link DataQueryOrder} comparator for the given
|
||||
* {@link PermissionHolder.Identifier holder identifier}.
|
||||
*
|
||||
* @param holderIdentifier the holder identifier
|
||||
* @return the comparator to use
|
||||
*/
|
||||
@NonNull Comparator<DataType> getOrderComparator(PermissionHolder.@NonNull Identifier holderIdentifier);
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user