增加Optional的序列化和反序列化
This commit is contained in:
@@ -50,7 +50,7 @@ public final class CollectionDecoder<T> implements Decodeable<Reader, Collection
|
||||
factory.register(type, this);
|
||||
this.decoder = factory.loadDecoder(this.componentType);
|
||||
} else {
|
||||
throw new ConvertException("collectiondecoder not support the type (" + type + ")");
|
||||
throw new ConvertException("CollectionDecoder not support the type (" + type + ")");
|
||||
}
|
||||
} finally {
|
||||
inited = true;
|
||||
|
||||
@@ -468,6 +468,8 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
decoder = new StreamDecoder(this, type);
|
||||
} else if (Map.class.isAssignableFrom(clazz)) {
|
||||
decoder = new MapDecoder(this, type);
|
||||
} else if (Optional.class == clazz) {
|
||||
decoder = new OptionalCoder(this, type);
|
||||
} else if (clazz == Object.class) {
|
||||
od = new ObjectDecoder(type);
|
||||
decoder = od;
|
||||
@@ -553,6 +555,8 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
||||
encoder = new StreamEncoder(this, type);
|
||||
} else if (Map.class.isAssignableFrom(clazz)) {
|
||||
encoder = new MapEncoder(this, type);
|
||||
} else if (Optional.class == clazz) {
|
||||
encoder = new OptionalCoder(this, type);
|
||||
} else if (clazz == Object.class) {
|
||||
return (Encodeable<W, E>) this.anyEncoder;
|
||||
} 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 stringencoder;
|
||||
|
||||
private final boolean keyany;
|
||||
|
||||
private final boolean valany;
|
||||
|
||||
private boolean inited = false;
|
||||
|
||||
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.valencoder = factory.getAnyEncoder();
|
||||
}
|
||||
this.keyany = this.keyencoder == factory.getAnyEncoder();
|
||||
this.valany = this.valencoder == factory.getAnyEncoder();
|
||||
this.stringencoder = factory.loadEncoder(String.class);
|
||||
} finally {
|
||||
inited = true;
|
||||
synchronized (lock) {
|
||||
@@ -67,6 +58,7 @@ public final class MapEncoder<K, V> implements Encodeable<Writer, Map<K, V>> {
|
||||
out.writeNull();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.keyencoder == null || this.valencoder == null) {
|
||||
if (!this.inited) {
|
||||
synchronized (lock) {
|
||||
@@ -82,19 +74,9 @@ public final class MapEncoder<K, V> implements Encodeable<Writer, Map<K, V>> {
|
||||
boolean first = true;
|
||||
for (Map.Entry<K, V> en : values.entrySet()) {
|
||||
if (!first) out.writeArrayMark();
|
||||
K key = en.getKey();
|
||||
V val = en.getValue();
|
||||
if (keyany && key instanceof String) {
|
||||
this.stringencoder.convertTo(out, key);
|
||||
} else {
|
||||
this.keyencoder.convertTo(out, key);
|
||||
}
|
||||
this.keyencoder.convertTo(out, en.getKey());
|
||||
out.writeMapMark();
|
||||
if (valany && val instanceof String) {
|
||||
this.stringencoder.convertTo(out, val);
|
||||
} else {
|
||||
this.valencoder.convertTo(out, val);
|
||||
}
|
||||
this.valencoder.convertTo(out, en.getValue());
|
||||
if (first) first = false;
|
||||
}
|
||||
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.util.*;
|
||||
import org.redkale.convert.json.*;
|
||||
import org.redkale.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -31,6 +32,7 @@ public class BsonTestMain {
|
||||
main3(args);
|
||||
main4(args);
|
||||
main5(args);
|
||||
main6(args);
|
||||
}
|
||||
|
||||
public static void main2(String[] args) throws Exception {
|
||||
@@ -98,4 +100,20 @@ public class BsonTestMain {
|
||||
Object mapobj = convert.convertFrom(Object.class, bs);
|
||||
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