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 list = message.toList(); // for(int i=0; i 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 itemMap = new LinkedHashMap(); 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 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 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) { // } }