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.impl; 018 019import ca.stellardrift.permissionsex.PermissionsEngine; 020import ca.stellardrift.permissionsex.PermissionsEngineBuilder; 021import ca.stellardrift.permissionsex.exception.PermissionsLoadingException; 022import ca.stellardrift.permissionsex.impl.config.FilePermissionsExConfiguration; 023import com.google.auto.service.AutoService; 024import io.leangen.geantyref.TypeToken; 025import org.checkerframework.checker.nullness.qual.Nullable; 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028import org.spongepowered.configurate.ConfigurateException; 029import org.spongepowered.configurate.gson.GsonConfigurationLoader; 030import org.spongepowered.configurate.hocon.HoconConfigurationLoader; 031import org.spongepowered.configurate.loader.ConfigurationLoader; 032import org.spongepowered.configurate.util.CheckedFunction; 033import org.spongepowered.configurate.util.UnmodifiableCollections; 034import org.spongepowered.configurate.yaml.NodeStyle; 035import org.spongepowered.configurate.yaml.YamlConfigurationLoader; 036 037import javax.sql.DataSource; 038import java.nio.file.Path; 039import java.nio.file.Paths; 040import java.sql.SQLException; 041import java.util.Map; 042import java.util.concurrent.Executor; 043import java.util.concurrent.ForkJoinPool; 044import java.util.function.Supplier; 045 046import static java.util.Objects.requireNonNull; 047import static net.kyori.adventure.text.Component.text; 048 049public final class PermissionsExBuilder<C> implements PermissionsEngineBuilder<C> { 050 final Class<C> configType; 051 @Nullable Path configFile; 052 @Nullable Path baseDirectory; 053 @Nullable Logger logger; 054 @Nullable Executor asyncExecutor; 055 CheckedFunction<String, @Nullable DataSource, SQLException> databaseProvider = $ -> null; 056 057 PermissionsExBuilder(final Class<C> configType) { 058 this.configType = configType; 059 } 060 061 @Override 062 public PermissionsEngineBuilder<C> configuration(final Path configFile) { 063 this.configFile = configFile; 064 return this; 065 } 066 067 @Override 068 public PermissionsEngineBuilder<C> baseDirectory(final Path baseDir) { 069 this.baseDirectory = baseDir; 070 return this; 071 } 072 073 @Override 074 public PermissionsEngineBuilder<C> logger(final Logger logger) { 075 this.logger = requireNonNull(logger, "logger"); 076 return this; 077 } 078 079 @Override 080 public PermissionsEngineBuilder<C> asyncExecutor(final Executor executor) { 081 this.asyncExecutor = requireNonNull(executor, "executor"); 082 return this; 083 } 084 085 @Override 086 public PermissionsEngineBuilder<C> databaseProvider(final CheckedFunction<String, @Nullable DataSource, SQLException> databaseProvider) { 087 this.databaseProvider = requireNonNull(databaseProvider, "databaseProvider"); 088 return this; 089 } 090 091 @Override 092 public PermissionsEx<?> build() throws PermissionsLoadingException { 093 return (PermissionsEx<?>) this.buildWithConfig().getKey(); 094 } 095 096 @Override 097 public Map.Entry<PermissionsEngine, Supplier<C>> buildWithConfig() throws PermissionsLoadingException { 098 if (this.logger == null) { 099 this.logger = LoggerFactory.getLogger("PermissionsEx"); 100 } 101 102 if (this.asyncExecutor == null) { 103 this.asyncExecutor = ForkJoinPool.commonPool(); 104 } 105 106 if (this.configFile == null) { 107 throw new PermissionsLoadingException(text("Configuration file has not been set")); 108 } 109 110 if (this.baseDirectory == null) { 111 this.baseDirectory = Paths.get("."); 112 } 113 114 final FilePermissionsExConfiguration<C> config = makeConfiguration(this.configFile); 115 final PermissionsEx<C> engine = new PermissionsEx<>( 116 this.logger, 117 this.baseDirectory, 118 this.asyncExecutor, 119 this.databaseProvider 120 ); 121 122 engine.initialize(config); 123 return UnmodifiableCollections.immutableMapEntry(engine, engine.config()::getPlatformConfig); 124 } 125 126 private FilePermissionsExConfiguration<C> makeConfiguration(final Path configFile) throws PermissionsLoadingException { 127 final String fileName = configFile.getFileName().toString(); 128 final ConfigurationLoader<?> loader; 129 if (fileName.endsWith(".yml") || fileName.endsWith(".yaml")) { 130 loader = YamlConfigurationLoader.builder() 131 .path(configFile) 132 .nodeStyle(NodeStyle.BLOCK) 133 .defaultOptions(FilePermissionsExConfiguration.PEX_OPTIONS) 134 .build(); 135 } else if (fileName.endsWith(".conf") || fileName.endsWith(".hocon")) { 136 loader = HoconConfigurationLoader.builder() 137 .path(configFile) 138 .defaultOptions(FilePermissionsExConfiguration.PEX_OPTIONS) 139 .build(); 140 } else if (fileName.endsWith(".json")) { 141 loader = GsonConfigurationLoader.builder() 142 .indent(2) 143 .defaultOptions(FilePermissionsExConfiguration.PEX_OPTIONS) 144 .build(); 145 } else { 146 throw new PermissionsLoadingException(Messages.CONFIG_ERROR_UNKNOWN_FORMAT.tr(fileName)); 147 } 148 149 try { 150 return FilePermissionsExConfiguration.fromLoader(loader, this.configType); 151 } catch (final ConfigurateException ex) { 152 throw new PermissionsLoadingException(Messages.CONFIG_ERROR_LOAD.tr(ex)); 153 } 154 } 155 156 @AutoService(PermissionsEngineBuilder.Factory.class) 157 public static class Factory implements PermissionsEngineBuilder.Factory { 158 159 @Override 160 public <C> PermissionsEngineBuilder<C> newBuilder(final Class<C> configType) { 161 return new PermissionsExBuilder<>(configType); 162 } 163 164 } 165 166}