You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2019/06/03 05:40:27 UTC

[struts] branch master updated: [WW-5034] Forward port Minor enhancement/fix to AbstractLocalizedTextProvider: - Forward port of equivalent change from 2.5.x. - Made "constant" RELOADED static to save an initialization every time. - Made ineffective clearBundle(final String bundleName) method a "no-op" with a debug log indicating the same. Marked method as deprecated. - Introduced protected clearBundle(final String bundleName, Locale locale) method for use by descendants, with debug log output when called. - Intro [...]

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

lukaszlenart pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/struts.git


The following commit(s) were added to refs/heads/master by this push:
     new 5c30e0d  [WW-5034] Forward port Minor enhancement/fix to   AbstractLocalizedTextProvider: - Forward port of equivalent change from 2.5.x. - Made "constant" RELOADED static to save an initialization every time. - Made ineffective clearBundle(final String bundleName) method a "no-op"   with a debug log indicating the same.  Marked method as deprecated. - Introduced protected clearBundle(final String bundleName, Locale locale)   method for use by descendants, with debug log output w [...]
     new b8ce02b  Merge pull request #360 from JCgH4164838Gh792C124B5/localS2_26x_TextProviderFix
5c30e0d is described below

commit 5c30e0d5c6ed8c6237f1e3705c8639a7f7a35214
Author: JCgH4164838Gh792C124B5 <43...@users.noreply.github.com>
AuthorDate: Sat Jun 1 14:58:18 2019 -0400

    [WW-5034] Forward port Minor enhancement/fix to
      AbstractLocalizedTextProvider:
    - Forward port of equivalent change from 2.5.x.
    - Made "constant" RELOADED static to save an initialization every time.
    - Made ineffective clearBundle(final String bundleName) method a "no-op"
      with a debug log indicating the same.  Marked method as deprecated.
    - Introduced protected clearBundle(final String bundleName, Locale locale)
      method for use by descendants, with debug log output when called.
    - Introduced protected clearMissingBundlesCache() method for use by
      descendants, with debug log when called.
---
 .../xwork2/util/AbstractLocalizedTextProvider.java | 46 ++++++++++-
 .../util/StrutsLocalizedTextProviderTest.java      | 90 ++++++++++++++++++++++
 2 files changed, 133 insertions(+), 3 deletions(-)

diff --git a/core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java b/core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java
index 03cb7d4..a8ccab5 100644
--- a/core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java
+++ b/core/src/main/java/com/opensymphony/xwork2/util/AbstractLocalizedTextProvider.java
@@ -53,7 +53,7 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
     public static final String STRUTS_MESSAGES_BUNDLE = "org/apache/struts2/struts-messages";
 
     private static final String TOMCAT_RESOURCE_ENTRIES_FIELD = "resourceEntries";
-    private final String RELOADED = "com.opensymphony.xwork2.util.LocalizedTextProvider.reloaded";
+    private static final String RELOADED = "com.opensymphony.xwork2.util.LocalizedTextProvider.reloaded";
 
     protected final ConcurrentMap<String, ResourceBundle> bundlesMap = new ConcurrentHashMap<>();
     protected boolean devMode = false;
