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