diff --git a/src/main/java/com/eactive/eai/transformer/SystemKeys.java b/src/main/java/com/eactive/eai/transformer/SystemKeys.java index ca36a2b..8d3c8c5 100644 --- a/src/main/java/com/eactive/eai/transformer/SystemKeys.java +++ b/src/main/java/com/eactive/eai/transformer/SystemKeys.java @@ -7,6 +7,7 @@ public class SystemKeys { public static final String TRANSFROMER_STRING_TRIMEND = "transformer.string.trimend"; public static final String TRANSFROMER_VALIDATION = "transformer.validation"; public static final String TRANSFROMER_DECIMALPOINT_ADD = "transformer.decimalpoint.add"; + public static final String TRANSFROMER_SCIENTIFIC_NORMALIZE = "transformer.scientific.normalize"; public static final String TRANSFROMER_LAYOUT_CACHE_INIT_ONSTARTUP = "transformer.layout.cache.init.onstartup"; public static final String TRANSFROMER_LAYOUT_CACHE_SIZE = "transformer.layout.cache.size"; @@ -30,6 +31,7 @@ public class SystemKeys { private static boolean stringTrimEnd = true; private static boolean validationEnabled = true; private static boolean addDecimalpoint = false; + private static boolean scientificNormalize = true; private static boolean layoutCacheOnStartup = false; @@ -64,7 +66,14 @@ public class SystemKeys { } catch (Exception ex) { addDecimalpoint = false; } - + + sBoolean = System.getProperty(TRANSFROMER_SCIENTIFIC_NORMALIZE, "false"); + try { + scientificNormalize = Boolean.valueOf(sBoolean); + } catch (Exception ex) { + scientificNormalize = false; + } + sBoolean = System.getProperty(TRANSFROMER_LAYOUT_CACHE_INIT_ONSTARTUP, "false"); try { layoutCacheOnStartup = Boolean.valueOf(sBoolean); @@ -93,6 +102,10 @@ public class SystemKeys { return addDecimalpoint; } + public static boolean isScientificNormalizeEnabled() { + return scientificNormalize; + } + public static boolean isLayoutCacheOnStartup() { return layoutCacheOnStartup; } 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 f7da5a6..5166aad 100644 --- a/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java +++ b/src/main/java/com/eactive/eai/transformer/message/JSONMessage.java @@ -703,7 +703,15 @@ public class JSONMessage extends Message { } private boolean isValid(String value,int length,int pointLength){ - String[] data = value.replaceAll(" ", "").split("[.]"); + String normalized = value.replaceAll(" ", ""); + if (SystemKeys.isScientificNormalizeEnabled()) { + try { + normalized = new BigDecimal(normalized).toPlainString(); + } catch (NumberFormatException e) { + return false; + } + } + String[] data = normalized.split("[.]"); if (pointLength > 0 ){ if (data.length ==1){ if (data[0].length() > length - pointLength - 1 ){ //정수부 오류 diff --git a/src/test/java/com/eactive/eai/transformer/JSONMessageValidationTest.java b/src/test/java/com/eactive/eai/transformer/JSONMessageValidationTest.java index ccd9334..a32256e 100644 --- a/src/test/java/com/eactive/eai/transformer/JSONMessageValidationTest.java +++ b/src/test/java/com/eactive/eai/transformer/JSONMessageValidationTest.java @@ -65,6 +65,7 @@ class JSONMessageValidationTest { @AfterEach void tearDown() { System.setProperty(SystemKeys.TRANSFROMER_VALIDATION, "false"); + System.setProperty(SystemKeys.TRANSFROMER_SCIENTIFIC_NORMALIZE, "false"); SystemKeys.reload(); } @@ -355,6 +356,81 @@ class JSONMessageValidationTest { assertTrue(result.contains("STR_VALUE"), "STR_VALUE가 결과에 포함되어야 합니다"); } + // ───────────────────────────────────────────────────────────────── + // 4. 지수 표현(Scientific Notation) 정규화 테스트 + // transformer.scientific.normalize=true 일 때만 적용 + // 4-a) 정규화 ON + validation ON + // 4-b) 정규화 OFF → 기존 동작(false positive / false negative) 확인 + // ───────────────────────────────────────────────────────────────── + + @Test + @DisplayName("[정규화 ON] 지수형 정수부 초과(1.23e5=123000 > 4자리 제한) → MessageSetDataException") + void testScientificNotationIntegerOverflow_withNormalize() { + enableValidation(); + enableScientificNormalize(); + + // 1.23e5 = 123000, 정수부 6자리 > 4자리 제한 + String data = "{\"EAI_UJSONTYPE_REQ1\":{\"BIG_VALUE\":1.23e5}}"; + Message msg = MessageFactory.getFactory().getMessage("EAI_UJSONTYPE_REQ1"); + + MessageSetDataException ex = assertThrows( + MessageSetDataException.class, + () -> msg.setData(data) + ); + assertTrue(containsMessage(ex, "Invalid decimal point format"), + "'Invalid decimal point format' 메시지가 포함되어야 합니다"); + } + + @Test + @DisplayName("[정규화 ON] 지수형 문자열 정수부 초과(\"1.23e5\" > 4자리 제한) → MessageSetDataException") + void testScientificNotationStringOverflow_withNormalize() { + enableValidation(); + enableScientificNormalize(); + + String data = "{\"EAI_UJSONTYPE_REQ1\":{\"BIG_VALUE\":\"1.23e5\"}}"; + Message msg = MessageFactory.getFactory().getMessage("EAI_UJSONTYPE_REQ1"); + + MessageSetDataException ex = assertThrows( + MessageSetDataException.class, + () -> msg.setData(data) + ); + assertTrue(containsMessage(ex, "Invalid decimal point format"), + "'Invalid decimal point format' 메시지가 포함되어야 합니다"); + } + + @Test + @DisplayName("[정규화 ON] 지수형 BIG15_VALUE 정상 범위(1.23e5=123000 ≤ 15자리) → 정상 처리") + void testScientificNotationBig15Valid_withNormalize() throws Exception { + enableValidation(); + enableScientificNormalize(); + + // 1.23e5 = 123000, 6자리 ≤ 15자리 제한 → 정상 + String data = "{\"EAI_UJSONTYPE_REQ1\":{\"BIG15_VALUE\":1.23e5}}"; + Message msg = MessageFactory.getFactory().getMessage("EAI_UJSONTYPE_REQ1"); + msg.setData(data); + + String result = (String) msg.getData(); + assertNotNull(result, "결과값이 null이 아니어야 합니다"); + assertTrue(result.contains("BIG15_VALUE"), "BIG15_VALUE가 결과에 포함되어야 합니다"); + } + + @Test + @DisplayName("[정규화 OFF] 지수형 BIG15_VALUE 정상값(1.23e5)이 false negative로 거부됨 → MessageSetDataException") + void testScientificNotationBig15Valid_withoutNormalize() { + enableValidation(); + disableScientificNormalize(); + + // 1.23e5 = 123000, 유효값(6자리 ≤ 15자리)이지만 정규화 없이는 "1.23E+5".split(".")=[2개] → 거부 + String data = "{\"EAI_UJSONTYPE_REQ1\":{\"BIG15_VALUE\":1.23e5}}"; + Message msg = MessageFactory.getFactory().getMessage("EAI_UJSONTYPE_REQ1"); + + assertThrows( + MessageSetDataException.class, + () -> msg.setData(data), + "정규화 OFF 시 false negative로 예외가 발생해야 합니다" + ); + } + // ───────────────────────────────────────────────────────────────── // 유틸 메서드 // ───────────────────────────────────────────────────────────────── @@ -364,6 +440,16 @@ class JSONMessageValidationTest { SystemKeys.reload(); } + private void enableScientificNormalize() { + System.setProperty(SystemKeys.TRANSFROMER_SCIENTIFIC_NORMALIZE, "true"); + SystemKeys.reload(); + } + + private void disableScientificNormalize() { + System.setProperty(SystemKeys.TRANSFROMER_SCIENTIFIC_NORMALIZE, "false"); + SystemKeys.reload(); + } + private boolean containsCause(Throwable e, Class causeClass) { Throwable t = e; while (t != null) {