oheger 2004/12/04 07:45:40
Modified: configuration/src/test/org/apache/commons/configuration
TestPropertiesConfiguration.java
TestConfigurationUtils.java
TestFileConfiguration.java
configuration/src/java/org/apache/commons/configuration
PropertiesConfiguration.java
ConfigurationUtils.java
AbstractFileConfiguration.java
configuration/src/java/org/apache/commons/configuration/reloading
FileChangedReloadingStrategy.java
configuration/src/test/org/apache/commons/configuration/reloading
TestFileChangedReloadingStrategy.java
Log:
Fix for Bug 30858, including some cleanup for file based configurations
Revision Changes Path
1.17 +20 -1
jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestPropertiesConfiguration.java
Index: TestPropertiesConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestPropertiesConfiguration.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- TestPropertiesConfiguration.java 14 Nov 2004 18:29:02 -0000 1.16
+++ TestPropertiesConfiguration.java 4 Dec 2004 15:45:39 -0000 1.17
@@ -152,6 +152,25 @@
//good
}
}
+
+ /**
+ * Tests if the base path is taken into account by the save() method.
+ * @throws Exception if an error occurs
+ */
+ public void testSaveWithBasePath() throws Exception
+ {
+ // remove the file previously saved if necessary
+ if (testSavePropertiesFile.exists())
+ {
+ assertTrue(testSavePropertiesFile.delete());
+ }
+
+ conf.setProperty("test", "true");
+
conf.setBasePath(testSavePropertiesFile.getParentFile().toURL().toString());
+ conf.setFileName(testSavePropertiesFile.getName());
+ conf.save();
+ assertTrue(testSavePropertiesFile.exists());
+ }
public void testLoadViaProperty() throws Exception
{
1.9 +13 -1
jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestConfigurationUtils.java
Index: TestConfigurationUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestConfigurationUtils.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- TestConfigurationUtils.java 19 Oct 2004 13:41:44 -0000 1.8
+++ TestConfigurationUtils.java 4 Dec 2004 15:45:39 -0000 1.9
@@ -171,4 +171,16 @@
expected.add("value2");
ListAssert.assertEquals("'key2' property", expected,
conf2.getList("key2"));
}
+
+ public void testGetFile() throws Exception
+ {
+ File directory = new File("target");
+ File reference = new File(directory, "test.txt").getAbsoluteFile();
+
+ assertEquals(reference, ConfigurationUtils.getFile(null,
reference.getAbsolutePath()));
+ assertEquals(reference,
ConfigurationUtils.getFile(directory.getAbsolutePath(),
reference.getAbsolutePath()));
+ assertEquals(reference,
ConfigurationUtils.getFile(directory.getAbsolutePath(), reference.getName()));
+ assertEquals(reference,
ConfigurationUtils.getFile(directory.toURL().toString(), reference.getName()));
+ assertEquals(reference, ConfigurationUtils.getFile("invalid",
reference.toURL().toString()));
+ }
}
1.3 +77 -4
jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestFileConfiguration.java
Index: TestFileConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/TestFileConfiguration.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TestFileConfiguration.java 19 Nov 2004 13:19:50 -0000 1.2
+++ TestFileConfiguration.java 4 Dec 2004 15:45:39 -0000 1.3
@@ -33,15 +33,39 @@
FileConfiguration config = new PropertiesConfiguration();
config.setURL(new
URL("http://jakarta.apache.org/commons/configuration/index.html"));
- assertEquals("base path",
"http://jakarta.apache.org/commons/configuration/", config.getBasePath());
+ assertEquals("base path",
"http://jakarta.apache.org/commons/configuration/", config
+ .getBasePath());
assertEquals("file name", "index.html", config.getFileName());
// file URL
config.setURL(new URL("file:/temp/test.properties"));
- assertEquals("base path", "/temp/", config.getBasePath());
+ assertEquals("base path", "file:/temp/", config.getBasePath());
assertEquals("file name", "test.properties", config.getFileName());
}
+ public void testLocations() throws Exception
+ {
+ PropertiesConfiguration config = new PropertiesConfiguration();
+
+ File directory = new File("conf");
+ File file = new File(directory, "test.properties");
+ config.setFile(file);
+ assertEquals(directory.getAbsolutePath(), config.getBasePath());
+ assertEquals("test.properties", config.getFileName());
+ assertEquals(file.getAbsolutePath(), config.getPath());
+
+ config.setPath("conf" + File.separator + "test.properties");
+ assertEquals("test.properties", config.getFileName());
+ assertEquals(directory.getAbsolutePath(), config.getBasePath());
+ assertEquals(file.getAbsolutePath(), config.getPath());
+ assertEquals(file.toURL(), config.getURL());
+
+ config.setBasePath(null);
+ config.setFileName("test.properties");
+ assertNull(config.getBasePath());
+ assertEquals("test.properties", config.getFileName());
+ }
+
public void testCreateFile1() throws Exception
{
File file = new
File("target/test-resources/foo/bar/test.properties");
@@ -93,4 +117,53 @@
assertTrue("The file doesn't exist", file.exists());
}
-}
+
+ /**
+ * Tests collaboration with ConfigurationFactory: Is the base path set on
+ * loading is valid in file based configurations?
+ *
+ * @throws Exception if an error occurs
+ */
+ public void testWithConfigurationFactory() throws Exception
+ {
+ File dir = new File("conf");
+ File file = new File(dir, "testFileConfiguration.properties");
+
+ if (file.exists())
+ {
+ assertTrue("File cannot be deleted", file.delete());
+ }
+
+ try
+ {
+ ConfigurationFactory factory = new ConfigurationFactory();
+ factory.setConfigurationURL(new File(dir,
"testDigesterConfiguration2.xml").toURL());
+ CompositeConfiguration cc = (CompositeConfiguration)
factory.getConfiguration();
+ PropertiesConfiguration config = null;
+ for (int i = 0; config == null; i++)
+ {
+ if (cc.getConfiguration(i) instanceof
PropertiesConfiguration)
+ {
+ config = (PropertiesConfiguration)
cc.getConfiguration(i);
+ }
+ }
+
+ config.setProperty("test", "yes");
+ config.save(file.getName());
+ assertTrue(file.exists());
+ config = new PropertiesConfiguration();
+ config.setFile(file);
+ config.load();
+
+ assertEquals("yes", config.getProperty("test"));
+ assertEquals("masterOfPost",
config.getProperty("mail.account.user"));
+ }
+ finally
+ {
+ if (file.exists())
+ {
+ assertTrue("File could not be deleted", file.delete());
+ }
+ }
+ }
+}
\ No newline at end of file
1.17 +2 -2
jakarta-commons/configuration/src/java/org/apache/commons/configuration/PropertiesConfiguration.java
Index: PropertiesConfiguration.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/PropertiesConfiguration.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- PropertiesConfiguration.java 19 Oct 2004 11:44:31 -0000 1.16
+++ PropertiesConfiguration.java 4 Dec 2004 15:45:40 -0000 1.17
@@ -273,7 +273,7 @@
if (StringUtils.isNotEmpty(getInclude())
&& key.equalsIgnoreCase(getInclude()))
{
- if (getIncludesAllowed() && url != null)
+ if (getIncludesAllowed())
{
String [] files = StringUtils.split(value,
getDelimiter());
for (int i = 0; i < files.length; i++)
1.13 +68 -7
jakarta-commons/configuration/src/java/org/apache/commons/configuration/ConfigurationUtils.java
Index: ConfigurationUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/ConfigurationUtils.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- ConfigurationUtils.java 19 Nov 2004 01:56:30 -0000 1.12
+++ ConfigurationUtils.java 4 Dec 2004 15:45:40 -0000 1.13
@@ -35,6 +35,9 @@
*/
public final class ConfigurationUtils
{
+ /** Constant for the file URL protocol.*/
+ static final String PROTOCOL_FILE = "file";
+
private static Log log = LogFactory.getLog(ConfigurationUtils.class);
private ConfigurationUtils()
@@ -144,7 +147,7 @@
public static URL getURL(String basePath, String file) throws
MalformedURLException
{
File f = new File(file);
- if (f.isAbsolute()) // already absolute?
+ if (f.isAbsolute()) // already absolute?
{
return f.toURL();
}
@@ -222,7 +225,6 @@
return file;
}
-
/**
* Return the location of the specified resource by searching the user
home
* directory, the current classpath and the system classpath.
@@ -287,7 +289,7 @@
if (url == null)
{
File file = new File(name);
- if (file.isAbsolute()) // already absolute?
+ if (file.isAbsolute() && file.exists()) // already absolute?
{
try
{
@@ -323,7 +325,6 @@
}
}
-
// attempt to load from the user home directory
if (url == null)
{
@@ -386,7 +387,7 @@
{
return null;
}
-
+
String s = url.toString();
if (s.endsWith("/") || StringUtils.isEmpty(url.getPath()))
@@ -421,4 +422,64 @@
}
}
-}
+ /**
+ * Tries to convert the specified base path and file name into a file
object.
+ * This method is called e.g. by the save() methods of file based
+ * configurations. The parameter strings can be relative files, absolute
+ * files and URLs as well.
+ *
+ * @param basePath the base path
+ * @param fileName the file name
+ * @return the file object
+ */
+ public static File getFile(String basePath, String fileName)
+ {
+ // Check if URLs are involved
+ URL url;
+ try
+ {
+ url = new URL(new URL(basePath), fileName);
+ }
+ catch (MalformedURLException mex1)
+ {
+ try
+ {
+ url = new URL(fileName);
+ }
+ catch (MalformedURLException mex2)
+ {
+ url = null;
+ }
+ }
+
+ if (url != null)
+ {
+ File result = fileFromURL(url);
+ if (result != null)
+ {
+ return result;
+ }
+ }
+
+ return constructFile(basePath, fileName);
+ }
+
+ /**
+ * Tries to convert the specified URL to a file object. If this fails,
+ * <b>null</b> is returned.
+ *
+ * @param url the URL
+ * @return the resulting file object
+ */
+ static File fileFromURL(URL url)
+ {
+ if (PROTOCOL_FILE.equals(url.getProtocol()))
+ {
+ return new File(url.getPath());
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
\ No newline at end of file
1.12 +92 -76
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.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- AbstractFileConfiguration.java 2 Dec 2004 22:05:52 -0000 1.11
+++ AbstractFileConfiguration.java 4 Dec 2004 15:45:40 -0000 1.12
@@ -33,22 +33,43 @@
import org.apache.commons.configuration.reloading.ReloadingStrategy;
/**
- * Partial implementation of the <code>FileConfiguration</code> interface.
- * Developpers of file based configuration may wan't to extend this class,
+ * <p>Partial implementation of the <code>FileConfiguration</code> interface.
+ * Developpers of file based configuration may want to extend this class,
* the two methods left to implement are [EMAIL PROTECTED]
AbstractFileConfiguration#load(Reader)}
- * and [EMAIL PROTECTED] AbstractFileConfiguration#save(Reader)}.
+ * and [EMAIL PROTECTED] AbstractFileConfiguration#save(Reader)}.</p>
+ * <p>This base class already implements a couple of ways to specify the
location
+ * of the file this configuration is based on. The following possibilities
+ * exist:
+ * <ul><li>URLs: With the method <code>setURL()</code> a full URL to the
+ * configuration source can be specified. This is the most flexible way. Note
+ * that the <code>save()</code> methods support only <em>file:</em>
URLs.</li>
+ * <li>Files: The <code>setFile()</code> method allows to specify the
+ * configuration source as a file. This can be either a relative or an
+ * absolute file. In the former case the file is resolved based on the
current
+ * directory.</li>
+ * <li>As file paths in string form: With the <code>setPath()</code> method a
+ * full path to a configuration file can be provided as a string.</li>
+ * <li>Separated as base path and file name: This is the native form in which
+ * the location is stored. The base path is a string defining either a local
+ * directory or a URL. It can be set using the <code>setBasePath()</code>
+ * method. The file name, non surprisingly, defines the name of the
configuration
+ * file.</li></ul></p>
*
* @author Emmanuel Bourg
* @version $Revision$, $Date$
* @since 1.0-rc2
*/
-public abstract class AbstractFileConfiguration extends BaseConfiguration
implements FileConfiguration
+public abstract class AbstractFileConfiguration extends BaseConfiguration
implements
+ FileConfiguration
{
protected String fileName;
+
protected String basePath;
- protected URL url;
+
protected boolean autoSave;
+
protected ReloadingStrategy strategy;
+
private Object reloadLock = new Object();
/**
@@ -62,7 +83,8 @@
}
/**
- * Creates and loads the configuration from the specified file.
+ * Creates and loads the configuration from the specified file. The
passed
+ * in string must be a valid file name, either absolute or relativ.
*
* @param fileName The name of the file to load.
*
@@ -74,10 +96,7 @@
this();
// store the file name
- setFileName(fileName);
-
- // update the base path
- setBasePath(ConfigurationUtils.getBasePath(url));
+ setPath(fileName);
// load the file
load();
@@ -114,7 +133,7 @@
public AbstractFileConfiguration(URL url) throws ConfigurationException
{
this();
-
+
// set the URL and update the base path and the file name
setURL(url);
@@ -123,21 +142,13 @@
}
/**
- * Load the configuration from the underlying URL. If the URL is not
- * specified, it attempts to locate the specified file name.
+ * Load the configuration from the underlying location.
*
- * @throws ConfigurationException
+ * @throws ConfigurationException if loading of the configuration fails
*/
public void load() throws ConfigurationException
{
- if (url == null)
- {
- load(fileName);
- }
- else
- {
- load(url);
- }
+ load(getFileName());
}
/**
@@ -262,7 +273,8 @@
}
catch (UnsupportedEncodingException e)
{
- throw new ConfigurationException("The requested encoding is
not supported, try the default encoding.", e);
+ throw new ConfigurationException(
+ "The requested encoding is not supported, try the
default encoding.", e);
}
}
@@ -298,7 +310,7 @@
try
{
// create a new file
- save(ConfigurationUtils.constructFile(basePath, fileName));
+ save(ConfigurationUtils.getFile(basePath, fileName));
}
catch (ConfigurationException e)
{
@@ -321,9 +333,10 @@
*/
public void save(URL url) throws ConfigurationException
{
- if ("file".equals(url.getProtocol()))
+ File file = ConfigurationUtils.fileFromURL(url);
+ if (file != null)
{
- save(new File(url.getFile()));
+ save(file);
}
}
@@ -400,7 +413,8 @@
}
catch (UnsupportedEncodingException e)
{
- throw new ConfigurationException("The requested encoding is
not supported, try the default encoding.", e);
+ throw new ConfigurationException(
+ "The requested encoding is not supported, try the
default encoding.", e);
}
}
@@ -421,16 +435,15 @@
}
/**
- * Set the name of the file.
+ * Set the name of the file. The passed in file name should not contain a
+ * path. Use <code>[EMAIL PROTECTED]
AbstractFileConfiguration#setPath(String)
+ * setPath()}</code> to set a full qualified file name.
*
* @param fileName the name of the file
*/
public void setFileName(String fileName)
{
this.fileName = fileName;
-
- // update the URL
- url = ConfigurationUtils.locate(basePath, fileName);
}
/**
@@ -443,82 +456,85 @@
/**
* Set the base path. Relative configurations are loaded from this path.
+ * The base path can be either a path to a directory or a URL.
*
* @param basePath the base path.
*/
public void setBasePath(String basePath)
{
this.basePath = basePath;
-
- // todo: update the url
}
/**
- * Return the file where the configuration is stored.
+ * Return the file where the configuration is stored. If the base path is
+ * a URL with a protocol different than "file", the return
value
+ * will not point to a valid file object.
+ *
+ * @return the file where the configuration is stored
*/
public File getFile()
{
- if (url != null && "file".equals(url.getProtocol()))
- {
- return new File(url.getFile());
- }
- else
- {
- return ConfigurationUtils.constructFile(getBasePath(),
getFileName());
- }
+ return ConfigurationUtils.getFile(getBasePath(), getFileName());
}
/**
- * Set the file where the configuration is stored.
+ * Set the file where the configuration is stored. The passed in file is
+ * made absolute if it is not yet. Then the file's path component becomes
+ * the base path and its name component becomes the file name.
*
- * @param file
+ * @param file the file where the configuration is stored
*/
public void setFile(File file)
{
- if (file != null)
- {
- try
- {
- setURL(file.toURL());
- }
- catch (IOException e)
- {
- e.printStackTrace();
- }
- }
- else
- {
- url = null;
- }
+ setFileName(file.getName());
+ setBasePath((file.getParentFile() != null) ?
file.getParentFile().getAbsolutePath() : null);
+ }
+
+ /**
+ * Returns the full path to the file this configuration is based on. The
+ * return value is valid only if this configuration is based on a file on
+ * the local disk.
+ *
+ * @return the full path to the configuration file
+ */
+ public String getPath()
+ {
+ return getFile().getAbsolutePath();
+ }
+
+ /**
+ * Sets the location of this configuration as a full path name. The
passed
+ * in path should represent a valid file name.
+ *
+ * @param path the full path name of the configuration file
+ */
+ public void setPath(String path)
+ {
+ setFile(new File(path));
}
/**
* Return the URL where the configuration is stored.
+ *
+ * @return the configuration's location as URL
*/
public URL getURL()
{
- return url;
+ return ConfigurationUtils.locate(getBasePath(), getFileName());
}
/**
- * Set the URL where the configuration is stored.
+ * Set the location of this configuration as a URL. For loading this can
be
+ * an arbitrary URL with a supported protocol. If the configuration is to
+ * be saved, too, a URL with the "file" protocol should be
+ * provided.
*
- * @param url
+ * @param url the location of this configuration as URL
*/
public void setURL(URL url)
{
- this.url = url;
-
- // update the base path
- basePath = ConfigurationUtils.getBasePath(url);
- if (basePath != null && basePath.startsWith("file:"))
- {
- // remove the "file:" prefix from file URLs
- basePath = basePath.substring(5);
- }
-
- // update the file name
- fileName = ConfigurationUtils.getFileName(url);
+ setBasePath(ConfigurationUtils.getBasePath(url));
+ setFileName(ConfigurationUtils.getFileName(url));
}
public void setAutoSave(boolean autoSave)
@@ -639,4 +655,4 @@
}
}
}
-}
+}
\ No newline at end of file
1.2 +3 -4
jakarta-commons/configuration/src/java/org/apache/commons/configuration/reloading/FileChangedReloadingStrategy.java
Index: FileChangedReloadingStrategy.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/java/org/apache/commons/configuration/reloading/FileChangedReloadingStrategy.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FileChangedReloadingStrategy.java 18 Oct 2004 15:45:10 -0000 1.1
+++ FileChangedReloadingStrategy.java 4 Dec 2004 15:45:40 -0000 1.2
@@ -106,13 +106,12 @@
*/
protected boolean hasChanged()
{
- if (configuration.getFileName() == null)
+ if (!configuration.getFile().exists())
{
return false;
}
- File file = new File(configuration.getFileName());
- return (file.lastModified() > lastModified);
+ return (configuration.getFile().lastModified() > lastModified);
}
}
1.2 +2 -2
jakarta-commons/configuration/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java
Index: TestFileChangedReloadingStrategy.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/configuration/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestFileChangedReloadingStrategy.java 18 Oct 2004 15:45:10 -0000
1.1
+++ TestFileChangedReloadingStrategy.java 4 Dec 2004 15:45:40 -0000
1.2
@@ -51,7 +51,7 @@
config.setReloadingStrategy(new FileChangedReloadingStrategy());
assertEquals("Initial value", "value1", config.getString("string"));
- Thread.sleep(500);
+ Thread.sleep(5000);
// change the file
out = new FileWriter(file);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]