added traversal library
fixed bug with missing .equals method implementation on net.woggioni.worth.value.ObjectEntry fixed multithreaded testing
This commit is contained in:
@@ -16,10 +16,9 @@ scalacOptions ++= Seq(
|
||||
|
||||
git.useGitDescribe := true
|
||||
fork := true
|
||||
//javaOptions in Test += "-Dnet.woggioni.worth.value.ObjectValue.listBasedImplementation=true"
|
||||
//javaOptions in Test += "-Xmx14G"
|
||||
//scalafmtOnCompile := true
|
||||
libraryDependencies += "org.projectlombok" % "lombok" % "1.18.2"
|
||||
libraryDependencies += "org.projectlombok" % "lombok" % "1.18.8"
|
||||
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test
|
||||
libraryDependencies += "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.6" % Test
|
||||
|
||||
@@ -33,4 +32,6 @@ artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
|
||||
|
||||
enablePlugins(Antlr4Plugin)
|
||||
antlr4Version in Antlr4 := "4.7.1"
|
||||
antlr4PackageName in Antlr4 := Some("net.woggioni.worth.antlr")
|
||||
antlr4PackageName in Antlr4 := Some("net.woggioni.worth.antlr")
|
||||
|
||||
testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-a")
|
@@ -116,7 +116,6 @@ public class JBONDumper extends ValueDumper {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
protected void endObject() {
|
||||
}
|
||||
|
||||
@@ -134,7 +133,6 @@ public class JBONDumper extends ValueDumper {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
protected void endArray() {
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,42 @@
|
||||
package net.woggioni.worth.traversal;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.woggioni.worth.value.ArrayValue;
|
||||
import net.woggioni.worth.xface.Value;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class ArrayStackElement extends StackElement {
|
||||
|
||||
@Getter
|
||||
private final ArrayValue value;
|
||||
|
||||
private final Iterator<Value> it;
|
||||
|
||||
@Getter
|
||||
private int currentIndex;
|
||||
|
||||
private Value currentValue = null;
|
||||
|
||||
ArrayStackElement(ArrayValue av) {
|
||||
this.value = av;
|
||||
it = av.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
Value current() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
Value next() {
|
||||
currentValue = it.next();
|
||||
currentIndex++;
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package net.woggioni.worth.traversal;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.woggioni.worth.value.ObjectValue;
|
||||
import net.woggioni.worth.xface.Value;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class ObjectStackElement extends StackElement {
|
||||
|
||||
private final Iterator<Map.Entry<String, Value>> it;
|
||||
|
||||
@Getter
|
||||
private final ObjectValue value;
|
||||
|
||||
@Getter
|
||||
private int currentIndex;
|
||||
|
||||
@Getter
|
||||
private String currentKey;
|
||||
|
||||
private Value currentValue;
|
||||
|
||||
public ObjectStackElement(ObjectValue ov) {
|
||||
value = ov;
|
||||
it = ov.iterator();
|
||||
currentIndex = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
Value current() {
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
Value next() {
|
||||
Map.Entry<String, Value> result = it.next();
|
||||
currentKey = result.getKey();
|
||||
currentIndex++;
|
||||
currentValue = result.getValue();
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
package net.woggioni.worth.traversal;
|
||||
|
||||
import net.woggioni.worth.xface.Value;
|
||||
|
||||
abstract class StackElement {
|
||||
abstract Value current();
|
||||
abstract Value next();
|
||||
abstract boolean hasNext();
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package net.woggioni.worth.traversal;
|
||||
|
||||
import net.woggioni.worth.xface.Value;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TraversalContext {
|
||||
Value getRoot();
|
||||
List<StackElement> getStack();
|
||||
String getPath();
|
||||
}
|
14
src/main/java/net/woggioni/worth/traversal/ValueVisitor.java
Normal file
14
src/main/java/net/woggioni/worth/traversal/ValueVisitor.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package net.woggioni.worth.traversal;
|
||||
|
||||
import net.woggioni.worth.value.*;
|
||||
|
||||
public interface ValueVisitor {
|
||||
|
||||
void visit(ObjectValue value, TraversalContext ctx);
|
||||
void visit(ArrayValue value, TraversalContext ctx);
|
||||
void visit(BooleanValue value, TraversalContext ctx);
|
||||
void visit(StringValue value, TraversalContext ctx);
|
||||
void visit(IntegerValue value, TraversalContext ctx);
|
||||
void visit(FloatValue value, TraversalContext ctx);
|
||||
void visit(NullValue value, TraversalContext ctx);
|
||||
}
|
153
src/main/java/net/woggioni/worth/traversal/ValueWalker.java
Normal file
153
src/main/java/net/woggioni/worth/traversal/ValueWalker.java
Normal file
@@ -0,0 +1,153 @@
|
||||
package net.woggioni.worth.traversal;
|
||||
|
||||
import net.woggioni.worth.value.*;
|
||||
import net.woggioni.worth.xface.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static net.woggioni.worth.utils.WorthUtils.dynamicCast;
|
||||
|
||||
public class ValueWalker {
|
||||
|
||||
private Value parent;
|
||||
|
||||
public ValueWalker(Value root) {
|
||||
parent = root;
|
||||
}
|
||||
|
||||
public ValueWalker get(String key) {
|
||||
if(parent.type() == Value.Type.OBJECT) {
|
||||
parent = parent.get(key);
|
||||
} else {
|
||||
parent = Value.Null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ValueWalker get(int index) {
|
||||
if(parent.type() == Value.Type.ARRAY) {
|
||||
parent = parent.get(index);
|
||||
} else {
|
||||
parent = Value.Null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Value get() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public <T> Optional<T> map(Function<Value, T> callback) {
|
||||
if(isPresent()) {
|
||||
return Optional.of(callback.apply(parent));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public <T> Optional<T> flatMap(Function<Value, Optional<T>> callback) {
|
||||
if(isPresent()) {
|
||||
return callback.apply(parent);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPresent() {
|
||||
return !isEmpty();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return parent.type() == Value.Type.NULL;
|
||||
}
|
||||
|
||||
public static void walk(Value root, ValueVisitor visitor) {
|
||||
List<StackElement> stack = new ArrayList<>();
|
||||
List<StackElement> immutableStack = Collections.unmodifiableList(stack);
|
||||
|
||||
TraversalContext ctx = new TraversalContext() {
|
||||
|
||||
@Override
|
||||
public Value getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StackElement> getStack() {
|
||||
return immutableStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(StackElement se : stack) {
|
||||
ArrayStackElement ase;
|
||||
ObjectStackElement ose;
|
||||
if((ase = dynamicCast(se, ArrayStackElement.class)) != null) {
|
||||
sb.append("[");
|
||||
sb.append(ase.getCurrentIndex());
|
||||
sb.append("]");
|
||||
} else if((ose = dynamicCast(se, ObjectStackElement.class)) != null) {
|
||||
sb.append("[\"");
|
||||
sb.append(ose.getCurrentKey());
|
||||
sb.append("\"]");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
};
|
||||
|
||||
ObjectValue ov;
|
||||
ArrayValue av = new ArrayValue();
|
||||
av.add(root);
|
||||
ArrayStackElement ase = new ArrayStackElement(av);
|
||||
stack.add(ase);
|
||||
while(true) {
|
||||
Value currentValue = stack.get(stack.size() - 1).next();
|
||||
if((av = dynamicCast(currentValue, ArrayValue.class)) != null) {
|
||||
ase = new ArrayStackElement(av);
|
||||
stack.add(ase);
|
||||
} else if((ov = dynamicCast(currentValue, ObjectValue.class)) != null) {
|
||||
ObjectStackElement ose = new ObjectStackElement(ov);
|
||||
stack.add(ose);
|
||||
} else {
|
||||
IntegerValue iv;
|
||||
BooleanValue bv;
|
||||
NullValue nv;
|
||||
FloatValue fv;
|
||||
StringValue sv;
|
||||
if((iv = dynamicCast(currentValue, IntegerValue.class)) != null) {
|
||||
visitor.visit(iv, ctx);
|
||||
} else if((fv = dynamicCast(currentValue, FloatValue.class)) != null) {
|
||||
visitor.visit(fv, ctx);
|
||||
} else if((bv = dynamicCast(currentValue, BooleanValue.class)) != null) {
|
||||
visitor.visit(bv, ctx);
|
||||
} else if ((sv = dynamicCast(currentValue, StringValue.class)) != null) {
|
||||
visitor.visit(sv, ctx);
|
||||
} else if ((nv = dynamicCast(currentValue, NullValue.class)) != null) {
|
||||
visitor.visit(nv, ctx);
|
||||
}
|
||||
}
|
||||
while(true) {
|
||||
if(stack.size() == 1) return;
|
||||
int lastIndex = stack.size() - 1;
|
||||
StackElement se = stack.get(lastIndex);
|
||||
if(!se.hasNext()) {
|
||||
ObjectStackElement ose;
|
||||
if((ase = dynamicCast(se, ArrayStackElement.class)) != null) {
|
||||
visitor.visit(ase.getValue(), ctx);
|
||||
} else if((ose = dynamicCast(se, ObjectStackElement.class)) != null) {
|
||||
visitor.visit(ose.getValue(), ctx);
|
||||
}
|
||||
stack.remove(lastIndex);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,61 +0,0 @@
|
||||
package net.woggioni.worth.utils;
|
||||
|
||||
import net.woggioni.worth.xface.Value;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ValueWalker {
|
||||
|
||||
private Value parent;
|
||||
|
||||
public ValueWalker(Value root) {
|
||||
parent = root;
|
||||
}
|
||||
|
||||
public ValueWalker get(String key) {
|
||||
if(parent.type() == Value.Type.OBJECT) {
|
||||
parent = parent.get(key);
|
||||
} else {
|
||||
parent = Value.Null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ValueWalker get(int index) {
|
||||
if(parent.type() == Value.Type.ARRAY) {
|
||||
parent = parent.get(index);
|
||||
} else {
|
||||
parent = Value.Null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Value get() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public <T> Optional<T> map(Function<Value, T> callback) {
|
||||
if(isPresent()) {
|
||||
return Optional.of(callback.apply(parent));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public <T> Optional<T> flatMap(Function<Value, Optional<T>> callback) {
|
||||
if(isPresent()) {
|
||||
return callback.apply(parent);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPresent() {
|
||||
return !isEmpty();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return parent.type() == Value.Type.NULL;
|
||||
}
|
||||
}
|
@@ -47,6 +47,7 @@ public interface ObjectValue extends Value, Iterable<Map.Entry<String, Value>> {
|
||||
}
|
||||
}
|
||||
|
||||
@EqualsAndHashCode
|
||||
final class ObjectEntry<K, V> implements Map.Entry<K, V> {
|
||||
private final K key;
|
||||
private V value;
|
||||
@@ -130,7 +131,7 @@ abstract class MapObjectValue implements ObjectValue {
|
||||
}
|
||||
}
|
||||
|
||||
@EqualsAndHashCode
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
class HashMapObjectValue extends MapObjectValue {
|
||||
|
||||
public HashMapObjectValue() {
|
||||
@@ -138,7 +139,7 @@ class HashMapObjectValue extends MapObjectValue {
|
||||
}
|
||||
}
|
||||
|
||||
@EqualsAndHashCode
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
class LinkedHashMapObjectValue extends MapObjectValue {
|
||||
|
||||
public LinkedHashMapObjectValue() {
|
||||
@@ -146,7 +147,7 @@ class LinkedHashMapObjectValue extends MapObjectValue {
|
||||
}
|
||||
}
|
||||
|
||||
@EqualsAndHashCode
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
class TreeMapObjectValue extends MapObjectValue {
|
||||
|
||||
public TreeMapObjectValue() {
|
||||
@@ -159,6 +160,7 @@ class TreeMapObjectValue extends MapObjectValue {
|
||||
@EqualsAndHashCode
|
||||
class ListObjectValue implements ObjectValue {
|
||||
|
||||
@EqualsAndHashCode.Include
|
||||
private final List<Map.Entry<String, Value>> value = new ArrayList<>();
|
||||
|
||||
public ListObjectValue(Map<String, Value> map) {
|
||||
|
@@ -26,11 +26,12 @@ public class JBONTest {
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void consistencyTest() {
|
||||
System.setProperty(ObjectValue.class.getName() + ".implementation", "TreeMap");
|
||||
Value.Configuration cfg = Value.Configuration.builder()
|
||||
.objectValueImplementation(ObjectValue.Implementation.TreeMap).build();
|
||||
for (String testFile : testFiles) {
|
||||
Value parsedValue;
|
||||
try(InputStream is = getTestSource(testFile)) {
|
||||
Parser parser = new JSONParser();
|
||||
Parser parser = new JSONParser(cfg);
|
||||
parsedValue = parser.parse(is);
|
||||
}
|
||||
byte[] dumpedJBON;
|
||||
@@ -40,7 +41,7 @@ public class JBONTest {
|
||||
}
|
||||
Value reParsedValue;
|
||||
try(InputStream is = new ByteArrayInputStream(dumpedJBON)) {
|
||||
Parser parser = new JBONParser();
|
||||
Parser parser = new JBONParser(cfg);
|
||||
reParsedValue = parser.parse(is);
|
||||
}
|
||||
Assert.assertEquals(parsedValue, reParsedValue);
|
||||
|
@@ -25,8 +25,8 @@ public class JSONTest {
|
||||
|
||||
private String[] testFiles = new String[]{"/test.json", "/wordpress.json"};
|
||||
|
||||
private InputStream getTestSource(String filename) {
|
||||
return getClass().getResourceAsStream(filename);
|
||||
public static InputStream getTestSource(String filename) {
|
||||
return JSONTest.class.getResourceAsStream(filename);
|
||||
}
|
||||
|
||||
private boolean compareValueAndJsonNode(Value value, JsonNode jsonNode) {
|
||||
@@ -186,16 +186,17 @@ public class JSONTest {
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void consistencyTest() {
|
||||
System.setProperty(ObjectValue.class.getName() + ".implementation", "ArrayList");
|
||||
Value.Configuration cfg = Value.Configuration.builder()
|
||||
.objectValueImplementation(ObjectValue.Implementation.ArrayList).build();
|
||||
for (String testFile : testFiles) {
|
||||
Parser parser = new JSONParser();
|
||||
Parser parser = new JSONParser(cfg);
|
||||
Value parsedValue = parser.parse(getTestSource(testFile));
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
JSONDumper.newInstance().dump(parsedValue, baos);
|
||||
String dumpedJSON = new String(baos.toByteArray());
|
||||
byte[] barray = baos.toByteArray();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(barray);
|
||||
parser = new JSONParser();
|
||||
parser = new JSONParser(cfg);
|
||||
Value reParsedValue = parser.parse(bais);
|
||||
Assert.assertEquals(parsedValue, reParsedValue);
|
||||
baos = new ByteArrayOutputStream();
|
||||
|
105
src/test/java/net/woggioni/worth/traversal/ValueWalkerTest.java
Normal file
105
src/test/java/net/woggioni/worth/traversal/ValueWalkerTest.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package net.woggioni.worth.traversal;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.woggioni.worth.serialization.json.JSONParser;
|
||||
import net.woggioni.worth.serialization.json.JSONTest;
|
||||
import net.woggioni.worth.utils.WorthUtils;
|
||||
import net.woggioni.worth.value.*;
|
||||
import net.woggioni.worth.xface.Parser;
|
||||
import net.woggioni.worth.xface.Value;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ValueWalkerTest {
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void test() {
|
||||
Value value;
|
||||
try(InputStream is = new BufferedInputStream(getClass().getResourceAsStream("/test.json"))) {
|
||||
Parser parser = JSONParser.newInstance();
|
||||
value = parser.parse(is);
|
||||
}
|
||||
ValueWalker valueWalker = new ValueWalker(value);
|
||||
Optional<String> text = valueWalker.get("widget").get("image").get("tags").get(1).map(Value::asString);
|
||||
Assert.assertTrue(text.isPresent());
|
||||
Assert.assertEquals("Amazon", text.get());
|
||||
}
|
||||
|
||||
private static class TestVisitor implements ValueVisitor {
|
||||
|
||||
public List<Value> values = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void visit(ObjectValue value, TraversalContext ctx) {
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ArrayValue value, TraversalContext ctx) {
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BooleanValue value, TraversalContext ctx) {
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(StringValue value, TraversalContext ctx) {
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(IntegerValue value, TraversalContext ctx) {
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(FloatValue value, TraversalContext ctx) {
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NullValue value, TraversalContext ctx) {
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void walk(List<Value> result, Value value) {
|
||||
ObjectValue ov;
|
||||
ArrayValue av;
|
||||
if((av = WorthUtils.dynamicCast(value, ArrayValue.class)) != null) {
|
||||
for(Value v : av) {
|
||||
walk(result, v);
|
||||
}
|
||||
} else if((ov = WorthUtils.dynamicCast(value, ObjectValue.class)) != null) {
|
||||
for(Map.Entry<String, Value> entry : ov) {
|
||||
walk(result, entry.getValue());
|
||||
}
|
||||
}
|
||||
result.add(value);
|
||||
}
|
||||
|
||||
private List<Value> recursiveWalk(Value root) {
|
||||
List<Value> result = new ArrayList<>();
|
||||
walk(result, root);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWalk() {
|
||||
Value v = JSONParser.newInstance().parse(JSONTest.getTestSource("/test.json"));
|
||||
TestVisitor visitor = new TestVisitor();
|
||||
ValueWalker.walk(v, visitor);
|
||||
Assert.assertFalse(visitor.values.isEmpty());
|
||||
Assert.assertEquals(recursiveWalk(v), visitor.values);
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
package net.woggioni.worth.utils;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import net.woggioni.worth.serialization.json.JSONParser;
|
||||
import net.woggioni.worth.xface.Parser;
|
||||
import net.woggioni.worth.xface.Value;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ValueWalkerTest {
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void test() {
|
||||
Value value;
|
||||
try(InputStream is = new BufferedInputStream(getClass().getResourceAsStream("/test.json"))) {
|
||||
Parser parser = JSONParser.newInstance();
|
||||
value = parser.parse(is);
|
||||
}
|
||||
ValueWalker valueWalker = new ValueWalker(value);
|
||||
Optional<String> text = valueWalker.get("widget").get("image").get("tags").get(1).map(Value::asString);
|
||||
Assert.assertTrue(text.isPresent());
|
||||
Assert.assertEquals("Amazon", text.get());
|
||||
}
|
||||
}
|
@@ -23,10 +23,8 @@ public class ObjectValueImplementationTest {
|
||||
public void test() {
|
||||
List<Tuple2<ObjectValue.Implementation, Class<? extends ObjectValue>>> mapping =
|
||||
getImplementationMapping();
|
||||
System.setProperty(ObjectValue.class.getName() + ".implementation",
|
||||
ObjectValue.Implementation.ArrayList.toString());
|
||||
ObjectValue.Implementation expectedImplementation =
|
||||
ObjectValue.Implementation.valueOf(System.getProperty(ObjectValue.class.getName() + ".implementation"));
|
||||
ObjectValue.Implementation.valueOf(System.getProperty(ObjectValue.class.getName() + ".implementation", "TreeMap"));
|
||||
Class<? extends ObjectValue> expectedClass =
|
||||
mapping.stream().filter(t -> t._1 == expectedImplementation).findFirst().get()._2;
|
||||
ObjectValue obj = ObjectValue.newInstance();
|
||||
|
@@ -6,7 +6,7 @@
|
||||
"title": "Sample Konfabulator Widget",
|
||||
"name": "main_window",
|
||||
"width": 500,
|
||||
"height": 500
|
||||
"height": 501
|
||||
},
|
||||
"image": {
|
||||
"src": "Images/Sun.png",
|
||||
|
Reference in New Issue
Block a user