Author: rgoers Date: Tue Jun 9 06:43:38 2009 New Revision: 782896 URL: http://svn.apache.org/viewvc?rev=782896&view=rev Log: VFSFileMonitorReloadingStrategy was not able to detect files with invalid urls - see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6351751. make HttpOutputStream and VFSURLStreamHandler private. Limit VerifiableOutputStream to package scope
Added: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/log4j-test.xml commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testFileMonitorConfigurationBuilder2.xml (with props) Removed: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/HttpOutputStream.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/VFSURLStreamHandler.java Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractFileConfiguration.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/ConfigurationUtils.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultFileSystem.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/VFSFileSystem.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/event/EventSource.java commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/VFSFileMonitorReloadingStrategy.java commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/ConfigurationAssert.java commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestConfigurationFactory.java commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestFileConfiguration.java commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestVFSConfigurationBuilder.java commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/reloading/TestVFSFileMonitorReloadingStrategy.java Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractFileConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractFileConfiguration.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractFileConfiguration.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractFileConfiguration.java Tue Jun 9 06:43:38 2009 @@ -84,6 +84,12 @@ /** Constant for the configuration reload event.*/ public static final int EVENT_RELOAD = 20; + /** Constant fro the configuration changed event. */ + public static final int EVENT_CONFIG_CHANGED = 21; + + /** The root of the file scheme */ + private static final String FILE_SCHEME = "file:"; + /** Stores the file name.*/ protected String fileName; @@ -555,6 +561,10 @@ */ public void setFileName(String fileName) { + if (fileName != null && fileName.startsWith(FILE_SCHEME) && !fileName.startsWith("file://")) + { + fileName = "file://" + fileName.substring(FILE_SCHEME.length()); + } sourceURL = null; this.fileName = fileName; } @@ -588,6 +598,10 @@ */ public void setBasePath(String basePath) { + if (basePath != null && basePath.startsWith(FILE_SCHEME) && !basePath.startsWith("file://")) + { + basePath = "file://" + basePath.substring(FILE_SCHEME.length()); + } sourceURL = null; this.basePath = basePath; } @@ -825,6 +839,14 @@ } /** + * Send notification that the configuration has changed. + */ + public void configurationChanged() + { + fireEvent(EVENT_CONFIG_CHANGED, null, getURL(), true); + } + + /** * Enters the "No reloading mode". As long as this mode is active * no reloading will be performed. This is necessary for some * implementations of <code>save()</code> in derived classes, which may Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java Tue Jun 9 06:43:38 2009 @@ -46,7 +46,7 @@ */ public abstract class AbstractHierarchicalFileConfiguration extends InMemoryConfiguration -implements FileConfiguration, ConfigurationListener +implements FileConfiguration, ConfigurationListener, FileSystemBased { /** Stores the delegate used for implementing functionality related to the * <code>FileConfiguration</code> interface. Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java Tue Jun 9 06:43:38 2009 @@ -522,7 +522,11 @@ */ public void configurationChanged(ConfigurationEvent event) { - if (!event.isBeforeUpdate()) + if (event.getType() == AbstractFileConfiguration.EVENT_CONFIG_CHANGED) + { + fireEvent(event.getType(), event.getPropertyName(), event.getPropertyValue(), event.isBeforeUpdate()); + } + else if (!event.isBeforeUpdate()) { invalidate(); } @@ -845,7 +849,7 @@ .convertToHierarchical(getConfiguration()); root = hc.getRootNode(); } - + // Copy data of the root node to the new path atParent.appendChildren(root); atParent.appendAttributes(root); Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/ConfigurationUtils.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/ConfigurationUtils.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/ConfigurationUtils.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/ConfigurationUtils.java Tue Jun 9 06:43:38 2009 @@ -53,6 +53,9 @@ /** Constant for the resource path separator.*/ static final String RESOURCE_PATH_SEPARATOR = "/"; + /** Constanct for the file URL protocol */ + private static final String FILE_SCHEME = "file:"; + /** Constant for the name of the clone() method.*/ private static final String METHOD_CLONE = "clone"; @@ -521,6 +524,10 @@ } String s = url.toString(); + if (s.startsWith(FILE_SCHEME) && !s.startsWith("file://")) + { + s = "file://" + s.substring(FILE_SCHEME.length()); + } if (s.endsWith("/") || StringUtils.isEmpty(url.getPath())) { Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultFileSystem.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultFileSystem.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultFileSystem.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultFileSystem.java Tue Jun 9 06:43:38 2009 @@ -278,4 +278,69 @@ } } } + + /** + * Wraps the output stream so errors can be detected in the HTTP response. + * + * @author <a + * href="http://commons.apache.org/configuration/team-list.html">Commons Configuration team</a> + * @since 1.7 + */ + private static class HttpOutputStream extends VerifiableOutputStream + { + /** + * The wrapped OutputStream + */ + private final OutputStream stream; + + /** + * The HttpURLConnection + */ + private final HttpURLConnection connection; + + public HttpOutputStream(OutputStream stream, HttpURLConnection connection) + { + this.stream = stream; + this.connection = connection; + } + + public void write(byte[] bytes) throws IOException + { + stream.write(bytes); + } + + public void write(byte[] bytes, int i, int i1) throws IOException + { + stream.write(bytes, i, i1); + } + + public void flush() throws IOException + { + stream.flush(); + } + + public void close() throws IOException + { + stream.close(); + } + + public void write(int i) throws IOException + { + stream.write(i); + } + + public String toString() + { + return stream.toString(); + } + + public void verify() throws IOException + { + if (connection.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST) + { + throw new IOException("HTTP Error " + connection.getResponseCode() + + " " + connection.getResponseMessage()); + } + } + } } Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java Tue Jun 9 06:43:38 2009 @@ -610,7 +610,7 @@ return super.removeConfigurationListener(l); } - public Collection getConfigurationListeners() + public Collection<ConfigurationListener> getConfigurationListeners() { return super.getConfigurationListeners(); } @@ -651,7 +651,7 @@ super.clearErrorListeners(); } - public Collection getErrorListeners() + public Collection<ConfigurationErrorListener> getErrorListeners() { return super.getErrorListeners(); } @@ -746,23 +746,17 @@ config.setExpressionEngine(this.getExpressionEngine()); config.setDelimiterParsingDisabled(isDelimiterParsingDisabled()); config.setListDelimiter(getListDelimiter()); - Iterator iter = config.getErrorListeners().iterator(); - while (iter.hasNext()) + for (ConfigurationErrorListener listener : getErrorListeners()) { - ConfigurationErrorListener listener = (ConfigurationErrorListener) iter.next(); config.addErrorListener(listener); } - iter = config.getConfigurationListeners().iterator(); - while (iter.hasNext()) + for (ConfigurationListener listener : getConfigurationListeners()) { - ConfigurationListener listener = (ConfigurationListener) iter.next(); config.addConfigurationListener(listener); } config.setForceReloadCheck(isForceReloadCheck()); - iter = configurations.iterator(); - while (iter.hasNext()) + for (ConfigData data : configurations) { - ConfigData data = (ConfigData) iter.next(); config.addConfiguration(data.getConfiguration(), data.getName(), data.getAt()); } Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/VFSFileSystem.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/VFSFileSystem.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/VFSFileSystem.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/VFSFileSystem.java Tue Jun 9 06:43:38 2009 @@ -33,9 +33,11 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.File; +import java.io.IOException; import java.net.URL; import java.net.URLStreamHandler; import java.net.MalformedURLException; +import java.net.URLConnection; import java.util.Map; /** @@ -426,4 +428,23 @@ } return opts; } + + /** + * Stream handler required to create URL. + */ + private static class VFSURLStreamHandler extends URLStreamHandler + { + /** The Protocol used */ + private final String protocol; + + public VFSURLStreamHandler(FileName file) + { + this.protocol = file.getScheme(); + } + + protected URLConnection openConnection(URL url) throws IOException + { + throw new IOException("VFS URLs can only be used with VFS APIs"); + } + } } Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/event/EventSource.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/event/EventSource.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/event/EventSource.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/event/EventSource.java Tue Jun 9 06:43:38 2009 @@ -70,10 +70,10 @@ public class EventSource { /** A collection for the registered event listeners. */ - private Collection listeners; + private Collection<ConfigurationListener> listeners; /** A collection for the registered error listeners.*/ - private Collection errorListeners; + private Collection<ConfigurationErrorListener> errorListeners; /** A counter for the detail events. */ private int detailEvents; @@ -117,7 +117,7 @@ * of the currently registered listeners; manipulating it has no effect * on this event source object) */ - public Collection getConfigurationListeners() + public Collection<ConfigurationListener> getConfigurationListeners() { return doGetListeners(listeners); } @@ -211,7 +211,7 @@ * snapshot of the currently registered listeners; it cannot be manipulated) * @since 1.4 */ - public Collection getErrorListeners() + public Collection<ConfigurationErrorListener> getErrorListeners() { return doGetListeners(errorListeners); } @@ -279,7 +279,7 @@ */ protected void fireError(int type, String propName, Object propValue, Throwable ex) { - Collection listenersToCall = null; + Collection<ConfigurationErrorListener> listenersToCall = null; synchronized (errorListeners) { @@ -287,7 +287,7 @@ { // Copy listeners to another collection so that manipulating // the listener list during event delivery won't cause problems - listenersToCall = new ArrayList(errorListeners); + listenersToCall = new ArrayList<ConfigurationErrorListener>(errorListeners); } } @@ -403,7 +403,7 @@ */ private void initListeners() { - listeners = new LinkedList(); - errorListeners = new LinkedList(); + listeners = new LinkedList<ConfigurationListener>(); + errorListeners = new LinkedList<ConfigurationErrorListener>(); } } Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/VFSFileMonitorReloadingStrategy.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/VFSFileMonitorReloadingStrategy.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/VFSFileMonitorReloadingStrategy.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/VFSFileMonitorReloadingStrategy.java Tue Jun 9 06:43:38 2009 @@ -20,6 +20,7 @@ import org.apache.commons.configuration2.ConfigurationRuntimeException; import org.apache.commons.configuration2.FileSystem; import org.apache.commons.configuration2.FileSystemBased; +import org.apache.commons.configuration2.AbstractFileConfiguration; import org.apache.commons.vfs.impl.DefaultFileMonitor; import org.apache.commons.vfs.FileListener; import org.apache.commons.vfs.FileChangeEvent; @@ -113,6 +114,25 @@ { throw new IllegalStateException("No configuration has been set for this strategy"); } + FileObject file; + + try + { + FileSystemManager fsManager = VFS.getManager(); + FileSystem fs = ((FileSystemBased) configuration).getFileSystem(); + String uri = fs.getPath(null, configuration.getURL(), configuration.getBasePath(), + configuration.getFileName()); + if (uri == null) + { + throw new ConfigurationRuntimeException("Unable to determine file to monitor"); + } + file = fsManager.resolveFile(uri); + } + catch (FileSystemException fse) + { + String msg = "Unable to monitor " + configuration.getURL().toString(); + throw new ConfigurationRuntimeException(msg, fse); + } synchronized (INIT_GATE) { if (fm == null) @@ -130,35 +150,17 @@ fm.setDelay(delay); } } - } - - try - { - FileSystemManager fsManager = VFS.getManager(); - FileSystem fs = ((FileSystemBased) configuration).getFileSystem(); - String uri = fs.getPath(null, configuration.getURL(), configuration.getBasePath(), - configuration.getFileName()); - if (uri == null) - { - throw new ConfigurationRuntimeException("Unable to determine file to monitor"); - } - FileObject file = fsManager.resolveFile(uri); file.getFileSystem().addListener(file, this); fm.addFile(file); strategies.put(file, this); } - catch (FileSystemException fse) - { - String msg = "Unable to monitor " + configuration.getURL().toString(); - throw new ConfigurationRuntimeException(msg, fse); - } } /** - * Shutdown the reloading strategy + * Shutdown all reloading strategies */ - public void stopMonitor() + public static void stopMonitor() { synchronized (INIT_GATE) { @@ -204,6 +206,7 @@ public void fileCreated(FileChangeEvent event) throws Exception { reloadRequired = true; + fireEvent(); } /** @@ -224,6 +227,14 @@ public void fileChanged(FileChangeEvent event) throws Exception { reloadRequired = true; + fireEvent(); } + private void fireEvent() + { + if (configuration instanceof AbstractFileConfiguration) + { + ((AbstractFileConfiguration) configuration).configurationChanged(); + } + } } Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/ConfigurationAssert.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/ConfigurationAssert.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/ConfigurationAssert.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/ConfigurationAssert.java Tue Jun 9 06:43:38 2009 @@ -33,7 +33,7 @@ public class ConfigurationAssert { /** Constant for the name of the directory with the test files. */ - public static final String TEST_DIR_NAME = "src/test/resources"; + public static final String TEST_DIR_NAME = "target/test-classes"; /** Constant for the name of the directory with the output files. */ public static final String OUT_DIR_NAME = "target"; Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestConfigurationFactory.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestConfigurationFactory.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestConfigurationFactory.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestConfigurationFactory.java Tue Jun 9 06:43:38 2009 @@ -21,6 +21,7 @@ import java.io.FileWriter; import java.util.Collection; import java.util.List; +import java.net.URI; import junit.framework.TestCase; import org.xml.sax.SAXException; @@ -309,7 +310,7 @@ factory = new DefaultConfigurationBuilder(); factory.setURL(testDigesterFile.toURL()); - assertEquals(testDigesterFile.getParentFile().toURL().toString(), factory.getBasePath()); + assertEquals(testDigesterFile.getParentFile().toURI(), new URI(factory.getBasePath())); } // Tests if system properties can be resolved in the configuration Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestFileConfiguration.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestFileConfiguration.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestFileConfiguration.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestFileConfiguration.java Tue Jun 9 06:43:38 2009 @@ -55,9 +55,9 @@ assertEquals("base path", "http://commons.apache.org/configuration/", config.getBasePath()); assertEquals("file name", "index.html", config.getFileName()); - // file URL + // file URL - This url is invalid, a valid url would be file:///temp/test.properties. config.setURL(new URL("file:/temp/test.properties")); - assertEquals("base path", "file:/temp/", config.getBasePath()); + assertEquals("base path", "file:///temp/", config.getBasePath()); assertEquals("file name", "test.properties", config.getFileName()); } Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestVFSConfigurationBuilder.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestVFSConfigurationBuilder.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestVFSConfigurationBuilder.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestVFSConfigurationBuilder.java Tue Jun 9 06:43:38 2009 @@ -26,13 +26,19 @@ import java.util.Collection; import java.util.Set; import java.util.List; +import java.util.logging.ConsoleHandler; +import java.util.logging.Logger; +import java.util.logging.Level; import junit.framework.TestCase; import org.apache.commons.configuration2.beanutils.BeanHelper; import org.apache.commons.configuration2.reloading.FileChangedReloadingStrategy; +import org.apache.commons.configuration2.reloading.VFSFileMonitorReloadingStrategy; import org.apache.commons.configuration2.tree.DefaultConfigurationNode; import org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine; +import org.apache.commons.configuration2.event.ConfigurationListener; +import org.apache.commons.configuration2.event.ConfigurationEvent; /** * Test class for DefaultConfigurationBuilder. @@ -40,7 +46,7 @@ * @author Oliver Heger * @version $Id$ */ -public class TestVFSConfigurationBuilder extends TestCase +public class TestVFSConfigurationBuilder extends TestCase implements ConfigurationListener { /** Test configuration definition file. */ private static final File TEST_FILE = ConfigurationAssert @@ -88,12 +94,28 @@ private static final File FILEMONITOR_FILE = ConfigurationAssert .getTestFile("testFileMonitorConfigurationBuilder.xml"); + private static final File FILEMONITOR2_FILE = ConfigurationAssert + .getTestFile("testFileMonitorConfigurationBuilder2.xml"); + + private static final String FILEMONITOR_URI = "file://" + System.getProperty("user.dir") + + "/target/test-classes/testFileMonitorConfigurationBuilder2.xml"; + /** Constant for the name of an optional configuration.*/ private static final String OPTIONAL_NAME = "optionalConfig"; + /** true when a file is changed */ + private boolean configChanged = false; + /** Stores the object to be tested. */ private DefaultConfigurationBuilder factory; + public TestVFSConfigurationBuilder() + { + super(); + //System.setProperty("log4j.configuration", "log4j-test.xml"); + VFSFileMonitorReloadingStrategy.stopMonitor(); + } + @Override protected void setUp() throws Exception { @@ -103,6 +125,7 @@ "org.apache.commons.configuration2.MockInitialContextFactory"); System.setProperty("test_file_xml", "test.xml"); System.setProperty("test_file_combine", "testcombine1.xml"); + System.setProperty("basePath", "file://" + System.getProperty("user.dir") + "/target/test-classes"); FileSystem.setDefaultFileSystem(new VFSFileSystem()); factory = new DefaultConfigurationBuilder(); factory.clearErrorListeners(); // avoid exception messages @@ -970,7 +993,7 @@ } } - public void testFileMonitor() throws Exception + public void testFileMonitor1() throws Exception { // create a new configuration @@ -985,6 +1008,74 @@ CombinedConfiguration config = factory.getConfiguration(true); assertNotNull(config); + config.addConfigurationListener(this); + verify("1001", config, 15); + + // Allow time for FileMonitor to set up. + Thread.sleep(1000); + XMLConfiguration x = new XMLConfiguration(output); + x.setProperty("rowsPerPage", "50"); + x.save(); + + waitForChange(); + verify("1001", config, 50); + output.delete(); + VFSFileMonitorReloadingStrategy.stopMonitor(); + } + + public void testFileMonitor2() throws Exception + { + // create a new configuration + File input = new File("target/test-classes/testMultiConfiguration_1002.xml"); + File output = new File("target/test-classes/testwrite/testMultiConfiguration_1002.xml"); + output.delete(); + + factory.setFile(FILEMONITOR_FILE); + FileSystem.resetDefaultFileSystem(); + System.getProperties().remove("Id"); + + CombinedConfiguration config = factory.getConfiguration(true); + config.addConfigurationListener(this); + assertNotNull(config); + + verify("1002", config, 50); + Thread.sleep(1000); + + output.getParentFile().mkdir(); + copyFile(input, output); + + // Allow time for the monitor to notice the change. + //Thread.sleep(2000); + waitForChange(); + try + { + verify("1002", config, 25); + } + finally + { + output.delete(); + VFSFileMonitorReloadingStrategy.stopMonitor(); + } + } + + + public void testFileMonitor3() throws Exception + { + // create a new configuration + File input = new File("target/test-classes/testMultiConfiguration_1001.xml"); + File output = new File("target/test-classes/testwrite/testMultiConfiguration_1001.xml"); + output.delete(); + output.getParentFile().mkdir(); + copyFile(input, output); + + factory.setFile(FILEMONITOR2_FILE); + FileSystem.resetDefaultFileSystem(); + System.getProperties().remove("Id"); + + CombinedConfiguration config = factory.getConfiguration(true); + //config.setLogger(logger); + assertNotNull(config); + config.addConfigurationListener(this); verify("1001", config, 15); // Allow time for FileMonitor to set up. @@ -993,8 +1084,40 @@ x.setProperty("rowsPerPage", "50"); x.save(); // Let FileMonitor detect the change. - Thread.sleep(2000); + //Thread.sleep(2000); + waitForChange(); verify("1001", config, 50); + output.delete(); + VFSFileMonitorReloadingStrategy.stopMonitor(); + } + + public void testFileMonitor4() throws Exception + { + // create a new configuration + File input = new File("target/test-classes/testMultiConfiguration_1002.xml"); + File output = new File("target/test-classes/testwrite/testMultiConfiguration_1002.xml"); + output.delete(); + + factory.setFileName(FILEMONITOR_URI); + FileSystem.resetDefaultFileSystem(); + System.getProperties().remove("Id"); + + CombinedConfiguration config = factory.getConfiguration(true); + assertNotNull(config); + config.addConfigurationListener(this); + + verify("1002", config, 50); + Thread.sleep(1000); + + output.getParentFile().mkdir(); + copyFile(input, output); + + // Allow time for the monitor to notice the change. + //Thread.sleep(2000); + waitForChange(); + verify("1002", config, 25); + output.delete(); + VFSFileMonitorReloadingStrategy.stopMonitor(); } private void copyFile(File input, File output) throws IOException @@ -1018,4 +1141,39 @@ int actual = config.getInt("rowsPerPage"); assertTrue("expected: " + rows + " actual: " + actual, actual == rows); } + + private void waitForChange() + { + synchronized(this) + { + try + { + int count = 0; + while (!configChanged && count++ <= 3) + { + this.wait(5000); + } + } + catch (InterruptedException ie) + { + throw new IllegalStateException("wait timed out"); + } + finally + { + configChanged = false; + } + } + } + + public void configurationChanged(ConfigurationEvent event) + { + if (event.getType() == AbstractFileConfiguration.EVENT_CONFIG_CHANGED) + { + synchronized(this) + { + configChanged = true; + this.notify(); + } + } + } } Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/reloading/TestVFSFileMonitorReloadingStrategy.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/reloading/TestVFSFileMonitorReloadingStrategy.java?rev=782896&r1=782895&r2=782896&view=diff ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/reloading/TestVFSFileMonitorReloadingStrategy.java (original) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/reloading/TestVFSFileMonitorReloadingStrategy.java Tue Jun 9 06:43:38 2009 @@ -28,6 +28,9 @@ import org.apache.commons.configuration2.XMLConfiguration; import org.apache.commons.configuration2.FileSystem; import org.apache.commons.configuration2.VFSFileSystem; +import org.apache.commons.configuration2.AbstractFileConfiguration; +import org.apache.commons.configuration2.event.ConfigurationListener; +import org.apache.commons.configuration2.event.ConfigurationEvent; /** * Test case for the VFSFileMonitorReloadingStrategy class. @@ -36,9 +39,10 @@ * @version $Revision: $ */ public class TestVFSFileMonitorReloadingStrategy extends TestCase + implements ConfigurationListener { - /** Constant for the name of a test properties file.*/ - private static final String TEST_FILE = "test.properties"; + /** true when a file is changed */ + private boolean configChanged = false; protected void setUp() throws Exception { @@ -106,6 +110,7 @@ PropertiesConfiguration config = new PropertiesConfiguration(); config.setFile(file); + config.addConfigurationListener(this); VFSFileMonitorReloadingStrategy strategy = new VFSFileMonitorReloadingStrategy(); strategy.setDelay(500); config.setReloadingStrategy(strategy); @@ -118,14 +123,20 @@ out.flush(); out.close(); - Thread.sleep(2000); + waitForChange(); // test the automatic reloading - assertEquals("Modified value with enabled reloading", "value1", config.getString("string")); - strategy.stopMonitor(); - if (file.exists()) + try { - file.delete(); + assertEquals("Modified value with enabled reloading", "value1", config.getString("string")); + } + finally + { + strategy.stopMonitor(); + if (file.exists()) + { + file.delete(); + } } } @@ -179,4 +190,39 @@ file.delete(); } } + private void waitForChange() + { + synchronized(this) + { + try + { + int count = 0; + while (!configChanged && count++ <= 3) + { + this.wait(5000); + } + } + catch (InterruptedException ie) + { + throw new IllegalStateException("wait timed out"); + } + finally + { + configChanged = false; + } + } + } + + public void configurationChanged(ConfigurationEvent event) + { + if (event.getType() == AbstractFileConfiguration.EVENT_CONFIG_CHANGED) + { + synchronized(this) + { + configChanged = true; + this.notify(); + } + } + } + } \ No newline at end of file Added: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/log4j-test.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/resources/log4j-test.xml?rev=782896&view=auto ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/resources/log4j-test.xml (added) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/resources/log4j-test.xml Tue Jun 9 06:43:38 2009 @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> + <appender name="console" class="org.apache.log4j.ConsoleAppender"> + <param name="Target" value="System.out"/> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/> + </layout> + </appender> + + <root> + <priority value ="debug" /> + <appender-ref ref="console" /> + </root> + +</log4j:configuration> \ No newline at end of file Added: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testFileMonitorConfigurationBuilder2.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testFileMonitorConfigurationBuilder2.xml?rev=782896&view=auto ============================================================================== --- commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testFileMonitorConfigurationBuilder2.xml (added) +++ commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testFileMonitorConfigurationBuilder2.xml Tue Jun 9 06:43:38 2009 @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> +<!-- Test configuration definition file that demonstrates complex initialization --> +<configuration> + <header> + <result delimiterParsingDisabled="true" forceReloadCheck="true" + config-class="org.apache.commons.configuration2.DynamicCombinedConfiguration" + keyPattern="$${sys:Id}"> + <nodeCombiner config-class="org.apache.commons.configuration2.tree.MergeCombiner"/> + <expressionEngine + config-class="org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine"/> + </result> + <fileSystem config-class="org.apache.commons.configuration2.VFSFileSystem"/> + <providers> + <provider config-tag="multifile" + config-class="org.apache.commons.configuration2.DefaultConfigurationBuilder$FileConfigurationProvider" + configurationClass="org.apache.commons.configuration2.MultiFileHierarchicalConfiguration"/> + </providers> + </header> + <override> + <multifile filePattern="${sys:basePath}/testwrite/testMultiConfiguration_$$${sys:Id}.xml" + config-name="clientConfig" delimiterParsingDisabled="true" schemaValidation="false"> + <expressionEngine + config-class="org.apache.commons.configuration2.expr.xpath.XPathExpressionEngine"/> + <reloadingStrategy delay="500" + config-class="org.apache.commons.configuration2.reloading.VFSFileMonitorReloadingStrategy"/> + </multifile> + <xml fileName="testMultiConfiguration_default.xml" + config-name="defaultConfig" delimiterParsingDisabled="true"> + <expressionEngine + config-class="org.apache.commons.configuration2.expr.xpath.XPathExpressionEngine"/> + <reloadingStrategy + config-class="org.apache.commons.configuration2.reloading.VFSFileMonitorReloadingStrategy"/> + </xml> + </override> +</configuration> \ No newline at end of file Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testFileMonitorConfigurationBuilder2.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testFileMonitorConfigurationBuilder2.xml ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testFileMonitorConfigurationBuilder2.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml