Author: apetrelli Date: Fri Jul 20 02:15:51 2007 New Revision: 557933 URL: http://svn.apache.org/viewvc?view=rev&rev=557933 Log: STR-3073 Now the Tiles 2 plugin fails in case of multiple conflicting configuration. STR-3075 Clean up of TilesPlugin JUnit test.
Modified: struts/struts1/trunk/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java struts/struts1/trunk/tiles2/src/test/java/org/apache/struts/tiles2/TestTilesPlugin.java Modified: struts/struts1/trunk/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java?view=diff&rev=557933&r1=557932&r2=557933 ============================================================================== --- struts/struts1/trunk/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java (original) +++ struts/struts1/trunk/tiles2/src/main/java/org/apache/struts/tiles2/TilesPlugin.java Fri Jul 20 02:15:51 2007 @@ -189,6 +189,17 @@ container); } if (container instanceof KeyedDefinitionsFactoryTilesContainer) { + KeyedDefinitionsFactoryTilesContainer keyedContainer = + (KeyedDefinitionsFactoryTilesContainer) container; + // If we have a definition factory for the current module prefix + // then we are trying to re-initialize the same module, and it is + // wrong! + if (keyedContainer.getProperDefinitionsFactory(moduleConfig + .getPrefix()) != null) { + throw new ServletException("Tiles definitions factory for module '" + + moduleConfig.getPrefix() + + "' has already been configured"); + } if (factory instanceof KeyedDefinitionsFactoryTilesContainerFactory) { DefinitionsFactory defsFactory = ((KeyedDefinitionsFactoryTilesContainerFactory) factory) @@ -205,8 +216,7 @@ initParameters.put(BasicTilesContainer .DEFINITIONS_CONFIG, param); } - ((KeyedDefinitionsFactoryTilesContainer) container) - .setDefinitionsFactory(moduleConfig.getPrefix(), + keyedContainer.setDefinitionsFactory(moduleConfig.getPrefix(), defsFactory, initParameters); } else { log.warn("The created factory is not instance of " @@ -221,6 +231,10 @@ } else { factory = TilesContainerFactory .getFactory(currentPlugInConfigContextAdapter); + if (TilesAccess.getContainer(currentPlugInConfigContextAdapter) != null) { + throw new ServletException( + "Tiles container has already been configured"); + } container = factory.createContainer( currentPlugInConfigContextAdapter); TilesAccess.setContainer(currentPlugInConfigContextAdapter, Modified: struts/struts1/trunk/tiles2/src/test/java/org/apache/struts/tiles2/TestTilesPlugin.java URL: http://svn.apache.org/viewvc/struts/struts1/trunk/tiles2/src/test/java/org/apache/struts/tiles2/TestTilesPlugin.java?view=diff&rev=557933&r1=557932&r2=557933 ============================================================================== --- struts/struts1/trunk/tiles2/src/test/java/org/apache/struts/tiles2/TestTilesPlugin.java (original) +++ struts/struts1/trunk/tiles2/src/test/java/org/apache/struts/tiles2/TestTilesPlugin.java Fri Jul 20 02:15:51 2007 @@ -21,12 +21,16 @@ package org.apache.struts.tiles2; +import java.lang.reflect.InvocationTargetException; + import javax.servlet.ServletException; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.beanutils.BeanUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.struts.Globals; import org.apache.struts.action.PlugIn; import org.apache.struts.config.ModuleConfig; @@ -41,125 +45,102 @@ import org.apache.tiles.impl.BasicTilesContainer; import org.apache.tiles.impl.KeyedDefinitionsFactoryTilesContainer; +/** + * Tests the Tiles plugin. + * + * @version $Rev$ $Date$ + */ public class TestTilesPlugin extends TestMockBase { + /** + * The first module to configure. + */ + protected ModuleConfig module1; - protected ModuleConfig module1; - protected ModuleConfig module2; - protected MockActionServlet actionServlet; + /** + * The second module to configure. + */ + protected ModuleConfig module2; - // ----------------------------------------------------------------- Basics + /** + * A testing action servlet. + */ + protected MockActionServlet actionServlet; + + /** + * The logging object. + */ + private static final Log LOG = LogFactory.getLog(TestTilesPlugin.class); + // ----------------------------------------------------------------- Basics + /** + * Constructor. + * + * @param name The name of the test. + */ public TestTilesPlugin(String name) { super(name); } - - public static void main(String args[]) { - junit.awtui.TestRunner.main - (new String[] { TestTilesPlugin.class.getName() } ); + /** + * Sample main method. + * + * @param args Arguments. + */ + public static void main(String[] args) { + junit.awtui.TestRunner.main(new String[] { TestTilesPlugin.class + .getName() }); } - + /** + * Test suite method. + * + * @return The test. + */ public static Test suite() { return (new TestSuite(TestTilesPlugin.class)); } - // ----------------------------------------------------- Instance Variables - - // ----------------------------------------------------- Setup and Teardown + /** [EMAIL PROTECTED] */ + public void setUp() { - public void setUp() - { - - super.setUp(); - actionServlet = new MockActionServlet(context, config); + super.setUp(); + actionServlet = new MockActionServlet(context, config); } - + /** [EMAIL PROTECTED] */ public void tearDown() { super.tearDown(); } - // ------------------------------------------------------- Individual Tests - - /** - * Create a module configuration - * @param moduleName - */ - public ModuleConfig createModuleConfig( - String moduleName, - String configFileName, - boolean moduleAware) { - - ModuleConfig moduleConfig = - ModuleConfigFactory.createFactory().createModuleConfig(moduleName); - - context.setAttribute(Globals.MODULE_KEY + moduleName, moduleConfig); - - // Set tiles plugin - PlugInConfig pluginConfig = new PlugInConfig(); - pluginConfig.setClassName("org.apache.struts.tiles2.TilesPlugin"); - - pluginConfig.addProperty( - "moduleAware", - (moduleAware == true ? "true" : "false")); - - pluginConfig.addProperty( - "definitions-config", - "/org/apache/struts/tiles2/config/" + configFileName); - - moduleConfig.addPlugInConfig(pluginConfig); - return moduleConfig; - } - - /** - * Fake call to init module plugins - * @param moduleConfig - */ - public void initModulePlugIns( ModuleConfig moduleConfig) - { - PlugInConfig plugInConfigs[] = moduleConfig.findPlugInConfigs(); - PlugIn plugIns[] = new PlugIn[plugInConfigs.length]; - - context.setAttribute(Globals.PLUG_INS_KEY + moduleConfig.getPrefix(), plugIns); - for (int i = 0; i < plugIns.length; i++) { - try { - plugIns[i] = - (PlugIn) RequestUtils.applicationInstance(plugInConfigs[i].getClassName()); - BeanUtils.populate(plugIns[i], plugInConfigs[i].getProperties()); - // Pass the current plugIn config object to the PlugIn. - // The property is set only if the plugin declares it. - // This plugin config object is needed by Tiles - BeanUtils.copyProperty( plugIns[i], "currentPlugInConfigObject", plugInConfigs[i]); - plugIns[i].init(actionServlet, moduleConfig); - } catch (ServletException e) { - // Lets propagate - e.printStackTrace(); - //throw e; - } catch (Exception e) { - e.printStackTrace(); - //throw e; - } - } - } - // ---------------------------------------------------------- absoluteURL() - /** * Test multi factory creation when moduleAware=true. + * + * @throws ServletException + * If something goes wrong during initialization. + * @throws InvocationTargetException + * Bean properties problems. + * @throws InstantiationException + * Bean properties problems. + * @throws IllegalAccessException + * Bean properties problems. + * @throws ClassNotFoundException + * Bean properties problems. */ - public void testMultiFactory() { + public void testMultiFactory() throws ClassNotFoundException, + IllegalAccessException, InstantiationException, + InvocationTargetException, ServletException { // init TilesPlugin module1 = createModuleConfig("/module1", "tiles-defs.xml", true); module2 = createModuleConfig("/module2", "tiles-defs.xml", true); @@ -169,16 +150,16 @@ // mock request context request.setAttribute(Globals.MODULE_KEY, module1); request.setPathElements("/myapp", "/module1/foo.do", null, null); - + // Retrieve TilesContainer TilesContainer container = TilesAccess.getContainer(actionServlet .getServletContext()); assertSame(container.getClass().getName(), KeyedDefinitionsFactoryTilesContainer.class.getName()); - + // Retrieve factory for module1 DefinitionsFactory factory1 = ((KeyedDefinitionsFactoryTilesContainer) container) - .getDefinitionsFactory("/module1"); + .getDefinitionsFactory("/module1"); assertNotNull("factory found", factory1); @@ -196,40 +177,142 @@ } /** + * Tests if the TilesPlugin does a fail-fast on multiple configuration of + * the same module. + * + * @throws ServletException If something goes wrong during initialization. + * @throws InvocationTargetException Bean properties problems. + * @throws InstantiationException Bean properties problems. + * @throws IllegalAccessException Bean properties problems. + * @throws ClassNotFoundException Bean properties problems. + */ + public void testMultiModuleFailFast() throws ClassNotFoundException, + IllegalAccessException, InstantiationException, + InvocationTargetException, ServletException { + // init TilesPlugin + module1 = createModuleConfig("/module1", "tiles-defs.xml", true); + + // The name is "/module1" on purpose + module2 = createModuleConfig("/module1", "tiles-defs.xml", true); + initModulePlugIns(module1); + try { + initModulePlugIns(module2); + fail("An exception should have been thrown"); + } catch (ServletException e) { + // It is ok + LOG.debug("Intercepted a ServletException, it is ok", e); + } + } + + /** * Test single factory creation when moduleAware=false. + * + * @throws ServletException If something goes wrong during initialization. + * @throws InvocationTargetException Bean properties problems. + * @throws InstantiationException Bean properties problems. + * @throws IllegalAccessException Bean properties problems. + * @throws ClassNotFoundException Bean properties problems. */ - public void testSingleSharedFactory() - { - // init TilesPlugin - module1 = createModuleConfig( "/module1", "tiles-defs.xml", false ); - module2 = createModuleConfig( "/module2", "tiles-defs.xml", false ); - initModulePlugIns(module1); - initModulePlugIns(module2); - - // mock request context - request.setAttribute(Globals.MODULE_KEY, module1); - request.setPathElements("/myapp", "/module1/foo.do", null, null); - // Retrieve TilesContainer - TilesContainer container = TilesAccess.getContainer(actionServlet - .getServletContext()); - assertSame(container.getClass().getName(), - BasicTilesContainer.class.getName()); - - // Retrieve factory for module1 - DefinitionsFactory factory1 = ((BasicTilesContainer) container) - .getDefinitionsFactory(); - assertNotNull( "factory found", factory1); - - // mock request context - request.setAttribute(Globals.MODULE_KEY, module2); - request.setPathElements("/myapp", "/module2/foo.do", null, null); - // Retrieve factory for module2 - DefinitionsFactory factory2 = ((BasicTilesContainer) container) - .getDefinitionsFactory(); - assertNotNull( "factory found", factory2); - - // Check that factory are different - assertEquals("Same factory", factory1, factory2); - } -} + public void testSingleSharedFactory() throws ClassNotFoundException, + IllegalAccessException, InstantiationException, + InvocationTargetException, ServletException { + // init TilesPlugin + module1 = createModuleConfig("/module1", "tiles-defs.xml", false); + module2 = createModuleConfig("/module2", "tiles-defs.xml", false); + initModulePlugIns(module1); + try { + initModulePlugIns(module2); + fail("An exception should have been thrown"); + } catch (ServletException e) { + // It is ok + LOG.debug("Intercepted a ServletException, it is ok", e); + } + + // mock request context + request.setAttribute(Globals.MODULE_KEY, module1); + request.setPathElements("/myapp", "/module1/foo.do", null, null); + // Retrieve TilesContainer + TilesContainer container = TilesAccess.getContainer(actionServlet + .getServletContext()); + assertSame(container.getClass().getName(), BasicTilesContainer.class + .getName()); + + // Retrieve factory for module1 + DefinitionsFactory factory1 = ((BasicTilesContainer) container) + .getDefinitionsFactory(); + assertNotNull("factory found", factory1); + + // mock request context + request.setAttribute(Globals.MODULE_KEY, module2); + request.setPathElements("/myapp", "/module2/foo.do", null, null); + // Retrieve factory for module2 + DefinitionsFactory factory2 = ((BasicTilesContainer) container) + .getDefinitionsFactory(); + assertNotNull("factory found", factory2); + // Check that factory are different + assertEquals("Same factory", factory1, factory2); + } + + /** + * Create a module configuration. + * + * @param moduleName The name of the module. + * @param configFileName The name of the configuration file. + * @param moduleAware <code>true</code> if the configuration must be + * module-aware. + * @return The configuration object. + */ + private ModuleConfig createModuleConfig(String moduleName, + String configFileName, boolean moduleAware) { + + ModuleConfig moduleConfig = ModuleConfigFactory.createFactory() + .createModuleConfig(moduleName); + + context.setAttribute(Globals.MODULE_KEY + moduleName, moduleConfig); + + // Set tiles plugin + PlugInConfig pluginConfig = new PlugInConfig(); + pluginConfig.setClassName("org.apache.struts.tiles2.TilesPlugin"); + + pluginConfig.addProperty("moduleAware", + (moduleAware ? "true" : "false")); + + pluginConfig.addProperty("definitions-config", + "/org/apache/struts/tiles2/config/" + configFileName); + + moduleConfig.addPlugInConfig(pluginConfig); + return moduleConfig; + } + + /** + * Fake call to init module plugins. + * + * @param moduleConfig The configuration of the module. + * @throws ServletException If something goes wrong during initialization. + * @throws InvocationTargetException Bean properties problems. + * @throws InstantiationException Bean properties problems. + * @throws IllegalAccessException Bean properties problems. + * @throws ClassNotFoundException Bean properties problems. + */ + private void initModulePlugIns(ModuleConfig moduleConfig) + throws ClassNotFoundException, IllegalAccessException, + InstantiationException, InvocationTargetException, ServletException { + PlugInConfig[] plugInConfigs = moduleConfig.findPlugInConfigs(); + PlugIn[] plugIns = new PlugIn[plugInConfigs.length]; + + context.setAttribute(Globals.PLUG_INS_KEY + moduleConfig.getPrefix(), + plugIns); + for (int i = 0; i < plugIns.length; i++) { + plugIns[i] = (PlugIn) RequestUtils + .applicationInstance(plugInConfigs[i].getClassName()); + BeanUtils.populate(plugIns[i], plugInConfigs[i].getProperties()); + // Pass the current plugIn config object to the PlugIn. + // The property is set only if the plugin declares it. + // This plugin config object is needed by Tiles + BeanUtils.copyProperty(plugIns[i], "currentPlugInConfigObject", + plugInConfigs[i]); + plugIns[i].init(actionServlet, moduleConfig); + } + } +}