package com.alibaba.json.test.performance;
import static com.alibaba.json.test.performance.JacksonPageModelParser.JsonParserHelper.assertExpectedFiled;
import static com.alibaba.json.test.performance.JacksonPageModelParser.JsonParserHelper.assertExpectedJsonToken;
import static com.alibaba.json.test.performance.JacksonPageModelParser.JsonParserHelper.getNextTextValue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.json.test.entity.pagemodel.LayoutInstance;
import com.alibaba.json.test.entity.pagemodel.PageInstance;
import com.alibaba.json.test.entity.pagemodel.RegionEnum;
import com.alibaba.json.test.entity.pagemodel.RegionInstance;
import com.alibaba.json.test.entity.pagemodel.SegmentInstance;
import com.alibaba.json.test.entity.pagemodel.WidgetInstance;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
public class JacksonPageModelParser {
/**
* @param content
* @throws JsonParseException
* @throws IOException
*/
public PageInstance parse(String content) throws JsonParseException, IOException {
JsonFactory f = new JsonFactory();
JsonParser parser = f.createJsonParser(content);
JsonToken current = parser.nextToken(); // move to the start of the
// object
String instanceId = getNextTextValue("sid", parser); // get instanceId
String pageId = getNextTextValue("cid", parser); // get pageId
current = parser.nextToken(); // move to field: segments
assertExpectedFiled(parser.getCurrentName(), "segments", parser.getCurrentLocation());
PageInstance pageInstance = new PageInstance();
pageInstance.setCid(pageId);
pageInstance.setSid(Long.valueOf(instanceId));
pageInstance.setSegments(parseSegments(parser));
return pageInstance;
// 构建组件树,用于递归渲染
// pageInstance.buildComponentTree();
}
/**
* @param parser
* @throws JsonParseException
* @throws IOException
*/
private List<SegmentInstance> parseSegments(JsonParser parser) throws JsonParseException, IOException {
JsonToken current = parser.nextToken();
assertExpectedJsonToken(current, JsonToken.START_ARRAY, parser.getCurrentLocation());
List<SegmentInstance> instances = new ArrayList<SegmentInstance>();
while ((current = parser.nextToken()) != JsonToken.END_ARRAY) {
assertExpectedJsonToken(current, JsonToken.START_OBJECT, parser.getCurrentLocation());
String segmentId = getNextTextValue("cid", parser); // get pageId
current = parser.nextToken(); // move to field: layouts
assertExpectedFiled(parser.getCurrentName(), "layouts", parser.getCurrentLocation());
SegmentInstance instance = new SegmentInstance();
instance.setLayouts(parseLayouts(parser, segmentId));
instances.add(instance);
assertExpectedJsonToken((current = parser.nextToken()), JsonToken.END_OBJECT, parser.getCurrentLocation());
}
return instances;
}
/**
* @param parser
* @param segmentId
* @throws JsonParseException
* @throws IOException
*/
private List<LayoutInstance> parseLayouts(JsonParser parser, String segment) throws JsonParseException, IOException {
JsonToken current = parser.nextToken();
assertExpectedJsonToken(current, JsonToken.START_ARRAY, parser.getCurrentLocation());
List<LayoutInstance> layoutInThisSegment = new ArrayList<LayoutInstance>();
while ((current = parser.nextToken()) != JsonToken.END_ARRAY) {
assertExpectedJsonToken(current, JsonToken.START_OBJECT, parser.getCurrentLocation());
String instanceId = getNextTextValue("sid", parser); // get
// instanceId
String layoutId = getNextTextValue("cid", parser); // get
// layoutId
LayoutInstance layoutInstance = new LayoutInstance();
layoutInstance.setCid(layoutId);
layoutInstance.setSid(Long.valueOf(instanceId));
layoutInThisSegment.add(layoutInstance);
current = parser.nextToken(); // move to field: regions
assertExpectedFiled(parser.getCurrentName(), "regions", parser.getCurrentLocation());
layoutInstance.setRegions(parseRegions(parser, segment));
assertExpectedJsonToken((current = parser.nextToken()), JsonToken.END_OBJECT, parser.getCurrentLocation());
}
return layoutInThisSegment;
}
/**
* @param parser
* @param layoutId
* @throws JsonParseException
* @throws IOException
*/
private List<RegionInstance> parseRegions(JsonParser parser, String segment) throws JsonParseException, IOException {
JsonToken current = parser.nextToken();
assertExpectedJsonToken(current, JsonToken.START_ARRAY, parser.getCurrentLocation());
List<RegionInstance> instances = new ArrayList<RegionInstance>();
while ((current = parser.nextToken()) != JsonToken.END_ARRAY) {
assertExpectedJsonToken(current, JsonToken.START_OBJECT, parser.getCurrentLocation());
String regionId = getNextTextValue("cid", parser); // get regionId
RegionEnum region = RegionEnum.valueOf(regionId);
current = parser.nextToken(); // move to field: widgtes
assertExpectedFiled(parser.getCurrentName(), "widgets", parser.getCurrentLocation());
RegionInstance instance = new RegionInstance();
instance.setWidgtes(parseWidgets(parser, region));
instances.add(instance);
assertExpectedJsonToken((current = parser.nextToken()), JsonToken.END_OBJECT, parser.getCurrentLocation());
}
return instances;
}
/**
* @param parser
* @param layoutId
* @param regionId
* @throws JsonParseException
* @throws IOException
*/
private List<WidgetInstance> parseWidgets(JsonParser parser, RegionEnum region) throws JsonParseException, IOException {
JsonToken current = parser.nextToken();
assertExpectedJsonToken(current, JsonToken.START_ARRAY, parser.getCurrentLocation());
List<WidgetInstance> widgetInThisRegion = new ArrayList<WidgetInstance>();
while ((current = parser.nextToken()) != JsonToken.END_ARRAY) {
assertExpectedJsonToken(current, JsonToken.START_OBJECT, parser.getCurrentLocation());
String instanceId = getNextTextValue("sid", parser); // get
// instanceId
String widgetId = getNextTextValue("cid", parser); // get
// widgetId
WidgetInstance widgetInstance = new WidgetInstance();
widgetInstance.setCid(widgetId);
widgetInstance.setSid(Long.valueOf(instanceId));
widgetInThisRegion.add(widgetInstance);
assertExpectedJsonToken((current = parser.nextToken()), JsonToken.END_OBJECT, parser.getCurrentLocation());
}
return widgetInThisRegion;
}
public static class JsonParserHelper {
public static String getNextTextValue(String fieldName, JsonParser parser) throws JsonParseException, IOException {
JsonToken current = parser.nextToken(); // move to filed
if (current != JsonToken.FIELD_NAME || !fieldName.equals(parser.getCurrentName())) {
reportParseError("Error occoured while getting value by field name:" + fieldName, parser.getCurrentLocation());
}
current = parser.nextToken(); // move to value
return parser.getText();
}
public static void assertExpectedJsonToken(JsonToken object, JsonToken expected, JsonLocation jsonLoc) throws JsonParseException {
if (object != expected) {
reportParseError(buildFailMessage(object, expected), jsonLoc);
}
}
public static void assertExpectedFiled(String object, String expected, JsonLocation jsonLoc) throws JsonParseException {
if (!expected.equals(object)) {
reportParseError(buildFailMessage(object, expected), jsonLoc);
}
}
private static String buildFailMessage(Object object, Object expected) {
StringBuilder sb = new StringBuilder();
sb.append("get [").append(object).append("] but expect [").append(expected).append("] !");
return sb.toString();
}
public static void reportParseError(String errorMsg, JsonLocation jsonLoc) throws JsonParseException {
throw new JsonParseException(errorMsg, jsonLoc);
}
}
}