Repository: johnzon Updated Branches: refs/heads/master 6ce0f08ac -> f8d76d759
JOHNZON-112 custom enum serialization support for arrays Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/f8d76d75 Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/f8d76d75 Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/f8d76d75 Branch: refs/heads/master Commit: f8d76d75969d826b0e3d046b4baed0114758e696 Parents: 6ce0f08 Author: rmannibucau <[email protected]> Authored: Thu Mar 30 09:41:11 2017 +0200 Committer: rmannibucau <[email protected]> Committed: Thu Mar 30 09:41:11 2017 +0200 ---------------------------------------------------------------------- .../org/apache/johnzon/mapper/MapperConfig.java | 6 ++ .../johnzon/mapper/MappingParserImpl.java | 9 ++- .../org/apache/johnzon/mapper/Mappings.java | 15 +++-- .../johnzon/mapper/CustomEnumCodecTest.java | 67 ++++++++++++++++++++ 4 files changed, 87 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/johnzon/blob/f8d76d75/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java ---------------------------------------------------------------------- diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java index 7b84f7a..983066d 100644 --- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java +++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperConfig.java @@ -106,6 +106,12 @@ public /* DON'T MAKE IT HIDDEN */ class MapperConfig implements Cloneable { if (converter != null) { return converter; } + /* could be an option but doesnt fit well our old converters + final Adapter<?, ?> reverseConverter = adapters.get(new AdapterKey(String.class, aClass)); + if (reverseConverter != null) { + return new ReversedAdapter<>(reverseConverter); + } + */ if (Class.class.isInstance(aClass)) { final Class<?> clazz = Class.class.cast(aClass); if (clazz.isEnum()) { http://git-wip-us.apache.org/repos/asf/johnzon/blob/f8d76d75/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 3e2a66e..4810f9d 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 @@ -161,16 +161,19 @@ public class MappingParserImpl implements MappingParser { JsonArray jsonArray = (JsonArray) jsonValue; if (Class.class.isInstance(targetType) && ((Class) targetType).isArray()) { - return (T) buildArrayWithComponentType(jsonArray, ((Class) targetType).getComponentType(), null); + final Class componentType = ((Class) targetType).getComponentType(); + return (T) buildArrayWithComponentType(jsonArray, componentType, config.findAdapter(componentType)); } if (ParameterizedType.class.isInstance(targetType)) { - final Mappings.CollectionMapping mapping = mappings.findCollectionMapping((ParameterizedType) targetType); + final ParameterizedType pt = (ParameterizedType) targetType; + final Mappings.CollectionMapping mapping = mappings.findCollectionMapping(pt); if (mapping == null) { throw new UnsupportedOperationException("type " + targetType + " not supported"); } - return (T) mapCollection(mapping, jsonArray, null); + final Type arg = pt.getActualTypeArguments()[0]; + return (T) mapCollection(mapping, jsonArray, Class.class.isInstance(arg) ? config.findAdapter(Class.class.cast(arg)) : null); } if (Object.class == targetType) { return (T) new ArrayList(asList(Object[].class.cast(buildArrayWithComponentType(jsonArray, Object.class, null)))); http://git-wip-us.apache.org/repos/asf/johnzon/blob/f8d76d75/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 7dd016c..35dea61 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 @@ -531,13 +531,6 @@ public class Mappings { if (Date.class.isAssignableFrom(type) && copyDate) { converter = new DateWithCopyConverter(Adapter.class.cast(adapters.get(new AdapterKey(Date.class, String.class)))); - } else if (type.isEnum()) { - final AdapterKey key = new AdapterKey(String.class, type); - converter = adapters.get(key); // first ensure user didnt override it - if (converter == null) { - converter = new ConverterAdapter(new EnumConverter(type)); - adapters.put(key, (Adapter<?, ?>) converter); - } } else { for (final Map.Entry<AdapterKey, Adapter<?, ?>> adapterEntry : adapters.entrySet()) { if (adapterEntry.getKey().getFrom() == adapterEntry.getKey().getTo()) { // String -> String @@ -555,6 +548,14 @@ public class Mappings { } } } + if (converter == null && type.isEnum()) { + final AdapterKey key = new AdapterKey(String.class, type); + converter = adapters.get(key); // first ensure user didnt override it + if (converter == null) { + converter = new ConverterAdapter(new EnumConverter(type)); + adapters.put(key, (Adapter<?, ?>) converter); + } + } } return converter; } http://git-wip-us.apache.org/repos/asf/johnzon/blob/f8d76d75/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/CustomEnumCodecTest.java ---------------------------------------------------------------------- diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/CustomEnumCodecTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/CustomEnumCodecTest.java new file mode 100644 index 0000000..0125ff4 --- /dev/null +++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/CustomEnumCodecTest.java @@ -0,0 +1,67 @@ +/* + * 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 org.junit.Test; + +import java.io.StringReader; +import java.util.Locale; + +import static org.junit.Assert.assertEquals; + +public class CustomEnumCodecTest { + @Test + public void roundTrip() { + final Mapper mapper = new MapperBuilder().addAdapter(E.class, String.class, new EConverter()).build(); + final String json = "{\"e\":\"a\"}"; + final EHolder holder = mapper.readObject(json, EHolder.class); + assertEquals(E.A, holder.e); + assertEquals(json, mapper.writeObjectAsString(holder)); + } + + @Test + public void roundTripArray() { + final Mapper mapper = new MapperBuilder().addAdapter(E.class, String.class, new EConverter()).build(); + final String json = "[\"b\"]"; + final E[] es = mapper.readArray(new StringReader(json), E.class); + assertEquals(1, es.length); + assertEquals(E.B, es[0]); + assertEquals(json, mapper.writeArrayAsString(es)); + } + + public static class EHolder { + public E e; + } + + public enum E { + A, B + } + + public static class EConverter implements Adapter<E, String> { + @Override + public String from(final E instance) { + return instance.name().toLowerCase(Locale.ENGLISH); + } + + @Override + public E to(final String text) { + return E.valueOf(text.toUpperCase(Locale.ENGLISH)); + } + } +}
