001/* 002 * PermissionsEx 003 * Copyright (C) zml and PermissionsEx contributors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package ca.stellardrift.permissionsex.subject; 018 019import ca.stellardrift.permissionsex.datastore.DataStore; 020import org.checkerframework.checker.nullness.qual.Nullable; 021 022import java.util.concurrent.CompletableFuture; 023import java.util.function.Consumer; 024import java.util.function.UnaryOperator; 025import java.util.stream.Stream; 026 027/** 028 * A cached view of the subject data within a particular {@link DataStore}. 029 * 030 * <p>Provides operations to manage querying, writing, and updating 031 * {@link ImmutableSubjectData} objects.</p> 032 * 033 * @since 2.0.0 034 */ 035public interface SubjectDataCache<I> { 036 /** 037 * Get the subject type for this cache. 038 * 039 * @return the subject type this cache contains data for 040 * @since 2.0.0 041 */ 042 SubjectType<I> type(); 043 044 /** 045 * Get data for a given subject. 046 * 047 * <p>This will return a data object even if the subject is not registered; the data object will 048 * just be empty.</p> 049 * 050 * <p>For most longer-lifetime use cases, {@link #referenceTo(Object)} will be the preferred 051 * method to get a reference to the latest subject data.</p> 052 * 053 * @param identifier The identifier of the subject to query 054 * @param listener A callback that will be notified whenever a change is made to the data object 055 * @return A future returning when the data is available 056 */ 057 CompletableFuture<ImmutableSubjectData> data(final I identifier, final @Nullable Consumer<ImmutableSubjectData> listener); 058 059 /** 060 * Get a reference to subject data for a given subject. The reference will update as changes are made to the backing 061 * data store, and can always be used to query a specific subject's raw data. 062 * 063 * @param identifier The identifier of the subject to get data for 064 * @return A future returning with a full reference to the given subject's data. 065 */ 066 CompletableFuture<? extends SubjectRef.ToData<I>> referenceTo(final I identifier); 067 068 /** 069 * Get a reference to subject data for a given subject 070 * 071 * @param identifier The identifier of the subject to get data for 072 * @param strongListeners Whether to hold listeners to this subject data even after they would be otherwise GC'd 073 * @return A future completing with the subject data reference 074 */ 075 CompletableFuture<? extends SubjectRef.ToData<I>> referenceTo(final I identifier, boolean strongListeners); 076 077 /** 078 * Update data for a given subject, acting on the latest data available. 079 * The {@code action} callback may be called within an asynchronous task. 080 * 081 * @param identifier The identifier of the subject to be updated 082 * @param action A function taking an old subject data instance and returning an updated one 083 * @return A future completing with the latest subject data after modifications are made 084 */ 085 CompletableFuture<ImmutableSubjectData> update(final I identifier, final UnaryOperator<ImmutableSubjectData> action); 086 087 /** 088 * Load data (if any) known for the given identifier 089 * 090 * @param identifier The subject identifier 091 */ 092 void load(final I identifier); 093 094 /** 095 * Remove a given subject identifier from the cache 096 * 097 * @param identifier The identifier of the subject to be removed 098 */ 099 void invalidate(final I identifier); 100 101 /** 102 * Enter all subjects of this type into cache 103 */ 104 void cacheAll(); 105 106 /** 107 * Check if a given subject is registered. This operation occurs asynchronously 108 * Registered means that a subject has any sort of data stored. 109 * 110 * @param identifier The identifier of the subject to check 111 * @return A future returning whether the subject has data stored 112 */ 113 CompletableFuture<Boolean> isRegistered(final I identifier); 114 115 /** 116 * Remove a subject from the backing data store 117 * 118 * @param identifier The identifier of the subject to remove 119 * @return A future returning the previous subject data. 120 */ 121 CompletableFuture<ImmutableSubjectData> remove(final I identifier); 122 123 /** 124 * Set the data for {@code identifier}. 125 * 126 * @param identifier identifier of the target subject 127 * @param newData data to set for the subject, {@code null} to clear all data. 128 * @return a future completing with the newly set subject data. 129 */ 130 CompletableFuture<ImmutableSubjectData> set(final I identifier, final @Nullable ImmutableSubjectData newData); 131 132 /** 133 * Add a listener to be notified on updates to the given subject 134 * 135 * @param identifier The identifier of the subject to receive notifications about 136 * @param listener The callback function to notify 137 */ 138 void addListener(final I identifier, final Consumer<ImmutableSubjectData> listener); 139 140 /** 141 * Get a set of identifiers for all registered subjects of this type 142 * 143 * @return The set of identifiers 144 */ 145 Stream<I> getAllIdentifiers(); 146 147 /** 148 * Get the identifier for the subject holding default data for subjects of this type 149 * 150 * @return The id for the default subject of this type 151 */ 152 SubjectRef<SubjectType<?>> getDefaultIdentifier(); 153}