增加Optional的序列化和反序列化

This commit is contained in:
Redkale
2017-12-25 10:12:01 +08:00
parent 0f545923b2
commit 921aedaf9d
5 changed files with 133 additions and 22 deletions

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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();

View 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));
}
}

View File

@@ -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));
}
}