From e295cf598e0045222ebdc09bc2191e40f8bd8e83 Mon Sep 17 00:00:00 2001 From: Walter Oggioni Date: Wed, 17 Jul 2019 17:45:31 +0200 Subject: [PATCH] added configuration class --- .../worth/serialization/ValueDumper.java | 10 ++++- .../worth/serialization/ValueParser.java | 19 ++++++--- .../serialization/binary/JBONDumper.java | 13 ++++++ .../serialization/binary/JBONParser.java | 13 ++++++ .../worth/serialization/json/JSONDumper.java | 12 ++++++ .../worth/serialization/json/JSONParser.java | 11 +++++ .../net/woggioni/worth/value/ObjectValue.java | 11 ++--- .../java/net/woggioni/worth/xface/Value.java | 9 ++++ .../serialization/json/PerformanceTest.java | 26 ++++++++++-- .../java/net/woggioni/worth/utils/Tuple2.java | 26 ++++++++++++ .../value/ObjectValueImplementationTest.java | 42 +++++++++++++++++++ 11 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 src/test/java/net/woggioni/worth/utils/Tuple2.java create mode 100644 src/test/java/net/woggioni/worth/value/ObjectValueImplementationTest.java diff --git a/src/main/java/net/woggioni/worth/serialization/ValueDumper.java b/src/main/java/net/woggioni/worth/serialization/ValueDumper.java index ff349e1..c3ee3d0 100644 --- a/src/main/java/net/woggioni/worth/serialization/ValueDumper.java +++ b/src/main/java/net/woggioni/worth/serialization/ValueDumper.java @@ -17,6 +17,8 @@ import java.util.Map; public abstract class ValueDumper implements Dumper { + protected final Value.Configuration cfg; + @RequiredArgsConstructor protected static class StackLevel { public int index = 0; @@ -64,10 +66,16 @@ public abstract class ValueDumper implements Dumper { protected ArrayDeque stack; - protected ValueDumper() { + protected ValueDumper(Value.Configuration cfg) { + this.cfg = cfg; stack = new ArrayDeque<>(); } + protected ValueDumper() { + this(Value.configuration); + } + + @Override public void dump(Value value, OutputStream stream) { throw new NotImplementedException("Method not implemented"); diff --git a/src/main/java/net/woggioni/worth/serialization/ValueParser.java b/src/main/java/net/woggioni/worth/serialization/ValueParser.java index 9e2c78b..1800d39 100644 --- a/src/main/java/net/woggioni/worth/serialization/ValueParser.java +++ b/src/main/java/net/woggioni/worth/serialization/ValueParser.java @@ -15,6 +15,8 @@ import java.util.ArrayDeque; public class ValueParser implements Parser { + protected final Value.Configuration cfg; + @RequiredArgsConstructor protected static class StackLevel { public final Value value; @@ -33,12 +35,12 @@ public class ValueParser implements Parser { protected static class ObjectStackLevel extends StackLevel { public String currentKey; - public ObjectStackLevel() { - super(ObjectValue.newInstance(), -1); + public ObjectStackLevel(Value.Configuration cfg) { + super(ObjectValue.newInstance(cfg), -1); } - public ObjectStackLevel(long expectedSize) { - super(ObjectValue.newInstance(), expectedSize); + public ObjectStackLevel(Value.Configuration cfg, long expectedSize) { + super(ObjectValue.newInstance(cfg), expectedSize); } } @@ -57,6 +59,11 @@ public class ValueParser implements Parser { } protected ValueParser() { + this(Value.configuration); + } + + protected ValueParser(Value.Configuration cfg) { + this.cfg = cfg; stack = new ArrayDeque<>(); stack.push(new ArrayStackLevel()); } @@ -77,11 +84,11 @@ public class ValueParser implements Parser { } protected void beginObject() { - stack.push(new ObjectStackLevel()); + stack.push(new ObjectStackLevel(cfg)); } protected void beginObject(long size) { - stack.push(new ObjectStackLevel(size)); + stack.push(new ObjectStackLevel(cfg, size)); } diff --git a/src/main/java/net/woggioni/worth/serialization/binary/JBONDumper.java b/src/main/java/net/woggioni/worth/serialization/binary/JBONDumper.java index fb6f35c..7d0af1e 100644 --- a/src/main/java/net/woggioni/worth/serialization/binary/JBONDumper.java +++ b/src/main/java/net/woggioni/worth/serialization/binary/JBONDumper.java @@ -3,6 +3,7 @@ package net.woggioni.worth.serialization.binary; import lombok.SneakyThrows; import net.woggioni.worth.exception.NotImplementedException; import net.woggioni.worth.serialization.ValueDumper; +import net.woggioni.worth.serialization.json.JSONDumper; import net.woggioni.worth.utils.Leb128; import net.woggioni.worth.utils.WorthUtils; import net.woggioni.worth.value.ArrayValue; @@ -21,6 +22,18 @@ public class JBONDumper extends ValueDumper { return new JBONDumper(); } + public static Dumper newInstance(Value.Configuration cfg) { + return new JBONDumper(cfg); + } + + public JBONDumper() { + super(Value.configuration); + } + + public JBONDumper(Value.Configuration cfg) { + super(cfg); + } + protected OutputStream os; @Override diff --git a/src/main/java/net/woggioni/worth/serialization/binary/JBONParser.java b/src/main/java/net/woggioni/worth/serialization/binary/JBONParser.java index 56b56d6..7c3537b 100644 --- a/src/main/java/net/woggioni/worth/serialization/binary/JBONParser.java +++ b/src/main/java/net/woggioni/worth/serialization/binary/JBONParser.java @@ -4,6 +4,7 @@ import lombok.SneakyThrows; import net.woggioni.worth.buffer.LookAheadInputStream; import net.woggioni.worth.exception.ParseException; import net.woggioni.worth.serialization.ValueParser; +import net.woggioni.worth.serialization.json.JSONParser; import net.woggioni.worth.utils.Leb128; import net.woggioni.worth.utils.WorthUtils; import net.woggioni.worth.xface.Parser; @@ -127,4 +128,16 @@ public class JBONParser extends ValueParser { public static Parser newInstance() { return new JBONParser(); } + + public static Parser newInstance(Value.Configuration cfg) { + return new JBONParser(cfg); + } + + public JBONParser() { + super(Value.configuration); + } + + public JBONParser(Value.Configuration cfg) { + super(cfg); + } } \ No newline at end of file diff --git a/src/main/java/net/woggioni/worth/serialization/json/JSONDumper.java b/src/main/java/net/woggioni/worth/serialization/json/JSONDumper.java index 6df547b..a208dda 100644 --- a/src/main/java/net/woggioni/worth/serialization/json/JSONDumper.java +++ b/src/main/java/net/woggioni/worth/serialization/json/JSONDumper.java @@ -20,6 +20,18 @@ public class JSONDumper extends ValueDumper { return new JSONDumper(); } + public static Dumper newInstance(Value.Configuration cfg) { + return new JSONDumper(cfg); + } + + public JSONDumper() { + super(Value.configuration); + } + + public JSONDumper(Value.Configuration cfg) { + super(cfg); + } + private Writer writer; private String escapeString(String value){ diff --git a/src/main/java/net/woggioni/worth/serialization/json/JSONParser.java b/src/main/java/net/woggioni/worth/serialization/json/JSONParser.java index aea328a..5b42899 100644 --- a/src/main/java/net/woggioni/worth/serialization/json/JSONParser.java +++ b/src/main/java/net/woggioni/worth/serialization/json/JSONParser.java @@ -140,6 +140,17 @@ public class JSONParser extends ValueParser { public static Parser newInstance() { return new JSONParser(); } + public static Parser newInstance(Value.Configuration cfg) { + return new JSONParser(cfg); + } + + public JSONParser() { + super(Value.configuration); + } + + public JSONParser(Value.Configuration cfg) { + super(cfg); + } @Override public Value parse(InputStream stream) { diff --git a/src/main/java/net/woggioni/worth/value/ObjectValue.java b/src/main/java/net/woggioni/worth/value/ObjectValue.java index 5aa7bf7..f32bbeb 100644 --- a/src/main/java/net/woggioni/worth/value/ObjectValue.java +++ b/src/main/java/net/woggioni/worth/value/ObjectValue.java @@ -9,12 +9,13 @@ import java.util.*; public interface ObjectValue extends Value, Iterable> { - Implementation implementation = Implementation.valueOf( - System.getProperty(ObjectValue.class.getName() + ".implementation", "TreeMap")); - static ObjectValue newInstance() { + return newInstance(Value.configuration); + } + + static ObjectValue newInstance(Configuration cfg) { ObjectValue result; - switch(implementation) { + switch(cfg.objectValueImplementation) { case ArrayList: result = new ListObjectValue(); break; @@ -31,7 +32,7 @@ public interface ObjectValue extends Value, Iterable> { throw WorthUtils.newThrowable(IllegalArgumentException.class, "Unknown value of %s: %s", Implementation.class.getName(), - implementation); + cfg.objectValueImplementation); } return result; } diff --git a/src/main/java/net/woggioni/worth/xface/Value.java b/src/main/java/net/woggioni/worth/xface/Value.java index 2b5d9df..38c1cd8 100644 --- a/src/main/java/net/woggioni/worth/xface/Value.java +++ b/src/main/java/net/woggioni/worth/xface/Value.java @@ -2,6 +2,7 @@ package net.woggioni.worth.xface; import net.woggioni.worth.exception.TypeException; import net.woggioni.worth.value.NullValue; +import net.woggioni.worth.value.ObjectValue; import java.util.List; import java.util.Map; @@ -83,4 +84,12 @@ public interface Value { default boolean has(String key) { throw new TypeException("Not an object"); } + + class Configuration { + public ObjectValue.Implementation objectValueImplementation = ObjectValue.Implementation.valueOf( + System.getProperty(ObjectValue.class.getName() + ".implementation", "TreeMap")); + public boolean useReferences = Boolean.valueOf( + System.getProperty(Value.class.getName() + ".useReferences", "false")); + } + Configuration configuration = new Configuration(); } diff --git a/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java b/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java index 879139f..6699dbf 100644 --- a/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java +++ b/src/test/java/net/woggioni/worth/serialization/json/PerformanceTest.java @@ -5,6 +5,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; import net.woggioni.worth.antlr.JSONLexer; import net.woggioni.worth.antlr.JSONListenerImpl; +import net.woggioni.worth.serialization.binary.JBONDumper; +import net.woggioni.worth.xface.Dumper; +import net.woggioni.worth.xface.Parser; import net.woggioni.worth.xface.Value; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; @@ -14,9 +17,7 @@ import org.junit.Ignore; import org.junit.Test; import org.tukaani.xz.XZInputStream; -import java.io.BufferedInputStream; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; class Chronometer { @@ -147,4 +148,23 @@ public class PerformanceTest { System.out.printf("Antlr time: %8s sec\n", String.format("%.3f", antlrTime)); } } + + @Test + @Ignore + @SneakyThrows + public void tess() { + Value value; + try(InputStream is = extractTestData()) { + Parser parser = JSONParser.newInstance(); + value = parser.parse(is); + } + try(OutputStream os = new BufferedOutputStream(new FileOutputStream("/tmp/citylots.json"))) { + Dumper dumper = JSONDumper.newInstance(); + dumper.dump(value, os); + } + try(OutputStream os = new BufferedOutputStream(new FileOutputStream("/tmp/citylots.jbon"))) { + Dumper dumper = JBONDumper.newInstance(); + dumper.dump(value, os); + } + } } diff --git a/src/test/java/net/woggioni/worth/utils/Tuple2.java b/src/test/java/net/woggioni/worth/utils/Tuple2.java new file mode 100644 index 0000000..3b11394 --- /dev/null +++ b/src/test/java/net/woggioni/worth/utils/Tuple2.java @@ -0,0 +1,26 @@ +package net.woggioni.worth.utils; + +import lombok.EqualsAndHashCode; +import lombok.RequiredArgsConstructor; + +import java.util.Comparator; + +@EqualsAndHashCode +@RequiredArgsConstructor +public class Tuple2 { + public final T _1; + public final U _2; + + public static , Y extends Comparable> Comparator> getComparator(Tuple2 tuple) { + return Comparator + .comparing((Tuple2 t) -> t._1) + .thenComparing((Tuple2 t) -> t._2); + } + + public static , Y extends Comparable> Comparator> getComparator(Class cls1, Class cls2) { + return Comparator + .comparing((Tuple2 t) -> t._1) + .thenComparing((Tuple2 t) -> t._2); + } + +} diff --git a/src/test/java/net/woggioni/worth/value/ObjectValueImplementationTest.java b/src/test/java/net/woggioni/worth/value/ObjectValueImplementationTest.java new file mode 100644 index 0000000..96d4925 --- /dev/null +++ b/src/test/java/net/woggioni/worth/value/ObjectValueImplementationTest.java @@ -0,0 +1,42 @@ +package net.woggioni.worth.value; + +import net.woggioni.worth.utils.Tuple2; +import net.woggioni.worth.xface.Value; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +public class ObjectValueImplementationTest { + + private static List>> getImplementationMapping() { + return Arrays.asList( + new Tuple2<>(ObjectValue.Implementation.ArrayList, ListObjectValue.class), + new Tuple2<>(ObjectValue.Implementation.TreeMap, TreeMapObjectValue.class), + new Tuple2<>(ObjectValue.Implementation.HashMap, HashMapObjectValue.class), + new Tuple2<>(ObjectValue.Implementation.LinkedHashMap, LinkedHashMapObjectValue.class) + ); + } + + @Test + public void test() { + List>> mapping = + getImplementationMapping(); + System.setProperty(ObjectValue.class.getName() + ".implementation", + ObjectValue.Implementation.ArrayList.toString()); + ObjectValue.Implementation expectedImplementation = + ObjectValue.Implementation.valueOf(System.getProperty(ObjectValue.class.getName() + ".implementation")); + Class expectedClass = + mapping.stream().filter(t -> t._1 == expectedImplementation).findFirst().get()._2; + ObjectValue obj = ObjectValue.newInstance(); + Assert.assertEquals(expectedClass, obj.getClass()); + mapping.forEach(tuple -> { + Value.Configuration cfg = new Value.Configuration(); + cfg.objectValueImplementation = tuple._1; + ObjectValue obj2 = ObjectValue.newInstance(cfg); + Assert.assertEquals(tuple._2, obj2.getClass()); + }); + } + +}