package com.firefly.utils.json.parser;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import com.firefly.utils.collection.IdentityHashMap;
import com.firefly.utils.json.JsonReader;
import com.firefly.utils.json.Parser;
import com.firefly.utils.json.exception.JsonException;
public class ParserStateMachine {
private static final IdentityHashMap<Class<?>, Parser> PARSER_MAP = new IdentityHashMap<Class<?>, Parser>();
private static final Object LOCK = new Object();
static {
PARSER_MAP.put(int.class, new IntParser());
PARSER_MAP.put(long.class, new LongParser());
PARSER_MAP.put(short.class, new ShortParser());
PARSER_MAP.put(float.class, new FloatParser());
PARSER_MAP.put(double.class, new DoubleParser());
PARSER_MAP.put(boolean.class, new BooleanParser());
PARSER_MAP.put(char.class, new CharacterParser());
PARSER_MAP.put(Integer.class, PARSER_MAP.get(int.class));
PARSER_MAP.put(Long.class, PARSER_MAP.get(long.class));
PARSER_MAP.put(Short.class, PARSER_MAP.get(short.class));
PARSER_MAP.put(Float.class, PARSER_MAP.get(float.class));
PARSER_MAP.put(Double.class, PARSER_MAP.get(double.class));
PARSER_MAP.put(Boolean.class, PARSER_MAP.get(boolean.class));
PARSER_MAP.put(Character.class, PARSER_MAP.get(char.class));
PARSER_MAP.put(BigDecimal.class, new BigDecimalParser());
PARSER_MAP.put(BigInteger.class, new BigIntegerParser());
PARSER_MAP.put(String.class, new StringParser());
PARSER_MAP.put(Date.class, new DateParser());
PARSER_MAP.put(int[].class, new ArrayParser(int.class));
PARSER_MAP.put(long[].class, new ArrayParser(long.class));
PARSER_MAP.put(short[].class, new ArrayParser(short.class));
PARSER_MAP.put(float[].class, new ArrayParser(float.class));
PARSER_MAP.put(double[].class, new ArrayParser(double.class));
PARSER_MAP.put(boolean[].class, new ArrayParser(boolean.class));
PARSER_MAP.put(byte[].class, new ByteArrayParser());
PARSER_MAP.put(char[].class, new CharArrayParser());
PARSER_MAP.put(Integer[].class, new ArrayParser(Integer.class));
PARSER_MAP.put(Long[].class, new ArrayParser(Long.class));
PARSER_MAP.put(Short[].class, new ArrayParser(Short.class));
PARSER_MAP.put(Float[].class, new ArrayParser(Float.class));
PARSER_MAP.put(Double[].class, new ArrayParser(Double.class));
PARSER_MAP.put(Boolean[].class, new ArrayParser(Boolean.class));
PARSER_MAP.put(String[].class, new ArrayParser(String.class));
}
public static Parser getParser(Class<?> clazz) {
Parser ret = PARSER_MAP.get(clazz);
if(ret == null) {
synchronized(LOCK) {
ret = PARSER_MAP.get(clazz);
if(ret == null) {
if (clazz.isEnum()) {
ret = new EnumParser(clazz);
PARSER_MAP.put(clazz, ret);
} else if (Collection.class.isAssignableFrom(clazz)
|| Map.class.isAssignableFrom(clazz)) {
throw new JsonException("not support type " + clazz);
} else if (clazz.isArray()) {
Class<?> elementClass = clazz.getComponentType();
ret = new ArrayParser(elementClass);
PARSER_MAP.put(clazz, ret);
} else {
ret = new ObjectParser();
PARSER_MAP.put(clazz, ret);
((ObjectParser)ret).init(clazz);
}
}
}
}
return ret;
}
@SuppressWarnings("unchecked")
public static <T> T toObject(JsonReader reader, Class<?> clazz) throws IOException {
Parser parser = getParser(clazz);
return (T) parser.convertTo(reader, clazz);
}
}