增加Optional的序列化和反序列化
This commit is contained in:
@@ -50,7 +50,7 @@ public final class CollectionDecoder<T> implements Decodeable<Reader, Collection
|
|||||||
factory.register(type, this);
|
factory.register(type, this);
|
||||||
this.decoder = factory.loadDecoder(this.componentType);
|
this.decoder = factory.loadDecoder(this.componentType);
|
||||||
} else {
|
} else {
|
||||||
throw new ConvertException("collectiondecoder not support the type (" + type + ")");
|
throw new ConvertException("CollectionDecoder not support the type (" + type + ")");
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
inited = true;
|
inited = true;
|
||||||
|
|||||||
@@ -468,6 +468,8 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
decoder = new StreamDecoder(this, type);
|
decoder = new StreamDecoder(this, type);
|
||||||
} else if (Map.class.isAssignableFrom(clazz)) {
|
} else if (Map.class.isAssignableFrom(clazz)) {
|
||||||
decoder = new MapDecoder(this, type);
|
decoder = new MapDecoder(this, type);
|
||||||
|
} else if (Optional.class == clazz) {
|
||||||
|
decoder = new OptionalCoder(this, type);
|
||||||
} else if (clazz == Object.class) {
|
} else if (clazz == Object.class) {
|
||||||
od = new ObjectDecoder(type);
|
od = new ObjectDecoder(type);
|
||||||
decoder = od;
|
decoder = od;
|
||||||
@@ -553,6 +555,8 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
encoder = new StreamEncoder(this, type);
|
encoder = new StreamEncoder(this, type);
|
||||||
} else if (Map.class.isAssignableFrom(clazz)) {
|
} else if (Map.class.isAssignableFrom(clazz)) {
|
||||||
encoder = new MapEncoder(this, type);
|
encoder = new MapEncoder(this, type);
|
||||||
|
} else if (Optional.class == clazz) {
|
||||||
|
encoder = new OptionalCoder(this, type);
|
||||||
} else if (clazz == Object.class) {
|
} else if (clazz == Object.class) {
|
||||||
return (Encodeable<W, E>) this.anyEncoder;
|
return (Encodeable<W, E>) this.anyEncoder;
|
||||||
} else if (!clazz.getName().startsWith("java.") || java.net.HttpCookie.class == clazz) {
|
} else if (!clazz.getName().startsWith("java.") || java.net.HttpCookie.class == clazz) {
|
||||||
|
|||||||
@@ -28,12 +28,6 @@ public final class MapEncoder<K, V> implements Encodeable<Writer, Map<K, V>> {
|
|||||||
|
|
||||||
private final Encodeable<Writer, V> valencoder;
|
private final Encodeable<Writer, V> valencoder;
|
||||||
|
|
||||||
private final Encodeable stringencoder;
|
|
||||||
|
|
||||||
private final boolean keyany;
|
|
||||||
|
|
||||||
private final boolean valany;
|
|
||||||
|
|
||||||
private boolean inited = false;
|
private boolean inited = false;
|
||||||
|
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
@@ -49,9 +43,6 @@ public final class MapEncoder<K, V> implements Encodeable<Writer, Map<K, V>> {
|
|||||||
this.keyencoder = factory.getAnyEncoder();
|
this.keyencoder = factory.getAnyEncoder();
|
||||||
this.valencoder = factory.getAnyEncoder();
|
this.valencoder = factory.getAnyEncoder();
|
||||||
}
|
}
|
||||||
this.keyany = this.keyencoder == factory.getAnyEncoder();
|
|
||||||
this.valany = this.valencoder == factory.getAnyEncoder();
|
|
||||||
this.stringencoder = factory.loadEncoder(String.class);
|
|
||||||
} finally {
|
} finally {
|
||||||
inited = true;
|
inited = true;
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
@@ -67,6 +58,7 @@ public final class MapEncoder<K, V> implements Encodeable<Writer, Map<K, V>> {
|
|||||||
out.writeNull();
|
out.writeNull();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.keyencoder == null || this.valencoder == null) {
|
if (this.keyencoder == null || this.valencoder == null) {
|
||||||
if (!this.inited) {
|
if (!this.inited) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
@@ -82,19 +74,9 @@ public final class MapEncoder<K, V> implements Encodeable<Writer, Map<K, V>> {
|
|||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (Map.Entry<K, V> en : values.entrySet()) {
|
for (Map.Entry<K, V> en : values.entrySet()) {
|
||||||
if (!first) out.writeArrayMark();
|
if (!first) out.writeArrayMark();
|
||||||
K key = en.getKey();
|
this.keyencoder.convertTo(out, en.getKey());
|
||||||
V val = en.getValue();
|
|
||||||
if (keyany && key instanceof String) {
|
|
||||||
this.stringencoder.convertTo(out, key);
|
|
||||||
} else {
|
|
||||||
this.keyencoder.convertTo(out, key);
|
|
||||||
}
|
|
||||||
out.writeMapMark();
|
out.writeMapMark();
|
||||||
if (valany && val instanceof String) {
|
this.valencoder.convertTo(out, en.getValue());
|
||||||
this.stringencoder.convertTo(out, val);
|
|
||||||
} else {
|
|
||||||
this.valencoder.convertTo(out, val);
|
|
||||||
}
|
|
||||||
if (first) first = false;
|
if (first) first = false;
|
||||||
}
|
}
|
||||||
out.writeMapE();
|
out.writeMapE();
|
||||||
|
|||||||
107
src/org/redkale/convert/OptionalCoder.java
Normal file
107
src/org/redkale/convert/OptionalCoder.java
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional 的SimpledCoder实现
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 详情见: https://redkale.org
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
* @param <R> Reader输入的子类型
|
||||||
|
* @param <W> Writer输出的子类型
|
||||||
|
*/
|
||||||
|
public class OptionalCoder<R extends Reader, W extends Writer, T> extends SimpledCoder<R, W, Optional<T>> {
|
||||||
|
|
||||||
|
private final Type type;
|
||||||
|
|
||||||
|
private final Type componentType;
|
||||||
|
|
||||||
|
protected final Class componentClass;
|
||||||
|
|
||||||
|
protected final Decodeable<Reader, T> decoder;
|
||||||
|
|
||||||
|
protected final Encodeable<Writer, T> encoder;
|
||||||
|
|
||||||
|
private boolean inited = false;
|
||||||
|
|
||||||
|
private final Object lock = new Object();
|
||||||
|
|
||||||
|
public OptionalCoder(final ConvertFactory factory, final Type type) {
|
||||||
|
this.type = type;
|
||||||
|
try {
|
||||||
|
if (type instanceof ParameterizedType) {
|
||||||
|
final ParameterizedType pt = (ParameterizedType) type;
|
||||||
|
this.componentType = pt.getActualTypeArguments()[0];
|
||||||
|
factory.register(type, this);
|
||||||
|
this.decoder = factory.loadDecoder(this.componentType);
|
||||||
|
if (this.componentType instanceof TypeVariable) {
|
||||||
|
this.encoder = factory.getAnyEncoder();
|
||||||
|
this.componentClass = Object.class;
|
||||||
|
} else {
|
||||||
|
if (componentType instanceof ParameterizedType) {
|
||||||
|
final ParameterizedType pt2 = (ParameterizedType) componentType;
|
||||||
|
this.componentClass = (Class) pt2.getRawType();
|
||||||
|
} else {
|
||||||
|
this.componentClass = (Class) componentType;
|
||||||
|
}
|
||||||
|
this.encoder = factory.loadEncoder(this.componentType);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.componentType = Object.class;
|
||||||
|
this.componentClass = Object.class;
|
||||||
|
this.decoder = factory.loadDecoder(this.componentType);
|
||||||
|
this.encoder = factory.getAnyEncoder();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
inited = true;
|
||||||
|
synchronized (lock) {
|
||||||
|
lock.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertTo(W out, Optional<T> value) {
|
||||||
|
if (value == null || !value.isPresent()) {
|
||||||
|
out.writeObjectNull(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.encoder == null) {
|
||||||
|
if (!this.inited) {
|
||||||
|
synchronized (lock) {
|
||||||
|
try {
|
||||||
|
lock.wait();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.encoder.convertTo(out, value.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<T> convertFrom(R in) {
|
||||||
|
if (this.decoder == null) {
|
||||||
|
if (!this.inited) {
|
||||||
|
synchronized (lock) {
|
||||||
|
try {
|
||||||
|
lock.wait();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(this.decoder.convertFrom(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import org.redkale.convert.bson.BsonConvert;
|
|||||||
import java.nio.*;
|
import java.nio.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.redkale.convert.json.*;
|
import org.redkale.convert.json.*;
|
||||||
|
import org.redkale.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -31,6 +32,7 @@ public class BsonTestMain {
|
|||||||
main3(args);
|
main3(args);
|
||||||
main4(args);
|
main4(args);
|
||||||
main5(args);
|
main5(args);
|
||||||
|
main6(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main2(String[] args) throws Exception {
|
public static void main2(String[] args) throws Exception {
|
||||||
@@ -98,4 +100,20 @@ public class BsonTestMain {
|
|||||||
Object mapobj = convert.convertFrom(Object.class, bs);
|
Object mapobj = convert.convertFrom(Object.class, bs);
|
||||||
System.out.println(mapobj);
|
System.out.println(mapobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void main6(String[] args) throws Exception {
|
||||||
|
final BsonConvert convert = BsonFactory.root().getConvert();
|
||||||
|
|
||||||
|
Optional<String> val = Optional.ofNullable("haha");
|
||||||
|
byte[] bs = convert.convertTo(val);
|
||||||
|
Object obj = convert.convertFrom(Optional.class, bs);
|
||||||
|
System.out.println(obj);
|
||||||
|
bs = convert.convertTo(Object.class, val);
|
||||||
|
obj = convert.convertFrom(Object.class, bs);
|
||||||
|
System.out.println(obj);
|
||||||
|
bs = convert.convertTo(new TypeToken<Optional<String>>(){}.getType(), val);
|
||||||
|
obj = convert.convertFrom(new TypeToken<Optional<String>>(){}.getType(), bs);
|
||||||
|
System.out.println(obj);
|
||||||
|
System.out.println(JsonConvert.root().convertTo(val));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user