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; 018 019import ca.stellardrift.permissionsex.context.ContextDefinitionProvider; 020import ca.stellardrift.permissionsex.context.ContextInheritance; 021import ca.stellardrift.permissionsex.datastore.DataStore; 022import ca.stellardrift.permissionsex.rank.RankLadderCollection; 023import ca.stellardrift.permissionsex.subject.CalculatedSubject; 024import ca.stellardrift.permissionsex.subject.SubjectRef; 025import ca.stellardrift.permissionsex.subject.SubjectType; 026import ca.stellardrift.permissionsex.subject.SubjectTypeCollection; 027import org.checkerframework.checker.nullness.qual.Nullable; 028 029import java.util.Collection; 030import java.util.Set; 031import java.util.concurrent.CompletableFuture; 032import java.util.function.Consumer; 033import java.util.function.Function; 034import java.util.regex.Pattern; 035 036/** 037 * A PermissionsEx engine. 038 * 039 * @since 2.0.0 040 */ 041public interface PermissionsEngine extends ContextDefinitionProvider { 042 043 /** 044 * Create a new builder for an engine. 045 * 046 * @return the engine builder 047 * @since 2.0.0 048 */ 049 static PermissionsEngineBuilder<Void> builder() { 050 return EngineBuilderService.ACTIVE_BUILDER.newBuilder(); 051 } 052 053 /** 054 * Create a new builder for an engine. 055 * 056 * @return the engine builder 057 * @since 2.0.0 058 */ 059 static <C> PermissionsEngineBuilder<C> builder(final Class<C> configType) { 060 return EngineBuilderService.ACTIVE_BUILDER.newBuilder(configType); 061 } 062 063 // -- Internal subject types -- // 064 065 /** 066 * Subjects holding data that will be applied to every subject of a type. 067 * 068 * @return the {@code fallback} subject type 069 * @since 2.0.0 070 */ 071 SubjectTypeCollection<SubjectType<?>> defaults(); 072 073 /** 074 * Subjects holding data that will be applied to subjects of each type when no other data is available. 075 * 076 * @return the {@code fallback} subject type 077 * @since 2.0.0 078 */ 079 SubjectTypeCollection<SubjectType<?>> fallbacks(); 080 081 // -- Working with subject types -- // 082 083 /** 084 * Register subject types with the engine. 085 * 086 * @param types the types to register 087 * @since 2.0.0 088 */ 089 void registerSubjectTypes(final SubjectType<?>... types); 090 091 /** 092 * Get a subject type by name. 093 * 094 * <p>If this subject type has not been seen before, it will be registered.</p> 095 * 096 * @param type the type identifier 097 * @return a subject type instance, never null 098 * @since 2.0.0 099 */ 100 <I> SubjectTypeCollection<I> subjects(final SubjectType<I> type); 101 102 /** 103 * Resolve a subject from a reference. 104 * 105 * @param reference the subject reference to resolve 106 * @param <I> identifier type 107 * @return a future providing the resolved subject 108 * @since 2.0.0 109 */ 110 default <I> CompletableFuture<CalculatedSubject> subject(final SubjectRef<I> reference) { 111 return this.subjects(reference.type()).get(reference.identifier()); 112 } 113 114 /** 115 * Get subject types with actively stored data. 116 * 117 * @return an unmodifiable view of the actively loaded subject types 118 */ 119 Collection<? extends SubjectTypeCollection<?>> loadedSubjectTypes(); 120 121 /** 122 * Get all registered subject types 123 * 124 * @return a stream producing all subject types 125 * @since 2.0.0 126 */ 127 Set<SubjectType<?>> knownSubjectTypes(); 128 129 /** 130 * Get a cache for rank ladders known by the engine. 131 * 132 * <p>Rank ladders allow for promotion and demotion of a subject among a 133 * set of ranked parents.</p> 134 * 135 * @return the ladder cache 136 * @since 2.0.0 137 */ 138 RankLadderCollection ladders(); 139 140 /** 141 * Perform a low-level bulk operation. 142 * 143 * <p>This can be used for transforming subjects if the subject type definition changes, and 144 * any large data changes that require information that may no longer be valid with current 145 * subject type options.</p> 146 * 147 * <p>When possible, higher-level bulk query API (not yet written) should be used instead.</p> 148 * 149 * @param actor the action to perform 150 * @param <V> the result type 151 * @return a future completing with the result of the action 152 */ 153 <V> CompletableFuture<V> doBulkOperation(final Function<DataStore, CompletableFuture<V>> actor); 154 155 /** 156 * Get the current context inheritance. 157 * 158 * <p>No update listener will be registered</p> 159 * 160 * @return a future providing the current context inheritance data 161 * @see #contextInheritance(Consumer) for more details on context inheritance 162 * @since 2.0.0 163 */ 164 default CompletableFuture<ContextInheritance> contextInheritance() { 165 return this.contextInheritance((Consumer<ContextInheritance>) null); 166 } 167 168 /** 169 * Get context inheritance data. 170 * 171 * <p>The result of the future is immutable -- to take effect, the object returned by any 172 * update methods in {@link ContextInheritance} must be passed to {@link #contextInheritance(ContextInheritance)}. 173 * It follows that anybody else's changes will not appear in the returned inheritance object -- so if updates are 174 * desired providing a callback function is important.</p> 175 * 176 * @param listener A callback function that will be triggered whenever there is a change to the context inheritance 177 * @return A future providing the current context inheritance data 178 * @since 2.0.0 179 */ 180 CompletableFuture<ContextInheritance> contextInheritance(final @Nullable Consumer<ContextInheritance> listener); 181 182 /** 183 * Update the context inheritance when values have been changed 184 * 185 * @param newInheritance The modified inheritance object 186 * @return A future containing the latest context inheritance object 187 * @since 2.0.0 188 */ 189 CompletableFuture<ContextInheritance> contextInheritance(ContextInheritance newInheritance); 190 191 // -- Engine state -- // 192 193 /** 194 * Get whether or not debug mode is enabled. 195 * 196 * <p>When debug mode is enabled, all permission queries will be logged to the engine's 197 * active logger.</p> 198 * 199 * @return the debug mode state 200 * @since 2.0.0 201 */ 202 boolean debugMode(); 203 204 /** 205 * Set the active debug mode state. 206 * 207 * @param enabled whether debug mode is enabled 208 * @since 2.0.0 209 * @see #debugMode() for information on the consequences of debug mode 210 */ 211 default void debugMode(final boolean enabled) { 212 this.debugMode(enabled, null); 213 } 214 215 /** 216 * Set the active debug mode state, and a filter. 217 * 218 * @param enabled whether debug mode is enabled 219 * @param filter a filter for values (permissions, options, and subject names) that will be 220 * logged by debug mode. 221 * @since 2.0.0 222 * @see #debugMode() for information on the consequences of debug mode 223 */ 224 void debugMode(final boolean enabled, final @Nullable Pattern filter); 225 226}