001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.configuration;
019    
020    import static org.junit.Assert.assertEquals;
021    import static org.junit.Assert.assertFalse;
022    import static org.junit.Assert.assertNotNull;
023    import static org.junit.Assert.assertNull;
024    import static org.junit.Assert.assertTrue;
025    import static org.junit.Assert.fail;
026    
027    import java.io.File;
028    import java.io.FileWriter;
029    import java.net.URL;
030    import java.util.Collection;
031    import java.util.List;
032    
033    import org.junit.Before;
034    import org.junit.Test;
035    import org.xml.sax.SAXException;
036    
037    /**
038     * Test the ConfigurationFactory.
039     *
040     * @version $Id: TestConfigurationFactory.java 1223011 2011-12-24 20:30:45Z oheger $
041     */
042    @SuppressWarnings("deprecation")
043    public class TestConfigurationFactory
044    {
045        /** The Files that we test with */
046        private URL digesterRules = getClass().getResource("/digesterRules.xml");
047        private File testDigesterFile = ConfigurationAssert.getTestFile("testDigesterConfiguration.xml");
048        private File testDigesterFileReverseOrder =
049                ConfigurationAssert.getTestFile("testDigesterConfigurationReverseOrder.xml");
050        private File testDigesterFileNamespaceAware =
051                ConfigurationAssert.getTestFile("testDigesterConfigurationNamespaceAware.xml");
052        private File testDigesterFileBasePath =
053                ConfigurationAssert.getTestFile("testDigesterConfigurationBasePath.xml");
054        private File testDigesterFileEnhanced =
055                ConfigurationAssert.getTestFile("testDigesterConfiguration2.xml");
056        private File testDigesterFileComplete =
057                ConfigurationAssert.getTestFile("testDigesterConfiguration3.xml");
058        private File testDigesterFileOptional =
059                ConfigurationAssert.getTestFile("testDigesterOptionalConfiguration.xml");
060        private File testDigesterFileOptionalEx =
061                ConfigurationAssert.getTestFile("testDigesterOptionalConfigurationEx.xml");
062        private File testDigesterFileSysProps =
063                ConfigurationAssert.getTestFile("testDigesterConfigurationSysProps.xml");
064        private File testDigesterFileInitProps =
065                ConfigurationAssert.getTestFile("testDigesterConfigurationWithProps.xml");
066    
067        private File testDigesterBadXML = ConfigurationAssert.getTestFile("testDigesterBadXML.xml");
068    
069        private String testBasePath = new File("conf").getAbsolutePath();
070    
071        private File testProperties = ConfigurationAssert.getTestFile("test.properties");
072        private File testAbsConfig = ConfigurationAssert.getOutFile("testAbsConfig.xml");
073    
074        private Configuration configuration;
075        private CompositeConfiguration compositeConfiguration;
076        private ConfigurationFactory factory;
077    
078        @Before
079        public void setUp() throws Exception
080        {
081            System.setProperty("java.naming.factory.initial", "org.apache.commons.configuration.MockInitialContextFactory");
082            factory = new ConfigurationFactory();
083        }
084    
085        @Test
086        public void testJNDI() throws Exception
087        {
088            JNDIConfiguration jndiConfiguration = new JNDIConfiguration();
089            Object o = jndiConfiguration.getProperty("test.boolean");
090            assertNotNull(o);
091            assertEquals("true", o.toString());
092        }
093    
094        @Test
095        public void testLoadingConfiguration() throws Exception
096        {
097            factory.setConfigurationFileName(testDigesterFile.toString());
098    
099            compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
100    
101            assertEquals("Number of configurations", 4, compositeConfiguration.getNumberOfConfigurations());
102            assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
103            assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration.getConfiguration(1).getClass());
104            assertEquals(XMLConfiguration.class, compositeConfiguration.getConfiguration(2).getClass());
105    
106            // check the first configuration
107            PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
108            assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc.getFileName());
109    
110            // check some properties
111            assertTrue("Make sure we have loaded our key", compositeConfiguration.getBoolean("test.boolean"));
112            assertEquals("I'm complex!", compositeConfiguration.getProperty("element2.subelement.subsubelement"));
113            assertEquals("property in the XMLPropertiesConfiguration", "value1", compositeConfiguration.getProperty("key1"));
114        }
115    
116        @Test
117        public void testLoadingConfigurationWithRulesXML() throws Exception
118        {
119            factory.setConfigurationFileName(testDigesterFile.toString());
120            factory.setDigesterRules(digesterRules);
121    
122            compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
123    
124            assertEquals("Number of configurations", 4, compositeConfiguration.getNumberOfConfigurations());
125            assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
126            //assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration.getConfiguration(1).getClass()); // doesn't work
127            assertEquals(XMLConfiguration.class, compositeConfiguration.getConfiguration(2).getClass());
128    
129            // check the first configuration
130            PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
131            assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc.getFileName());
132    
133            // check some properties
134            assertTrue("Make sure we have loaded our key", pc.getBoolean("test.boolean"));
135            assertTrue("Make sure we have loaded our key", compositeConfiguration.getBoolean("test.boolean"));
136    
137            assertEquals("I'm complex!", compositeConfiguration.getProperty("element2.subelement.subsubelement"));
138        }
139    
140        @Test
141        public void testLoadingConfigurationReverseOrder() throws Exception
142        {
143            factory.setConfigurationFileName(testDigesterFileReverseOrder.toString());
144    
145            configuration = factory.getConfiguration();
146    
147            assertEquals("8", configuration.getProperty("test.short"));
148    
149            factory.setConfigurationFileName(testDigesterFile.toString());
150    
151            configuration = factory.getConfiguration();
152            assertEquals("1", configuration.getProperty("test.short"));
153        }
154    
155        @Test
156        public void testLoadingConfigurationNamespaceAware() throws Exception
157        {
158            factory.setConfigurationFileName(testDigesterFileNamespaceAware.toString());
159            factory.setDigesterRuleNamespaceURI("namespace-one");
160    
161            checkCompositeConfiguration();
162        }
163    
164        @Test
165        public void testLoadingConfigurationBasePath() throws Exception
166        {
167            factory.setConfigurationFileName(testDigesterFileBasePath.toString());
168    
169            factory.setBasePath(testBasePath);
170    
171            //factory.setDigesterRuleNamespaceURI("namespace-one");
172    
173            checkCompositeConfiguration();
174        }
175    
176        @Test
177        public void testLoadingAdditional() throws Exception
178        {
179            factory.setConfigurationFileName(testDigesterFileEnhanced.toString());
180            factory.setBasePath(null);
181            checkUnionConfig();
182        }
183    
184        @Test
185        public void testLoadingURL() throws Exception
186        {
187            factory.setConfigurationURL(testDigesterFileEnhanced.toURL());
188            checkUnionConfig();
189        }
190    
191        @Test(expected = ConfigurationException.class)
192        public void testLoadingURLNonExisting() throws Exception
193        {
194            factory = new ConfigurationFactory();
195            File nonExistingFile = new File("conf/nonexisting.xml");
196            factory.setConfigurationURL(nonExistingFile.toURL());
197            factory.getConfiguration();
198        }
199    
200        @Test
201        public void testThrowingConfigurationInitializationException() throws Exception
202        {
203            factory.setConfigurationFileName(testDigesterBadXML.toString());
204            try
205            {
206                factory.getConfiguration();
207                fail("Should have throw an Exception");
208            }
209            catch (ConfigurationException cle)
210            {
211                assertTrue("Unexpected cause: " + cle.getCause(),
212                        cle.getCause() instanceof SAXException);
213            }
214        }
215    
216        // Tests if properties from all sources can be loaded
217        @Test
218        public void testAllConfiguration() throws Exception
219        {
220            factory.setConfigurationURL(testDigesterFileComplete.toURL());
221            Configuration config = factory.getConfiguration();
222            assertFalse(config.isEmpty());
223            assertTrue(config instanceof CompositeConfiguration);
224            CompositeConfiguration cc = (CompositeConfiguration) config;
225            assertTrue(cc.getNumberOfConfigurations() > 1);
226            // Currently fails, should be 4?  Only 2?
227            //assertEquals(4, cc.getNumberOfConfigurations());
228    
229            assertNotNull(config.getProperty("tables.table(0).fields.field(2).name"));
230            assertNotNull(config.getProperty("element2.subelement.subsubelement"));
231            assertEquals("value", config.getProperty("element3"));
232            assertEquals("foo", config.getProperty("element3[@name]"));
233            assertNotNull(config.getProperty("mail.account.user"));
234    
235            // test JNDIConfiguration
236            assertNotNull(config.getProperty("test.onlyinjndi"));
237            assertTrue(config.getBoolean("test.onlyinjndi"));
238    
239            Configuration subset = config.subset("test");
240            assertNotNull(subset.getProperty("onlyinjndi"));
241            assertTrue(subset.getBoolean("onlyinjndi"));
242    
243            // test SystemConfiguration
244            assertNotNull(config.getProperty("java.version"));
245            assertEquals(System.getProperty("java.version"), config.getString("java.version"));
246        }
247    
248        // Checks if optional configurations work
249        @Test
250        public void testOptionalConfigurations() throws Exception
251        {
252            factory.setConfigurationURL(testDigesterFileOptional.toURL());
253            Configuration config = factory.getConfiguration();
254            assertTrue(config.getBoolean("test.boolean"));
255            assertEquals("value", config.getProperty("element"));
256    
257            factory.setConfigurationURL(testDigesterFileOptionalEx.toURL());
258            try
259            {
260                config = factory.getConfiguration();
261                fail("Unexisting properties loaded!");
262            }
263            catch(ConfigurationException cex)
264            {
265                // fine
266            }
267        }
268    
269        // Checks if a file with an absolute path can be loaded
270        @Test
271        public void testLoadAbsolutePath() throws Exception
272        {
273            try
274            {
275                FileWriter out = null;
276                try
277                {
278                    out = new FileWriter(testAbsConfig);
279                    out.write("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>");
280                    out.write("<configuration>");
281                    out.write("<properties fileName=\"");
282                    out.write(testProperties.getAbsolutePath());
283                    out.write("\"/>");
284                    out.write("</configuration>");
285                }
286                finally
287                {
288                    if (out != null)
289                    {
290                        out.close();
291                    }
292                }
293    
294                factory.setConfigurationFileName(testAbsConfig.toString());
295                Configuration config = factory.getConfiguration();
296                assertTrue(config.getBoolean("configuration.loaded"));
297            }
298            finally
299            {
300                if (testAbsConfig.exists())
301                {
302                    testAbsConfig.delete();
303                }
304            }
305        }
306    
307        @Test
308        public void testBasePath() throws Exception
309        {
310            assertEquals(".", factory.getBasePath());
311            factory.setConfigurationFileName(testDigesterFile.getAbsolutePath());
312            // if no specific base path has been set, the base is determined
313            // from the file name
314            assertEquals(testDigesterFile.getParentFile().getAbsolutePath(),
315                    factory.getBasePath());
316    
317            String homeDir = System.getProperty("user.home");
318            factory = new ConfigurationFactory();
319            factory.setBasePath(homeDir);
320            factory.setConfigurationFileName(testDigesterFile.getAbsolutePath());
321            // if a base path was set, the file name does not play a role
322            assertEquals(homeDir, factory.getBasePath());
323    
324            factory = new ConfigurationFactory(testDigesterFile.getAbsolutePath());
325            assertEquals(testDigesterFile.getParentFile().getAbsolutePath(),
326                    factory.getBasePath());
327            factory.setBasePath(homeDir);
328            assertEquals(homeDir, factory.getBasePath());
329    
330            factory = new ConfigurationFactory();
331            factory.setConfigurationURL(testDigesterFile.toURL());
332            assertEquals(testDigesterFile.toURL().toString(), factory.getBasePath());
333        }
334    
335        // Tests if system properties can be resolved in the configuration
336        // definition
337        @Test
338        public void testLoadingWithSystemProperties() throws ConfigurationException
339        {
340            System.setProperty("config.file", "test.properties");
341            factory.setConfigurationFileName(testDigesterFileSysProps
342                    .getAbsolutePath());
343            Configuration config = factory.getConfiguration();
344            assertTrue("Configuration not loaded", config
345                    .getBoolean("configuration.loaded"));
346        }
347    
348        // Tests if the properties of a configuration object are correctly set
349        // before it is loaded.
350        @Test
351        public void testLoadInitProperties() throws ConfigurationException
352        {
353            factory.setConfigurationFileName(testDigesterFileInitProps
354                    .getAbsolutePath());
355            Configuration config = factory.getConfiguration();
356            PropertiesConfiguration c = (PropertiesConfiguration) ((CompositeConfiguration) config)
357                    .getConfiguration(0);
358            assertEquals("List delimiter was not set", ';', c.getListDelimiter());
359            List<Object> l = c.getList("test.mixed.array");
360            assertEquals("Wrong number of list elements", 2, l.size());
361            assertEquals("List delimiter was not applied", "b, c, d", l.get(1));
362        }
363    
364        private void checkUnionConfig() throws Exception
365        {
366            compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
367            assertEquals("Verify how many configs", 3, compositeConfiguration.getNumberOfConfigurations());
368    
369            // Test if union was constructed correctly
370            Object prop = compositeConfiguration.getProperty("tables.table.name");
371            assertTrue(prop instanceof Collection);
372            assertEquals(3, ((Collection<?>) prop).size());
373            assertEquals("users", compositeConfiguration.getProperty("tables.table(0).name"));
374            assertEquals("documents", compositeConfiguration.getProperty("tables.table(1).name"));
375            assertEquals("tasks", compositeConfiguration.getProperty("tables.table(2).name"));
376    
377            prop = compositeConfiguration.getProperty("tables.table.fields.field.name");
378            assertTrue(prop instanceof Collection);
379            assertEquals(17, ((Collection<?>) prop).size());
380    
381            assertEquals("smtp.mydomain.org", compositeConfiguration.getString("mail.host.smtp"));
382            assertEquals("pop3.mydomain.org", compositeConfiguration.getString("mail.host.pop"));
383    
384            // This was overriden
385            assertEquals("masterOfPost", compositeConfiguration.getString("mail.account.user"));
386            assertEquals("topsecret", compositeConfiguration.getString("mail.account.psswd"));
387    
388            // This was overriden, too, but not in additional section
389            assertEquals("enhanced factory", compositeConfiguration.getString("test.configuration"));
390        }
391    
392        private void checkCompositeConfiguration() throws Exception
393        {
394            compositeConfiguration = (CompositeConfiguration) factory.getConfiguration();
395    
396            assertEquals("Verify how many configs", 2, compositeConfiguration.getNumberOfConfigurations());
397            assertEquals(PropertiesConfiguration.class, compositeConfiguration.getConfiguration(0).getClass());
398    
399            PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration.getConfiguration(0);
400            assertNotNull("Make sure we have a fileName:" + pc.getFileName(), pc.getFileName());
401            assertTrue("Make sure we have loaded our key", pc.getBoolean("test.boolean"));
402            assertTrue("Make sure we have loaded our key", compositeConfiguration.getBoolean("test.boolean"));
403    
404            Object property = compositeConfiguration.getProperty("element2.subelement.subsubelement");
405            assertNull("Should have returned a null", property);
406        }
407    }