/**
* PermissionsEx
* Copyright (C) zml and PermissionsEx contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ninja.leaping.permissionsex.config;
import com.google.common.reflect.TypeToken;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.hocon.HoconConfigurationLoader;
import ninja.leaping.configurate.loader.ConfigurationLoader;
import ninja.leaping.configurate.objectmapping.ObjectMapper;
import ninja.leaping.configurate.objectmapping.ObjectMappingException;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializers;
import ninja.leaping.permissionsex.backend.DataStore;
import ninja.leaping.permissionsex.exception.PEBKACException;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static ninja.leaping.permissionsex.util.Translations.t;
/**
* Configuration for PermissionsEx. This is designed to be serialized with a Configurate {@link ObjectMapper}
*/
@ConfigSerializable
public class FilePermissionsExConfiguration implements PermissionsExConfiguration {
private static final TypeToken<FilePermissionsExConfiguration> TYPE = TypeToken.of(FilePermissionsExConfiguration.class);
static {
TypeSerializers.getDefaultSerializers().registerType(TypeToken.of(DataStore.class), new DataStoreSerializer());
}
private final ConfigurationLoader<?> loader;
private final ConfigurationNode node;
@Setting private Map<String, DataStore> backends;
@Setting("default-backend") private String defaultBackend;
@Setting private boolean debug;
@Setting("server-tags") private List<String> serverTags;
protected FilePermissionsExConfiguration(ConfigurationLoader<?> loader, ConfigurationNode node) {
this.loader = loader;
this.node = node;
}
public static FilePermissionsExConfiguration fromLoader(ConfigurationLoader<?> loader) throws IOException {
ConfigurationNode node = loader.load();
ConfigurationNode fallbackConfig;
try {
fallbackConfig = FilePermissionsExConfiguration.loadDefaultConfiguration();
} catch (IOException e) {
throw new Error("PEX's default configuration could not be loaded!", e);
}
ConfigTransformations.versions().apply(node);
node.mergeValuesFrom(fallbackConfig);
ConfigurationNode defBackendNode = node.getNode("default-backend");
if (defBackendNode.isVirtual() || defBackendNode.getValue() == null) { // Set based on whether or not the H2 backend is available
defBackendNode.setValue("default-file");
/*try {
Class.forName("org.h2.Driver");
defBackendNode.setValue("default");
} catch (ClassNotFoundException e) {
defBackendNode.setValue("default-file");
}*/
}
FilePermissionsExConfiguration config = new FilePermissionsExConfiguration(loader, node);
config.load();
return config;
}
private void load() throws IOException {
try {
ObjectMapper.forObject(this).populate(this.node);
} catch (ObjectMappingException e) {
throw new IOException(e);
}
this.loader.save(node);
}
@Override
public void save() throws IOException {
try {
ObjectMapper.forObject(this).serialize(this.node);
} catch (ObjectMappingException e) {
throw new IOException(e);
}
this.loader.save(node);
}
@Override
public DataStore getDataStore(String name) {
return backends.get(name);
}
@Override
public DataStore getDefaultDataStore() {
return backends.get(defaultBackend);
}
@Override
public boolean isDebugEnabled() {
return debug;
}
@Override
public List<String> getServerTags() {
return Collections.unmodifiableList(serverTags);
}
@Override
public void validate() throws PEBKACException {
if (backends.isEmpty()) {
throw new PEBKACException(t("No backends defined!"));
}
if (defaultBackend == null) {
throw new PEBKACException(t("Default backend is not set!"));
}
if (!backends.containsKey(defaultBackend)) {
throw new PEBKACException(t("Default backend % is not an available backend! Choices are: %s", defaultBackend, backends.keySet()));
}
}
@Override
public PermissionsExConfiguration reload() throws IOException {
ConfigurationNode node = this.loader.load();
FilePermissionsExConfiguration ret = new FilePermissionsExConfiguration(this.loader, node);
ret.load();
return ret;
}
public static ConfigurationNode loadDefaultConfiguration() throws IOException {
final URL defaultConfig = FilePermissionsExConfiguration.class.getResource("default.conf");
if (defaultConfig == null) {
throw new Error(t("Default config file is not present in jar!").translate(Locale.getDefault()));
}
HoconConfigurationLoader fallbackLoader = HoconConfigurationLoader.builder().setURL(defaultConfig).build();
return fallbackLoader.load();
}
}