Author: lukaszlenart
Date: Tue Jan 22 12:44:45 2013
New Revision: 1436878

URL: http://svn.apache.org/viewvc?rev=1436878&view=rev
Log:
WW-3971 adds ContainerHolder to reduce numbers of calls to getConfiguration() 
and optimize RuntimeConfiguration class to more thread friendly

Added:
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ContainerHolder.java
Modified:
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
    
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
    
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java
    
struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java

Added: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ContainerHolder.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ContainerHolder.java?rev=1436878&view=auto
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ContainerHolder.java
 (added)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ContainerHolder.java
 Tue Jan 22 12:44:45 2013
@@ -0,0 +1,33 @@
+package org.apache.struts2.dispatcher;
+
+import com.opensymphony.xwork2.inject.Container;
+import org.apache.struts2.StrutsConstants;
+
+/**
+ * Simple class to hold Container instance per thread to minimise number of 
attempts
+ * to read configuration and build each time a new configuration.
+ *
+ * Thus depends on {@link StrutsConstants#STRUTS_CONFIGURATION_XML_RELOAD} 
flag,
+ * if set to false just use stored container, configuration will do not change.
+ */
+class ContainerHolder {
+
+    private static ThreadLocal<Container> instance = new 
ThreadLocal<Container>();
+
+    public static void store(Container instance) {
+        boolean reloadConfigs = 
Boolean.valueOf(instance.getInstance(String.class, 
StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD));
+        if (!reloadConfigs) {
+            // reloadConfigs is false, configuration will do not change, just 
keep it
+            ContainerHolder.instance.set(instance);
+        }
+    }
+
+    public static Container get() {
+        return ContainerHolder.instance.get();
+    }
+
+    public static void clear() {
+        ContainerHolder.instance.set(null);
+    }
+
+}

Modified: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java?rev=1436878&r1=1436877&r2=1436878&view=diff
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
 (original)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
 Tue Jan 22 12:44:45 2013
@@ -432,6 +432,8 @@ public class Dispatcher {
         boolean reloadi18n = 
Boolean.valueOf(container.getInstance(String.class, 
StrutsConstants.STRUTS_I18N_RELOAD));
         LocalizedTextUtil.setReloadBundles(reloadi18n);
 
+        ContainerHolder.store(container);
+
         return container;
     }
 
@@ -908,8 +910,10 @@ public class Dispatcher {
      * Modify the ConfigurationManager instance
      *
      * @param mgr The configuration manager
+     * @deprecated should be removed as is used only in tests
      */
     public void setConfigurationManager(ConfigurationManager mgr) {
+        ContainerHolder.clear();
         this.configurationManager = mgr;
     }
 
@@ -918,6 +922,9 @@ public class Dispatcher {
      * @return Our dependency injection container
      */
     public Container getContainer() {
+        if (ContainerHolder.get() != null) {
+            return ContainerHolder.get();
+        }
         ConfigurationManager mgr = getConfigurationManager();
         if (mgr == null) {
             throw new IllegalStateException("The configuration manager 
shouldn't be null");
@@ -926,8 +933,11 @@ public class Dispatcher {
             if (config == null) {
                 throw new IllegalStateException("Unable to load 
configuration");
             } else {
-                return config.getContainer();
+                Container container = config.getContainer();
+                ContainerHolder.store(container);
+                return container;
             }
         }
     }
+
 }

Modified: 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java?rev=1436878&r1=1436877&r2=1436878&view=diff
==============================================================================
--- 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
 (original)
+++ 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
 Tue Jan 22 12:44:45 2013
@@ -194,6 +194,8 @@ public class DispatcherTest extends Stru
         
         Mock mockContainer = new Mock(Container.class);
         String reloadConfigs = container.getInstance(String.class, 
XWorkConstants.RELOAD_XML_CONFIGURATION);
+        mockContainer.expectAndReturn("getInstance", 
C.args(C.eq(String.class), 
C.eq(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD)),
+                reloadConfigs);
         mockContainer.expectAndReturn("getInstance", 
C.args(C.eq(String.class), C.eq(XWorkConstants.RELOAD_XML_CONFIGURATION)),
                 reloadConfigs);
         mockContainer.expectAndReturn("getInstance", 
C.args(C.eq(ObjectFactory.class)), destroyedObjectFactory);
@@ -228,6 +230,8 @@ public class DispatcherTest extends Stru
         Mock mockContainer = new Mock(Container.class);
         mockContainer.matchAndReturn("getInstance", 
C.args(C.eq(ObjectFactory.class)), new ObjectFactory());
         String reloadConfigs = container.getInstance(String.class, 
XWorkConstants.RELOAD_XML_CONFIGURATION);
+        mockContainer.expectAndReturn("getInstance", 
C.args(C.eq(String.class), 
C.eq(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD)),
+                reloadConfigs);
         mockContainer.expectAndReturn("getInstance", 
C.args(C.eq(String.class), C.eq(XWorkConstants.RELOAD_XML_CONFIGURATION)),
                 reloadConfigs);
 

Modified: 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java?rev=1436878&r1=1436877&r2=1436878&view=diff
==============================================================================
--- 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java
 (original)
+++ 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java
 Tue Jan 22 12:44:45 2013
@@ -38,6 +38,7 @@ import org.apache.struts2.StrutsConstant
 import org.apache.struts2.TestAction;
 import org.apache.struts2.TestConfigurationProvider;
 import org.apache.struts2.components.Form;
+import org.apache.struts2.dispatcher.Dispatcher;
 import org.apache.struts2.views.jsp.AbstractUITagTest;
 import org.apache.struts2.views.jsp.ActionTag;
 import org.easymock.EasyMock;
@@ -249,6 +250,8 @@ public class FormTagTest extends Abstrac
             }
         });
 
+        Dispatcher.getInstance().setConfigurationManager(configurationManager);
+
         FormTag tag = new FormTag();
         tag.setPageContext(pageContext);
         tag.setName("myForm");
@@ -336,6 +339,8 @@ public class FormTagTest extends Abstrac
                 }
             });
 
