com.firefly.utils.json.parser.ObjectParser Maven / Gradle / Ivy
package com.firefly.utils.json.parser;
import java.util.HashMap;
import java.util.Map;
import com.firefly.utils.json.JsonReader;
import com.firefly.utils.json.Parser;
import com.firefly.utils.json.compiler.DecodeCompiler;
import com.firefly.utils.json.exception.JsonException;
import com.firefly.utils.json.support.ParserMetaInfo;
public class ObjectParser implements Parser {
private ParserMetaInfo[] parserMetaInfos;
private int max;
private Map map;
private boolean useMap;
public void init(Class> clazz) {
parserMetaInfos = DecodeCompiler.compile(clazz);
max = parserMetaInfos.length - 1;
if(max >= 8) {
map = new HashMap();
for(ParserMetaInfo parserMetaInfo : parserMetaInfos) {
map.put(parserMetaInfo.getPropertyNameString(), parserMetaInfo);
}
useMap = true;
}
}
@Override
public Object convertTo(JsonReader reader, Class> clazz) {
if(reader.isNull())
return null;
if(!reader.isObject())
throw new JsonException("json string is not object format");
Object obj = null;
try {
obj = clazz.newInstance();
} catch (Throwable e) {
e.printStackTrace();
}
if(reader.isEmptyObject())
return obj;
for (int i = 0;;i++) {
ParserMetaInfo parser = parserMetaInfos[i];
char[] field = reader.readField(parser.getPropertyName());
if(!reader.isColon())
throw new JsonException("missing ':'");
if(field == null) { // the same order,skip
parser.invoke(obj, reader);
} else {
ParserMetaInfo np = find(field);
if(np != null)
np.invoke(obj, reader);
else
reader.skipValue();
}
if(i == max)
break;
char ch = reader.readAndSkipBlank();
if(ch == '}') // if JSON string fields is less than the meta information,end reading
return obj;
if(ch != ',')
throw new JsonException("missing ','");
}
char ch = reader.readAndSkipBlank();
if(ch == '}')
return obj;
if(ch != ',')
throw new JsonException("json string is not object format");
for(;;) { // if JSON string fields is more than the meta information, continue reading
char[] field = reader.readChars();
if(!reader.isColon())
throw new JsonException("missing ':'");
ParserMetaInfo np = find(field);
if(np != null)
np.invoke(obj, reader);
else
reader.skipValue();
char c = reader.readAndSkipBlank();
if(c == '}') // the object end symbol
return obj;
if(c != ',')
throw new JsonException("missing ','");
}
}
private ParserMetaInfo find(char[] field) {
if(useMap) {
return map.get(new String(field));
} else {
for(ParserMetaInfo parserMetaInfo : parserMetaInfos) {
if(parserMetaInfo.equals(field))
return parserMetaInfo;
}
}
return null;
}
}