net.easymfne.displayframes.Localization.java Source code

Java tutorial

Introduction

Here is the source code for net.easymfne.displayframes.Localization.java

Source

/*
 * This file is part of the DisplayFrames plugin by EasyMFnE.
 * 
 * DisplayFrames 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 any later version.
 * 
 * DisplayFrames 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 details.
 * 
 * You should have received a copy of the GNU General Public License v3 along
 * with DisplayFrames. If not, see <http://www.gnu.org/licenses/>.
 */
package net.easymfne.displayframes;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Level;

import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

/**
 * Utility class with static methods for fetching localized names for items and
 * other content. Can be used to create new localization file templates as well.
 * 
 * @author Eric Hildebrand
 */
public class Localization {

    private static final String LOCALE_FOLDER = File.separator + "locale" + File.separator;
    private static final String LOCALE_EXTENSION = ".lang";
    private static final String ENCHANTED_APPLE_COLOR = ChatColor.AQUA.toString();

    private static YamlConfiguration locale;

    /**
     * Take an enum name string (e.g. "DIAMOND_SWORD") and transform it into a
     * more displayable format (e.g. "Diamond Sword"). This method is typically
     * used as a fallback when no localized name for an object could be found.
     * 
     * @param enumString
     *            String to transform
     * @return Nicely formatted string
     */
    protected static String formatEnumString(String enumString) {
        if (enumString == null) {
            return null;
        }
        if (enumString.length() == 0) {
            return "";
        }
        String[] parts = enumString.split("_");
        for (int i = 0; i < parts.length; i++) {
            parts[i] = parts[i].substring(0, 1).toUpperCase() + parts[i].substring(1).toLowerCase();
        }
        return StringUtils.join(parts, " ");
    }

    /**
     * Process a raw tick count into a nicely formatted display string
     * 
     * @param ticks
     * @return
     */
    protected static String formatTime(int ticks) {
        return String.format("(%d:%02d)", ticks / 1200, (ticks % 1200) / 20);
    }

    /**
     * Get a display String representing an Enchantment and its level.
     * 
     * @param enchant
     * @param level
     * @return
     */
    protected static String getEnchantment(Enchantment enchant, int level) {
        return locale.getString("enchantmentName." + enchant.getName(), formatEnumString(enchant.getName())) + " "
                + locale.getString("enchantmentLevel." + level, "" + level);
    }

    /**
     * Get a display String representing an ItemStack's name based upon its
     * Material and durability values. Handles special cases, or passes the item
     * along to getItemNameNormal() and gets its result.
     * 
     * @param item
     * @return
     */
    protected static String getItemName(ItemStack item) {
        switch (item.getType()) {
        case POTION:
            String potionName = getPotionName(item);
            if (potionName != null) {
                return potionName;
            }
            break;
        case GOLDEN_APPLE:
            if (item.getDurability() != 1) {
                break;
            }
            return ENCHANTED_APPLE_COLOR + getItemNameNormal(item);
        case MONSTER_EGG:
            return getItemNameNormal(item) + locale.getString("eggNames." + item.getDurability(), "");
        case SKULL_ITEM:
            if (item.getDurability() != 3) {
                break;
            }
            SkullMeta meta = (SkullMeta) item.getItemMeta();
            if (meta != null && meta.hasOwner()) {
                return String.format(getItemNameNormal(item), meta.getOwner());
            }
            return getItemNameNormal(new ItemStack(Material.SKULL_ITEM, 1, (short) -1));
        case GOLD_RECORD:
        case GREEN_RECORD:
        case RECORD_3:
        case RECORD_4:
        case RECORD_5:
        case RECORD_6:
        case RECORD_7:
        case RECORD_8:
        case RECORD_9:
        case RECORD_10:
        case RECORD_11:
        case RECORD_12:
            if (!locale.contains("itemName." + item.getType())) {
                break;
            }
            return locale.getString("itemExtra.record", formatEnumString(item.getType().toString()));
        default:
            break;
        }
        return getItemNameNormal(item);
    }

    /**
     * Get a display String representing an ItemStack's name based upon its
     * Material and durability values.
     * 
     * @param item
     * @return
     */
    private static String getItemNameNormal(ItemStack item) {
        /* Defined with specific damage value */
        if (locale.contains("itemName." + item.getType().toString() + ":" + item.getDurability())) {
            return locale.getString("itemName." + item.getType().toString() + ":" + item.getDurability());
        }
        /* Defined generically */
        else if (locale.contains("itemName." + item.getType())) {
            return locale.getString("itemName." + item.getType());
        }
        /* Undefined */
        else {
            return formatEnumString(item.getType().toString());
        }
    }

    /**
     * @return Current locale name for display
     */
    protected static String getLocaleName() {
        return locale.getString("language.name", "Unknown") + " (" + locale.getString("language.code", "N/A") + ")";
    }