+            
Dispatcher.getInstance().setConfigurationManager(configurationManager);
+
             FormTag tag = new FormTag();
             tag.setPageContext(pageContext);
             tag.setName("myForm");
@@ -420,6 +425,8 @@ public class FormTagTest extends Abstrac
             }
         });
 
+        Dispatcher.getInstance().setConfigurationManager(configurationManager);
+
         FormTag tag = new FormTag();
         tag.setPageContext(pageContext);
         tag.setName("myForm");
@@ -501,6 +508,8 @@ public class FormTagTest extends Abstrac
             }
         });
 
+        Dispatcher.getInstance().setConfigurationManager(configurationManager);
+
         FormTag tag = new FormTag();
         tag.setPageContext(pageContext);
         tag.setName("myForm");

Modified: 
struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java?rev=1436878&r1=1436877&r2=1436878&view=diff
==============================================================================
--- 
struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java
 (original)
+++ 
struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java
 Tue Jan 22 12:44:45 2013
@@ -69,6 +69,7 @@ import com.opensymphony.xwork2.util.refl
 import ognl.PropertyAccessor;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -337,8 +338,6 @@ public class DefaultConfiguration implem
                     configs.put(actionName, 
buildFullActionConfig(packageConfig, baseConfig));
                 }
 
-
-
                 namespaceActionConfigs.put(namespace, configs);
                 if (packageConfig.getFullDefaultActionRef() != null) {
                     namespaceConfigs.put(namespace, 
packageConfig.getFullDefaultActionRef());
@@ -346,7 +345,9 @@ public class DefaultConfiguration implem
             }
         }
 
-        return new RuntimeConfigurationImpl(namespaceActionConfigs, 
namespaceConfigs);
+        PatternMatcher<int[]> matcher = 
container.getInstance(PatternMatcher.class);
+        return new 
RuntimeConfigurationImpl(Collections.unmodifiableMap(namespaceActionConfigs),
+                Collections.unmodifiableMap(namespaceConfigs), matcher);
     }
 
     private void setDefaultResults(Map<String, ResultConfig> results, 
PackageConfig packageContext) {
@@ -396,8 +397,6 @@ public class DefaultConfiguration implem
             }
         }
 
-
-
         return new ActionConfig.Builder(baseConfig)
             .addParams(params)
             .addResultConfigs(results)
@@ -408,25 +407,24 @@ public class DefaultConfiguration implem
     }
 
 
-    private class RuntimeConfigurationImpl implements RuntimeConfiguration {
+    private static class RuntimeConfigurationImpl implements 
RuntimeConfiguration {
+
         private Map<String, Map<String, ActionConfig>> namespaceActionConfigs;
         private Map<String, ActionConfigMatcher> namespaceActionConfigMatchers;
         private NamespaceMatcher namespaceMatcher;
         private Map<String, String> namespaceConfigs;
 
-        public RuntimeConfigurationImpl(Map<String, Map<String, ActionConfig>> 
namespaceActionConfigs, Map<String, String> namespaceConfigs) {
+        public RuntimeConfigurationImpl(Map<String, Map<String, ActionConfig>> 
namespaceActionConfigs,
+                                        Map<String, String> namespaceConfigs,
+                                        PatternMatcher<int[]> matcher) {
             this.namespaceActionConfigs = namespaceActionConfigs;
             this.namespaceConfigs = namespaceConfigs;
 
-            PatternMatcher<int[]> matcher = 
container.getInstance(PatternMatcher.class);
-
             this.namespaceActionConfigMatchers = new LinkedHashMap<String, 
ActionConfigMatcher>();
             this.namespaceMatcher = new NamespaceMatcher(matcher, 
namespaceActionConfigs.keySet());
 
             for (String ns : namespaceActionConfigs.keySet()) {
-                namespaceActionConfigMatchers.put(ns,
-                        new ActionConfigMatcher(matcher,
-                                namespaceActionConfigs.get(ns), true));
+                namespaceActionConfigMatchers.put(ns, new 
ActionConfigMatcher(matcher, namespaceActionConfigs.get(ns), true));
             }
         }
 
@@ -439,7 +437,7 @@ public class DefaultConfiguration implem
          * @param namespace the namespace for the action or null for the empty 
namespace, ""
          * @return the configuration information for action requested
          */
-        public synchronized ActionConfig getActionConfig(String namespace, 
String name) {
+        public ActionConfig getActionConfig(String namespace, String name) {
             ActionConfig config = findActionConfigInNamespace(namespace, name);
 
             // try wildcarded namespaces
@@ -466,7 +464,7 @@ public class DefaultConfiguration implem
             return config;
         }
 
-        ActionConfig findActionConfigInNamespace(String namespace, String 
name) {
+        private ActionConfig findActionConfigInNamespace(String namespace, 
String name) {
             ActionConfig config = null;
             if (namespace == null) {
                 namespace = "";
@@ -494,7 +492,7 @@ public class DefaultConfiguration implem
          *
          * @return a Map of namespace - > Map of ActionConfig objects, with 
the key being the action name
          */
-        public synchronized Map<String, Map<String, ActionConfig>>  
getActionConfigs() {
+        public Map<String, Map<String, ActionConfig>>  getActionConfigs() {
             return namespaceActionConfigs;
         }
 


Reply via email to