diff --git a/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java b/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java index 8957d22..e708fe3 100644 --- a/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java +++ b/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java @@ -10,6 +10,7 @@ import org.apache.commons.lang3.StringUtils; import com.eactive.eai.transformer.SystemKeys; import com.eactive.eai.transformer.layout.Converter; +import com.eactive.eai.transformer.layout.Group; import com.eactive.eai.transformer.layout.InvalidNodeException; import com.eactive.eai.transformer.layout.Item; import com.eactive.eai.transformer.layout.Types; @@ -18,6 +19,7 @@ import com.eactive.eai.transformer.util.Logger; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.json.JsonReadFeature; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -37,22 +39,24 @@ public class JSONMessage extends Message { protected JsonNode data; protected ObjectMapper mapper = null; protected JsonFactory factory = null; - protected boolean bStaled = false; + protected boolean bStaled = true; public JSONMessage() { super(); mapper = new ObjectMapper(); // if necessary, add proper options -> use system property config ? - mapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); + mapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); mapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS); mapper.setNodeFactory(JsonNodeFactory.withExactBigDecimals(true)); - + factory = mapper.getFactory(); + factory.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true); } @Override public void createObject() { - data = mapper.createObjectNode(); +// data = mapper.createObjectNode(); + data = null; } @Override @@ -98,59 +102,28 @@ public class JSONMessage extends Message { throw new InvalidDataTypeException("Not able to generate JSON messages with data. data type = " + data.getClass().getName(), data); } } - - if (this.data == null) { - logger.error("Parsed data is null"); - return; - } - - //ObjectNode node = (ObjectNode) this.data.get(getName()); - /* - if(node == null) { + + ObjectNode node = (ObjectNode) this.data.get(getName()); + if(node == null) { // if layoutname not appended - setValue(this.data, getName()); + setValue(this.data, getName()); } else { - setValue(node, getName()); + setValue(node, getName()); } - */ - - ObjectNode node = null; - - // 변경된 부분: NullNode 검사 추가 - if (this.data.has(getName()) && !this.data.get(getName()).isNull()) { - JsonNode nameNode = this.data.get(getName()); - if (nameNode.isObject()) { - node = (ObjectNode) nameNode; - - // 배열 데이터 처리 개선 - processArrayNodes(this.data); - - // 값 설정 - setValue(node, getName()); - } else { - logger.warn("Node with name '" + getName() + "' is not an object, skipping setValue operation"); - } - } else { - // layoutname이 추가되지 않은 경우 - setValue(this.data, getName()); - } - } catch (Exception e) { throw new MessageSetDataException(e.getMessage(), this, data, e); } } - public void setValue(JsonNode node, String itempPath) throws InvalidAccessException { - + public void setValue(JsonNode node, String itempPath) throws InvalidAccessException { try { // this.value = Converter.convert(value, getDataTypeId()); /** * occRef 설정을 위해 */ - HashMap validationTargets = new HashMap(); - + HashMap validationTargets = new HashMap(); doSetValue(node, validationTargets, itempPath); // validation @@ -172,22 +145,33 @@ public class JSONMessage extends Message { } catch(Exception e) { throw new InvalidAccessException("setValue error", getItemPath(), null, e); } - } + } - protected void doSetValue(JsonNode node, HashMap validationTargets, String parentPath) { + protected void doSetValue(JsonNode node, HashMap validationTargets, String parentPath) { Item item = null; - + if (node.isNull()) { + // null이면 타겟 형식에서 Grid인지 확인 해 봄 + String itemPath = parentPath + "[-1]"; + item = this.getItem(itemPath); + if (item != null && item instanceof Group && StringUtils.equalsAny(item.getOccType(), "*", "+")) { + item = getOrCreateItem(denomalizeXPath(parentPath)); + if (item != null) { + item.setIndex(-1); + } + } + return; + } if( node.isObject()) { - Iterator fieldNames = node.fieldNames(); + Iterator fieldNames = node.fieldNames(); if(StringUtils.isNotEmpty(parentPath)) { - item = getOrCreateItem(denomalizeXPath(parentPath)); + item = getOrCreateItem(denomalizeXPath(parentPath)); + if(SystemKeys.isValidationEnabled() && StringUtils.isNotEmpty(item.getOccRef())) { validationTargets.put(item.getParent().getItemPath() + Types.FIELD_SEPARATOR + item.getOccRef(), item); } } while(fieldNames.hasNext()) { String fieldName = fieldNames.next(); - JsonNode fieldValue = node.get(fieldName); try { String path = null; @@ -206,58 +190,42 @@ public class JSONMessage extends Message { } else if( node.isArray() ) { ArrayNode arrayNode = (ArrayNode) node; - - // 배열이 문자열 값만 포함하는지 확인 - boolean isSimpleArray = true; - for (int i = 0; i < arrayNode.size(); i++) { - if (!arrayNode.get(i).isValueNode()) { - isSimpleArray = false; - break; + if(arrayNode.size() == 0 && StringUtils.isNotEmpty(parentPath)) { + try { + // 아직 clone 되지 않았으면 생성 안함. + item = this.getItem(denomalizeXPath(parentPath)); + if (item != null) { + // clone 후에는 -1로 + item = getOrCreateItem(denomalizeXPath(parentPath)); + if (item != null) { + item.setIndex(-1); + } + } + } catch (InvalidNodeException ie) { + // continue silently + } + } + for(int i = 0; i < arrayNode.size(); i++) { + JsonNode arrayItem = arrayNode.get(i); + if(StringUtils.isNotEmpty(parentPath)) { + try { + item = getOrCreateItem(denomalizeXPath(parentPath + "[" + i + "]")); + } catch(InvalidNodeException ie) { + continue; + } } - } - - if (isSimpleArray) { - // 문자열 배열은 직접 값 설정 - try { - setString(parentPath, arrayNode.toString()); - } catch (Exception e) { - logger.error("Error setting simple array: " + parentPath, e); - // 개별 요소 설정 - for (int i = 0; i < arrayNode.size(); i++) { - try { - String itemPath = parentPath + "[" + i + "]"; - setString(itemPath, arrayNode.get(i).asText()); - } catch (Exception ex) { - logger.error("Error setting array item: " + parentPath + "[" + i + "]", ex); - } - } - } - } else { - // 복잡한 배열 구조 처리 - for (int i = 0; i < arrayNode.size(); i++) { - JsonNode arrayItem = arrayNode.get(i); - - if (StringUtils.isNotEmpty(parentPath)) { - try { - item = getOrCreateItem(denomalizeXPath(parentPath + "[" + i + "]")); - } catch (InvalidNodeException ie) { - continue; - } - } - doSetValue(arrayItem, validationTargets, parentPath + "[" + i + "]"); - } - } + doSetValue(arrayItem, validationTargets, parentPath + "[" + i + "]"); + } } - else { + else { String itemPath = parentPath; item = getOrCreateItem(denomalizeXPath(itemPath)); String value = node.asText(); - - if(node == null || node.isNull()) { - setObject(itemPath, null); // 실제 null 값 설정 - } else if(value == null || value.length() == 0) { + if (node.isNull()) return; + if(value == null || value.length() == 0) { setObject( itemPath, value ); - } else { + } + else { int itemType = item.getDataTypeId(); try { switch(itemType) { @@ -283,12 +251,12 @@ public class JSONMessage extends Message { case Types.TYPE_FLOAT : setFloat( itemPath, new Float(value) ); break; - case Types.TYPE_BOOLEAN : + case Types.TYPE_BOOLEAN : setObject( itemPath, new Boolean(value) ); break; case Types.TYPE_STRING : setString(itemPath, value); - break; + break; default : setString(itemPath, value); break; @@ -370,9 +338,8 @@ public class JSONMessage extends Message { if( parent instanceof ObjectNode ) { obj = (ObjectNode)parent; - String val = getStringValue(item.getValue(),item); - int itemType = item.getDataTypeId(); - + String val = getStringValue(item.getValue(),item); + int itemType = item.getDataTypeId(); if (isMask && "Y".equals(item.getMask()) && (Types.TYPE_STRING == itemType )){ val = maskString2(val, item.getMaskLength(), item.getMaskOffset()); item.setValue(val); @@ -385,8 +352,9 @@ public class JSONMessage extends Message { arr = mapper.createArrayNode(); setJsonArrayValue(arr, item); obj.set(prefix+item.getName(), arr); - }else{ - arr.add(value); + }else{ +// arr.add(value); + setJsonArrayValue(arr, item); //IBK에서 사용. } } else { //FIELD @@ -418,7 +386,7 @@ public class JSONMessage extends Message { logger.error("not support parent type JSONArray"); throw new Exception("not support parent type JSONArray"); } - if (item.getChildCount() > 0){ + if (item.getChildCount() > 0 ){ stack.push(current); } break; @@ -443,38 +411,11 @@ public class JSONMessage extends Message { private void setJsonNodeValue(ObjectNode node, String fieldName, Item item) { int itemType = item.getDataTypeId(); Object value = item.getValue(); - + if(value == null) { node.putNull(fieldName); return; } - - if(value instanceof JsonNode) { - node.set(fieldName, (JsonNode) value); - return; - } - - // New code to check if string is JSON array - if (itemType == Types.TYPE_STRING && value instanceof String) { - String strValue = (String) value; - if ((strValue.startsWith("[") && strValue.endsWith("]")) || - (strValue.startsWith("{") && strValue.endsWith("}"))) { - try { - // Try to parse as JSON - JsonNode jsonNode = mapper.readTree(strValue); - node.set(fieldName, jsonNode); - return; - } catch (Exception e) { - // Not valid JSON, continue with normal processing - logger.debug("Failed to parse as JSON, using as string: " + e.getMessage()); - } - } - } - - if (!(value instanceof byte[])) { - logger.info("value : " + value.toString()); - } - switch(itemType) { case Types.TYPE_INT : case Types.TYPE_SHORT : @@ -484,8 +425,9 @@ public class JSONMessage extends Message { node.put(fieldName, (long) value); break; case Types.TYPE_BIGDECIMAL : - BigDecimal bd = (BigDecimal)value; - node.put(fieldName, bd); +// BigDecimal bd = (BigDecimal)value; +// node.put(fieldName, bd.floatValue()); + node.put(fieldName, (BigDecimal)value); break; case Types.TYPE_DOUBLE : node.put(fieldName, (double) value); @@ -497,12 +439,7 @@ public class JSONMessage extends Message { node.put(fieldName, (boolean) value); break; case Types.TYPE_STRING : - node.put(fieldName, (String) value); - if (value instanceof JsonNode) { - logger.info("value : " + (String) value ); - } - break; default : node.put(fieldName, (String) value); @@ -524,13 +461,13 @@ public class JSONMessage extends Message { arrayNode.add( (long) value); break; case Types.TYPE_BIGDECIMAL : - arrayNode.add( (float) value); + arrayNode.add( (BigDecimal)value); break; case Types.TYPE_DOUBLE : arrayNode.add( (double) value); break; case Types.TYPE_FLOAT : - arrayNode.add( (float) value); + arrayNode.add( (float) value); break; case Types.TYPE_BOOLEAN : arrayNode.add( (boolean) value); @@ -539,7 +476,7 @@ public class JSONMessage extends Message { arrayNode.add( (String) value); break; default : - arrayNode.add( (String) value); + arrayNode.add( (String) value); } } @@ -583,8 +520,7 @@ public class JSONMessage extends Message { } @Override public Object getData() { - - if (bStaled) { + if (bStaled || this.data == null) { try { this.data = getJSONData(); } catch(Exception e) { @@ -604,7 +540,6 @@ public class JSONMessage extends Message { return null; } if(this.data == null) return null; - if(isPretty) return data.toPrettyString(); else return data.toString(); } @@ -703,6 +638,36 @@ public class JSONMessage extends Message { } } + private boolean isValid(String value,int length,int pointLength){ + String[] data = value.replaceAll(" ", "").split("[.]"); + if (pointLength > 0 ){ + if (data.length ==1){ + if (data[0].length() > length - pointLength - 1 ){ //정수부 오류 + return false; + } + }else if (data.length ==2){ + if (data[0].length() > length - pointLength - 1 ){ //정수부 오류 + return false; + } + if (data[1].length() > pointLength ){ //실수부 오류 + return false; + } + }else{ + //오류 + return false; + } + + }else{ + if (data.length != 1){ //소수점이 들어와서 오류 + return false; + } + if (data[0].length() > length - pointLength - 1){ //정수부 오류 + return false; + } + } + return true; + } + // private Object toJsonObjectType(int itemType, String value) { // Object jsonValueObject = null; // @@ -735,71 +700,12 @@ public class JSONMessage extends Message { private String getHeader() { return getName() + " (" + MESSAGE_NAME + ")"; } - - // 배열 처리 메소드 - private void processArrayNodes(JsonNode rootNode) { - Iterator fieldNames = rootNode.fieldNames(); - while (fieldNames.hasNext()) { - String fieldName = fieldNames.next(); - JsonNode node = rootNode.get(fieldName); - - // data_part와 같은 객체 노드 처리 - if (node.isObject()) { - processArrayNodes(node); - } - // 배열 노드 처리 - else if (node.isArray()) { - ArrayNode arrayNode = (ArrayNode) node; - - // 배열 노드 처리 - if (arrayNode.size() > 0) { - // 배열 데이터 설정 - try { - - if(this.data instanceof ObjectNode) { - ObjectNode objNode = (ObjectNode) this.data; - objNode.set(fieldName, arrayNode); - } else if (rootNode instanceof ObjectNode) { - ((ObjectNode) rootNode).set(fieldName, arrayNode); - } - - for(int i=0; i < arrayNode.size(); i++) { - JsonNode itemNode = arrayNode.get(i); - - String itemPath = fieldName + "[" + i + "]"; - - if(itemNode.isObject()) { - processArrayNodes(itemNode); - } - } - - } catch (Exception e) { - logger.error("Error setting array data for field: " + fieldName, e); - // 배열 요소를 개별적으로 처리 - for (int i = 0; i < arrayNode.size(); i++) { - try { - String itemPath = fieldName + "[" + i + "]"; - JsonNode itemNode = arrayNode.get(i); - if (itemNode.isTextual()) { - setString(itemPath, itemNode.asText()); - } else { - setString(itemPath, itemNode.toString()); - } - } catch (Exception ex) { - logger.error("Error setting array item [" + i + "] for field: " + fieldName, ex); - } - } - } - } - } - } - } - + public String toString(){ // if staled -> reorganize data String jsonString = null; try { - jsonString = (String)getData(); + jsonString = toLogString(); } catch (Exception e) { logger.error("[JSONMessage] " + e.getMessage(), e); }