@@ -225,10 +225,50 @@ abstract class AbstractLocalizedTextProvider implements LocalizedTextProvider {
     }
 
     /**
-     * @param bundleName Removes the bundle from any cached "misses"
+     * Clear a specific bundle from the <code>bundlesMap</code>.
+     *
+     * Warning: This method is <b>now a "no-op"</b>.  It <b>was ineffective</b> due
+     *   to the way the <code>bundlesMap</code> is used in combination with locale.
+     *   Descendants should use the method {@link #clearBundle(java.lang.String, java.util.Locale)} instead.
+     *
+     * @param bundleName The bundle to remove from the bundle map
+     *
+     * @deprecated A "no-op" since 2.6.  Use {@link #clearBundle(java.lang.String, java.util.Locale)} instead.
      */
     public void clearBundle(final String bundleName) {
-        bundlesMap.remove(getCurrentThreadContextClassLoader().hashCode() + bundleName);
+        LOG.debug("No-op.  Did NOT clear resource bundle [{}], result: false.", bundleName);
+    }
+
+    /**
+     * Clear a specific bundle + locale combination from the <code>bundlesMap</code>.
+     *   Intended for descendants to use clear a bundle + locale combination.
+     *
+     * @param bundleName The bundle (combined with locale) to remove from the bundle map
+     * @param locale     Provides the locale to combine with the bundle to get the key
+     *
+     * @since 2.6
+     */
+    protected void clearBundle(final String bundleName, Locale locale) {
+        final String key = createMissesKey(String.valueOf(getCurrentThreadContextClassLoader().hashCode()), bundleName, locale);
+        final ResourceBundle removedBundle = bundlesMap.remove(key);
+        LOG.debug("Clearing resource bundle [{}], locale [{}], result: [{}].", bundleName, locale, Boolean.valueOf(removedBundle != null));
+    }
+
+    /**
+     * Clears the <code>missingBundles</code> contents.  This allows descendants to
+     *   clear the <b>"missing bundles cache"</b> when desired (or needed).
+     *
+     * Note: This method may be used when the <code>bundlesMap</code> state has changed
+     *   in such a way that bundles that were previously "missing" may now be available
+     *   (e.g. after calling {@link #addDefaultResourceBundle(java.lang.String)} when the
+     *   {@link AbstractLocalizedTextProvider} has already been used for failed bundle
+     *   lookups of a given key, or some transitory state made a bundle lookup fail.
+     *
+     * @since 2.6
+     */
+    protected void clearMissingBundlesCache() {
+        missingBundles.clear();
+        LOG.debug("Cleared the missing bundles cache.");
     }
 
     protected void reloadBundles() {
diff --git a/core/src/test/java/com/opensymphony/xwork2/util/StrutsLocalizedTextProviderTest.java b/core/src/test/java/com/opensymphony/xwork2/util/StrutsLocalizedTextProviderTest.java
index c2ff4b5..7429082 100644
--- a/core/src/test/java/com/opensymphony/xwork2/util/StrutsLocalizedTextProviderTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/util/StrutsLocalizedTextProviderTest.java
@@ -249,6 +249,73 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
         assertEquals("Hallo", rbGermany.getString("hello"));
     }
 
