001/*
002 * Trident - A Multithreaded Server Alternative
003 * Copyright 2014 The TridentSDK Team
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 */
017
018package net.tridentsdk.config;
019
020import com.google.common.base.Charsets;
021import com.google.gson.JsonIOException;
022import com.google.gson.JsonObject;
023import com.google.gson.JsonParser;
024import com.google.gson.JsonSyntaxException;
025import net.tridentsdk.plugin.Plugin;
026import net.tridentsdk.util.TridentLogger;
027
028import javax.annotation.concurrent.ThreadSafe;
029import java.io.File;
030import java.io.IOException;
031import java.nio.file.Files;
032import java.nio.file.Path;
033import java.nio.file.Paths;
034import java.nio.file.StandardOpenOption;
035
036/**
037 * Represents the root ConfigSection of a Configuration file Controls all IO actions of the file
038 *
039 * @author The TridentSDK Team
040 * @since 0.3-alpha-DP
041 */
042@ThreadSafe
043public class Config extends ConfigSection {
044    private final Path path;
045
046    /**
047     * Creates a new JSON configuration file from NIO path
048     *
049     * @param path the NIO path for file directory
050     */
051    public Config(Path path) {
052        this.path = path;
053        this.reload();
054    }
055
056    /**
057     * Creates a new JSON configuration file using the file that may or may not exist
058     *
059     * @param file the file to use as a JSON config, preferably suffixed with {@code .json}
060     */
061    public Config(File file) {
062        this.path = file.toPath();
063        this.reload();
064    }
065
066    /**
067     * Creates a new JSON configuration file from the String path
068     *
069     * @param path the path
070     */
071    public Config(String path) {
072        this.path = Paths.get(path);
073        this.reload();
074    }
075
076    /**
077     * Creates a new configuration using the plugin's config direction
078     *
079     * @param plugin   the plugin directory to use
080     * @param fileName the file name
081     */
082    public Config(Plugin plugin, String fileName) {
083        this(plugin.configDirectory() + fileName);
084    }
085
086    /**
087     * Gets the path to the configuration file
088     *
089     * @return the path where this configuration is stored
090     */
091    public Path path() {
092        return path;
093    }
094
095    @Override
096    public void save() {
097        JsonObject object;
098        synchronized (handleLock) {
099            object = jsonHandle;
100        }
101
102        try {
103            Files.write(this.path, GsonFactory.gson().toJson(object).getBytes(Charsets.UTF_8),
104                    StandardOpenOption.TRUNCATE_EXISTING);
105        } catch (IOException ex) {
106            TridentLogger.get().error(ex);
107        }
108    }
109
110    @Override
111    public Config rootSection() {
112        return this;
113    }
114
115    @Override
116    public Config parentSection() {
117        return this;
118    }
119
120    /**
121     * Reloads the configuration
122     */
123    public void reload() {
124        JsonObject object = null;
125        try {
126            object = Files.isReadable(this.path) ? new JsonParser().parse(
127                    Files.newBufferedReader(this.path, Charsets.UTF_8)).getAsJsonObject() : new JsonObject();
128        } catch (JsonIOException | JsonSyntaxException | IOException e) {
129            TridentLogger.get().error(e);
130        }
131
132        synchronized (handleLock) {
133            jsonHandle = object;
134        }
135    }
136}