ebourg 2004/10/18 08:45:10
Modified: configuration/src/java/org/apache/commons/configuration
AbstractFileConfiguration.java
FileConfiguration.java
HierarchicalXMLConfiguration.java
configuration/xdocs changes.xml
Added: configuration/src/java/org/apache/commons/configuration/reloading
FileChangedReloadingStrategy.java
InvariantReloadingStrategy.java
ReloadingStrategy.java
configuration/src/test/org/apache/commons/configuration/reloading
TestFileChangedReloadingStrategy.java
Log:
Implemented configuration reloading
Revision Changes Path
1.6 +72 -1
jakarta-commons/configuration/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java
Index: AbstractFileConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/AbstractFileConfiguration.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- AbstractFileConfiguration.java 18 Oct 2004 11:12:08 -0000 1.5
+++ AbstractFileConfiguration.java 18 Oct 2004 15:45:10 -0000 1.6
@@ -29,6 +29,10 @@
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Iterator;
+
+import org.apache.commons.configuration.reloading.InvariantReloadingStrategy;
+import org.apache.commons.configuration.reloading.ReloadingStrategy;
/**
* Partial implementation of the <code>FileConfiguration</code> interface.
@@ -46,6 +50,13 @@
protected String basePath;
protected URL url;
protected boolean autoSave;
+ protected ReloadingStrategy strategy;
+ private Object reloadLock = new Object();
+
+ public AbstractFileConfiguration()
+ {
+ setReloadingStrategy(new InvariantReloadingStrategy());
+ }
/**
* Load the configuration from the underlying URL. If the URL is not
@@ -199,6 +210,7 @@
public void save() throws ConfigurationException
{
save(fileName);
+ strategy.init();
}
/**
@@ -472,5 +484,64 @@
{
super.clearProperty(key);
possiblySave();
+ }
+
+ public ReloadingStrategy getReloadingStrategy()
+ {
+ return strategy;
+ }
+
+ public void setReloadingStrategy(ReloadingStrategy strategy)
+ {
+ this.strategy = strategy;
+ strategy.setConfiguration(this);
+ strategy.init();
+ }
+
+ public void reload()
+ {
+ synchronized (reloadLock)
+ {
+ if (strategy.reloadingRequired())
+ {
+ try
+ {
+ clear();
+ load();
+
+ // notify the strategy
+ strategy.reloadingPerformed();
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ // todo rollback the changes if the file can't be reloaded
+ }
+ }
+ }
+ }
+
+ protected Object getPropertyDirect(String key)
+ {
+ reload();
+ return super.getPropertyDirect(key);
+ }
+
+ public boolean isEmpty()
+ {
+ reload();
+ return super.isEmpty();
+ }
+
+ public boolean containsKey(String key)
+ {
+ reload();
+ return super.containsKey(key);
+ }
+
+ public Iterator getKeys()
+ {
+ reload();
+ return super.getKeys();
}
}
1.3 +24 -1
jakarta-commons/configuration/src/java/org/apache/commons/configuration/FileConfiguration.java
Index: FileConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/FileConfiguration.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- FileConfiguration.java 18 Oct 2004 11:12:08 -0000 1.2
+++ FileConfiguration.java 18 Oct 2004 15:45:10 -0000 1.3
@@ -23,6 +23,8 @@
import java.io.Writer;
import java.io.File;
+import org.apache.commons.configuration.reloading.ReloadingStrategy;
+
/**
* A persistent configuration loaded and saved to a file.
*
@@ -222,5 +224,26 @@
* @since 1.1
*/
boolean isAutoSave();
+
+ /**
+ * Return the reloading strategy.
+ *
+ * @since 1.1
+ */
+ ReloadingStrategy getReloadingStrategy();
+
+ /**
+ * Set the reloading strategy.
+ *
+ * @since 1.1
+ */
+ void setReloadingStrategy(ReloadingStrategy strategy);
+
+ /**
+ * Reload the configuration.
+ *
+ * @since 1.1
+ */
+ void reload();
}
1.5 +17 -1
jakarta-commons/configuration/src/java/org/apache/commons/configuration/HierarchicalXMLConfiguration.java
Index: HierarchicalXMLConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/HierarchicalXMLConfiguration.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- HierarchicalXMLConfiguration.java 18 Oct 2004 11:12:08 -0000 1.4
+++ HierarchicalXMLConfiguration.java 18 Oct 2004 15:45:10 -0000 1.5
@@ -32,6 +32,7 @@
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
+import org.apache.commons.configuration.reloading.ReloadingStrategy;
/**
* A specialized hierarchical configuration class that is able to parse
@@ -247,6 +248,21 @@
public boolean isAutoSave()
{
return delegate.isAutoSave();
+ }
+
+ public ReloadingStrategy getReloadingStrategy()
+ {
+ return delegate.getReloadingStrategy();
+ }
+
+ public void setReloadingStrategy(ReloadingStrategy strategy)
+ {
+ delegate.setReloadingStrategy(strategy);
+ }
+
+ public void reload()
+ {
+ delegate.reload();
}
private class FileConfigurationDelegate extends AbstractFileConfiguration {
1.62 +4 -0 jakarta-commons/configuration/xdocs/changes.xml
Index: changes.xml
===================================================================
RCS file: /home/cvs/jakarta-commons/configuration/xdocs/changes.xml,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- changes.xml 18 Oct 2004 14:05:23 -0000 1.61
+++ changes.xml 18 Oct 2004 15:45:10 -0000 1.62
@@ -8,6 +8,10 @@
<body>
<release version="1.1-dev" date="in CVS">
+ <action dev="ebourg" type="add" issue="25661">
+ File based configurations can now be automatically reloaded when the
+ underlying file is modified.
+ </action>
<action dev="ebourg" type="add" issue="26102">
Added a clear() method to the Configuration interface to remove
all properties.
1.1
jakarta-commons/configuration/src/java/org/apache/commons/configuration/reloading/FileChangedReloadingStrategy.java
Index: FileChangedReloadingStrategy.java
===================================================================
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed 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.reloading;
import java.io.File;
import org.apache.commons.configuration.FileConfiguration;
/**
* A reloading strategy that will reload the configuration every time its
* underlying file is changed. The file is not reloaded more than once
* every 5 seconds by default, this time can be changed by setting the refresh
* delay. This strategy only works with FileConfiguration instances.
*
* @author Emmanuel Bourg
* @version $Revision: 1.1 $, $Date: 2004/10/18 15:45:10 $
* @since 1.1
*/
public class FileChangedReloadingStrategy implements ReloadingStrategy
{
protected FileConfiguration configuration;
/** The last time the configuration file was modified. */
protected long lastModified;
/** The last time the file was checked for changes. */
protected long lastChecked;
/** The minimum delay in milliseconds between checks. */
protected long refreshDelay = 5000;
public void setConfiguration(FileConfiguration configuration)
{
this.configuration = configuration;
}
public void init()
{
updateLastModified();
}
public boolean reloadingRequired()
{
boolean reloading = false;
long now = System.currentTimeMillis();
if ((now > lastChecked + refreshDelay) && hasChanged())
{
lastChecked = now;
reloading = true;
}
return reloading;
}
public void reloadingPerformed()
{
updateLastModified();
}
/**
* Return the minimal time in milliseconds between two reloadings.
*/
public long getRefreshDelay()
{
return refreshDelay;
}
/**
* Set the minimal time between two reloadings.
*
* @param refreshDelay refresh delay in milliseconds
*/
public void setRefreshDelay(long refreshDelay)
{
this.refreshDelay = refreshDelay;
}
/**
* Update the last modified time.
*/
protected void updateLastModified()
{
File file = new File(configuration.getFileName());
lastModified = file.lastModified();
}
/**
* Check if the configuration has changed since the last
* time it was loaded.
*/
protected boolean hasChanged()
{
if (configuration.getFileName() == null)
{
return false;
}
File file = new File(configuration.getFileName());
return (file.lastModified() > lastModified);
}
}
1.1
jakarta-commons/configuration/src/java/org/apache/commons/configuration/reloading/InvariantReloadingStrategy.java
Index: InvariantReloadingStrategy.java
===================================================================
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed 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.reloading;
import org.apache.commons.configuration.FileConfiguration;
/**
* A strategy that never triggers a reloading.
*
* @author Emmanuel Bourg
* @version $Revision: 1.1 $, $Date: 2004/10/18 15:45:10 $
* @since 1.1
*/
public class InvariantReloadingStrategy implements ReloadingStrategy
{
public void setConfiguration(FileConfiguration configuration)
{
}
public void init()
{
}
public boolean reloadingRequired()
{
return false;
}
public void reloadingPerformed()
{
}
}
1.1
jakarta-commons/configuration/src/java/org/apache/commons/configuration/reloading/ReloadingStrategy.java
Index: ReloadingStrategy.java
===================================================================
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed 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.reloading;
import org.apache.commons.configuration.FileConfiguration;
/**
* A strategy to decide if a configuration should be reloaded.
*
* @author Emmanuel Bourg
* @author Olivier Heger
* @version $Revision: 1.1 $, $Date: 2004/10/18 15:45:10 $
* @since 1.1
*/
public interface ReloadingStrategy {
/**
* Set the configuration managed by this strategy.
*/
void setConfiguration(FileConfiguration configuration);
/**
* Initialize the strategy.
*/
void init();
/**
* Tell if the evaluation of the strategy requires to reload the configuration.
*/
boolean reloadingRequired();
/**
* Notify the strategy that the file has been reloaded.
*/
void reloadingPerformed();
}
1.1
jakarta-commons/configuration/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java
Index: TestFileChangedReloadingStrategy.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed 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.reloading;
import java.io.File;
import java.io.FileWriter;
import junit.framework.TestCase;
import org.apache.commons.configuration.PropertiesConfiguration;
/**
* Test case for the ReloadableConfiguration class.
*
* @author Emmanuel Bourg
* @version $Revision: 1.1 $, $Date: 2004/10/18 15:45:10 $
*/
public class TestFileChangedReloadingStrategy extends TestCase
{
public void testAutomaticReloading() throws Exception
{
// create a new configuration
File file = new File("target/testReload.properties");
if (file.exists())
{
file.delete();
}
// create the configuration file
FileWriter out = new FileWriter(file);
out.write("string=value1");
out.flush();
out.close();
// load the configuration
PropertiesConfiguration config = new
PropertiesConfiguration("target/testReload.properties");
config.setReloadingStrategy(new FileChangedReloadingStrategy());
assertEquals("Initial value", "value1", config.getString("string"));
Thread.sleep(500);
// change the file
out = new FileWriter(file);
out.write("string=value2");
out.flush();
out.close();
// test the automatic reloading
assertEquals("Modified value with enabled reloading", "value2",
config.getString("string"));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]