1   /*
2    * $Id: TestTilesPlugin.java 471754 2006-11-06 14:55:09Z husted $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  package org.apache.struts.tiles;
23  
24  import org.apache.struts.config.ModuleConfig;
25  import org.apache.struts.config.ModuleConfigFactory;
26  import org.apache.struts.config.PlugInConfig;
27  import org.apache.struts.mock.MockActionServlet;
28  import org.apache.struts.mock.TestMockBase;
29  import org.apache.struts.Globals;
30  import org.apache.struts.tiles.xmlDefinition.I18nFactorySet;
31  import org.apache.struts.util.RequestUtils;
32  import org.apache.struts.action.PlugIn;
33  import org.apache.commons.beanutils.BeanUtils;
34  import junit.framework.Test;
35  import junit.framework.TestSuite;
36  
37  import javax.servlet.ServletException;
38  import java.util.Locale;
39  import java.util.Map;
40  import java.util.HashMap;
41  
42  public class TestTilesPlugin extends TestMockBase {
43  
44  
45    protected ModuleConfig module1;
46    protected ModuleConfig module2;
47    protected MockActionServlet actionServlet;
48  
49      // ----------------------------------------------------------------- Basics
50  
51  
52      public TestTilesPlugin(String name) {
53          super(name);
54      }
55  
56  
57      public static void main(String args[]) {
58          junit.awtui.TestRunner.main
59              (new String[] { TestTilesPlugin.class.getName() } );
60      }
61  
62  
63      public static Test suite() {
64          return (new TestSuite(TestTilesPlugin.class));
65      }
66  
67  
68      // ----------------------------------------------------- Instance Variables
69  
70  
71  
72      // ----------------------------------------------------- Setup and Teardown
73  
74  
75      public void setUp()
76      {
77  
78      super.setUp();
79      TilesUtil.testReset();
80      actionServlet = new MockActionServlet(context, config);
81      }
82  
83  
84      public void tearDown() {
85  
86          super.tearDown();
87  
88      }
89  
90  
91      // ------------------------------------------------------- Individual Tests
92  
93  
94      /**
95       * Create a module configuration
96       * @param moduleName
97       */
98      public ModuleConfig createModuleConfig(
99          String moduleName,
100         String configFileName,
101         boolean moduleAware) {
102 
103         ModuleConfig moduleConfig =
104             ModuleConfigFactory.createFactory().createModuleConfig(moduleName);
105 
106         context.setAttribute(Globals.MODULE_KEY + moduleName, moduleConfig);
107 
108         // Set tiles plugin
109         PlugInConfig pluginConfig = new PlugInConfig();
110         pluginConfig.setClassName("org.apache.struts.tiles.TilesPlugin");
111 
112         pluginConfig.addProperty(
113             "moduleAware",
114             (moduleAware == true ? "true" : "false"));
115 
116         pluginConfig.addProperty(
117             "definitions-config",
118             "/org/apache/struts/tiles/config/" + configFileName);
119 
120         moduleConfig.addPlugInConfig(pluginConfig);
121         return moduleConfig;
122     }
123 
124     /**
125      * Fake call to init module plugins
126      * @param moduleConfig
127      */
128   public void initModulePlugIns( ModuleConfig moduleConfig)
129   {
130   PlugInConfig plugInConfigs[] = moduleConfig.findPlugInConfigs();
131   PlugIn plugIns[] = new PlugIn[plugInConfigs.length];
132 
133   context.setAttribute(Globals.PLUG_INS_KEY + moduleConfig.getPrefix(), plugIns);
134   for (int i = 0; i < plugIns.length; i++) {
135       try {
136           plugIns[i] =
137               (PlugIn) RequestUtils.applicationInstance(plugInConfigs[i].getClassName());
138           BeanUtils.populate(plugIns[i], plugInConfigs[i].getProperties());
139             // Pass the current plugIn config object to the PlugIn.
140             // The property is set only if the plugin declares it.
141             // This plugin config object is needed by Tiles
142           BeanUtils.copyProperty( plugIns[i], "currentPlugInConfigObject", plugInConfigs[i]);
143           plugIns[i].init(actionServlet, moduleConfig);
144       } catch (ServletException e) {
145           // Lets propagate
146           e.printStackTrace();
147           //throw e;
148       } catch (Exception e) {
149           e.printStackTrace();
150           //throw e;
151       }
152   }
153   }
154 
155     // ---------------------------------------------------------- absoluteURL()
156 
157 
158     /**
159      * Test multi factory creation when moduleAware=true.
160      */
161     public void testMultiFactory() {
162         // init TilesPlugin
163         module1 = createModuleConfig("/module1", "tiles-defs.xml", true);
164         module2 = createModuleConfig("/module2", "tiles-defs.xml", true);
165         initModulePlugIns(module1);
166         initModulePlugIns(module2);
167 
168         // mock request context
169         request.setAttribute(Globals.MODULE_KEY, module1);
170         request.setPathElements("/myapp", "/module1/foo.do", null, null);
171         // Retrieve factory for module1
172         DefinitionsFactory factory1 =
173             TilesUtil.getDefinitionsFactory(request, context);
174 
175         assertNotNull("factory found", factory1);
176         assertEquals(
177             "factory name",
178             "/module1",
179             factory1.getConfig().getFactoryName());
180 
181         // mock request context
182         request.setAttribute(Globals.MODULE_KEY, module2);
183         request.setPathElements("/myapp", "/module2/foo.do", null, null);
184         // Retrieve factory for module2
185         DefinitionsFactory factory2 =
186             TilesUtil.getDefinitionsFactory(request, context);
187         assertNotNull("factory found", factory2);
188         assertEquals(
189             "factory name",
190             "/module2",
191             factory2.getConfig().getFactoryName());
192 
193         // Check that factory are different
194         assertNotSame("Factory from different modules", factory1, factory2);
195     }
196 
197     /**
198      * Test single factory creation when moduleAware=false.
199      */
200   public void testSingleSharedFactory()
201   {
202     // init TilesPlugin
203   module1 = createModuleConfig( "/module1", "tiles-defs.xml", false );
204   module2 = createModuleConfig( "/module2", "tiles-defs.xml", false );
205   initModulePlugIns(module1);
206   initModulePlugIns(module2);
207 
208     // mock request context
209   request.setAttribute(Globals.MODULE_KEY, module1);
210   request.setPathElements("/myapp", "/module1/foo.do", null, null);
211     // Retrieve factory for module1
212   DefinitionsFactory factory1 = TilesUtil.getDefinitionsFactory( request, context);
213   assertNotNull( "factory found", factory1);
214   assertEquals( "factory name", "/module1", factory1.getConfig().getFactoryName() );
215 
216     // mock request context
217   request.setAttribute(Globals.MODULE_KEY, module2);
218   request.setPathElements("/myapp", "/module2/foo.do", null, null);
219     // Retrieve factory for module2
220   DefinitionsFactory factory2 = TilesUtil.getDefinitionsFactory( request, context);
221   assertNotNull( "factory found", factory2);
222   assertEquals( "factory name", "/module1", factory2.getConfig().getFactoryName() );
223 
224     // Check that factory are different
225   assertEquals("Same factory", factory1, factory2);
226   }
227 
228   /**
229    * Test I18nFactorySet.
230    */
231   public void testI18FactorySet_A() {
232 
233      Locale locale = null;
234      ComponentDefinition definition = null;
235      org.apache.struts.tiles.xmlDefinition.DefinitionsFactory factory = null;
236 
237      Map properties = new HashMap();
238 
239      // Set the file name
240      properties.put(I18nFactorySet.DEFINITIONS_CONFIG_PARAMETER_NAME,
241                     "config/I18nFactorySet-A.xml");
242 
243      try {
244          CustomI18nFactorySet i18nFactorySet = new CustomI18nFactorySet(context, properties);
245          String defName = "A-DEFAULT";
246 
247          // Default Locale
248          locale = new Locale("", "", "");
249          factory = i18nFactorySet.createFactory(locale , request, context);
250          assertNotNull("DefinitionsFactory is nullfor locale='" + print(locale) + "'", factory);
251          definition = factory.getDefinition(defName, request, context);
252          assertNotNull("Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
253          assertEquals("Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
254 
255          // Variant Only
256          locale = new Locale("", "", "XX");
257          factory = i18nFactorySet.createFactory(locale , request, context);
258          assertNotNull("DefinitionsFactory is null for locale='" + print(locale) + "'", factory);
259          definition = factory.getDefinition(defName, request, context);
260          assertNotNull("Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
261          assertEquals("Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
262 
263          // No Language, Country & Variant Locale
264          locale = new Locale("", "US", "XX");
265          factory = i18nFactorySet.createFactory(locale , request, context);
266          assertNotNull("DefinitionsFactory is null for locale='" + print(locale) + "'", factory);
267          definition = factory.getDefinition(defName, request, context);
268          assertNotNull("Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
269          assertEquals("Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
270 
271          // Language & Country
272          locale = new Locale("en", "US");
273          factory = i18nFactorySet.createFactory(locale , request, context);
274          assertNotNull("DefinitionsFactory is null for locale='" + print(locale) + "'", factory);
275          definition = factory.getDefinition(defName, request, context);
276          assertNotNull("Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
277          assertEquals("Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
278 
279      } catch(Exception ex) {
280          fail(ex.toString());
281      }
282   }
283 
284 
285   /**
286    * Test I18nFactorySet.
287    */
288   public void testI18FactorySet_B() {
289 
290      Locale locale = null;
291      ComponentDefinition definition = null;
292      org.apache.struts.tiles.xmlDefinition.DefinitionsFactory factory = null;
293 
294      Map properties = new HashMap();
295 
296      // Set the file name
297      properties.put(I18nFactorySet.DEFINITIONS_CONFIG_PARAMETER_NAME,
298                     "config/I18nFactorySet-B.xml");
299 
300      try {
301 
302          CustomI18nFactorySet i18nFactorySet = new CustomI18nFactorySet(context, properties);
303          String defName = null;
304 
305          // Default Locale
306          locale = new Locale("", "", "");
307          factory = i18nFactorySet.createFactory(locale , request, context);
308          assertNotNull("1. DefinitionsFactory is nullfor locale='" + print(locale) + "'", factory);
309          defName = "B-DEFAULT";
310          definition = factory.getDefinition(defName, request, context);
311          assertNotNull("2. Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
312          assertEquals("3. Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
313 
314          // Variant Only
315          locale = new Locale("", "", "XX");
316          factory = i18nFactorySet.createFactory(locale , request, context);
317          assertNotNull("4. DefinitionsFactory is null for locale='" + print(locale) + "'", factory);
318          defName = "B___XX";
319          definition = factory.getDefinition(defName, request, context);
320          assertNotNull("5. Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
321          assertEquals("6. Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
322          defName = "B-DEFAULT";
323          definition = factory.getDefinition(defName, request, context);
324          assertNotNull("7. Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
325          assertEquals("8. Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
326 
327          // No Language, Country & Unknown Variant
328          locale = new Locale("", "US", "XX");
329          factory = i18nFactorySet.createFactory(locale , request, context);
330          assertNotNull("9. DefinitionsFactory is null for locale='" + print(locale) + "'", factory);
331          defName = "B__US";
332          definition = factory.getDefinition(defName, request, context);
333          assertNotNull("10. Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
334          assertEquals("11. Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
335 
336          // Language & Country
337          locale = new Locale("en", "US");
338          factory = i18nFactorySet.createFactory(locale , request, context);
339          assertNotNull("12. DefinitionsFactory is null for locale='" + print(locale) + "'", factory);
340          defName = "B_en_US";
341          definition = factory.getDefinition(defName, request, context);
342          assertNotNull("13. Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
343          assertEquals("14. Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
344 
345          // Language, Country & Unknown Variant
346          locale = new Locale("en", "GB", "XX");
347          factory = i18nFactorySet.createFactory(locale , request, context);
348          assertNotNull("15. DefinitionsFactory is null for locale='" + print(locale) + "'", factory);
349          defName = "B_en_GB";
350          definition = factory.getDefinition(defName, request, context);
351          assertNotNull("16. Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
352          assertEquals("17. Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
353 
354          // Language, Unknown Country & Unknown Variant
355          locale = new Locale("en", "FR", "XX");
356          factory = i18nFactorySet.createFactory(locale , request, context);
357          assertNotNull("18. DefinitionsFactory is null for locale='" + print(locale) + "'", factory);
358          defName = "B_en";
359          definition = factory.getDefinition(defName, request, context);
360          assertNotNull("19. Definition '" + defName + "' Not Found for locale='" + print(locale) + "'", definition);
361          assertEquals("20. Definition '" + defName + "' for locale='" + print(locale) + "'", defName, definition.getName());
362 
363      } catch(Exception ex) {
364          fail(ex.toString());
365      }
366 
367   }
368 
369   /**
370    * String representation of a Locale. A bug in the
371    * Locale.toString() method results in Locales with
372    * just a variant being incorrectly displayed.
373    */
374   private String print(Locale locale) {
375 
376       return locale.getLanguage() + "_" +
377                 locale.getCountry() + "_" +
378                 locale.getVariant();
379   }
380 
381 
382 
383 }
384