com.megahardcore.config.messages.MessageConfig.java Source code

Java tutorial

Introduction

Here is the source code for com.megahardcore.config.messages.MessageConfig.java

Source

/*
 * This file is part of
 * MegaHardCore Server Plugin for Minecraft
 *
 * Copyright (C) 2012 Ryan Hamshire
 * Copyright (C) 2013 Diemex
 *
 * MegaHardCore is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * MegaHardCore is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with MegaHardCore.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.megahardcore.config.messages;

import com.megahardcore.MegaHardCore;
import com.megahardcore.service.IoHelper;
import com.megahardcore.service.config.ConfigNode;
import com.megahardcore.service.config.ModularConfig;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;

import java.io.*;
import java.nio.charset.Charset;
import java.util.logging.Level;

/** Configuration handler for the messages.yml file. */
public class MessageConfig extends ModularConfig {
    /** File reference. */
    private final File file;

    /** Configuration object reference. */
    private final YamlConfiguration config;

    /**
     * Constructor.
     *
     * @param plugin - Plugin instance.
     */
    public MessageConfig(MegaHardCore plugin) {
        super(plugin);
        file = new File(plugin.getDataFolder().getPath() + File.separator + "messages.yml");
        config = YamlConfiguration.loadConfiguration(file);
    }

    @Override
    public void starting() {
        loadDefaults(config);
        reload();
        save();
    }

    @Override
    public void closing() {
        OPTIONS.clear();
        //reload();
        //save();
    }

    @Override
    public void save() {
        //Cleanly rewrite the config every time to remove comments and derp etc.
        try {
            FileConfiguration reorderedConfig = new YamlConfiguration();
            for (MessageNode node : MessageNode.values()) {
                if (node.isCategoryNode()) //convert the parsed enum value to a string representation
                    reorderedConfig.set(node.getPath(), getCat(node).name().toLowerCase());
                else
                    switch (node.getVarType()) {
                    case COLOR:
                        if (getColor(node) == null)
                            reorderedConfig.set(node.getPath(), "NONE");
                        else
                            reorderedConfig.set(node.getPath(), getColor(node).name());
                        break;
                    default:
                        reorderedConfig.set(node.getPath(), OPTIONS.get(node));
                    }
            }
            reorderedConfig.save(file);
        } catch (IOException e) {
            plugin.getLogger().log(Level.SEVERE, "File I/O Exception on saving messages.yml", e);
        }
        setHeader(file);
    }

