Repository: johnzon
Updated Branches:
  refs/heads/master 2507062b0 -> 4166c51f6


JOHNZON-198 basic adder support


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

Branch: refs/heads/master
Commit: 4166c51f6daa73cf080b33896328f0b4bd13126f
Parents: 2507062
Author: Romain Manni-Bucau <[email protected]>
Authored: Mon Dec 17 18:11:12 2018 +0100
Committer: Romain Manni-Bucau <[email protected]>
Committed: Mon Dec 17 18:11:12 2018 +0100

----------------------------------------------------------------------
 .../jsonb/OverrideDefaultAdaptersTest.java      | 29 +++++-----
 .../johnzon/mapper/MappingParserImpl.java       | 20 +++++++
 .../org/apache/johnzon/mapper/Mappings.java     | 12 +++--
 .../johnzon/mapper/access/AccessMode.java       | 52 ++++++++++++++++--
 .../org/apache/johnzon/mapper/AdderTest.java    | 56 ++++++++++++++++++++
 5 files changed, 150 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/4166c51f/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/OverrideDefaultAdaptersTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/OverrideDefaultAdaptersTest.java
 
b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/OverrideDefaultAdaptersTest.java
index a7118c5..99b2f22 100644
--- 
a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/OverrideDefaultAdaptersTest.java
+++ 
b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/OverrideDefaultAdaptersTest.java
@@ -1,17 +1,20 @@
-/**
- * Copyright (C) 2006-2018 Talend Inc. - www.talend.com
- * <p>
- * Licensed 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
- * <p>
+/*
+ * 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
- * <p>
- * 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.
+ *
+ * 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.jsonb;
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/4166c51f/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
----------------------------------------------------------------------
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 a920324..4ad1633 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
@@ -357,6 +357,26 @@ public class MappingParserImpl implements MappingParser {
                 }
             }
         }
+        if (classMapping.mapAdder != null) {
+            object.entrySet().stream()
+                .filter(it -> !classMapping.setters.containsKey(it.getKey()))
+                .filter(it -> it.getValue().getValueType() != NULL)
+                .forEach(e -> {
+                    final Object convertedValue = toValue(
+                            null, e.getValue(), null, null,
+                            classMapping.mapAdderType, null,
+                            new JsonPointerTracker(jsonPointer, e.getKey()), 
inType);
+                    if (convertedValue != null) {
+                        try {
+                            classMapping.mapAdder.invoke(t, e.getKey(), 
convertedValue);
+                        } catch (final IllegalAccessException ex) {
+                            throw new IllegalStateException(ex);
+                        } catch (final InvocationTargetException ex) {
+                            throw new MapperException(ex.getCause());
+                        }
+                    }
+                });
+        }
 
         return t;
     }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/4166c51f/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
index d18d085..539fdb8 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
@@ -67,6 +67,8 @@ public class Mappings {
         public final ObjectConverter.Writer writer;
         public final Getter anyGetter;
         public final Method anySetter;
+        public final Method mapAdder;
+        public final Class<?> mapAdderType;
 
         private Boolean deduplicateObjects;
         private boolean deduplicationEvaluated = false;
@@ -75,7 +77,8 @@ public class Mappings {
                                final Map<String, Getter> getters, final 
Map<String, Setter> setters,
                                final Adapter<?, ?> adapter,
                                final ObjectConverter.Reader<?> reader, final 
ObjectConverter.Writer<?> writer,
-                               final Getter anyGetter, final Method anySetter) 
{
+                               final Getter anyGetter, final Method anySetter,
+                               final Method mapAdder) {
             this.clazz = clazz;
             this.factory = factory;
             this.getters = getters;
@@ -85,11 +88,13 @@ public class Mappings {
             this.reader = reader;
             this.anyGetter = anyGetter;
             this.anySetter = anySetter;
+            this.mapAdder = mapAdder;
+            this.mapAdderType = mapAdder == null ? null : 
mapAdder.getParameterTypes()[1];
         }
 
         public Boolean isDeduplicateObjects() {
             if (!deduplicationEvaluated) {
-                JohnzonDeduplicateObjects jdo = 
((Class<JohnzonDeduplicateObjects>) 
clazz).getAnnotation(JohnzonDeduplicateObjects.class);
+                JohnzonDeduplicateObjects jdo = 
clazz.getAnnotation(JohnzonDeduplicateObjects.class);
                 if (jdo != null){
                     deduplicateObjects = jdo.value();
                 }
@@ -424,7 +429,8 @@ public class Mappings {
                 anyGetter != null ? new Getter(
                         new MethodAccessMode.MethodReader(anyGetter, 
anyGetter.getReturnType()),
                         false,false, false, false, true, null, null, -1, null) 
: null,
-                accessMode.findAnySetter(clazz));
+                accessMode.findAnySetter(clazz),
+                Map.class.isAssignableFrom(clazz) ? 
accessMode.findMapAdder(clazz) : null);
 
         accessMode.afterParsed(clazz);
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/4166c51f/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java
index 4d590bf..6c95675 100644
--- 
a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java
+++ 
b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java
@@ -18,14 +18,56 @@
  */
 package org.apache.johnzon.mapper.access;
 
