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