Maybe too late but is the commit in MapperTest intended? to avoid
ordering issue it was using try/catch pattern, now it seems this is
broken


Romain Manni-Bucau
@rmannibucau
http://www.tomitribe.com
http://rmannibucau.wordpress.com
https://github.com/rmannibucau



---------- Forwarded message ----------
From:  <[email protected]>
Date: 2014-11-04 22:53 GMT+00:00
Subject: [2/2] git commit: JOHNZON-21 (renamed setter/getter to
method), implemented basic null and empty array handling (allow to
have nulls in the serialization, allow to have/skip empty arrays in
the serialization)
To: [email protected]


JOHNZON-21 (renamed setter/getter to method), implemented basic null
and empty array handling (allow to have nulls in the serialization,
allow to have/skip empty arrays in the serialization)


Project: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/commit/c0ebe9d2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/tree/c0ebe9d2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/diff/c0ebe9d2

Branch: refs/heads/master
Commit: c0ebe9d2acbd8515a6169e7c1c80ecbe3ae67988
Parents: 7176fde
Author: Hendrik Saly <[email protected]>
Authored: Tue Nov 4 23:53:29 2014 +0100
Committer: Hendrik Saly <[email protected]>
Committed: Tue Nov 4 23:53:29 2014 +0100

----------------------------------------------------------------------
 .../java/org/apache/johnzon/mapper/Mapper.java  |  37 +++-
 .../apache/johnzon/mapper/MapperBuilder.java    |  14 +-
 .../johnzon/mapper/reflection/Mappings.java     |  18 +-
 .../org/apache/johnzon/mapper/MapperTest.java   |   2 +-
 .../org/apache/johnzon/mapper/NullTest.java     | 195 +++++++++++++++++++
 5 files changed, 248 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c0ebe9d2/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
