Author: husted Date: Sun Nov 26 17:56:16 2006 New Revision: 479495 URL: http://svn.apache.org/viewvc?view=rev&rev=479495 Log: WW-1522 "Automatic Alias ActionConfigs" - Add prototype tests and class before continuing with implementation.
Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/MethodConfigurationProvider.java struts/struts2/trunk/core/src/test/java/org/apache/struts2/config/MethodConfigurationProviderTest.java Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/MethodConfigurationProvider.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/MethodConfigurationProvider.java?view=auto&rev=479495 ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/MethodConfigurationProvider.java (added) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/MethodConfigurationProvider.java Sun Nov 26 17:56:16 2006 @@ -0,0 +1,55 @@ +package org.apache.struts2.config; + +import com.opensymphony.xwork2.config.ConfigurationProvider; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.inject.ContainerBuilder; +import com.opensymphony.xwork2.util.location.LocatableProperties; + + +/** + * MethodConfigurationProvider creates ActionConfigs for potential action + * methods without a corresponding action. + * <p> + * The provider iterates over the set of namespaces and the set of actionNames + * in a Configuration and retrieves each ActionConfig. + * For each ActionConfig that invokes the default "execute" method, + * the provider inspects the className class for other non-void, + * no-argument methods that do not begin with "get". + * For each qualifying method, the provider looks for another actionName in + * the same namespace that equals action.name + "!" + method.name. + * If that actionName is not found, System copies the ActionConfig, + * changes the method property, and adds it to the package configuration + * under the new actionName (action!method). + * <p> + * The system ignores ActionConfigs with a method property set so as to + * avoid creating alias methods for alias methods. + * The system ignores "get" methods since these would appeare to be + * JavaBeans property and would not be intended as action methods. + * + * + * starts with default "execute" ActionConfigs so that an + * application can provide its own alias methods too. + */ +public class MethodConfigurationProvider implements ConfigurationProvider { + + public void destroy() { + // TODO + } + + public void init(Configuration configuration) throws ConfigurationException { + // TODO + } + + public void register(ContainerBuilder containerBuilder, LocatableProperties locatableProperties) throws ConfigurationException { + // TODO + } + + public void loadPackages() throws ConfigurationException { + // TODO + } + + public boolean needsReload() { + return false; // TODO + } +} 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?view=diff&rev=479495&r1=479494&r2=479495 ============================================================================== --- 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 Sun Nov 26 17:56:16 2006 @@ -276,22 +276,11 @@ configurationManager = null; } - /** - * Load configurations, including both XML and zero-configuration strategies, - * and update optional settings, including whether to reload configurations and resource files. - */ - public void init() { - - if (configurationManager == null) { - configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME); - } - - // 1] Configuration: legacy properties file (struts.properties) + private void init_LegacyStrutsProperties() { configurationManager.addConfigurationProvider(new LegacyPropertiesConfigurationProvider()); - - - // 2] Configuration: traditional xml configuration (eg. struts-default.xml, struts-plugin.xml, struts.xml) - // Load traditional xml configuration + } + + private void init_TraditionalXmlConfigurations() { String configPaths = initParams.get("config"); if (configPaths == null) { configPaths = DEFAULT_CONFIGURATION_PATHS; @@ -308,9 +297,9 @@ throw new IllegalArgumentException("Invalid configuration file name"); } } + } - // 3] Configuration: zero-configuration stuff - // Load configuration from a scan of the classloader + private void init_ZeroConfiguration() { String packages = initParams.get("actionPackages"); if (packages != null) { String[] names = packages.split("\\s*[,]\\s*"); @@ -321,8 +310,9 @@ configurationManager.addConfigurationProvider(provider); } } - - // 4] Configuration: custom ConfigurationProviders + } + + private void init_CustomConfigurationProviders() { String configProvs = initParams.get("configProviders"); if (configProvs != null) { String[] classes = configProvs.split("\\s*[,]\\s*"); @@ -340,9 +330,14 @@ } } } - - // 5] Configurations: Filter's init-parameters as constants to be injected - // Load filter init params as constants + } + + private void init_MethodConfigurationProvider() { + // TODO + // See https://issues.apache.org/struts/browse/WW-1522 + } + + private void init_FilterInitParameters() { configurationManager.addConfigurationProvider(new ConfigurationProvider() { public void destroy() {} public void init(Configuration configuration) throws ConfigurationException {} @@ -353,11 +348,13 @@ props.putAll(initParams); } }); - - - // 6] Configurations: Alias standard Struts2 beans + } + + private void init_AliasStandardObjects() { configurationManager.addConfigurationProvider(new BeanSelectionProvider()); - // Preload the configuration + } + + private Container init_PreloadConfiguration() { Configuration config = configurationManager.getConfiguration(); Container container = config.getContainer(); @@ -367,7 +364,10 @@ ObjectTypeDeterminer objectTypeDeterminer = container.getInstance(ObjectTypeDeterminer.class); ObjectTypeDeterminerFactory.setInstance(objectTypeDeterminer); - //check for configuration reloading + return container; + } + + private void init_CheckConfigurationReloading(Container container) { FileManager.setReloadingConfigs("true".equals(container.getInstance(String.class, StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD))); @@ -376,7 +376,10 @@ ObjectFactory.setContinuationPackage(pkg); } - // test wether param-access workaround needs to be enabled + } + + private void init_CheckWebLogicWorkaround(Container container) { + // test whether param-access workaround needs to be enabled if (servletContext != null && servletContext.getServerInfo() != null && servletContext.getServerInfo().indexOf("WebLogic") >= 0) { LOG.info("WebLogic server detected. Enabling Struts parameter access work-around."); @@ -384,7 +387,7 @@ } else { paramsWorkaroundEnabled = "true".equals(container.getInstance(String.class, StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND)); - } + } synchronized(Dispatcher.class) { if (dispatcherListeners.size() > 0) { @@ -393,6 +396,31 @@ } } } + + } + + /** + * Load configurations, including both XML and zero-configuration strategies, + * and update optional settings, including whether to reload configurations and resource files. + */ + public void init() { + + if (configurationManager == null) { + configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME); + } + + init_LegacyStrutsProperties(); // [1] + init_TraditionalXmlConfigurations(); // [2] + init_ZeroConfiguration(); // [3] + init_CustomConfigurationProviders(); // [4] + init_MethodConfigurationProvider(); + init_FilterInitParameters() ; // [5] + init_AliasStandardObjects() ; // [6] + + Container container = init_PreloadConfiguration(); + init_CheckConfigurationReloading(container); + init_CheckWebLogicWorkaround(container); + } /** Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/config/MethodConfigurationProviderTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/config/MethodConfigurationProviderTest.java?view=auto&rev=479495 ============================================================================== --- struts/struts2/trunk/core/src/test/java/org/apache/struts2/config/MethodConfigurationProviderTest.java (added) +++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/config/MethodConfigurationProviderTest.java Sun Nov 26 17:56:16 2006 @@ -0,0 +1,136 @@ +/* + * $Id: $ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.config; + +import org.apache.struts2.dispatcher.ServletDispatcherResult; + +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.entities.PackageConfig; +import com.opensymphony.xwork2.config.entities.ResultTypeConfig; +import com.opensymphony.xwork2.config.entities.ActionConfig; +import com.opensymphony.xwork2.config.impl.DefaultConfiguration; +import com.opensymphony.xwork2.ActionSupport; + +import junit.framework.TestCase; + +/** + * Preliminary test to define parameters of MethodConfigurationProvide. WORK IN PROGESS. + */ +public class MethodConfigurationProviderTest extends TestCase { + + MethodConfigurationProvider provider; + Configuration config; + + public void setUp() { + + config = new DefaultConfiguration(); + + PackageConfig strutsDefault = new PackageConfig("struts-default"); + strutsDefault.addResultTypeConfig(new ResultTypeConfig("dispatcher", ServletDispatcherResult.class.getName(), "location")); + strutsDefault.setDefaultResultType("dispatcher"); + config.addPackageConfig("struts-default", strutsDefault); + + PackageConfig customPackage = new PackageConfig("custom-package"); + customPackage.setNamespace("/custom"); + ActionConfig action = new ActionConfig(null, ActionSupport.class, null, null, null); + customPackage.addActionConfig("action",action); + config.addPackageConfig("custom-package", customPackage); + + provider = new MethodConfigurationProvider(); + provider.init(config); + provider.loadPackages(); + } + + private PackageConfig getCustom() { + return config.getPackageConfig("custom-package"); + } + + /** + * Confirms baseline setup works as expected. + */ + public void off_testSetup() { + assertEquals(2, config.getPackageConfigs().size()); + PackageConfig struts = config.getPackageConfig("struts-default"); + assertNotNull(struts); + PackageConfig custom = getCustom(); + assertNotNull(custom); + assertEquals(0,struts.getActionConfigs().size()); + assertTrue("testSetup: Expected ActionConfigs to be added!", 1 <struts.getActionConfigs().size()); + } + + /** + * Confirms system detects other non-void, no-argument methods + * on the class of default actions, and that it creates an ActionConfig + * matching the default action. + */ + public void off_testQualifyingMethods() { + + PackageConfig custom = getCustom(); + + boolean baseline = custom.getActionConfigs().containsKey("action"); + assertTrue("The root action is missing!",baseline); + + boolean action_execute = custom.getActionConfigs().containsKey("action!execute"); + assertFalse("The execute method should not have an ActionConfig!",action_execute); + + boolean action_validate = custom.getActionConfigs().containsKey("action!validate"); + assertTrue("Expected an ActionConfig for the validate method",action_validate); + + } + + /** + * Confirms system excludes methods that are not non-void and no-argument or begin with "get". + */ + public void testExcludedMethods() { + + PackageConfig custom = getCustom(); + + boolean action_getLocale = custom.getActionConfigs().containsKey("action!getLocale"); + assertFalse("A 'get' method has an ActionConfig!",action_getLocale); + + boolean action_pause = custom.getActionConfigs().containsKey("action!pause"); + assertFalse("A void method with arguments has an ActionConfig!",action_pause); + + } + + /** + * Confirms system does not create an ActionConfig for + * methods that already have an action. + */ + public void testCustomMethods() { + + ActionConfig action_validate = getCustom().getActionConfigs().get("action!validate"); + // TODO + + } + + /** + * Confirms system creates an ActionConfig that matches default action. + */ + public void testActionConfig() { + + ActionConfig action_input = getCustom().getActionConfigs().get("action!input"); + // TODO + + } + +} +