diff --git a/src/main/java/com/eactive/eai/transformer/function/generic/GetMapping.java b/src/main/java/com/eactive/eai/transformer/function/generic/GetMapping.java new file mode 100644 index 0000000..ad046dc --- /dev/null +++ b/src/main/java/com/eactive/eai/transformer/function/generic/GetMapping.java @@ -0,0 +1,107 @@ +package com.eactive.eai.transformer.function.generic; + +import java.util.Stack; + +import org.nfunk.jep.ParseException; +import org.nfunk.jep.function.PostfixMathCommand; + +import com.eactive.eai.common.property.PropManager; + +/** + * JEP 커스텀 함수 - PropManager 프러퍼티 그룹 기반 값 매핑 + * + *
고정된 변환 룰이 아닌, PropManager의 프러퍼티 그룹(예: 공통코드 매핑 테이블)을 + * 동적으로 조회하여 입력값을 매핑된 값으로 변환한다. + * 매핑 정보는 {@code 1000 -> AAAAA}, {@code 1001 -> BBBBB} 처럼 그룹의 key/value로 관리된다. + * + *
사용법: + *
예: 그룹 "COMMON_CODE"에 {@code 1000=AAAAA}가 있을 때 + * {@code getmapping("COMMON_CODE", "1000")} → {@code "AAAAA"} + */ +public class GetMapping extends PostfixMathCommand { + public GetMapping() { + numberOfParameters = -1; + } + + /** + * 스택에서 (group, value) 또는 (group, value, default)를 꺼내 매핑값을 조회한다. + * + * @param inStack JEP 후위 연산 스택 + * @throws ParseException 파라미터 개수가 2 또는 3이 아니거나 group이 문자열이 아닌 경우 + */ + @SuppressWarnings("unchecked") + public void run(Stack inStack) throws ParseException { + checkStack(inStack); + + int n = curNumberOfParameters; + if (n != 2 && n != 3) { + throw new ParseException( + "getmapping() requires 2 or 3 parameters: getmapping(group, value [, default])"); + } + + boolean hasDefault = (n == 3); + Object defaultValue = hasDefault ? inStack.pop() : null; + Object value = inStack.pop(); + Object groupObj = inStack.pop(); + + if (!(groupObj instanceof String)) { + throw new ParseException("getmapping(): first parameter (group name) must be a string"); + } + + String group = (String) groupObj; + String key = toKey(value); + + String mapped = (key == null) ? null : lookup(group, key); + + if (mapped != null) { + inStack.push(mapped); + } else if (hasDefault) { + inStack.push(defaultValue); + } else { + inStack.push(value); // 매핑 없음 → 원본값 그대로 반환 + } + } + + /** + * PropManager 프러퍼티 그룹에서 key에 해당하는 값을 조회한다. + * 매핑이 없거나 그룹이 존재하지 않으면 null을 반환한다. + * + *
단위 테스트에서는 이 메서드를 오버라이드하여 Spring 컨텍스트 없이 매핑을 주입할 수 있다.
+ */
+ protected String lookup(String group, String key) {
+ return PropManager.getInstance().getProperty(group, key);
+ }
+
+ /**
+ * 매핑 조회에 사용할 문자열 key로 변환한다.
+ * 정수형 숫자(JEP는 숫자를 Double로 처리)는 {@code "1000.0"}이 아닌 {@code "1000"}으로 변환한다.
+ */
+ private String toKey(Object value) {
+ if (value == null) {
+ return null;
+ }
+ if (value instanceof String) {
+ return (String) value;
+ }
+ if (value instanceof Number) {
+ double d = ((Number) value).doubleValue();
+ if (!Double.isInfinite(d) && !Double.isNaN(d) && d == Math.rint(d)) {
+ return Long.toString((long) d);
+ }
+ }
+ return value.toString();
+ }
+}
diff --git a/src/test/java/com/eactive/eai/transformer/GetMappingFunctionTest.java b/src/test/java/com/eactive/eai/transformer/GetMappingFunctionTest.java
new file mode 100644
index 0000000..2e58f0c
--- /dev/null
+++ b/src/test/java/com/eactive/eai/transformer/GetMappingFunctionTest.java
@@ -0,0 +1,158 @@
+package com.eactive.eai.transformer;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.nfunk.jep.JEP;
+
+import com.eactive.eai.transformer.function.generic.GetMapping;
+
+@DisplayName("GetMapping 프러퍼티 그룹 매핑 함수 테스트")
+class GetMappingFunctionTest {
+
+ private JEP jep;
+
+ /**
+ * PropManager(Spring 컨텍스트) 없이 테스트하기 위해 lookup()을 로컬 맵으로 대체한 스텁.
+ * groups: 그룹명 → (key → value) 매핑 테이블
+ */
+ static class StubGetMapping extends GetMapping {
+ private final Map