From 929c5b3fe28e62c379883bdfa3146a5324889eb7 Mon Sep 17 00:00:00 2001 From: salyh Date: Sat, 16 Aug 2014 15:36:07 +0200 Subject: [PATCH] Mapper: fix boolean and char handling Signed-off-by: salyh --- .../main/java/org/apache/fleece/mapper/Mapper.java | 89 +++++++++++++++++----- .../org/apache/fleece/mapper/MapperBuilder.java | 4 + .../apache/fleece/mapper/reflection/Mappings.java | 2 + .../apache/fleece/mapper/MapperEnhancedTest.java | 39 +++++++++- .../java/org/apache/fleece/mapper/MapperTest.java | 6 +- 5 files changed, 117 insertions(+), 23 deletions(-) diff --git a/fleece-mapper/src/main/java/org/apache/fleece/mapper/Mapper.java b/fleece-mapper/src/main/java/org/apache/fleece/mapper/Mapper.java index 967d597..a258579 100644 --- a/fleece-mapper/src/main/java/org/apache/fleece/mapper/Mapper.java +++ b/fleece-mapper/src/main/java/org/apache/fleece/mapper/Mapper.java @@ -107,7 +107,13 @@ public class Mapper { return generator.write(BigDecimal.class.cast(value)); } else if (type == BigInteger.class) { return generator.write(BigInteger.class.cast(value)); - } + } else if (type == short.class || type == Short.class) { + return generator.write(Short.class.cast(value).shortValue()); + } else if (type == char.class || type == Character.class) { + return generator.write(Character.class.cast(value).toString()); + } else if (type == byte.class || type == Byte.class) { + return generator.write(Byte.class.cast(value).byteValue()); + } return null; } @@ -129,7 +135,9 @@ public class Mapper { return generator.write(key, BigDecimal.class.cast(value)); } else if (type == BigInteger.class) { return generator.write(key, BigInteger.class.cast(value)); - } + } else if (type == char.class || type == Character.class) { + return generator.write(key, Character.class.cast(value).toString()); + } return generator; } @@ -519,41 +527,84 @@ public class Mapper { } private Object toObject(final JsonValue jsonValue, final Type type) throws InstantiationException, IllegalAccessException { + + if(jsonValue == null || jsonValue == JsonValue.NULL) { + return null; + } + + if (type == Boolean.class || type == boolean.class) { + + //if this would be commented out than the json string value "true" would pe parsed to a bool literal + //but this is according to json spec invalid + /*if (JsonString.class.isInstance(jsonValue)) { + return Boolean.valueOf(JsonString.class.cast(jsonValue).getString()); + }*/ + + if(jsonValue == JsonValue.FALSE) { + return Boolean.FALSE; + } + + if(jsonValue == JsonValue.TRUE) { + return Boolean.TRUE; + } + + throw new MapperException("Unable to parse "+jsonValue+" to boolean"); + } + + if (type == Character.class || type == char.class) { + + return convertTo(Class.class.cast(type), (JsonString.class.cast(jsonValue).getString())); + } - Object convertedValue = null; if (JsonObject.class.isInstance(jsonValue)) { - convertedValue = buildObject(type, JsonObject.class.cast(jsonValue)); + return buildObject(type, JsonObject.class.cast(jsonValue)); } else if (JsonArray.class.isInstance(jsonValue)) { - convertedValue = buildArray(type, JsonArray.class.cast(jsonValue)); - } else if (JsonString.class.isInstance(jsonValue)) { - convertedValue = JsonString.class.cast(jsonValue).getString(); - } else if (jsonValue != null && JsonValue.NULL != jsonValue) { - if (JsonNumber.class.isInstance(jsonValue)) { + return buildArray(type, JsonArray.class.cast(jsonValue)); + } else if (JsonNumber.class.isInstance(jsonValue)) { + final JsonNumber number = JsonNumber.class.cast(jsonValue); + + if (type == Long.class || type == long.class) { + return number.longValue(); + } + if (type == Integer.class || type == int.class) { return number.intValue(); } - if (type == Long.class || type == long.class) { - return number.longValue(); + + if (type == Short.class || type == short.class) { + return (short) number.intValue(); + } + + if (type == Byte.class || type == byte.class) { + return (byte) number.intValue(); } + + if (type == Byte.class || type == byte.class) { + return (byte) number.intValue(); + } + + if (type == Float.class || type == float.class) { + return (float) number.doubleValue(); + } + if (type == Double.class || type == double.class) { return number.doubleValue(); } + if (type == BigInteger.class) { return number.bigIntegerValue(); } if (type == BigDecimal.class) { return number.bigDecimalValue(); } - } - - final String text = jsonValue.toString(); - if (text != null) { - - convertedValue = convertTo(Class.class.cast(type), text); - } + + } else if (JsonString.class.isInstance(jsonValue)) { + return convertTo(Class.class.cast(type), (JsonString.class.cast(jsonValue).getString())); } - return convertedValue; + + + throw new MapperException("Unable to parse "+jsonValue+" to "+type); } private Object buildArray(final Type type, final JsonArray jsonArray) throws IllegalAccessException, InstantiationException { diff --git a/fleece-mapper/src/main/java/org/apache/fleece/mapper/MapperBuilder.java b/fleece-mapper/src/main/java/org/apache/fleece/mapper/MapperBuilder.java index 02b2de2..7ec07bd 100644 --- a/fleece-mapper/src/main/java/org/apache/fleece/mapper/MapperBuilder.java +++ b/fleece-mapper/src/main/java/org/apache/fleece/mapper/MapperBuilder.java @@ -23,6 +23,7 @@ import org.apache.fleece.mapper.converter.BigIntegerConverter; import org.apache.fleece.mapper.converter.BooleanConverter; import org.apache.fleece.mapper.converter.ByteConverter; import org.apache.fleece.mapper.converter.CachedDelegateConverter; +import org.apache.fleece.mapper.converter.CharacterConverter; import org.apache.fleece.mapper.converter.ClassConverter; import org.apache.fleece.mapper.converter.DateConverter; import org.apache.fleece.mapper.converter.DoubleConverter; @@ -35,6 +36,7 @@ import org.apache.fleece.mapper.converter.StringConverter; import javax.json.JsonReaderFactory; import javax.json.spi.JsonProvider; import javax.json.stream.JsonGeneratorFactory; + import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collections; @@ -54,6 +56,7 @@ public class MapperBuilder { DEFAULT_CONVERTERS.put(BigDecimal.class, new BigDecimalConverter()); DEFAULT_CONVERTERS.put(BigInteger.class, new BigIntegerConverter()); DEFAULT_CONVERTERS.put(Byte.class, new CachedDelegateConverter(new ByteConverter())); + DEFAULT_CONVERTERS.put(Character.class, new CharacterConverter()); DEFAULT_CONVERTERS.put(Double.class, new DoubleConverter()); DEFAULT_CONVERTERS.put(Float.class, new FloatConverter()); DEFAULT_CONVERTERS.put(Integer.class, new IntegerConverter()); @@ -61,6 +64,7 @@ public class MapperBuilder { DEFAULT_CONVERTERS.put(Short.class, new ShortConverter()); DEFAULT_CONVERTERS.put(Boolean.class, new CachedDelegateConverter(new BooleanConverter())); DEFAULT_CONVERTERS.put(byte.class, DEFAULT_CONVERTERS.get(Byte.class)); + DEFAULT_CONVERTERS.put(char.class, new CharacterConverter()); DEFAULT_CONVERTERS.put(double.class, DEFAULT_CONVERTERS.get(Double.class)); DEFAULT_CONVERTERS.put(float.class, DEFAULT_CONVERTERS.get(Float.class)); DEFAULT_CONVERTERS.put(int.class, DEFAULT_CONVERTERS.get(Integer.class)); diff --git a/fleece-mapper/src/main/java/org/apache/fleece/mapper/reflection/Mappings.java b/fleece-mapper/src/main/java/org/apache/fleece/mapper/reflection/Mappings.java index 51a2299..4006515 100644 --- a/fleece-mapper/src/main/java/org/apache/fleece/mapper/reflection/Mappings.java +++ b/fleece-mapper/src/main/java/org/apache/fleece/mapper/reflection/Mappings.java @@ -160,6 +160,8 @@ public class Mappings { public static boolean isPrimitive(final Type type) { if (type == String.class) { return true; + } else if (type == char.class || type == Character.class) { + return true; } else if (type == long.class || type == Long.class) { return true; } else if (type == int.class || type == Integer.class diff --git a/fleece-mapper/src/test/java/org/apache/fleece/mapper/MapperEnhancedTest.java b/fleece-mapper/src/test/java/org/apache/fleece/mapper/MapperEnhancedTest.java index 403ee34..4f020e6 100644 --- a/fleece-mapper/src/test/java/org/apache/fleece/mapper/MapperEnhancedTest.java +++ b/fleece-mapper/src/test/java/org/apache/fleece/mapper/MapperEnhancedTest.java @@ -18,12 +18,14 @@ */ package org.apache.fleece.mapper; +import org.junit.Assert; import org.junit.Test; import java.io.StringReader; import java.io.StringWriter; import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.HashMap; @@ -46,7 +48,21 @@ public class MapperEnhancedTest { new MapperBuilder().build().writeObject(null, sw); assertEquals("{}", sw.toString()); } - + + @Test + public void writeReadChar() { + CharClass charClass = new CharClass(); + charClass.setCharValue('G'); + charClass.setCharArr(new char[]{'G','O'}); + final StringWriter sw = new StringWriter(); + + new MapperBuilder().build().writeObject(charClass, sw); + assertEquals("{\"charArr\":[\"G\",\"O\"],\"charValue\":\"G\"}", sw.toString()); + CharClass read = new MapperBuilder().build().readObject(new StringReader(sw.toString()), CharClass.class); + Assert.assertNotNull(read); + Assert.assertEquals('G', read.getCharValue()); + Assert.assertTrue(Arrays.equals(new char[]{'G','O'}, read.getCharArr())); + } @Test public void writeReadSortedMap() { @@ -199,6 +215,27 @@ public class MapperEnhancedTest { } } + public static class CharClass { + private char charValue; + private char charArr[]; + + public char[] getCharArr() { + return charArr; + } + + public void setCharArr(char[] charArr) { + this.charArr = charArr; + } + + public char getCharValue() { + return charValue; + } + + public void setCharValue(char charValue) { + this.charValue = charValue; + } + } + public static class TestClass { private List> dates = new ArrayList>(); private Map>, Long> map = new HashMap>, Long>(); diff --git a/fleece-mapper/src/test/java/org/apache/fleece/mapper/MapperTest.java b/fleece-mapper/src/test/java/org/apache/fleece/mapper/MapperTest.java index bcba569..6779f0b 100644 --- a/fleece-mapper/src/test/java/org/apache/fleece/mapper/MapperTest.java +++ b/fleece-mapper/src/test/java/org/apache/fleece/mapper/MapperTest.java @@ -177,7 +177,7 @@ public class MapperTest { } - @Test(expected= IllegalArgumentException.class) + @Test(expected= MapperException.class) public void literalFail() { final Bool instance = new MapperBuilder().build() @@ -187,7 +187,7 @@ public class MapperTest { } - /*@Test(expected= IllegalArgumentException.class) + @Test(expected= MapperException.class) public void literalFail2() { final Bool2 instance = new MapperBuilder().build() @@ -195,7 +195,7 @@ public class MapperTest { - }*/ + } @Test public void writeArray() { -- 1.8.5.2 (Apple Git-48)