    /**
     * Set the header of the file before writing to it with bukkit yaml implementation
     *
     * @param file file to write the header to
     */
    private void setHeader(File file) {
        try {
            //Write header to a new file
            ByteArrayOutputStream memStream = new ByteArrayOutputStream();
            OutputStreamWriter memWriter = new OutputStreamWriter(memStream, Charset.forName("UTF-8").newEncoder());
            String[] header = { "Messages sent by MegaHardCore",
                    "Messages are only sent for modules that are activated",
                    "Modes (has to match exactly, ignores case)",
                    "Disabled: Message won't be sent even if feature that would sent the message is active",
                    "One_Time: Will be sent to every player only once",
                    "Notification: Gets sent every time with a timeout to prevent spamming chat",
                    "Tutorial: Sent a limited number of times and not displayed after 3 times",
                    "Broadcast: Shown to whole server. Only few messages make sense to be broadcasted",
                    "Variables:", "$ALLCAPS is a variable and will be filled in for some messages",
                    "$PLAYER: Affected player", "$PLAYERS: If multiple players are affected",
                    "$DEATH_MSG: Death message if someone dies", "$ITEMS: a player lost" };
            StringBuilder sb = new StringBuilder();
            sb.append(StringUtils.repeat("#", 100));
            sb.append(System.lineSeparator());
            for (String line : header) {
                sb.append('#');
                sb.append(StringUtils.repeat(" ", 100 / 2 - line.length() / 2 - 1));
                sb.append(line);
                sb.append(StringUtils.repeat(" ", 100 / 2 - line.length() / 2 - 1 - line.length() % 2));
                sb.append('#');
                sb.append(String.format(System.lineSeparator()));
            }
            sb.append(StringUtils.repeat("#", 100));
            sb.append(String.format(System.lineSeparator()));
            //String.format: %n as platform independent line seperator
            memWriter.write(sb.toString());
            memWriter.close();

            IoHelper.writeHeader(file, memStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void set(String path, Object value) {
        config.set(path, value);
    }

    @Override
    public void reload() {
        // Reload config from file.
        try {
            if (!file.exists())
                file.createNewFile();
            config.load(file);
            loadSettings(config);
            boundsCheck();
        } catch (FileNotFoundException e) {
            plugin.getLogger().log(Level.SEVERE, "File messages.yml not found.", e);
        } catch (IOException e) {
            plugin.getLogger().log(Level.SEVERE, "File I/O Exception on saving messages.yml", e);
        } catch (InvalidConfigurationException e) {
            plugin.getLogger().log(Level.SEVERE, "Invalid configuration for messages.yml", e);
        }
    }

    @Override
    public void loadSettings(ConfigurationSection config) {
        for (MessageNode node : MessageNode.values()) {
            if (node.isCategoryNode())
                updateCat(node, config);
            else
                updateOption(node, config);
        }
    }

    @Override
    public void loadDefaults(ConfigurationSection config) {
        for (MessageNode node : MessageNode.values()) {
            if (!config.contains(node.getPath())) {
                config.set(node.getPath(), node.getDefaultValue());
            }
        }
    }

    @Override
    public String getString(ConfigNode node) {
        return ChatColor.translateAlternateColorCodes('&', super.getString(node));
    }

    private void updateCat(MessageNode node, ConfigurationSection config) {
        String val = config.getString(node.getPath());
        MsgCategory cat = null;
        try {
            cat = MsgCategory.valueOf(val != null ? val.toUpperCase() : "");
        } catch (IllegalArgumentException ignored) {
        } finally {
            if (cat == null)
                cat = node.getDefaultCategory();
            OPTIONS.put(node, cat);
        }
    }

    /**
     * Match the value of the node to the MsgCategory, also gets the mode of a given message if found
     *
     * @param node node to check
     *
     * @return the {@link MsgCategory} enum value of the node or null if the enum name of the node doesn't end with _MODE or value of the node is not found.
     */
    public MsgCategory getCat(MessageNode node) {
        MessageNode modeNode = null;
        Object obj = null;
        try {
            modeNode = MessageNode.valueOf(!node.name().endsWith("_MODE") ? node.name() + "_MODE" : node.name());
        } catch (IllegalArgumentException ignored) {
        } finally {
            //if (!node.name().endsWith("_MODE"))
            //Validate.notNull(modeNode, "There is no MODE node set for " + node.name());
            if (modeNode != null)
                obj = OPTIONS.get(modeNode);
        }
        return obj instanceof MsgCategory ? (MsgCategory) obj : null;
    }

    /**
     * Get how often a message is supposed to be displayed
     *
     * @return how often this message will be displayed. -1 = no limit
     */
    public int getMsgCount(MessageNode node) {
        switch (getCat(node)) {
        case TUTORIAL:
            return 3;
        case NOTIFICATION:
            return -1;
        case BROADCAST:
            return -1;
        case ONE_TIME:
            return 1;
        default:
            throw new UnsupportedOperationException("Not Implemented MsgCategory");
        }
    }

    @Override
    public void boundsCheck() {
        for (ConfigNode node : MessageNode.values()) {
            if (node.getSubType() == ConfigNode.SubType.PLAYER_NAME) {
                String nodeValue = config.getString(node.getPath());
                if (nodeValue != null)
                    set(node, nodeValue.length() > 16 ? nodeValue.substring(0, 16) : nodeValue);
                updateOption(node, config); //Kinda a quick workaround for the set() method in the super class not being implemented
            }
        }
    }
}