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
commit aa5b800e1eb3840f74af8e3190d8a4bea0748b61 Author: Romain Manni-Bucau <[email protected]> AuthorDate: Wed Aug 7 18:15:55 2019 +0200 JOHNZON-228 ensure all primitives are mapped in Mapper#readObject and not only JSON-P ones --- .../apache/johnzon/mapper/MappingParserImpl.java | 34 +++++--- .../apache/johnzon/mapper/number/Validator.java | 35 ++++++++ .../apache/johnzon/mapper/ReadPrimitiveTest.java | 93 ++++++++++++++++++++++ 3 files changed, 152 insertions(+), 10 deletions(-) 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 ee2ae64..c9aa1b4 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 @@ -24,6 +24,7 @@ import org.apache.johnzon.mapper.converter.EnumConverter; import org.apache.johnzon.mapper.internal.AdapterKey; import org.apache.johnzon.mapper.internal.ConverterAdapter; import org.apache.johnzon.mapper.internal.JsonPointerTracker; +import org.apache.johnzon.mapper.number.Validator; import org.apache.johnzon.mapper.reflection.JohnzonParameterizedType; import javax.json.JsonArray; @@ -140,8 +141,17 @@ public class MappingParserImpl implements MappingParser { if (JsonObject.class.isInstance(jsonValue)) { return (T) buildObject(targetType, JsonObject.class.cast(jsonValue), applyObjectConverter, isDeduplicateObjects ? new JsonPointerTracker(null, "/") : null); } - if (JsonString.class.isInstance(jsonValue) && (targetType == String.class || targetType == Object.class)) { - return (T) JsonString.class.cast(jsonValue).getString(); + if (JsonString.class.isInstance(jsonValue)) { + if ((targetType == String.class || targetType == Object.class)) { + return (T) JsonString.class.cast(jsonValue).getString(); + } + if (targetType == Character.class || targetType == char.class) { + final CharSequence string = JsonString.class.cast(jsonValue).getChars(); + if (string.length() == 1) { + return (T) Character.valueOf(string.charAt(0)); + } + throw new IllegalArgumentException("Invalid Character binding"); // don't log the value (pwd case) + } } if (JsonNumber.class.isInstance(jsonValue)) { final JsonNumber number = JsonNumber.class.cast(jsonValue); @@ -154,6 +164,17 @@ public class MappingParserImpl implements MappingParser { if (targetType == double.class || targetType == Double.class || targetType == Object.class) { return (T) Double.valueOf(number.doubleValue()); } + if (targetType == float.class || targetType == Float.class) { + return (T) Float.valueOf((float) number.doubleValue()); + } + if (targetType == byte.class || targetType == Byte.class) { + final int intValue = number.intValue(); + Validator.validateByte(intValue); + return (T) Byte.valueOf((byte) intValue); + } + if (targetType == short.class || targetType == Short.class) { + return (T) Short.valueOf((short) number.intValue()); + } if (targetType == BigDecimal.class) { return (T) number.bigDecimalValue(); } @@ -607,14 +628,7 @@ public class MappingParserImpl implements MappingParser { } if (type == Byte.class || type == byte.class) { - - // bytes have a special handling as they are often used - // to transport binary. So we have to pass on the full 8 bit. - // TODO: ATTENTION: this is only an intermediate solution until JOHNZON-177 - // resp https://github.com/eclipse-ee4j/jsonb-api/issues/82 is properly specced - if (intValue < -128 || intValue > 255) { - throw new java.lang.ArithmeticException("Overflow"); - } + Validator.validateByte(intValue); return (byte) intValue; } diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/number/Validator.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/number/Validator.java new file mode 100644 index 0000000..7e550d2 --- /dev/null +++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/number/Validator.java @@ -0,0 +1,35 @@ +/* + * 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.number; + +public final class Validator { + private Validator() { + // no-op + } + + public static void validateByte(final int value) { + // bytes have a special handling as they are often used + // to transport binary. So we have to pass on the full 8 bit. + // TODO: ATTENTION: this is only an intermediate solution until JOHNZON-177 + // resp https://github.com/eclipse-ee4j/jsonb-api/issues/82 is properly specced + if (value < -128 || value > 255) { + throw new java.lang.ArithmeticException("Overflow"); + } + } +} diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ReadPrimitiveTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ReadPrimitiveTest.java new file mode 100644 index 0000000..77ffbbb --- /dev/null +++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ReadPrimitiveTest.java @@ -0,0 +1,93 @@ +/* + * 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 static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class ReadPrimitiveTest { + private final Mapper mapper = new MapperBuilder().build(); + + @Test + public void testBoolean() { + final Boolean val1 = mapper.readObject("false", Boolean.class); + final Boolean val2 = mapper.readObject("true", Boolean.TYPE); + assertFalse(val1); + assertTrue(val2); + } + + @Test + public void testByte() { + final Byte val1 = mapper.readObject("-50", Byte.class); + final Byte val2 = mapper.readObject("110", Byte.TYPE); + assertEquals((byte) -50, val1.byteValue()); + assertEquals((byte) 110, val2.byteValue()); + } + + @Test + public void testCharacter() { + final Character val1 = mapper.readObject("\"a\"", Character.class); + final Character val2 = mapper.readObject("\"-\"", Character.TYPE); + assertEquals('a', val1.charValue()); + assertEquals('-', val2.charValue()); + } + + @Test + public void testDouble() { + final Double val1 = mapper.readObject("5.096684684960", Double.class); + final Double val2 = mapper.readObject("-886968406846.86468464", Double.TYPE); + assertEquals(5.096684684960, val1, 0.0000001); + assertEquals(-886968406846.86468464, val2, 0.0000001); + } + + @Test + public void testFloat() { + final Float val1 = mapper.readObject("5.0964960", Float.class); + final Float val2 = mapper.readObject("-886946.864", Float.TYPE); + assertEquals(5.0964960, val1, 0.00001); + assertEquals(-886946.864, val2, 0.02); + } + + @Test + public void testInteger() { + final Integer val1 = mapper.readObject("450500", Integer.class); + final Integer val2 = mapper.readObject("8984609", Integer.TYPE); + assertEquals(450500, val1.intValue()); + assertEquals(8984609, val2.intValue()); + } + + @Test + public void testLong() { + final Long val1 = mapper.readObject("45050880", Long.class); + final Long val2 = mapper.readObject("898464509", Long.TYPE); + assertEquals(45050880L, val1.longValue()); + assertEquals(898464509L, val2.longValue()); + } + + @Test + public void testShort() { + final Short val1 = mapper.readObject("4505", Short.class); + final Short val2 = mapper.readObject("4509", Short.TYPE); + assertEquals((short) 4505, val1.shortValue()); + assertEquals((short) 4509, val2.shortValue()); + } +}
