• R/O
  • SSH
  • HTTPS

jsonic: コミット


コミットメタ情報

リビジョン1852 (tree)
日時2015-05-04 03:00:32
作者hizuno

ログメッセージ

(メッセージはありません)

変更サマリ

差分

--- trunk/jsonic-1.3/src/net/arnx/jsonic/JSONReader.java (revision 1851)
+++ trunk/jsonic-1.3/src/net/arnx/jsonic/JSONReader.java (revision 1852)
@@ -1,12 +1,12 @@
1-/*
1+/*
22 * Copyright 2014 Hidekatsu Izuno
3- *
3+ *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
66 * You may obtain a copy of the License at
7- *
7+ *
88 * http://www.apache.org/licenses/LICENSE-2.0
9- *
9+ *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1212 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,75 +28,80 @@
2828 import net.arnx.jsonic.parse.JSONParser;
2929 import net.arnx.jsonic.parse.ScriptParser;
3030 import net.arnx.jsonic.parse.TraditionalParser;
31+import net.arnx.jsonic.util.ClassUtil;
3132
3233 public class JSONReader {
3334 private Context context;
3435 private JSONParser parser;
3536 private JSONEventType type;
36-
37+
3738 JSONReader(Context context, InputSource in, boolean multilineMode, boolean ignoreWhitespace) {
3839 this.context = context;
39-
40+
4041 switch (context.getMode()) {
4142 case STRICT:
42- parser = new JSONParser(in, context.getMaxDepth(), multilineMode, ignoreWhitespace,
43+ parser = new JSONParser(in, context.getMaxDepth(), multilineMode, ignoreWhitespace,
4344 context.getLocalCache());
4445 break;
4546 case SCRIPT:
46- parser = new ScriptParser(in, context.getMaxDepth(), multilineMode, ignoreWhitespace,
47+ parser = new ScriptParser(in, context.getMaxDepth(), multilineMode, ignoreWhitespace,
4748 context.getLocalCache());
4849 break;
4950 default:
50- parser = new TraditionalParser(in, context.getMaxDepth(), multilineMode, ignoreWhitespace,
51+ parser = new TraditionalParser(in, context.getMaxDepth(), multilineMode, ignoreWhitespace,
5152 context.getLocalCache());
5253 }
5354 }
54-
55+
5556 public JSONEventType next() throws IOException {
5657 type = parser.next();
5758 return type;
5859 }
59-
60+
6061 @SuppressWarnings("unchecked")
6162 public <T> T getValue(Class<T> cls) throws IOException {
62- return (T)context.convertInternal(getValue(), cls);
63+ return (T)context.convertInternal(getValue(), cls, cls);
6364 }
64-
65- public Object getValue(Type t) throws IOException {
66- return context.convertInternal(getValue(), t);
65+
66+ public Object getValue(Type type) throws IOException {
67+ if (type instanceof TypeReference<?>) {
68+ type = ((TypeReference<?>)type).getType();
69+ }
70+
71+ return context.convertInternal(getValue(), ClassUtil.getRawType(type), type);
6772 }
68-
73+
6974 public Map<?, ?> getMap() throws IOException {
7075 return (Map<?, ?>)getValue();
7176 }
72-
77+
7378 public List<?> getList() throws IOException {
7479 return (List<?>)getValue();
7580 }
76-
81+
7782 public String getString() throws IOException {
7883 return (String)parser.getValue();
7984 }
80-
85+
8186 public BigDecimal getNumber() throws IOException {
8287 return (BigDecimal)parser.getValue();
8388 }
84-
89+
8590 public Boolean getBoolean() throws IOException {
8691 return (Boolean)parser.getValue();
8792 }
88-
93+
8994 Object getValue() throws IOException {
9095 if (type == null) {
9196 throw new IllegalStateException("you should call next.");
9297 }
93-
98+
9499 int ilen = 0;
95100 int[] istack = new int[8];
96-
101+
97102 int olen = 0;
98103 Object[] ostack = new Object[16];
99-
104+
100105 do {
101106 switch (type) {
102107 case START_OBJECT:
@@ -129,9 +134,9 @@
129134 int start = istack[--ilen];
130135 int len = olen - start;
131136 Map<Object, Object> object = new LinkedHashMap<Object, Object>(
132- (len < 2) ? 4 :
133- (len < 4) ? 8 :
134- (len < 12) ? 16 :
137+ (len < 2) ? 4 :
138+ (len < 4) ? 8 :
139+ (len < 12) ? 16 :
135140 (int)(len / 0.75f) + 1);
136141 for (int i = start; i < olen; i+=2) {
137142 object.put(ostack[i], ostack[i+1]);
@@ -141,19 +146,19 @@
141146 ostack[olen++] = object;
142147 break;
143148 }
144-
149+
145150 if (parser.isInterpretterMode() && ilen == 0) {
146151 break;
147152 }
148153 } while ((type = parser.next()) != null);
149-
154+
150155 return ostack[0];
151156 }
152-
157+
153158 public int getDepth() {
154159 return parser.getDepth();
155160 }
156-
161+
157162 private int[] iexpand(int[] array, int min) {
158163 if (min > array.length) {
159164 int[] narray = new int[array.length * 3 / 2 + 1];
@@ -162,7 +167,7 @@
162167 }
163168 return array;
164169 }
165-
170+
166171 private Object[] oexpand(Object[] array, int min) {
167172 if (min > array.length) {
168173 Object[] narray = new Object[array.length * 3 / 2 + 1];
--- trunk/jsonic-1.3/src/net/arnx/jsonic/Formatter.java (revision 1851)
+++ trunk/jsonic-1.3/src/net/arnx/jsonic/Formatter.java (revision 1852)
@@ -42,9 +42,21 @@
4242 import java.util.List;
4343 import java.util.Locale;
4444 import java.util.Map;
45+import java.util.Optional;
46+import java.util.OptionalDouble;
47+import java.util.OptionalInt;
48+import java.util.OptionalLong;
4549 import java.util.RandomAccess;
4650 import java.util.TimeZone;
4751
52+import net.arnx.jsonic.JSON.Context;
53+import net.arnx.jsonic.JSON.Mode;
54+import net.arnx.jsonic.io.OutputSource;
55+import net.arnx.jsonic.util.Base64;
56+import net.arnx.jsonic.util.BeanInfo;
57+import net.arnx.jsonic.util.ClassUtil;
58+import net.arnx.jsonic.util.PropertyInfo;
59+
4860 import org.apache.commons.beanutils.DynaBean;
4961 import org.apache.commons.beanutils.DynaProperty;
5062 import org.w3c.dom.Attr;
@@ -58,14 +70,6 @@
5870 import org.w3c.dom.NodeList;
5971 import org.w3c.dom.Text;
6072
61-import net.arnx.jsonic.JSON.Context;
62-import net.arnx.jsonic.JSON.Mode;
63-import net.arnx.jsonic.io.OutputSource;
64-import net.arnx.jsonic.util.Base64;
65-import net.arnx.jsonic.util.BeanInfo;
66-import net.arnx.jsonic.util.ClassUtil;
67-import net.arnx.jsonic.util.PropertyInfo;
68-
6973 interface Formatter {
7074 boolean accept(Object o);
7175 boolean isStruct();
@@ -281,6 +285,24 @@
281285 out.append(o.toString());
282286 }
283287 }
288+
289+ public void format(final Context context, final int num, final OutputSource out) throws Exception {
290+ NumberFormat f = context.getNumberFormat();
291+ if (f != null) {
292+ StringFormatter.serialize(context, f.format(num), out);
293+ } else {
294+ out.append(Integer.toString(num));
295+ }
296+ }
297+
298+ public void format(final Context context, final long num, final OutputSource out) throws Exception {
299+ NumberFormat f = context.getNumberFormat();
300+ if (f != null) {
301+ StringFormatter.serialize(context, f.format(num), out);
302+ } else {
303+ out.append(Long.toString(num));
304+ }
305+ }
284306 }
285307
286308 final class EnumFormatter implements Formatter {
@@ -319,15 +341,18 @@
319341
320342 @Override
321343 public void format(final Context context, final Object src, final Object o, final OutputSource out) throws Exception {
344+ format(context, ((Number)o).doubleValue(), out);
345+ }
346+
347+ public void format(final Context context, final double d, final OutputSource out) throws Exception {
322348 NumberFormat f = context.getNumberFormat();
323349 if (f != null) {
324- StringFormatter.serialize(context, f.format(o), out);
350+ StringFormatter.serialize(context, f.format(d), out);
325351 } else {
326- double d = ((Number) o).doubleValue();
327352 if (Double.isNaN(d) || Double.isInfinite(d)) {
328353 if (context.getMode() != Mode.SCRIPT) {
329354 out.append('"');
330- out.append(o.toString());
355+ out.append(Double.toString(d));
331356 out.append('"');
332357 } else if (Double.isNaN(d)) {
333358 out.append("Number.NaN");
@@ -337,7 +362,7 @@
337362 out.append("_INFINITY");
338363 }
339364 } else {
340- out.append(o.toString());
365+ out.append(Double.toString(d));
341366 }
342367 }
343368 }
@@ -1458,7 +1483,7 @@
14581483 }
14591484 }
14601485
1461-final class TemporalFromatter implements Formatter {
1486+final class TemporalFormatter implements Formatter {
14621487 private static final Class<?>[] targets = {
14631488 TemporalAccessor.class,
14641489 TemporalAmount.class,
@@ -1465,7 +1490,7 @@
14651490 ZoneId.class
14661491 };
14671492
1468- public TemporalFromatter() {
1493+ public TemporalFormatter() {
14691494 }
14701495
14711496 @Override
@@ -1488,3 +1513,112 @@
14881513 StringFormatter.serialize(context, o.toString(), out);
14891514 }
14901515 }
1516+
1517+
1518+final class OptionalIntFormatter implements Formatter {
1519+ public static final OptionalIntFormatter INSTNACE = new OptionalIntFormatter();
1520+
1521+ public OptionalIntFormatter() {
1522+ }
1523+
1524+ @Override
1525+ public boolean accept(Object o) {
1526+ return o != null && OptionalInt.class.equals(o.getClass());
1527+ }
1528+
1529+ @Override
1530+ public boolean isStruct() {
1531+ return false;
1532+ }
1533+
1534+ @Override
1535+ public void format(Context context, Object src, Object o, OutputSource out) throws Exception {
1536+ OptionalInt optional = (OptionalInt)o;
1537+ if (optional.isPresent()) {
1538+ NumberFormatter.INSTANCE.format(context, optional.getAsInt(), out);
1539+ } else {
1540+ NullFormatter.INSTANCE.format(context, src, o, out);
1541+ }
1542+ }
1543+}
1544+
1545+final class OptionalLongFormatter implements Formatter {
1546+ public static final OptionalLongFormatter INSTNACE = new OptionalLongFormatter();
1547+
1548+ public OptionalLongFormatter() {
1549+ }
1550+
1551+ @Override
1552+ public boolean accept(Object o) {
1553+ return o != null && OptionalLong.class.equals(o.getClass());
1554+ }
1555+
1556+ @Override
1557+ public boolean isStruct() {
1558+ return false;
1559+ }
1560+
1561+ @Override
1562+ public void format(Context context, Object src, Object o, OutputSource out) throws Exception {
1563+ OptionalLong optional = (OptionalLong)o;
1564+ if (optional.isPresent()) {
1565+ NumberFormatter.INSTANCE.format(context, optional.getAsLong(), out);
1566+ } else {
1567+ NullFormatter.INSTANCE.format(context, src, o, out);
1568+ }
1569+ }
1570+}
1571+
1572+final class OptionalDoubleFormatter implements Formatter {
1573+ public static final OptionalDoubleFormatter INSTNACE = new OptionalDoubleFormatter();
1574+
1575+ public OptionalDoubleFormatter() {
1576+ }
1577+
1578+ @Override
1579+ public boolean accept(Object o) {
1580+ return o != null && OptionalDouble.class.equals(o.getClass());
1581+ }
1582+
1583+ @Override
1584+ public boolean isStruct() {
1585+ return false;
1586+ }
1587+
1588+ @Override
1589+ public void format(Context context, Object src, Object o, OutputSource out) throws Exception {
1590+ OptionalDouble optional = (OptionalDouble)o;
1591+ if (optional.isPresent()) {
1592+ FloatFormatter.INSTANCE.format(context, optional.getAsDouble(), out);
1593+ } else {
1594+ NullFormatter.INSTANCE.format(context, src, o, out);
1595+ }
1596+ }
1597+}
1598+
1599+final class OptionalFormatter implements Formatter {
1600+ public static final OptionalFormatter INSTNACE = new OptionalFormatter();
1601+
1602+ public OptionalFormatter() {
1603+ }
1604+
1605+ @Override
1606+ public boolean accept(Object o) {
1607+ return o != null && Optional.class.isAssignableFrom(o.getClass());
1608+ }
1609+
1610+ @Override
1611+ public boolean isStruct() {
1612+ return false;
1613+ }
1614+
1615+ @Override
1616+ public void format(Context context, Object src, Object o, OutputSource out) throws Exception {
1617+ Optional<?> optional = (Optional<?>)o;
1618+ if (optional.isPresent()) {
1619+ context.formatInternal(optional.get(), out);
1620+ } else {
1621+ NullFormatter.INSTANCE.format(context, src, o, out);
1622+ }
1623+ }
1624+}
--- trunk/jsonic-1.3/src/net/arnx/jsonic/Converter.java (revision 1851)
+++ trunk/jsonic-1.3/src/net/arnx/jsonic/Converter.java (revision 1852)
@@ -63,6 +63,10 @@
6363 import java.util.List;
6464 import java.util.Locale;
6565 import java.util.Map;
66+import java.util.Optional;
67+import java.util.OptionalDouble;
68+import java.util.OptionalInt;
69+import java.util.OptionalLong;
6670 import java.util.Properties;
6771 import java.util.SortedMap;
6872 import java.util.TimeZone;
@@ -82,19 +86,6 @@
8286 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception;
8387 }
8488
85-final class NullConverter implements Converter {
86- public static final NullConverter INSTANCE = new NullConverter();
87-
88- @Override
89- public boolean accept(Class<?> cls) {
90- return true;
91- }
92-
93- public Object convert(Context context, Object value, Class<?> c, Type t) {
94- return null;
95- }
96-}
97-
9889 final class NullableConverter implements Converter {
9990 private static final Class<?>[] targets = new Class<?>[] {
10091 java.sql.Array.class,
@@ -122,31 +113,14 @@
122113 final class PlainConverter implements Converter {
123114 public static final PlainConverter INSTANCE = new PlainConverter();
124115
125- private static final Map<Class<?>, Object> PRIMITIVE_MAP = new HashMap<Class<?>, Object>(8);
126-
127- static {
128- PRIMITIVE_MAP.put(boolean.class, false);
129- PRIMITIVE_MAP.put(byte.class, (byte)0);
130- PRIMITIVE_MAP.put(short.class, (short)0);
131- PRIMITIVE_MAP.put(int.class, 0);
132- PRIMITIVE_MAP.put(long.class, 0l);
133- PRIMITIVE_MAP.put(float.class, 0.0f);
134- PRIMITIVE_MAP.put(double.class, 0.0);
135- PRIMITIVE_MAP.put(char.class, '\0');
136- }
137-
138116 @Override
139117 public boolean accept(Class<?> cls) {
140- return PRIMITIVE_MAP.containsKey(cls);
118+ return true;
141119 }
142120
143121 public Object convert(Context context, Object value, Class<?> c, Type t) {
144122 return value;
145123 }
146-
147- public static Object getDefaultValue(Class<?> cls) {
148- return PRIMITIVE_MAP.get(cls);
149- }
150124 }
151125
152126 final class FormatConverter implements Converter {
@@ -186,7 +160,9 @@
186160 }
187161
188162 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
189- if (c.isEnum() || Enum.class.isAssignableFrom(c)) {
163+ if (value == null) {
164+ return null;
165+ } else if (c.isEnum() || Enum.class.isAssignableFrom(c)) {
190166 return EnumConverter.INSTANCE.convert(context, value, c, t);
191167 } else if (value instanceof String) {
192168 if (c == String.class) {
@@ -200,10 +176,9 @@
200176 return null;
201177 }
202178 }
203- } else if (value != null) {
179+ } else {
204180 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
205181 }
206- return null;
207182 }
208183 }
209184
@@ -216,12 +191,13 @@
216191 }
217192
218193 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
219- if (value instanceof String) {
194+ if (value == null) {
195+ return null;
196+ } else if (value instanceof String) {
220197 return ClassUtil.deserialize(Base64.decode((String)value));
221- } else if (value != null) {
198+ } else {
222199 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
223200 }
224- return null;
225201 }
226202 }
227203
@@ -230,11 +206,13 @@
230206
231207 @Override
232208 public boolean accept(Class<?> cls) {
233- return Boolean.class == cls;
209+ return boolean.class == cls || Boolean.class == cls;
234210 }
235211
236212 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
237- if (value instanceof Map<?, ?>) {
213+ if (value == null) {
214+ return (c == boolean.class) ? false : null;
215+ } else if (value instanceof Map<?, ?>) {
238216 value = ((Map<?,?>)value).get(null);
239217 } else if (value instanceof List<?>) {
240218 List<?> src = (List<?>)value;
@@ -241,7 +219,9 @@
241219 value = (!src.isEmpty()) ? src.get(0) : null;
242220 }
243221
244- if (value instanceof Boolean) {
222+ if (value == null) {
223+ return (c == boolean.class) ? false : null;
224+ } else if (value instanceof Boolean) {
245225 return value;
246226 } else if (value instanceof BigDecimal) {
247227 return !value.equals(BigDecimal.ZERO);
@@ -249,7 +229,7 @@
249229 return !value.equals(BigInteger.ZERO);
250230 } else if (value instanceof Number) {
251231 return ((Number)value).doubleValue() != 0;
252- } else if (value != null){
232+ } else {
253233 String s = value.toString().trim();
254234 if (s.length() == 0
255235 || s.equalsIgnoreCase("0")
@@ -263,7 +243,6 @@
263243 return true;
264244 }
265245 }
266- return PlainConverter.getDefaultValue(c);
267246 }
268247 }
269248
@@ -276,7 +255,9 @@
276255 }
277256
278257 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
279- if (value instanceof Map<?, ?>) {
258+ if (value == null) {
259+ return (c == char.class) ? '\0' : null;
260+ } else if (value instanceof Map<?, ?>) {
280261 value = ((Map<?,?>)value).get(null);
281262 } else if (value instanceof List<?>) {
282263 List<?> src = (List<?>)value;
@@ -283,7 +264,9 @@
283264 value = (!src.isEmpty()) ? src.get(0) : null;
284265 }
285266
286- if (value instanceof Boolean) {
267+ if (value == null) {
268+ return (c == char.class) ? '\0' : null;
269+ } else if (value instanceof Boolean) {
287270 return (((Boolean)value).booleanValue()) ? '1' : '0';
288271 } else if (value instanceof BigDecimal) {
289272 return (char)((BigDecimal)value).intValueExact();
@@ -292,12 +275,13 @@
292275 if (s.length() > 0) {
293276 return s.charAt(0);
294277 } else {
295- return PlainConverter.getDefaultValue(c);
278+ return (c == char.class) ? '\0' : null;
296279 }
297- } else if (value != null) {
280+ } else if (value instanceof Number) {
281+ return (char)((Number)value).intValue();
282+ } else {
298283 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
299284 }
300- return PlainConverter.getDefaultValue(c);
301285 }
302286 }
303287
@@ -310,7 +294,9 @@
310294 }
311295
312296 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
313- if (value instanceof Map<?, ?>) {
297+ if (value == null) {
298+ return (c == byte.class) ? (byte)0 : null;
299+ } else if (value instanceof Map<?, ?>) {
314300 value = ((Map<?,?>)value).get(null);
315301 } else if (value instanceof List<?>) {
316302 List<?> src = (List<?>)value;
@@ -317,18 +303,14 @@
317303 value = (!src.isEmpty()) ? src.get(0) : null;
318304 }
319305
320- if (value instanceof String) {
306+ if (value == null) {
307+ return (c == byte.class) ? (byte)0 : null;
308+ } else if (value instanceof BigDecimal) {
309+ return ((BigDecimal)value).byteValueExact();
310+ } else if (value instanceof String) {
321311 NumberFormat f = context.getNumberFormat();
322312 if (f != null) value = f.parse((String)value);
323- }
324313
325- if (value instanceof Boolean) {
326- return (((Boolean)value).booleanValue()) ? 1 : 0;
327- } else if (value instanceof BigDecimal) {
328- return ((BigDecimal)value).byteValueExact();
329- } else if (value instanceof Number) {
330- return ((Number)value).byteValue();
331- } else if (value instanceof String) {
332314 String str = value.toString().trim().toLowerCase();
333315 if (str.length() > 0) {
334316 int start = 0;
@@ -345,12 +327,15 @@
345327
346328 return (byte)((num > 127) ? num-256 : num);
347329 } else {
348- return PlainConverter.getDefaultValue(c);
330+ return (c == byte.class) ? (byte)0 : null;
349331 }
350- } else if (value != null) {
332+ } else if (value instanceof Boolean) {
333+ return (((Boolean)value).booleanValue()) ? 1 : 0;
334+ } else if (value instanceof Number) {
335+ return ((Number)value).byteValue();
336+ } else {
351337 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
352338 }
353- return PlainConverter.getDefaultValue(c);
354339 }
355340 }
356341
@@ -363,7 +348,9 @@
363348 }
364349
365350 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
366- if (value instanceof Map<?, ?>) {
351+ if (value == null) {
352+ return (c == short.class) ? (short)0 : null;
353+ } else if (value instanceof Map<?, ?>) {
367354 value = ((Map<?,?>)value).get(null);
368355 } else if (value instanceof List<?>) {
369356 List<?> src = (List<?>)value;
@@ -370,18 +357,14 @@
370357 value = (!src.isEmpty()) ? src.get(0) : null;
371358 }
372359
373- if (value instanceof String) {
360+ if (value == null) {
361+ return (c == short.class) ? (short)0 : null;
362+ } else if (value instanceof BigDecimal) {
363+ return ((BigDecimal)value).shortValueExact();
364+ } else if (value instanceof String) {
374365 NumberFormat f = context.getNumberFormat();
375366 if (f != null) value = f.parse((String)value);
376- }
377367
378- if (value instanceof Boolean) {
379- return (((Boolean)value).booleanValue()) ? 1 : 0;
380- } else if (value instanceof BigDecimal) {
381- return ((BigDecimal)value).shortValueExact();
382- } else if (value instanceof Number) {
383- return ((Number)value).shortValue();
384- } else if (value instanceof String) {
385368 String str = value.toString().trim();
386369 if (str.length() > 0) {
387370 int start = 0;
@@ -395,12 +378,15 @@
395378 return (short)Integer.parseInt(str.substring(start));
396379 }
397380 } else {
398- return PlainConverter.getDefaultValue(c);
381+ return (c == short.class) ? (short)0 : null;
399382 }
400- } else if (value != null) {
383+ } else if (value instanceof Boolean) {
384+ return (((Boolean)value).booleanValue()) ? 1 : 0;
385+ } else if (value instanceof Number) {
386+ return ((Number)value).shortValue();
387+ } else {
401388 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
402389 }
403- return PlainConverter.getDefaultValue(c);
404390 }
405391 }
406392
@@ -413,7 +399,9 @@
413399 }
414400
415401 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
416- if (value instanceof Map<?, ?>) {
402+ if (value == null) {
403+ return (c == int.class) ? 0 : null;
404+ } else if (value instanceof Map<?, ?>) {
417405 value = ((Map<?,?>)value).get(null);
418406 } else if (value instanceof List<?>) {
419407 List<?> src = (List<?>)value;
@@ -420,18 +408,14 @@
420408 value = (!src.isEmpty()) ? src.get(0) : null;
421409 }
422410
423- if (value instanceof String) {
411+ if (value == null) {
412+ return (c == int.class) ? 0 : null;
413+ } else if (value instanceof BigDecimal) {
414+ return ((BigDecimal)value).intValueExact();
415+ } else if (value instanceof String) {
424416 NumberFormat f = context.getNumberFormat();
425417 if (f != null) value = f.parse((String)value);
426- }
427418
428- if (value instanceof Boolean) {
429- return (((Boolean)value).booleanValue()) ? 1 : 0;
430- } else if (value instanceof BigDecimal) {
431- return ((BigDecimal)value).intValueExact();
432- } else if (value instanceof Number) {
433- return ((Number)value).intValue();
434- } else if (value instanceof String) {
435419 String str = value.toString().trim();
436420 if (str.length() > 0) {
437421 int start = 0;
@@ -445,12 +429,15 @@
445429 return Integer.parseInt(str.substring(start));
446430 }
447431 } else {
448- return PlainConverter.getDefaultValue(c);
432+ return (c == int.class) ? 0 : null;
449433 }
450- } else if (value != null) {
434+ } else if (value instanceof Boolean) {
435+ return (((Boolean)value).booleanValue()) ? 1 : 0;
436+ } else if (value instanceof Number) {
437+ return ((Number)value).intValue();
438+ } else {
451439 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
452440 }
453- return PlainConverter.getDefaultValue(c);
454441 }
455442 }
456443
@@ -463,7 +450,9 @@
463450 }
464451
465452 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
466- if (value instanceof Map<?, ?>) {
453+ if (value == null) {
454+ return (c == long.class) ? 0L : null;
455+ } else if (value instanceof Map<?, ?>) {
467456 value = ((Map<?,?>)value).get(null);
468457 } else if (value instanceof List<?>) {
469458 List<?> src = (List<?>)value;
@@ -470,18 +459,14 @@
470459 value = (!src.isEmpty()) ? src.get(0) : null;
471460 }
472461
473- if (value instanceof String) {
462+ if (value == null) {
463+ return (c == long.class) ? 0L : null;
464+ } else if (value instanceof BigDecimal) {
465+ return ((BigDecimal)value).longValueExact();
466+ } else if (value instanceof String) {
474467 NumberFormat f = context.getNumberFormat();
475468 if (f != null) value = f.parse((String)value);
476- }
477469
478- if (value instanceof Boolean) {
479- return (((Boolean)value).booleanValue()) ? 1l : 0l;
480- } else if (value instanceof BigDecimal) {
481- return ((BigDecimal)value).longValueExact();
482- } else if (value instanceof Number) {
483- return ((Number)value).longValue();
484- } else if (value instanceof String) {
485470 String str = value.toString().trim();
486471 if (str.length() > 0) {
487472 int start = 0;
@@ -495,12 +480,15 @@
495480 return Long.parseLong(str.substring(start));
496481 }
497482 } else {
498- return PlainConverter.getDefaultValue(c);
483+ return (c == long.class) ? 0L : null;
499484 }
500- } else if (value != null) {
485+ } else if (value instanceof Boolean) {
486+ return (((Boolean)value).booleanValue()) ? 1l : 0l;
487+ } else if (value instanceof Number) {
488+ return ((Number)value).longValue();
489+ } else {
501490 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
502491 }
503- return PlainConverter.getDefaultValue(c);
504492 }
505493 }
506494
@@ -513,7 +501,9 @@
513501 }
514502
515503 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
516- if (value instanceof Map<?, ?>) {
504+ if (value == null) {
505+ return (c == float.class) ? 0.0F : null;
506+ } else if (value instanceof Map<?, ?>) {
517507 value = ((Map<?,?>)value).get(null);
518508 } else if (value instanceof List<?>) {
519509 List<?> src = (List<?>)value;
@@ -520,26 +510,25 @@
520510 value = (!src.isEmpty()) ? src.get(0) : null;
521511 }
522512
523- if (value instanceof String) {
513+ if (value == null) {
514+ return (c == float.class) ? 0.0F : null;
515+ } else if (value instanceof String) {
524516 NumberFormat f = context.getNumberFormat();
525517 if (f != null) value = f.parse((String)value);
526- }
527518
528- if (value instanceof Boolean) {
529- return (((Boolean)value).booleanValue()) ? 1.0f : Float.NaN;
530- } else if (value instanceof Number) {
531- return ((Number)value).floatValue();
532- } else if (value instanceof String) {
533519 String str = value.toString().trim();
534520 if (str.length() > 0) {
535521 return Float.valueOf(str);
536522 } else {
537- return PlainConverter.getDefaultValue(c);
523+ return (c == float.class) ? 0.0F : null;
538524 }
539- } else if (value != null) {
525+ } else if (value instanceof Boolean) {
526+ return (((Boolean)value).booleanValue()) ? 1.0f : Float.NaN;
527+ } else if (value instanceof Number) {
528+ return ((Number)value).floatValue();
529+ } else {
540530 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
541531 }
542- return PlainConverter.getDefaultValue(c);
543532 }
544533 }
545534
@@ -552,7 +541,9 @@
552541 }
553542
554543 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
555- if (value instanceof Map<?, ?>) {
544+ if (value == null) {
545+ return (c == double.class) ? 0.0 : null;
546+ } else if (value instanceof Map<?, ?>) {
556547 value = ((Map<?,?>)value).get(null);
557548 } else if (value instanceof List<?>) {
558549 List<?> src = (List<?>)value;
@@ -559,26 +550,27 @@
559550 value = (!src.isEmpty()) ? src.get(0) : null;
560551 }
561552
562- if (value instanceof String) {
553+ if (value == null) {
554+ return (c == double.class) ? 0.0 : null;
555+ } else if (value instanceof BigDecimal) {
556+ return ((BigDecimal)value).doubleValue();
557+ } else if (value instanceof String) {
563558 NumberFormat f = context.getNumberFormat();
564559 if (f != null) value = f.parse((String)value);
565- }
566560
567- if (value instanceof Boolean) {
568- return (((Boolean)value).booleanValue()) ? 1.0 : Double.NaN;
569- } else if (value instanceof Number) {
570- return ((Number)value).doubleValue();
571- } else if (value instanceof String) {
572561 String str = value.toString().trim();
573562 if (str.length() > 0) {
574563 return Double.valueOf(str);
575564 } else {
576- return PlainConverter.getDefaultValue(c);
565+ return (c == double.class) ? 0.0 : null;
577566 }
578- } else if (value != null) {
567+ } else if (value instanceof Boolean) {
568+ return (((Boolean)value).booleanValue()) ? 1.0 : Double.NaN;
569+ } else if (value instanceof Number) {
570+ return ((Number)value).doubleValue();
571+ } else {
579572 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
580573 }
581- return PlainConverter.getDefaultValue(c);
582574 }
583575 }
584576
@@ -591,7 +583,9 @@
591583 }
592584
593585 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
594- if (value instanceof Map<?, ?>) {
586+ if (value == null) {
587+ return null;
588+ } else if (value instanceof Map<?, ?>) {
595589 value = ((Map<?,?>)value).get(null);
596590 } else if (value instanceof List<?>) {
597591 List<?> src = (List<?>)value;
@@ -598,20 +592,16 @@
598592 value = (!src.isEmpty()) ? src.get(0) : null;
599593 }
600594
601- if (value instanceof String) {
602- NumberFormat f = context.getNumberFormat();
603- if (f != null) value = f.parse((String)value);
604- }
605-
606- if (value instanceof Boolean) {
607- return (((Boolean)value).booleanValue()) ? BigInteger.ONE : BigInteger.ZERO;
595+ if (value == null) {
596+ return null;
608597 } else if (value instanceof BigDecimal) {
609598 return ((BigDecimal)value).toBigIntegerExact();
610599 } else if (value instanceof BigInteger) {
611600 return value;
612- } else if (value instanceof Number) {
613- return BigInteger.valueOf(((Number)value).longValue());
614601 } else if (value instanceof String) {
602+ NumberFormat f = context.getNumberFormat();
603+ if (f != null) value = f.parse((String)value);
604+
615605 String str = value.toString().trim();
616606 if (str.length() > 0) {
617607 int start = 0;
@@ -626,10 +616,13 @@
626616 }
627617 }
628618 return null;
629- } else if (value != null) {
619+ } else if (value instanceof Boolean) {
620+ return (((Boolean)value).booleanValue()) ? BigInteger.ONE : BigInteger.ZERO;
621+ } else if (value instanceof Number) {
622+ return BigInteger.valueOf(((Number)value).longValue());
623+ } else {
630624 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
631625 }
632- return null;
633626 }
634627 }
635628
@@ -649,7 +642,9 @@
649642 value = (!src.isEmpty()) ? src.get(0) : null;
650643 }
651644
652- if (value instanceof BigDecimal) {
645+ if (value == null) {
646+ return null;
647+ } else if (value instanceof BigDecimal) {
653648 return value;
654649 } else if (value instanceof String) {
655650 NumberFormat f = context.getNumberFormat();
@@ -664,10 +659,9 @@
664659 }
665660 }
666661 return null;
667- } else if (value != null) {
662+ } else {
668663 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
669664 }
670- return null;
671665 }
672666 }
673667
@@ -680,7 +674,9 @@
680674 }
681675
682676 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
683- if (value instanceof Map<?, ?>) {
677+ if (value == null) {
678+ return null;
679+ } else if (value instanceof Map<?, ?>) {
684680 value = ((Map<?,?>)value).get(null);
685681 } else if (value instanceof List<?>) {
686682 List<?> src = (List<?>)value;
@@ -687,12 +683,13 @@
687683 value = (!src.isEmpty()) ? src.get(0) : null;
688684 }
689685
690- if (value instanceof String) {
686+ if (value == null) {
687+ return null;
688+ } else if (value instanceof String) {
691689 return Pattern.compile(value.toString());
692- } else if (value != null) {
690+ } else {
693691 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
694692 }
695- return null;
696693 }
697694 }
698695
@@ -705,7 +702,9 @@
705702 }
706703
707704 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
708- if (value instanceof Map<?, ?>) {
705+ if (value == null) {
706+ return null;
707+ } else if (value instanceof Map<?, ?>) {
709708 value = ((Map<?,?>)value).get(null);
710709 } else if (value instanceof List<?>) {
711710 List<?> src = (List<?>)value;
@@ -712,12 +711,13 @@
712711 value = (!src.isEmpty()) ? src.get(0) : null;
713712 }
714713
715- if (value instanceof String) {
714+ if (value == null) {
715+ return null;
716+ } else if (value instanceof String) {
716717 return TimeZone.getTimeZone(value.toString().trim());
717- } else if (value != null) {
718+ } else {
718719 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
719720 }
720- return null;
721721 }
722722 }
723723
@@ -730,7 +730,9 @@
730730 }
731731
732732 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
733- if (value instanceof List<?>) {
733+ if (value == null) {
734+ return null;
735+ } else if (value instanceof List<?>) {
734736 List<?> src = (List<?>)value;
735737 if (src.size() == 1) {
736738 return new Locale(src.get(0).toString());
@@ -758,11 +760,10 @@
758760 } else {
759761 return null;
760762 }
761- } else if (value != null) {
763+ } else {
762764 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
763765 }
764766 }
765- return null;
766767 }
767768 }
768769
@@ -775,18 +776,22 @@
775776 }
776777
777778 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
778- if (value instanceof Map<?, ?>) {
779+ if (value == null) {
780+ return null;
781+ } else if (value instanceof Map<?, ?>) {
779782 value = ((Map<?,?>)value).get(null);
780783 } else if (value instanceof List<?>) {
781784 List<?> src = (List<?>)value;
782785 value = (!src.isEmpty()) ? src.get(0) : null;
783786 }
784- if (value instanceof String) {
787+
788+ if (value == null) {
789+ return null;
790+ } else if (value instanceof String) {
785791 return new File(value.toString().trim());
786- } else if (value != null) {
792+ } else {
787793 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
788794 }
789- return null;
790795 }
791796 }
792797
@@ -799,13 +804,18 @@
799804 }
800805
801806 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
802- if (value instanceof Map<?, ?>) {
807+ if (value == null) {
808+ return null;
809+ } else if (value instanceof Map<?, ?>) {
803810 value = ((Map<?,?>)value).get(null);
804811 } else if (value instanceof List<?>) {
805812 List<?> src = (List<?>)value;
806813 value = (!src.isEmpty()) ? src.get(0) : null;
807814 }
808- if (value instanceof String) {
815+
816+ if (value == null) {
817+ return null;
818+ } else if (value instanceof String) {
809819 if (value instanceof File) {
810820 return ((File)value).toURI().toURL();
811821 } else if (value instanceof URI) {
@@ -813,10 +823,9 @@
813823 } else {
814824 return new URL(value.toString().trim());
815825 }
816- } else if (value != null) {
826+ } else {
817827 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
818828 }
819- return null;
820829 }
821830 }
822831
@@ -829,13 +838,18 @@
829838 }
830839
831840 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
832- if (value instanceof Map<?, ?>) {
841+ if (value == null) {
842+ return null;
843+ } else if (value instanceof Map<?, ?>) {
833844 value = ((Map<?,?>)value).get(null);
834845 } else if (value instanceof List<?>) {
835846 List<?> src = (List<?>)value;
836847 value = (!src.isEmpty()) ? src.get(0) : null;
837848 }
838- if (value instanceof String) {
849+
850+ if (value == null) {
851+ return null;
852+ } else if (value instanceof String) {
839853 if (value instanceof File) {
840854 return ((File)value).toURI();
841855 } else if (value instanceof URL) {
@@ -843,10 +857,9 @@
843857 } else {
844858 return new URI(value.toString().trim());
845859 }
846- } else if (value != null) {
860+ } else {
847861 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
848862 }
849- return null;
850863 }
851864 }
852865
@@ -859,18 +872,22 @@
859872 }
860873
861874 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
862- if (value instanceof Map<?, ?>) {
875+ if (value == null) {
876+ return null;
877+ } else if (value instanceof Map<?, ?>) {
863878 value = ((Map<?,?>)value).get(null);
864879 } else if (value instanceof List<?>) {
865880 List<?> src = (List<?>)value;
866881 value = (!src.isEmpty()) ? src.get(0) : null;
867882 }
868- if (value instanceof String) {
883+
884+ if (value == null) {
885+ return null;
886+ } else if (value instanceof String) {
869887 return UUID.fromString(value.toString().trim());
870- } else if (value != null) {
888+ } else {
871889 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
872890 }
873- return null;
874891 }
875892 }
876893
@@ -883,18 +900,22 @@
883900 }
884901
885902 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
886- if (value instanceof Map<?, ?>) {
903+ if (value == null) {
904+ return null;
905+ } else if (value instanceof Map<?, ?>) {
887906 value = ((Map<?,?>)value).get(null);
888907 } else if (value instanceof List<?>) {
889908 List<?> src = (List<?>)value;
890909 value = (!src.isEmpty()) ? src.get(0) : null;
891910 }
892- if (value instanceof String) {
911+
912+ if (value == null) {
913+ return null;
914+ } else if (value instanceof String) {
893915 return Charset.forName(value.toString().trim());
894- } else if (value != null) {
916+ } else {
895917 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
896918 }
897- return null;
898919 }
899920 }
900921
@@ -907,13 +928,18 @@
907928 }
908929
909930 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
910- if (value instanceof Map<?, ?>) {
931+ if (value == null) {
932+ return null;
933+ } else if (value instanceof Map<?, ?>) {
911934 value = ((Map<?,?>)value).get(null);
912935 } else if (value instanceof List<?>) {
913936 List<?> src = (List<?>)value;
914937 value = (!src.isEmpty()) ? src.get(0) : null;
915938 }
916- if (value instanceof String) {
939+
940+ if (value == null) {
941+ return null;
942+ } else if (value instanceof String) {
917943 String s = value.toString().trim();
918944 if (s.equals("boolean")) {
919945 return boolean.class;
@@ -937,10 +963,9 @@
937963 return null;
938964 }
939965 }
940- } else if (value != null) {
966+ } else {
941967 throw new UnsupportedOperationException("Cannot convert " + value.getClass() + " to " + t);
942968 }
943- return null;
944969 }
945970 }
946971
@@ -953,16 +978,20 @@
953978 }
954979
955980 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
956- if (value instanceof Map<?, ?>) {
981+ if (value == null) {
982+ return null;
983+ } else if (value instanceof Map<?, ?>) {
957984 value = ((Map<?,?>)value).get(null);
958985 } else if (value instanceof List<?>) {
959986 List<?> src = (List<?>)value;
960987 value = (!src.isEmpty()) ? src.get(0) : null;
961988 }
962- if (value != null) {
989+
990+ if (value == null) {
991+ return null;
992+ } else {
963993 return value.toString();
964994 }
965- return null;
966995 }
967996 }
968997
@@ -975,7 +1004,9 @@
9751004 }
9761005
9771006 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
978- if (value instanceof Map<?, ?>) {
1007+ if (value == null) {
1008+ return null;
1009+ } else if (value instanceof Map<?, ?>) {
9791010 value = ((Map<?,?>)value).get(null);
9801011 } else if (value instanceof List<?>) {
9811012 List<?> src = (List<?>)value;
@@ -982,11 +1013,12 @@
9821013 value = (!src.isEmpty()) ? src.get(0) : null;
9831014 }
9841015
985- if (value != null) {
1016+ if (value == null) {
1017+ return null;
1018+ } else {
9861019 Appendable a = (Appendable)context.createInternal(c);
9871020 return a.append(value.toString());
9881021 }
989- return null;
9901022 }
9911023 }
9921024
@@ -1000,7 +1032,9 @@
10001032
10011033 @SuppressWarnings({ "rawtypes" })
10021034 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1003- if (value instanceof Map<?, ?>) {
1035+ if (value == null) {
1036+ return null;
1037+ } else if (value instanceof Map<?, ?>) {
10041038 value = ((Map<?,?>)value).get(null);
10051039 } else if (value instanceof List<?>) {
10061040 List<?> src = (List<?>)value;
@@ -1007,12 +1041,16 @@
10071041 value = (!src.isEmpty()) ? src.get(0) : null;
10081042 }
10091043
1044+ if (value == null) {
1045+ return null;
1046+ }
1047+
10101048 Enum[] enums = (Enum[])c.getEnumConstants();
10111049 if (value instanceof Number) {
10121050 return enums[((Number)value).intValue()];
10131051 } else if (value instanceof Boolean) {
10141052 return enums[((Boolean)value) ? 1 : 0];
1015- } else if (value != null) {
1053+ } else {
10161054 String str = value.toString().trim();
10171055 if (str.length() == 0) {
10181056 return null;
@@ -1030,7 +1068,6 @@
10301068 throw new IllegalArgumentException(str + " is not " + c);
10311069 }
10321070 }
1033- return null;
10341071 }
10351072 }
10361073
@@ -1044,7 +1081,9 @@
10441081 }
10451082
10461083 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1047- if (value instanceof Map<?, ?>) {
1084+ if (value == null) {
1085+ return null;
1086+ } else if (value instanceof Map<?, ?>) {
10481087 value = ((Map<?,?>)value).get(null);
10491088 } else if (value instanceof List<?>) {
10501089 List<?> src = (List<?>)value;
@@ -1051,6 +1090,10 @@
10511090 value = (!src.isEmpty()) ? src.get(0) : null;
10521091 }
10531092
1093+ if (value == null) {
1094+ return null;
1095+ }
1096+
10541097 Date date = null;
10551098 if (value instanceof Number) {
10561099 date = (Date)context.createInternal(c);
@@ -1187,7 +1230,9 @@
11871230 }
11881231
11891232 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1190- if (value instanceof Map<?, ?>) {
1233+ if (value == null) {
1234+ return null;
1235+ } else if (value instanceof Map<?, ?>) {
11911236 value = ((Map<?,?>)value).get(null);
11921237 } else if (value instanceof List<?>) {
11931238 List<?> src = (List<?>)value;
@@ -1194,11 +1239,13 @@
11941239 value = (!src.isEmpty()) ? src.get(0) : null;
11951240 }
11961241
1197- if (value instanceof Number) {
1242+ if (value == null) {
1243+ return null;
1244+ } else if (value instanceof Number) {
11981245 Calendar cal = (Calendar)context.createInternal(c);
11991246 cal.setTimeInMillis(((Number)value).longValue());
12001247 return cal;
1201- } else if (value != null) {
1248+ } else {
12021249 String str = value.toString().trim();
12031250 if (str.length() > 0) {
12041251 Calendar cal = (Calendar)context.createInternal(c);
@@ -1210,9 +1257,10 @@
12101257 cal.setTime(DateConverter.convertDate(context, str));
12111258 }
12121259 return cal;
1260+ } else {
1261+ return null;
12131262 }
12141263 }
1215- return null;
12161264 }
12171265 }
12181266
@@ -1227,7 +1275,9 @@
12271275
12281276 @Override
12291277 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1230- if (value instanceof Map<?, ?>) {
1278+ if (value == null) {
1279+ return null;
1280+ } else if (value instanceof Map<?, ?>) {
12311281 value = ((Map<?,?>)value).get(null);
12321282 } else if (value instanceof List<?>) {
12331283 List<?> src = (List<?>)value;
@@ -1234,10 +1284,11 @@
12341284 value = (!src.isEmpty()) ? src.get(0) : null;
12351285 }
12361286
1237- if (value != null) {
1287+ if (value == null) {
1288+ return null;
1289+ } else {
12381290 return InetAddress.getByName(value.toString().trim());
12391291 }
1240- return null;
12411292 }
12421293 }
12431294
@@ -1250,7 +1301,9 @@
12501301 }
12511302
12521303 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1253- if (value instanceof Map<?, ?>) {
1304+ if (value == null) {
1305+ return null;
1306+ } else if (value instanceof Map<?, ?>) {
12541307 Map<?, ?> src = (Map<?, ?>)value;
12551308 if (!(src instanceof SortedMap<?, ?>)) {
12561309 src = new TreeMap<Object, Object>(src);
@@ -1258,7 +1311,9 @@
12581311 value = src.values();
12591312 }
12601313
1261- if (value instanceof Collection) {
1314+ if (value == null) {
1315+ return null;
1316+ } else if (value instanceof Collection) {
12621317 Collection<?> src = (Collection<?>)value;
12631318 Object array = Array.newInstance(c.getComponentType(), src.size());
12641319 Class<?> pc = c.getComponentType();
@@ -1304,11 +1359,16 @@
13041359
13051360 @SuppressWarnings("unchecked")
13061361 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1362+ if (value == null) {
1363+ return null;
1364+ }
1365+
13071366 Type pt = context.getParameterType(t, Collection.class, 0);
13081367 Class<?> pc = ClassUtil.getRawType(pt);
13091368 JSONHint hint = context.getHint();
13101369
13111370 Collection<Object> collection = null;
1371+
13121372 if (value instanceof List) {
13131373 List<?> src = (List<?>)value;
13141374
@@ -1389,10 +1449,14 @@
13891449 }
13901450
13911451 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1452+ if (value == null) {
1453+ return null;
1454+ }
1455+
13921456 Properties prop = (Properties)context.createInternal(c);
13931457 if (value instanceof Map<?, ?> || value instanceof List<?>) {
13941458 flattenProperties(context.getLocalCache().getCachedBuffer(), value, prop);
1395- } else if (value != null) {
1459+ } else {
13961460 prop.setProperty(value.toString(), null);
13971461 }
13981462 return prop;
@@ -1432,6 +1496,10 @@
14321496
14331497 @SuppressWarnings("unchecked")
14341498 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1499+ if (value == null) {
1500+ return null;
1501+ }
1502+
14351503 Type pt0 = context.getParameterType(t, Map.class, 0);
14361504 Type pt1 = context.getParameterType(t, Map.class, 1);
14371505 Class<?> pc0 = ClassUtil.getRawType(pt0);
@@ -1509,6 +1577,10 @@
15091577 }
15101578
15111579 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1580+ if (value == null) {
1581+ return null;
1582+ }
1583+
15121584 if (props == null) props = getSetProperties(context, cls);
15131585
15141586 if (value instanceof Map<?, ?>) {
@@ -1674,7 +1746,9 @@
16741746 }
16751747
16761748 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1677- if (value instanceof Map<?, ?>) {
1749+ if (value == null) {
1750+ return null;
1751+ } else if (value instanceof Map<?, ?>) {
16781752 value = ((Map<?,?>)value).get(null);
16791753 } else if (value instanceof List<?>) {
16801754 List<?> src = (List<?>)value;
@@ -1702,7 +1776,9 @@
17021776
17031777 @Override
17041778 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1705- if (value instanceof Map<?, ?>) {
1779+ if (value == null) {
1780+ return null;
1781+ } else if (value instanceof Map<?, ?>) {
17061782 value = ((Map<?,?>)value).get(null);
17071783 } else if (value instanceof List<?>) {
17081784 List<?> src = (List<?>)value;
@@ -1732,7 +1808,9 @@
17321808
17331809 @Override
17341810 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1735- if (value instanceof Map<?, ?>) {
1811+ if (value == null) {
1812+ return null;
1813+ } else if (value instanceof Map<?, ?>) {
17361814 value = ((Map<?,?>)value).get(null);
17371815 } else if (value instanceof List<?>) {
17381816 List<?> src = (List<?>)value;
@@ -1766,7 +1844,9 @@
17661844
17671845 @Override
17681846 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1769- if (value instanceof Map<?, ?>) {
1847+ if (value == null) {
1848+ return null;
1849+ } else if (value instanceof Map<?, ?>) {
17701850 value = ((Map<?,?>)value).get(null);
17711851 } else if (value instanceof List<?>) {
17721852 List<?> src = (List<?>)value;
@@ -1800,7 +1880,9 @@
18001880
18011881 @Override
18021882 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1803- if (value instanceof Map<?, ?>) {
1883+ if (value == null) {
1884+ return null;
1885+ } else if (value instanceof Map<?, ?>) {
18041886 value = ((Map<?,?>)value).get(null);
18051887 } else if (value instanceof List<?>) {
18061888 List<?> src = (List<?>)value;
@@ -1834,7 +1916,9 @@
18341916
18351917 @Override
18361918 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1837- if (value instanceof Map<?, ?>) {
1919+ if (value == null) {
1920+ return null;
1921+ } else if (value instanceof Map<?, ?>) {
18381922 value = ((Map<?,?>)value).get(null);
18391923 } else if (value instanceof List<?>) {
18401924 List<?> src = (List<?>)value;
@@ -1868,7 +1952,9 @@
18681952
18691953 @Override
18701954 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1871- if (value instanceof Map<?, ?>) {
1955+ if (value == null) {
1956+ return null;
1957+ } else if (value instanceof Map<?, ?>) {
18721958 value = ((Map<?,?>)value).get(null);
18731959 } else if (value instanceof List<?>) {
18741960 List<?> src = (List<?>)value;
@@ -1902,7 +1988,9 @@
19021988
19031989 @Override
19041990 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1905- if (value instanceof Map<?, ?>) {
1991+ if (value == null) {
1992+ return null;
1993+ } else if (value instanceof Map<?, ?>) {
19061994 value = ((Map<?,?>)value).get(null);
19071995 } else if (value instanceof List<?>) {
19081996 List<?> src = (List<?>)value;
@@ -1936,7 +2024,9 @@
19362024
19372025 @Override
19382026 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1939- if (value instanceof Map<?, ?>) {
2027+ if (value == null) {
2028+ return null;
2029+ } else if (value instanceof Map<?, ?>) {
19402030 value = ((Map<?,?>)value).get(null);
19412031 } else if (value instanceof List<?>) {
19422032 List<?> src = (List<?>)value;
@@ -1964,7 +2054,9 @@
19642054
19652055 @Override
19662056 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
1967- if (value instanceof Map<?, ?>) {
2057+ if (value == null) {
2058+ return null;
2059+ } else if (value instanceof Map<?, ?>) {
19682060 value = ((Map<?,?>)value).get(null);
19692061 } else if (value instanceof List<?>) {
19702062 List<?> src = (List<?>)value;
@@ -2000,7 +2092,9 @@
20002092
20012093 @Override
20022094 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2003- if (value instanceof Map<?, ?>) {
2095+ if (value == null) {
2096+ return null;
2097+ } else if (value instanceof Map<?, ?>) {
20042098 value = ((Map<?,?>)value).get(null);
20052099 } else if (value instanceof List<?>) {
20062100 List<?> src = (List<?>)value;
@@ -2034,7 +2128,9 @@
20342128
20352129 @Override
20362130 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2037- if (value instanceof Map<?, ?>) {
2131+ if (value == null) {
2132+ return null;
2133+ } else if (value instanceof Map<?, ?>) {
20382134 value = ((Map<?,?>)value).get(null);
20392135 } else if (value instanceof List<?>) {
20402136 List<?> src = (List<?>)value;
@@ -2068,7 +2164,9 @@
20682164
20692165 @Override
20702166 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2071- if (value instanceof Map<?, ?>) {
2167+ if (value == null) {
2168+ return null;
2169+ } else if (value instanceof Map<?, ?>) {
20722170 value = ((Map<?,?>)value).get(null);
20732171 } else if (value instanceof List<?>) {
20742172 List<?> src = (List<?>)value;
@@ -2096,7 +2194,9 @@
20962194
20972195 @Override
20982196 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2099- if (value instanceof Map<?, ?>) {
2197+ if (value == null) {
2198+ return null;
2199+ } else if (value instanceof Map<?, ?>) {
21002200 value = ((Map<?,?>)value).get(null);
21012201 } else if (value instanceof List<?>) {
21022202 List<?> src = (List<?>)value;
@@ -2124,7 +2224,9 @@
21242224
21252225 @Override
21262226 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2127- if (value instanceof Map<?, ?>) {
2227+ if (value == null) {
2228+ return null;
2229+ } else if (value instanceof Map<?, ?>) {
21282230 value = ((Map<?,?>)value).get(null);
21292231 } else if (value instanceof List<?>) {
21302232 List<?> src = (List<?>)value;
@@ -2154,7 +2256,9 @@
21542256
21552257 @Override
21562258 public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2157- if (value instanceof Map<?, ?>) {
2259+ if (value == null) {
2260+ return null;
2261+ } else if (value instanceof Map<?, ?>) {
21582262 value = ((Map<?,?>)value).get(null);
21592263 } else if (value instanceof List<?>) {
21602264 List<?> src = (List<?>)value;
@@ -2172,3 +2276,96 @@
21722276 }
21732277 }
21742278 }
2279+
2280+final class OptionalIntConverter implements Converter {
2281+ public OptionalIntConverter() {
2282+ }
2283+
2284+ @Override
2285+ public boolean accept(Class<?> cls) {
2286+ return OptionalInt.class.equals(cls);
2287+ }
2288+
2289+ public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2290+ if (value == null) {
2291+ return OptionalInt.empty();
2292+ }
2293+
2294+ value = IntegerConverter.INSTANCE.convert(context, value, c, t);
2295+ if (value instanceof Integer) {
2296+ return OptionalInt.of((Integer)value);
2297+ } else {
2298+ return OptionalInt.empty();
2299+ }
2300+ }
2301+}
2302+
2303+final class OptionalLongConverter implements Converter {
2304+ public OptionalLongConverter() {
2305+ }
2306+
2307+ @Override
2308+ public boolean accept(Class<?> cls) {
2309+ return OptionalLong.class.equals(cls);
2310+ }
2311+
2312+ public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2313+ if (value == null) {
2314+ return OptionalLong.empty();
2315+ }
2316+
2317+ value = LongConverter.INSTANCE.convert(context, value, c, t);
2318+ if (value instanceof Long) {
2319+ return OptionalLong.of((Long)value);
2320+ } else {
2321+ return OptionalLong.empty();
2322+ }
2323+ }
2324+}
2325+
2326+final class OptionalDoubleConverter implements Converter {
2327+ public OptionalDoubleConverter() {
2328+ }
2329+
2330+ @Override
2331+ public boolean accept(Class<?> cls) {
2332+ return OptionalDouble.class.equals(cls);
2333+ }
2334+
2335+ public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2336+ if (value == null) {
2337+ return OptionalDouble.empty();
2338+ }
2339+
2340+ value = DoubleConverter.INSTANCE.convert(context, value, c, t);
2341+ if (value instanceof Double) {
2342+ return OptionalDouble.of((Double)value);
2343+ } else {
2344+ return OptionalDouble.empty();
2345+ }
2346+ }
2347+}
2348+
2349+final class OptionalConverter implements Converter {
2350+ public OptionalConverter() {
2351+ }
2352+
2353+ @Override
2354+ public boolean accept(Class<?> cls) {
2355+ return Optional.class.isAssignableFrom(cls);
2356+ }
2357+
2358+ public Object convert(Context context, Object value, Class<?> c, Type t) throws Exception {
2359+ if (value == null) {
2360+ return Optional.empty();
2361+ }
2362+
2363+ t = ClassUtil.getParameterType(t, c, 0);
2364+ value = context.convertInternal(value, ClassUtil.getRawType(t), t);
2365+ if (value != null) {
2366+ return Optional.of(value);
2367+ } else {
2368+ return Optional.empty();
2369+ }
2370+ }
2371+}
\ No newline at end of file
--- trunk/jsonic-1.3/src/net/arnx/jsonic/JSON.java (revision 1851)
+++ trunk/jsonic-1.3/src/net/arnx/jsonic/JSON.java (revision 1852)
@@ -181,10 +181,11 @@
181181 static final Character ROOT = '$';
182182
183183 private static final String PACKAGE_NAME = JSON.class.getName().substring(0, JSON.class.getName().lastIndexOf('.'));
184+ private static final Map<Class<?>, Class<?>> PRIMITIVE_MAP = new HashMap<Class<?>, Class<?>>(10);
184185 private static final Map<Class<?>, Formatter> FORMAT_MAP = new HashMap<Class<?>, Formatter>(50);
185- private static final List<Formatter> FORMAT_LIST = new ArrayList<Formatter>(20);
186+ private static final List<Formatter> FORMAT_LIST = new ArrayList<Formatter>(24);
186187 private static final Map<Class<?>, Converter> CONVERT_MAP = new HashMap<Class<?>, Converter>(50);
187- private static final List<Converter> CONVERT_LIST = new ArrayList<Converter>(20);
188+ private static final List<Converter> CONVERT_LIST = new ArrayList<Converter>(24);
188189
189190 static {
190191 ClassLoader cl = JSON.class.getClassLoader();
@@ -202,6 +203,15 @@
202203 // no handle
203204 }
204205
206+ PRIMITIVE_MAP.put(boolean.class, Boolean.class);
207+ PRIMITIVE_MAP.put(byte.class, Byte.class);
208+ PRIMITIVE_MAP.put(short.class, Short.class);
209+ PRIMITIVE_MAP.put(int.class, Integer.class);
210+ PRIMITIVE_MAP.put(long.class, Long.class);
211+ PRIMITIVE_MAP.put(float.class, Float.class);
212+ PRIMITIVE_MAP.put(double.class, Double.class);
213+ PRIMITIVE_MAP.put(char.class, Character.class);
214+
205215 Formatter formatter = null;
206216 FORMAT_MAP.put(boolean.class, PlainFormatter.INSTANCE);
207217 FORMAT_MAP.put(char.class, StringFormatter.INSTANCE);
@@ -292,9 +302,21 @@
292302 formatter = getFormatterInstance(PACKAGE_NAME + ".DynaBeanFormatter", cl);
293303 if (formatter != null) FORMAT_LIST.add(formatter);
294304
295- formatter = getFormatterInstance(PACKAGE_NAME + ".TemporalFromatter", cl);
305+ formatter = getFormatterInstance(PACKAGE_NAME + ".OptionalIntFormatter", cl);
296306 if (formatter != null) FORMAT_LIST.add(formatter);
297307
308+ formatter = getFormatterInstance(PACKAGE_NAME + ".OptionalLongFormatter", cl);
309+ if (formatter != null) FORMAT_LIST.add(formatter);
310+
311+ formatter = getFormatterInstance(PACKAGE_NAME + ".OptionalDoubleFormatter", cl);
312+ if (formatter != null) FORMAT_LIST.add(formatter);
313+
314+ formatter = getFormatterInstance(PACKAGE_NAME + ".OptionalFormatter", cl);
315+ if (formatter != null) FORMAT_LIST.add(formatter);
316+
317+ formatter = getFormatterInstance(PACKAGE_NAME + ".TemporalFormatter", cl);
318+ if (formatter != null) FORMAT_LIST.add(formatter);
319+
298320 Converter converter = null;
299321 CONVERT_MAP.put(boolean.class, BooleanConverter.INSTANCE);
300322 CONVERT_MAP.put(char.class, CharacterConverter.INSTANCE);
@@ -385,6 +407,18 @@
385407 converter = getConverterInstance(PACKAGE_NAME + ".NullableConverter", cl);
386408 if (converter != null) CONVERT_LIST.add(converter);
387409
410+ converter = getConverterInstance(PACKAGE_NAME + ".OptionalIntConverter", cl);
411+ if (converter != null) CONVERT_LIST.add(converter);
412+
413+ converter = getConverterInstance(PACKAGE_NAME + ".OptionalLongConverter", cl);
414+ if (converter != null) CONVERT_LIST.add(converter);
415+
416+ converter = getConverterInstance(PACKAGE_NAME + ".OptionalDoubleConverter", cl);
417+ if (converter != null) CONVERT_LIST.add(converter);
418+
419+ converter = getConverterInstance(PACKAGE_NAME + ".OptionalConverter", cl);
420+ if (converter != null) CONVERT_LIST.add(converter);
421+
388422 converter = getConverterInstance(PACKAGE_NAME + ".DurationConverter", cl);
389423 if (converter != null) CONVERT_LIST.add(converter);
390424
@@ -1090,12 +1124,16 @@
10901124 is = new CharSequenceInputSource(cs);
10911125 }
10921126
1127+ if (type instanceof TypeReference<?>) {
1128+ type = ((TypeReference<?>)type).getType();
1129+ }
1130+
10931131 T value = null;
10941132 try {
10951133 Context context = new Context();
10961134 JSONReader jreader = new JSONReader(context, is, false, true);
10971135 Object result = (jreader.next() != null) ? jreader.getValue() : null;
1098- value = (T)context.convertInternal(result, type);
1136+ value = (T)context.convertInternal(result, ClassUtil.getRawType(type), type);
10991137 } catch (IOException e) {
11001138 // never occur
11011139 }
@@ -1115,10 +1153,14 @@
11151153
11161154 @SuppressWarnings("unchecked")
11171155 public <T> T parse(InputStream in, Type type) throws IOException, JSONException {
1156+ if (type instanceof TypeReference<?>) {
1157+ type = ((TypeReference<?>)type).getType();
1158+ }
1159+
11181160 Context context = new Context();
11191161 JSONReader jreader = new JSONReader(context, new ReaderInputSource(in), false, true);
11201162 Object result = (jreader.next() != null) ? jreader.getValue() : null;
1121- return (T)context.convertInternal(result, type);
1163+ return (T)context.convertInternal(result, ClassUtil.getRawType(type), type);
11221164 }
11231165
11241166 @SuppressWarnings("unchecked")
@@ -1134,10 +1176,14 @@
11341176
11351177 @SuppressWarnings("unchecked")
11361178 public <T> T parse(Reader reader, Type type) throws IOException, JSONException {
1179+ if (type instanceof TypeReference<?>) {
1180+ type = ((TypeReference<?>)type).getType();
1181+ }
1182+
11371183 Context context = new Context();
11381184 JSONReader jreader = new JSONReader(context, new ReaderInputSource(reader), false, true);
11391185 Object result = (jreader.next() != null) ? jreader.getValue() : null;
1140- return (T)context.convertInternal(result, type);
1186+ return (T)context.convertInternal(result, ClassUtil.getRawType(type), type);
11411187 }
11421188
11431189 public JSONReader getReader(CharSequence cs) {
@@ -1175,7 +1221,11 @@
11751221 }
11761222
11771223 public Object convert(Object value, Type type) throws JSONException {
1178- return (new Context()).convertInternal(value, type);
1224+ if (type instanceof TypeReference<?>) {
1225+ type = ((TypeReference<?>)type).getType();
1226+ }
1227+
1228+ return (new Context()).convertInternal(value, ClassUtil.getRawType(type), type);
11791229 }
11801230
11811231 /**
@@ -1192,11 +1242,7 @@
11921242 protected <T> T postparse(Context context, Object value, Class<? extends T> cls, Type type) throws Exception {
11931243 Converter c = null;
11941244
1195- if (value == null) {
1196- if (!cls.isPrimitive()) {
1197- c = NullConverter.INSTANCE;
1198- }
1199- } else {
1245+ if (value != null) {
12001246 JSONHint hint = context.getHint();
12011247 if (hint == null) {
12021248 // no handle
@@ -1503,7 +1549,7 @@
15031549 enter(key, getHint());
15041550 T o = JSON.this.postparse(this, value, c, c);
15051551 exit();
1506- return (T)((c.isPrimitive()) ? PlainConverter.getDefaultValue(c).getClass() : c).cast(o);
1552+ return (T)((c.isPrimitive()) ? PRIMITIVE_MAP.get(c) : c).cast(o);
15071553 }
15081554
15091555 public Object convert(Object key, Object value, Type t) throws Exception {
@@ -1511,7 +1557,7 @@
15111557 enter(key, getHint());
15121558 Object o = JSON.this.postparse(this, value, c, t);
15131559 exit();
1514- return ((c.isPrimitive()) ? PlainConverter.getDefaultValue(c).getClass() : c).cast(o);
1560+ return ((c.isPrimitive()) ? PRIMITIVE_MAP.get(c) : c).cast(o);
15151561 }
15161562
15171563 void enter(Object key, JSONHint hint) {
@@ -1690,13 +1736,7 @@
16901736 }
16911737
16921738 @SuppressWarnings("unchecked")
1693- <T> T convertInternal(Object value, Type type) throws JSONException {
1694- if (type instanceof TypeReference<?>) {
1695- type = ((TypeReference<?>)type).getType();
1696- }
1697-
1698- Class<?> cls = ClassUtil.getRawType(type);
1699-
1739+ <T> T convertInternal(Object value, Class<?> cls, Type type) throws JSONException {
17001740 T result = null;
17011741 try {
17021742 enter(ROOT, null);
--- trunk/jsonic-1.3/docs/index.html (revision 1851)
+++ trunk/jsonic-1.3/docs/index.html (revision 1852)
@@ -182,6 +182,7 @@
182182 <tr><td>Date, Calendar</td><td>number (1970年からのミリ秒)</td></tr>
183183 <tr><td>Enum</td><td>string (デフォルトは名前で文字列化。<code>setEnumStyle</code> にて動作の変更が可能)<br />
184184 number (<code>setEnumStyle</code> に null を指定すると Enum.ordinal により変換)</td></tr>
185+<tr><td>Optional型</td><td>isPresent() が false を返す時 null、その他の時、保持値</td></tr>
185186 <tr><td>boolean, Boolean</td><td>true/false</td></tr>
186187 <tr><td>null</td><td>null</td></tr>
187188 </table>
@@ -258,6 +259,7 @@
258259 <tr><td>byte, short, int, long,<br />Byte, Short, Integer, Long,<br />BigInteger</td><td>指定された型(trueの時1、falseの時0)</td></tr>
259260 <tr><td>boolean</td><td>boolean</td></tr>
260261 <tr><td>Enum派生型</td><td>指定された型(trueを1、falseを0とみなしEnum.ordinal()に従い変換)</td></tr>
262+<tr><td>Optional型</td><td>保持値(nullの場合 empty()の値が設定されます)</td></tr>
261263 <tr><td rowspan="4">null</td><td>なし, Object</td><td>null</td></tr>
262264 <tr><td>byte, short, int, long, float, double</td><td>0</td></tr>
263265 <tr><td>boolean</td><td>false</td></tr>
@@ -865,6 +867,11 @@
865867
866868 <h2 id="releasenote">リリースノート</h2>
867869
870+<h3>2015/5/4 version 1.3.8</h3>
871+<ul>
872+<li>[機能追加] Java8 の Optional 型(OptionalInt、OptionalLong、OptionalDouble、Optional)に対応しました。</li>
873+</ul>
874+
868875 <h3>2014/12/23 version 1.3.7</h3>
869876 <ul>
870877 <li>[不具合修正] JSONHint に type を指定しても、type のプロパティに値が設定されない問題を修正しました。</li>
--- trunk/jsonic-1.3/pom.xml (revision 1851)
+++ trunk/jsonic-1.3/pom.xml (revision 1852)
@@ -7,7 +7,7 @@
77 <artifactId>jsonic</artifactId>
88 <packaging>jar</packaging>
99 <name>jsonic</name>
10- <version>1.3.7</version>
10+ <version>1.3.8</version>
1111 <description>simple json encoder/decoder for java</description>
1212 <url>http://jsonic.sourceforge.jp/</url>
1313 <licenses>
--- trunk/jsonic-1.3/test/net/arnx/jsonic/JSONJava8Test.java (revision 1851)
+++ trunk/jsonic-1.3/test/net/arnx/jsonic/JSONJava8Test.java (revision 1852)
@@ -2,6 +2,7 @@
22
33 import static org.junit.Assert.*;
44
5+import java.math.BigDecimal;
56 import java.time.Duration;
67 import java.time.Instant;
78 import java.time.LocalDate;
@@ -17,6 +18,10 @@
1718 import java.time.ZoneId;
1819 import java.time.ZoneOffset;
1920 import java.time.ZonedDateTime;
21+import java.util.Optional;
22+import java.util.OptionalDouble;
23+import java.util.OptionalInt;
24+import java.util.OptionalLong;
2025
2126 import org.junit.Test;
2227
@@ -24,7 +29,7 @@
2429
2530 @Test
2631 public void testEncode() {
27- Java8Bean bean = new Java8Bean();
32+ Java8DataTimeAPIBean bean = new Java8DataTimeAPIBean();
2833 bean.duration = Duration.ofDays(3L);
2934 bean.instant = Instant.from(ZonedDateTime.of(2010, 3, 3, 2, 2, 2, 2, ZoneOffset.of("Z")));
3035 bean.localDate = LocalDate.of(2010, 3, 3);
@@ -58,11 +63,39 @@
5863 + "\"zonedDateTime\":\"2010-03-03T02:02:02.000000002Z\","
5964 + "\"zonedOffset\":\"Z\""
6065 + "}", JSON.encode(bean));
66+
67+ Java8OptionalBean obean = new Java8OptionalBean();
68+ obean.optionalInt = OptionalInt.of(2);
69+ obean.optionalLong = OptionalLong.of(10000L);
70+ obean.optionalDouble = OptionalDouble.of(100.123D);
71+ obean.optionalBigDecimal = Optional.of(new BigDecimal("3.14"));
72+ obean.optionalBean = Optional.of(new OptionalBeanBean());
73+ assertEquals("{"
74+ + "\"optionalBean\":{\"text\":\"text\"},"
75+ + "\"optionalBigDecimal\":3.14,"
76+ + "\"optionalDouble\":100.123,"
77+ + "\"optionalInt\":2,"
78+ + "\"optionalLong\":10000"
79+ + "}", JSON.encode(obean));
80+
81+ obean = new Java8OptionalBean();
82+ obean.optionalInt = OptionalInt.empty();
83+ obean.optionalLong = OptionalLong.empty();
84+ obean.optionalDouble = OptionalDouble.empty();
85+ obean.optionalBigDecimal = Optional.empty();
86+ obean.optionalBean = Optional.empty();
87+ assertEquals("{"
88+ + "\"optionalBean\":null,"
89+ + "\"optionalBigDecimal\":null,"
90+ + "\"optionalDouble\":null,"
91+ + "\"optionalInt\":null,"
92+ + "\"optionalLong\":null"
93+ + "}", JSON.encode(obean));
6194 }
6295
6396 @Test
6497 public void testDecode() {
65- Java8Bean bean = new Java8Bean();
98+ Java8DataTimeAPIBean bean = new Java8DataTimeAPIBean();
6699 bean.duration = Duration.ofDays(3L);
67100 bean.instant = Instant.from(ZonedDateTime.of(2010, 3, 3, 2, 2, 2, 2, ZoneOffset.of("Z")));
68101 bean.localDate = LocalDate.of(2010, 3, 3);
@@ -95,10 +128,38 @@
95128 + "\"zoneId\":\"UTC\","
96129 + "\"zonedDateTime\":\"2010-03-03T02:02:02.000000002Z\","
97130 + "\"zonedOffset\":\"Z\""
98- + "}", Java8Bean.class));
131+ + "}", Java8DataTimeAPIBean.class));
132+
133+ Java8OptionalBean obean = new Java8OptionalBean();
134+ obean.optionalInt = OptionalInt.of(2);
135+ obean.optionalLong = OptionalLong.of(10000L);
136+ obean.optionalDouble = OptionalDouble.of(100.123D);
137+ obean.optionalBigDecimal = Optional.of(new BigDecimal("3.14"));
138+ obean.optionalBean = Optional.of(new OptionalBeanBean());
139+ assertEquals(obean, JSON.decode("{"
140+ + "\"optionalBean\":{\"text\":\"text\"},"
141+ + "\"optionalBigDecimal\":3.14,"
142+ + "\"optionalDouble\":100.123,"
143+ + "\"optionalInt\":2,"
144+ + "\"optionalLong\":10000"
145+ + "}", Java8OptionalBean.class));
146+
147+ obean = new Java8OptionalBean();
148+ obean.optionalInt = OptionalInt.empty();
149+ obean.optionalLong = OptionalLong.empty();
150+ obean.optionalDouble = OptionalDouble.empty();
151+ obean.optionalBigDecimal = Optional.empty();
152+ obean.optionalBean = Optional.empty();
153+ assertEquals(obean, JSON.decode("{"
154+ + "\"optionalBean\":null,"
155+ + "\"optionalBigDecimal\":null,"
156+ + "\"optionalDouble\":null,"
157+ + "\"optionalInt\":null,"
158+ + "\"optionalLong\":null"
159+ + "}", Java8OptionalBean.class));
99160 }
100161
101- public static class Java8Bean {
162+ public static class Java8DataTimeAPIBean {
102163 public Duration duration;
103164 public Instant instant;
104165 public LocalDate localDate;
@@ -158,7 +219,7 @@
158219 return false;
159220 if (getClass() != obj.getClass())
160221 return false;
161- Java8Bean other = (Java8Bean) obj;
222+ Java8DataTimeAPIBean other = (Java8DataTimeAPIBean) obj;
162223 if (duration == null) {
163224 if (other.duration != null)
164225 return false;
@@ -233,9 +294,10 @@
233294 return false;
234295 return true;
235296 }
297+
236298 @Override
237299 public String toString() {
238- return "Java8Bean [duration=" + duration + ", instant=" + instant
300+ return "Java8DataTimeAPIBean [duration=" + duration + ", instant=" + instant
239301 + ", localDate=" + localDate + ", localDateTime="
240302 + localDateTime + ", localTime=" + localTime
241303 + ", monthDay=" + monthDay + ", offsetDateTimey="
@@ -245,7 +307,110 @@
245307 + zonedDateTime + ", zoneId=" + zoneId
246308 + ", zonedOffset=" + zonedOffset + "]";
247309 }
310+ }
248311
312+ public static class Java8OptionalBean {
313+ public OptionalInt optionalInt;
314+ public OptionalLong optionalLong;
315+ public OptionalDouble optionalDouble;
316+ public Optional<BigDecimal> optionalBigDecimal;
317+ public Optional<OptionalBeanBean> optionalBean;
318+ @Override
319+ public int hashCode() {
320+ final int prime = 31;
321+ int result = 1;
322+ result = prime * result
323+ + ((optionalBean == null) ? 0 : optionalBean.hashCode());
324+ result = prime
325+ * result
326+ + ((optionalBigDecimal == null) ? 0 : optionalBigDecimal
327+ .hashCode());
328+ result = prime
329+ * result
330+ + ((optionalDouble == null) ? 0 : optionalDouble.hashCode());
331+ result = prime * result
332+ + ((optionalInt == null) ? 0 : optionalInt.hashCode());
333+ result = prime * result
334+ + ((optionalLong == null) ? 0 : optionalLong.hashCode());
335+ return result;
336+ }
337+ @Override
338+ public boolean equals(Object obj) {
339+ if (this == obj)
340+ return true;
341+ if (obj == null)
342+ return false;
343+ if (getClass() != obj.getClass())
344+ return false;
345+ Java8OptionalBean other = (Java8OptionalBean) obj;
346+ if (optionalBean == null) {
347+ if (other.optionalBean != null)
348+ return false;
349+ } else if (!optionalBean.equals(other.optionalBean))
350+ return false;
351+ if (optionalBigDecimal == null) {
352+ if (other.optionalBigDecimal != null)
353+ return false;
354+ } else if (!optionalBigDecimal.equals(other.optionalBigDecimal))
355+ return false;
356+ if (optionalDouble == null) {
357+ if (other.optionalDouble != null)
358+ return false;
359+ } else if (!optionalDouble.equals(other.optionalDouble))
360+ return false;
361+ if (optionalInt == null) {
362+ if (other.optionalInt != null)
363+ return false;
364+ } else if (!optionalInt.equals(other.optionalInt))
365+ return false;
366+ if (optionalLong == null) {
367+ if (other.optionalLong != null)
368+ return false;
369+ } else if (!optionalLong.equals(other.optionalLong))
370+ return false;
371+ return true;
372+ }
373+ @Override
374+ public String toString() {
375+ return "Java8OptionalBean [optionalInt=" + optionalInt
376+ + ", optionalLong=" + optionalLong + ", optionalDouble="
377+ + optionalDouble + ", optionalBigDecimal="
378+ + optionalBigDecimal + ", optionalBean=" + optionalBean
379+ + "]";
380+ }
381+ }
249382
383+ public static class OptionalBeanBean {
384+ public String text = "text";
385+
386+ @Override
387+ public int hashCode() {
388+ final int prime = 31;
389+ int result = 1;
390+ result = prime * result + ((text == null) ? 0 : text.hashCode());
391+ return result;
392+ }
393+
394+ @Override
395+ public boolean equals(Object obj) {
396+ if (this == obj)
397+ return true;
398+ if (obj == null)
399+ return false;
400+ if (getClass() != obj.getClass())
401+ return false;
402+ OptionalBeanBean other = (OptionalBeanBean) obj;
403+ if (text == null) {
404+ if (other.text != null)
405+ return false;
406+ } else if (!text.equals(other.text))
407+ return false;
408+ return true;
409+ }
410+
411+ @Override
412+ public String toString() {
413+ return "OptionalBeanBean [text=" + text + "]";
414+ }
250415 }
251416 }
旧リポジトリブラウザで表示