You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2019/08/07 17:07:06 UTC
[johnzon] branch master updated: JOHNZON-229 serializing streams as
list for now
This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/johnzon.git
The following commit(s) were added to refs/heads/master by this push:
new cb1b21b JOHNZON-229 serializing streams as list for now
cb1b21b is described below
commit cb1b21b216aee6a94dd4d1cbec03304b0e6201c6
Author: Romain Manni-Bucau <rm...@apache.org>
AuthorDate: Wed Aug 7 19:06:59 2019 +0200
JOHNZON-229 serializing streams as list for now
---
.../johnzon/mapper/MappingGeneratorImpl.java | 73 ++++++++++++++--------
.../apache/johnzon/mapper/MappingParserImpl.java | 27 +++++++-
.../java/org/apache/johnzon/mapper/StreamTest.java | 51 +++++++++++++++
3 files changed, 123 insertions(+), 28 deletions(-)
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java
index 9febaa8..34ae88e 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java
@@ -32,7 +32,9 @@ import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
+import java.util.stream.BaseStream;
public class MappingGeneratorImpl implements MappingGenerator {
private final MapperConfig config;
@@ -385,33 +387,9 @@ public class MappingGeneratorImpl implements MappingGenerator {
}
if ((!dynamic && array) || (dynamic && type.isArray())) {
writeArray(type, itemConverter, key, value, ignoredProperties, jsonPointer);
- } else if ((!dynamic && collection) || (dynamic && Collection.class.isAssignableFrom(type))) {
- generator.writeStartArray(key);
- int i = 0;
- for (final Object o : Collection.class.cast(value)) {
- String valJsonPointer = jsonPointers.get(o);
- if (valJsonPointer != null) {
- // write JsonPointer instead of the original object
- writePrimitives(valJsonPointer);
- } else {
- ObjectConverter.Writer objectConverterToUse = objectConverter;
- if (o != null && objectConverterToUse == null) {
- objectConverterToUse = config.findObjectConverterWriter(o.getClass());
- }
-
- if (objectConverterToUse != null) {
- final DynamicMappingGenerator dynamicMappingGenerator = new DynamicMappingGenerator(this,
- generator::writeStartObject, generator::writeEnd, null);
- objectConverterToUse.writeJson(o, dynamicMappingGenerator);
- dynamicMappingGenerator.flushIfNeeded();
- } else {
- writeItem(itemConverter != null ? itemConverter.from(o) : o, ignoredProperties,
- isDeduplicateObjects ? new JsonPointerTracker(jsonPointer, i) : null);
- }
- }
- i++;
- }
- generator.writeEnd();
+ } else if ((!dynamic && collection) || (dynamic && Iterable.class.isAssignableFrom(type))) {
+ writeIterator(itemConverter, key, objectConverter, ignoredProperties, jsonPointer, generator,
+ Iterable.class.cast(value).iterator());
} else if ((!dynamic && map) || (dynamic && Map.class.isAssignableFrom(type))) {
generator.writeStartObject(key);
writeMapBody((Map<?, ?>) value, itemConverter);
@@ -425,6 +403,12 @@ public class MappingGeneratorImpl implements MappingGenerator {
} else {
writePrimitives(key, type, value, generator);
}
+ } else if (BaseStream.class.isAssignableFrom(type)) {
+ writeIterator(itemConverter, key, objectConverter, ignoredProperties, jsonPointer, generator,
+ BaseStream.class.cast(value).iterator());
+ } else if (Iterator.class.isAssignableFrom(type)) {
+ writeIterator(itemConverter, key, objectConverter, ignoredProperties, jsonPointer, generator,
+ Iterator.class.cast(value));
} else {
if (objectConverter != null) {
final DynamicMappingGenerator dynamicMappingGenerator = new DynamicMappingGenerator(this,
@@ -465,6 +449,41 @@ public class MappingGeneratorImpl implements MappingGenerator {
}
}
+ private void writeIterator(final Adapter itemConverter, final String key,
+ final ObjectConverter.Writer objectConverter,
+ final Collection<String> ignoredProperties,
+ final JsonPointerTracker jsonPointer,
+ final JsonGenerator generator,
+ final Iterator<?> iterator) {
+ int i = 0;
+ generator.writeStartArray(key);
+ while (iterator.hasNext()) {
+ final Object o = iterator.next();
+ String valJsonPointer = jsonPointers.get(o);
+ if (valJsonPointer != null) {
+ // write JsonPointer instead of the original object
+ writePrimitives(valJsonPointer);
+ } else {
+ ObjectConverter.Writer objectConverterToUse = objectConverter;
+ if (o != null && objectConverterToUse == null) {
+ objectConverterToUse = config.findObjectConverterWriter(o.getClass());
+ }
+
+ if (objectConverterToUse != null) {
+ final DynamicMappingGenerator dynamicMappingGenerator = new DynamicMappingGenerator(this,
+ generator::writeStartObject, generator::writeEnd, null);
+ objectConverterToUse.writeJson(o, dynamicMappingGenerator);
+ dynamicMappingGenerator.flushIfNeeded();
+ } else {
+ writeItem(itemConverter != null ? itemConverter.from(o) : o, ignoredProperties,
+ isDeduplicateObjects ? new JsonPointerTracker(jsonPointer, i) : null);
+ }
+ }
+ i++;
+ }
+ generator.writeEnd();
+ }
+
/**
* Write a JSON Array with a given Array Value, like byte[], int[], Person[] etc.
* @param key either the attribute key or {@code null} if the array should be rendered without key
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 c9aa1b4..0068880 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
@@ -69,6 +69,10 @@ import java.util.TreeSet;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import java.util.stream.Stream;
import static java.util.Arrays.asList;
import static javax.json.JsonValue.ValueType.ARRAY;
@@ -667,7 +671,14 @@ public class MappingParserImpl implements MappingParser {
}
if (ParameterizedType.class.isInstance(type)) {
- final Mappings.CollectionMapping mapping = mappings.findCollectionMapping(ParameterizedType.class.cast(type), rootType);
+ final ParameterizedType genericType = ParameterizedType.class.cast(type);
+ if (Stream.class == genericType.getRawType()) {
+ return Stream.of(1).flatMap(seed -> Collection.class.cast(buildArray(
+ new JohnzonParameterizedType(List.class, genericType.getActualTypeArguments()),
+ jsonArray, itemConverter, objectConverter, jsonPointer, rootType)).stream());
+ }
+
+ final Mappings.CollectionMapping mapping = mappings.findCollectionMapping(genericType, rootType);
if (mapping != null) {
return mapCollection(mapping, jsonArray, itemConverter, objectConverter, jsonPointer, rootType);
}
@@ -677,6 +688,20 @@ public class MappingParserImpl implements MappingParser {
return buildArray(ANY_LIST, jsonArray, null, null, jsonPointer, rootType);
}
+ // guess we don't want to map stream impls - keep it lazy since it is the only advantage to have streams there
+ if (IntStream.class == type) {
+ return Stream.of(1).flatMapToInt(seed -> IntStream.of(int[].class.cast(
+ buildArray(int[].class, jsonArray, null, null, jsonPointer, rootType))));
+ }
+ if (LongStream.class == type) {
+ return Stream.of(1).flatMapToLong(seed -> LongStream.of(long[].class.cast(
+ buildArray(long[].class, jsonArray, null, null, jsonPointer, rootType))));
+ }
+ if (DoubleStream.class == type) {
+ return Stream.of(1).flatMapToDouble(seed -> DoubleStream.of(double[].class.cast(
+ buildArray(double[].class, jsonArray, null, null, jsonPointer, rootType))));
+ }
+
throw new UnsupportedOperationException("type " + type + " not supported");
}
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/StreamTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/StreamTest.java
new file mode 100644
index 0000000..3fdafbf
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/StreamTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.mapper;
+
+import static java.util.Arrays.asList;
+import static java.util.stream.Collectors.toList;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import org.junit.Test;
+
+public class StreamTest {
+ private final Mapper mapper = new MapperBuilder().setAttributeOrder(String::compareTo).build();
+
+ @Test
+ public void roundTrip() {
+ final String json = "{\"ints\":[0,1,2,3,4],\"strings\":[\"a\",\"b\",\"c\"]}";
+ final ILoveStreams instance = new ILoveStreams();
+ assertEquals(json, mapper.writeObjectAsString(instance));
+ instance.ints = null;
+ instance.strings = null;
+ assertEquals("{}", mapper.writeObjectAsString(instance));
+ final ILoveStreams deserialized = mapper.readObject(json, ILoveStreams.class);
+ assertEquals(asList("a", "b", "c"), deserialized.strings.collect(toList()));
+ assertArrayEquals(IntStream.range(0, 5).toArray(), deserialized.ints.toArray());
+ }
+
+ public static class ILoveStreams {
+ public Stream<String> strings = Stream.of("a", "b", "c");
+ public IntStream ints = IntStream.range(0, 5);
+ }
+}