    /**
     * Get a display String representing a PotionEffect, including its duration.
     * 
     * @param effect
     * @return
     */
    protected static String getPotionEffect(PotionEffect effect) {
        String level;
        if (locale.contains("potionLevel." + effect.getAmplifier())) {
            level = " " + locale.getString("potionLevel." + effect.getAmplifier());
        } else if (effect.getAmplifier() != 0) {
            level = " " + effect.getAmplifier();
        } else {
            level = "";
        }
        return locale.getString("potionEffect." + effect.getType().getName(),
                formatEnumString(effect.getType().getName())) + level
                + (effect.getDuration() > 19 ? " " + Localization.formatTime(effect.getDuration()) : "");
    }

    /**
     * Get a display String representing a Potion, using its effects and custom
     * effects. Utilized privately by getItemName() in the case that the item is
     * a potion.
     * 
     * @param item
     *            Potion item
     * @return
     */
    private static String getPotionName(ItemStack item) {
        try {
            Potion potion = Potion.fromItemStack(item);
            PotionMeta meta = (PotionMeta) item.getItemMeta();

            if (meta.hasCustomEffects() && !meta.getCustomEffects().isEmpty()
                    && locale.contains("potionName." + meta.getCustomEffects().get(0))) {
                return locale.getString("potionName." + meta.getCustomEffects().get(0));
            } else if (potion.getEffects() != null && !potion.getEffects().isEmpty()
                    && locale.contains("potionName." + potion.getEffects().iterator().next())) {
                return locale.getString("potionName." + potion.getEffects().iterator().next());
            } else {
                return null;
            }
        } catch (IllegalArgumentException e) {
        } catch (ClassCastException e) {
        } catch (NullPointerException e) {
        }
        return null;
    }

    /**
     * Attempt to load a selected locale file by name. If the file cannot be
     * read, fall back to default 'en_US' locale. If that file also cannot be
     * read, use a blank locale (thus all display names come from Bukkit).
     * 
     * @param plugin
     *            DisplayFrames plugin instance
     * @param localeName
     *            Name of desired locale
     */
    protected static void load(DisplayFrames plugin, String localeName) {
        locale = new YamlConfiguration();
        File localeFile = new File(
                plugin.getDataFolder().getAbsolutePath() + LOCALE_FOLDER + localeName + LOCALE_EXTENSION);
        if (!localeFile.exists()) {
            try {
                plugin.saveResource("locale/" + localeName + LOCALE_EXTENSION, false);
            } catch (IllegalArgumentException e) {
                plugin.fancyLog(Level.WARNING, "Locale '" + localeName + "' is not included with this plugin.");
            }
        }
        try {
            locale.load(localeFile);
            plugin.fancyLog("Loaded strings from: " + localeName);
            return;
        } catch (FileNotFoundException e) {
            plugin.fancyLog(Level.WARNING, "Locale file not found for: " + localeName);
        } catch (IOException e) {
            plugin.fancyLog(Level.WARNING, "Locale file readable for: " + localeName);
        } catch (InvalidConfigurationException e) {
            plugin.fancyLog(Level.WARNING, "Locale file has syntax errors: " + localeName);
            e.printStackTrace();
        }
        plugin.fancyLog(Level.WARNING, "Falling back to Bukkit names");
    }

    /**
     * Generate a new locale file template using all Material, Enchantment, and
     * PotionEffectType enum values and their respective display names as
     * returned by {@link #formatEnumString(String) formatEnumString()}.
     * 
     * @param plugin
     *            DisplayFrames instance
     * @return Whether a new template was saved
     */
    protected static boolean makeNewTemplate(DisplayFrames plugin) {
        YamlConfiguration newTemplate = new YamlConfiguration();
        newTemplate.set("_comment_",
                new String[] { "To configure a display name for an item with a specific data",
                        "value, add a new node in the format",
                        "  'ITEM_NAME:#': 'Display Name' (e.g. 'WOOL:0': 'White Wool')",
                        "If an item with a data value is not explicitly defined, it",
                        "will use the general display name from the Material." });
        for (Material material : Material.values()) {
            newTemplate.set("item." + material.name(), formatEnumString(material.name()));
        }
        for (Enchantment enchantment : Enchantment.values()) {
            newTemplate.set("enchantment." + enchantment.getName(), formatEnumString(enchantment.getName()));
        }
        for (PotionEffectType potionEffect : PotionEffectType.values()) {
            if (potionEffect != null) {
                newTemplate.set("potionEffect." + potionEffect.getName(), formatEnumString(potionEffect.getName()));
            }
        }
        File localeFile = new File(
                plugin.getDataFolder().getAbsolutePath() + LOCALE_FOLDER + "new" + LOCALE_EXTENSION);
        try {
            newTemplate.save(localeFile);
            return true;
        } catch (IOException e) {
            return false;
        }
    }

}