diff --git a/Foundation/org.egovframe.rte.fdl.string/src/main/java/org/egovframe/rte/fdl/string/EgovStringUtil.java b/Foundation/org.egovframe.rte.fdl.string/src/main/java/org/egovframe/rte/fdl/string/EgovStringUtil.java index 4e280948..6ec761be 100755 --- a/Foundation/org.egovframe.rte.fdl.string/src/main/java/org/egovframe/rte/fdl/string/EgovStringUtil.java +++ b/Foundation/org.egovframe.rte.fdl.string/src/main/java/org/egovframe/rte/fdl/string/EgovStringUtil.java @@ -25,6 +25,7 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -990,7 +991,7 @@ public static List> getTokens(String lst) { public static String convertToCamelCase(String targetString, char posChar) { StringBuilder result = new StringBuilder(); boolean nextUpper = false; - String allLower = targetString.toLowerCase(); + String allLower = targetString.toLowerCase(Locale.ROOT); for (int i = 0; i < allLower.length(); i++) { char currentChar = allLower.charAt(i); if (currentChar == posChar) { @@ -1029,7 +1030,7 @@ public static String convertToUnderScore(String camelCase) { if (i > 0 && Character.isUpperCase(currentChar)) { result = result.concat("_"); } - result = result.concat(Character.toString(currentChar).toLowerCase()); + result = result.concat(Character.toString(currentChar).toLowerCase(Locale.ROOT)); } return result; } diff --git a/Foundation/org.egovframe.rte.fdl.string/src/test/java/org/egovframe/rte/fdl/string/EgovStringUtilLocaleTest.java b/Foundation/org.egovframe.rte.fdl.string/src/test/java/org/egovframe/rte/fdl/string/EgovStringUtilLocaleTest.java new file mode 100644 index 00000000..b47ab019 --- /dev/null +++ b/Foundation/org.egovframe.rte.fdl.string/src/test/java/org/egovframe/rte/fdl/string/EgovStringUtilLocaleTest.java @@ -0,0 +1,44 @@ +package org.egovframe.rte.fdl.string; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Locale; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * 식별자 변환 메서드들이 JVM 기본 로케일과 무관하게 동작하는지 검증한다. + * + *
터키어·아제르바이잔어 로케일에서는 인자 없는 toUpperCase()/toLowerCase()가 + * i ↔ İ(U+0130) / I ↔ ı(U+0131)로 변환한다. 같은 저장소의 CamelCaseUtil은 + * Character 단위 변환을 써서 이 문제가 없다.
+ */ +public class EgovStringUtilLocaleTest { + + private void underTurkishLocale(Runnable body) { + Locale original = Locale.getDefault(); + try { + Locale.setDefault(Locale.forLanguageTag("tr-TR")); + body.run(); + } finally { + Locale.setDefault(original); + } + } + + @Test + @DisplayName("convertToCamelCase는 로케일과 무관하게 ASCII 규칙으로 변환한다") + public void convertToCamelCaseIsLocaleIndependent() { + underTurkishLocale(() -> + assertEquals("printStatus", EgovStringUtil.convertToCamelCase("PRINT_STATUS", '_'))); + assertEquals("printStatus", EgovStringUtil.convertToCamelCase("PRINT_STATUS", '_')); + } + + @Test + @DisplayName("convertToUnderScore는 로케일과 무관하게 ASCII 규칙으로 변환한다") + public void convertToUnderScoreIsLocaleIndependent() { + underTurkishLocale(() -> + assertEquals("print_id", EgovStringUtil.convertToUnderScore("printId"))); + assertEquals("print_id", EgovStringUtil.convertToUnderScore("printId")); + } +}