index eadaac9..77dd96c 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
@@ -74,16 +74,20 @@ public class Mapper {
     protected final boolean close;
     protected final ConcurrentMap<Type, Converter<?>> converters;
     protected final int version;
+    protected boolean skipNull;
+    protected boolean skipEmptyArray;

     public Mapper(final JsonReaderFactory readerFactory, final
JsonGeneratorFactory generatorFactory,
                   final boolean doClose, final Map<Class<?>,
Converter<?>> converters,
-                  final int version, final Comparator<String> attributeOrder) {
+                  final int version, final Comparator<String>
attributeOrder, boolean skipNull, boolean skipEmptyArray) {
         this.readerFactory = readerFactory;
         this.generatorFactory = generatorFactory;
         this.close = doClose;
         this.converters = new ConcurrentHashMap<Type,
Converter<?>>(converters);
         this.version = version;
         this.mappings = new Mappings(attributeOrder);
+        this.skipNull =  skipNull;
+        this.skipEmptyArray = skipEmptyArray;
     }

     private static JsonGenerator writePrimitives(final JsonGenerator
generator, final Object value) {
@@ -301,11 +305,20 @@ public class Mapper {
         JsonGenerator generator = gen;
         for (final Map.Entry<String, Mappings.Getter> getterEntry :
classMapping.getters.entrySet()) {
             final Mappings.Getter getter = getterEntry.getValue();
-            final Object value = getter.setter.invoke(object);
-            if (value == null || (getter.version >= 0 && version >=
getter.version)) {
+            final Object value = getter.method.invoke(object);
+            if (getter.version >= 0 && version >= getter.version) {
                 continue;
             }

+            if (value == null) {
+                if(skipNull) {
+                    continue;
+                } else {
+                    gen.writeNull(getterEntry.getKey());
+                    continue;
+                }
+            }
+
             generator = writeValue(generator, value.getClass(),
                                     getter.primitive, getter.array,
                                     getter.collection, getter.map,
@@ -319,11 +332,17 @@ public class Mapper {
         JsonGenerator generator = gen;
         for (final Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
             final Object value = entry.getValue();
+            final Object key = entry.getKey();
+
             if (value == null) {
-                continue;
+                if(skipNull) {
+                    continue;
+                } else {
+                    gen.writeNull(key == null ? "null" : key.toString());
+                    continue;
+                }
             }

-            final Object key = entry.getKey();
             final Class<?> valueClass = value.getClass();
             final boolean primitive = Mappings.isPrimitive(valueClass);
             final boolean clazz = mappings.getClassMapping(valueClass) != null;
@@ -342,8 +361,12 @@ public class Mapper {
                                      final boolean collection, final
boolean map,
                                      final String key, final Object
value) throws InvocationTargetException, IllegalAccessException {
         if (array) {
-            JsonGenerator gen = generator.writeStartArray(key);
             final int length = Array.getLength(value);
+            if(length == 0 && skipEmptyArray) {
+                return generator;
+            }
+
+            JsonGenerator gen = generator.writeStartArray(key);
             for (int i = 0; i < length; i++) {
                 gen = writeItem(gen, Array.get(value, i));
             }
@@ -511,7 +534,7 @@ public class Mapper {
         for (final Map.Entry<String, Mappings.Setter> setter :
classMapping.setters.entrySet()) {
             final JsonValue jsonValue = object.get(setter.getKey());
             final Mappings.Setter value = setter.getValue();
-            final Method setterMethod = value.setter;
+            final Method setterMethod = value.method;
             final Object convertedValue = value.converter == null?
                     toObject(jsonValue, value.paramType) :
jsonValue.getValueType() == ValueType.STRING ?

value.converter.fromString(JsonString.class.cast(jsonValue).getString()):

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c0ebe9d2/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
index e31aab6..b20fdbd 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
@@ -78,6 +78,8 @@ public class MapperBuilder {
     private boolean doCloseOnStreams = false;
     private int version = -1;
     private Comparator<String> attributeOrder = null;
+    private boolean skipNull = true;
+    private boolean skipEmptyArray = false;
     private final Map<Class<?>, Converter<?>> converters = new
HashMap<Class<?>, Converter<?>>(DEFAULT_CONVERTERS);

     public Mapper build() {
@@ -92,7 +94,7 @@ public class MapperBuilder {
             }
         }

-        return new Mapper(readerFactory, generatorFactory,
doCloseOnStreams, converters, version, attributeOrder);
+        return new Mapper(readerFactory, generatorFactory,
doCloseOnStreams, converters, version, attributeOrder, skipNull,
skipEmptyArray);
     }

     public MapperBuilder setAttributeOrder(final Comparator<String>
attributeOrder) {
@@ -124,4 +126,14 @@ public class MapperBuilder {
         this.version = version;
         return this;
     }
+
+    public MapperBuilder setSkipNull(final boolean skipNull) {
+        this.skipNull = skipNull;
+        return this;
+    }
+
+    public MapperBuilder setSkipEmptyArray(final boolean skipEmptyArray) {
+        this.skipEmptyArray = skipEmptyArray;
+        return this;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c0ebe9d2/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Mappings.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Mappings.java
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Mappings.java
index 5baae6b..d0e2d07 100644
--- 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Mappings.java
+++ 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/reflection/Mappings.java
@@ -33,7 +33,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collection;
 import java.util.Comparator;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Queue;
@@ -70,7 +70,7 @@ public class Mappings {
     }

     public static class Getter {
-        public final Method setter;
+        public final Method method;
         public final int version;
         public final Converter<Object> converter;
         public final boolean primitive;
@@ -78,11 +78,11 @@ public class Mappings {
         public final boolean map;
         public final boolean collection;

-        public Getter(final Method setter,
+        public Getter(final Method method,
                       final boolean primitive, final boolean array,
                       final boolean collection, final boolean map,
                       final Converter<Object> converter, final int version) {
-            this.setter = setter;
+            this.method = method;
             this.converter = converter;
             this.version = version;
             this.array = array;
@@ -93,14 +93,14 @@ public class Mappings {
     }

     public static class Setter {
-        public final Method setter;
+        public final Method method;
         public final int version;
         public final Type paramType;
         public final Converter<?> converter;
         public final boolean primitive;

-        public Setter(final Method setter, final boolean primitive,
final Type paramType, final Converter<?> converter, final int version)
{
-            this.setter = setter;
+        public Setter(final Method method, final boolean primitive,
final Type paramType, final Converter<?> converter, final int version)
{
+            this.method = method;
             this.paramType = paramType;
             this.converter = converter;
             this.version = version;
@@ -204,9 +204,9 @@ public class Mappings {
     private ClassMapping createClassMapping(final Class<?> clazz) {
         try {
             final Map<String, Getter> getters = fieldOrdering != null ?
-                new TreeMap<String, Getter>(fieldOrdering) : new
HashMap<String, Getter>();
+                new TreeMap<String, Getter>(fieldOrdering) : new
LinkedHashMap<String, Getter>();
             final Map<String, Setter> setters = fieldOrdering != null ?
-                new TreeMap<String, Setter>(fieldOrdering) : new
HashMap<String, Setter>();
+                new TreeMap<String, Setter>(fieldOrdering) : new
LinkedHashMap<String, Setter>();

             final PropertyDescriptor[] propertyDescriptors =
Introspector.getBeanInfo(clazz).getPropertyDescriptors();
             for (final PropertyDescriptor descriptor : propertyDescriptors) {

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c0ebe9d2/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
index 59711d8..26ff435 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
@@ -169,7 +169,7 @@ public class MapperTest {
             final ByteArrayOutputStream baos = new ByteArrayOutputStream();
             new MapperBuilder().build().writeArray(new Pair[] { new
Pair(1, "a"), new Pair(2, "b") }, baos);
             try {
-
assertEquals("[{\"s\":\"a\",\"i\":1},{\"s\":\"b\",\"i\":2}]", new
String(baos.toByteArray()));
+
assertEquals("[{\"i\":1,\"s\":\"a\"},{\"i\":2,\"s\":\"b\"}]", new
String(baos.toByteArray()));
             } catch (final AssertionFailedError afe) { // a bit lazy
but to avoid field ordering on java > 6

assertEquals("[{\"i\":1,\"s\":\"a\"},{\"i\":2,\"s\":\"b\"}]", new
String(baos.toByteArray()));
             }

http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c0ebe9d2/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/NullTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/NullTest.java
b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/NullTest.java
new file mode 100644
index 0000000..54354a2
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/NullTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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 org.junit.Assert.assertEquals;
+
+import java.io.StringWriter;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+public class NullTest {
+
+    @Test
+    public void writeNullObjectDefault() {
+        final StringWriter writer = new StringWriter();
+        new MapperBuilder().build().writeObject(new NullObject(), writer);
+        assertEquals("{\"emptyArray\":[]}", writer.toString());
+    }
+
+    @Test
+    public void writeNullObjectDefaultMap() {
+        final StringWriter writer = new StringWriter();
+
+        final String expectedJson =
"{\"map\":{\"key1\":\"val1\",\"null\":\"val3\"}}";
+
+        final Comparator<String> attributeOrder = new Comparator<String>() {
+            @Override
+            public int compare(String o1, String o2) {
+
+                if(o1 == null) {
+                    o1 = "null";
+                }
+
+                if(o2 == null) {
+                    o2 = "null";
+                }
+
+                return expectedJson.indexOf(o1) - expectedJson.indexOf(o2);
+            }
+        };
+
+        new 
MapperBuilder().setAttributeOrder(attributeOrder).build().writeObject(new
NullObjectWithMap(), writer);
+        assertEquals(expectedJson, writer.toString());
+    }
+
+    @Test
+    public void writeNullObjectDefaultMapAllowNull() {
+        final StringWriter writer = new StringWriter();
+
+        final String expectedJson =
"{\"map\":{\"key1\":\"val1\",\"key2\":null,\"null\":\"val3\"}}";
+
+        final Comparator<String> attributeOrder = new Comparator<String>() {
+            @Override
+            public int compare(String o1, String o2) {
+
+                if(o1 == null) {
+                    o1 = "null";
+                }
+
+                if(o2 == null) {
+                    o2 = "null";
+                }
+
+                return expectedJson.indexOf(o1) - expectedJson.indexOf(o2);
+            }
+        };
+
+        new 
MapperBuilder().setSkipNull(false).setAttributeOrder(attributeOrder).build().writeObject(new
NullObjectWithMap(), writer);
+        assertEquals(expectedJson, writer.toString());
+    }
+
+    @Test
+    public void writeNullObjectAllowNull() {
+        final StringWriter writer = new StringWriter();
+
+        final String expectedJson =
"{\"stringIsnull\":null,\"integerIsnull\":null,\"nullArray\":null,\"emptyArray\":[]}";
+
+        final Comparator<String> attributeOrder = new Comparator<String>() {
+            @Override
+            public int compare(final String o1, final String o2) {
+                return expectedJson.indexOf(o1) - expectedJson.indexOf(o2);
+            }
+        };
+
+        new 
MapperBuilder().setSkipNull(false).setAttributeOrder(attributeOrder).build().writeObject(new
NullObject(), writer);
+        assertEquals(expectedJson, writer.toString());
+    }
+
+    @Test
+    public void writeNullObjectAllowNullSkipEmptyArray() {
+        final StringWriter writer = new StringWriter();
+
+        final String expectedJson =
"{\"stringIsnull\":null,\"integerIsnull\":null,\"nullArray\":null}";
+
+        final Comparator<String> attributeOrder = new Comparator<String>() {
+            @Override
+            public int compare(final String o1, final String o2) {
+                return expectedJson.indexOf(o1) - expectedJson.indexOf(o2);
+            }
+        };
+
+        new 
MapperBuilder().setSkipNull(false).setSkipEmptyArray(true).setAttributeOrder(attributeOrder).build()
+                .writeObject(new NullObject(), writer);
+        assertEquals(expectedJson, writer.toString());
+    }
+
+    @Test
+    public void writeNullObjectSkipAll() {
+        final StringWriter writer = new StringWriter();
+        new 
MapperBuilder().setSkipNull(true).setSkipEmptyArray(true).build().writeObject(new
NullObject(), writer);
+        assertEquals("{}", writer.toString());
+    }
+
+    public static class NullObjectWithMap {
+
+        private Map map = new LinkedHashMap();
+
+        NullObjectWithMap() {
+            super();
+            map.put("key1", "val1");
+            map.put("key2", null);
+            map.put(null, "val3");
+        }
+
+        public Map getMap() {
+            return map;
+        }
+
+        public void setMap(final Map map) {
+            this.map = map;
+        }
+
+    }
+
+    public static class NullObject {
+
+        private String stringIsnull;
+        private Integer integerIsnull;
+        private String[] nullArray;
+        private String[] emptyArray = new String[0];
+
+        public String[] getNullArray() {
+            return nullArray;
+        }
+
+        public void setNullArray(final String[] nullArray) {
+            this.nullArray = nullArray;
+        }
+
+        public String[] getEmptyArray() {
+            return emptyArray;
+        }
+
+        public void setEmptyArray(final String[] emptyArray) {
+            this.emptyArray = emptyArray;
+        }
+
+        public String getStringIsnull() {
+            return stringIsnull;
+        }
+
+        public void setStringIsnull(final String stringIsnull) {
+            this.stringIsnull = stringIsnull;
+        }
+
+        public Integer getIntegerIsnull() {
+            return integerIsnull;
+        }
+
+        public void setIntegerIsnull(final Integer integerIsnull) {
+            this.integerIsnull = integerIsnull;
+        }
+
+    }
+
+}

Reply via email to