diff --git a/api/src/main/java/me/lucko/luckperms/api/Storage.java b/api/src/main/java/me/lucko/luckperms/api/Storage.java
index bede6fbc..e05140a0 100644
--- a/api/src/main/java/me/lucko/luckperms/api/Storage.java
+++ b/api/src/main/java/me/lucko/luckperms/api/Storage.java
@@ -25,6 +25,10 @@
package me.lucko.luckperms.api;
+import me.lucko.luckperms.api.manager.GroupManager;
+import me.lucko.luckperms.api.manager.TrackManager;
+import me.lucko.luckperms.api.manager.UserManager;
+
import java.util.List;
import java.util.Set;
import java.util.UUID;
@@ -38,13 +42,15 @@ import javax.annotation.Nullable;
/**
* A means of loading and saving permission data to/from the backend.
*
- *
All blocking methods return {@link CompletableFuture}s, which will be populated with the result once the data has been
- * loaded/saved asynchronously. Care should be taken when using such methods to ensure that the main server thread is not
- * blocked.
+ * All blocking methods return {@link CompletableFuture}s, which will be
+ * populated with the result once the data has been loaded/saved asynchronously.
+ * Care should be taken when using such methods to ensure that the main server
+ * thread is not blocked.
*
- * Methods such as {@link CompletableFuture#get()} and equivalent should not be called on the main
- * server thread. If you need to use the result of these operations on the main server thread, register a
- * callback using {@link CompletableFuture#thenAcceptAsync(Consumer, Executor)} and {@link #getSyncExecutor()}.
+ * Methods such as {@link CompletableFuture#get()} and equivalent should
+ * not be called on the main server thread. If you need to use
+ * the result of these operations on the main server thread, register a
+ * callback using {@link CompletableFuture#thenAcceptAsync(Consumer, Executor)}.
*
* @since 2.14
*/
@@ -58,42 +64,6 @@ public interface Storage {
@Nonnull
String getName();
- /**
- * Gets whether the storage instance is allowing logins on the platform.
- *
- * @return true if logins are enabled
- */
- boolean isAcceptingLogins();
-
- /**
- * Returns an executor which will run all passed runnables on the main server thread.
- *
- * @return an executor instance
- */
- @Nonnull
- Executor getSyncExecutor();
-
- /**
- * Returns an executor which will run all passed runnables asynchronously using the platforms scheduler and thread
- * pools.
- *
- * @return an executor instance
- */
- @Nonnull
- Executor getAsyncExecutor();
-
- /**
- * Saves an action to storage
- *
- * @param entry the log entry to be saved
- * @return true if the operation completed successfully.
- * @throws NullPointerException if entry is null
- * @deprecated in favour of {@link ActionLogger#submit(LogEntry)}.
- */
- @Nonnull
- @Deprecated
- CompletableFuture logAction(@Nonnull LogEntry entry);
-
/**
* Loads and returns the entire log from storage
*
@@ -102,40 +72,6 @@ public interface Storage {
@Nonnull
CompletableFuture getLog();
- /**
- * Loads a user's data from the main storage into the plugins local storage.
- *
- * @param uuid the uuid of the user to load
- * @param username the users username, or null if it is not known.
- * @return if the operation completed successfully
- * @throws NullPointerException if uuid is null
- */
- @Nonnull
- CompletableFuture loadUser(@Nonnull UUID uuid, @Nullable String username);
-
- /**
- * Loads a user's data from the main storage into the plugins local storage.
- *
- * @param uuid the uuid of the user to load
- * @return if the operation completed successfully
- * @throws NullPointerException if uuid is null
- */
- @Nonnull
- default CompletableFuture loadUser(@Nonnull UUID uuid) {
- return loadUser(uuid, null);
- }
-
- /**
- * Saves a user object back to storage. You should call this after you make any changes to a user.
- *
- * @param user the user to save
- * @return true if the operation completed successfully.
- * @throws NullPointerException if user is null
- * @throws IllegalStateException if the user instance was not obtained from LuckPerms.
- */
- @Nonnull
- CompletableFuture saveUser(@Nonnull User user);
-
/**
* Gets a set all "unique" user UUIDs.
*
@@ -157,58 +93,6 @@ public interface Storage {
@Nonnull
CompletableFuture>> getUsersWithPermission(@Nonnull String permission);
- /**
- * Creates and loads a group into the plugins local storage
- *
- * @param name the name of the group
- * @return true if the operation completed successfully
- * @throws NullPointerException if name is null
- * @throws IllegalArgumentException if the name is invalid
- */
- @Nonnull
- CompletableFuture createAndLoadGroup(@Nonnull String name);
-
- /**
- * Loads a group into the plugins local storage.
- *
- * @param name the name of the group
- * @return true if the operation completed successfully
- * @throws NullPointerException if name is null
- * @throws IllegalArgumentException if the name is invalid
- */
- @Nonnull
- CompletableFuture loadGroup(@Nonnull String name);
-
- /**
- * Loads all groups from the storage into memory
- *
- * @return true if the operation completed successfully.
- */
- @Nonnull
- CompletableFuture loadAllGroups();
-
- /**
- * Saves a group back to storage. You should call this after you make any changes to a group.
- *
- * @param group the group to save
- * @return true if the operation completed successfully.
- * @throws NullPointerException if group is null
- * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
- */
- @Nonnull
- CompletableFuture saveGroup(@Nonnull Group group);
-
- /**
- * Permanently deletes a group from storage.
- *
- * @param group the group to delete
- * @return true if the operation completed successfully.
- * @throws NullPointerException if group is null
- * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
- */
- @Nonnull
- CompletableFuture deleteGroup(@Nonnull Group group);
-
/**
* Searches for a list of groups with a given permission.
*
@@ -220,58 +104,6 @@ public interface Storage {
@Nonnull
CompletableFuture>> getGroupsWithPermission(@Nonnull String permission);
- /**
- * Creates and loads a track into the plugins local storage
- *
- * @param name the name of the track
- * @return true if the operation completed successfully
- * @throws NullPointerException if name is null
- * @throws IllegalArgumentException if the name is invalid
- */
- @Nonnull
- CompletableFuture createAndLoadTrack(@Nonnull String name);
-
- /**
- * Loads a track into the plugins local storage.
- *
- * @param name the name of the track
- * @return true if the operation completed successfully
- * @throws NullPointerException if name is null
- * @throws IllegalArgumentException if the name is invalid
- */
- @Nonnull
- CompletableFuture loadTrack(@Nonnull String name);
-
- /**
- * Loads all tracks from the storage into memory
- *
- * @return true if the operation completed successfully.
- */
- @Nonnull
- CompletableFuture loadAllTracks();
-
- /**
- * Saves a track back to storage. You should call this after you make any changes to a track.
- *
- * @param track the track to save
- * @return true if the operation completed successfully.
- * @throws NullPointerException if track is null
- * @throws IllegalStateException if the track instance was not obtained from LuckPerms.
- */
- @Nonnull
- CompletableFuture saveTrack(@Nonnull Track track);
-
- /**
- * Permanently deletes a track from storage
- *
- * @param track the track to delete
- * @return true if the operation completed successfully.
- * @throws NullPointerException if track is null
- * @throws IllegalStateException if the track instance was not obtained from LuckPerms.
- */
- @Nonnull
- CompletableFuture deleteTrack(@Nonnull Track track);
-
/**
* Saves UUID caching data to the global cache
*
@@ -306,4 +138,221 @@ public interface Storage {
@Nonnull
CompletableFuture getName(@Nonnull UUID uuid);
+ /**
+ * Gets whether the storage instance is allowing logins on the platform.
+ *
+ * @return true if logins are enabled
+ * @deprecated as this method always returns true.
+ */
+ @Deprecated
+ boolean isAcceptingLogins();
+
+ /**
+ * Returns an executor which will run all passed runnables on the
+ * main server thread.
+ *
+ * This method is deprecated as plugins should create and use their own
+ * executor instances.
+ *
+ * @return an executor instance
+ * @deprecated as plugins should create their own executors
+ */
+ @Nonnull
+ @Deprecated
+ Executor getSyncExecutor();
+
+ /**
+ * Returns an executor which will run all passed runnables asynchronously
+ * using the platforms scheduler and thread pools.
+ *
+ * This method is deprecated as plugins should create and use their own
+ * executor instances.
+ *
+ * @return an executor instance
+ * @deprecated as plugins should create their own executors
+ */
+ @Nonnull
+ @Deprecated
+ Executor getAsyncExecutor();
+
+ /**
+ * Saves an action to storage
+ *
+ * @param entry the log entry to be saved
+ * @return true if the operation completed successfully.
+ * @throws NullPointerException if entry is null
+ * @deprecated in favour of {@link ActionLogger#submit(LogEntry)}.
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture logAction(@Nonnull LogEntry entry);
+
+ /**
+ * Loads a user's data from the main storage into the plugins local storage.
+ *
+ * @param uuid the uuid of the user to load
+ * @param username the users username, or null if it is not known.
+ * @return if the operation completed successfully
+ * @throws NullPointerException if uuid is null
+ * @deprecated in favour of {@link UserManager#loadUser(UUID, String)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture loadUser(@Nonnull UUID uuid, @Nullable String username);
+
+ /**
+ * Loads a user's data from the main storage into the plugins local storage.
+ *
+ * @param uuid the uuid of the user to load
+ * @return if the operation completed successfully
+ * @throws NullPointerException if uuid is null
+ * @deprecated in favour of {@link UserManager#loadUser(UUID)}
+ */
+ @Nonnull
+ @Deprecated
+ default CompletableFuture loadUser(@Nonnull UUID uuid) {
+ return loadUser(uuid, null);
+ }
+
+ /**
+ * Saves a user object back to storage.
+ *
+ * You should call this after you make any changes to a user.
+ *
+ * @param user the user to save
+ * @return true if the operation completed successfully.
+ * @throws NullPointerException if user is null
+ * @throws IllegalStateException if the user instance was not obtained from LuckPerms.
+ * @deprecated in favour of {@link UserManager#saveUser(User)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture saveUser(@Nonnull User user);
+
+ /**
+ * Creates and loads a group into the plugins local storage
+ *
+ * @param name the name of the group
+ * @return true if the operation completed successfully
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException if the name is invalid
+ * @deprecated in favour of {@link GroupManager#createAndLoadGroup(String)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture createAndLoadGroup(@Nonnull String name);
+
+ /**
+ * Loads a group into the plugins local storage.
+ *
+ * @param name the name of the group
+ * @return true if the operation completed successfully
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException if the name is invalid
+ * @deprecated in favour of {@link GroupManager#loadGroup(String)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture loadGroup(@Nonnull String name);
+
+ /**
+ * Loads all groups from the storage into memory
+ *
+ * @return true if the operation completed successfully.
+ * @deprecated in favour of {@link GroupManager#loadAllGroups()}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture loadAllGroups();
+
+ /**
+ * Saves a group back to storage.
+ *
+ * You should call this after you make any changes to a group.
+ *
+ * @param group the group to save
+ * @return true if the operation completed successfully.
+ * @throws NullPointerException if group is null
+ * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
+ * @deprecated in favour of {@link GroupManager#saveGroup(Group)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture saveGroup(@Nonnull Group group);
+
+ /**
+ * Permanently deletes a group from storage.
+ *
+ * @param group the group to delete
+ * @return true if the operation completed successfully.
+ * @throws NullPointerException if group is null
+ * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
+ * @deprecated in favour of {@link GroupManager#deleteGroup(Group)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture deleteGroup(@Nonnull Group group);
+
+ /**
+ * Creates and loads a track into the plugins local storage
+ *
+ * @param name the name of the track
+ * @return true if the operation completed successfully
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException if the name is invalid
+ * @deprecated in favour of {@link TrackManager#createAndLoadTrack(String)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture createAndLoadTrack(@Nonnull String name);
+
+ /**
+ * Loads a track into the plugins local storage.
+ *
+ * @param name the name of the track
+ * @return true if the operation completed successfully
+ * @throws NullPointerException if name is null
+ * @throws IllegalArgumentException if the name is invalid
+ * @deprecated in favour of {@link TrackManager#loadTrack(String)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture loadTrack(@Nonnull String name);
+
+ /**
+ * Loads all tracks from the storage into memory
+ *
+ * @return true if the operation completed successfully.
+ * @deprecated in favour of {@link TrackManager#loadAllTracks()}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture loadAllTracks();
+
+ /**
+ * Saves a track back to storage. You should call this after you make any changes to a track.
+ *
+ * @param track the track to save
+ * @return true if the operation completed successfully.
+ * @throws NullPointerException if track is null
+ * @throws IllegalStateException if the track instance was not obtained from LuckPerms.
+ * @deprecated in favour of {@link TrackManager#saveTrack(Track)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture saveTrack(@Nonnull Track track);
+
+ /**
+ * Permanently deletes a track from storage
+ *
+ * @param track the track to delete
+ * @return true if the operation completed successfully.
+ * @throws NullPointerException if track is null
+ * @throws IllegalStateException if the track instance was not obtained from LuckPerms.
+ * @deprecated in favour of {@link TrackManager#deleteTrack(Track)}
+ */
+ @Nonnull
+ @Deprecated
+ CompletableFuture deleteTrack(@Nonnull Track track);
+
}
diff --git a/api/src/main/java/me/lucko/luckperms/api/manager/GroupManager.java b/api/src/main/java/me/lucko/luckperms/api/manager/GroupManager.java
index 69b72a12..2f6f0e37 100644
--- a/api/src/main/java/me/lucko/luckperms/api/manager/GroupManager.java
+++ b/api/src/main/java/me/lucko/luckperms/api/manager/GroupManager.java
@@ -26,9 +26,11 @@
package me.lucko.luckperms.api.manager;
import me.lucko.luckperms.api.Group;
+import me.lucko.luckperms.api.Storage;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -41,7 +43,103 @@ import javax.annotation.Nullable;
public interface GroupManager {
/**
- * Gets a wrapped group object from the group storage
+ * Creates a new group in the plugin's storage provider and then loads it
+ * into memory.
+ *
+ * If a group by the same name already exists, it will be loaded.
+ *
+ * This method is effectively the same as
+ * {@link Storage#createAndLoadGroup(String)}, however, the Future returns
+ * the resultant group instance instead of a boolean flag.
+ *
+ * Unlike the method in {@link Storage}, when a group cannot be loaded,
+ * the future will be {@link CompletableFuture completed exceptionally}.
+ *
+ * @param name the name of the group
+ * @return the resultant group
+ * @throws NullPointerException if the name is null
+ * @since 4.1
+ */
+ @Nonnull
+ CompletableFuture createAndLoadGroup(@Nonnull String name);
+
+ /**
+ * Loads a group from the plugin's storage provider into memory.
+ *
+ * Returns an {@link Optional#empty() empty optional} if the group does
+ * not exist.
+ *
+ * This method is effectively the same as
+ * {@link Storage#loadGroup(String)}, however, the Future returns
+ * the resultant group instance instead of a boolean flag.
+ *
+ * Unlike the method in {@link Storage}, when a group cannot be loaded,
+ * the future will be {@link CompletableFuture completed exceptionally}.
+ *
+ * @param name the name of the group
+ * @return the resultant group
+ * @throws NullPointerException if the name is null
+ * @since 4.1
+ */
+ @Nonnull
+ CompletableFuture> loadGroup(@Nonnull String name);
+
+ /**
+ * Saves a group's data back to the plugin's storage provider.
+ *
+ * You should call this after you make any changes to a group.
+ *
+ * This method is effectively the same as {@link Storage#saveGroup(Group)},
+ * however, the Future returns void instead of a boolean flag.
+ *
+ * Unlike the method in {@link Storage}, when a group cannot be saved,
+ * the future will be {@link CompletableFuture completed exceptionally}.
+ *
+ * @param group the group to save
+ * @return a future to encapsulate the operation.
+ * @throws NullPointerException if group is null
+ * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
+ * @since 4.1
+ */
+ @Nonnull
+ CompletableFuture saveGroup(@Nonnull Group group);
+
+ /**
+ * Permanently deletes a group from the plugin's storage provider.
+ *
+ * This method is effectively the same as {@link Storage#deleteGroup(Group)},
+ * however, the Future returns void instead of a boolean flag.
+ *
+ * Unlike the method in {@link Storage}, when a group cannot be deleted,
+ * the future will be {@link CompletableFuture completed exceptionally}.
+ *
+ *
+ * @param group the group to delete
+ * @return a future to encapsulate the operation.
+ * @throws NullPointerException if group is null
+ * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
+ * @since 4.1
+ */
+ @Nonnull
+ CompletableFuture deleteGroup(@Nonnull Group group);
+
+ /**
+ * Loads all groups into memory.
+ *
+ * This method is effectively the same as {@link Storage#loadAllTracks()},
+ * however, the Future returns void instead of a boolean flag.
+ *
+ * Unlike the method in {@link Storage}, when a group cannot be loaded,
+ * the future will be {@link CompletableFuture completed exceptionally}.
+ *
+ * @return a future to encapsulate the operation.
+ * @since 4.1
+ */
+ @Nonnull
+ CompletableFuture loadAllGroups();
+
+ /**
+ * Gets a loaded group.
*
* @param name the name of the group to get
* @return a {@link Group} object, if one matching the name exists, or null if not
@@ -51,7 +149,7 @@ public interface GroupManager {
Group getGroup(@Nonnull String name);
/**
- * Gets a wrapped group object from the group storage.
+ * Gets a loaded group.
*
* This method does not return null, unlike {@link #getGroup}
*
diff --git a/api/src/main/java/me/lucko/luckperms/api/manager/TrackManager.java b/api/src/main/java/me/lucko/luckperms/api/manager/TrackManager.java
index b31531b4..3a6491aa 100644
--- a/api/src/main/java/me/lucko/luckperms/api/manager/TrackManager.java
+++ b/api/src/main/java/me/lucko/luckperms/api/manager/TrackManager.java
@@ -25,10 +25,12 @@
package me.lucko.luckperms.api.manager;
+import me.lucko.luckperms.api.Storage;
import me.lucko.luckperms.api.Track;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -41,7 +43,103 @@ import javax.annotation.Nullable;
public interface TrackManager {
/**
- * Gets a wrapped track object from the track storage
+ * Creates a new track in the plugin's storage provider and then loads it
+ * into memory.
+ *
+ * If a track by the same name already exists, it will be loaded.
+ *
+ * This method is effectively the same as
+ * {@link Storage#createAndLoadTrack(String)}, however, the Future returns
+ * the resultant track instance instead of a boolean flag.
+ *
+ * Unlike the method in {@link Storage}, when a track cannot be loaded,
+ * the future will be {@link CompletableFuture completed exceptionally}.
+ *
+ * @param name the name of the track
+ * @return the resultant track
+ * @throws NullPointerException if the name is null
+ * @since 4.1
+ */
+ @Nonnull
+ CompletableFuture