net.dmulloy2.ultimatearena.api.ArenaType.java Source code

Java tutorial

Introduction

Here is the source code for net.dmulloy2.ultimatearena.api.ArenaType.java

Source

/**
 * UltimateArena - fully customizable PvP arenas
 * Copyright (C) 2012 - 2015 MineSworn
 * Copyright (C) 2013 - 2015 dmulloy2
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.dmulloy2.ultimatearena.api;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Level;

import lombok.Getter;
import net.dmulloy2.io.Closer;
import net.dmulloy2.ultimatearena.UltimateArena;
import net.dmulloy2.ultimatearena.arenas.Arena;
import net.dmulloy2.ultimatearena.types.ArenaConfig;
import net.dmulloy2.ultimatearena.types.ArenaCreator;
import net.dmulloy2.ultimatearena.types.ArenaZone;

import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;

/**
 * Represents an arena type.
 *
 * @author dmulloy2
 */

@Getter
public abstract class ArenaType {
    private boolean initialized;

    private File file;
    private File dataFolder;
    private ArenaLogger logger;
    private UltimateArena plugin;
    private ArenaClassLoader classLoader;
    private ArenaDescription description;

    // Base Constructor
    public ArenaType() {
    }

    // ---- Optional Hooks

    /**
     * Called when this ArenaType is enabled.
     */
    public void onEnable() {
    }

    /**
     * Called when this ArenaType is disabled.
     */
    public void onDisable() {
    }

    /**
     * Called when UltimateArena is reloaded.
     */
    public void onReload() {
    }

    /**
     * Gets the {@link ArenaZone} associated with this ArenaType. Will return a
     * default ArenaZone if this method is not overriden.
     *
     * @param file Data file
     * @return The ArenaZone
     */
    public ArenaZone getArenaZone(File file) {
        return new ArenaZone(this, file);
    }

    /**
     * Gets the {@link ArenaConfig} associated with this ArenaType. Will return
     * a default ArenaConfig if this method is not overriden.
     *
     * @return The ArenaConfig
     */
    public ArenaConfig newConfig() {
        String name = getName().toLowerCase();
        return new ArenaConfig(plugin, name, new File(dataFolder, "config.yml"));
    }

    /**
     * Gets the {@link ArenaConfig} associated with this ArenaType for an arena.
     * Will return a default ArenaConfig if this method is not overriden.
     *
     * @param az Arena to get the config for
     * @return The ArenaConfig
     */
    public ArenaConfig newConfig(ArenaZone az) {
        return new ArenaConfig(az);
    }

    // ---- Required Hooks

    /**
     * Gets the {@link ArenaCreator} associated with this ArenaType. Must be
     * overriden.
     *
     * @param player {@link Player} creating the arena
     * @param name Name of the arena
     * @return The ArenaCreator
     */
    public abstract ArenaCreator newCreator(Player player, String name);

    /**
     * Gets the {@link Arena} associated with this ArenaType. Must be overriden.
     *
     * @param az Underlying {@link ArenaZone}
     * @return The Arena
     */
    public abstract Arena newArena(ArenaZone az);

    /**
     * Gets the name of this ArenaType.
     *
     * @return The name of this ArenaType
     */
    public final String getName() {
        return getDescription().getName();
    }

    /**
     * Gets the stylized name of this ArenaType.
     *
     * @return The stylized name of this ArenaType
     */
    public final String getStylizedName() {
        return getDescription().getStylized();
    }

    final void initialize(UltimateArena plugin, ArenaDescription description, ArenaClassLoader classLoader,
            File file, File dataFolder) {
        Validate.isTrue(!initialized, "Already initialized!");

        this.plugin = plugin;
        this.description = description;
        this.classLoader = classLoader;
        this.file = file;
        this.dataFolder = dataFolder;
        this.logger = new ArenaLogger(this);
        this.initialized = true;
    }

    // ---- Configuration

    /**
     * Loads this type's config. If the config doesn't exist, the default config
     * is saved.
     *
     * @return The loaded config
     */
    public final ArenaConfig loadConfig() {
        saveDefaultConfig();
        return getConfig();
    }

    protected ArenaConfig config;

    /**
     * Gets this type's configuration.
     *
     * @return This type's configuration
     */
    public final ArenaConfig getConfig() {
        if (config == null) {
            try {
                saveDefaultConfig();
                config = newConfig();
            } catch (Throwable ex) {
                getLogger().log(Level.WARNING, "Failed to obtain configuration: ", ex);
            }
        }

        return config;
    }

