summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsnowleo <schneeleo@gmail.com>2011-10-13 01:39:52 +0200
committersnowleo <schneeleo@gmail.com>2011-10-13 01:40:11 +0200
commitd3aaf3c14ac5d227861820b8ae769db89b6501e6 (patch)
treef36d42bbb07dcf588c1cc7088768d4c9fdb262ec
parentd732821e06f917085a2c659879a14da1100ea2e8 (diff)
downloadEssentials-d3aaf3c14ac5d227861820b8ae769db89b6501e6.tar
Essentials-d3aaf3c14ac5d227861820b8ae769db89b6501e6.tar.gz
Essentials-d3aaf3c14ac5d227861820b8ae769db89b6501e6.tar.lz
Essentials-d3aaf3c14ac5d227861820b8ae769db89b6501e6.tar.xz
Essentials-d3aaf3c14ac5d227861820b8ae769db89b6501e6.zip
New storage system for settings (WIP)
-rw-r--r--Essentials/nbproject/project.properties9
-rw-r--r--Essentials/src/com/earth2me/essentials/settings/Backup.java17
-rw-r--r--Essentials/src/com/earth2me/essentials/settings/General.java37
-rw-r--r--Essentials/src/com/earth2me/essentials/settings/Location.java28
-rw-r--r--Essentials/src/com/earth2me/essentials/settings/Settings.java40
-rw-r--r--Essentials/src/com/earth2me/essentials/storage/Comment.java16
-rw-r--r--Essentials/src/com/earth2me/essentials/storage/ListType.java14
-rw-r--r--Essentials/src/com/earth2me/essentials/storage/MapType.java14
-rw-r--r--Essentials/src/com/earth2me/essentials/storage/StorageObject.java244
-rw-r--r--Essentials/test/com/earth2me/essentials/StorageTest.java34
-rw-r--r--lib/lombok-0.10.1.jarbin0 -> 1668835 bytes
11 files changed, 450 insertions, 3 deletions
diff --git a/Essentials/nbproject/project.properties b/Essentials/nbproject/project.properties
index db78855e6..17af87b61 100644
--- a/Essentials/nbproject/project.properties
+++ b/Essentials/nbproject/project.properties
@@ -1,6 +1,7 @@
annotation.processing.enabled=true
-annotation.processing.enabled.in.editor=false
-annotation.processing.run.all.processors=true
+annotation.processing.enabled.in.editor=true
+annotation.processing.processors.list=lombok.core.AnnotationProcessor
+annotation.processing.run.all.processors=false
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=Essentials
application.vendor=
@@ -68,6 +69,7 @@ file.reference.iCo4.jar=../lib/iCo4.jar
file.reference.iCo5.jar=../lib/iCo5.jar
file.reference.iCo6.jar=../lib/iCo6.jar
file.reference.junit-4.5.jar=..\\lib\\junit_4\\junit-4.5.jar
+file.reference.lombok-0.10.1.jar=../lib/lombok-0.10.1.jar
file.reference.MultiCurrency.jar=../lib/MultiCurrency.jar
file.reference.Permissions3.jar=../lib/Permissions3.jar
file.reference.PermissionsBukkit-1.2.jar=../lib/PermissionsBukkit-1.2.jar
@@ -86,7 +88,8 @@ javac.classpath=\
${file.reference.BOSEconomy7.jar}:\
${file.reference.PermissionsEx.jar}:\
${file.reference.bPermissions.jar}:\
- ${file.reference.PermissionsBukkit-1.2.jar}
+ ${file.reference.PermissionsBukkit-1.2.jar}:\
+ ${file.reference.lombok-0.10.1.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
diff --git a/Essentials/src/com/earth2me/essentials/settings/Backup.java b/Essentials/src/com/earth2me/essentials/settings/Backup.java
new file mode 100644
index 000000000..1b59260db
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/settings/Backup.java
@@ -0,0 +1,17 @@
+package com.earth2me.essentials.settings;
+
+import com.earth2me.essentials.storage.Comment;
+import com.earth2me.essentials.storage.StorageObject;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class Backup extends StorageObject
+{
+ @Comment("Interval in minutes")
+ private long interval = 60;
+ @Comment("Add a command that backups your data, e.g. 'rdiff-backup World1 backups/World1'")
+ private String command;
+}
diff --git a/Essentials/src/com/earth2me/essentials/settings/General.java b/Essentials/src/com/earth2me/essentials/settings/General.java
new file mode 100644
index 000000000..b88242cd6
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/settings/General.java
@@ -0,0 +1,37 @@
+package com.earth2me.essentials.settings;
+
+import com.earth2me.essentials.storage.Comment;
+import com.earth2me.essentials.storage.MapType;
+import com.earth2me.essentials.storage.StorageObject;
+import java.util.HashMap;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class General extends StorageObject
+{
+ public General()
+ {
+ super();
+ locations.put("Test", new Location());
+ locations.put("Test2", new Location());
+ }
+ private boolean debug = false;
+ private boolean signsDisabled = false;
+ private int test = 1;
+ private String test2 = "\tline1\nline2\nline3";
+ @Comment("Backup runs a command while saving is disabled")
+ private Backup backup = new Backup();
+ @Comment(
+ {
+ "Set the locale here, if you want to change the language of Essentials.",
+ "If this is not set, Essentials will use the language of your computer.",
+ "Available locales: da, de, en, fr, nl"
+ })
+ private String locale;
+ @MapType(Location.class)
+ private Map<String, Location> locations = new HashMap<String, Location>();
+}
diff --git a/Essentials/src/com/earth2me/essentials/settings/Location.java b/Essentials/src/com/earth2me/essentials/settings/Location.java
new file mode 100644
index 000000000..0535fdf52
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/settings/Location.java
@@ -0,0 +1,28 @@
+package com.earth2me.essentials.settings;
+
+import com.earth2me.essentials.storage.StorageObject;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.bukkit.Server;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class Location extends StorageObject
+{
+ private String worldName = "Test";
+ private double x;
+ private double y;
+ private double z;
+ private Float yaw;
+ private Float pitch;
+
+ public org.bukkit.Location getBukkit(Server server)
+ {
+ if (yaw == null || pitch == null)
+ {
+ return new org.bukkit.Location(server.getWorld(worldName), x, y, z);
+ }
+ return new org.bukkit.Location(server.getWorld(worldName), x, y, z, yaw, pitch);
+ }
+}
diff --git a/Essentials/src/com/earth2me/essentials/settings/Settings.java b/Essentials/src/com/earth2me/essentials/settings/Settings.java
new file mode 100644
index 000000000..1d3256c84
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/settings/Settings.java
@@ -0,0 +1,40 @@
+package com.earth2me.essentials.settings;
+
+import com.earth2me.essentials.storage.Comment;
+import com.earth2me.essentials.storage.ListType;
+import com.earth2me.essentials.storage.MapType;
+import com.earth2me.essentials.storage.StorageObject;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class Settings extends StorageObject
+{
+ public Settings()
+ {
+ super();
+ locations.put("Test", new Location());
+ m_o_t_d.add("Welcome to the server!");
+ m_o_t_d.add("Have a nice day!\nwoooooo");
+ }
+ private boolean test;
+ private Boolean test2;
+ @Comment(
+ {
+ "Hello!",
+ "World"
+ })
+ private String yay = "null";
+ private String lol = "lol: 1";
+ private General general = new General();
+ @MapType(Location.class)
+ private Map<String, Location> locations = new HashMap<String, Location>();
+ @ListType
+ private List<String> m_o_t_d = new ArrayList<String>();
+}
diff --git a/Essentials/src/com/earth2me/essentials/storage/Comment.java b/Essentials/src/com/earth2me/essentials/storage/Comment.java
new file mode 100644
index 000000000..b43cec980
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/storage/Comment.java
@@ -0,0 +1,16 @@
+package com.earth2me.essentials.storage;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Target(ElementType.FIELD)
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Comment
+{
+ String[] value() default "";
+} \ No newline at end of file
diff --git a/Essentials/src/com/earth2me/essentials/storage/ListType.java b/Essentials/src/com/earth2me/essentials/storage/ListType.java
new file mode 100644
index 000000000..9bf6e2e64
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/storage/ListType.java
@@ -0,0 +1,14 @@
+package com.earth2me.essentials.storage;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ListType
+{
+ Class value() default String.class;
+}
diff --git a/Essentials/src/com/earth2me/essentials/storage/MapType.java b/Essentials/src/com/earth2me/essentials/storage/MapType.java
new file mode 100644
index 000000000..dc5636315
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/storage/MapType.java
@@ -0,0 +1,14 @@
+package com.earth2me.essentials.storage;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MapType
+{
+ Class value() default String.class;
+} \ No newline at end of file
diff --git a/Essentials/src/com/earth2me/essentials/storage/StorageObject.java b/Essentials/src/com/earth2me/essentials/storage/StorageObject.java
new file mode 100644
index 000000000..5840e33a7
--- /dev/null
+++ b/Essentials/src/com/earth2me/essentials/storage/StorageObject.java
@@ -0,0 +1,244 @@
+package com.earth2me.essentials.storage;
+
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.yaml.snakeyaml.DumperOptions;
+import org.yaml.snakeyaml.TypeDescription;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+
+
+public class StorageObject
+{
+ protected Class<? extends StorageObject> clazz;
+
+ protected StorageObject()
+ {
+ }
+ private static Map<Class, Constructor> constructors = new HashMap<Class, Constructor>();
+
+ public static <T extends StorageObject> T load(Class<? extends T> clazz, Reader reader)
+ {
+ Constructor constructor;
+ if (constructors.containsKey(clazz))
+ {
+ constructor = constructors.get(clazz);
+ }
+ else
+ {
+ constructor = prepareConstructor(clazz);
+ constructors.put(clazz, constructor);
+ }
+
+ final Yaml yaml = new Yaml(constructor);
+ T ret = (T)yaml.load(reader);
+ if (ret == null)
+ {
+ try
+ {
+ ret = (T)clazz.newInstance();
+ }
+ catch (InstantiationException ex)
+ {
+ Logger.getLogger(StorageObject.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ catch (IllegalAccessException ex)
+ {
+ Logger.getLogger(StorageObject.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ ret.clazz = clazz;
+ return ret;
+ }
+
+ private static Constructor prepareConstructor(final Class<?> clazz)
+ {
+ final Constructor constructor = new Constructor(clazz);
+ final Set<Class> classes = new HashSet<Class>();
+
+ prepareConstructor(constructor, classes, clazz);
+ return constructor;
+ }
+
+ private static void prepareConstructor(final Constructor constructor, final Set<Class> classes, final Class clazz)
+ {
+ classes.add(clazz);
+ final TypeDescription description = new TypeDescription(clazz);
+ for (Field field : clazz.getDeclaredFields())
+ {
+ final ListType listType = field.getAnnotation(ListType.class);
+ if (listType != null)
+ {
+ description.putListPropertyType(field.getName(), listType.value());
+ if (StorageObject.class.isAssignableFrom(listType.value())
+ && !classes.contains(listType.value()))
+ {
+ prepareConstructor(constructor, classes, listType.value());
+ }
+ }
+ final MapType mapType = field.getAnnotation(MapType.class);
+ if (mapType != null)
+ {
+ description.putMapPropertyType(field.getName(), String.class, mapType.value());
+ if (StorageObject.class.isAssignableFrom(mapType.value())
+ && !classes.contains(mapType.value()))
+ {
+ prepareConstructor(constructor, classes, mapType.value());
+ }
+ }
+ if (StorageObject.class.isAssignableFrom(field.getType())
+ && !classes.contains(field.getType()))
+ {
+ prepareConstructor(constructor, classes, field.getType());
+ }
+ }
+ constructor.addTypeDescription(description);
+ }
+ private transient Yaml yaml;
+
+ public void save(final PrintWriter writer)
+ {
+ final DumperOptions ops = new DumperOptions();
+ yaml = new Yaml(ops);
+ try
+ {
+ writeToFile(this, writer, 0, clazz);
+ }
+ catch (IllegalArgumentException ex)
+ {
+ Logger.getLogger(StorageObject.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ catch (IllegalAccessException ex)
+ {
+ Logger.getLogger(StorageObject.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ private void writeToFile(final Object object, final PrintWriter writer, final int depth, final Class clazz) throws IllegalArgumentException, IllegalAccessException
+ {
+ for (Field field : clazz.getDeclaredFields())
+ {
+ final int modifier = field.getModifiers();
+ if (Modifier.isPrivate(modifier) && !Modifier.isTransient(depth) && !Modifier.isStatic(depth))
+ {
+ field.setAccessible(true);
+ final boolean commentPresent = field.isAnnotationPresent(Comment.class);
+ final String name = field.getName();
+ if (commentPresent)
+ {
+ final Comment comments = field.getAnnotation(Comment.class);
+ for (String comment : comments.value())
+ {
+ final String trimmed = comment.trim();
+ if (trimmed.isEmpty())
+ {
+ continue;
+ }
+ writeIndention(writer, depth);
+ writer.print("# ");
+ writer.print(trimmed);
+ writer.println();
+ }
+ }
+
+ final Object data = field.get(object);
+ if (data == null && !commentPresent)
+ {
+ continue;
+ }
+ writeIndention(writer, depth);
+ if (data == null && commentPresent)
+ {
+ writer.print('#');
+ }
+ writer.print(name);
+ writer.print(": ");
+ if (data == null && commentPresent)
+ {
+ writer.println();
+ continue;
+ }
+ if (data instanceof StorageObject)
+ {
+ writer.println();
+ writeToFile(data, writer, depth + 1, data.getClass());
+ }
+ else if (data instanceof Map)
+ {
+ writer.println();
+ for (Entry<String, Object> entry : ((Map<String, Object>)data).entrySet())
+ {
+ final Object value = entry.getValue();
+ if (value != null)
+ {
+ writeIndention(writer, depth + 1);
+ writer.print(entry.getKey());
+ writer.print(": ");
+ if (value instanceof StorageObject)
+ {
+ writer.println();
+ writeToFile(value, writer, depth + 2, value.getClass());
+ }
+ else if (value instanceof String || value instanceof Boolean || value instanceof Number)
+ {
+ yaml.dumpAll(Collections.singletonList(value).iterator(), writer);
+ }
+ else
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+ }
+ }
+ else if (data instanceof Collection)
+ {
+ writer.println();
+ for (Object entry : (Collection<Object>)data)
+ {
+ if (entry != null)
+ {
+ writeIndention(writer, depth + 1);
+ writer.print("- ");
+ if (entry instanceof String || entry instanceof Boolean || entry instanceof Number)
+ {
+ yaml.dumpAll(Collections.singletonList(entry).iterator(), writer);
+ }
+ else
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+ }
+ else if (data instanceof String || data instanceof Boolean || data instanceof Number)
+ {
+ yaml.dumpAll(Collections.singletonList(data).iterator(), writer);
+ }
+ else
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+ }
+
+ private void writeIndention(final PrintWriter writer, final int depth)
+ {
+ for (int i = 0; i < depth; i++)
+ {
+ writer.print(" ");
+ }
+ }
+}
diff --git a/Essentials/test/com/earth2me/essentials/StorageTest.java b/Essentials/test/com/earth2me/essentials/StorageTest.java
new file mode 100644
index 000000000..6ab5980c1
--- /dev/null
+++ b/Essentials/test/com/earth2me/essentials/StorageTest.java
@@ -0,0 +1,34 @@
+package com.earth2me.essentials;
+
+import junit.framework.TestCase;
+import com.earth2me.essentials.settings.Settings;
+import com.earth2me.essentials.storage.StorageObject;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.Reader;
+import org.junit.Test;
+
+
+public class StorageTest extends TestCase
+{
+ @Test
+ public void testSettings()
+ {
+ assertTrue(StorageObject.class.isAssignableFrom(Settings.class));
+ final ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);
+ final Reader reader = new InputStreamReader(bais);
+ final Settings settings = StorageObject.load(Settings.class, reader);
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ final PrintWriter writer = new PrintWriter(baos);
+ settings.save(writer);
+ writer.close();
+ byte[] written = baos.toByteArray();
+ System.out.println(new String(written));
+ final ByteArrayInputStream bais2 = new ByteArrayInputStream(written);
+ final Reader reader2 = new InputStreamReader(bais2);
+ final Settings settings2 = StorageObject.load(Settings.class, reader2);
+ assertEquals("Default and rewritten config should be equal", settings, settings2);
+ }
+}
diff --git a/lib/lombok-0.10.1.jar b/lib/lombok-0.10.1.jar
new file mode 100644
index 000000000..993ebc3c2
--- /dev/null
+++ b/lib/lombok-0.10.1.jar
Binary files differ