init
This commit is contained in:
@@ -0,0 +1,289 @@
|
||||
package com.eactive.eai.message.parser;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.eactive.eai.message.EncodingVar;
|
||||
import com.eactive.eai.message.StandardDataType;
|
||||
import com.eactive.eai.message.StandardItem;
|
||||
import com.eactive.eai.message.StandardMessage;
|
||||
import com.eactive.eai.message.StandardType;
|
||||
|
||||
public class FlatReader implements StandardReader {
|
||||
static Logger logger = LoggerFactory.getLogger(FlatReader.class);
|
||||
private char FIELD_SEPARATOR = '.';
|
||||
private boolean ZERO_BASE_INDEX = true;
|
||||
|
||||
public FlatReader() {
|
||||
|
||||
}
|
||||
|
||||
public StandardMessage parse(StandardMessage message, Object flatObject) throws Exception {
|
||||
ArrayList<StandardItem> list = message.toList();
|
||||
for(int i=0; i<list.size(); i++) {
|
||||
StandardItem item = list.get(i);
|
||||
logger.debug("{} Level={} Name={}", i, item.getLevel(), item.getName());
|
||||
}
|
||||
|
||||
byte[] srcbytes = null;
|
||||
String encoding = EncodingVar.flatEncoding;
|
||||
if (flatObject instanceof String) {
|
||||
try {
|
||||
logger.debug("Encoding : {}", encoding);
|
||||
srcbytes = ((String) flatObject).getBytes(encoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
srcbytes = ((String) flatObject).getBytes();
|
||||
}
|
||||
} else {
|
||||
srcbytes = (byte[]) flatObject;
|
||||
}
|
||||
|
||||
// make item map(path, value)
|
||||
LinkedHashMap<String, String> itemMap = new LinkedHashMap<String, String>();
|
||||
|
||||
message.setReadPosition(0);
|
||||
|
||||
traverse(message, message, srcbytes, null, itemMap);
|
||||
int remain = srcbytes.length - message.getReadPosition();
|
||||
if(remain > 0) {
|
||||
throw new Exception("flat message parsing error(overflow) remain size="+remain);
|
||||
}
|
||||
|
||||
message.setBizDataCharset(encoding);
|
||||
logger.debug("setBizDataCharset : {}", encoding);
|
||||
|
||||
// for(String key:itemMap.keySet()) {
|
||||
// logger.debug("~ itemMap : {} => {}", key, itemMap.get(key) );
|
||||
// }
|
||||
return message;
|
||||
}
|
||||
|
||||
private void traverse(StandardMessage message, StandardItem currentItem, byte[] srcbytes, String parentName
|
||||
, LinkedHashMap<String, String> itemMap){
|
||||
String fieldName = null;
|
||||
ArrayList<StandardItem> childList = null;
|
||||
StandardItem item = null;
|
||||
|
||||
int type = currentItem.getType();
|
||||
int start = message.getReadPosition();
|
||||
fieldName = genPath(parentName, currentItem.getName());
|
||||
logger.debug("<-> CALL path = " + fieldName);
|
||||
switch(type) {
|
||||
case StandardType.MESSAGE:
|
||||
childList = currentItem.getChildsList();
|
||||
for(int i=0; i<childList.size(); i++) {
|
||||
item = childList.get(i);
|
||||
logger.debug("@MESSAGE path = {}, start={}, length={}, value=[{}]", fieldName, start, item.getLength(), item.getValue());
|
||||
traverse(message, item, srcbytes, null, itemMap);
|
||||
}
|
||||
break;
|
||||
case StandardType.FIELD:
|
||||
item = currentItem; //message.findItem(fieldName, FIELD_SEPARATOR, ZERO_BASE_INDEX, true);
|
||||
//아래로직은 BIZDATA 에서 처리 하기 때문에 삭제
|
||||
// if(item.getDataType() == StandardDataType.ZZ_STRING) {
|
||||
//// start = start - item.getLength();
|
||||
// logger.debug("@FIELD path = {}, start={}, length={}, ZZ check start {}", fieldName, start, item.getLength(), item.getValue(), start);
|
||||
// // cut bizData
|
||||
// try {
|
||||
// message.cutBizData(item.getLength());
|
||||
// } catch (Exception e) {
|
||||
// logger.error("@FIELD path = {}, start={}, length={}, cutBizData Failed", fieldName, start, item.getLength(), e);
|
||||
// }
|
||||
// }
|
||||
byte[] value = cut(fieldName, srcbytes, start, item.getLength());
|
||||
item.setBytesValue(value, EncodingVar.flatEncoding);
|
||||
itemMap.put(fieldName, item.getValue());
|
||||
logger.debug("@FIELD path = {}, start={}, length={}, value=[{}]", fieldName, start, item.getLength(), item.getValue());
|
||||
start = start + item.getLength();
|
||||
message.setReadPosition(start);
|
||||
break;
|
||||
case StandardType.GROUP:
|
||||
logger.debug("@GROUP name={}, getLength={}, getRefPath={}, getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getLength(), currentItem.getRefPath(), currentItem.getRefValue());
|
||||
if( currentItem.getSize() == 0
|
||||
&& StringUtils.isNotBlank(currentItem.getRefPath())
|
||||
&& StringUtils.isNotBlank(currentItem.getRefValue()) ) {
|
||||
String refItemValue = itemMap.get(currentItem.getRefPath());
|
||||
|
||||
logger.debug("@GROUP name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getRefPath(), refItemValue, currentItem.getRefValue());
|
||||
|
||||
if(refItemValue != null) refItemValue = refItemValue.trim();
|
||||
|
||||
/*
|
||||
* 값의 경우의수 NR,ER,""(blank)
|
||||
* ER이 아닐경우 표현하고 싶어서 ! 를 추가했음
|
||||
* 원칙으로는 NR을 넣었을경우에는 NR 이 있을경우에만 해당됨
|
||||
* !ER일경우에는 blank와 NR일 경우에 해당됨
|
||||
*/
|
||||
String refValue = currentItem.getRefValue();
|
||||
if (refValue.startsWith("!")) { // 느낌표가 들어가면 다음에 나오는게 아닌경우
|
||||
refValue = refValue.substring(1);
|
||||
if (refValue.equals(refItemValue)) {
|
||||
logger.warn("@GROUP name={} SKIPPED.", currentItem.getName());
|
||||
currentItem.setHidden(true);
|
||||
break;
|
||||
} else {
|
||||
currentItem.setHidden(false);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!currentItem.getRefValue().equals(refItemValue)) {
|
||||
logger.warn("@GROUP name={} SKIPPED.", currentItem.getName());
|
||||
currentItem.setHidden(true);
|
||||
break;
|
||||
} else {
|
||||
currentItem.setHidden(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
childList = currentItem.getChildsList();
|
||||
for(int i=0; i<childList.size(); i++) {
|
||||
item = childList.get(i);
|
||||
logger.debug("@GROUP item={}, path = {}, start={}, length={}, value=[{}]", item.getName(), fieldName, start, item.getLength(), item.getValue());
|
||||
traverse(message, item, srcbytes, fieldName, itemMap);
|
||||
}
|
||||
if( currentItem.getSize() == 0) {
|
||||
currentItem.setSize(1);
|
||||
}
|
||||
break;
|
||||
case StandardType.GRID:
|
||||
logger.debug("@GRID name={}, getLength={}, getRefPath={}, getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getLength(), currentItem.getRefPath(), currentItem.getRefValue());
|
||||
if( currentItem.getSize() == 0
|
||||
&& (StringUtils.isNotBlank(currentItem.getRefPath())
|
||||
|| StringUtils.isNotBlank(currentItem.getRefValue())) ) {
|
||||
String refItemValue = "";
|
||||
if (StringUtils.isNotBlank(currentItem.getRefPath())) {
|
||||
refItemValue = itemMap.get(currentItem.getRefPath());
|
||||
currentItem.setRefValue(refItemValue);
|
||||
} else {
|
||||
refItemValue = currentItem.getRefValue();
|
||||
}
|
||||
currentItem.setSize(NumberUtils.toInt(StringUtils.trim(refItemValue)));
|
||||
|
||||
logger.debug("@GRID name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getRefPath(), refItemValue, currentItem.getRefValue());
|
||||
|
||||
if( !currentItem.getRefValue().equals(refItemValue) ) {
|
||||
logger.warn("@GRID name={} SKIPPED.", currentItem.getName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
int arraySize = currentItem.getSize();
|
||||
for(int ai = 0; ai<arraySize; ai++) {
|
||||
LinkedHashMap<String, StandardItem> map = currentItem.getArrayChilds(ai, true);
|
||||
if(map == null) {
|
||||
logger.warn("Array create failed item path = {}", fieldName +"[" + ai +"]");
|
||||
continue;
|
||||
}
|
||||
childList = new ArrayList<StandardItem>(map.values());
|
||||
for(int i=0; i<childList.size(); i++) {
|
||||
item = childList.get(i);
|
||||
logger.debug("@ARRAY parent path = {}, item={}, start={}, length={}, current value=[{}]", fieldName+"[" + ai +"]", item.getName(), start, item.getLength(), item.getValue());
|
||||
traverse(message, item, srcbytes, fieldName +"[" + ai +"]", itemMap);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case StandardType.FARRAY:
|
||||
logger.debug("@FARRAY name={}, getLength={}, getRefPath={}, getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getLength(), currentItem.getRefPath(), currentItem.getRefValue());
|
||||
|
||||
int farraySize = currentItem.getSize();
|
||||
item = currentItem; //message.findItem(fieldName, FIELD_SEPARATOR, ZERO_BASE_INDEX, true);
|
||||
for(int ai = 0; ai<farraySize; ai++) {
|
||||
//아래로직은 BIZDATA 에서 처리 하기 때문에 삭제
|
||||
// if(item.getDataType() == StandardDataType.ZZ_STRING) {
|
||||
// start = start - item.getLength();
|
||||
// logger.debug("@FARRAY path = {}, start={}, length={}, ZZ check start {}", fieldName, start, item.getLength(), item.getValue(), start);
|
||||
// // cut bizData
|
||||
// try {
|
||||
// message.cutBizData(item.getLength());
|
||||
// } catch (Exception e) {
|
||||
// logger.error("@FARRAY path = {}, start={}, length={}, cutBizData Failed", fieldName, start, item.getLength(), e);
|
||||
// }
|
||||
// }
|
||||
value = cut(fieldName, srcbytes, start, item.getLength());
|
||||
item.addBytesValue(value);
|
||||
|
||||
itemMap.put(fieldName, item.getValue());
|
||||
logger.debug("@FARRAY path = {}, start={}, length={}, value=[{}]", fieldName, start, item.getLength(), item.getValue());
|
||||
start = start + item.getLength();
|
||||
message.setReadPosition(start);
|
||||
}
|
||||
break;
|
||||
case StandardType.BIZDATA:
|
||||
// FIX-ME : how to calculate bzi data size ?
|
||||
// current : bizData is last item in layout items (variable size)
|
||||
item = message.findItem(fieldName, FIELD_SEPARATOR, ZERO_BASE_INDEX, true);
|
||||
int bizDataSize = item.getLength();
|
||||
int zzLength = 0;
|
||||
String zzDataPath = message.getZzDataPath();
|
||||
if(StringUtils.isNotEmpty(zzDataPath)) {
|
||||
try {
|
||||
StandardItem zzItem = message.findItem(zzDataPath);
|
||||
if(zzItem != null) {
|
||||
zzLength = zzItem.getLength();
|
||||
}
|
||||
}
|
||||
catch(Exception ex) {
|
||||
logger.warn("ZzData check error", ex);
|
||||
}
|
||||
}
|
||||
if(bizDataSize == 0) {
|
||||
bizDataSize = srcbytes.length - start - zzLength;
|
||||
}
|
||||
byte[] bizDataBytes = cut(fieldName, srcbytes, start, bizDataSize);
|
||||
|
||||
item.setBytesValue(bizDataBytes, EncodingVar.flatEncoding);
|
||||
|
||||
itemMap.put(fieldName, item.getValue());
|
||||
logger.debug("@BIZDATA path = {}, start={}, length={}, value=[{}]", fieldName, start, item.getLength(), item.getValue());
|
||||
start = start + bizDataSize;
|
||||
message.setReadPosition(start);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String genPath(String parent, String nodeName) {
|
||||
if(parent == null || parent.length() < 1) {
|
||||
return nodeName;
|
||||
}
|
||||
return parent + FIELD_SEPARATOR + nodeName;
|
||||
}
|
||||
|
||||
private static byte[] cut(String fieldName, byte[] srcBytes, int start, int length) {
|
||||
if (srcBytes == null) {
|
||||
return null;
|
||||
}
|
||||
if (srcBytes.length < (start+length)) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("item="+ fieldName);
|
||||
sb.append(", cut failed(underflow) - start index=" + start);
|
||||
sb.append(", item length=" + length);
|
||||
sb.append(", total size=" + srcBytes.length);
|
||||
throw new RuntimeException(sb.toString());
|
||||
}
|
||||
|
||||
byte[] result = new byte[length];
|
||||
int end = start + length;
|
||||
int p=0;
|
||||
for (int i = start; i < end; i++) {
|
||||
result[p] = srcBytes[i];
|
||||
p++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// public static void main(String[] args) {
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
package com.eactive.eai.message.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.eactive.eai.message.EncodingVar;
|
||||
import com.eactive.eai.message.StandardItem;
|
||||
import com.eactive.eai.message.StandardMessage;
|
||||
import com.eactive.eai.message.StandardType;
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeType;
|
||||
|
||||
public class JsonReader implements StandardReader {
|
||||
static Logger logger = LoggerFactory.getLogger(JsonReader.class);
|
||||
private char FIELD_SEPARATOR = '.';
|
||||
private boolean ZERO_BASE_INDEX = true;
|
||||
|
||||
public JsonReader() {
|
||||
|
||||
}
|
||||
|
||||
public StandardMessage parse(StandardMessage message, Object obj) throws Exception {
|
||||
String jsonString;
|
||||
if (obj instanceof byte[]) {
|
||||
jsonString = new String((byte[]) obj, EncodingVar.jsonEncoding);
|
||||
} else {
|
||||
jsonString = (String) obj;
|
||||
}
|
||||
|
||||
JsonNode jsonNode = null;
|
||||
ObjectMapper mapper = null;
|
||||
JsonFactory factory = null;
|
||||
JsonParser parser = null;
|
||||
mapper = new ObjectMapper();
|
||||
mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
|
||||
factory = mapper.getFactory();
|
||||
try {
|
||||
parser = factory.createParser(jsonString);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
jsonNode = mapper.readTree(parser);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
|
||||
// ArrayList<StandardItem> list = message.toList();
|
||||
// for(int i=0; i<list.size(); i++) {
|
||||
// StandardItem item = list.get(i);
|
||||
// logger.debug( i + " - "+ item.getLevel() + " : " +item.getName());
|
||||
// }
|
||||
// ArrayList<StandardItem> childList = message.getChildsList();
|
||||
// int i=0;
|
||||
// for(StandardItem item:childList) {
|
||||
// logger.debug( i++ + " - "+ item.getLevel() + " : " +item.getName());
|
||||
// jsonNode.get(item.getName());
|
||||
// }
|
||||
|
||||
// make json map(path, value)
|
||||
LinkedHashMap<String, String> itemMap = new LinkedHashMap<String, String>();
|
||||
traverse(message, jsonNode, null, itemMap);
|
||||
|
||||
// for(String key:itemMap.keySet()) {
|
||||
// logger.debug("~ itemMap : " + key + " => " + itemMap.get(key));
|
||||
// }
|
||||
return message;
|
||||
}
|
||||
|
||||
private void traverse(StandardMessage message, JsonNode currentNode, String parentName, LinkedHashMap<String, String> itemMap){
|
||||
StandardItem currentItem = null;
|
||||
String fieldName = null;
|
||||
if(parentName != null) {
|
||||
if(logger.isDebugEnabled()) logger.debug("$ findItem :: findItem="+ parentName);
|
||||
currentItem = message.findItem(parentName, FIELD_SEPARATOR, ZERO_BASE_INDEX, true);
|
||||
if(currentItem == null) {
|
||||
if(logger.isDebugEnabled()) logger.debug("$ SKIP :: undefined path in StandardMessage node name="+ parentName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(currentNode == null) {
|
||||
if(logger.isDebugEnabled()) logger.debug("$ SKIP :: node is NULL name="+ parentName);
|
||||
return;
|
||||
}
|
||||
|
||||
if( currentItem!=null && currentItem.getType() == StandardType.BIZDATA) {
|
||||
String bizData = null;
|
||||
if(currentNode.getNodeType() == JsonNodeType.STRING) {
|
||||
bizData = currentNode.asText();
|
||||
}
|
||||
else {
|
||||
bizData = currentNode.toString();
|
||||
}
|
||||
itemMap.put(parentName , bizData);
|
||||
currentItem.setValue(bizData);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(currentNode.getNodeType()) {
|
||||
case OBJECT:
|
||||
if( currentItem != null && currentItem.getSize() == 0
|
||||
&& StringUtils.isNotBlank(currentItem.getRefPath())
|
||||
&& StringUtils.isNotBlank(currentItem.getRefValue()) ) {
|
||||
String refItemValue = itemMap.get(currentItem.getRefPath());
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("@GROUP name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]",
|
||||
currentItem.getName(), currentItem.getRefPath(), refItemValue,
|
||||
currentItem.getRefValue());
|
||||
|
||||
if (refItemValue != null) refItemValue = refItemValue.trim();
|
||||
String refValue = currentItem.getRefValue();
|
||||
if (refValue.startsWith("!")) { // 느낌표가 들어가면 다음에 나오는게 아닌경우
|
||||
refValue = refValue.substring(1);
|
||||
if (refValue.equals(refItemValue)) {
|
||||
logger.warn("@GROUP name={} SKIPPED.", currentItem.getName());
|
||||
currentItem.setHidden(true);
|
||||
break;
|
||||
} else {
|
||||
currentItem.setHidden(false);
|
||||
}
|
||||
} else {
|
||||
if (!currentItem.getRefValue().equals(refItemValue)) {
|
||||
if (logger.isDebugEnabled())
|
||||
logger.warn("@GROUP name={} SKIPPED.", currentItem.getName());
|
||||
currentItem.setHidden(true);
|
||||
break;
|
||||
} else {
|
||||
currentItem.setHidden(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Iterator<String> fieldNames = currentNode.fieldNames();
|
||||
while(fieldNames.hasNext()) {
|
||||
fieldName = fieldNames.next();
|
||||
JsonNode fieldValue = currentNode.get(fieldName);
|
||||
fieldName = genPath(parentName, fieldName);
|
||||
traverse(message, fieldValue, fieldName, itemMap);
|
||||
}
|
||||
if(currentItem != null && currentItem.getSize() == 0) {
|
||||
currentItem.setSize(1);
|
||||
}
|
||||
break;
|
||||
case ARRAY:
|
||||
if(logger.isDebugEnabled()) logger.debug("@ARRAY name={}, getLength={}, getRefPath={}, getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getLength(), currentItem.getRefPath(), currentItem.getRefValue());
|
||||
if( currentItem != null && currentItem.getSize() == 0
|
||||
&& StringUtils.isNotBlank(currentItem.getRefPath())
|
||||
&& StringUtils.isNotBlank(currentItem.getRefValue()) ) {
|
||||
String refItemValue = itemMap.get(currentItem.getRefPath());
|
||||
|
||||
if(logger.isDebugEnabled()) logger.debug("@ARRAY name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getRefPath(), refItemValue, currentItem.getRefValue());
|
||||
|
||||
if( !currentItem.getRefValue().equals(refItemValue) ) {
|
||||
if(logger.isDebugEnabled()) logger.warn("@ARRAY name={} SKIPPED.", currentItem.getName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
ArrayNode arrayNode = (ArrayNode) currentNode;
|
||||
for(int i = 0; i < arrayNode.size(); i++) {
|
||||
JsonNode arrayElement = arrayNode.get(i);
|
||||
traverse(message, arrayElement, parentName+"["+ i+"]", itemMap);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if(logger.isDebugEnabled()) logger.debug("parsing : " + parentName + "=" +currentNode.asText());
|
||||
itemMap.put(parentName , currentNode.asText());
|
||||
if(currentItem.getType() == StandardType.FARRAY) {
|
||||
currentItem.addValue(currentNode.asText());
|
||||
}
|
||||
else {
|
||||
currentItem.setValue(currentNode.asText());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private String genPath(String parent, String nodeName) {
|
||||
if(parent == null || parent.length() < 1) {
|
||||
return nodeName;
|
||||
}
|
||||
return parent +FIELD_SEPARATOR + nodeName;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.eactive.eai.message.parser;
|
||||
|
||||
public interface ReaderType {
|
||||
public final String FLAT = "FLAT";
|
||||
public final String ASC = "ASC";
|
||||
public final String XML = "XML";
|
||||
public final String UXML = "UXL";
|
||||
public final String JSON = "JSN";
|
||||
public final String UJSON = "UJN";
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.eactive.eai.message.parser;
|
||||
|
||||
import com.eactive.eai.message.StandardMessage;
|
||||
|
||||
public interface StandardReader {
|
||||
public StandardMessage parse(StandardMessage message, Object data) throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package com.eactive.eai.message.parser;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dom4j.Attribute;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.Node;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.eactive.eai.message.EncodingVar;
|
||||
import com.eactive.eai.message.StandardItem;
|
||||
import com.eactive.eai.message.StandardMessage;
|
||||
import com.eactive.eai.message.StandardType;
|
||||
|
||||
public class XmlReader implements StandardReader {
|
||||
static Logger logger = LoggerFactory.getLogger(XmlReader.class);
|
||||
private char FIELD_SEPARATOR = '/'; // XML use /
|
||||
private boolean ZERO_BASE_INDEX = false; // 1 base
|
||||
|
||||
private boolean BIZDATA_NAME_INCLUDE = true;
|
||||
|
||||
public XmlReader() {
|
||||
|
||||
}
|
||||
|
||||
public StandardMessage parse(StandardMessage message, Object obj) throws Exception {
|
||||
String xmlString;
|
||||
if (obj instanceof byte[]) {
|
||||
xmlString = new String((byte[]) obj, EncodingVar.xmlEncoding);
|
||||
} else {
|
||||
xmlString = (String) obj;
|
||||
}
|
||||
|
||||
org.dom4j.io.SAXReader saxReader = new org.dom4j.io.SAXReader();
|
||||
org.dom4j.Document document = null;
|
||||
try {
|
||||
document = saxReader.read(new StringReader(xmlString));
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
org.dom4j.Element root = document.getRootElement();
|
||||
// ArrayList<StandardItem> list = message.toList();
|
||||
// for(int i=0; i<list.size(); i++) {
|
||||
// StandardItem item = list.get(i);
|
||||
// logger.debug( i + " - "+ item.getLevel() + " : " +item.getName());
|
||||
// }
|
||||
|
||||
|
||||
// ArrayList<StandardItem> childList = message.getChildsList();
|
||||
// int i=0;
|
||||
// for(StandardItem item:childList) {
|
||||
// logger.debug( i++ + " - "+ item.getLevel() + " : " +item.getName());
|
||||
// jsonNode.get(item.getName());
|
||||
// }
|
||||
|
||||
// make json map(path, value)
|
||||
LinkedHashMap<String, String> itemMap = new LinkedHashMap<String, String>();
|
||||
String rootName = root.getName();
|
||||
message.setName(rootName);
|
||||
traverse(message, root, null, itemMap);
|
||||
// for(String key:itemMap.keySet()) {
|
||||
// logger.debug("~ itemMap : " + key + " => " + itemMap.get(key));
|
||||
// }
|
||||
return message;
|
||||
}
|
||||
|
||||
private String getContent(org.dom4j.Element element) {
|
||||
if (element.isTextOnly())
|
||||
return element.getText();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Element currElement = null;
|
||||
Iterator<org.dom4j.Element> iterator = element.elementIterator();
|
||||
while( iterator.hasNext() ) {
|
||||
currElement = iterator.next();
|
||||
sb.append(currElement.asXML());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void traverse(StandardMessage message, org.dom4j.Element currentNode, String parentName, LinkedHashMap<String, String> itemMap){
|
||||
StandardItem currentItem = null;
|
||||
String fullPath = null;
|
||||
String fieldName = null;
|
||||
if(currentNode == null) {
|
||||
if(logger.isDebugEnabled()) logger.debug("$ SKIP :: node is NULL name="+ parentName);
|
||||
return;
|
||||
}
|
||||
Iterator<org.dom4j.Element> i = currentNode.elementIterator();
|
||||
while (i.hasNext()) {
|
||||
org.dom4j.Element child = (org.dom4j.Element) i.next();
|
||||
// if necessary, uncomment below 2 lines.
|
||||
// QName qn = new QName(child.getName(),Namespace.NO_NAMESPACE);
|
||||
// child.setQName(qn);
|
||||
|
||||
fullPath = child.getUniquePath();
|
||||
fieldName = lastNodeName(fullPath);
|
||||
|
||||
fieldName = genPath(parentName, fieldName);
|
||||
currentItem = message.findItem(fieldName, FIELD_SEPARATOR, ZERO_BASE_INDEX, true);
|
||||
if(currentItem == null) continue;
|
||||
|
||||
if(currentItem.getType() == StandardType.BIZDATA) {
|
||||
String bizData = null;
|
||||
if(BIZDATA_NAME_INCLUDE)
|
||||
bizData = getContent(child);
|
||||
else
|
||||
bizData = child.asXML();
|
||||
|
||||
itemMap.put(fieldName , bizData);
|
||||
currentItem.setValue(bizData);
|
||||
// item.setBizData(bizData);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(child.getNodeType()) {
|
||||
case Node.ELEMENT_NODE:
|
||||
if(logger.isDebugEnabled()) logger.debug("$ ELEMENT_NODE name="+ fieldName + ", fullPath="+ fullPath+ ", value="+ child.getStringValue());
|
||||
if(currentItem.getType() == StandardType.FIELD) {
|
||||
itemMap.put(fieldName , child.getStringValue());
|
||||
currentItem.setValue(child.getStringValue());
|
||||
}
|
||||
else if(currentItem.getType() == StandardType.FARRAY) {
|
||||
itemMap.put(fieldName , child.getStringValue());
|
||||
currentItem.addValue(child.getStringValue());
|
||||
}
|
||||
else {
|
||||
if(logger.isDebugEnabled()) logger.debug("@GROUP name={}, getLength={}, getRefPath={}, getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getLength(), currentItem.getRefPath(), currentItem.getRefValue());
|
||||
if( currentItem.getSize() == 0
|
||||
&& StringUtils.isNotBlank(currentItem.getRefPath())
|
||||
&& StringUtils.isNotBlank(currentItem.getRefValue()) ) {
|
||||
String refItemValue = null;
|
||||
StandardItem refItem = message.findItem(currentItem.getRefPath(), '.', true, false);
|
||||
if(refItem != null) {
|
||||
refItemValue = refItem.getValue();
|
||||
}
|
||||
|
||||
if(logger.isDebugEnabled()) logger.debug("@GROUP name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getRefPath(), refItemValue, currentItem.getRefValue());
|
||||
|
||||
if( !currentItem.getRefValue().equals(refItemValue) ) {
|
||||
if(logger.isDebugEnabled()) logger.warn("@GROUP name={} SKIPPED.", currentItem.getName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
int attrCnt = child.attributeCount();
|
||||
for (int ai=0; ai<attrCnt; ai++) {
|
||||
Attribute at = child.attribute(ai);
|
||||
String atPath = genPath(fieldName, at.getName());
|
||||
if(logger.isDebugEnabled()) logger.debug("@ ATTRIBUTE name="+ atPath + ", fullPath="+ at.getUniquePath()+ ", value="+ at.getStringValue());
|
||||
StandardItem attrItem = message.findItem(atPath, FIELD_SEPARATOR, ZERO_BASE_INDEX, true);
|
||||
itemMap.put(atPath, at.getStringValue());
|
||||
attrItem.setValue(at.getStringValue());
|
||||
}
|
||||
if( currentItem.getSize() == 0) {
|
||||
currentItem.setSize(1);
|
||||
}
|
||||
traverse(message, child, fieldName, itemMap);
|
||||
}
|
||||
break;
|
||||
case Node.TEXT_NODE:
|
||||
if(logger.isDebugEnabled()) logger.debug("$ TEXT_NODE value="+ child.getStringValue());
|
||||
break;
|
||||
default:
|
||||
if(logger.isDebugEnabled()) logger.debug("$ type="+ child.getNodeType() + ", name=" + fieldName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String genPath(String parent, String nodeName) {
|
||||
if(parent == null || parent.length() < 1) {
|
||||
return nodeName;
|
||||
}
|
||||
return parent + FIELD_SEPARATOR + nodeName;
|
||||
}
|
||||
|
||||
protected String lastNodeName(String xpath) {
|
||||
String itemPath = null;
|
||||
int sepPosition = xpath.lastIndexOf(FIELD_SEPARATOR);
|
||||
if(sepPosition < 0) {
|
||||
return xpath;
|
||||
}
|
||||
itemPath = xpath.substring(sepPosition+1);
|
||||
|
||||
return itemPath;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user