+    /**
+     * Unit test to confirm expected behaviour of "clearing methods" provided to
+     *   StrutsLocalizedTextProvider (from AbstractLocalizedTextProvider).
+     *
+     * @since 2.6
+     */
+    public void testLocalizedTextProviderClearingMethods() {
+        TestStrutsLocalizedTextProvider testStrutsLocalizedTextProvider = new TestStrutsLocalizedTextProvider();
+        assertTrue("testStrutsLocalizedTextProvider not instance of AbstractLocalizedTextProvider ?",
+                testStrutsLocalizedTextProvider instanceof AbstractLocalizedTextProvider);
+        assertEquals("testStrutsLocalizedTextProvider starting default bundle map size not 0 before any retrievals ?",
+                0, testStrutsLocalizedTextProvider.currentBundlesMapSize());
+
+        // Access the two default bundles to populate their cache entries and test bundle map size.
+        ResourceBundle tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
+                TestStrutsLocalizedTextProvider.XWORK_MESSAGES_BUNDLE, Locale.ENGLISH);
+        assertNotNull("XWORK_MESSAGES_BUNDLE retrieval null ?", tempBundle);
+        tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
+                TestStrutsLocalizedTextProvider.STRUTS_MESSAGES_BUNDLE, Locale.ENGLISH);
+        assertNotNull("STRUTS_MESSAGES_BUNDLE retrieval null ?", tempBundle);
+        assertEquals("testStrutsLocalizedTextProvider bundle map size not 2 after retrievals ?",
+                2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
+
+        // Add and then access four test bundles to populate their cache entries and test bundle map size.
+        testStrutsLocalizedTextProvider.addDefaultResourceBundle("com/opensymphony/xwork2/util/LocalizedTextUtilTest");
+        testStrutsLocalizedTextProvider.addDefaultResourceBundle("com/opensymphony/xwork2/util/FindMe");
+        testStrutsLocalizedTextProvider.addDefaultResourceBundle("com/opensymphony/xwork2/SimpleAction");
+        testStrutsLocalizedTextProvider.addDefaultResourceBundle("com/opensymphony/xwork2/test");
+        tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
+                "com/opensymphony/xwork2/util/LocalizedTextUtilTest", Locale.ENGLISH);
+        assertNotNull("com/opensymphony/xwork2/util/LocalizedTextUtilTest retrieval null ?", tempBundle);
+        tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
+                "com/opensymphony/xwork2/util/FindMe", Locale.ENGLISH);
+        assertNotNull("com/opensymphony/xwork2/util/FindMe retrieval null ?", tempBundle);
+        tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
+                "com/opensymphony/xwork2/SimpleAction", Locale.ENGLISH);
+        assertNotNull("com/opensymphony/xwork2/SimpleAction retrieval null ?", tempBundle);
+        tempBundle = testStrutsLocalizedTextProvider.findResourceBundle(
+                "com/opensymphony/xwork2/test", Locale.ENGLISH);
+        assertNotNull("com/opensymphony/xwork2/test retrieval null ?", tempBundle);
+        assertEquals("testStrutsLocalizedTextProvider bundle map size not 6 after retrievals ?",
+                6, testStrutsLocalizedTextProvider.currentBundlesMapSize());
+
+        // Expect the call to be ineffective due to deprecation and change to a "no-op" (but shouldn't throw an Exception or cause failure).
+        testStrutsLocalizedTextProvider.callClearBundleNoLocale("com/opensymphony/xwork2/test");
+        assertEquals("testStrutsLocalizedTextProvider bundle map size not 6 after non-locale clear call ?",
+                6, testStrutsLocalizedTextProvider.currentBundlesMapSize());
+
+        // Expect the call to function with bundle name + locale.  Remove all four of the non-default
+        //   bundles and confirm the bundle map size changes.
+        testStrutsLocalizedTextProvider.callClearBundleWithLocale("com/opensymphony/xwork2/test", Locale.ENGLISH);
+        assertEquals("testStrutsLocalizedTextProvider bundle map size not 5 after locale clear call ?",
+                5, testStrutsLocalizedTextProvider.currentBundlesMapSize());
+        testStrutsLocalizedTextProvider.callClearBundleWithLocale("com/opensymphony/xwork2/SimpleAction", Locale.ENGLISH);
+        assertEquals("testStrutsLocalizedTextProvider bundle map size not 4 after locale clear call ?",
+                4, testStrutsLocalizedTextProvider.currentBundlesMapSize());
+        testStrutsLocalizedTextProvider.callClearBundleWithLocale("com/opensymphony/xwork2/util/FindMe", Locale.ENGLISH);
+        assertEquals("testStrutsLocalizedTextProvider bundle map size not 3 after locale clear call ?",
+                3, testStrutsLocalizedTextProvider.currentBundlesMapSize());
+        testStrutsLocalizedTextProvider.callClearBundleWithLocale("com/opensymphony/xwork2/util/LocalizedTextUtilTest", Locale.ENGLISH);
+        assertEquals("testStrutsLocalizedTextProvider bundle map size not 2 after locale clear call ?",
+                2, testStrutsLocalizedTextProvider.currentBundlesMapSize());
+
+        // Confirm the missing bundles cache clearing method does not produce any Exceptions or failures.
+        testStrutsLocalizedTextProvider.callClearMissingBundlesCache();
+    }
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -267,4 +334,27 @@ public class StrutsLocalizedTextProviderTest extends XWorkTestCase {
         localizedTextProvider = null;
     }
 
+    /**
+     * Basic test class to allow specific testing of StrutsLocalizedTextProvider.
+     *
+     * @since 2.6
+     */
+    class TestStrutsLocalizedTextProvider extends StrutsLocalizedTextProvider {
+
+        public void callClearBundleNoLocale(String bundleName) {
+            super.clearBundle(bundleName);
+}
+
+        public void callClearBundleWithLocale(String bundleName, Locale locale) {
+            super.clearBundle(bundleName, locale);
+        }
+
+        public void callClearMissingBundlesCache() {
+            super.clearMissingBundlesCache();
+        }
+
+        public int currentBundlesMapSize() {
+            return super.bundlesMap.size();
+        }
+    }
 }