A few API javadoc improvements

This commit is contained in:
Luck 2018-07-27 23:45:16 -07:00
parent ae3adf23c8
commit 952e41ad3d
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
15 changed files with 404 additions and 132 deletions

View File

@ -26,10 +26,12 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.caching.GroupData;
import me.lucko.luckperms.api.context.ContextSet;
import java.util.OptionalInt;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* An inheritable holder of permission data.
@ -44,6 +46,33 @@ public interface Group extends PermissionHolder {
@Nonnull
String getName();
/**
* Gets the groups "display name", if it has one that differs from it's actual name.
*
* <p>The lookup is made using the current servers active context.</p>
*
* <p>Will return <code>null</code> if the groups display name is equal to it's
* {@link #getName() actual name}.</p>
*
* @return the display name
* @since 4.3
*/
@Nullable
String getDisplayName();
/**
* Gets the groups "display name", if it has one that differs from it's actual name.
*
* <p>Will return <code>null</code> if the groups display name is equal to it's
* {@link #getName() actual name}.</p>
*
* @param contextSet the contexts to lookup in
* @return the display name
* @since 4.3
*/
@Nullable
String getDisplayName(@Nonnull ContextSet contextSet);
/**
* Gets the weight of this group, if present.
*

View File

@ -25,13 +25,12 @@
package me.lucko.luckperms.api;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.concurrent.Immutable;
/**
* A node with a traceable origin
* An extension of {@link Node}, providing information about
* where the node originated from.
*
* @since 2.11
*/
@ -39,19 +38,9 @@ import javax.annotation.concurrent.Immutable;
public interface LocalizedNode extends Node {
/**
* Returns a predicate which unwraps the localised node parameter before delegating
* the handling to the provided predicate.
* Gets the delegate node.
*
* @param delegate the delegate predicate.
* @return the composed predicate
* @since 4.3
*/
static Predicate<? super LocalizedNode> composedPredicate(Predicate<Node> delegate) {
return localizedNode -> delegate.test(localizedNode.getNode());
}
/**
* Gets the delegate node
* <p>Result is never another {@link LocalizedNode} instance.</p>
*
* @return the node this instance is representing
*/
@ -59,10 +48,15 @@ public interface LocalizedNode extends Node {
Node getNode();
/**
* Gets the location where the {@link Node} is inherited from
* Gets the location where the {@link Node} is inherited from.
*
* @return where the node was inherited from. Will not return null.
* @see PermissionHolder#getObjectName()
* <p>The resultant string is the {@link PermissionHolder#getObjectName() 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}
* of the permission holder itself (the one that defined the node) will be returned.</p>
*
* @return where the node was inherited from.
*/
@Nonnull
String getLocation();

View File

@ -33,8 +33,7 @@ import javax.annotation.Nonnull;
* <p>Generally, individual instances of this interface should fulfil the same
* requirements as the {@link Object#equals(Object)} contract.</p>
*
* <p>Some standard implementations are provided by
* {@link StandardNodeEquality}.</p>
* <p>Some standard implementations are provided by {@link StandardNodeEquality}.</p>
*
* @since 4.1
*/

View File

@ -31,29 +31,40 @@ import com.google.common.collect.Multimap;
import me.lucko.luckperms.api.caching.CachedData;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.manager.GroupManager;
import me.lucko.luckperms.api.manager.UserManager;
import me.lucko.luckperms.api.nodetype.types.MetaType;
import me.lucko.luckperms.api.nodetype.types.PrefixType;
import me.lucko.luckperms.api.nodetype.types.SuffixType;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
/**
* An object which holds permissions.
*
* <p>Any changes made to permission holding objects will be lost unless the
* instance is saved back to the {@link Storage}.</p>
* Generic superinterface for an object which holds permissions.
*/
public interface PermissionHolder {
/**
* Gets the objects name.
* Gets the objects generic name.
*
* <p>{@link User#getUuid()}, {@link User#getName()} or {@link Group#getName()} should normally be used instead of
* this method.</p>
* <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#getUuid() unique id}.</p>
*
* <p>For {@link Group}s, this method returns the {@link Group#getName() group name}.</p>
*
* <p>The {@link User#getUuid()}, {@link User#getName()} 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.
*/
@ -63,8 +74,14 @@ public interface PermissionHolder {
/**
* 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>
* <p>This will <strong>always</strong> return a value, eventually falling back to
* {@link #getObjectName()} if no other "friendlier" identifiers are present.</p>
*
* <p>For {@link User}s, this method will attempt to return the {@link User#getName() username},
* before falling back to {@link #getObjectName()}.</p>
*
* <p>For {@link Group}s, this method will attempt to return the groups display name, before
* falling back to {@link #getObjectName()}.</p>
*
* @return a friendly identifier for this holder
* @since 3.2
@ -128,6 +145,8 @@ public interface PermissionHolder {
*
* <p>Use {@link #getPermissions()} for a view without duplicates.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* @return a list of the holders own nodes.
* @since 3.3
*/
@ -137,6 +156,13 @@ public interface PermissionHolder {
/**
* Gets a sorted set of all held permissions.
*
* <p>Effectively a sorted version of {@link #getOwnNodes()}, without duplicates. Use the
* aforementioned method if you don't require either of these attributes.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getPermissions, it will actually return all types of node.</p>
*
* @return an immutable set of permissions in priority order
* @since 2.6
*/
@ -144,9 +170,16 @@ public interface PermissionHolder {
SortedSet<? extends Node> getPermissions();
/**
* Similar to {@link #getPermissions()}, except without transient permissions.
* Similar to {@link #getPermissions()}, except only including permissions from the enduring
* node map. (See {@link #getNodes()})
*
* <p>Unlike transient permissions, enduring permissions will be saved to storage, and exist after the session.</p>
* <p>Unlike transient permissions, enduring permissions will be saved to storage, and exist
* after the session.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getEnduringPermissions, it will actually return all types
* of node.</p>
*
* @return a set of nodes
* @since 2.6
@ -155,10 +188,16 @@ public interface PermissionHolder {
Set<? extends Node> getEnduringPermissions();
/**
* Similar to {@link #getPermissions()}, except without enduring permissions.
* Similar to {@link #getPermissions()}, except only including permissions from the enduring
* node map. (See {@link #getTransientNodes()})
*
* <p>Transient permissions only exist for the duration of the session.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getTransientPermissions, it will actually return all types
* of node.</p>
*
* @return a set of nodes
* @since 2.6
*/
@ -166,7 +205,14 @@ public interface PermissionHolder {
Set<? extends Node> getTransientPermissions();
/**
* Processes the nodes and returns the non-temporary ones.
* A filtered view of this holders nodes, only including permanent entries.
*
* <p>Data is sourced from {@link #getOwnNodes()}, filtered, and then collected to a set.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getPermanentPermissionNodes, it will actually return all types
* of node.</p>
*
* @return a set of permanent nodes
* @since 2.6
@ -175,7 +221,14 @@ public interface PermissionHolder {
Set<Node> getPermanentPermissionNodes();
/**
* Processes the nodes and returns the temporary ones.
* A filtered view of this holders nodes, only including temporary entries.
*
* <p>Data is sourced from {@link #getOwnNodes()}, filtered, and then collected to a set.</p>
*
* <p>This method <b>does not</b> resolve inheritance rules.</p>
*
* <p>Although this method is named getTemporaryPermissionNodes, it will actually return all types
* of node.</p>
*
* @return a set of temporary nodes
* @since 2.6
@ -191,12 +244,16 @@ public interface PermissionHolder {
*
* <p>This means the list will contain duplicates.</p>
*
* <p>Inheritance is performed according to the platforms rules, and the order will vary
* depending on the accumulation order. By default, the holders own nodes are first in the list,
* with the entries from the end of the inheritance tree appearing last.</p>
*
* @param contexts the contexts for the lookup
* @return a list of nodes
* @since 3.3
*/
@Nonnull
List<LocalizedNode> resolveInheritances(Contexts contexts);
List<LocalizedNode> resolveInheritances(@Nonnull Contexts contexts);
/**
* Recursively resolves this holders permissions.
@ -209,6 +266,10 @@ public interface PermissionHolder {
* <p>Unlike {@link #resolveInheritances(Contexts)}, this method does not
* filter by context, at all.</p>
*
* <p>Inheritance is performed according to the platforms rules, and the order will vary
* depending on the accumulation order. By default, the holders own nodes are first in the list,
* with the entries from the end of the inheritance tree appearing last.</p>
*
* @return a list of nodes
* @since 3.3
*/
@ -218,13 +279,14 @@ public interface PermissionHolder {
/**
* Gets a mutable sorted set of the nodes that this object has and inherits, filtered by context
*
* <p>Unlike {@link #getAllNodesFiltered(Contexts)}, this method will not filter individual nodes. The context is only
* used to determine which groups should apply.</p>
* <p>Unlike {@link #getAllNodesFiltered(Contexts)}, this method will not filter individual
* nodes by context. The context is only used to determine which groups should apply.</p>
*
* <p>Nodes are sorted into priority order.</p>
* <p>Nodes are sorted into priority order. The order of inheritance is only important during
* the process of flattening inherited entries.</p>
*
* @param contexts the context for the lookup
* @return a mutable sorted set of permissions
* @return an immutable sorted set of permissions
* @throws NullPointerException if the context is null
* @since 2.11
*/
@ -236,9 +298,10 @@ public interface PermissionHolder {
*
* <p>Unlike {@link #getAllNodes(Contexts)}, this method does not filter by context, at all.</p>
*
* <p>Nodes are sorted into priority order.</p>
* <p>Nodes are sorted into priority order. The order of inheritance is only important during
* the process of flattening inherited entries.</p>
*
* @return a mutable sorted set of permissions
* @return an immutable sorted set of permissions
* @throws NullPointerException if the context is null
* @since 3.3
*/
@ -248,8 +311,8 @@ public interface PermissionHolder {
/**
* Gets a mutable set of the nodes that this object has and inherits, filtered by context.
*
* <p>Unlike {@link #getAllNodes(Contexts)}, this method WILL filter individual nodes, and only return ones that fully
* meet the context provided.</p>
* <p>Unlike {@link #getAllNodes(Contexts)}, this method WILL filter individual nodes,
* and only return ones that fully meet the context provided.</p>
*
* @param contexts the context for the lookup
* @return a mutable set of permissions
@ -260,22 +323,28 @@ public interface PermissionHolder {
Set<LocalizedNode> getAllNodesFiltered(@Nonnull Contexts contexts);
/**
* Converts the output of {@link #getAllNodesFiltered(Contexts)}, and expands shorthand permissions.
* Converts the output of {@link #getAllNodesFiltered(Contexts)} into string and boolean form,
* and expands shorthand permissions.
*
* @param contexts the context for the lookup
* @param lowerCase if the keys should be made lowercase whilst being exported
* @param convertToLowercase if the keys should be made lowercase whilst being exported
* @return a mutable map of permissions
*/
@Nonnull
Map<String, Boolean> exportNodes(@Nonnull Contexts contexts, boolean lowerCase);
Map<String, Boolean> exportNodes(@Nonnull Contexts contexts, boolean convertToLowercase);
/**
* Removes temporary permissions that have expired
* Removes any temporary permissions that have expired.
*
* <p>This method is called periodically by the platform, so it is only necessary to run
* if you want to guarentee that the current data is totally up-to-date.</p>
*/
void auditTemporaryPermissions();
/**
* Checks to see if the object has a certain permission
* Checks to see if the object has a certain permission.
*
* <p>Although this method is named hasPermission, it can be used for all node types.</p>
*
* @param node the node to check for
* @param equalityPredicate how to determine if a node matches
@ -287,7 +356,9 @@ public interface PermissionHolder {
Tristate hasPermission(@Nonnull Node node, @Nonnull NodeEqualityPredicate equalityPredicate);
/**
* Checks to see if the object has a certain permission
* Checks to see if the object has a certain permission.
*
* <p>Although this method is named hasTransientPermission, it can be used for all node types.</p>
*
* @param node the node to check for
* @param equalityPredicate how to determine if a node matches
@ -299,7 +370,9 @@ public interface PermissionHolder {
Tristate hasTransientPermission(@Nonnull Node node, @Nonnull NodeEqualityPredicate equalityPredicate);
/**
* Checks to see if the object inherits a certain permission
* Checks to see if the object inherits a certain permission.
*
* <p>Although this method is named inheritsPermission, it can be used for all node types.</p>
*
* @param node the node to check for
* @param equalityPredicate how to determine if a node matches
@ -311,7 +384,9 @@ public interface PermissionHolder {
Tristate inheritsPermission(@Nonnull Node node, @Nonnull NodeEqualityPredicate equalityPredicate);
/**
* Checks to see if the object has a certain permission
* Checks to see if the object has a certain permission.
*
* <p>Although this method is named hasPermission, it can be used for all node types.</p>
*
* @param node the node to check for
* @return a Tristate for the holders permission status for the node
@ -322,7 +397,9 @@ public interface PermissionHolder {
Tristate hasPermission(@Nonnull Node node);
/**
* Checks to see if the object has a certain permission
* Checks to see if the object has a certain permission.
*
* <p>Although this method is named hasTransientPermission, it can be used for all node types.</p>
*
* @param node the node to check for
* @return a Tristate for the holders permission status for the node
@ -333,7 +410,9 @@ public interface PermissionHolder {
Tristate hasTransientPermission(@Nonnull Node node);
/**
* Checks to see if the object inherits a certain permission
* Checks to see if the object inherits a certain permission.
*
* <p>Although this method is named inheritsPermission, it can be used for all node types.</p>
*
* @param node the node to check for
* @return a Tristate for the holders inheritance status for the node
@ -344,7 +423,11 @@ public interface PermissionHolder {
Tristate inheritsPermission(@Nonnull Node node);
/**
* Check to see if this holder inherits another group directly
* Check to see if this holder inherits another group in the global context.
*
* <p>"Global context" simply means an empty context set.</p>
*
* <p>This method only checks for direct inheritance - one hop up the inheritance tree.</p>
*
* @param group The group to check membership of
* @return true if the group inherits the other group
@ -355,7 +438,9 @@ public interface PermissionHolder {
boolean inheritsGroup(@Nonnull Group group);
/**
* Check to see if this holder inherits another group directly
* Check to see if this holder inherits another group.
*
* <p>This method only checks for direct inheritance - one hop up the inheritance tree.</p>
*
* @param group The group to check membership of
* @param contextSet the context set to filter by
@ -367,7 +452,20 @@ public interface PermissionHolder {
boolean inheritsGroup(@Nonnull Group group, @Nonnull ContextSet contextSet);
/**
* Sets a permission for the object
* Sets a permission node for the permission holder.
*
* <p>Although this method is named setPermission, it can be used for all node types.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param node The node to be set
* @return the result of the operation
@ -378,16 +476,20 @@ public interface PermissionHolder {
DataMutateResult setPermission(@Nonnull Node node);
/**
* Sets a transient permission for the object
* Sets a transient permission for the permission holder.
*
* <p>A transient node is a permission that does not persist.
* Whenever a user logs out of the server, or the server restarts, this permission will disappear.
* It is never saved to the datastore, and therefore will not apply on other servers.</p>
* Whenever a user logs out of the server, or the server restarts, this permission will
* disappear. It is never saved to the datastore, and therefore will not apply on other
* servers.</p>
*
* <p>This is useful if you want to temporarily set a permission for a user while they're online, but don't
* want it to persist, and have to worry about removing it when they log out.</p>
* <p>This is useful if you want to temporarily set a permission for a user while they're
* online, but don't want it to persist, and have to worry about removing it when they log
* out.</p>
*
* <p>For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}</p>
* <p>For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}.</p>
*
* <p>Although this method is named setTransientPermission, it can be used for all node types.</p>
*
* @param node The node to be set
* @return the result of the operation
@ -398,7 +500,20 @@ public interface PermissionHolder {
DataMutateResult setTransientPermission(@Nonnull Node node);
/**
* Unsets a permission for the object
* Unsets a permission for the permission holder.
*
* <p>Although this method is named unsetPermission, it can be used for all node types.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param node The node to be unset
* @return the result of the operation
@ -409,7 +524,9 @@ public interface PermissionHolder {
DataMutateResult unsetPermission(@Nonnull Node node);
/**
* Unsets a transient permission for the object
* Unsets a transient permission for the permission holder.
*
* <p>Although this method is named unsetTransientPermission, it can be used for all node types.</p>
*
* @param node The node to be unset
* @return the result of the operation
@ -420,7 +537,20 @@ public interface PermissionHolder {
DataMutateResult unsetTransientPermission(@Nonnull Node node);
/**
* Clears any nodes from the holder which pass the predicate
* Clears any nodes from the holder which pass the predicate.
*
* <p>This method only targets enduring data.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param test the predicate to test for nodes which should be removed
* @since 3.2
@ -428,7 +558,18 @@ public interface PermissionHolder {
void clearMatching(@Nonnull Predicate<Node> test);
/**
* Clears any transient nodes from the holder which pass the predicate
* Clears any transient nodes from the holder which pass the predicate.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param test the predicate to test for nodes which should be removed
* @since 3.2
@ -436,14 +577,36 @@ public interface PermissionHolder {
void clearMatchingTransient(@Nonnull Predicate<Node> test);
/**
* Clears all nodes held by the object
* Clears all nodes held by the permission holder.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @since 2.17
*/
void clearNodes();
/**
* Clears all nodes held by the object in a specific context
* Clears all nodes held by the permission holder in a specific context.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param contextSet the contexts to filter by
* @since 3.2
@ -451,14 +614,36 @@ public interface PermissionHolder {
void clearNodes(@Nonnull ContextSet contextSet);
/**
* Clears all parent groups
* Clears all parent groups.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @since 2.17
*/
void clearParents();
/**
* Clears all parent groups in a specific context
* Clears all parent groups in a specific context.
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param contextSet the contexts to filter by
* @since 3.2
@ -466,14 +651,42 @@ public interface PermissionHolder {
void clearParents(@Nonnull ContextSet contextSet);
/**
* Clears all meta held by the object
* Clears all meta held by the permission holder.
*
* <p>Meta nodes in this case, are any nodes which have a {@link MetaType}, {@link PrefixType}
* or {@link SuffixType} type.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @since 2.17
*/
void clearMeta();
/**
* Clears all meta held by the object in a specific context
* Clears all meta held by the permission holder in a specific context.
*
* <p>Meta nodes in this case, are any nodes which have a {@link MetaType}, {@link PrefixType}
* or {@link SuffixType} type.</p>
*
* <p>The effect of this mutate operation will not persist in storage unless changes are
* explicitly saved. If changes are not saved, the effect will only be observed until the next
* time the holders permission data is (re)loaded. Changes to {@link User}s should be saved
* using {@link UserManager#saveUser(User)}, and changes to {@link Group}s should be saved
* using {@link GroupManager#saveGroup(Group)}.</p>
*
* <p>Before making changes to a user or group, it may be a good idea to load a fresh copy of
* the backing data from the storage if you haven't done so already, to avoid overwriting changes
* made already. This can be done via {@link UserManager#loadUser(UUID)} or
* {@link GroupManager#loadGroup(String)} respectively.</p>
*
* @param contextSet the contexts to filter by
* @since 3.2
@ -481,12 +694,12 @@ public interface PermissionHolder {
void clearMeta(@Nonnull ContextSet contextSet);
/**
* Clears all transient permissions the holder has.
* Clears all transient nodes the permission holder has.
*/
void clearTransientNodes();
/**
* Sets a permission for the object
* Sets a permission for the permission holder.
*
* @param node The node to be set
* @return the result of the operation
@ -501,7 +714,7 @@ public interface PermissionHolder {
}
/**
* Sets a transient permission for the object
* Sets a transient permission for the permission holder.
*
* @param node The node to be set
* @return the result of the operation
@ -516,7 +729,7 @@ public interface PermissionHolder {
}
/**
* Unsets a permission for the object
* Unsets a permission for the permission holder.
*
* @param node The node to be unset
* @throws NullPointerException if the node is null
@ -531,7 +744,7 @@ public interface PermissionHolder {
}
/**
* Unsets a transient permission for the object
* Unsets a transient permission for the permission holder.
*
* @param node The node to be unset
* @throws NullPointerException if the node is null

View File

@ -25,6 +25,8 @@
package me.lucko.luckperms.api;
import me.lucko.luckperms.api.manager.UserManager;
import java.util.Set;
import java.util.UUID;
@ -34,6 +36,9 @@ import javax.annotation.Nullable;
/**
* Encapsulates the result of an operation to save uuid data about a player.
*
* <p>The corresponding method can be found at
* {@link UserManager#savePlayerData(UUID, String)}.</p>
*
* @since 4.2
*/
public interface PlayerSaveResult {

View File

@ -48,7 +48,7 @@ public interface User extends PermissionHolder {
/**
* Gets the users username
*
* <p>Returns null if no username is associated with this user.</p>
* <p>Returns null if no username is known for the user.</p>
*
* @return the users username
*/
@ -58,8 +58,9 @@ public interface User extends PermissionHolder {
/**
* Gets the users current primary group.
*
* <p>The result of this method depends on which method is configured for primary group calculation. It may not
* be the same as any value set through {@link #setPrimaryGroup(String)}.</p>
* <p>The result of this method depends on which method is configured for primary group
* calculation. It may not be the same as any value set through
* {@link #setPrimaryGroup(String)}.</p>
*
* @return the users primary group
*/
@ -67,7 +68,10 @@ public interface User extends PermissionHolder {
String getPrimaryGroup();
/**
* Sets a users primary group. This will only take effect if platform is using stored primary groups.
* Sets a users primary group.
*
* <p>This modifies the "stored value" for the users primary group, which may or may not
* actually take effect, depending on how the platform is calculating primary groups.</p>
*
* @param group the new primary group
* @return if the change was applied successfully
@ -90,10 +94,9 @@ public interface User extends PermissionHolder {
/**
* Refresh and re-assign the users permissions.
*
* <p>This request is not buffered, and the refresh call will be ran directly. This should be called on an
* asynchronous thread.</p>
*
* @deprecated in favour of {@link #refreshCachedData()}.
* @deprecated Calling this method is no longer necessary. Permissions data is now refreshed on
* demand, as changes are made. Consider use of {@link #refreshCachedData()}
* instead. This method is now implemented as a no-op.
*/
@Deprecated
void refreshPermissions();
@ -101,11 +104,8 @@ public interface User extends PermissionHolder {
/**
* Pre-calculates some values in the user's data cache.
*
* <p>Is it <b>not</b> necessary to call this method before
* using {@link #getCachedData()}.</p>
*
* @since 2.17
* @deprecated because use of this method is no longer necessary.
* @deprecated Use of this method is no longer necessary. It is implemented as a no-op.
*/
@Deprecated
void setupDataCache();

View File

@ -28,6 +28,7 @@ package me.lucko.luckperms.api.caching;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.PermissionHolder;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@ -372,7 +373,14 @@ public interface CachedData {
* @param contexts the contexts to pre-calculate for
* @throws NullPointerException if contexts is null
*/
void preCalculate(@Nonnull Contexts contexts);
default void preCalculate(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
// pre-calculate just by requesting the data from this cache.
// if the data isn't already loaded, it will be calculated.
getPermissionData(contexts);
getMetaData(contexts);
}
/**
* Invalidates any cached {@link PermissionData} instances mapped to the given

View File

@ -32,7 +32,7 @@ import javax.annotation.Nonnull;
/**
* Encapsulates the LuckPerms system which accepts incoming {@link Message}s
* from implementations of {@link MessengerProvider}.
* from implementations of {@link Messenger}.
*
* @since 4.1
*/

View File

@ -45,12 +45,18 @@ public interface Messenger extends AutoCloseable {
* of the interfaces extending {@link Message} in the
* 'api.messenger.message.type' package.</p>
*
* <p>3rd party implementations are encouraged to implement this method with consideration
* that new types may be added in the future.</p>
*
* <p>This call is always made async.</p>
*
* @param outgoingMessage the outgoing message
*/
void sendOutgoingMessage(@Nonnull OutgoingMessage outgoingMessage);
/**
* Performs the necessary action to gracefully shutdown the messenger.
*/
@Override
default void close() {

View File

@ -27,13 +27,13 @@ package me.lucko.luckperms.bukkit.model.permissible;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.bukkit.model.dummy.DummyPlugin;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.node.model.ImmutableTransientNode;
import me.lucko.luckperms.common.node.utils.NodeTools;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionRemovedExecutor;
@ -199,13 +199,13 @@ public class LPPermissionAttachment extends PermissionAttachment {
// remove transient permissions from the holder which were added by this attachment & equal the permission
User user = this.permissible.getUser();
user.removeIfTransient(LocalizedNode.composedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name)));
user.removeIfTransient(NodeTools.localizedNodeComposedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name)));
}
private void clearInternal() {
// remove all transient permissions added by this attachment
User user = this.permissible.getUser();
user.removeIfTransient(LocalizedNode.composedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this));
user.removeIfTransient(NodeTools.localizedNodeComposedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this));
}
@Override

View File

@ -28,12 +28,14 @@ package me.lucko.luckperms.common.api.delegates.model;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.caching.GroupData;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.model.Group;
import java.util.Objects;
import java.util.OptionalInt;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public final class ApiGroup extends ApiPermissionHolder implements me.lucko.luckperms.api.Group {
public static Group cast(me.lucko.luckperms.api.Group group) {
@ -60,6 +62,18 @@ public final class ApiGroup extends ApiPermissionHolder implements me.lucko.luck
return this.handle.getName();
}
@Nullable
@Override
public String getDisplayName() {
return this.handle.getDisplayName().orElse(null);
}
@Nullable
@Override
public String getDisplayName(@Nonnull ContextSet contextSet) {
return this.handle.getDisplayName(contextSet).orElse(null);
}
@Nonnull
@Override
public OptionalInt getWeight() {

View File

@ -342,7 +342,7 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.PermissionHol
@Nonnull
@Override
public List<LocalizedNode> resolveInheritances(Contexts contexts) {
public List<LocalizedNode> resolveInheritances(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
return ImmutableList.copyOf(this.handle.resolveInheritances(contexts));
}

View File

@ -186,7 +186,7 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull
@Override
public PermissionCache getPermissionData(@Nonnull Contexts contexts) {
public final PermissionCache getPermissionData(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
//noinspection ConstantConditions
@ -195,7 +195,7 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull
@Override
public MetaCache getMetaData(@Nonnull MetaContexts contexts) {
public final MetaCache getMetaData(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts");
//noinspection ConstantConditions
@ -204,53 +204,53 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull
@Override
public MetaCache getMetaData(@Nonnull Contexts contexts) {
public final MetaCache getMetaData(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
return getMetaData(getDefaultMetaContexts(contexts));
}
@Nonnull
@Override
public PermissionCache calculatePermissions(@Nonnull Contexts contexts) {
public final PermissionCache calculatePermissions(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
return calculatePermissions(contexts, null);
}
@Nonnull
@Override
public MetaCache calculateMeta(@Nonnull MetaContexts contexts) {
public final MetaCache calculateMeta(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts");
return calculateMeta(contexts, null);
}
@Nonnull
@Override
public MetaCache calculateMeta(@Nonnull Contexts contexts) {
public final MetaCache calculateMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
return calculateMeta(getDefaultMetaContexts(contexts));
}
@Override
public void recalculatePermissions(@Nonnull Contexts contexts) {
public final void recalculatePermissions(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
this.permission.synchronous().refresh(contexts);
}
@Override
public void recalculateMeta(@Nonnull MetaContexts contexts) {
public final void recalculateMeta(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts");
this.meta.synchronous().refresh(contexts);
}
@Override
public void recalculateMeta(@Nonnull Contexts contexts) {
public final void recalculateMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
recalculateMeta(getDefaultMetaContexts(contexts));
}
@Nonnull
@Override
public CompletableFuture<PermissionCache> reloadPermissions(@Nonnull Contexts contexts) {
public final CompletableFuture<PermissionCache> reloadPermissions(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
// get the previous value - to use when recalculating
@ -271,7 +271,7 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull
@Override
public CompletableFuture<MetaCache> reloadMeta(@Nonnull MetaContexts contexts) {
public final CompletableFuture<MetaCache> reloadMeta(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts");
// get the previous value - to use when recalculating
@ -292,86 +292,76 @@ public abstract class AbstractCachedData implements CachedData {
@Nonnull
@Override
public CompletableFuture<MetaCache> reloadMeta(@Nonnull Contexts contexts) {
public final CompletableFuture<MetaCache> reloadMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
return reloadMeta(getDefaultMetaContexts(contexts));
}
@Override
public void recalculatePermissions() {
public final void recalculatePermissions() {
Set<Contexts> keys = this.permission.synchronous().asMap().keySet();
keys.forEach(this::recalculatePermissions);
}
@Override
public void recalculateMeta() {
public final void recalculateMeta() {
Set<MetaContexts> keys = this.meta.synchronous().asMap().keySet();
keys.forEach(this::recalculateMeta);
}
@Nonnull
@Override
public CompletableFuture<Void> reloadPermissions() {
public final CompletableFuture<Void> reloadPermissions() {
Set<Contexts> keys = this.permission.synchronous().asMap().keySet();
return CompletableFuture.allOf(keys.stream().map(this::reloadPermissions).toArray(CompletableFuture[]::new));
}
@Nonnull
@Override
public CompletableFuture<Void> reloadMeta() {
public final CompletableFuture<Void> reloadMeta() {
Set<MetaContexts> keys = this.meta.synchronous().asMap().keySet();
return CompletableFuture.allOf(keys.stream().map(this::reloadMeta).toArray(CompletableFuture[]::new));
}
@Override
public void preCalculate(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
// pre-calculate just by requesting the data from this cache.
// if the data isn't already loaded, it will be calculated.
getPermissionData(contexts);
getMetaData(contexts);
}
@Override
public void invalidatePermissions(@Nonnull Contexts contexts) {
public final void invalidatePermissions(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
this.permission.synchronous().invalidate(contexts);
}
@Override
public void invalidateMeta(@Nonnull MetaContexts contexts) {
public final void invalidateMeta(@Nonnull MetaContexts contexts) {
Objects.requireNonNull(contexts, "contexts");
this.meta.synchronous().invalidate(contexts);
}
@Override
public void invalidateMeta(@Nonnull Contexts contexts) {
public final void invalidateMeta(@Nonnull Contexts contexts) {
Objects.requireNonNull(contexts, "contexts");
this.meta.synchronous().invalidate(getDefaultMetaContexts(contexts));
}
@Override
public void invalidatePermissions() {
public final void invalidatePermissions() {
this.permission.synchronous().invalidateAll();
}
@Override
public void invalidateMeta() {
public final void invalidateMeta() {
this.meta.synchronous().invalidateAll();
}
@Override
public void invalidatePermissionCalculators() {
public final void invalidatePermissionCalculators() {
this.permission.synchronous().asMap().values().forEach(PermissionCache::invalidateCache);
}
public void invalidate() {
public final void invalidate() {
invalidatePermissions();
invalidateMeta();
}
public void doCacheCleanup() {
public final void doCacheCleanup() {
this.permission.synchronous().cleanUp();
this.meta.synchronous().cleanUp();
}

View File

@ -25,6 +25,7 @@
package me.lucko.luckperms.common.node.utils;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.NodeEqualityPredicate;
@ -33,6 +34,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
public final class NodeTools {
@ -64,5 +66,17 @@ public final class NodeTools {
}
}
/**
* Returns a predicate which unwraps the localised node parameter before delegating
* the handling to the provided predicate.
*
* @param delegate the delegate predicate.
* @return the composed predicate
* @since 4.3
*/
public static Predicate<? super LocalizedNode> localizedNodeComposedPredicate(Predicate<Node> delegate) {
return localizedNode -> delegate.test(localizedNode.getNode());
}
private NodeTools() {}
}

View File

@ -27,12 +27,12 @@ package me.lucko.luckperms.nukkit.model.permissible;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.factory.NodeFactory;
import me.lucko.luckperms.common.node.model.ImmutableTransientNode;
import me.lucko.luckperms.common.node.utils.NodeTools;
import me.lucko.luckperms.nukkit.model.dummy.DummyPlugin;
import cn.nukkit.permission.Permission;
@ -200,13 +200,13 @@ public class LPPermissionAttachment extends PermissionAttachment {
// remove transient permissions from the holder which were added by this attachment & equal the permission
User user = this.permissible.getUser();
user.removeIfTransient(LocalizedNode.composedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name)));
user.removeIfTransient(NodeTools.localizedNodeComposedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name)));
}
private void clearInternal() {
// remove all transient permissions added by this attachment
User user = this.permissible.getUser();
user.removeIfTransient(LocalizedNode.composedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this));
user.removeIfTransient(NodeTools.localizedNodeComposedPredicate(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this));
}
@Override