-import org.apache.johnzon.mapper.Adapter;
-import org.apache.johnzon.mapper.ObjectConverter;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.Comparator;
 import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+import org.apache.johnzon.mapper.Adapter;
+import org.apache.johnzon.mapper.ObjectConverter;
+
+@FunctionalInterface
+interface FindMethod {
+    Method get(String name, Class<?> type, Class<?> param) throws 
NoSuchMethodException;
+}
+
+class MapHelper {
+    private MapHelper() {
+        // no-op
+    }
+
+    static Method find(final FindMethod finder, final Class<?> type) {
+        return Stream.of(type.getGenericSuperclass())
+                     .filter(ParameterizedType.class::isInstance)
+                     .map(ParameterizedType.class::cast)
+                     .filter(it -> Class.class.isInstance(it.getRawType()) && 
Map.class.isAssignableFrom(Class.class.cast(it.getRawType())))
+                     .map(ParameterizedType::getActualTypeArguments)
+                     .filter(a -> a.length == 2)
+                     .map(a -> a[1])
+                     .filter(Class.class::isInstance)
+                     .map(Class.class::cast)
+                     .flatMap(param -> {
+                         final String simpleName = param.getSimpleName();
+                         return Stream.of( // direct name or if the pattern is 
FoosImpl try addFoo
+                                 simpleName,
+                                 simpleName.replaceAll("Impl$" 
,"").replaceAll("s$", ""))
+                                      .map(it -> {
+                                          try {
+                                              return finder.get(it, type, 
param);
+                                          } catch (final NoSuchMethodException 
e) {
+                                              return null;
+                                          }
+                                      })
+                                      .filter(Objects::nonNull);
+                     })
+                     .findFirst()
+                     .orElse(null);
+    }
+}
 
 public interface AccessMode {
     interface DecoratedType {
@@ -65,6 +107,10 @@ public interface AccessMode {
     Method findAnyGetter(Class<?> clazz);
     Method findAnySetter(Class<?> clazz);
 
+    default Method findMapAdder(final Class<?> clazz) {
+        return MapHelper.find((name, type, param) -> type.getMethod("add" + 
name, String.class, param), clazz);
+    }
+
     /**
      * Called once johnzon will not use AccessMode anymore. Can be used to 
clean up any local cache.
      *

http://git-wip-us.apache.org/repos/asf/johnzon/blob/4166c51f/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/AdderTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/AdderTest.java 
b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/AdderTest.java
new file mode 100644
index 0000000..82b5ae9
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/AdderTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.Collections.singletonMap;
+import static org.junit.Assert.assertEquals;
+
+import java.util.LinkedHashMap;
+
+import org.junit.Test;
+
+public class AdderTest {
+    @Test
+    public void adderString() {
+        assertEquals(singletonMap("foo", "bar"), new MapperBuilder().build()
+                .readObject("{\"foo\":\"bar\"}", MyMap.class));
+    }
+    @Test
+    public void adderObject() {
+        final MyMapOfObjects map = new MapperBuilder().build()
+                                                 
.readObject("{\"foo\":{\"value\":\"bar\"}}", MyMapOfObjects.class);
+        assertEquals("bar", map.get("foo").value);
+    }
+
+    public static class MyMap extends LinkedHashMap<String, String>  {
+        public void addString(final String name, final String value) {
+            put(name, value);
+        }
+    }
+
+    public static class MyObject {
+        public String value;
+    }
+
+    public static class MyMapOfObjects extends LinkedHashMap<String, MyObject> 
 {
+        public void addMyObject(final String name, final MyObject value) {
+            put(name, value);
+        }
+    }
+}

Reply via email to