diff --git a/src/main/java/nl/sander/jsontoy2/JavaObjectReaderFactory.java b/src/main/java/nl/sander/jsontoy2/JavaObjectReaderFactory.java
index 5559c64..cfbcc92 100644
--- a/src/main/java/nl/sander/jsontoy2/JavaObjectReaderFactory.java
+++ b/src/main/java/nl/sander/jsontoy2/JavaObjectReaderFactory.java
@@ -7,12 +7,15 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
+/**
+ * Responsible for generating classes that parse into java beans.
+ *
+ * TODO remove javassist both for analysing java beans and for generating bytecode
+ */
public class JavaObjectReaderFactory {
public static final String ROOT_PACKAGE = "serializer.";
private final static CtClass DESERIALIZER_BASE = Javassist.getTypeDefinition(JsonValueReader.class);
@@ -21,13 +24,6 @@ public class JavaObjectReaderFactory {
private static final Class>[] NO_PARAMS = {};
private static final CtClass[] CT_NO_PARAMS = {};
private final static CtClass OBJECT_CLASS = Javassist.getTypeDefinition(Object.class);
- private final static CtClass BOOLEAN = Javassist.getTypeDefinition(boolean.class);
- private final static CtClass INT = Javassist.getTypeDefinition(int.class);
- private final static CtClass LONG = Javassist.getTypeDefinition(long.class);
- private final static CtClass BYTE = Javassist.getTypeDefinition(byte.class);
- private final static CtClass SHORT = Javassist.getTypeDefinition(short.class);
- private final static CtClass FLOAT = Javassist.getTypeDefinition(float.class);
- private final static CtClass DOUBLE = Javassist.getTypeDefinition(double.class);
@SuppressWarnings("unchecked")
static JsonValueReader createReaderInstance(Class type) {
@@ -56,7 +52,7 @@ public class JavaObjectReaderFactory {
private static CtMethod createReadJsonMethod(CtClass serializerClass, Class> type) {
try {
String readMethodBodySource = createReadMethodBodySource(type);
- System.out.println(readMethodBodySource);
+// System.out.println(readMethodBodySource);
return CtNewMethod.make(Modifier.PUBLIC, OBJECT_CLASS, "read", PARSER_PARAM, NO_EXCEPTIONS, readMethodBodySource, serializerClass);
} catch (CannotCompileException e) {
throw new ClassCreationException(e);
@@ -110,7 +106,7 @@ public class JavaObjectReaderFactory {
}
}
-
+ //should be reinstated
private static String genericType(CtField field) {
try {
if (!Javassist.isCollection(field.getType())) {
@@ -138,10 +134,6 @@ public class JavaObjectReaderFactory {
return lowercase.substring(0, 1).toUpperCase() + lowercase.substring(1);
}
- private static Set createTypeList(Class>... classes) {
- return Arrays.stream(classes).map(Class::getName).collect(Collectors.toSet());
- }
-
/*
* custom root package is prepended to avoid the java.lang class in which it's illegal to create new classes
*
diff --git a/src/main/java/nl/sander/jsontoy2/JsonReader.java b/src/main/java/nl/sander/jsontoy2/JsonReader.java
index ccd6e11..43cd2ad 100644
--- a/src/main/java/nl/sander/jsontoy2/JsonReader.java
+++ b/src/main/java/nl/sander/jsontoy2/JsonReader.java
@@ -1,21 +1,16 @@
package nl.sander.jsontoy2;
import java.io.BufferedInputStream;
-import java.io.ByteArrayInputStream;
import java.io.InputStream;
-import java.lang.ref.SoftReference;
-import java.nio.charset.StandardCharsets;
import java.util.Map;
-import java.util.Objects;
/**
* public api
*/
public class JsonReader {
-
- private final static ThreadLocal> PARSERS = new ThreadLocal<>();
-
+ private JsonReader() {
+ }
/**
* reads a value from a stream for a type that is not known beforehand
@@ -32,7 +27,7 @@ public class JsonReader {
*/
public static Object read(InputStream inputStream) {
final InputStream in = ensureBufferedStream(inputStream);
- try (Parser parser = getParser(in)) {
+ try (Parser parser = ParserFactory.getParser(in)) {
return read(parser);
}
}
@@ -44,7 +39,7 @@ public class JsonReader {
* @return @see read(InputStream stream)
*/
public static Object read(String jsonString) {
- return read(getParser(jsonString));
+ return read(ParserFactory.getParser(jsonString));
}
/**
@@ -56,7 +51,7 @@ public class JsonReader {
* @return Object the specified type
*/
public static T read(Class type, InputStream inputStream) {
- Parser parser = getParser(inputStream);
+ Parser parser = ParserFactory.getParser(inputStream);
T value = read(type, parser);
parser.close();
return value;
@@ -71,31 +66,15 @@ public class JsonReader {
* @return Object the specified type
*/
public static T read(Class type, String jsonString) {
- return read(type, getParser(jsonString));
+ return read(type, ParserFactory.getParser(jsonString));
}
- private static Parser getParser(String jsonString) {
- return getParser(new ByteArrayInputStream(jsonString.getBytes(StandardCharsets.UTF_8)));
- }
-
- private static Parser getParser(InputStream inputStream) {
- Objects.requireNonNull(inputStream, "File not found");
- Parser parser;
- SoftReference parserReference = PARSERS.get();
- if (parserReference == null || (parser = parserReference.get()) == null) {
- parser = new Parser(inputStream);
- parserReference = new SoftReference<>(parser);
- PARSERS.set(parserReference);
- } else {
- parser.init(inputStream);
- }
- return parser;
- }
static Object read(Parser parser) {
return parser.parseAny();
}
+ //TODO should not be public
@SuppressWarnings("unchecked")
public static T read(Class type, Parser parser) {
return (T) ReaderFactory.getReader(type).read(parser);
diff --git a/src/main/java/nl/sander/jsontoy2/ParserFactory.java b/src/main/java/nl/sander/jsontoy2/ParserFactory.java
new file mode 100644
index 0000000..0520c1b
--- /dev/null
+++ b/src/main/java/nl/sander/jsontoy2/ParserFactory.java
@@ -0,0 +1,38 @@
+package nl.sander.jsontoy2;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.lang.ref.SoftReference;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+
+/**
+ * Keeps a Threadlocal parser that can be (re)used by clients.
+ *
+ * The parser is not kept indefinitely, but garbage collected when the JVM considers necessary.
+ */
+public class ParserFactory {
+
+ private final static ThreadLocal> PARSERS = new ThreadLocal<>();
+
+ private ParserFactory() {
+ }
+
+ static Parser getParser(String jsonString) {
+ return getParser(new ByteArrayInputStream(jsonString.getBytes(StandardCharsets.UTF_8)));
+ }
+
+ static Parser getParser(InputStream inputStream) {
+ Objects.requireNonNull(inputStream, "File not found");
+ Parser parser;
+ SoftReference parserReference = PARSERS.get();
+ if (parserReference == null || (parser = parserReference.get()) == null) {
+ parser = new Parser(inputStream);
+ parserReference = new SoftReference<>(parser);
+ PARSERS.set(parserReference);
+ } else {
+ parser.init(inputStream);
+ }
+ return parser;
+ }
+}
diff --git a/src/main/java/nl/sander/jsontoy2/ReaderFactory.java b/src/main/java/nl/sander/jsontoy2/ReaderFactory.java
index 29d2059..6b3a199 100644
--- a/src/main/java/nl/sander/jsontoy2/ReaderFactory.java
+++ b/src/main/java/nl/sander/jsontoy2/ReaderFactory.java
@@ -18,7 +18,10 @@ public class ReaderFactory {
registerPrimitiveTypeReaders();
}
- public void registerCustomReader(Class type, JsonValueReader reader) {
+ private ReaderFactory() {
+ }
+
+ public static void registerCustomReader(Class type, JsonValueReader reader) {
readers.put(type, reader);
}
diff --git a/src/test/java/nl/sander/jsontoy2/WrapperObjectTests.java b/src/test/java/nl/sander/jsontoy2/WrapperObjectTests.java
index 8df9b8e..817d465 100644
--- a/src/test/java/nl/sander/jsontoy2/WrapperObjectTests.java
+++ b/src/test/java/nl/sander/jsontoy2/WrapperObjectTests.java
@@ -6,8 +6,7 @@ import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.HashSet;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.*;
public class WrapperObjectTests {
@@ -22,9 +21,9 @@ public class WrapperObjectTests {
@Test
public void testBoolean() {
-// BooleanBean trueBean = JsonReader.read(BooleanBean.class, "{\"value\": true}");
-// assertTrue(trueBean.isValue());
- // second call to read, must not recreate class definition, would not compile
+ BooleanBean trueBean = JsonReader.read(BooleanBean.class, "{\"value\": true}");
+ assertTrue(trueBean.isValue());
+ // second call to read, must not recreate class definition, (it would not compile)
// so this test implicitly tests caching function too
BooleanBean falseBean = JsonReader.read(BooleanBean.class, "{\"value2\": false}");
assertFalse(falseBean.isValue());