Skip to content

Instantly share code, notes, and snippets.

@Wolvereness
Created August 3, 2012 22:18
Show Gist options
  • Save Wolvereness/3252102 to your computer and use it in GitHub Desktop.
Save Wolvereness/3252102 to your computer and use it in GitHub Desktop.
Localized abstract class
import static java.util.logging.Level.SEVERE;
import static org.bukkit.ChatColor.translateAlternateColorCodes;
import static org.bukkit.configuration.file.YamlConfiguration.loadConfiguration;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.Validate;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import com.google.common.io.ByteStreams;
/**
* Licensed under GNU GPL v3
* @author Wolfe
* @param <Message> The enum for this Localized
*/
public abstract class Localized<Message extends Enum<Message>> {
private final YamlConfiguration config;
private final Logger logger;
private final Random random;
/**
* @param plugin plugin to consider for getting resources
*/
public Localized(final Plugin plugin) {
this(plugin, new Random());
}
/**
* @param plugin plugin to consider for getting resources
* @param random a random number generator, if messages have multiple outputs
*/
public Localized(final Plugin plugin, final Random random) {
this.random = random;
this.logger = plugin.getLogger();
final String language = String.valueOf(plugin.getConfig().get(getLanguageNode())).toUpperCase();
final File file = new File(plugin.getDataFolder(),"Locales" + File.separatorChar + language + ".yml");
if(file.exists()) {
config = loadConfiguration(file);
} else {
config = new YamlConfiguration();
}
InputStream resource = plugin.getResource("Locales/" + language + ".yml");
final YamlConfiguration defaults = new YamlConfiguration();
if(resource == null) {
resource = plugin.getResource("Locales/ENGLISH.yml");
}
try {
defaults.loadFromString(new String(ByteStreams.toByteArray(resource), "UTF-8"));
} catch (final IOException e) {
throw new RuntimeException(e);
} catch (final InvalidConfigurationException e) {
throw new RuntimeException(e);
} finally {
try {
resource.close();
} catch (final IOException e) {
}
}
config.addDefaults(defaults);
config.options().copyDefaults(true);
try {
config.save(file);
} catch (final IOException e) {
plugin.getLogger().log(Level.WARNING, "Failed to save locale file " + file, e);
}
}
/**
* @return The string name of the language node
*/
public abstract String getLanguageNode();
/**
* @param message message to get
* @return message stored
*/
public String getMessage(final Message message) {
final String string = toFormattableMessage(message);
return string == null ? null : translateAlternateColorCodes('&', string);
}
/**
* This recursion will only be a problem with nested values,
* where an infinite loop is worse than stack overflow.
*/
private String parseObject(final Object obj) {
if (obj == null)
return null;
if (obj.getClass().isArray())
return parseObject(Array.get(obj, (int) (random.nextDouble() * Array.getLength(obj))));
if (obj instanceof List) {
final List<?> list = (List<?>) obj;
return parseObject(list.get((int) (random.nextDouble() * list.size())));
}
return obj.toString();
}
/**
* Sends the recipient a formatted message located at the node defined
* @param recipient Player to receive the message
* @param message Message to send
* @param args The arguments to String.format
*/
public void sendMessage(final CommandSender recipient, final Message message, final Object...args) {
final String string = toFormattableMessage(message);
if (string == null) {
recipient.sendMessage("ERROR_"+message);
logger.log(SEVERE,"Unknown message:" + message + " name:" + message.name(), new Exception());
} else {
recipient.sendMessage(translateAlternateColorCodes('&', String.format(string, args)));
}
}
private String toFormattableMessage(final Message message) {
Validate.notNull(message, "Cannot retrieve message for null");
return parseObject(config.get(message.name()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment