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
9
* http://www.apache.org/licenses/LICENSE-2.0
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.
18
package org.apache.commons.configuration;
20
import java.io.BufferedReader;
22
import java.io.FileOutputStream;
23
import java.io.FileReader;
24
import java.io.FileWriter;
25
import java.io.IOException;
26
import java.io.InputStream;
27
import java.io.OutputStream;
28
import java.io.PrintWriter;
29
import java.io.Reader;
30
import java.io.StringReader;
31
import java.io.StringWriter;
32
import java.io.Writer;
33
import java.net.HttpURLConnection;
35
import java.net.URLConnection;
36
import java.net.URLStreamHandler;
37
import java.util.ArrayList;
38
import java.util.HashSet;
39
import java.util.Iterator;
40
import java.util.List;
43
import junit.framework.TestCase;
45
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
46
import org.apache.commons.lang.SystemUtils;
49
* Test for loading and saving properties files.
51
* @version $Id: TestPropertiesConfiguration.java 951878 2010-06-06 15:56:47Z oheger $
53
public class TestPropertiesConfiguration extends TestCase
55
/** Constant for a test property name.*/
56
private static final String PROP_NAME = "testProperty";
58
/** Constant for a test property value.*/
59
private static final String PROP_VALUE = "value";
61
/** The configuration to be tested.*/
62
private PropertiesConfiguration conf;
64
/** The File that we test with */
65
private static String testProperties = new File("conf/test.properties").getAbsolutePath();
67
private static String testBasePath = new File("conf").getAbsolutePath();
68
private static String testBasePath2 = new File("conf").getAbsoluteFile().getParentFile().getAbsolutePath();
69
private static File testSavePropertiesFile = new File("target/testsave.properties");
71
protected void setUp() throws Exception
73
conf = new PropertiesConfiguration(testProperties);
75
// remove the test save file if it exists
76
if (testSavePropertiesFile.exists())
78
assertTrue("Test output file could not be deleted",
79
testSavePropertiesFile.delete());
83
public void testLoad() throws Exception
85
String loaded = conf.getString("configuration.loaded");
86
assertEquals("true", loaded);
90
* Tests if properties can be appended by simply calling load() another
93
public void testAppend() throws Exception
95
File file2 = new File("conf/threesome.properties");
97
assertEquals("aaa", conf.getString("test.threesome.one"));
98
assertEquals("true", conf.getString("configuration.loaded"));
102
* Tests that empty properties are treated as the empty string
103
* (rather than as null).
105
public void testEmpty() throws Exception
107
String empty = conf.getString("test.empty");
108
assertNotNull(empty);
109
assertEquals("", empty);
113
* Tests that references to other properties work
115
public void testReference() throws Exception
117
assertEquals("baseextra", conf.getString("base.reference"));
121
* test if includes properties get loaded too
123
public void testLoadInclude() throws Exception
125
String loaded = conf.getString("include.loaded");
126
assertEquals("true", loaded);
130
* test if includes properties from interpolated file
133
public void testLoadIncludeInterpol() throws Exception
135
String loaded = conf.getString("include.interpol.loaded");
136
assertEquals("true", loaded);
139
public void testSetInclude() throws Exception
141
// change the include key
142
PropertiesConfiguration.setInclude("import");
144
// load the configuration
145
PropertiesConfiguration conf = new PropertiesConfiguration();
146
conf.load("conf/test.properties");
148
// restore the previous value for the other tests
149
PropertiesConfiguration.setInclude("include");
151
assertNull(conf.getString("include.loaded"));
155
* Tests <code>List</code> parsing.
157
public void testList() throws Exception
159
List packages = conf.getList("packages");
160
// we should get 3 packages here
161
assertEquals(3, packages.size());
164
public void testSave() throws Exception
166
// add an array of strings to the configuration
167
conf.addProperty("string", "value1");
168
List list = new ArrayList();
169
for (int i = 1; i < 5; i++)
171
list.add("value" + i);
173
conf.addProperty("array", list);
175
// save the configuration
176
String filename = testSavePropertiesFile.getAbsolutePath();
179
assertTrue("The saved file doesn't exist", testSavePropertiesFile.exists());
181
// read the configuration and compare the properties
182
PropertiesConfiguration checkConfig = new PropertiesConfiguration(filename);
183
ConfigurationAssert.assertEquals(conf, checkConfig);
185
// Save it again, verifing a save with a filename works.
189
public void testSaveToCustomURL() throws Exception
191
// save the configuration to a custom URL
192
URL url = new URL("foo", "", 0, "./target/testsave-custom-url.properties", new FileURLStreamHandler());
195
// reload the configuration
196
Configuration config2 = new PropertiesConfiguration(url);
197
assertEquals("true", config2.getString("configuration.loaded"));
200
public void testInMemoryCreatedSave() throws Exception
202
PropertiesConfiguration pc = new PropertiesConfiguration();
203
// add an array of strings to the configuration
204
pc.addProperty("string", "value1");
205
List list = new ArrayList();
206
for (int i = 1; i < 5; i++)
208
list.add("value" + i);
210
pc.addProperty("array", list);
212
// save the configuration
213
String filename = testSavePropertiesFile.getAbsolutePath();
216
assertTrue("The saved file doesn't exist", testSavePropertiesFile.exists());
218
// read the configuration and compare the properties
219
PropertiesConfiguration checkConfig = new PropertiesConfiguration(filename);
220
ConfigurationAssert.assertEquals(pc, checkConfig);
222
// Save it again, verifing a save with a filename works.
227
* Tests saving a configuration when delimiter parsing is disabled.
229
public void testSaveWithDelimiterParsingDisabled() throws ConfigurationException
232
conf.setDelimiterParsingDisabled(true);
233
conf.addProperty("test.list", "a,b,c");
234
conf.addProperty("test.dirs", "C:\\Temp\\,D:\\Data\\");
235
conf.save(testSavePropertiesFile);
237
PropertiesConfiguration checkConfig = new PropertiesConfiguration();
238
checkConfig.setDelimiterParsingDisabled(true);
239
checkConfig.setFile(testSavePropertiesFile);
241
ConfigurationAssert.assertEquals(conf, checkConfig);
244
public void testSaveMissingFilename()
246
PropertiesConfiguration pc = new PropertiesConfiguration();
250
fail("Should have throw ConfigurationException");
252
catch (ConfigurationException ce)
259
* Tests if the base path is taken into account by the save() method.
260
* @throws Exception if an error occurs
262
public void testSaveWithBasePath() throws Exception
264
conf.setProperty("test", "true");
265
conf.setBasePath(testSavePropertiesFile.getParentFile().toURI().toURL()
267
conf.setFileName(testSavePropertiesFile.getName());
269
assertTrue(testSavePropertiesFile.exists());
273
* Tests whether the escape character for list delimiters can be itself
274
* escaped and survives a save operation.
276
public void testSaveEscapedEscapingCharacter()
277
throws ConfigurationException
279
conf.addProperty("test.dirs", "C:\\Temp\\\\,D:\\Data\\\\,E:\\Test\\");
280
List dirs = conf.getList("test.dirs");
281
assertEquals("Wrong number of list elements", 3, dirs.size());
282
conf.save(testSavePropertiesFile);
284
PropertiesConfiguration checkConfig = new PropertiesConfiguration(
285
testSavePropertiesFile);
286
ConfigurationAssert.assertEquals(conf, checkConfig);
289
public void testLoadViaProperty() throws Exception
291
PropertiesConfiguration pc = new PropertiesConfiguration();
292
pc.setFileName(testProperties);
295
assertTrue("Make sure we have multiple keys", pc.getBoolean("test.boolean"));
298
public void testLoadViaPropertyWithBasePath() throws Exception
300
PropertiesConfiguration pc = new PropertiesConfiguration();
301
pc.setBasePath(testBasePath);
302
pc.setFileName("test.properties");
305
assertTrue("Make sure we have multiple keys", pc.getBoolean("test.boolean"));
308
public void testLoadViaPropertyWithBasePath2() throws Exception
310
PropertiesConfiguration pc = new PropertiesConfiguration();
311
pc.setBasePath(testBasePath2);
312
pc.setFileName("conf/test.properties");
315
assertTrue("Make sure we have multiple keys", pc.getBoolean("test.boolean"));
317
pc = new PropertiesConfiguration();
318
pc.setBasePath(testBasePath2);
319
pc.setFileName("conf/test.properties");
322
assertTrue("Make sure we have multiple keys", pc.getBoolean("test.boolean"));
325
public void testLoadFromFile() throws Exception
327
File file = new File("conf/test.properties");
328
conf = new PropertiesConfiguration(file);
330
assertEquals("true", conf.getString("configuration.loaded"));
333
public void testLoadUnexistingFile()
337
conf = new PropertiesConfiguration("Unexisting file");
338
fail("Unexisting file was loaded.");
340
catch(ConfigurationException cex)
347
* Tests to load a file with enabled auto save mode.
349
public void testLoadWithAutoSave() throws Exception
351
setUpSavedProperties();
355
* Tests the auto save functionality when an existing property is modified.
357
public void testLoadWithAutoSaveAndSetExisting() throws Exception
359
setUpSavedProperties();
360
conf.setProperty("a", "moreThanOne");
365
* Tests the auto save functionality when a new property is added using the
366
* setProperty() method.
368
public void testLoadWithAutoSaveAndSetNew() throws Exception
370
setUpSavedProperties();
371
conf.setProperty("d", "four");
376
* Tests the auto save functionality when a new property is added using the
377
* addProperty() method.
379
public void testLoadWithAutoSaveAndAdd() throws Exception
381
setUpSavedProperties();
382
conf.addProperty("d", "four");
387
* Tests the auto save functionality when a property is removed.
389
public void testLoadWithAutoSaveAndClear() throws Exception
391
setUpSavedProperties();
392
conf.clearProperty("c");
393
PropertiesConfiguration checkConfig = checkSavedConfig();
394
assertFalse("The saved configuration contain the key '" + "c" + "'", checkConfig.containsKey("c"));
398
* Creates a properties file on disk. Used for testing load and save
401
* @throws IOException if an I/O error occurs
403
private void setUpSavedProperties() throws IOException, ConfigurationException
405
PrintWriter out = null;
409
out = new PrintWriter(new FileWriter(testSavePropertiesFile));
410
out.println("a = one");
411
out.println("b = two");
412
out.println("c = three");
416
conf = new PropertiesConfiguration();
417
conf.setAutoSave(true);
418
conf.setFile(testSavePropertiesFile);
420
assertEquals("one", conf.getString("a"));
421
assertEquals("two", conf.getString("b"));
422
assertEquals("three", conf.getString("c"));
434
* Helper method for testing a saved configuration. Reads in the file using
435
* a new instance and compares this instance with the original one.
437
* @return the newly created configuration instance
438
* @throws ConfigurationException if an error occurs
440
private PropertiesConfiguration checkSavedConfig()
441
throws ConfigurationException
443
PropertiesConfiguration checkConfig = new PropertiesConfiguration(testSavePropertiesFile);
444
ConfigurationAssert.assertEquals(conf, checkConfig);
448
public void testGetStringWithEscapedChars()
450
String property = conf.getString("test.unescape");
451
assertEquals("String with escaped characters", "This \n string \t contains \" escaped \\ characters", property);
454
public void testGetStringWithEscapedComma()
456
String property = conf.getString("test.unescape.list-separator");
457
assertEquals("String with an escaped list separator", "This string contains , an escaped list separator", property);
460
public void testUnescapeJava()
462
assertEquals("test\\,test", PropertiesConfiguration.unescapeJava("test\\,test", ','));
465
public void testEscapedKey() throws Exception
467
PropertiesConfiguration conf = new PropertiesConfiguration();
468
conf.load(new StringReader("\\u0066\\u006f\\u006f=bar"));
470
assertEquals("value of the 'foo' property", "bar", conf.getString("foo"));
473
public void testMixedArray()
475
String[] array = conf.getStringArray("test.mixed.array");
477
assertEquals("array length", 4, array.length);
478
assertEquals("1st element", "a", array[0]);
479
assertEquals("2nd element", "b", array[1]);
480
assertEquals("3rd element", "c", array[2]);
481
assertEquals("4th element", "d", array[3]);
484
public void testMultilines()
486
String property = "This is a value spread out across several adjacent "
487
+ "natural lines by escaping the line terminator with "
488
+ "a backslash character.";
490
assertEquals("'test.multilines' property", property, conf.getString("test.multilines"));
493
public void testChangingDefaultListDelimiter() throws Exception
495
PropertiesConfiguration pc = new PropertiesConfiguration(testProperties);
496
assertEquals(4, pc.getList("test.mixed.array").size());
498
char delimiter = PropertiesConfiguration.getDefaultListDelimiter();
499
PropertiesConfiguration.setDefaultListDelimiter('^');
500
pc = new PropertiesConfiguration(testProperties);
501
assertEquals(2, pc.getList("test.mixed.array").size());
502
PropertiesConfiguration.setDefaultListDelimiter(delimiter);
505
public void testChangingListDelimiter() throws Exception
507
PropertiesConfiguration pc1 = new PropertiesConfiguration(testProperties);
508
assertEquals(4, pc1.getList("test.mixed.array").size());
510
PropertiesConfiguration pc2 = new PropertiesConfiguration();
511
pc2.setListDelimiter('^');
512
pc2.setFileName(testProperties);
514
assertEquals("Should obtain the first value", "a", pc2.getString("test.mixed.array"));
515
assertEquals(2, pc2.getList("test.mixed.array").size());
518
public void testDisableListDelimiter() throws Exception
520
PropertiesConfiguration pc1 = new PropertiesConfiguration(testProperties);
521
assertEquals(4, pc1.getList("test.mixed.array").size());
523
PropertiesConfiguration pc2 = new PropertiesConfiguration();
524
pc2.setDelimiterParsingDisabled(true);
525
pc2.setFileName(testProperties);
527
assertEquals(2, pc2.getList("test.mixed.array").size());
531
* Tests escaping of an end of line with a backslash.
533
public void testNewLineEscaping()
535
List list = conf.getList("test.path");
536
assertEquals(3, list.size());
537
assertEquals("C:\\path1\\", list.get(0));
538
assertEquals("C:\\path2\\", list.get(1));
539
assertEquals("C:\\path3\\complex\\test\\", list.get(2));
543
* Tests if included files are loaded when the source lies in the class path.
545
public void testLoadIncludeFromClassPath() throws ConfigurationException
547
conf = new PropertiesConfiguration("test.properties");
548
assertEquals("true", conf.getString("include.loaded"));
552
* Test if the lines starting with # or ! are properly ignored.
554
public void testComment() {
555
assertFalse("comment line starting with '#' parsed as a property", conf.containsKey("#comment"));
556
assertFalse("comment line starting with '!' parsed as a property", conf.containsKey("!comment"));
560
* Check that key/value separators can be part of a key.
562
public void testEscapedKeyValueSeparator()
564
assertEquals("Escaped separator '=' not supported in keys", "foo", conf.getProperty("test.separator=in.key"));
565
assertEquals("Escaped separator ':' not supported in keys", "bar", conf.getProperty("test.separator:in.key"));
566
assertEquals("Escaped separator '\\t' not supported in keys", "foo", conf.getProperty("test.separator\tin.key"));
567
assertEquals("Escaped separator '\\f' not supported in keys", "bar", conf.getProperty("test.separator\fin.key"));
568
assertEquals("Escaped separator ' ' not supported in keys" , "foo", conf.getProperty("test.separator in.key"));
572
* Test all acceptable key/value separators ('=', ':' or white spaces).
574
public void testKeyValueSeparators() {
575
assertEquals("equal separator not properly parsed", "foo", conf.getProperty("test.separator.equal"));
576
assertEquals("colon separator not properly parsed", "foo", conf.getProperty("test.separator.colon"));
577
assertEquals("tab separator not properly parsed", "foo", conf.getProperty("test.separator.tab"));
578
assertEquals("formfeed separator not properly parsed", "foo", conf.getProperty("test.separator.formfeed"));
579
assertEquals("whitespace separator not properly parsed", "foo", conf.getProperty("test.separator.whitespace"));
583
* Tests including properties when they are loaded from a nested directory
586
public void testIncludeInSubDir() throws ConfigurationException
588
ConfigurationFactory factory = new ConfigurationFactory("conf/testFactoryPropertiesInclude.xml");
589
Configuration config = factory.getConfiguration();
590
assertEquals(true, config.getBoolean("deeptest"));
591
assertEquals(true, config.getBoolean("deepinclude"));
592
assertFalse(config.containsKey("deeptestinvalid"));
596
* Tests whether the correct line separator is used.
598
public void testLineSeparator() throws ConfigurationException
600
final String EOL = System.getProperty("line.separator");
601
conf = new PropertiesConfiguration();
602
conf.setHeader("My header");
603
conf.setProperty("prop", "value");
605
StringWriter out = new StringWriter();
607
String content = out.toString();
608
assertTrue("Header could not be found", content.indexOf("# My header"
610
assertTrue("Property could not be found", content.indexOf("prop = value" + EOL) > 0);
614
* Tests what happens if a reloading strategy's <code>reloadingRequired()</code>
615
* implementation accesses methods of the configuration that in turn cause a reload.
617
public void testReentrantReload()
619
conf.setProperty("shouldReload", Boolean.FALSE);
620
conf.setReloadingStrategy(new FileChangedReloadingStrategy()
622
public boolean reloadingRequired()
624
return configuration.getBoolean("shouldReload");
627
assertFalse("Property has wrong value", conf.getBoolean("shouldReload"));
631
* Tests accessing the layout object.
633
public void testGetLayout()
635
PropertiesConfigurationLayout layout = conf.getLayout();
636
assertNotNull("Layout is null", layout);
637
assertSame("Different object returned", layout, conf.getLayout());
638
conf.setLayout(null);
639
PropertiesConfigurationLayout layout2 = conf.getLayout();
640
assertNotNull("Layout 2 is null", layout2);
641
assertNotSame("Same object returned", layout, layout2);
645
* Tests the propertyLoaded() method for a simple property.
647
public void testPropertyLoaded() throws ConfigurationException
649
DummyLayout layout = new DummyLayout(conf);
650
conf.setLayout(layout);
651
conf.propertyLoaded("layoutLoadedProperty", "yes");
652
assertEquals("Layout's load() was called", 0, layout.loadCalls);
653
assertEquals("Property not added", "yes", conf.getString("layoutLoadedProperty"));
657
* Tests the propertyLoaded() method for an include property.
659
public void testPropertyLoadedInclude() throws ConfigurationException
661
DummyLayout layout = new DummyLayout(conf);
662
conf.setLayout(layout);
663
conf.propertyLoaded(PropertiesConfiguration.getInclude(), "testClasspath.properties,testEqual.properties");
664
assertEquals("Layout's load() was not correctly called", 2, layout.loadCalls);
665
assertFalse("Property was added", conf.containsKey(PropertiesConfiguration.getInclude()));
669
* Tests propertyLoaded() for an include property, when includes are
672
public void testPropertyLoadedIncludeNotAllowed() throws ConfigurationException
674
DummyLayout layout = new DummyLayout(conf);
675
conf.setLayout(layout);
676
conf.setIncludesAllowed(false);
677
conf.propertyLoaded(PropertiesConfiguration.getInclude(), "testClassPath.properties,testEqual.properties");
678
assertEquals("Layout's load() was called", 0, layout.loadCalls);
679
assertFalse("Property was added", conf.containsKey(PropertiesConfiguration.getInclude()));
683
* Tests whether comment lines are correctly detected.
685
public void testIsCommentLine()
687
assertTrue("Comment not detected", PropertiesConfiguration.isCommentLine("# a comment"));
688
assertTrue("Alternative comment not detected", PropertiesConfiguration.isCommentLine("! a comment"));
689
assertTrue("Comment with no space not detected", PropertiesConfiguration.isCommentLine("#a comment"));
690
assertTrue("Comment with leading space not detected", PropertiesConfiguration.isCommentLine(" ! a comment"));
691
assertFalse("Wrong comment", PropertiesConfiguration.isCommentLine(" a#comment"));
695
* Tests whether a properties configuration can be successfully cloned. It
696
* is especially checked whether the layout object is taken into account.
698
public void testClone() throws ConfigurationException
700
PropertiesConfiguration copy = (PropertiesConfiguration) conf.clone();
701
assertNotSame("Copy has same layout object", conf.getLayout(), copy.getLayout());
702
assertEquals("Wrong number of event listeners for original", 1, conf.getConfigurationListeners().size());
703
assertEquals("Wrong number of event listeners for clone", 1, copy.getConfigurationListeners().size());
704
assertSame("Wrong event listener for original", conf.getLayout(), conf.getConfigurationListeners().iterator().next());
705
assertSame("Wrong event listener for clone", copy.getLayout(), copy.getConfigurationListeners().iterator().next());
706
StringWriter outConf = new StringWriter();
708
StringWriter outCopy = new StringWriter();
710
assertEquals("Output from copy is different", outConf.toString(), outCopy.toString());
714
* Tests the clone() method when no layout object exists yet.
716
public void testCloneNullLayout()
718
conf = new PropertiesConfiguration();
719
PropertiesConfiguration copy = (PropertiesConfiguration) conf.clone();
720
assertNotSame("Layout objects are the same", conf.getLayout(), copy.getLayout());
724
* Tests saving a file-based configuration to a HTTP server.
726
public void testSaveToHTTPServerSuccess() throws Exception
728
MockHttpURLStreamHandler handler = new MockHttpURLStreamHandler(
729
HttpURLConnection.HTTP_OK, testSavePropertiesFile);
730
URL url = new URL(null, "http://jakarta.apache.org", handler);
732
MockHttpURLConnection con = handler.getMockConnection();
733
assertTrue("Wrong output flag", con.getDoOutput());
734
assertEquals("Wrong method", "PUT", con.getRequestMethod());
736
PropertiesConfiguration checkConfig = new PropertiesConfiguration(
737
testSavePropertiesFile);
738
ConfigurationAssert.assertEquals(conf, checkConfig);
742
* Tests saving a file-based configuration to a HTTP server when the server
743
* reports a failure. This should cause an exception.
745
public void testSaveToHTTPServerFail() throws Exception
747
MockHttpURLStreamHandler handler = new MockHttpURLStreamHandler(
748
HttpURLConnection.HTTP_BAD_REQUEST, testSavePropertiesFile);
749
URL url = new URL(null, "http://jakarta.apache.org", handler);
753
fail("Response code was not checked!");
755
catch (ConfigurationException cex)
757
assertTrue("Wrong root cause: " + cex,
758
cex.getCause() instanceof IOException);
763
* Test the creation of a file containing a '#' in its name. This test is
764
* skipped on Java 1.3 as it always fails.
766
public void testFileWithSharpSymbol() throws Exception
768
if (SystemUtils.isJavaVersionAtLeast(1.4f))
770
File file = new File("target/sharp#1.properties");
771
file.createNewFile();
773
PropertiesConfiguration conf = new PropertiesConfiguration(file);
776
assertTrue("Missing file " + file, file.exists());
781
* Tests initializing a properties configuration from a non existing file.
782
* There was a bug, which caused properties getting lost when later save()
785
public void testInitFromNonExistingFile() throws ConfigurationException
787
final String testProperty = "test.successfull";
788
conf = new PropertiesConfiguration(testSavePropertiesFile);
789
conf.addProperty(testProperty, Boolean.TRUE);
791
PropertiesConfiguration checkConfig = new PropertiesConfiguration(
792
testSavePropertiesFile);
793
assertTrue("Test property not found", checkConfig
794
.getBoolean(testProperty));
798
* Tests copying another configuration into the test configuration. This
799
* test ensures that the layout object is informed about the newly added
802
public void testCopyAndSave() throws ConfigurationException
804
Configuration copyConf = setUpCopyConfig();
806
checkCopiedConfig(copyConf);
810
* Tests appending a configuration to the test configuration. Again it has
811
* to be ensured that the layout object is correctly updated.
813
public void testAppendAndSave() throws ConfigurationException
815
Configuration copyConf = setUpCopyConfig();
816
conf.append(copyConf);
817
checkCopiedConfig(copyConf);
821
* Tests adding properties through a DataConfiguration. This is related to
824
public void testSaveWithDataConfig() throws ConfigurationException
826
conf = new PropertiesConfiguration(testSavePropertiesFile);
827
DataConfiguration dataConfig = new DataConfiguration(conf);
828
dataConfig.setProperty("foo", "bar");
829
assertEquals("Property not set", "bar", conf.getString("foo"));
832
PropertiesConfiguration config2 = new PropertiesConfiguration(
833
testSavePropertiesFile);
834
assertEquals("Property not saved", "bar", config2.getString("foo"));
838
* Tests whether the correct default encoding is used when loading a
839
* properties file. This test is related to CONFIGURATION-345.
841
public void testLoadWithDefaultEncoding() throws ConfigurationException
843
class PropertiesConfigurationTestImpl extends PropertiesConfiguration
847
public PropertiesConfigurationTestImpl(String fileName)
848
throws ConfigurationException
853
public void load(InputStream in, String encoding)
854
throws ConfigurationException
856
loadEncoding = encoding;
857
super.load(in, encoding);
861
PropertiesConfigurationTestImpl testConf = new PropertiesConfigurationTestImpl(
863
assertEquals("Default encoding not used", "ISO-8859-1",
864
testConf.loadEncoding);
868
* Tests whether a default IOFactory is set.
870
public void testGetIOFactoryDefault()
872
assertNotNull("No default IO factory", conf.getIOFactory());
876
* Tests setting the IOFactory to null. This should cause an exception.
878
public void testSetIOFactoryNull()
882
conf.setIOFactory(null);
883
fail("Could set IO factory to null!");
885
catch (IllegalArgumentException iex)
892
* Tests setting an IOFactory that uses a specialized reader.
894
public void testSetIOFactoryReader() throws ConfigurationException
896
final int propertyCount = 10;
898
conf.setIOFactory(new PropertiesConfiguration.IOFactory()
900
public PropertiesConfiguration.PropertiesReader createPropertiesReader(
901
Reader in, char delimiter)
903
return new PropertiesReaderTestImpl(in, delimiter,
907
public PropertiesConfiguration.PropertiesWriter createPropertiesWriter(
908
Writer out, char delimiter)
910
throw new UnsupportedOperationException("Unexpected call!");
914
for (int i = 1; i <= propertyCount; i++)
916
assertEquals("Wrong property value at " + i, PROP_VALUE + i, conf
917
.getString(PROP_NAME + i));
922
* Tests setting an IOFactory that uses a specialized writer.
924
public void testSetIOFactoryWriter() throws ConfigurationException, IOException
926
final PropertiesWriterTestImpl testWriter = new PropertiesWriterTestImpl(',');
927
conf.setIOFactory(new PropertiesConfiguration.IOFactory()
929
public PropertiesConfiguration.PropertiesReader createPropertiesReader(
930
Reader in, char delimiter)
932
throw new UnsupportedOperationException("Unexpected call!");
935
public PropertiesConfiguration.PropertiesWriter createPropertiesWriter(
936
Writer out, char delimiter)
941
conf.save(new StringWriter());
947
* Tests that the property separators are retained when saving the
950
public void testKeepSeparators() throws ConfigurationException, IOException
952
conf.save(testSavePropertiesFile);
953
final String[] separatorTests = {
954
"test.separator.equal = foo", "test.separator.colon : foo",
955
"test.separator.tab\tfoo", "test.separator.whitespace foo",
956
"test.separator.no.space=foo"
958
Set foundLines = new HashSet();
959
BufferedReader in = new BufferedReader(new FileReader(
960
testSavePropertiesFile));
964
while ((s = in.readLine()) != null)
966
for (int i = 0; i < separatorTests.length; i++)
968
if (separatorTests[i].equals(s))
979
assertEquals("No all separators were found: " + foundLines,
980
separatorTests.length, foundLines.size());
984
* Tests whether properties with slashes in their values can be saved. This
985
* test is related to CONFIGURATION-408.
987
public void testSlashEscaping() throws ConfigurationException
989
conf.setProperty(PROP_NAME, "http://www.apache.org");
990
StringWriter writer = new StringWriter();
992
String s = writer.toString();
993
assertTrue("Value not found: " + s, s.indexOf(PROP_NAME
994
+ " = http://www.apache.org") >= 0);
998
* Tests whether backslashes are correctly handled if lists are parsed. This
999
* test is related to CONFIGURATION-418.
1001
public void testBackslashEscapingInLists() throws ConfigurationException
1003
checkBackslashList("share2");
1004
checkBackslashList("share1");
1008
* Helper method for testing the content of a list with elements that
1009
* contain backslashes.
1011
* @param key the key
1013
private void checkBackslashList(String key)
1015
Object prop = conf.getProperty("test." + key);
1016
assertTrue("Not a list", prop instanceof List);
1017
List list = (List) prop;
1018
assertEquals("Wrong number of list elements", 2, list.size());
1019
final String prefix = "\\\\" + key;
1020
assertEquals("Wrong element 1", prefix + "a", list.get(0));
1021
assertEquals("Wrong element 2", prefix + "b", list.get(1));
1025
* Creates a configuration that can be used for testing copy operations.
1027
* @return the configuration to be copied
1029
private Configuration setUpCopyConfig()
1031
final int count = 25;
1032
Configuration result = new BaseConfiguration();
1033
for (int i = 1; i <= count; i++)
1035
result.addProperty("copyKey" + i, "copyValue" + i);
1041
* Tests whether the data of a configuration that was copied into the test
1042
* configuration is correctly saved.
1044
* @param copyConf the copied configuration
1045
* @throws ConfigurationException if an error occurs
1047
private void checkCopiedConfig(Configuration copyConf)
1048
throws ConfigurationException
1050
conf.save(testSavePropertiesFile);
1051
PropertiesConfiguration checkConf = new PropertiesConfiguration(
1052
testSavePropertiesFile);
1053
for (Iterator it = copyConf.getKeys(); it.hasNext();)
1055
String key = (String) it.next();
1056
assertEquals("Wrong value for property " + key, checkConf
1057
.getProperty(key), copyConf.getProperty(key));
1062
* A dummy layout implementation for checking whether certain methods are
1063
* correctly called by the configuration.
1065
static class DummyLayout extends PropertiesConfigurationLayout
1067
/** Stores the number how often load() was called. */
1068
public int loadCalls;
1070
public DummyLayout(PropertiesConfiguration config)
1075
public void load(Reader in) throws ConfigurationException
1082
* A mock implementation of a HttpURLConnection used for testing saving to
1085
static class MockHttpURLConnection extends HttpURLConnection
1087
/** The response code to return.*/
1088
private int responseCode;
1090
/** The output file. The output stream will point to this file.*/
1091
private File outputFile;
1093
protected MockHttpURLConnection(URL u, int respCode, File outFile)
1096
responseCode = respCode;
1097
outputFile = outFile;
1100
public void disconnect()
1104
public boolean usingProxy()
1109
public void connect() throws IOException
1113
public int getResponseCode() throws IOException
1115
return responseCode;
1118
public OutputStream getOutputStream() throws IOException
1120
return new FileOutputStream(outputFile);
1125
* A mock stream handler for working with the mock HttpURLConnection.
1127
static class MockHttpURLStreamHandler extends URLStreamHandler
1129
/** Stores the response code.*/
1130
private int responseCode;
1132
/** Stores the output file.*/
1133
private File outputFile;
1135
/** Stores the connection.*/
1136
private MockHttpURLConnection connection;
1138
public MockHttpURLStreamHandler(int respCode, File outFile)
1140
responseCode = respCode;
1141
outputFile = outFile;
1144
public MockHttpURLConnection getMockConnection()
1149
protected URLConnection openConnection(URL u) throws IOException
1151
connection = new MockHttpURLConnection(u, responseCode, outputFile);
1157
* A test PropertiesReader for testing whether a custom reader can be
1158
* injected. This implementation creates a configurable number of synthetic
1161
private static class PropertiesReaderTestImpl extends
1162
PropertiesConfiguration.PropertiesReader
1164
/** The number of test properties to be created. */
1165
private final int maxProperties;
1167
/** The current number of properties. */
1168
private int propertyCount;
1170
public PropertiesReaderTestImpl(Reader reader, char listDelimiter,
1173
super(reader, listDelimiter);
1174
assertEquals("Wrong list delimiter", ',', listDelimiter);
1175
maxProperties = maxProps;
1178
public String getPropertyName()
1180
return PROP_NAME + propertyCount;
1183
public String getPropertyValue()
1185
return PROP_VALUE + propertyCount;
1188
public boolean nextProperty() throws IOException
1191
return propertyCount <= maxProperties;
1196
* A test PropertiesWriter for testing whether a custom writer can be
1197
* injected. This implementation simply redirects all output into a test
1200
private static class PropertiesWriterTestImpl extends
1201
PropertiesConfiguration.PropertiesWriter
1203
public PropertiesWriterTestImpl(char delimiter) throws IOException
1205
super(new FileWriter(testSavePropertiesFile), delimiter);