Interface SubjectCollection
-
public interface SubjectCollection
An object which manages subjects of a certain type (user, group, etc).A distinction is made between subjects which exist and are loaded, and subjects which exist but are not currently loaded into memory. The methods to "load" data return
CompletableFuture
s, and will load the data into memory if it isn't already loaded. The methods to "get" data returnOptional
s, which will only be filled if the data is currently loaded.Note: the default subject must already be cached when the subject collection is fetched.
When Subjects are loaded, it may not be necessary to load data about all parent subjects immediately, however, lookups should still honour inheritance rules.
-
-
Method Summary
All Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description CompletableFuture<? extends Set<String>>
allIdentifiers()
Gets a set of Subject identifiers being stored in the collection.CompletableFuture<? extends Map<? extends SubjectReference,Boolean>>
allWithPermission(String permission)
Return the identifiers of all known subjects with the given permission set.CompletableFuture<? extends Map<? extends SubjectReference,Boolean>>
allWithPermission(String permission, Cause cause)
Return the identifiers of all known subjects with the given permission set.default CompletableFuture<Void>
applyToAll(Iterable<String> identifiers, Consumer<Subject> action)
Performs an action on each Subject in the provided set.default CompletableFuture<Void>
applyToAll(Consumer<Subject> action)
Performs an action on each Subject in the collection.Subject
defaults()
Gets the subject holding data that is applied by default to all subjects in this collection.CompletableFuture<Boolean>
hasSubject(String identifier)
Returns whether a subject with the given identifier currently exists.String
identifier()
Return the identifier for this collection.Predicate<String>
identifierValidityPredicate()
Returns a predicate which determines whether or not a given identifier is valid for a subject held by this collection.Collection<? extends Subject>
loadedSubjects()
Returns an immutable copy of all subjects currently loaded in this collection.Map<? extends Subject,Boolean>
loadedWithPermission(String permission)
Return all loaded subjects with the given permission set.Map<? extends Subject,Boolean>
loadedWithPermission(String permission, Cause cause)
Return all loaded subjects with the given permission set.CompletableFuture<? extends Subject>
loadSubject(String identifier)
Loads and returns a subject with the given identifier.CompletableFuture<? extends Map<String,? extends Subject>>
loadSubjects(Iterable<String> identifiers)
Gets a map of subjects from the provided set of identifiers.SubjectReference
newSubjectReference(String subjectIdentifier)
Creates a new subject reference to represent the expressed subject.Optional<? extends Subject>
subject(String identifier)
Returns a subject with the given identifier, if the subject is already loaded within this collection.void
suggestUnload(String identifier)
Indicate that a certain subject may be unloaded by the implementation.
-
-
-
Method Detail
-
identifier
String identifier()
Return the identifier for this collection.- Returns:
- The identifier
-
identifierValidityPredicate
Predicate<String> identifierValidityPredicate()
Returns a predicate which determines whether or not a given identifier is valid for a subject held by this collection.It is expected that the
PermissionService.SUBJECTS_USER
collection should accept identifiers in UUID RFC4122 string format. (In the format produced byUUID.toString()
- Returns:
- The predicate
-
loadSubject
CompletableFuture<? extends Subject> loadSubject(String identifier)
Loads and returns a subject with the given identifier.The returned future will complete exceptionally if the subject with the given identifier cannot be loaded.
A
IllegalArgumentException
will be thrown directly by this method if the identifier does not pass the identifier validity predicate.- Parameters:
identifier
- The identifier. All identifiers are case-insensitive- Returns:
- A subject for the given identifier
- Throws:
IllegalArgumentException
- If the subject identifier does not pass the validity predicate for this collection.
-
subject
Optional<? extends Subject> subject(String identifier)
Returns a subject with the given identifier, if the subject is already loaded within this collection.It is important to note that a subject with the given identifier may still exist, even if this method returns an empty optional. Checking for the presence of a subject should be done using
hasSubject(String)
.If the subject identifier does not pass the validity predicate, this method will return an empty optional, and not throw an exception.
- Parameters:
identifier
- The identifier- Returns:
- A subject for the given identifier
-
hasSubject
CompletableFuture<Boolean> hasSubject(String identifier)
Returns whether a subject with the given identifier currently exists.The return value of this function does not influence whether or not the results from any subject lookups should be obtained.
- Parameters:
identifier
- The identifier of the subject- Returns:
- If the subject currently exists
-
loadSubjects
CompletableFuture<? extends Map<String,? extends Subject>> loadSubjects(Iterable<String> identifiers)
Gets a map of subjects from the provided set of identifiers.If any of the identifiers do not pass the collections
identifierValidityPredicate()
, a subject will not be returned for that identifier.- Parameters:
identifiers
- A set of identifiers to get subjects for- Returns:
- a map of subjects corresponding to the identifiers passed
-
loadedSubjects
Collection<? extends Subject> loadedSubjects()
Returns an immutable copy of all subjects currently loaded in this collection.- Returns:
- A collection containing the subjects currently loaded into this subject collection.
-
allIdentifiers
CompletableFuture<? extends Set<String>> allIdentifiers()
Gets a set of Subject identifiers being stored in the collection. This method must return a complete list, including identifiers of subjects not currently loaded.The results of this method should not be passed directly to
loadSubjects(Iterable)
. Instead, each individual subject should be loaded, processed, and then allowed to be unloaded usingsuggestUnload(String)
.If you simply need to process each subject in the collection, you can use
applyToAll(Consumer)
and gather data.- Returns:
- A set containing the identifiers of every Subject in this collection
-
newSubjectReference
SubjectReference newSubjectReference(String subjectIdentifier)
Creates a new subject reference to represent the expressed subject.Note that instances of SubjectReference must be capable of resolving the identifier to a Subject without being passed a reference to the service.
A
IllegalArgumentException
will be thrown directly by this method if the identifier does not pass the identifier validity predicate.- Parameters:
subjectIdentifier
- The identifier of the subject- Returns:
- A subject reference to represent the expressed subject
- Throws:
IllegalArgumentException
- If the subject identifier does not pass the validity predicate for this collection.
-
applyToAll
default CompletableFuture<Void> applyToAll(Consumer<Subject> action)
Performs an action on each Subject in the collection.Subjects are loaded, supplied to the consumer, and then allowed to be uncached by the implementation.
This should be used to apply bulk changes or gather data about all Subjects in the collection. The provided consumer will be supplied asynchronously. Acting upon a large collection may be particularly resource intensive.
Implementations may choose to load and process subjects in parallel.
- Parameters:
action
- The action to perform on each subject- Returns:
- A future which will complete when the operation has finished
-
applyToAll
default CompletableFuture<Void> applyToAll(Iterable<String> identifiers, Consumer<Subject> action)
Performs an action on each Subject in the provided set.Subjects are loaded, supplied to the consumer, and then allowed to be uncached by the implementation.
This should be used to apply bulk changes or gather data about all Subjects in the collection. The provided consumer will be supplied asynchronously. Acting upon a large collection may be particularly resource intensive.
Implementations may choose to load and process subjects in parallel.
- Parameters:
identifiers
- a set of identifiers to apply the action toaction
- The action to perform on each subject- Returns:
- A future which will complete when the operation has finished
-
allWithPermission
CompletableFuture<? extends Map<? extends SubjectReference,Boolean>> allWithPermission(String permission)
Return the identifiers of all known subjects with the given permission set.This method DOES NOT consider inheritance, and will only query the data set to the subjects
Subject.subjectData()
. Transient data is not considered.As no context is passed, it is up to the implementation to decide which contexts to use. When available, it is likely that
SubjectData.GLOBAL_CONTEXT
will be used.Contexts will be extracted from the current cause for each lookup.
- Parameters:
permission
- The permission to check- Returns:
- A reference to any subject known to have this permission set, and the value this permission is set to
-
allWithPermission
CompletableFuture<? extends Map<? extends SubjectReference,Boolean>> allWithPermission(String permission, Cause cause)
Return the identifiers of all known subjects with the given permission set.This method DOES NOT consider inheritance, and will only query the data set to the subjects
Subject.subjectData()
. Transient data is not considered.- Parameters:
permission
- The permission to checkcause
- The cause to extract context information from- Returns:
- A reference to any subject known to have this permission set, and the value this permission is set to
-
loadedWithPermission
Map<? extends Subject,Boolean> loadedWithPermission(String permission)
Return all loaded subjects with the given permission set.This method DOES NOT consider inheritance, and will only query the data set to the subjects
Subject.subjectData()
. Transient data is not considered.Contexts will be extracted from the current cause for each lookup.
- Parameters:
permission
- The permission to check- Returns:
- A map containing any subject known to have this permission set, and the value this permission is set to
-
loadedWithPermission
Map<? extends Subject,Boolean> loadedWithPermission(String permission, Cause cause)
Return all loaded subjects with the given permission set.This method DOES NOT consider inheritance, and will only query the data set to the subjects
Subject.subjectData()
. Transient data is not considered.- Parameters:
permission
- The permission to checkcause
- The cause to extract context information from- Returns:
- A map containing any subject known to have this permission set, and the value this permission is set to
-
defaults
Subject defaults()
Gets the subject holding data that is applied by default to all subjects in this collection.This subject is at the root of all inheritance trees for subjects in this collection, but at a higher priority chan defaults expressed to
PermissionService.defaults()
.Note: This data may be persisted, so plugins that add permissions to this subject must take care to not override permissions already set or modified.
It is also recommended to use
Subject.transientSubjectData()
where possible to avoid persisting unnecessary data.Assigning default permissions should be used sparingly, and by convention, only in situations where "default" game behaviour is restored by granting a certain permission.
- Returns:
- The subject holding defaults for this collection
-
suggestUnload
void suggestUnload(String identifier)
Indicate that a certain subject may be unloaded by the implementation.This is only a hint to the implementation, and does not guarantee that the subject will be unloaded.
- Parameters:
identifier
- The subject to be unloaded
-
-