summaryrefslogtreecommitdiffstats
path: root/Essentials/src/com/earth2me/essentials/storage/YamlStorageWriter.java
diff options
context:
space:
mode:
Diffstat (limited to 'Essentials/src/com/earth2me/essentials/storage/YamlStorageWriter.java')
-rw-r--r--Essentials/src/com/earth2me/essentials/storage/YamlStorageWriter.java295
1 files changed, 295 insertions, 0 deletions
diff --git a/Essentials/src/com/earth2me/essentials/storage/YamlStorageWriter.java b/Essentials/src/com/earth2me/essentials/storage/YamlStorageWriter.java
new file mode 100644
index 000000000..209de1ed7
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/storage/YamlStorageWriter.java
@@ -0,0 +1,295 @@
+package com.earth2me.essentials.storage;
+
+import java.io.PrintWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.material.MaterialData;
+import org.yaml.snakeyaml.Yaml;
+
+
+public class YamlStorageWriter implements IStorageWriter
+{
+ private transient static Pattern pattern = Pattern.compile("\\w");
+ private transient final PrintWriter writer;
+ private transient static final Yaml YAML = new Yaml();
+
+ public YamlStorageWriter(final PrintWriter writer)
+ {
+ this.writer = writer;
+ }
+
+ public void save(final StorageObject object)
+ {
+ try
+ {
+ writeToFile(object, 0, object.getClass());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ Logger.getLogger(YamlStorageWriter.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ catch (IllegalAccessException ex)
+ {
+ Logger.getLogger(YamlStorageWriter.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ private void writeToFile(final Object object, final int depth, final Class clazz) throws IllegalAccessException
+ {
+ for (Field field : clazz.getDeclaredFields())
+ {
+ final int modifier = field.getModifiers();
+ if (Modifier.isPrivate(modifier) && !Modifier.isTransient(modifier) && !Modifier.isStatic(modifier))
+ {
+ field.setAccessible(true);
+
+ final Object data = field.get(object);
+ if (writeKey(field, depth, data))
+ {
+ continue;
+ }
+ if (data instanceof StorageObject)
+ {
+ writer.println();
+ writeToFile(data, depth + 1, data.getClass());
+ }
+ else if (data instanceof Map)
+ {
+ writeMap((Map<Object, Object>)data, depth + 1);
+ }
+ else if (data instanceof Collection)
+ {
+ writeCollection((Collection<Object>)data, depth + 1);
+ }
+ else if (data instanceof Location)
+ {
+ writeLocation((Location)data, depth + 1);
+ }
+ else
+ {
+ writeScalar(data);
+ writer.println();
+ }
+ }
+ }
+ }
+
+ private boolean writeKey(final Field field, final int depth, final Object data)
+ {
+ final boolean commentPresent = writeComment(field, depth);
+ if (data == null && !commentPresent)
+ {
+ return true;
+ }
+ writeIndention(depth);
+ if (data == null && commentPresent)
+ {
+ writer.print('#');
+ }
+ final String name = field.getName();
+ writer.print(name);
+ writer.print(": ");
+ if (data == null && commentPresent)
+ {
+ writer.println();
+ writer.println();
+ return true;
+ }
+ return false;
+ }
+
+ private boolean writeComment(final Field field, final int depth)
+ {
+ final boolean commentPresent = field.isAnnotationPresent(Comment.class);
+ if (commentPresent)
+ {
+ final Comment comments = field.getAnnotation(Comment.class);
+ for (String comment : comments.value())
+ {
+ final String trimmed = comment.trim();
+ if (trimmed.isEmpty())
+ {
+ continue;
+ }
+ writeIndention(depth);
+ writer.print("# ");
+ writer.print(trimmed);
+ writer.println();
+ }
+ }
+ return commentPresent;
+ }
+
+ private void writeCollection(final Collection<Object> data, final int depth) throws IllegalAccessException
+ {
+ writer.println();
+ if (data.isEmpty())
+ {
+ writer.println();
+ }
+ for (Object entry : data)
+ {
+ if (entry != null)
+ {
+ writeIndention(depth);
+ writer.print("- ");
+ if (entry instanceof StorageObject)
+ {
+ writer.println();
+ writeToFile(entry, depth + 1, entry.getClass());
+ }
+ else if (entry instanceof Location)
+ {
+ writeLocation((Location)entry, depth + 1);
+ }
+ else
+ {
+ writeScalar(entry);
+ }
+ }
+ }
+ writer.println();
+ }
+
+ private void writeMap(final Map<Object, Object> data, final int depth) throws IllegalArgumentException, IllegalAccessException
+ {
+ writer.println();
+ if (data.isEmpty())
+ {
+ writer.println();
+ }
+ for (Entry<Object, Object> entry : data.entrySet())
+ {
+ final Object value = entry.getValue();
+ if (value != null)
+ {
+ writeIndention(depth);
+ writeKey(entry.getKey());
+ writer.print(": ");
+ if (value instanceof StorageObject)
+ {
+ writer.println();
+ writeToFile(value, depth + 1, value.getClass());
+ }
+ else if (value instanceof Collection)
+ {
+ writeCollection((Collection<Object>)value, depth + 1);
+ }
+ else if (value instanceof Location)
+ {
+ writeLocation((Location)value, depth + 1);
+ }
+ else
+ {
+ writeScalar(value);
+ writer.println();
+ }
+ }
+ }
+ }
+
+ private void writeIndention(final int depth)
+ {
+ for (int i = 0; i < depth; i++)
+ {
+ writer.print(" ");
+ }
+ }
+
+ private void writeScalar(final Object data)
+ {
+ if (data instanceof String || data instanceof Boolean || data instanceof Number)
+ {
+ synchronized (YAML)
+ {
+ YAML.dumpAll(Collections.singletonList(data).iterator(), writer);
+ }
+ }
+ else if (data instanceof Material)
+ {
+ writer.println(data.toString().toLowerCase());
+ }
+ else if (data instanceof MaterialData)
+ {
+ final MaterialData matData = (MaterialData)data;
+ writer.println(matData.getItemType().toString().toLowerCase()
+ + (matData.getData() > 0 ? ":" + matData.getData() : ""));
+ }
+ else if (data instanceof ItemStack)
+ {
+ final ItemStack itemStack = (ItemStack)data;
+ writer.println(itemStack.getType().toString().toLowerCase()
+ + (itemStack.getDurability() > 0 ? ":" + itemStack.getDurability() : "")
+ + " " + itemStack.getAmount());
+ }
+ else
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private void writeKey(final Object data)
+ {
+ if (data instanceof String || data instanceof Boolean || data instanceof Number)
+ {
+ String output = data.toString();
+ if (pattern.matcher(output).find())
+ {
+ writer.print('"');
+ writer.print(output.replace("\"", "\\\""));
+ writer.print('"');
+ }
+ else
+ {
+ writer.print(output);
+ }
+ }
+ else if (data instanceof Material)
+ {
+ writer.print(data.toString().toLowerCase());
+ }
+ else if (data instanceof MaterialData)
+ {
+ final MaterialData matData = (MaterialData)data;
+ writer.print(matData.getItemType().toString().toLowerCase()
+ + (matData.getData() > 0 ? ":" + matData.getData() : ""));
+ }
+ else
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private void writeLocation(final Location entry, final int depth)
+ {
+ writer.println();
+ writeIndention(depth);
+ writer.print("world: ");
+ writeScalar(entry.getWorld().getName());
+ writeIndention(depth);
+ writer.print("x: ");
+ writeScalar(entry.getX());
+ writeIndention(depth);
+ writer.print("y: ");
+ writeScalar(entry.getY());
+ writeIndention(depth);
+ writer.print("z: ");
+ writeScalar(entry.getZ());
+ writeIndention(depth);
+ writer.print("yaw: ");
+ writeScalar(entry.getYaw());
+ writeIndention(depth);
+ writer.print("pitch: ");
+ writeScalar(entry.getPitch());
+ }
+}