diff --git a/src/org/redkale/convert/CollectionDecoder.java b/src/org/redkale/convert/CollectionDecoder.java index 6231d7f5e..0e432a0b6 100644 --- a/src/org/redkale/convert/CollectionDecoder.java +++ b/src/org/redkale/convert/CollectionDecoder.java @@ -8,7 +8,7 @@ package org.redkale.convert; import org.redkale.util.Creator; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.Collection; +import java.util.*; /** * Collection的反序列化操作类
@@ -60,6 +60,17 @@ public class CollectionDecoder implements Decodeable> { } } + //仅供类似JsonAnyDecoder这种动态创建使用, 不得调用 factory.register + public CollectionDecoder(final ConvertFactory factory, Type type, Type componentType, + Creator> creator, final Decodeable componentDecoder) { + Objects.requireNonNull(componentDecoder); + this.type = type; + this.componentType = componentType; + this.creator = creator; + this.componentDecoder = componentDecoder; + this.inited = true; + } + @Override public Collection convertFrom(Reader in) { return convertFrom(in, null); diff --git a/src/org/redkale/convert/MapDecoder.java b/src/org/redkale/convert/MapDecoder.java index d3c7ed70e..bef9269f8 100644 --- a/src/org/redkale/convert/MapDecoder.java +++ b/src/org/redkale/convert/MapDecoder.java @@ -8,7 +8,7 @@ package org.redkale.convert; import org.redkale.util.Creator; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.Map; +import java.util.*; /** * Map的反序列化操作类
@@ -74,6 +74,20 @@ public class MapDecoder implements Decodeable> { } } + //仅供类似JsonAnyDecoder这种动态创建使用, 不得调用 factory.register + public MapDecoder(final ConvertFactory factory, Type type, Type keyType, Type valueType, + Creator> creator, final Decodeable keyDecoder, Decodeable valueDecoder) { + Objects.requireNonNull(keyDecoder); + Objects.requireNonNull(valueDecoder); + this.type = type; + this.keyType = keyType; + this.valueType = valueType; + this.creator = creator; + this.keyDecoder = keyDecoder; + this.valueDecoder = valueDecoder; + this.inited = true; + } + @Override public Map convertFrom(Reader in) { return convertFrom(in, null); diff --git a/src/org/redkale/convert/json/JsonAnyDecoder.java b/src/org/redkale/convert/json/JsonAnyDecoder.java new file mode 100644 index 000000000..7b259971d --- /dev/null +++ b/src/org/redkale/convert/json/JsonAnyDecoder.java @@ -0,0 +1,64 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.redkale.convert.json; + +import java.lang.reflect.*; +import java.util.*; +import org.redkale.convert.*; +import org.redkale.convert.json.JsonReader.ValueType; +import org.redkale.util.*; + +/** + * 对不明类型的对象进行JSON反序列化。 + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + */ +@SuppressWarnings("unchecked") +public final class JsonAnyDecoder implements Decodeable { + + private static final Type collectionObjectType = new TypeToken>() { + }.getType(); + + private static final Type mapObjectType = new TypeToken>() { + }.getType(); + + private static final Creator collectionCreator = Creator.create(ArrayList.class); + + private static final Creator mapCreator = Creator.create(HashMap.class); + + protected final Decodeable stringDecoder; + + protected final CollectionDecoder collectionDecoder; + + protected final MapDecoder mapDecoder; + + public JsonAnyDecoder(final ConvertFactory factory) { + this.stringDecoder = factory.loadDecoder(String.class); + this.collectionDecoder = new CollectionDecoder(factory, collectionObjectType, Object.class, collectionCreator, this); + this.mapDecoder = new MapDecoder(factory, mapObjectType, String.class, Object.class, mapCreator, stringDecoder, this); + } + + @Override + public Object convertFrom(JsonReader in) { + ValueType vt = in.readType(); + if (vt == null) return null; + switch (vt) { + case COLLECTION: + return this.collectionDecoder.convertFrom(in); + case JSONOBJECT: + return this.mapDecoder.convertFrom(in); + } + return this.stringDecoder.convertFrom(in); + } + + @Override + public Type getType() { + return void.class; + } + +} diff --git a/src/org/redkale/convert/json/JsonConvert.java b/src/org/redkale/convert/json/JsonConvert.java index 658929754..275f9adc5 100644 --- a/src/org/redkale/convert/json/JsonConvert.java +++ b/src/org/redkale/convert/json/JsonConvert.java @@ -128,6 +128,45 @@ public final class JsonConvert extends TextConvert { return rs; } + public Object convertFrom(final String text) { + if (text == null) return null; + return convertFrom(Utility.charArray(text)); + } + + public Object convertFrom(final char[] text) { + if (text == null) return null; + return convertFrom(text, 0, text.length); + } + + public Object convertFrom(final char[] text, final int start, final int len) { + if (text == null) return null; + final JsonReader in = readerPool.get(); + in.setText(text, start, len); + Object rs = new JsonAnyDecoder(factory).convertFrom(in); + readerPool.accept(in); + return rs; + } + + public Object convertFrom(final InputStream in) { + if (in == null) return null; + return new JsonAnyDecoder(factory).convertFrom(new JsonStreamReader(in)); + } + + public Object convertFrom(final ByteBuffer... buffers) { + if (buffers == null || buffers.length == 0) return null; + return new JsonAnyDecoder(factory).convertFrom(new JsonByteBufferReader((ConvertMask) null, buffers)); + } + + public Object convertFrom(final ConvertMask mask, final ByteBuffer... buffers) { + if (buffers == null || buffers.length == 0) return null; + return new JsonAnyDecoder(factory).convertFrom(new JsonByteBufferReader(mask, buffers)); + } + + public Object convertFrom(final JsonReader reader) { + if (reader == null) return null; + return new JsonAnyDecoder(factory).convertFrom(reader); + } + //------------------------------ convertTo ----------------------------------------------------------- @Override public String convertTo(final Object value) { diff --git a/src/org/redkale/convert/json/JsonReader.java b/src/org/redkale/convert/json/JsonReader.java index 40d6e3e42..30a765295 100644 --- a/src/org/redkale/convert/json/JsonReader.java +++ b/src/org/redkale/convert/json/JsonReader.java @@ -19,6 +19,10 @@ import org.redkale.util.*; */ public class JsonReader extends Reader { + static enum ValueType { + STRING, COLLECTION, JSONOBJECT; + } + protected int position = -1; private char[] text; @@ -158,6 +162,20 @@ public class JsonReader extends Reader { this.position--; } + final ValueType readType() { + char ch = nextGoodChar(); + if (ch == '{') { + backChar(ch); + return ValueType.JSONOBJECT; + } + if (ch == '[') { + backChar(ch); + return ValueType.COLLECTION; + } + backChar(ch); + return ValueType.STRING; + } + /** * 判断下一个非空白字符是否为{ * diff --git a/test/org/redkale/test/convert/JsonTestMain.java b/test/org/redkale/test/convert/JsonTestMain.java index 038e37cdd..0eec31816 100644 --- a/test/org/redkale/test/convert/JsonTestMain.java +++ b/test/org/redkale/test/convert/JsonTestMain.java @@ -69,5 +69,7 @@ public class JsonTestMain { SimpleChildEntity entry2 = convert.convertFrom(SimpleChildEntity.class, in); System.out.println(entry); System.out.println(entry2); + Map rs = (Map) convert.convertFrom(entry2.toString()); + System.out.println(convert.convertTo(rs)); } }