This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch fix/WW-5422-trimable
in repository https://gitbox.apache.org/repos/asf/struts.git

commit 67eb1aac4a45f753bc179d7e1990df02142a3edd
Author: Lukasz Lenart <lukaszlen...@apache.org>
AuthorDate: Sat May 11 07:23:22 2024 +0200

    WW-5422 Adds dedicate unit test to cover DefaultLocaleProvider
---
 .../com/opensymphony/xwork2/ActionSupport.java     |   5 +
 .../opensymphony/xwork2/DefaultLocaleProvider.java |  18 ++-
 .../com/opensymphony/xwork2/LocaleProvider.java    |  16 +++
 .../validator/DelegatingValidatorContext.java      |  12 +-
 .../struts2/interceptor/I18nInterceptor.java       |  25 ++--
 .../xwork2/DefaultLocaleProviderTest.java          | 156 +++++++++++++++++++++
 .../struts2/interceptor/I18nInterceptorTest.java   |  20 +++
 7 files changed, 229 insertions(+), 23 deletions(-)

diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionSupport.java 
b/core/src/main/java/com/opensymphony/xwork2/ActionSupport.java
index 8c7e15e60..ab1a18099 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ActionSupport.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ActionSupport.java
@@ -90,6 +90,11 @@ public class ActionSupport implements Action, Validateable, 
ValidationAware, Tex
         return getLocaleProvider().isValidLocale(locale);
     }
 
