1   /*
2    * Copyright 2004-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.net.URL;
20  import java.util.Properties;
21  import java.io.File;
22  import java.io.FileInputStream;
23  import java.io.FileOutputStream;
24  import java.io.FileWriter;
25  import java.io.IOException;
26  import java.io.PrintWriter;
27  
28  import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
29  
30  import junit.framework.TestCase;
31  
32  /***
33   * @author Emmanuel Bourg
34   * @version $Revision$, $Date: 2005-12-14 20:59:07 +0100 (Wed, 14 Dec 2005) $
35   */
36  public class TestFileConfiguration extends TestCase
37  {
38      private static final File TARGET_DIR = new File("target");
39  
40      public void testSetURL() throws Exception
41      {
42          // http URL
43          FileConfiguration config = new PropertiesConfiguration();
44          config.setURL(new URL("http://jakarta.apache.org/commons/configuration/index.html"));
45  
46          assertEquals("base path", "http://jakarta.apache.org/commons/configuration/", config
47                  .getBasePath());
48          assertEquals("file name", "index.html", config.getFileName());
49  
50          // file URL
51          config.setURL(new URL("file:/temp/test.properties"));
52          assertEquals("base path", "file:/temp/", config.getBasePath());
53          assertEquals("file name", "test.properties", config.getFileName());
54      }
55  
56      public void testSetURLWithParams() throws Exception
57      {
58          FileConfiguration config = new PropertiesConfiguration();
59          URL url = new URL(
60                  "http://issues.apache.org/bugzilla/show_bug.cgi?id=37886");
61          config.setURL(url);
62          assertEquals("Base path incorrect",
63                  "http://issues.apache.org/bugzilla/", config.getBasePath());
64          assertEquals("File name incorrect", "show_bug.cgi", config
65                  .getFileName());
66          assertEquals("URL was not correctly stored", url, config.getURL());
67      }
68  
69      public void testLocations() throws Exception
70      {
71          PropertiesConfiguration config = new PropertiesConfiguration();
72  
73          File directory = new File("conf");
74          File file = new File(directory, "test.properties");
75          config.setFile(file);
76          assertEquals(directory.getAbsolutePath(), config.getBasePath());
77          assertEquals("test.properties", config.getFileName());
78          assertEquals(file.getAbsolutePath(), config.getPath());
79  
80          config.setPath("conf" + File.separator + "test.properties");
81          assertEquals("test.properties", config.getFileName());
82          assertEquals(directory.getAbsolutePath(), config.getBasePath());
83          assertEquals(file.getAbsolutePath(), config.getPath());
84          assertEquals(file.toURL(), config.getURL());
85  
86          config.setBasePath(null);
87          config.setFileName("test.properties");
88          assertNull(config.getBasePath());
89          assertEquals("test.properties", config.getFileName());
90      }
91  
92      public void testCreateFile1() throws Exception
93      {
94          File file = new File("target/test-resources/foo/bar/test.properties");
95          if (file.exists())
96          {
97              file.delete();
98              file.getParentFile().delete();
99          }
100 
101         assertFalse("The file should not exist", file.exists());
102 
103         FileConfiguration config = new PropertiesConfiguration(file);
104         config.save();
105 
106         assertTrue("The file doesn't exist", file.exists());
107     }
108 
109     public void testCreateFile2() throws Exception
110     {
111         File file = new File("target/test-resources/foo/bar/test.properties");
112         if (file.exists())
113         {
114             file.delete();
115             file.getParentFile().delete();
116         }
117 
118         assertFalse("The file should not exist", file.exists());
119 
120         FileConfiguration config = new PropertiesConfiguration();
121         config.setFile(file);
122         config.save();
123 
124         assertTrue("The file doesn't exist", file.exists());
125     }
126 
127     public void testCreateFile3() throws Exception
128     {
129         File file = new File("target/test-resources/foo/bar/test.properties");
130         if (file.exists())
131         {
132             file.delete();
133             file.getParentFile().delete();
134         }
135 
136         assertFalse("The file should not exist", file.exists());
137 
138         FileConfiguration config = new PropertiesConfiguration();
139         config.save(file);
140 
141         assertTrue("The file doesn't exist", file.exists());
142     }
143 
144     /***
145      * Tests collaboration with ConfigurationFactory: Is the base path set on
146      * loading is valid in file based configurations?
147      *
148      * @throws Exception if an error occurs
149      */
150     public void testWithConfigurationFactory() throws Exception
151     {
152         File dir = new File("conf");
153         File file = new File(dir, "testFileConfiguration.properties");
154 
155         if (file.exists())
156         {
157             assertTrue("File cannot be deleted", file.delete());
158         }
159 
160         try
161         {
162             ConfigurationFactory factory = new ConfigurationFactory();
163             factory.setConfigurationURL(new File(dir, "testDigesterConfiguration2.xml").toURL());
164             CompositeConfiguration cc = (CompositeConfiguration) factory.getConfiguration();
165             PropertiesConfiguration config = null;
166             for (int i = 0; config == null; i++)
167             {
168                 if (cc.getConfiguration(i) instanceof PropertiesConfiguration)
169                 {
170                     config = (PropertiesConfiguration) cc.getConfiguration(i);
171                 }
172             }
173 
174             config.setProperty("test", "yes");
175             config.save(file.getName());
176             assertTrue(file.exists());
177             config = new PropertiesConfiguration();
178             config.setFile(file);
179             config.load();
180 
181             assertEquals("yes", config.getProperty("test"));
182             assertEquals("masterOfPost", config.getProperty("mail.account.user"));
183         }
184         finally
185         {
186             if (file.exists())
187             {
188                 assertTrue("File could not be deleted", file.delete());
189             }
190         }
191     }
192 
193     /***
194      * Tests if invalid URLs cause an exception.
195      */
196     public void testSaveInvalidURL() throws Exception
197     {
198         FileConfiguration config = new PropertiesConfiguration();
199         try
200         {
201             config.save(new URL("http://jakarta.apache.org"));
202             fail("Should throw a ConfigurationException!");
203         }
204         catch (ConfigurationException cex)
205         {
206             //fine
207         }
208 
209         try
210         {
211             config.save("http://www.apache.org");
212             fail("Should throw a ConfigurationException!");
213         }
214         catch (ConfigurationException cex)
215         {
216             //fine
217         }
218     }
219 
220     /***
221      * Tests if the URL used by the load() method is also used by save().
222      */
223     public void testFileOverwrite() throws Exception
224     {
225         FileOutputStream out = null;
226         FileInputStream in = null;
227         File tempFile = null;
228         try
229         {
230             String path = System.getProperties().getProperty("user.home");
231             File homeDir = new File(path);
232             tempFile = File.createTempFile("CONF", null, homeDir);
233             String fileName = tempFile.getName();
234             Properties props = new Properties();
235             props.setProperty("1", "one");
236             out = new FileOutputStream(tempFile);
237             props.store(out, "TestFileOverwrite");
238             out.close();
239             out = null;
240             FileConfiguration config = new PropertiesConfiguration(fileName);
241             config.load();
242             String value = config.getString("1");
243             assertTrue("one".equals(value));
244             config.setProperty("1", "two");
245             config.save();
246             props = new Properties();
247             in = new FileInputStream(tempFile);
248             props.load(in);
249             String value2 = props.getProperty("1");
250             assertTrue("two".equals(value2));
251         }
252         finally
253         {
254             if (out != null)
255             {
256                 try
257                 {
258                     out.close();
259                 }
260                 catch (IOException ioex)
261                 {
262                     ioex.printStackTrace();
263                 }
264             }
265             if (in != null)
266             {
267                 try
268                 {
269                     in.close();
270                 }
271                 catch (IOException ioex)
272                 {
273                     ioex.printStackTrace();
274                 }
275             }
276             if (tempFile.exists())
277             {
278                 assertTrue(tempFile.delete());
279             }
280         }
281     }
282 
283     /***
284      * Tests setting a file changed reloading strategy together with the auto
285      * save feature.
286      */
287     public void testReloadingWithAutoSave() throws Exception
288     {
289         File configFile = new File(TARGET_DIR, "test.properties");
290         PrintWriter out = null;
291 
292         try
293         {
294             out = new PrintWriter(new FileWriter(configFile));
295             out.println("a = one");
296             out.close();
297             out = null;
298 
299             PropertiesConfiguration config = new PropertiesConfiguration(
300                     configFile);
301             config.setReloadingStrategy(new FileChangedReloadingStrategy());
302             config.setAutoSave(true);
303 
304             assertEquals("one", config.getProperty("a"));
305             config.setProperty("b", "two");
306             assertEquals("one", config.getProperty("a"));
307         }
308         finally
309         {
310             if (out != null)
311             {
312                 out.close();
313             }
314             if (configFile.exists())
315             {
316                 assertTrue(configFile.delete());
317             }
318         }
319     }
320 
321     /***
322      * Tests loading and saving a configuration file with a complicated path
323      * name including spaces. (related to issue 35210)
324      */
325     public void testPathWithSpaces() throws Exception
326     {
327         File path = new File(TARGET_DIR, "path with spaces");
328         File confFile = new File(path, "config-test.properties");
329         PrintWriter out = null;
330 
331         try
332         {
333             if (!path.exists())
334             {
335                 assertTrue(path.mkdir());
336             }
337             out = new PrintWriter(new FileWriter(confFile));
338             out.println("saved = false");
339             out.close();
340             out = null;
341 
342             URL url = new URL(TARGET_DIR.toURL()
343                     + "path%20with%20spaces/config-test.properties");
344             PropertiesConfiguration config = new PropertiesConfiguration(url);
345             config.load();
346             assertFalse(config.getBoolean("saved"));
347 
348             config.setProperty("saved", Boolean.TRUE);
349             config.save();
350             config = new PropertiesConfiguration();
351             config.setFile(confFile);
352             config.load();
353             assertTrue(config.getBoolean("saved"));
354         }
355         finally
356         {
357             if (out != null)
358             {
359                 out.close();
360             }
361             if (confFile.exists())
362             {
363                 assertTrue(confFile.delete());
364             }
365             if (path.exists())
366             {
367                 assertTrue(path.delete());
368             }
369         }
370     }
371 
372     /***
373      * Tests the getFile() method.
374      */
375     public void testGetFile() throws ConfigurationException
376     {
377         FileConfiguration config = new PropertiesConfiguration();
378         assertNull(config.getFile());
379         File file = new File("conf/test.properties").getAbsoluteFile();
380         config.setFile(file);
381         assertEquals(file, config.getFile());
382         config.load();
383         assertEquals(file, config.getFile());
384     }
385 
386     /***
387      * Tests to invoke save() without explicitely setting a file name. This
388      * will cause an exception.
389      */
390     public void testSaveWithoutFileName() throws Exception
391     {
392         FileConfiguration config = new PropertiesConfiguration();
393         File file = new File("conf/test.properties");
394         config.load(file);
395         try
396         {
397             config.save();
398             fail("Could save config without setting a file name!");
399         }
400         catch(ConfigurationException cex)
401         {
402             //ok
403         }
404 
405         config = new PropertiesConfiguration();
406         config.load("conf/test.properties");
407         try
408         {
409             config.save();
410             fail("Could save config without setting a file name!");
411         }
412         catch(ConfigurationException cex)
413         {
414             //ok
415         }
416 
417         config = new PropertiesConfiguration();
418         config.load(file.toURL());
419         try
420         {
421             config.save();
422             fail("Could save config without setting a file name!");
423         }
424         catch(ConfigurationException cex)
425         {
426             //ok
427         }
428     }
429 
430     /***
431      * Checks that loading a directory instead of a file throws an exception.
432      */
433     public void testLoadDirectory()
434     {
435         PropertiesConfiguration config = new PropertiesConfiguration();
436 
437         try
438         {
439             config.load("target");
440             fail("Could load config from a directory!");
441         }
442         catch (ConfigurationException e)
443         {
444             // ok
445         }
446 
447         try
448         {
449             config.load(new File("target"));
450             fail("Could load config from a directory!");
451         }
452         catch (ConfigurationException e)
453         {
454             // ok
455         }
456 
457         try
458         {
459             new PropertiesConfiguration("target");
460             fail("Could load config from a directory!");
461         }
462         catch (ConfigurationException e)
463         {
464             // ok
465         }
466 
467         try
468         {
469             new PropertiesConfiguration(new File("target"));
470             fail("Could load config from a directory!");
471         }
472         catch (ConfigurationException e)
473         {
474             // ok
475         }
476     }
477 }