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.exception.PermissionsLoadingException;
020import org.checkerframework.checker.nullness.qual.Nullable;
021import org.slf4j.Logger;
022import org.spongepowered.configurate.util.CheckedFunction;
023
024import javax.sql.DataSource;
025import java.nio.file.Path;
026import java.sql.SQLException;
027import java.util.Map;
028import java.util.concurrent.Executor;
029import java.util.concurrent.ForkJoinPool;
030import java.util.function.Supplier;
031
032/**
033 * A builder for creating permissions engines.
034 *
035 * @param <C> The type of an extra platform-specific configuration
036 *           that will be injected into the engine configuration
037 * @since 2.0.0
038 */
039public interface PermissionsEngineBuilder<C> {
040
041    /**
042     * Set the file that this engine will load its configuration from.
043     *
044     * @param configFile The configuration file.
045     * @return this builder
046     * @since 2.0.0
047     */
048    PermissionsEngineBuilder<C> configuration(final Path configFile);
049
050    /**
051     * Set the base directory for this engine instance.
052     *
053     * @param baseDir the base directory
054     * @return this builder
055     * @since 2.0.0
056     */
057    PermissionsEngineBuilder<C> baseDirectory(Path baseDir);
058
059    /**
060     * Set a logger that will receive messages logged by the engine.
061     *
062     * <p>By default, this will be a logger named {@code PermissionsEx}</p>
063     *
064     * @param logger the logger to log to
065     * @return this builder
066     * @since 2.0.0
067     */
068    PermissionsEngineBuilder<C> logger(final Logger logger);
069
070    /**
071     * Set an executor to use to execute asynchronous tasks.
072     *
073     * <p>By default, the {@link ForkJoinPool#commonPool()} will be used.</p>
074     *
075     * @param executor The executor
076     * @return this builder
077     * @since 2.0.0
078     */
079    PermissionsEngineBuilder<C> asyncExecutor(final Executor executor);
080
081    /**
082     * Set a callback function that will be queried to provide database for a url.
083     *
084     * <p>Implementations may allow this url to be an alias to an existing connection definition,
085     * rather than an actual URL.</p>
086     *
087     * @param databaseProvider The database provider
088     * @return this builder
089     * @since 2.0.0
090     */
091    PermissionsEngineBuilder<C> databaseProvider(final CheckedFunction<String, @Nullable DataSource, SQLException> databaseProvider);
092
093    /**
094     * Create a full engine.
095     *
096     * @return the built engine
097     * @throws PermissionsLoadingException if any errors occur while loading the engine or its configuration
098     * @since 2.0.0
099     */
100    PermissionsEngine build() throws PermissionsLoadingException;
101
102    /**
103     * Create a full engine, and return it with a supplier for the implementation configuration
104     *
105     * @return the built engine
106     * @throws PermissionsLoadingException if any errors occur while loading the engine or its configuration
107     * @since 2.0.0
108     */
109    Map.Entry<PermissionsEngine, Supplier<C>> buildWithConfig() throws PermissionsLoadingException;
110
111    /**
112     * A service interface for creating new engine builders.
113     *
114     * <p>Implementations of the PermissionsEx engine must register a {@link java.util.ServiceLoader}-compatible service
115     * implementing this interface.</p>
116     *
117     * @see PermissionsEngine#builder() to create a new builder
118     * @since 2.0.0
119     */
120    interface Factory {
121
122        /**
123         * Create a new empty builder.
124         *
125         * @return a new builder
126         * @since 2.0.0
127         */
128        default PermissionsEngineBuilder<Void> newBuilder() {
129            return this.newBuilder(Void.class);
130        }
131
132        /**
133         * Create a new empty builder.
134         *
135         * @return a new builder
136         * @since 2.0.0
137         */
138        <C> PermissionsEngineBuilder<C> newBuilder(final Class<C> configType);
139    }
140}