package hprose.example.io;
import hprose.common.HproseException;
import static hprose.io.HproseTags.TagEmpty;
import static hprose.io.HproseTags.TagList;
import static hprose.io.HproseTags.TagMap;
import static hprose.io.HproseTags.TagObject;
import hprose.io.unserialize.BaseUnserializer;
import hprose.io.unserialize.Reader;
import hprose.io.unserialize.ReferenceReader;
import hprose.io.unserialize.ValueReader;
import hprose.util.CaseInsensitiveMap;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.tuple.ImmutablePair;
public class ImmutablePairUnserializer extends BaseUnserializer<ImmutablePair> {
public static final ImmutablePairUnserializer instance = new ImmutablePairUnserializer();
private static final ImmutablePairConverter converter = ImmutablePairConverter.instance;
private Type[] getTypes(Type type) {
if (type instanceof ParameterizedType) {
return ((ParameterizedType)type).getActualTypeArguments();
}
return new Type[] { Object.class, Object.class };
}
private Map<String, Type> getTypeMap(Type[] types) {
Map<String, Type> typeMap = new CaseInsensitiveMap();
typeMap.put("key", types[0]);
typeMap.put("value", types[1]);
typeMap.put("left", types[0]);
typeMap.put("right", types[1]);
return typeMap;
}
private ImmutablePair readListAsImmutablePair(Reader reader, Type type) throws IOException {
int count = ValueReader.readCount(reader);
if (count != 2) throw new HproseException("Can't unserialize List to ImmutablePair.");
Object[] array = new Object[2];
ReferenceReader.readArray(reader, getTypes(type), array, 2);
return new ImmutablePair(array[0], array[1]);
}
private ImmutablePair readMapAsImmutablePair(Reader reader, Type type) throws IOException {
int count = ValueReader.readCount(reader);
Type[] types = getTypes(type);
if (count == 1) {
Map<?, ?> map = new HashMap();
ReferenceReader.readMap(reader, map, types[0], types[1], count);
return converter.convertTo(map);
}
Map<String, Type> typeMap = getTypeMap(types);
Map<String, Object> map = new CaseInsensitiveMap();
ReferenceReader.readMap(reader, map, typeMap, count);
return converter.convertTo(map);
}
private ImmutablePair readObjectAsImmutablePair(Reader reader, Type type) throws IOException {
Type[] types = getTypes(type);
Map<String, Type> typeMap = getTypeMap(types);
Map<String, Object> map = ReferenceReader.readObjectAsMap(reader, CaseInsensitiveMap.class, typeMap);
return converter.convertTo(map);
}
@Override
public ImmutablePair unserialize(Reader reader, int tag, Type type) throws IOException {
switch (tag) {
case TagEmpty: return null;
case TagList: return readListAsImmutablePair(reader, type);
case TagMap: return readMapAsImmutablePair(reader, type);
case TagObject: return readObjectAsImmutablePair(reader, type);
}
return super.unserialize(reader, tag, type);
}
}