JOHNZON-367 Snippet accepts a JsonGeneratorFactory and is reusable
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/Snippet.java b/johnzon-core/src/main/java/org/apache/johnzon/core/Snippet.java
index 7e2f14a..356762d 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/Snippet.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/Snippet.java
@@ -21,146 +21,168 @@
import javax.json.JsonObject;
import javax.json.JsonValue;
import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
+import java.util.Collections;
import java.util.Map;
-public class Snippet implements Flushable, Closeable {
+public class Snippet {
- private final JsonGenerator generator;
- private final SnippetOutputStream snippet;
+ private final int max;
+ private final JsonGeneratorFactory generatorFactory;
- private Snippet(final int max) {
- this.snippet = new SnippetOutputStream(max);
- this.generator = Json.createGenerator(snippet);
+ public Snippet(final int max) {
+ this(max, Json.createGeneratorFactory(Collections.EMPTY_MAP));
}
- private void write(final JsonValue value) {
- if (snippet.isComplete()) {
- return;
- }
+ public Snippet(final int max, final JsonGeneratorFactory generatorFactory) {
+ this.max = max;
+ this.generatorFactory = generatorFactory;
+ }
+ public String of(final JsonValue value) {
switch (value.getValueType()) {
- case ARRAY: {
- write(value.asJsonArray());
- break;
- }
- case OBJECT: {
- write(value.asJsonObject());
- break;
- }
+ case TRUE: return "true";
+ case FALSE: return "false";
+ case NULL: return "null";
default: {
- generator.write(value);
- }
- }
- }
-
- private void write(final JsonArray array) {
- if (snippet.isComplete()) {
- return;
- }
-
- if (array.isEmpty()) {
- generator.write(array);
- return;
- }
-
- generator.writeStartArray();
- for (final JsonValue jsonValue : array) {
- if (snippet.isComplete()) {
- break;
- }
- write(jsonValue);
- }
- generator.writeEnd();
- }
-
- private void write(final JsonObject object) {
- if (snippet.isComplete()) {
- return;
- }
-
- if (object.isEmpty()) {
- generator.write(object);
- return;
- }
-
- generator.writeStartObject();
- for (final Map.Entry<String, JsonValue> entry : object.entrySet()) {
- if (snippet.isComplete()) {
- break;
- }
- write(entry.getKey(), entry.getValue());
- }
- generator.writeEnd();
- }
-
- private void write(final String name, final JsonValue value) {
- if (snippet.isComplete()) {
- return;
- }
-
- switch (value.getValueType()) {
- case ARRAY:
- generator.writeStartArray(name);
- final JsonArray array = value.asJsonArray();
- for (final JsonValue jsonValue : array) {
- write(jsonValue);
+ try (final Buffer buffer = new Buffer()) {
+ buffer.write(value);
+ return buffer.get();
}
- generator.writeEnd();
-
- break;
- case OBJECT:
- generator.writeStartObject(name);
- final JsonObject object = value.asJsonObject();
- for (final Map.Entry<String, JsonValue> keyval : object.entrySet()) {
- write(keyval.getKey(), keyval.getValue());
- }
- generator.writeEnd();
-
- break;
- default: generator.write(name, value);
+ }
}
}
- private String get() {
- generator.close();
- return snippet.get();
- }
-
- @Override
- public void close() {
- generator.close();
- }
-
- @Override
- public void flush() {
- generator.flush();
- }
-
- public static String of(final JsonValue object) {
- return of(object, 50);
- }
-
public static String of(final JsonValue value, final int max) {
- try (final Snippet snippet = new Snippet(max)){
+ return new Snippet(max).of(value);
+ }
+
+ class Buffer implements Flushable, Closeable {
+ private final JsonGenerator generator;
+ private final SnippetOutputStream snippet;
+
+ private Buffer() {
+ this.snippet = new SnippetOutputStream(max);
+ this.generator = generatorFactory.createGenerator(snippet);
+ }
+
+ private void write(final JsonValue value) {
+ if (snippet.isComplete()) {
+ return;
+ }
+
switch (value.getValueType()) {
- case TRUE: return "true";
- case FALSE: return "false";
- case NULL: return "null";
+ case ARRAY: {
+ write(value.asJsonArray());
+ break;
+ }
+ case OBJECT: {
+ write(value.asJsonObject());
+ break;
+ }
default: {
- snippet.write(value);
- return snippet.get();
+ generator.write(value);
}
}
}
+
+ private void write(final JsonArray array) {
+ if (snippet.isComplete()) {
+ return;
+ }
+
+ if (array.isEmpty()) {
+ generator.write(array);
+ return;
+ }
+
+ generator.writeStartArray();
+ for (final JsonValue jsonValue : array) {
+ if (snippet.isComplete()) {
+ break;
+ }
+ write(jsonValue);
+ }
+ generator.writeEnd();
+ }
+
+ private void write(final JsonObject object) {
+ if (snippet.isComplete()) {
+ return;
+ }
+
+ if (object.isEmpty()) {
+ generator.write(object);
+ return;
+ }
+
+ generator.writeStartObject();
+ for (final Map.Entry<String, JsonValue> entry : object.entrySet()) {
+ if (snippet.isComplete()) {
+ break;
+ }
+ write(entry.getKey(), entry.getValue());
+ }
+ generator.writeEnd();
+ }
+
+ private void write(final String name, final JsonValue value) {
+ if (snippet.isComplete()) {
+ return;
+ }
+
+ switch (value.getValueType()) {
+ case ARRAY:
+ generator.writeStartArray(name);
+ final JsonArray array = value.asJsonArray();
+ for (final JsonValue jsonValue : array) {
+ if (snippet.isComplete()) {
+ break;
+ }
+ write(jsonValue);
+ }
+ generator.writeEnd();
+
+ break;
+ case OBJECT:
+ generator.writeStartObject(name);
+ final JsonObject object = value.asJsonObject();
+ for (final Map.Entry<String, JsonValue> keyval : object.entrySet()) {
+ if (snippet.isComplete()) {
+ break;
+ }
+ write(keyval.getKey(), keyval.getValue());
+ }
+ generator.writeEnd();
+
+ break;
+ default: generator.write(name, value);
+ }
+ }
+
+ private String get() {
+ generator.close();
+ return snippet.get();
+ }
+
+ @Override
+ public void close() {
+ generator.close();
+ }
+
+ @Override
+ public void flush() {
+ generator.flush();
+ }
}
- private static class SnippetOutputStream extends OutputStream {
+ static class SnippetOutputStream extends OutputStream {
private final ByteArrayOutputStream buffer;
private OutputStream mode;
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
index 300d8b5..5c8af0c 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
@@ -347,7 +347,7 @@
}
}
if (classMapping == null) {
- throw new MapperException("Can't map JSON Object to " + type + ": " + Snippet.of(object));
+ throw new MapperException("Can't map JSON Object to " + type + ": " + new Snippet(50).of(object));
}
if (applyObjectConverter && classMapping.reader != null && (skippedConverters == null || !skippedConverters.contains(type))) {