+    @Override
+    public Locale toLocale(String localeStr) {
+        return getLocaleProvider().toLocale(localeStr);
+    }
+
     @Override
     public boolean hasKey(String key) {
         return getTextProvider().hasKey(key);
diff --git 
a/core/src/main/java/com/opensymphony/xwork2/DefaultLocaleProvider.java 
b/core/src/main/java/com/opensymphony/xwork2/DefaultLocaleProvider.java
index da89306c0..35f16191a 100644
--- a/core/src/main/java/com/opensymphony/xwork2/DefaultLocaleProvider.java
+++ b/core/src/main/java/com/opensymphony/xwork2/DefaultLocaleProvider.java
@@ -46,17 +46,23 @@ public class DefaultLocaleProvider implements 
LocaleProvider {
 
     @Override
     public boolean isValidLocaleString(String localeStr) {
+        Locale locale = this.toLocale(localeStr);
+        return isValidLocale(locale);
+    }
+
+    @Override
+    public boolean isValidLocale(Locale locale) {
+        return locale != null && LocaleUtils.isAvailableLocale(locale);
+    }
+
+    @Override
+    public Locale toLocale(String localeStr) {
         Locale locale = null;
         try {
             locale = LocaleUtils.toLocale(StringUtils.trimToNull(localeStr));
         } catch (IllegalArgumentException e) {
             LOG.warn(new ParameterizedMessage("Cannot convert [{}] to proper 
locale", localeStr), e);
         }
-        return isValidLocale(locale);
-    }
-
-    @Override
-    public boolean isValidLocale(Locale locale) {
-        return LocaleUtils.isAvailableLocale(locale);
+        return locale;
     }
 }
diff --git a/core/src/main/java/com/opensymphony/xwork2/LocaleProvider.java 
b/core/src/main/java/com/opensymphony/xwork2/LocaleProvider.java
index 67972af34..00a41a25b 100644
--- a/core/src/main/java/com/opensymphony/xwork2/LocaleProvider.java
+++ b/core/src/main/java/com/opensymphony/xwork2/LocaleProvider.java
@@ -18,6 +18,9 @@
  */
 package com.opensymphony.xwork2;
 
+import org.apache.commons.lang3.LocaleUtils;
+import org.apache.commons.lang3.StringUtils;
+
 import java.util.Locale;
 
 
@@ -58,4 +61,17 @@ public interface LocaleProvider {
      */
     boolean isValidLocale(Locale locale);
 
+    /**
+     * Tries to convert provided locale string into {@link Locale} or returns 
null
+     * @param localeStr a String representing locale, e.g.: en_EN
+     * @return instance of {@link Locale} or null
+     * @since Struts 6.5.0
+     */
+    default Locale toLocale(String localeStr) {
+        try {
+            return LocaleUtils.toLocale(StringUtils.trimToNull(localeStr));
+        } catch (IllegalArgumentException e) {
+            return null;
+        }
+    }
 }
diff --git 
a/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java
 
b/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java
index 5c7f2c136..bc8c88875 100644
--- 
a/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java
+++ 
b/core/src/main/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java
@@ -122,10 +122,15 @@ public class DelegatingValidatorContext implements 
ValidatorContext {
         return localeProvider.isValidLocale(locale);
     }
 
+    @Override
+    public Locale toLocale(String localeStr) {
+        return localeProvider.toLocale(localeStr);
+    }
+
     public boolean hasKey(String key) {
        return textProvider.hasKey(key);
     }
-    
+
     public String getText(String aTextName) {
         return textProvider.getText(aTextName);
     }
@@ -280,6 +285,11 @@ public class DelegatingValidatorContext implements 
ValidatorContext {
         public boolean isValidLocale(Locale locale) {
             return getLocaleProvider().isValidLocale(locale);
         }
+
+        @Override
+        public Locale toLocale(String localeStr) {
+            return getLocaleProvider().toLocale(localeStr);
+        }
     }
 
     /**
diff --git 
a/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java 
b/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java
index e0f978f6e..6bce04244 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java
@@ -24,7 +24,6 @@ import com.opensymphony.xwork2.LocaleProviderFactory;
 import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
 import com.opensymphony.xwork2.util.TextParseUtil;
-import org.apache.commons.lang3.LocaleUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.message.ParameterizedMessage;
@@ -85,7 +84,7 @@ public class I18nInterceptor extends AbstractInterceptor {
     }
 
     public void setLocaleStorage(String storageName) {
-        if (storageName == null || "".equals(storageName)) {
+        if (storageName == null || storageName.isEmpty()) {
             this.storage = Storage.ACCEPT_LANGUAGE;
         } else {
             try {
@@ -169,27 +168,21 @@ public class I18nInterceptor extends AbstractInterceptor {
     }
 
     /**
-     * Creates a Locale object from the request param, which might
-     * be already a Local or a String
+     * Creates a Locale object from the request param
      *
      * @param requestedLocale the parameter from the request
-     * @return the Locale
+     * @return instance of {@link Locale} or null
      */
-    protected Locale getLocaleFromParam(Object requestedLocale) {
+    protected Locale getLocaleFromParam(String requestedLocale) {
         LocaleProvider localeProvider = 
localeProviderFactory.createLocaleProvider();
 
         Locale locale = null;
         if (requestedLocale != null) {
-            if (requestedLocale instanceof Locale) {
-                locale = (Locale) requestedLocale;
-            } else {
-                String localeStr = requestedLocale.toString();
-                if (localeProvider.isValidLocaleString(localeStr)) {
-                    locale = LocaleUtils.toLocale(localeStr);
-                } else {
-                    locale = localeProvider.getLocale();
-                }
+            locale = localeProvider.toLocale(requestedLocale);
+            if (locale == null) {
+                locale = localeProvider.getLocale();
             }
+
             if (locale != null) {
                 LOG.debug("Found locale: {}", locale);
             }
@@ -285,7 +278,7 @@ public class I18nInterceptor extends AbstractInterceptor {
         @Override
         @SuppressWarnings("rawtypes")
         public Locale find() {
-            if (supportedLocale.size() > 0) {
+            if (!supportedLocale.isEmpty()) {
                 Enumeration locales = 
actionInvocation.getInvocationContext().getServletRequest().getLocales();
                 while (locales.hasMoreElements()) {
                     Locale locale = (Locale) locales.nextElement();
diff --git 
a/core/src/test/java/com/opensymphony/xwork2/DefaultLocaleProviderTest.java 
b/core/src/test/java/com/opensymphony/xwork2/DefaultLocaleProviderTest.java
new file mode 100644
index 000000000..17144a6fe
--- /dev/null
+++ b/core/src/test/java/com/opensymphony/xwork2/DefaultLocaleProviderTest.java
@@ -0,0 +1,156 @@
+package com.opensymphony.xwork2;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.Locale;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class DefaultLocaleProviderTest {
+
+    private DefaultLocaleProvider provider;
+
+    @Before
+    public void setUp() throws Exception {
+        provider = new DefaultLocaleProvider();
+    }
+
+    @BeforeClass
+    public static void beforeClass() throws Exception {
+        ActionContext.of().bind();
+    }
+
+    @AfterClass
+    public static void afterClass() throws Exception {
+        ActionContext.clear();
+    }
+
+    @Test
+    public void getLocale() {
+        // given
+        ActionContext.getContext().withLocale(Locale.ITALY);
+
+        // when
+        Locale expected = provider.getLocale();
+
+        // then
+        assertEquals(expected, Locale.ITALY);
+    }
+
+    @Test
+    public void getLocaleNull() {
+        // given
+        ActionContext backup = ActionContext.getContext();
+        ActionContext.clear();
+
+        // when
+        Locale expected = provider.getLocale();
+
+        // then
+        assertNull(expected);
+        ActionContext.bind(backup);
+    }
+
+    @Test
+    public void toLocale() {
+        // given
+        ActionContext.getContext().withLocale(Locale.GERMAN);
+
+        // when
+        Locale expected = provider.toLocale("it");
+
+        // then
+        assertEquals(expected, Locale.ITALIAN);
+    }
+
+    @Test
+    public void toLocaleFull() {
+        // given
+        ActionContext.getContext().withLocale(Locale.GERMAN);
+
+        // when
+        Locale expected = provider.toLocale("it_IT");
+
+        // then
+        assertEquals(expected, Locale.ITALY);
+    }
+
+    @Test
+    public void toLocaleTrimEndOfLine() {
+        // given
+        ActionContext.getContext().withLocale(Locale.GERMAN);
+
+        // when
+        Locale expected = provider.toLocale("it_IT\n");
+
+        // then
+        assertEquals(expected, Locale.ITALY);
+    }
+
+    @Test
+    public void toLocaleTrimEmptySpace() {
+        // given
+        ActionContext.getContext().withLocale(Locale.GERMAN);
+
+        // when
+        Locale expected = provider.toLocale(" it_IT ");
+
+        // then
+        assertEquals(expected, Locale.ITALY);
+    }
+
+    @Test
+    public void isValidLocaleNull() {
+        // given
+        ActionContext.getContext().withLocale(Locale.GERMAN);
+
+        // when
+        boolean expected = provider.isValidLocale(null);
+
+        // then
+        assertFalse(expected);
+    }
+
+    @Test
+    public void isValidLocale() {
+        // given
+        ActionContext.getContext().withLocale(Locale.GERMAN);
+
+        // when
+        boolean expected = provider.isValidLocale(Locale.ITALIAN);
+
+        // then
+        assertTrue(expected);
+    }
+
+    @Test
+    public void isValidLocaleString() {
+        // given
+        ActionContext.getContext().withLocale(Locale.GERMAN);
+
+        // when
+        boolean expected = provider.isValidLocaleString("it");
+
+        // then
+        assertTrue(expected);
+    }
+
+    @Test
+    public void isValidLocaleStringNot() {
+        // given
+        ActionContext.getContext().withLocale(Locale.GERMAN);
+
+        // when
+        boolean expected = provider.isValidLocaleString("italy");
+
+        // then
+        assertFalse(expected);
+    }
+
+}
\ No newline at end of file
diff --git 
a/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java 
b/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java
index a8fd8420f..604d61be6 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java
@@ -147,6 +147,26 @@ public class I18nInterceptorTest extends TestCase {
         assertEquals(Locale.getDefault(), 
session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a 
locale object
     }
 
+    public void testTrimableLocaleString1() throws Exception {
+        prepare(I18nInterceptor.DEFAULT_PARAMETER, "de\n");
+
+        interceptor.intercept(mai);
+
+        
assertFalse(mai.getInvocationContext().getParameters().get(I18nInterceptor.DEFAULT_PARAMETER).isDefined());
 // should have been removed
+        assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); 
// should be stored here
+        assertEquals(Locale.GERMAN, 
session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a 
locale object
+    }
+
+    public void testTrimableLocaleString2() throws Exception {
+        prepare(I18nInterceptor.DEFAULT_PARAMETER, "de ");
+
+        interceptor.intercept(mai);
+
+        
assertFalse(mai.getInvocationContext().getParameters().get(I18nInterceptor.DEFAULT_PARAMETER).isDefined());
 // should have been removed
+        assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); 
// should be stored here
+        assertEquals(Locale.GERMAN, 
session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a 
locale object
+    }
+
     public void testWithVariant() throws Exception {
         prepare(I18nInterceptor.DEFAULT_PARAMETER, "ja_JP_JP");
         interceptor.intercept(mai);

Reply via email to