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 CompletableFutures, and will load the data into memory if it isn't already loaded. The methods to "get" data return Optionals, 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 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 by UUID.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 using suggestUnload(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 to
        action - 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 check
        cause - 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 check
        cause - 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