EZDATA 없는데, Ref필드에는 'ERP'로 되어 있는 경우, flat 전문 파싱 오류 처리
This commit is contained in:
@@ -295,6 +295,58 @@ public class StandardItem implements Serializable, Cloneable {
|
||||
this.isHidden = isHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* 조건부 블록의 refValue 와 실제 필드값을 비교한다.
|
||||
* FlatReader / StandardMessageCoordinator 와 동일한 기준을 쓰기 위한 공용 판정 로직이다.
|
||||
* - '!' 접두사 : NOT 조건 (예: !S → S가 아닌 경우)
|
||||
* - '|' 구분자 : OR 조건 (예: NM|EM → NM 또는 EM인 경우)
|
||||
* - '!' 와 '|' 조합 가능 (예: !NM|EM → NM도 EM도 아닌 경우)
|
||||
*/
|
||||
public static boolean matchRefCondition(String refValue, String actualValue) {
|
||||
if(refValue == null) return false;
|
||||
String expect = refValue;
|
||||
boolean negate = expect.startsWith("!");
|
||||
if(negate) {
|
||||
expect = expect.substring(1);
|
||||
}
|
||||
String actual = (actualValue == null) ? null : actualValue.trim();
|
||||
boolean matched = false;
|
||||
String[] expectValues = expect.split("\\|");
|
||||
for(int i=0; i<expectValues.length; i++) {
|
||||
if(expectValues[i].equals(actual)) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return negate ? !matched : matched;
|
||||
}
|
||||
|
||||
/**
|
||||
* FLAT 직렬화 시 이 GROUP 블록의 바이트를 출력할지 판단한다.
|
||||
* FlatReader.traverse() 의 GROUP 처리와 같은 기준을 쓰기 위한 것으로,
|
||||
* ref 조건이 성립하면 size==0(전문에 블록이 없어 미활성) 이어도 레이아웃 기본값으로 출력한다.
|
||||
* 조건이 성립하는데 출력하지 않으면, 파서는 블록이 있다고 보고 읽어 오프셋이 어긋난다.
|
||||
*
|
||||
* @param root 조건 평가 기준이 되는 최상위 메시지. null 이면 조건 평가 없이 기존 규칙만 적용
|
||||
* @param parentActivated 조건 성립으로 활성화된 상위 GROUP 하위인지 여부
|
||||
*/
|
||||
protected boolean isFlatGroupActive(StandardMessage root, boolean parentActivated) {
|
||||
if(isHidden) return false;
|
||||
if(getSize() > 0) return true;
|
||||
if(root != null
|
||||
&& StringUtils.isNotBlank(getRefPath())
|
||||
&& StringUtils.isNotBlank(getRefValue())
|
||||
&& matchRefCondition(getRefValue(), root.findItemValue(getRefPath())) ) {
|
||||
if(logger.isDebugEnabled()) {
|
||||
logger.debug("@GROUP name={} ACTIVATED by ref condition({}=[{}]). size=0 이지만 FLAT 출력 대상"
|
||||
, getName(), getRefPath(), getRefValue());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// 조건 성립으로 활성화된 상위 GROUP 하위의 무조건 블록은 함께 출력한다.
|
||||
return parentActivated;
|
||||
}
|
||||
|
||||
protected String toTypeValue(String svalue) {
|
||||
if(svalue == null) return svalue;
|
||||
|
||||
@@ -1007,6 +1059,15 @@ public class StandardItem implements Serializable, Cloneable {
|
||||
}
|
||||
|
||||
public int getBytesDataLength(String charset) {
|
||||
return getBytesDataLength(charset, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param root 조건부 블록(refPath/refValue) 평가 기준이 되는 최상위 메시지
|
||||
* @param parentActivated 조건 성립으로 활성화된 상위 GROUP 하위인지 여부
|
||||
* @see #isFlatGroupActive(StandardMessage, boolean)
|
||||
*/
|
||||
public int getBytesDataLength(String charset, StandardMessage root, boolean parentActivated) {
|
||||
int totalSize = 0;
|
||||
Iterator<String> keyIter = null;
|
||||
try {
|
||||
@@ -1016,23 +1077,25 @@ public class StandardItem implements Serializable, Cloneable {
|
||||
while(keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
StandardItem item = childs.get(key);
|
||||
totalSize +=item.getBytesDataLength(charset);
|
||||
totalSize +=item.getBytesDataLength(charset, root, false);
|
||||
}
|
||||
break;
|
||||
case StandardType.FIELD :
|
||||
totalSize += getLength();
|
||||
break;
|
||||
case StandardType.GROUP :
|
||||
// skip inactive/conditional group (size==0 means not activated)
|
||||
if( getSize() == 0 ) {
|
||||
// ref 조건이 성립하면 size==0 이어도 출력한다(FlatReader 와 동일 기준)
|
||||
if( !isFlatGroupActive(root, parentActivated) ) {
|
||||
break;
|
||||
}
|
||||
if (isHidden) break;
|
||||
// 출력하는 GROUP 의 하위 무조건 블록은 함께 출력한다.
|
||||
// FlatReader 는 이 블록을 조건 없이 읽으므로 빼면 오프셋이 어긋난다.
|
||||
boolean childActivated = true;
|
||||
keyIter = childs.keySet().iterator();
|
||||
while(keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
StandardItem item = childs.get(key);
|
||||
totalSize +=item.getBytesDataLength(charset);
|
||||
totalSize +=item.getBytesDataLength(charset, root, childActivated);
|
||||
}
|
||||
break;
|
||||
case StandardType.GRID :
|
||||
@@ -1050,7 +1113,7 @@ public class StandardItem implements Serializable, Cloneable {
|
||||
while(keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
StandardItem item = group.get(key);
|
||||
totalSize +=item.getBytesDataLength(charset);
|
||||
totalSize +=item.getBytesDataLength(charset, root, false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1086,6 +1149,15 @@ public class StandardItem implements Serializable, Cloneable {
|
||||
return toByteArray(true, charset);
|
||||
}
|
||||
public byte[] toByteArray(boolean withBizData, String charset) {
|
||||
return toByteArray(withBizData, charset, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param root 조건부 블록(refPath/refValue) 평가 기준이 되는 최상위 메시지
|
||||
* @param parentActivated 조건 성립으로 활성화된 상위 GROUP 하위인지 여부
|
||||
* @see #isFlatGroupActive(StandardMessage, boolean)
|
||||
*/
|
||||
public byte[] toByteArray(boolean withBizData, String charset, StandardMessage root, boolean parentActivated) {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
Iterator<String> keyIter = null;
|
||||
// logger.debug("Encoding : {}", charset);
|
||||
@@ -1096,7 +1168,7 @@ public class StandardItem implements Serializable, Cloneable {
|
||||
while(keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
StandardItem item = childs.get(key);
|
||||
bos.write(item.toByteArray(withBizData,charset)); //하위로 내려갈때 withBizDat 값이 없어져서 추가 jun's 20231101
|
||||
bos.write(item.toByteArray(withBizData, charset, root, false)); //하위로 내려갈때 withBizDat 값이 없어져서 추가 jun's 20231101
|
||||
}
|
||||
break;
|
||||
case StandardType.FIELD :
|
||||
@@ -1118,16 +1190,18 @@ public class StandardItem implements Serializable, Cloneable {
|
||||
}
|
||||
break;
|
||||
case StandardType.GROUP :
|
||||
// skip inactive/conditional group (size==0 means not activated)
|
||||
if( getSize() == 0 ) {
|
||||
// ref 조건이 성립하면 size==0 이어도 출력한다(FlatReader 와 동일 기준)
|
||||
if( !isFlatGroupActive(root, parentActivated) ) {
|
||||
break;
|
||||
}
|
||||
if (isHidden) break;
|
||||
// 출력하는 GROUP 의 하위 무조건 블록은 함께 출력한다.
|
||||
// FlatReader 는 이 블록을 조건 없이 읽으므로 빼면 오프셋이 어긋난다.
|
||||
boolean childActivated = true;
|
||||
keyIter = childs.keySet().iterator();
|
||||
while(keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
StandardItem item = childs.get(key);
|
||||
bos.write(item.toByteArray(withBizData,charset)); //하위로 내려갈때 withBizDat 값이 없어져서 추가 jun's 20231101
|
||||
bos.write(item.toByteArray(withBizData, charset, root, childActivated)); //하위로 내려갈때 withBizDat 값이 없어져서 추가 jun's 20231101
|
||||
}
|
||||
break;
|
||||
case StandardType.GRID :
|
||||
@@ -1145,7 +1219,7 @@ public class StandardItem implements Serializable, Cloneable {
|
||||
while(keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
StandardItem item = group.get(key);
|
||||
bos.write(item.toByteArray(withBizData, charset)); //하위로 내려갈때 withBizDat 값이 없어져서 추가 jun's 20231101
|
||||
bos.write(item.toByteArray(withBizData, charset, root, false)); //하위로 내려갈때 withBizDat 값이 없어져서 추가 jun's 20231101
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -461,7 +461,8 @@ public class StandardMessage extends StandardItem {
|
||||
while(keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
StandardItem item = childs.get(key);
|
||||
bos.write(item.toByteArray(withBizData, charset));
|
||||
// this 를 root 로 넘겨 조건부 블록(refPath/refValue)을 평가하게 한다
|
||||
bos.write(item.toByteArray(withBizData, charset, this, false));
|
||||
}
|
||||
return bos.toByteArray();
|
||||
} catch(Exception e) {
|
||||
@@ -490,7 +491,7 @@ public class StandardMessage extends StandardItem {
|
||||
while(keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
StandardItem item = childs.get(key);
|
||||
totalSize +=item.getBytesDataLength(charset);
|
||||
totalSize +=item.getBytesDataLength(charset, this, false);
|
||||
}
|
||||
return totalSize;
|
||||
} catch(Exception e) {
|
||||
@@ -516,7 +517,7 @@ public class StandardMessage extends StandardItem {
|
||||
while (keyIter.hasNext()) {
|
||||
String key = keyIter.next();
|
||||
StandardItem item = find.childs.get(key);
|
||||
totalSize += item.getBytesDataLength(this.bizDataCharset);
|
||||
totalSize += item.getBytesDataLength(this.bizDataCharset, this, false);
|
||||
}
|
||||
return totalSize;
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -121,24 +121,15 @@ public class FlatReader implements StandardReader {
|
||||
logger.debug("@GROUP name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]"
|
||||
, currentItem.getName(), currentItem.getRefPath(), refItemValue, currentItem.getRefValue());
|
||||
|
||||
if(refItemValue != null) refItemValue = refItemValue.trim();
|
||||
|
||||
/*
|
||||
* 값의 경우의수 NM,EM,""(blank)
|
||||
* ! : NOT 조건 (예: !EM → EM이 아닌 경우)
|
||||
* | : OR 조건 (예: NM|EM → NM 또는 EM인 경우)
|
||||
* !와 | 조합 가능 (예: !NM|EM → NM도 아니고 EM도 아닌 경우)
|
||||
* 판정 기준은 StandardItem.matchRefCondition 하나로 통일한다.
|
||||
* (FLAT 직렬화 StandardItem.isFlatGroupActive 와 같은 기준이어야 오프셋이 어긋나지 않음)
|
||||
*/
|
||||
String refValue = currentItem.getRefValue();
|
||||
boolean isNot = refValue.startsWith("!");
|
||||
if (isNot) {
|
||||
refValue = refValue.substring(1);
|
||||
}
|
||||
|
||||
boolean matched = matchRefValue(refValue, refItemValue);
|
||||
if (isNot) {
|
||||
matched = !matched;
|
||||
}
|
||||
boolean matched = StandardItem.matchRefCondition(currentItem.getRefValue(), refItemValue);
|
||||
|
||||
if (!matched) {
|
||||
logger.warn("@GROUP name={} SKIPPED.", currentItem.getName());
|
||||
@@ -307,21 +298,4 @@ public class FlatReader implements StandardReader {
|
||||
}
|
||||
return refItemValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* refValue와 refItemValue를 비교하여 일치 여부를 반환
|
||||
* | 구분자로 OR 조건 지원 (예: "NM|EM" → "NM" 또는 "EM"과 일치하면 true)
|
||||
*/
|
||||
private boolean matchRefValue(String refValue, String refItemValue) {
|
||||
if (refValue.contains("|")) {
|
||||
String[] values = refValue.split("\\|");
|
||||
for (String val : values) {
|
||||
if (val.equals(refItemValue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return refValue.equals(refItemValue);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user