blob: 5a3354b028f35f7a91e9d78e01404e8eccb5181a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.configuration;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import junit.framework.TestCase;
import org.apache.commons.configuration.reloading.FileAlwaysReloadingStrategy;
import org.apache.commons.configuration.reloading.InvariantReloadingStrategy;
import org.apache.commons.configuration.tree.ConfigurationNode;
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
import org.apache.commons.configuration.resolver.CatalogResolver;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* test for loading and saving xml properties files
*
* @version $Id$
*/
public class TestXMLConfiguration extends TestCase
{
private static final String CATALOG_FILES = "conf/catalog.xml";
/** Constant for the used encoding.*/
static final String ENCODING = "ISO-8859-1";
/** Constant for the test system ID.*/
static final String SYSTEM_ID = "properties.dtd";
/** Constant for the test public ID.*/
static final String PUBLIC_ID = "-//Commons Configuration//DTD Test Configuration 1.3//EN";
/** Constant for the DOCTYPE declaration.*/
static final String DOCTYPE_DECL = " PUBLIC \"" + PUBLIC_ID + "\" \"" + SYSTEM_ID + "\">";
/** Constant for the DOCTYPE prefix.*/
static final String DOCTYPE = "<!DOCTYPE ";
/** Constant for the transformer factory property.*/
static final String PROP_FACTORY = "javax.xml.transform.TransformerFactory";
/** The File that we test with */
private String testProperties = new File("conf/test.xml").getAbsolutePath();
private String testProperties2 = new File("conf/testDigesterConfigurationInclude1.xml").getAbsolutePath();
private String testBasePath = new File("conf").getAbsolutePath();
private File testSaveConf = new File("target/testsave.xml");
private File testSaveFile = new File("target/testsample2.xml");
private String testFile2 = new File("conf/sample.xml").getAbsolutePath();
private XMLConfiguration conf;
protected void setUp() throws Exception
{
conf = new XMLConfiguration();
conf.setFile(new File(testProperties));
conf.load();
removeTestFile();
}
public void testGetProperty()
{
assertEquals("value", conf.getProperty("element"));
}
public void testGetCommentedProperty()
{
assertEquals("", conf.getProperty("test.comment"));
}
public void testGetPropertyWithXMLEntity()
{
assertEquals("1<2", conf.getProperty("test.entity"));
}
public void testClearProperty() throws ConfigurationException, IOException
{
// test non-existent element
String key = "clearly";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
// test single element
conf.load();
key = "clear.element";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
// test single element with attribute
conf.load();
key = "clear.element2";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
key = "clear.element2[@id]";
assertNotNull(key, conf.getProperty(key));
assertNotNull(key, conf.getProperty(key));
// test non-text/cdata element
conf.load();
key = "clear.comment";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
// test cdata element
conf.load();
key = "clear.cdata";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
// test multiple sibling elements
conf.load();
key = "clear.list.item";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
key = "clear.list.item[@id]";
assertNotNull(key, conf.getProperty(key));
assertNotNull(key, conf.getProperty(key));
// test multiple, disjoined elements
conf.load();
key = "list.item";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
}
public void testgetProperty() {
// test non-leaf element
Object property = conf.getProperty("clear");
assertNull(property);
// test non-existent element
property = conf.getProperty("e");
assertNull(property);
// test non-existent element
property = conf.getProperty("element3[@n]");
assertNull(property);
// test single element
property = conf.getProperty("element");
assertNotNull(property);
assertTrue(property instanceof String);
assertEquals("value", property);
// test single attribute
property = conf.getProperty("element3[@name]");
assertNotNull(property);
assertTrue(property instanceof String);
assertEquals("foo", property);
// test non-text/cdata element
property = conf.getProperty("test.comment");
assertEquals("", property);
// test cdata element
property = conf.getProperty("test.cdata");
assertNotNull(property);
assertTrue(property instanceof String);
assertEquals("<cdata value>", property);
// test multiple sibling elements
property = conf.getProperty("list.sublist.item");
assertNotNull(property);
assertTrue(property instanceof List);
List list = (List)property;
assertEquals(2, list.size());
assertEquals("five", list.get(0));
assertEquals("six", list.get(1));
// test multiple, disjoined elements
property = conf.getProperty("list.item");
assertNotNull(property);
assertTrue(property instanceof List);
list = (List)property;
assertEquals(4, list.size());
assertEquals("one", list.get(0));
assertEquals("two", list.get(1));
assertEquals("three", list.get(2));
assertEquals("four", list.get(3));
// test multiple, disjoined attributes
property = conf.getProperty("list.item[@name]");
assertNotNull(property);
assertTrue(property instanceof List);
list = (List)property;
assertEquals(2, list.size());
assertEquals("one", list.get(0));
assertEquals("three", list.get(1));
}
public void testGetAttribute()
{
assertEquals("element3[@name]", "foo", conf.getProperty("element3[@name]"));
}
public void testClearAttribute() throws Exception
{
// test non-existent attribute
String key = "clear[@id]";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
// test single attribute
conf.load();
key = "clear.element2[@id]";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
key = "clear.element2";
assertNotNull(key, conf.getProperty(key));
assertNotNull(key, conf.getProperty(key));
// test multiple, disjoined attributes
conf.load();
key = "clear.list.item[@id]";
conf.clearProperty(key);
assertNull(key, conf.getProperty(key));
assertNull(key, conf.getProperty(key));
key = "clear.list.item";
assertNotNull(key, conf.getProperty(key));
assertNotNull(key, conf.getProperty(key));
}
public void testSetAttribute()
{
// replace an existing attribute
conf.setProperty("element3[@name]", "bar");
assertEquals("element3[@name]", "bar", conf.getProperty("element3[@name]"));
// set a new attribute
conf.setProperty("foo[@bar]", "value");
assertEquals("foo[@bar]", "value", conf.getProperty("foo[@bar]"));
conf.setProperty("name1","value1");
assertEquals("value1",conf.getProperty("name1"));
}
public void testAddAttribute()
{
conf.addProperty("element3[@name]", "bar");
List list = conf.getList("element3[@name]");
assertNotNull("null list", list);
assertTrue("'foo' element missing", list.contains("foo"));
assertTrue("'bar' element missing", list.contains("bar"));
assertEquals("list size", 2, list.size());
}
public void testAddObjectAttribute()
{
conf.addProperty("test.boolean[@value]", Boolean.TRUE);
assertTrue("test.boolean[@value]", conf.getBoolean("test.boolean[@value]"));
}
/**
* Tests setting an attribute on the root element.
*/
public void testSetRootAttribute() throws ConfigurationException
{
conf.setProperty("[@test]", "true");
assertEquals("Root attribute not set", "true", conf
.getString("[@test]"));
conf.save(testSaveConf);
XMLConfiguration checkConf = new XMLConfiguration();
checkConf.setFile(testSaveConf);
checkSavedConfig(checkConf);
assertTrue("Attribute not found after save", checkConf
.containsKey("[@test]"));
checkConf.setProperty("[@test]", "newValue");
checkConf.save();
conf = checkConf;
checkConf = new XMLConfiguration();
checkConf.setFile(testSaveConf);
checkSavedConfig(checkConf);
assertEquals("Attribute not modified after save", "newValue", checkConf
.getString("[@test]"));
}
/**
* Tests whether the configuration's root node is initialized with a
* reference to the corresponding XML element.
*/
public void testGetRootReference()
{
assertNotNull("Root node has no reference", conf.getRootNode()
.getReference());
}
public void testAddList()
{
conf.addProperty("test.array", "value1");
conf.addProperty("test.array", "value2");
List list = conf.getList("test.array");
assertNotNull("null list", list);
assertTrue("'value1' element missing", list.contains("value1"));
assertTrue("'value2' element missing", list.contains("value2"));
assertEquals("list size", 2, list.size());
}
public void testGetComplexProperty()
{
assertEquals("I'm complex!", conf.getProperty("element2.subelement.subsubelement"));
}
public void testSettingFileNames()
{
conf = new XMLConfiguration();
conf.setFileName(testProperties);
assertEquals(testProperties.toString(), conf.getFileName());
conf.setBasePath(testBasePath);
conf.setFileName("hello.xml");
assertEquals("hello.xml", conf.getFileName());
assertEquals(testBasePath.toString(), conf.getBasePath());
assertEquals(new File(testBasePath, "hello.xml"), conf.getFile());
conf.setBasePath(testBasePath);
conf.setFileName("subdir/hello.xml");
assertEquals("subdir/hello.xml", conf.getFileName());
assertEquals(testBasePath.toString(), conf.getBasePath());
assertEquals(new File(testBasePath, "subdir/hello.xml"), conf.getFile());
}
public void testLoad() throws Exception
{
conf = new XMLConfiguration();
conf.setFileName(testProperties);
conf.load();
assertEquals("I'm complex!", conf.getProperty("element2.subelement.subsubelement"));
}
public void testLoadWithBasePath() throws Exception
{
conf = new XMLConfiguration();
conf.setFileName("test.xml");
conf.setBasePath(testBasePath);
conf.load();
assertEquals("I'm complex!", conf.getProperty("element2.subelement.subsubelement"));
}
/**
* Tests constructing an XMLConfiguration from a non existing file and
* later saving to this file.
*/
public void testLoadAndSaveFromFile() throws Exception
{
// If the file does not exist, an empty config is created
conf = new XMLConfiguration(testSaveConf);
assertTrue(conf.isEmpty());
conf.addProperty("test", "yes");
conf.save();
conf = new XMLConfiguration(testSaveConf);
assertEquals("yes", conf.getString("test"));
}
/**
* Tests loading a configuration from a URL.
*/
public void testLoadFromURL() throws Exception
{
URL url = new File(testProperties).toURL();
conf = new XMLConfiguration(url);
assertEquals("value", conf.getProperty("element"));
assertEquals(url, conf.getURL());
}
/**
* Tests loading from a stream.
*/
public void testLoadFromStream() throws Exception
{
String xml = "<?xml version=\"1.0\"?><config><test>1</test></config>";
conf = new XMLConfiguration();
conf.load(new ByteArrayInputStream(xml.getBytes()));
assertEquals(1, conf.getInt("test"));
conf = new XMLConfiguration();
conf.load(new ByteArrayInputStream(xml.getBytes()), "UTF8");
assertEquals(1, conf.getInt("test"));
}
/**
* Tests loading a non well formed XML from a string.
*/
public void testLoadInvalidXML() throws Exception
{
String xml = "<?xml version=\"1.0\"?><config><test>1</rest></config>";
conf = new XMLConfiguration();
try
{
conf.load(new StringReader(xml));
fail("Could load invalid XML!");
}
catch(ConfigurationException cex)
{
//ok
}
}
public void testSetProperty() throws Exception
{
conf.setProperty("element.string", "hello");
assertEquals("'element.string'", "hello", conf.getString("element.string"));
assertEquals("XML value of element.string", "hello", conf.getProperty("element.string"));
}
public void testAddProperty()
{
// add a property to a non initialized xml configuration
XMLConfiguration config = new XMLConfiguration();
config.addProperty("test.string", "hello");
assertEquals("'test.string'", "hello", config.getString("test.string"));
}
public void testAddObjectProperty()
{
// add a non string property
conf.addProperty("test.boolean", Boolean.TRUE);
assertTrue("'test.boolean'", conf.getBoolean("test.boolean"));
}
public void testSave() throws Exception
{
// add an array of strings to the configuration
conf.addProperty("string", "value1");
for (int i = 1; i < 5; i++)
{
conf.addProperty("test.array", "value" + i);
}
// add an array of strings in an attribute
for (int i = 1; i < 5; i++)
{
conf.addProperty("test.attribute[@array]", "value" + i);
}
// add comma delimited lists with escaped delimiters
conf.addProperty("split.list5", "a\\,b\\,c");
conf.setProperty("element3", "value\\,value1\\,value2");
conf.setProperty("element3[@name]", "foo\\,bar");
// save the configuration
conf.save(testSaveConf.getAbsolutePath());
// read the configuration and compare the properties
XMLConfiguration checkConfig = new XMLConfiguration();
checkConfig.setFileName(testSaveConf.getAbsolutePath());
checkSavedConfig(checkConfig);
}
/**
* Tests saving to a URL.
*/
public void testSaveToURL() throws Exception
{
conf.save(testSaveConf.toURL());
XMLConfiguration checkConfig = new XMLConfiguration();
checkConfig.setFile(testSaveConf);
checkSavedConfig(checkConfig);
}
/**
* Tests saving to a stream.
*/
public void testSaveToStream() throws Exception
{
assertNull(conf.getEncoding());
conf.setEncoding("UTF8");
FileOutputStream out = null;
try
{
out = new FileOutputStream(testSaveConf);
conf.save(out);
}
finally
{
if(out != null)
{
out.close();
}
}
XMLConfiguration checkConfig = new XMLConfiguration();
checkConfig.setFile(testSaveConf);
checkSavedConfig(checkConfig);
try
{
out = new FileOutputStream(testSaveConf);
conf.save(out, "UTF8");
}
finally
{
if(out != null)
{
out.close();
}
}
checkConfig.clear();
checkSavedConfig(checkConfig);
}
public void testAutoSave() throws Exception
{
conf.setFile(testSaveConf);
assertFalse(conf.isAutoSave());
conf.setAutoSave(true);
assertTrue(conf.isAutoSave());
conf.setProperty("autosave", "ok");
// reload the configuration
XMLConfiguration conf2 = new XMLConfiguration(conf.getFile());
assertEquals("'autosave' property", "ok", conf2.getString("autosave"));
conf.clearTree("clear");
conf2 = new XMLConfiguration(conf.getFile());
Configuration sub = conf2.subset("clear");
assertTrue(sub.isEmpty());
}
/**
* Tests if a second file can be appended to a first.
*/
public void testAppend() throws Exception
{
conf = new XMLConfiguration();
conf.setFileName(testProperties);
conf.load();
conf.load(testProperties2);
assertEquals("value", conf.getString("element"));
assertEquals("tasks", conf.getString("table.name"));
conf.save(testSaveConf);
conf = new XMLConfiguration(testSaveConf);
assertEquals("value", conf.getString("element"));
assertEquals("tasks", conf.getString("table.name"));
assertEquals("application", conf.getString("table[@tableType]"));
}
/**
* Tests saving attributes (related to issue 34442).
*/
public void testSaveAttributes() throws Exception
{
conf.clear();
conf.load();
conf.save(testSaveConf);
conf = new XMLConfiguration();
conf.load(testSaveConf);
assertEquals("foo", conf.getString("element3[@name]"));
}
/**
* Tests collaboration between XMLConfiguration and a reloading strategy.
*/
public void testReloading() throws Exception
{
assertNotNull(conf.getReloadingStrategy());
assertTrue(conf.getReloadingStrategy() instanceof InvariantReloadingStrategy);
PrintWriter out = null;
try
{
out = new PrintWriter(new FileWriter(testSaveConf));
out.println("<?xml version=\"1.0\"?><config><test>1</test></config>");
out.close();
out = null;
conf.setFile(testSaveConf);
FileAlwaysReloadingStrategy strategy = new FileAlwaysReloadingStrategy();
strategy.setRefreshDelay(100);
conf.setReloadingStrategy(strategy);
assertEquals(strategy, conf.getReloadingStrategy());
assertEquals("Wrong file monitored", testSaveConf.getAbsolutePath(),
strategy.getMonitoredFile().getAbsolutePath());
conf.load();
assertEquals(1, conf.getInt("test"));
out = new PrintWriter(new FileWriter(testSaveConf));
out.println("<?xml version=\"1.0\"?><config><test>2</test></config>");
out.close();
out = null;
int value = conf.getInt("test");
assertEquals("No reloading performed", 2, value);
}
finally
{
if (out != null)
{
out.close();
}
}
}
public void testReloadingOOM() throws Exception
{
assertNotNull(conf.getReloadingStrategy());
assertTrue(conf.getReloadingStrategy() instanceof InvariantReloadingStrategy);
PrintWriter out = null;
try
{
out = new PrintWriter(new FileWriter(testSaveConf));
out.println("<?xml version=\"1.0\"?><config><test>1</test></config>");
out.close();
out = null;
conf.setFile(testSaveConf);
FileAlwaysReloadingStrategy strategy = new FileAlwaysReloadingStrategy();
strategy.setRefreshDelay(100);
conf.setReloadingStrategy(strategy);
conf.load();
assertEquals(1, conf.getInt("test"));
for (int i = 1; i < 50000; ++i)
{
assertEquals(1, conf.getInt("test"));
}
}
finally
{
if (out != null)
{
out.close();
}
}
}
/**
* Tests access to tag names with delimiter characters.
*/
public void testComplexNames()
{
assertEquals("Name with dot", conf.getString("complexNames.my..elem"));
assertEquals("Another dot", conf.getString("complexNames.my..elem.sub..elem"));
}
/**
* Tests setting a custom document builder.
*/
public void testCustomDocBuilder() throws Exception
{
// Load an invalid XML file with the default (non validating)
// doc builder. This should work...
conf = new XMLConfiguration();
conf.load(new File("conf/testValidateInvalid.xml"));
assertEquals("customers", conf.getString("table.name"));
assertFalse(conf.containsKey("table.fields.field(1).type"));
// Now create a validating doc builder and set it.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(new DefaultHandler() {
public void error(SAXParseException ex) throws SAXException
{
throw ex;
}
});
conf = new XMLConfiguration();
conf.setDocumentBuilder(builder);
try
{
conf.load(new File("conf/testValidateInvalid.xml"));
fail("Could load invalid file with validating set to true!");
}
catch(ConfigurationException ex)
{
//ok
}
// Try to load a valid document with a validating builder
conf = new XMLConfiguration();
conf.setDocumentBuilder(builder);
conf.load(new File("conf/testValidateValid.xml"));
assertTrue(conf.containsKey("table.fields.field(1).type"));
}
/**
* Tests the clone() method.
*/
public void testClone()
{
Configuration c = (Configuration) conf.clone();
assertTrue(c instanceof XMLConfiguration);
XMLConfiguration copy = (XMLConfiguration) c;
assertNotNull(conf.getDocument());
assertNull(copy.getDocument());
assertNotNull(conf.getFileName());
assertNull(copy.getFileName());
copy.setProperty("element3", "clonedValue");
assertEquals("value", conf.getString("element3"));
conf.setProperty("element3[@name]", "originalFoo");
assertEquals("foo", copy.getString("element3[@name]"));
}
/**
* Tests saving a configuration after cloning to ensure that the clone and
* the original are completely detachted.
*/
public void testCloneWithSave() throws ConfigurationException
{
XMLConfiguration c = (XMLConfiguration) conf.clone();
c.addProperty("test.newProperty", Boolean.TRUE);
conf.addProperty("test.orgProperty", Boolean.TRUE);
c.save(testSaveConf);
XMLConfiguration c2 = new XMLConfiguration(testSaveConf);
assertTrue("New property after clone() was not saved", c2
.getBoolean("test.newProperty"));
assertFalse("Property of original config was saved", c2
.containsKey("test.orgProperty"));
}
/**
* Tests the subset() method. There was a bug that calling subset() had
* undesired side effects.
*/
public void testSubset() throws ConfigurationException
{
conf = new XMLConfiguration();
conf.load(new File("conf/testHierarchicalXMLConfiguration.xml"));
conf.subset("tables.table(0)");
conf.save(testSaveConf);
conf = new XMLConfiguration(testSaveConf);
assertEquals("users", conf.getString("tables.table(0).name"));
}
/**
* Tests string properties with list delimiters and escaped delimiters.
*/
public void testSplitLists()
{
assertEquals("a", conf.getString("split.list3[@values]"));
assertEquals(2, conf.getMaxIndex("split.list3[@values]"));
assertEquals("a,b,c", conf.getString("split.list4[@values]"));
assertEquals("a", conf.getString("split.list1"));
assertEquals(2, conf.getMaxIndex("split.list1"));
assertEquals("a,b,c", conf.getString("split.list2"));
}
/**
* Tests string properties with list delimiters when delimiter parsing
* is disabled
*/
public void testDelimiterParsingDisabled() throws ConfigurationException {
XMLConfiguration conf2 = new XMLConfiguration();
conf2.setDelimiterParsingDisabled(true);
conf2.setFile(new File(testProperties));
conf2.load();
assertEquals("a,b,c", conf2.getString("split.list3[@values]"));
assertEquals(0, conf2.getMaxIndex("split.list3[@values]"));
assertEquals("a\\,b\\,c", conf2.getString("split.list4[@values]"));
assertEquals("a,b,c", conf2.getString("split.list1"));
assertEquals(0, conf2.getMaxIndex("split.list1"));
assertEquals("a\\,b\\,c", conf2.getString("split.list2"));
conf2 = new XMLConfiguration();
conf2.setExpressionEngine(new XPathExpressionEngine());
conf2.setDelimiterParsingDisabled(true);
conf2.setFile(new File(testProperties));
conf2.load();
assertEquals("a,b,c", conf2.getString("split/list3/@values"));
assertEquals(0, conf2.getMaxIndex("split/list3/@values"));
assertEquals("a\\,b\\,c", conf2.getString("split/list4/@values"));
assertEquals("a,b,c", conf2.getString("split/list1"));
assertEquals(0, conf2.getMaxIndex("split/list1"));
assertEquals("a\\,b\\,c", conf2.getString("split/list2"));
}
/**
* Tests string properties with list delimiters when delimiter parsing
* is disabled
*/
public void testSaveWithDelimiterParsingDisabled() throws ConfigurationException {
XMLConfiguration conf = new XMLConfiguration();
conf.setExpressionEngine(new XPathExpressionEngine());
conf.setDelimiterParsingDisabled(true);
conf.setAttributeSplittingDisabled(true);
conf.setFile(new File(testProperties));
conf.load();
assertEquals("a,b,c", conf.getString("split/list3/@values"));
assertEquals(0, conf.getMaxIndex("split/list3/@values"));
assertEquals("a\\,b\\,c", conf.getString("split/list4/@values"));
assertEquals("a,b,c", conf.getString("split/list1"));
assertEquals(0, conf.getMaxIndex("split/list1"));
assertEquals("a\\,b\\,c", conf.getString("split/list2"));
// save the configuration
conf.save(testSaveConf.getAbsolutePath());
// read the configuration and compare the properties
XMLConfiguration checkConfig = new XMLConfiguration();
checkConfig.setFileName(testSaveConf.getAbsolutePath());
checkSavedConfig(checkConfig);
XMLConfiguration config = new XMLConfiguration();
config.setFileName(testFile2);
//config.setExpressionEngine(new XPathExpressionEngine());
config.setDelimiterParsingDisabled(true);
config.setAttributeSplittingDisabled(true);
config.load();
config.setProperty("Employee[@attr1]", "3,2,1");
assertEquals("3,2,1", config.getString("Employee[@attr1]"));
config.save(testSaveFile.getAbsolutePath());
config = new XMLConfiguration();
config.setFileName(testSaveFile.getAbsolutePath());
//config.setExpressionEngine(new XPathExpressionEngine());
config.setDelimiterParsingDisabled(true);
config.setAttributeSplittingDisabled(true);
config.load();
config.setProperty("Employee[@attr1]", "1,2,3");
assertEquals("1,2,3", config.getString("Employee[@attr1]"));
config.setProperty("Employee[@attr2]", "one, two, three");
assertEquals("one, two, three", config.getString("Employee[@attr2]"));
config.setProperty("Employee.text", "a,b,d");
assertEquals("a,b,d", config.getString("Employee.text"));
config.setProperty("Employee.Salary", "100,000");
assertEquals("100,000", config.getString("Employee.Salary"));
config.save(testSaveFile.getAbsolutePath());
checkConfig = new XMLConfiguration();
checkConfig.setFileName(testSaveFile.getAbsolutePath());
checkConfig.setExpressionEngine(new XPathExpressionEngine());
checkConfig.setDelimiterParsingDisabled(true);
checkConfig.setAttributeSplittingDisabled(true);
checkConfig.load();
assertEquals("1,2,3", checkConfig.getString("Employee/@attr1"));
assertEquals("one, two, three", checkConfig.getString("Employee/@attr2"));
assertEquals("a,b,d", checkConfig.getString("Employee/text"));
assertEquals("100,000", checkConfig.getString("Employee/Salary"));
}
/**
* Tests whether a DTD can be accessed.
*/
public void testDtd() throws ConfigurationException
{
conf = new XMLConfiguration("testDtd.xml");
assertEquals("value1", conf.getString("entry(0)"));
assertEquals("test2", conf.getString("entry(1)[@key]"));
}
/**
* Tests DTD validation using the setValidating() method.
*/
public void testValidating() throws ConfigurationException
{
File nonValidFile = new File("conf/testValidateInvalid.xml");
conf = new XMLConfiguration();
assertFalse(conf.isValidating());
// Load a non valid XML document. Should work for isValidating() == false
conf.load(nonValidFile);
assertEquals("customers", conf.getString("table.name"));
assertFalse(conf.containsKey("table.fields.field(1).type"));
// Now set the validating flag to true
conf.setValidating(true);
try
{
conf.load(nonValidFile);
fail("Validation was not performed!");
}
catch(ConfigurationException cex)
{
//ok
}
}
/**
* Tests handling of empty elements.
*/
public void testEmptyElements() throws ConfigurationException
{
assertTrue(conf.containsKey("empty"));
assertEquals("", conf.getString("empty"));
conf.addProperty("empty2", "");
conf.setProperty("empty", "no more empty");
conf.save(testSaveConf);
conf = new XMLConfiguration(testSaveConf);
assertEquals("no more empty", conf.getString("empty"));
assertEquals("", conf.getProperty("empty2"));
}
/**
* Tests whether the encoding is correctly detected by the XML parser. This
* is done by loading an XML file with the encoding "UTF-16". If this
* encoding is not detected correctly, an exception will be thrown that
* "Content is not allowed in prolog". This test case is related to issue
* 34204.
*/
public void testLoadWithEncoding() throws ConfigurationException
{
File file = new File("conf/testEncoding.xml");
conf = new XMLConfiguration();
conf.load(file);
assertEquals("test3_yoge", conf.getString("yoge"));
}
/**
* Tests whether the encoding is written to the generated XML file.
*/
public void testSaveWithEncoding() throws ConfigurationException
{
conf = new XMLConfiguration();
conf.setProperty("test", "a value");
conf.setEncoding(ENCODING);
StringWriter out = new StringWriter();
conf.save(out);
assertTrue("Encoding was not written to file", out.toString().indexOf(
"encoding=\"" + ENCODING + "\"") >= 0);
}
/**
* Tests whether a default encoding is used if no specific encoding is set.
* According to the XSLT specification (http://www.w3.org/TR/xslt#output)
* this should be either UTF-8 or UTF-16.
*/
public void testSaveWithNullEncoding() throws ConfigurationException
{
conf = new XMLConfiguration();
conf.setProperty("testNoEncoding", "yes");
conf.setEncoding(null);
StringWriter out = new StringWriter();
conf.save(out);
assertTrue("Encoding was written to file", out.toString().indexOf(
"encoding=\"UTF-") >= 0);
}
/**
* Tests whether the DOCTYPE survives a save operation.
*/
public void testSaveWithDoctype() throws ConfigurationException
{
String content = "<?xml version=\"1.0\"?>"
+ DOCTYPE
+ "properties"
+ DOCTYPE_DECL
+ "<properties version=\"1.0\"><entry key=\"test\">value</entry></properties>";
StringReader in = new StringReader(content);
conf = new XMLConfiguration();
conf.setFileName("conf/testDtd.xml");
conf.load();
conf.clear();
conf.load(in);
assertEquals("Wrong public ID", PUBLIC_ID, conf.getPublicID());
assertEquals("Wrong system ID", SYSTEM_ID, conf.getSystemID());
StringWriter out = new StringWriter();
conf.save(out);
System.out.println(out.toString());
assertTrue("Did not find DOCTYPE", out.toString().indexOf(DOCTYPE) >= 0);
}
/**
* Tests setting public and system IDs for the D'OCTYPE and then saving the
* configuration. This should generate a DOCTYPE declaration.
*/
public void testSaveWithDoctypeIDs() throws ConfigurationException
{
assertNull("A public ID was found", conf.getPublicID());
assertNull("A system ID was found", conf.getSystemID());
conf.setPublicID(PUBLIC_ID);
conf.setSystemID(SYSTEM_ID);
StringWriter out = new StringWriter();
conf.save(out);
assertTrue("Did not find DOCTYPE", out.toString().indexOf(
DOCTYPE + "testconfig" + DOCTYPE_DECL) >= 0);
}
/**
* Tests saving a configuration when an invalid transformer factory is
* specified. In this case the error thrown by the TransformerFactory class
* should be caught and re-thrown as a ConfigurationException.
*/
public void testSaveWithInvalidTransformerFactory()
{
System.setProperty(PROP_FACTORY, "an.invalid.Class");
try
{
conf.save(testSaveConf);
fail("Could save with invalid TransformerFactory!");
}
catch (ConfigurationException cex)
{
// ok
}
finally
{
System.getProperties().remove(PROP_FACTORY);
}
}
/**
* Tests if reloads are recognized by subset().
*/
public void testSubsetWithReload() throws ConfigurationException
{
XMLConfiguration c = setUpReloadTest();
Configuration sub = c.subset("test");
assertEquals("New value not read", "newValue", sub.getString("entity"));
}
/**
* Tests if reloads are recognized by configurationAt().
*/
public void testConfigurationAtWithReload() throws ConfigurationException
{
XMLConfiguration c = setUpReloadTest();
HierarchicalConfiguration sub = c.configurationAt("test(0)");
assertEquals("New value not read", "newValue", sub.getString("entity"));
}
/**
* Tests if reloads are recognized by configurationsAt().
*/
public void testConfigurationsAtWithReload() throws ConfigurationException
{
XMLConfiguration c = setUpReloadTest();
List configs = c.configurationsAt("test");
assertEquals("New value not read", "newValue",
((HierarchicalConfiguration) configs.get(0))
.getString("entity"));
}
/**
* Tests whether reloads are recognized when querying the configuration's
* keys.
*/
public void testGetKeysWithReload() throws ConfigurationException
{
XMLConfiguration c = setUpReloadTest();
conf.addProperty("aNewKey", "aNewValue");
conf.save(testSaveConf);
boolean found = false;
for (Iterator it = c.getKeys(); it.hasNext();)
{
if ("aNewKey".equals(it.next()))
{
found = true;
}
}
assertTrue("Reload not performed", found);
}
/**
* Tests accessing properties when the XPATH expression engine is set.
*/
public void testXPathExpressionEngine()
{
conf.setExpressionEngine(new XPathExpressionEngine());
assertEquals("Wrong attribute value", "foo\"bar", conf
.getString("test[1]/entity/@name"));
conf.clear();
assertNull(conf.getString("test[1]/entity/@name"));
}
/**
* Tests the copy constructor.
*/
public void testInitCopy() throws ConfigurationException
{
XMLConfiguration copy = new XMLConfiguration(conf);
assertEquals("value", copy.getProperty("element"));
assertNull("Document was copied, too", copy.getDocument());
ConfigurationNode root = copy.getRootNode();
for(Iterator it = root.getChildren().iterator(); it.hasNext();)
{
ConfigurationNode node = (ConfigurationNode) it.next();
assertNull("Reference was not cleared", node.getReference());
}
removeTestFile();
copy.setFile(testSaveConf);
copy.save();
copy.clear();
checkSavedConfig(copy);
}
/**
* Tests setting text of the root element.
*/
public void testSetTextRootElement() throws ConfigurationException
{
conf.setProperty("", "Root text");
conf.save(testSaveConf);
XMLConfiguration copy = new XMLConfiguration();
copy.setFile(testSaveConf);
checkSavedConfig(copy);
}
/**
* Tests removing the text of the root element.
*/
public void testClearTextRootElement() throws ConfigurationException
{
final String xml = "<e a=\"v\">text</e>";
conf.clear();
StringReader in = new StringReader(xml);
conf.load(in);
assertEquals("Wrong text of root", "text", conf.getString(""));
conf.clearProperty("");
conf.save(testSaveConf);
XMLConfiguration copy = new XMLConfiguration();
copy.setFile(testSaveConf);
checkSavedConfig(copy);
}
/**
* Tests list nodes with multiple values and attributes.
*/
public void testListWithAttributes()
{
assertEquals("Wrong number of <a> elements", 6, conf.getList(
"attrList.a").size());
assertEquals("Wrong value of first element", "ABC", conf
.getString("attrList.a(0)"));
assertEquals("Wrong value of first name attribute", "x", conf
.getString("attrList.a(0)[@name]"));
assertEquals("Wrong number of name attributes", 5, conf.getList(
"attrList.a[@name]").size());
}
/**
* Tests a list node with attributes that has multiple values separated by
* the list delimiter. In this scenario the attribute should be added to the
* node with the first value.
*/
public void testListWithAttributesMultiValue()
{
assertEquals("Wrong value of 2nd element", "1", conf
.getString("attrList.a(1)"));
assertEquals("Wrong value of 2nd name attribute", "y", conf
.getString("attrList.a(1)[@name]"));
for (int i = 2; i <= 3; i++)
{
assertEquals("Wrong value of element " + (i + 1), i, conf
.getInt("attrList.a(" + i + ")"));
assertFalse("element " + (i + 1) + " has attribute", conf
.containsKey("attrList.a(2)[@name]"));
}
}
/**
* Tests a list node with a multi-value attribute and multiple values. All
* attribute values should be assigned to the node with the first value.
*/
public void testListWithMultiAttributesMultiValue()
{
for (int i = 1; i <= 2; i++)
{
assertEquals("Wrong value of multi-valued node", "value" + i, conf
.getString("attrList.a(" + (i + 3) + ")"));
}
List attrs = conf.getList("attrList.a(4)[@name]");
final String attrVal = "uvw";
assertEquals("Wrong number of name attributes", attrVal.length(), attrs
.size());
for (int i = 0; i < attrVal.length(); i++)
{
assertEquals("Wrong value for attribute " + i, String
.valueOf(attrVal.charAt(i)), attrs.get(i));
}
assertEquals("Wrong value of test attribute", "yes", conf
.getString("attrList.a(4)[@test]"));
assertFalse("Name attribute for 2nd value", conf
.containsKey("attrList.a(5)[@name]"));
assertFalse("Test attribute for 2nd value", conf
.containsKey("attrList.a(5)[@test]"));
}
/**
* Tests whether the auto save mechanism is triggered by changes at a
* subnode configuration.
*/
public void testAutoSaveWithSubnodeConfig() throws ConfigurationException
{
final String newValue = "I am autosaved";
conf.setFile(testSaveConf);
conf.setAutoSave(true);
Configuration sub = conf.configurationAt("element2.subelement");
sub.setProperty("subsubelement", newValue);
assertEquals("Change not visible to parent", newValue, conf
.getString("element2.subelement.subsubelement"));
XMLConfiguration conf2 = new XMLConfiguration(testSaveConf);
assertEquals("Change was not saved", newValue, conf2
.getString("element2.subelement.subsubelement"));
}
/**
* Tests whether a subnode configuration created from another subnode
* configuration of a XMLConfiguration can trigger the auto save mechanism.
*/
public void testAutoSaveWithSubSubnodeConfig() throws ConfigurationException
{
final String newValue = "I am autosaved";
conf.setFile(testSaveConf);
conf.setAutoSave(true);
SubnodeConfiguration sub1 = conf.configurationAt("element2");
SubnodeConfiguration sub2 = sub1.configurationAt("subelement");
sub2.setProperty("subsubelement", newValue);
assertEquals("Change not visible to parent", newValue, conf
.getString("element2.subelement.subsubelement"));
XMLConfiguration conf2 = new XMLConfiguration(testSaveConf);
assertEquals("Change was not saved", newValue, conf2
.getString("element2.subelement.subsubelement"));
}
/**
* Tests saving and loading a configuration when delimiter parsing is
* disabled.
*/
public void testSaveDelimiterParsingDisabled()
throws ConfigurationException
{
checkSaveDelimiterParsingDisabled("list.delimiter.test");
}
/**
* Tests saving and loading a configuration when delimiter parsing is
* disabled and attributes are involved.
*/
public void testSaveDelimiterParsingDisabledAttrs()
throws ConfigurationException
{
checkSaveDelimiterParsingDisabled("list.delimiter.test[@attr]");
}
/**
* Helper method for testing saving and loading a configuration when
* delimiter parsing is disabled.
*
* @param key the key to be checked
* @throws ConfigurationException if an error occurs
*/
private void checkSaveDelimiterParsingDisabled(String key)
throws ConfigurationException
{
conf.clear();
conf.setDelimiterParsingDisabled(true);
conf.load();
conf.setProperty(key, "C:\\Temp\\,C:\\Data\\");
conf.addProperty(key, "a,b,c");
conf.save(testSaveConf);
XMLConfiguration checkConf = new XMLConfiguration();
checkConf.setDelimiterParsingDisabled(true);
checkConf.setFile(testSaveConf);
checkSavedConfig(checkConf);
}
/**
* Tests multiple attribute values in delimiter parsing disabled mode.
*/
public void testDelimiterParsingDisabledMultiAttrValues() throws ConfigurationException
{
conf.clear();
conf.setDelimiterParsingDisabled(true);
conf.load();
List expr = conf.getList("expressions[@value]");
assertEquals("Wrong list size", 2, expr.size());
assertEquals("Wrong element 1", "a || (b && c)", expr.get(0));
assertEquals("Wrong element 2", "!d", expr.get(1));
}
/**
* Tests using multiple attribute values, which are partly escaped when
* delimiter parsing is not disabled.
*/
public void testMultipleAttrValuesEscaped() throws ConfigurationException
{
conf.addProperty("test.dir[@name]", "C:\\Temp\\");
conf.addProperty("test.dir[@name]", "C:\\Data\\");
conf.save(testSaveConf);
XMLConfiguration checkConf = new XMLConfiguration();
checkConf.setFile(testSaveConf);
checkSavedConfig(checkConf);
}
/**
* Tests a combination of auto save = true and an associated reloading
* strategy.
*/
public void testAutoSaveWithReloadingStrategy() throws ConfigurationException
{
conf.setFile(testSaveConf);
conf.save();
conf.setReloadingStrategy(new FileAlwaysReloadingStrategy());
conf.setAutoSave(true);
assertEquals("Value not found", "value", conf.getProperty("element"));
}
/**
* Tests adding nodes from another configuration.
*/
public void testAddNodesCopy() throws ConfigurationException
{
XMLConfiguration c2 = new XMLConfiguration(testProperties2);
conf.addNodes("copiedProperties", c2.getRootNode().getChildren());
conf.save(testSaveConf);
XMLConfiguration checkConf = new XMLConfiguration();
checkConf.setFile(testSaveConf);
checkSavedConfig(checkConf);
}
/**
* Tests whether the addNodes() method triggers an auto save.
*/
public void testAutoSaveAddNodes() throws ConfigurationException
{
conf.setFile(testSaveConf);
conf.setAutoSave(true);
HierarchicalConfiguration.Node node = new HierarchicalConfiguration.Node(
"addNodesTest", Boolean.TRUE);
Collection nodes = new ArrayList(1);
nodes.add(node);
conf.addNodes("test.autosave", nodes);
XMLConfiguration c2 = new XMLConfiguration(testSaveConf);
assertTrue("Added nodes are not saved", c2
.getBoolean("test.autosave.addNodesTest"));
}
/**
* Tests saving a configuration after a node was added. Test for
* CONFIGURATION-294.
*/
public void testAddNodesAndSave() throws ConfigurationException
{
ConfigurationNode node = new HierarchicalConfiguration.Node("test");
ConfigurationNode child = new HierarchicalConfiguration.Node("child");
node.addChild(child);
ConfigurationNode attr = new HierarchicalConfiguration.Node("attr");
node.addAttribute(attr);
ConfigurationNode node2 = conf.createNode("test2");
Collection nodes = new ArrayList(2);
nodes.add(node);
nodes.add(node2);
conf.addNodes("add.nodes", nodes);
conf.setFile(testSaveConf);
conf.save();
conf.setProperty("add.nodes.test", "true");
conf.setProperty("add.nodes.test.child", "yes");
conf.setProperty("add.nodes.test[@attr]", "existing");
conf.setProperty("add.nodes.test2", "anotherValue");
conf.save();
XMLConfiguration c2 = new XMLConfiguration(testSaveConf);
assertEquals("Value was not saved", "true", c2
.getString("add.nodes.test"));
assertEquals("Child value was not saved", "yes", c2
.getString("add.nodes.test.child"));
assertEquals("Attr value was not saved", "existing", c2
.getString("add.nodes.test[@attr]"));
assertEquals("Node2 not saved", "anotherValue", c2
.getString("add.nodes.test2"));
}
/**
* Tests registering the publicId of a DTD.
*/
public void testRegisterEntityId() throws ConfigurationException,
IOException
{
File dtdFile = new File("conf/properties.dtd");
final String publicId = "http://commons.apache.org/test/properties.dtd";
conf = new XMLConfiguration("testDtd.xml");
conf.setPublicID(publicId);
conf.save(testSaveConf);
XMLConfiguration checkConfig = new XMLConfiguration();
checkConfig.setFile(testSaveConf);
checkConfig.registerEntityId(publicId, dtdFile.toURL());
checkConfig.setValidating(true);
checkSavedConfig(checkConfig);
}
/**
* Tries to register a null public ID. This should cause an exception.
*/
public void testRegisterEntityIdNull() throws IOException
{
try
{
conf.registerEntityId(null, new URL("http://commons.apache.org"));
fail("Could register null public ID!");
}
catch (IllegalArgumentException iex)
{
// ok
}
}
/**
* Tests saving a configuration that was created from a hierarchical
* configuration. This test exposes bug CONFIGURATION-301.
*/
public void testSaveAfterCreateWithCopyConstructor()
throws ConfigurationException
{
HierarchicalConfiguration hc = conf.configurationAt("element2");
conf = new XMLConfiguration(hc);
conf.save(testSaveConf);
XMLConfiguration checkConfig = new XMLConfiguration();
checkConfig.setFile(testSaveConf);
checkSavedConfig(checkConfig);
assertEquals("Wrong name of root element", "element2", checkConfig
.getRootElementName());
}
/**
* Tests whether the name of the root element is copied when a configuration
* is created using the copy constructor.
*/
public void testCopyRootName() throws ConfigurationException
{
final String rootName = "rootElement";
final String xml = "<" + rootName + "><test>true</test></" + rootName
+ ">";
conf.clear();
conf.load(new StringReader(xml));
XMLConfiguration copy = new XMLConfiguration(conf);
assertEquals("Wrong name of root element", rootName, copy
.getRootElementName());
copy.save(testSaveConf);
copy = new XMLConfiguration(testSaveConf);
assertEquals("Wrong name of root element after save", rootName, copy
.getRootElementName());
}
/**
* Tests whether the name of the root element is copied for a configuration
* for which not yet a document exists.
*/
public void testCopyRootNameNoDocument() throws ConfigurationException
{
final String rootName = "rootElement";
conf = new XMLConfiguration();
conf.setRootElementName(rootName);
conf.setProperty("test", Boolean.TRUE);
XMLConfiguration copy = new XMLConfiguration(conf);
assertEquals("Wrong name of root element", rootName, copy
.getRootElementName());
copy.save(testSaveConf);
copy = new XMLConfiguration(testSaveConf);
assertEquals("Wrong name of root element after save", rootName, copy
.getRootElementName());
}
/**
* Tests adding an attribute node using the addNodes() method.
*/
public void testAddNodesAttributeNode()
{
conf.addProperty("testAddNodes.property[@name]", "prop1");
conf.addProperty("testAddNodes.property(0).value", "value1");
conf.addProperty("testAddNodes.property(-1)[@name]", "prop2");
conf.addProperty("testAddNodes.property(1).value", "value2");
Collection nodes = new ArrayList();
nodes.add(new HierarchicalConfiguration.Node("property"));
conf.addNodes("testAddNodes", nodes);
nodes.clear();
ConfigurationNode nd = new HierarchicalConfiguration.Node("name",
"prop3");
nd.setAttribute(true);
nodes.add(nd);
conf.addNodes("testAddNodes.property(2)", nodes);
assertEquals("Attribute not added", "prop3", conf
.getString("testAddNodes.property(2)[@name]"));
}
/**
* Tests whether spaces are preserved when the xml:space attribute is set.
*/
public void testPreserveSpace()
{
assertEquals("Wrong value of blanc", " ", conf.getString("space.blanc"));
assertEquals("Wrong value of stars", " * * ", conf
.getString("space.stars"));
}
/**
* Tests whether the xml:space attribute can be overridden in nested
* elements.
*/
public void testPreserveSpaceOverride()
{
assertEquals("Not trimmed", "Some text", conf
.getString("space.description"));
}
/**
* Tests an xml:space attribute with an invalid value. This will be
* interpreted as default.
*/
public void testPreserveSpaceInvalid()
{
assertEquals("Invalid not trimmed", "Some other text", conf
.getString("space.testInvalid"));
}
/**
* Tests whether attribute splitting can be disabled.
*/
public void testAttributeSplittingDisabled() throws ConfigurationException
{
List values = conf.getList("expressions[@value2]");
assertEquals("Wrong number of attribute values", 2, values.size());
assertEquals("Wrong value 1", "a", values.get(0));
assertEquals("Wrong value 2", "b|c", values.get(1));
XMLConfiguration conf2 = new XMLConfiguration();
conf2.setAttributeSplittingDisabled(true);
conf2.setFile(conf.getFile());
conf2.load();
assertEquals("Attribute was split", "a,b|c", conf2
.getString("expressions[@value2]"));
}
/**
* Tests disabling both delimiter parsing and attribute splitting.
*/
public void testAttributeSplittingAndDelimiterParsingDisabled()
throws ConfigurationException
{
conf.clear();
conf.setDelimiterParsingDisabled(true);
conf.load();
List values = conf.getList("expressions[@value2]");
assertEquals("Wrong number of attribute values", 2, values.size());
assertEquals("Wrong value 1", "a,b", values.get(0));
assertEquals("Wrong value 2", "c", values.get(1));
XMLConfiguration conf2 = new XMLConfiguration();
conf2.setAttributeSplittingDisabled(true);
conf2.setDelimiterParsingDisabled(true);
conf2.setFile(conf.getFile());
conf2.load();
assertEquals("Attribute was split", "a,b|c", conf2
.getString("expressions[@value2]"));
}
/**
* Tests modifying an XML document and saving it with schema validation enabled.
*/
public void testSaveWithValidation() throws Exception
{
CatalogResolver resolver = new CatalogResolver();
resolver.setCatalogFiles(CATALOG_FILES);
conf = new XMLConfiguration();
conf.setEntityResolver(resolver);
conf.setFileName(testFile2);
conf.setSchemaValidation(true);
conf.load();
conf.setProperty("Employee.SSN", "123456789");
conf.validate();
conf.save(testSaveConf);
conf = new XMLConfiguration(testSaveConf);
assertEquals("123456789", conf.getString("Employee.SSN"));
}
/**
* Tests modifying an XML document and validating it against the schema.
*/
public void testSaveWithValidationFailure() throws Exception
{
CatalogResolver resolver = new CatalogResolver();
resolver.setCatalogFiles(CATALOG_FILES);
conf = new XMLConfiguration();
conf.setEntityResolver(resolver);
conf.setFileName(testFile2);
conf.setSchemaValidation(true);
conf.load();
conf.setProperty("Employee.Email", "JohnDoe@apache.org");
try
{
conf.validate();
fail("No validation failure on save");
}
catch (Exception e)
{
Throwable cause = e.getCause();
assertNotNull("No cause for exception on save", cause);
assertTrue("Incorrect exception on save", cause instanceof SAXParseException);
}
}
public void testConcurrentGetAndReload() throws Exception
{
//final FileConfiguration config = new PropertiesConfiguration("test.properties");
final FileConfiguration config = new XMLConfiguration("test.xml");
config.setReloadingStrategy(new FileAlwaysReloadingStrategy());
assertTrue("Property not found", config.getProperty("test.short") != null);
Thread testThreads[] = new Thread[5];
for (int i = 0; i < testThreads.length; ++i)
{
testThreads[i] = new ReloadThread(config);
testThreads[i].start();
}
for (int i = 0; i < 2000; i++)
{
assertTrue("Property not found", config.getProperty("test.short") != null);
}
for (int i = 0; i < testThreads.length; ++i)
{
testThreads[i].join();
}
}
private class ReloadThread extends Thread
{
FileConfiguration config;
ReloadThread(FileConfiguration config)
{
this.config = config;
}
public void run()
{
for (int i = 0; i < 1000; i++)
{
config.reload();
}
}
}
/**
* Prepares a configuration object for testing a reload operation.
*
* @return the initialized configuration
* @throws ConfigurationException if an error occurs
*/
private XMLConfiguration setUpReloadTest() throws ConfigurationException
{
removeTestFile();
conf.save(testSaveConf);
XMLConfiguration c = new XMLConfiguration(testSaveConf);
c.setReloadingStrategy(new FileAlwaysReloadingStrategy());
conf.setProperty("test(0).entity", "newValue");
conf.save(testSaveConf);
return c;
}
/**
* Removes the test output file if it exists.
*/
private void removeTestFile()
{
if (testSaveConf.exists())
{
assertTrue(testSaveConf.delete());
}
}
/**
* Helper method for checking if a save operation was successful. Loads a
* saved configuration and then tests against a reference configuration.
* @param checkConfig the configuration to check
* @throws ConfigurationException if an error occurs
*/
private void checkSavedConfig(FileConfiguration checkConfig) throws ConfigurationException
{
checkConfig.load();
ConfigurationAssert.assertEquals(conf, checkConfig);
}
}