package com.kokakiwi.mclauncher.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import org.yaml.snakeyaml.Yaml;
public class Configuration
{
private final Map<String, Object> config = new HashMap<String, Object>();
public boolean load(File file)
{
return load(file, true);
}
public boolean load(File file, boolean overwrite)
{
final String ext = file.getName().substring(
file.getName().lastIndexOf(".") + 1);
String type;
if (ext.equals("yml"))
{
type = "yaml";
}
else
{
type = "";
}
try
{
return load(new FileInputStream(file), type);
}
catch (final FileNotFoundException e)
{
e.printStackTrace();
}
return false;
}
public boolean load(InputStream inputStream)
{
return load(inputStream, true);
}
public boolean load(InputStream inputStream, boolean overwrite)
{
return load(inputStream, "", overwrite);
}
public boolean load(InputStream inputFile, String type)
{
return load(inputFile, type, true);
}
@SuppressWarnings("unchecked")
public boolean load(InputStream inputFile, String type, boolean overwrite)
{
if (type.equalsIgnoreCase("yaml"))
{
final Yaml yamlParser = new Yaml();
final Map<String, Object> data = (Map<String, Object>) yamlParser
.load(inputFile);
if (data != null)
{
merge(data, config, overwrite);
}
}
else
{
final Properties props = new Properties();
try
{
props.load(inputFile);
}
catch (final IOException e)
{
e.printStackTrace();
return false;
}
for (final Object key : props.stringPropertyNames())
{
final String name = key.toString();
final String value = props.getProperty(name);
config.put(name, value);
}
}
return true;
}
public void load(Configuration config)
{
load(config, true);
}
public void load(Configuration config, boolean overwrite)
{
merge(config.getConfig(), this.config, overwrite);
}
public void merge(Map<String, Object> from, Map<String, Object> to)
{
merge(from, to, true);
}
@SuppressWarnings("unchecked")
public void merge(Map<String, Object> from, Map<String, Object> to,
boolean overwrite)
{
for (final String key : from.keySet())
{
if (to.get(key) == null)
{
to.put(key, from.get(key));
}
else
{
if (to.get(key) instanceof Map)
{
merge((Map<String, Object>) from.get(key),
(Map<String, Object>) to.get(key), overwrite);
}
else
{
if (overwrite)
{
to.put(key, from.get(key));
}
}
}
}
}
public void set(String name, Object value)
{
config.put(name, value);
}
/**
* Return String property. Or null if node doesn't exists.
*
* @param name
* Node name
* @return Node value, null if doesn't exists.
*/
public String getString(String name)
{
return getString(name, null);
}
public String getString(String name, String def)
{
final Object value = get(name);
return value == null ? def : value.toString();
}
@SuppressWarnings("unchecked")
public List<Object> getList(String name)
{
return (List<Object>) get(name);
}
@SuppressWarnings("unchecked")
public List<String> getStringList(String name)
{
return (List<String>) get(name);
}
@SuppressWarnings("unchecked")
public List<Map<String, Object>> getMapList(String name)
{
return (List<Map<String, Object>>) get(name);
}
public Map<String, String> getStringMap(String name)
{
final Map<String, String> map = new HashMap<String, String>();
for (final Entry<String, Object> entry : getNode(name).entrySet())
{
if (entry.getValue() instanceof String)
{
map.put(entry.getKey(), entry.getValue().toString());
}
}
return map;
}
public Map<String, Object> getMap(String name)
{
return getNode(name);
}
@SuppressWarnings("unchecked")
public Map<String, Object> getNode(String name)
{
return (Map<String, Object>) get(name);
}
public boolean getBoolean(String name)
{
return getBoolean(name, false);
}
public boolean getBoolean(String name, boolean def)
{
return (Boolean) (get(name) == null ? def : get(name));
}
public int getInteger(String name)
{
return (Integer) get(name);
}
@SuppressWarnings("unchecked")
public Object get(String nodeName)
{
Object result = null;
if (config.containsKey(nodeName))
{
result = config.get(nodeName);
}
else
{
if (nodeName.contains("."))
{
final String[] nodes = nodeName.split("\\.");
Object currentNode = null;
for (final String node : nodes)
{
if (currentNode == null)
{
currentNode = config.get(node);
}
else
{
if (currentNode instanceof Map)
{
currentNode = ((Map<String, Object>) currentNode)
.get(node);
}
else
{
break;
}
}
}
result = currentNode;
}
else
{
result = config.get(nodeName);
}
}
return result;
}
public Map<String, Object> getConfig()
{
return config;
}
public boolean has(String node)
{
return get(node) != null;
}
public void clear()
{
config.clear();
}
public void save(File file) throws Exception
{
final OutputStream out = new FileOutputStream(file);
final Yaml yaml = new Yaml();
final byte[] data = yaml.dump(config).getBytes("UTF-8");
out.write(data);
out.close();
}
public static Configuration getLauncherConfiguration()
{
final Configuration config = new Configuration();
// Load JavaConfig class.
try
{
Class<?> clazz = configClass;
if (clazz == null)
{
clazz = Configuration.class.getClassLoader().loadClass(
"com.kokakiwi.mclauncher.core.JavaConfig");
}
final Method method = clazz.getMethod("config");
final Configuration javaConfig = (Configuration) method
.invoke(null);
if (javaConfig.getBoolean("load.user-config"))
{
config.load(Configuration.class
.getResourceAsStream("/config/default.yml"), "yaml");
}
config.load(javaConfig);
}
catch (final Exception e)
{
config.load(Configuration.class
.getResourceAsStream("/config/default.yml"), "yaml");
}
return config;
}
private static Class<?> configClass = null;
public static void setConfigClass(Class<?> configClass)
{
Configuration.configClass = configClass;
}
}