1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.configuration;
19  
20  import java.io.File;
21  import java.io.FileWriter;
22  import java.util.Collection;
23  import java.util.List;
24  
25  import junit.framework.TestCase;
26  
27  import org.xml.sax.SAXParseException;
28  
29  /***
30   * Test the ConfigurationFactory.
31   *
32   * @version $Id: TestConfigurationFactory.java 506128 2007-02-11 20:43:08Z oheger $
33   */
34  public class TestConfigurationFactory extends TestCase
35  {
36      /*** The Files that we test with */
37      private File digesterRules = new File("conf/digesterRules.xml");
38      private File testDigesterFile =
39              new File("conf/testDigesterConfiguration.xml");
40      private File testDigesterFileReverseOrder =
41              new File("conf/testDigesterConfigurationReverseOrder.xml");
42      private File testDigesterFileNamespaceAware =
43              new File("conf/testDigesterConfigurationNamespaceAware.xml");
44      private File testDigesterFileBasePath =
45              new File("conf/testDigesterConfigurationBasePath.xml");
46      private File testDigesterFileEnhanced =
47              new File("conf/testDigesterConfiguration2.xml");
48      private File testDigesterFileComplete =
49              new File("conf/testDigesterConfiguration3.xml");
50      private File testDigesterFileOptional =
51              new File("conf/testDigesterOptionalConfiguration.xml");
52      private File testDigesterFileOptionalEx =
53              new File("conf/testDigesterOptionalConfigurationEx.xml");
54      private File testDigesterFileSysProps =
55              new File("conf/testDigesterConfigurationSysProps.xml");
56      private File testDigesterFileInitProps =
57              new File("conf/testDigesterConfigurationWithProps.xml");
58  
59      private File testDigesterBadXML = new File("conf/testDigesterBadXML.xml");
60  
61      private String testBasePath = new File("conf").getAbsolutePath();
62  
63      private File testProperties = new File("conf/test.properties");
64      private File testAbsConfig = new File("target/testAbsConfig.xml");
65  
66      private Configuration configuration;
67      private CompositeConfiguration compositeConfiguration;
68      private ConfigurationFactory factory;
69  
70      public void setUp() throws Exception
71      {
72          System.setProperty("java.naming.factory.initial", "org.apache.commons.configuration.MockInitialContextFactory");
73          factory = new ConfigurationFactory();
74      }
75  
76      public void testJNDI() throws Exception
77      {
78          JNDIConfiguration jndiConfiguration = new JNDIConfiguration();
79          Object o = jndiConfiguration.getProperty("test.boolean");
80          assertNotNull(o);
81          assertEquals("true", o.toString());
82      }
83  
84      public void testLoadingConfiguration() throws Exception
85      {
86          factory.setConfigurationFileName(testDigesterFile.toString());
87  
88          compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
89  
90          assertEquals("Number of configurations", 4, compositeConfiguration.getNumberOfConfigurations());
91          assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
92          assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration.getConfiguration(1).getClass());
93          assertEquals(XMLConfiguration.class, compositeConfiguration.getConfiguration(2).getClass());
94  
95          // check the first configuration
96          PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
97          assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc.getFileName());
98  
99          // check some properties
100         assertTrue("Make sure we have loaded our key", compositeConfiguration.getBoolean("test.boolean"));
101         assertEquals("I'm complex!", compositeConfiguration.getProperty("element2.subelement.subsubelement"));
102         assertEquals("property in the XMLPropertiesConfiguration", "value1", compositeConfiguration.getProperty("key1"));
103     }
104 
105     public void testLoadingConfigurationWithRulesXML() throws Exception
106     {
107         factory.setConfigurationFileName(testDigesterFile.toString());
108         factory.setDigesterRules(digesterRules.toURL());
109 
110         compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
111 
112         assertEquals("Number of configurations", 4, compositeConfiguration.getNumberOfConfigurations());
113         assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
114         //assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration.getConfiguration(1).getClass()); // doesn't work
115         assertEquals(XMLConfiguration.class, compositeConfiguration.getConfiguration(2).getClass());
116 
117         // check the first configuration
118         PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
119         assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc.getFileName());
120 
121         // check some properties
122         assertTrue("Make sure we have loaded our key", pc.getBoolean("test.boolean"));
123         assertTrue("Make sure we have loaded our key", compositeConfiguration.getBoolean("test.boolean"));
124 
125         assertEquals("I'm complex!", compositeConfiguration.getProperty("element2.subelement.subsubelement"));
126     }
127 
128     public void testLoadingConfigurationReverseOrder() throws Exception
129     {
130         factory.setConfigurationFileName(testDigesterFileReverseOrder.toString());
131 
132         configuration = factory.getConfiguration();
133 
134         assertEquals("8", configuration.getProperty("test.short"));
135 
136         factory.setConfigurationFileName(testDigesterFile.toString());
137 
138         configuration = factory.getConfiguration();
139         assertEquals("1", configuration.getProperty("test.short"));
140     }
141 
142     public void testLoadingConfigurationNamespaceAware() throws Exception
143     {
144         factory.setConfigurationFileName(testDigesterFileNamespaceAware.toString());
145         //factory.setDigesterRules(digesterRules.toURL());
146         factory.setDigesterRuleNamespaceURI("namespace-one");
147 
148         checkCompositeConfiguration();
149     }
150 
151     public void testLoadingConfigurationBasePath() throws Exception
152     {
153         factory.setConfigurationFileName(testDigesterFileBasePath.toString());
154 
155         factory.setBasePath(testBasePath);
156 
157         //factory.setDigesterRules(digesterRules.toURL());
158         //factory.setDigesterRuleNamespaceURI("namespace-one");
159 
160         checkCompositeConfiguration();
161     }
162 
163     public void testLoadingAdditional() throws Exception
164     {
165         factory.setConfigurationFileName(testDigesterFileEnhanced.toString());
166         factory.setBasePath(null);
167         checkUnionConfig();
168     }
169 
170     public void testLoadingURL() throws Exception
171     {
172         factory.setConfigurationURL(testDigesterFileEnhanced.toURL());
173         checkUnionConfig();
174 
175         factory = new ConfigurationFactory();
176         File nonExistingFile = new File("conf/nonexisting.xml");
177         factory.setConfigurationURL(nonExistingFile.toURL());
178         try
179         {
180             factory.getConfiguration();
181             fail("Could load non existing file!");
182         }
183         catch(ConfigurationException cex)
184         {
185             //ok
186         }
187     }
188 
189     public void testThrowingConfigurationInitializationException() throws Exception
190     {
191         factory.setConfigurationFileName(testDigesterBadXML.toString());
192         try
193         {
194             factory.getConfiguration();
195             fail("Should have throw an Exception");
196         }
197         catch (ConfigurationException cle)
198         {
199             assertTrue(cle.getCause() instanceof SAXParseException);
200         }
201     }
202 
203     // Tests if properties from all sources can be loaded
204     public void testAllConfiguration() throws Exception
205     {
206         factory.setConfigurationURL(testDigesterFileComplete.toURL());
207         Configuration config = factory.getConfiguration();
208         assertFalse(config.isEmpty());
209         assertTrue(config instanceof CompositeConfiguration);
210         CompositeConfiguration cc = (CompositeConfiguration) config;
211         assertTrue(cc.getNumberOfConfigurations() > 1);
212         // Currently fails, should be 4?  Only 2?
213         //assertEquals(4, cc.getNumberOfConfigurations());
214 
215         assertNotNull(config.getProperty("tables.table(0).fields.field(2).name"));
216         assertNotNull(config.getProperty("element2.subelement.subsubelement"));
217         assertEquals("value", config.getProperty("element3"));
218         assertEquals("foo", config.getProperty("element3[@name]"));
219         assertNotNull(config.getProperty("mail.account.user"));
220 
221         // test JNDIConfiguration
222         assertNotNull(config.getProperty("test.onlyinjndi"));
223         assertTrue(config.getBoolean("test.onlyinjndi"));
224 
225         Configuration subset = config.subset("test");
226         assertNotNull(subset.getProperty("onlyinjndi"));
227         assertTrue(subset.getBoolean("onlyinjndi"));
228 
229         // test SystemConfiguration
230         assertNotNull(config.getProperty("java.version"));
231         assertEquals(System.getProperty("java.version"), config.getString("java.version"));
232     }
233 
234     // Checks if optional configurations work
235     public void testOptionalConfigurations() throws Exception
236     {
237         factory.setConfigurationURL(testDigesterFileOptional.toURL());
238         Configuration config = factory.getConfiguration();
239         assertTrue(config.getBoolean("test.boolean"));
240         assertEquals("value", config.getProperty("element"));
241 
242         factory.setConfigurationURL(testDigesterFileOptionalEx.toURL());
243         try
244         {
245             config = factory.getConfiguration();
246             fail("Unexisting properties loaded!");
247         }
248         catch(ConfigurationException cex)
249         {
250             // fine
251         }
252     }
253 
254     // Checks if a file with an absolute path can be loaded
255     public void testLoadAbsolutePath() throws Exception
256     {
257         try
258         {
259             FileWriter out = null;
260             try
261             {
262                 out = new FileWriter(testAbsConfig);
263                 out.write("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>");
264                 out.write("<configuration>");
265                 out.write("<properties fileName=\"");
266                 out.write(testProperties.getAbsolutePath());
267                 out.write("\"/>");
268                 out.write("</configuration>");
269             }
270             finally
271             {
272                 if (out != null)
273                 {
274                     out.close();
275                 }
276             }
277 
278             factory.setConfigurationFileName(testAbsConfig.toString());
279             Configuration config = factory.getConfiguration();
280             assertTrue(config.getBoolean("configuration.loaded"));
281         }
282         finally
283         {
284             if (testAbsConfig.exists())
285             {
286                 testAbsConfig.delete();
287             }
288         }
289     }
290 
291     public void testBasePath() throws Exception
292     {
293         assertEquals(".", factory.getBasePath());
294         factory.setConfigurationFileName(testDigesterFile.getAbsolutePath());
295         // if no specific base path has been set, the base is determined
296         // from the file name
297         assertEquals(testDigesterFile.getParentFile().getAbsolutePath(),
298                 factory.getBasePath());
299 
300         String homeDir = System.getProperty("user.home");
301         factory = new ConfigurationFactory();
302         factory.setBasePath(homeDir);
303         factory.setConfigurationFileName(testDigesterFile.getAbsolutePath());
304         // if a base path was set, the file name does not play a role
305         assertEquals(homeDir, factory.getBasePath());
306 
307         factory = new ConfigurationFactory(testDigesterFile.getAbsolutePath());
308         assertEquals(testDigesterFile.getParentFile().getAbsolutePath(),
309                 factory.getBasePath());
310         factory.setBasePath(homeDir);
311         assertEquals(homeDir, factory.getBasePath());
312 
313         factory = new ConfigurationFactory();
314         factory.setConfigurationURL(testDigesterFile.toURL());
315         assertEquals(testDigesterFile.toURL().toString(), factory.getBasePath());
316     }
317 
318     // Tests if system properties can be resolved in the configuration
319     // definition
320     public void testLoadingWithSystemProperties() throws ConfigurationException
321     {
322         System.setProperty("config.file", "test.properties");
323         factory.setConfigurationFileName(testDigesterFileSysProps
324                 .getAbsolutePath());
325         Configuration config = factory.getConfiguration();
326         assertTrue("Configuration not loaded", config
327                 .getBoolean("configuration.loaded"));
328     }
329 
330     // Tests if the properties of a configuration object are correctly set
331     // before it is loaded.
332     public void testLoadInitProperties() throws ConfigurationException
333     {
334         factory.setConfigurationFileName(testDigesterFileInitProps
335                 .getAbsolutePath());
336         Configuration config = factory.getConfiguration();
337         PropertiesConfiguration c = (PropertiesConfiguration) ((CompositeConfiguration) config)
338                 .getConfiguration(0);
339         assertEquals("List delimiter was not set", ';', c.getListDelimiter());
340         List l = c.getList("test.mixed.array");
341         assertEquals("Wrong number of list elements", 2, l.size());
342         assertEquals("List delimiter was not applied", "b, c, d", l.get(1));
343     }
344 
345     private void checkUnionConfig() throws Exception
346     {
347         compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
348         assertEquals("Verify how many configs", 3, compositeConfiguration.getNumberOfConfigurations());
349 
350         // Test if union was constructed correctly
351         Object prop = compositeConfiguration.getProperty("tables.table.name");
352         assertTrue(prop instanceof Collection);
353         assertEquals(3, ((Collection) prop).size());
354         assertEquals("users", compositeConfiguration.getProperty("tables.table(0).name"));
355         assertEquals("documents", compositeConfiguration.getProperty("tables.table(1).name"));
356         assertEquals("tasks", compositeConfiguration.getProperty("tables.table(2).name"));
357 
358         prop = compositeConfiguration.getProperty("tables.table.fields.field.name");
359         assertTrue(prop instanceof Collection);
360         assertEquals(17, ((Collection) prop).size());
361 
362         assertEquals("smtp.mydomain.org", compositeConfiguration.getString("mail.host.smtp"));
363         assertEquals("pop3.mydomain.org", compositeConfiguration.getString("mail.host.pop"));
364 
365         // This was overriden
366         assertEquals("masterOfPost", compositeConfiguration.getString("mail.account.user"));
367         assertEquals("topsecret", compositeConfiguration.getString("mail.account.psswd"));
368 
369         // This was overriden, too, but not in additional section
370         assertEquals("enhanced factory", compositeConfiguration.getString("test.configuration"));
371     }
372 
373     private void checkCompositeConfiguration() throws Exception
374     {
375         compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
376 
377         assertEquals("Verify how many configs", 2, compositeConfiguration.getNumberOfConfigurations());
378         assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
379 
380         PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
381         assertNotNull("Make sure we have a fileName:" + pc.getFileName(), pc.getFileName());
382         assertTrue("Make sure we have loaded our key", pc.getBoolean("test.boolean"));
383         assertTrue("Make sure we have loaded our key", compositeConfiguration.getBoolean("test.boolean"));
384 
385         Object property = compositeConfiguration.getProperty("element2.subelement.subsubelement");
386         assertNull("Should have returned a null", property);
387     }
388 }