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.net.URL;
22  import java.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import junit.framework.TestCase;
27  import junitx.framework.ListAssert;
28  
29  import org.apache.commons.configuration.tree.DefaultExpressionEngine;
30  import org.apache.commons.configuration.tree.ExpressionEngine;
31  
32  import com.mockobjects.dynamic.Mock;
33  
34  /***
35   * Tests the ConfigurationUtils class
36   *
37   * @version $Revision: 710159 $, $Date: 2008-11-03 22:07:27 +0100 (Mo, 03 Nov 2008) $
38   */
39  public class TestConfigurationUtils extends TestCase
40  {
41      protected Configuration config = new BaseConfiguration();
42  
43      public void testToString()
44      {
45          String lineSeparator = System.getProperty("line.separator");
46  
47          assertEquals("String representation of an empty configuration", "", ConfigurationUtils.toString(config));
48  
49          config.setProperty("one", "1");
50          assertEquals("String representation of a configuration", "one=1", ConfigurationUtils.toString(config));
51  
52          config.setProperty("two", "2");
53          assertEquals("String representation of a configuration", "one=1" + lineSeparator + "two=2" , ConfigurationUtils.toString(config));
54  
55          config.clearProperty("one");
56          assertEquals("String representation of a configuration", "two=2" , ConfigurationUtils.toString(config));
57  
58          config.setProperty("one","1");
59          assertEquals("String representation of a configuration", "two=2" + lineSeparator + "one=1" , ConfigurationUtils.toString(config));
60      }
61  
62      public void testGetURL() throws Exception
63      {
64          assertEquals(
65              "http://localhost:8080/webapp/config/config.xml",
66              ConfigurationUtils
67                  .getURL(
68                      "http://localhost:8080/webapp/config/baseConfig.xml",
69                      "config.xml")
70                  .toString());
71          assertEquals(
72              "http://localhost:8080/webapp/config/config.xml",
73              ConfigurationUtils
74                  .getURL(
75                      "http://localhost:8080/webapp/baseConfig.xml",
76                      "config/config.xml")
77                  .toString());
78          URL url = ConfigurationUtils.getURL(null, "config.xml");
79          assertEquals("file", url.getProtocol());
80          assertEquals("", url.getHost());
81  
82          assertEquals(
83              "http://localhost:8080/webapp/config/config.xml",
84              ConfigurationUtils
85                  .getURL(
86                      "ftp://ftp.server.com/downloads/baseConfig.xml",
87                      "http://localhost:8080/webapp/config/config.xml")
88                  .toString());
89          assertEquals(
90              "http://localhost:8080/webapp/config/config.xml",
91              ConfigurationUtils
92                  .getURL(null, "http://localhost:8080/webapp/config/config.xml")
93                  .toString());
94          File absFile = new File("config.xml").getAbsoluteFile();
95          assertEquals(
96              absFile.toURL(),
97              ConfigurationUtils.getURL(
98                  "http://localhost:8080/webapp/config/baseConfig.xml",
99                  absFile.getAbsolutePath()));
100         assertEquals(
101             absFile.toURL(),
102             ConfigurationUtils.getURL(null, absFile.getAbsolutePath()));
103 
104 		assertEquals(absFile.toURL(),
105 		ConfigurationUtils.getURL(absFile.getParent(), "config.xml"));
106     }
107 
108     public void testGetBasePath() throws Exception
109     {
110         URL url = new URL("http://xyz.net/foo/bar.xml");
111         assertEquals("base path of " + url, "http://xyz.net/foo/", ConfigurationUtils.getBasePath(url));
112 
113         url = new URL("http://xyz.net/foo/");
114         assertEquals("base path of " + url, "http://xyz.net/foo/", ConfigurationUtils.getBasePath(url));
115 
116         url = new URL("http://xyz.net/foo");
117         assertEquals("base path of " + url, "http://xyz.net/", ConfigurationUtils.getBasePath(url));
118 
119         url = new URL("http://xyz.net/");
120         assertEquals("base path of " + url, "http://xyz.net/", ConfigurationUtils.getBasePath(url));
121 
122         url = new URL("http://xyz.net");
123         assertEquals("base path of " + url, "http://xyz.net", ConfigurationUtils.getBasePath(url));
124     }
125 
126     public void testGetFileName() throws Exception
127     {
128         assertEquals("file name for a null URL", null, ConfigurationUtils.getFileName(null));
129 
130         URL url = new URL("http://xyz.net/foo/");
131         assertEquals("file for a directory URL " + url, null, ConfigurationUtils.getFileName(url));
132 
133         url = new URL("http://xyz.net/foo/bar.xml");
134         assertEquals("file name for a valid URL " + url, "bar.xml", ConfigurationUtils.getFileName(url));
135     }
136 
137     public void testCopy()
138     {
139         // create the source configuration
140         Configuration conf1 = new BaseConfiguration();
141         conf1.addProperty("key1", "value1");
142         conf1.addProperty("key2", "value2");
143 
144         // create the target configuration
145         Configuration conf2 = new BaseConfiguration();
146         conf2.addProperty("key1", "value3");
147         conf2.addProperty("key2", "value4");
148 
149         // copy the source configuration into the target configuration
150         ConfigurationUtils.copy(conf1, conf2);
151 
152         assertEquals("'key1' property", "value1", conf2.getProperty("key1"));
153         assertEquals("'key2' property", "value2", conf2.getProperty("key2"));
154     }
155 
156     public void testAppend()
157     {
158         // create the source configuration
159         Configuration conf1 = new BaseConfiguration();
160         conf1.addProperty("key1", "value1");
161         conf1.addProperty("key2", "value2");
162 
163         // create the target configuration
164         Configuration conf2 = new BaseConfiguration();
165         conf2.addProperty("key1", "value3");
166         conf2.addProperty("key2", "value4");
167 
168         // append the source configuration to the target configuration
169         ConfigurationUtils.append(conf1, conf2);
170 
171         List expected = new ArrayList();
172         expected.add("value3");
173         expected.add("value1");
174         ListAssert.assertEquals("'key1' property", expected, conf2.getList("key1"));
175 
176         expected = new ArrayList();
177         expected.add("value4");
178         expected.add("value2");
179         ListAssert.assertEquals("'key2' property", expected, conf2.getList("key2"));
180     }
181 
182     public void testGetFile() throws Exception
183     {
184         File directory = new File("target");
185         File reference = new File(directory, "test.txt").getAbsoluteFile();
186 
187         assertEquals(reference, ConfigurationUtils.getFile(null, reference.getAbsolutePath()));
188         assertEquals(reference, ConfigurationUtils.getFile(directory.getAbsolutePath(), reference.getAbsolutePath()));
189         assertEquals(reference, ConfigurationUtils.getFile(directory.getAbsolutePath(), reference.getName()));
190         assertEquals(reference, ConfigurationUtils.getFile(directory.toURL().toString(), reference.getName()));
191         assertEquals(reference, ConfigurationUtils.getFile("invalid", reference.toURL().toString()));
192         assertEquals(reference, ConfigurationUtils.getFile(
193                 "jar:file:/C:/myjar.jar!/my-config.xml/someprops.properties",
194                 reference.getAbsolutePath()));
195     }
196 
197     public void testLocateWithNullTCCL() throws Exception
198     {
199         ClassLoader cl = Thread.currentThread().getContextClassLoader();
200         try
201         {
202             Thread.currentThread().setContextClassLoader(null);
203             assertNull(ConfigurationUtils.locate("abase", "aname"));
204             // This assert fails when maven 2 is used, so commented out
205             //assertNotNull(ConfigurationUtils.locate("test.xml"));
206         }
207         finally
208         {
209             Thread.currentThread().setContextClassLoader(cl);
210         }
211     }
212 
213     /***
214      * Tests converting a configuration into a hierarchical one.
215      */
216     public void testConvertToHierarchical()
217     {
218         Configuration conf = new BaseConfiguration();
219         for (int i = 0; i < 10; i++)
220         {
221             conf.addProperty("test" + i, "value" + i);
222             conf.addProperty("test.list", "item" + i);
223         }
224 
225         HierarchicalConfiguration hc = ConfigurationUtils
226                 .convertToHierarchical(conf);
227         for (Iterator it = conf.getKeys(); it.hasNext();)
228         {
229             String key = (String) it.next();
230             assertEquals("Wrong value for key " + key, conf.getProperty(key),
231                     hc.getProperty(key));
232         }
233     }
234 
235     /***
236      * Tests converting a configuration into a hierarchical one that is already
237      * hierarchical.
238      */
239     public void testConvertHierarchicalToHierarchical()
240     {
241         Configuration conf = new HierarchicalConfiguration();
242         conf.addProperty("test", "yes");
243         assertSame("Wrong configuration returned", conf, ConfigurationUtils
244                 .convertToHierarchical(conf));
245     }
246 
247     /***
248      * Tests converting a null configuration to a hierarchical one. The result
249      * should be null, too.
250      */
251     public void testConvertNullToHierarchical()
252     {
253         assertNull("Wrong conversion result for null config",
254                 ConfigurationUtils.convertToHierarchical(null));
255     }
256 
257     /***
258      * Tests converting a configuration into a hierarchical one if some of its
259      * properties contain escaped list delimiter characters.
260      */
261     public void testConvertToHierarchicalDelimiters()
262     {
263         Configuration conf = new BaseConfiguration();
264         conf.addProperty("test.key", "1//,2//,3");
265         assertEquals("Wrong property value", "1,2,3", conf
266                 .getString("test.key"));
267         HierarchicalConfiguration hc = ConfigurationUtils
268                 .convertToHierarchical(conf);
269         assertEquals("Escaped list delimiters not correctly handled", "1,2,3",
270                 hc.getString("test.key"));
271     }
272 
273     /***
274      * Tests converting a configuration to a hierarchical one using a specific
275      * expression engine.
276      */
277     public void testConvertToHierarchicalEngine()
278     {
279         Configuration conf = new BaseConfiguration();
280         conf.addProperty("test(a)", Boolean.TRUE);
281         conf.addProperty("test(b)", Boolean.FALSE);
282         DefaultExpressionEngine engine = new DefaultExpressionEngine();
283         engine.setIndexStart("[");
284         engine.setIndexEnd("]");
285         HierarchicalConfiguration hc = ConfigurationUtils
286                 .convertToHierarchical(conf, engine);
287         assertTrue("Wrong value for test(a)", hc.getBoolean("test(a)"));
288         assertFalse("Wrong value for test(b)", hc.getBoolean("test(b)"));
289     }
290 
291     /***
292      * Tests converting an already hierarchical configuration using an
293      * expression engine. The new engine should be set.
294      */
295     public void testConvertHierarchicalToHierarchicalEngine()
296     {
297         HierarchicalConfiguration hc = new HierarchicalConfiguration();
298         ExpressionEngine engine = new DefaultExpressionEngine();
299         assertSame("Created new configuration", hc, ConfigurationUtils
300                 .convertToHierarchical(hc, engine));
301         assertSame("Engine was not set", engine, hc.getExpressionEngine());
302     }
303 
304     /***
305      * Tests converting an already hierarchical configuration using a null
306      * expression engine. In this case the expression engine of the
307      * configuration should not be touched.
308      */
309     public void testConvertHierarchicalToHierarchicalNullEngine()
310     {
311         HierarchicalConfiguration hc = new HierarchicalConfiguration();
312         ExpressionEngine engine = new DefaultExpressionEngine();
313         hc.setExpressionEngine(engine);
314         assertSame("Created new configuration", hc, ConfigurationUtils
315                 .convertToHierarchical(hc, null));
316         assertSame("Expression engine was changed", engine, hc
317                 .getExpressionEngine());
318     }
319 
320     /***
321      * Tests converting a configuration to a hierarchical one that contains a
322      * property with multiple values. This test is related to CONFIGURATION-346.
323      */
324     public void testConvertToHierarchicalMultiValues()
325     {
326         BaseConfiguration config = new BaseConfiguration();
327         config.addProperty("test", "1,2,3");
328         HierarchicalConfiguration hc = ConfigurationUtils
329                 .convertToHierarchical(config);
330         assertEquals("Wrong value 1", 1, hc.getInt("test(0)"));
331         assertEquals("Wrong value 2", 2, hc.getInt("test(1)"));
332         assertEquals("Wrong value 3", 3, hc.getInt("test(2)"));
333     }
334 
335     /***
336      * Tests cloning a configuration that supports this operation.
337      */
338     public void testCloneConfiguration()
339     {
340         HierarchicalConfiguration conf = new HierarchicalConfiguration();
341         conf.addProperty("test", "yes");
342         HierarchicalConfiguration copy = (HierarchicalConfiguration) ConfigurationUtils
343                 .cloneConfiguration(conf);
344         assertNotSame("Same object was returned", conf, copy);
345         assertEquals("Property was not cloned", "yes", copy.getString("test"));
346     }
347 
348     /***
349      * Tests cloning a configuration that does not support this operation. This
350      * should cause an exception.
351      */
352     public void testCloneConfigurationNotSupported()
353     {
354         Configuration myNonCloneableConfig = new NonCloneableConfiguration();
355         try
356         {
357             ConfigurationUtils.cloneConfiguration(myNonCloneableConfig);
358             fail("Could clone non cloneable config!");
359         }
360         catch (ConfigurationRuntimeException crex)
361         {
362             // ok
363         }
364     }
365 
366     /***
367      * Tests cloning a <b>null</b> configuration.
368      */
369     public void testCloneConfigurationNull()
370     {
371         assertNull("Wrong return value", ConfigurationUtils
372                 .cloneConfiguration(null));
373     }
374 
375     /***
376      * Tests whether runtime exceptions can be enabled.
377      */
378     public void testEnableRuntimeExceptions()
379     {
380         PropertiesConfiguration config = new PropertiesConfiguration()
381         {
382             protected void addPropertyDirect(String key, Object value)
383             {
384                 // always simulate an exception
385                 fireError(EVENT_ADD_PROPERTY, key, value, new RuntimeException(
386                         "A faked exception!"));
387             }
388         };
389         config.clearErrorListeners();
390         ConfigurationUtils.enableRuntimeExceptions(config);
391         try
392         {
393             config.addProperty("test", "testValue");
394             fail("No runtime exception was thrown!");
395         }
396         catch (ConfigurationRuntimeException crex)
397         {
398             // ok
399         }
400     }
401 
402     /***
403      * Tries to enable runtime exceptions for a configurtion that does not
404      * inherit from EventSource. This should cause an exception.
405      */
406     public void testEnableRuntimeExceptionsInvalid()
407     {
408         try
409         {
410             ConfigurationUtils
411                     .enableRuntimeExceptions((Configuration) new Mock(
412                             Configuration.class).proxy());
413             fail("Could enable exceptions for non EventSource configuration!");
414         }
415         catch (IllegalArgumentException iex)
416         {
417             // ok
418         }
419     }
420 
421     /***
422      * Tries to enable runtime exceptions for a null configuration. This should
423      * cause an exception.
424      */
425     public void testEnableRuntimeExceptionsNull()
426     {
427         try
428         {
429             ConfigurationUtils.enableRuntimeExceptions(null);
430             fail("Could enable exceptions for a null configuration!");
431         }
432         catch (IllegalArgumentException iex)
433         {
434             //ok
435         }
436     }
437 }