    /**
     * Saves this type's default config.
     */
    public void saveDefaultConfig() {
        File file = new File(dataFolder, "config.yml");
        if (!file.exists())
            saveResource("config.yml", false);
    }

    /**
     * Saves this type's default config
     *
     * @param defaultType if this is a default arena type
     * @deprecated Meaning is misleading
     * @see #saveDefaultConfig()
     * @see #saveDefaultJarConfig()
     */
    @Deprecated
    public void saveDefaultConfig(boolean defaultType) {
        if (defaultType)
            saveDefaultJarConfig();
        else
            saveDefaultConfig();
    }

    /**
     * Saves this type's default config from the UltimateArena jar.
     * <p>
     * Note: This should only be called by default types.
     */
    protected void saveDefaultJarConfig() {
        String name = getName().toLowerCase();
        InputStream in = plugin.getResource("configs/" + name + "Config.yml");
        if (in == null)
            throw new IllegalStateException("saveDefaultJarConfig() can only be called by default types!");

        File outFile = new File(dataFolder, "config.yml");
        if (!outFile.exists())
            saveResource(in, outFile);
    }

    /**
     * Reloads this type's configuration.
     */
    public final void reloadConfig() {
        if (config != null)
            config.reload();
    }

    // ---- Utility Methods (Credit to Bukkit for the resource methods)

    /**
     * Saves the raw contents of any resource embedded with a plugin's .jar file
     * assuming it can be found using {@link #getResource(String)}.<br>
     * The resource is saved into the plugin's data folder using the same
     * hierarchy as the .jar file (subdirectories are preserved).
     *
     * @param resourcePath the embedded resource path to look for within the
     *        plugin's .jar file. (No preceding slash).
     * @param replace if true, the embedded resource will overwrite the contents
     *        of an existing file.
     * @throws IllegalArgumentException if the resource path is empty or
     *         points to a nonexistent resource.
     */
    protected final void saveResource(String resourcePath, boolean replace) {
        Validate.notEmpty(resourcePath, "resourcePath cannot be empty!");

        File outFile = null;
        try (Closer closer = new Closer()) {
            resourcePath = resourcePath.replace('\\', '/');
            InputStream in = closer.register(getResource(resourcePath));
            if (in == null) {
                logger.log(Level.WARNING,
                        "The embedded resource '" + resourcePath + "' cannot be found in " + file);
                return;
            }

            outFile = new File(dataFolder, resourcePath);
            int lastIndex = resourcePath.lastIndexOf('/');
            File outDir = new File(dataFolder, resourcePath.substring(0, lastIndex >= 0 ? lastIndex : 0));

            if (!outDir.exists()) {
                outDir.mkdirs();
            }

            if (!outFile.exists() || replace) {
                OutputStream out = closer.register(new FileOutputStream(outFile));
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            }
        } catch (IOException ex) {
            logger.log(Level.SEVERE, "Could not save " + resourcePath + " to " + outFile, ex);
        }
    }

    private final void saveResource(InputStream in, File outFile) {
        try (Closer closer = new Closer()) {
            closer.register(in);
            if (!outFile.exists()) {
                OutputStream out = closer.register(new FileOutputStream(outFile));
                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
            }
        } catch (IOException ex) {
            logger.log(Level.SEVERE, "Could not save " + outFile.getName() + " to " + outFile, ex);
        }
    }

    /**
     * Gets an embedded resource in this arena type's jar file.
     *
     * @param fileName Name of the resource
     * @return File, or null if it cannot be found
     */
    protected final InputStream getResource(String fileName) {
        try {
            URL url = getClassLoader().getResource(fileName);
            if (url == null)
                return null;

            URLConnection connection = url.openConnection();
            connection.setUseCaches(false);
            return connection.getInputStream();
        } catch (Throwable ex) {
        }
        return null;
    }

    /**
     * Registers a {@link Listener} via UltimateArena
     *
     * @param listener {@link Listener} to register
     * @throws IllegalArgumentException if listener is null
     */
    protected final void registerListener(Listener listener) {
        Validate.notNull(listener, "listener cannot be null!");
        plugin.getServer().getPluginManager().registerEvents(listener, plugin);
    }

    // ---- Generic Methods

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof ArenaType) {
            ArenaType that = (ArenaType) obj;
            return that.getName().equals(getName());
        }

        return false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        int hash = 38;
        hash *= 1 + getName().hashCode();
        return hash;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return getDescription().getFullName() + " by " + getDescription().getAuthor();
    }
}