Author: oheger
Date: Mon Sep 16 20:23:54 2013
New Revision: 1523795
URL: http://svn.apache.org/r1523795
Log:
Added an implementation class for FileLocator.
FileLocatorUtils offers a new method for creating FileLocator objects using a
fluent interface.
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/FileLocatorUtils.java
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestFileLocatorUtils.java
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/FileLocatorUtils.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/FileLocatorUtils.java?rev=1523795&r1=1523794&r2=1523795&view=diff
==============================================================================
---
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/FileLocatorUtils.java
(original)
+++
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/FileLocatorUtils.java
Mon Sep 16 20:23:54 2013
@@ -22,6 +22,9 @@ import java.net.URL;
import org.apache.commons.configuration.ConfigurationUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -68,6 +71,44 @@ public final class FileLocatorUtils
}
/**
+ * Returns an uninitialized {@code FileLocatorBuilder} which can be used
+ * for the creation of a {@code FileLocator} object. This method provides
+ * a convenient way to create file locators using a fluent API as in the
+ * following example:
+ * <pre>
+ * FileLocator locator = FileLocatorUtils.fileLocator()
+ * .basePath(myBasePath)
+ * .fileName("test.xml")
+ * .create();
+ * </pre>
+ * @return a builder object for defining a {@code FileLocator}
+ */
+ public static FileLocatorBuilder fileLocator()
+ {
+ return fileLocator(null);
+ }
+
+ /**
+ * Returns a {@code FileLocatorBuilder} which is already initialized with
+ * the properties of the passed in {@code FileLocator}. This builder can
+ * be used to create a {@code FileLocator} object which shares properties
+ * of the original locator (e.g. the {@code FileSystem} or the encoding),
+ * but points to a different file. An example use case is as follows:
+ * <pre>
+ * FileLocator loc1 = ...
+ * FileLocator loc2 = FileLocatorUtils.fileLocator(loc1)
+ * .setFileName("anotherTest.xml")
+ * .create();
+ * </pre>
+ * @param src the source {@code FileLocator} (may be <b>null</b>)
+ * @return an initialized builder object for defining a {@code FileLocator}
+ */
+ public static FileLocatorBuilder fileLocator(FileLocator src)
+ {
+ return new FileLocatorBuilder(src);
+ }
+
+ /**
* Return the location of the specified resource by searching the user home
* directory, the current classpath and the system classpath.
*
@@ -387,4 +428,261 @@ public final class FileLocatorUtils
return file;
}
+
+ /**
+ * A typical <em>builder</em> implementation for creating
+ * {@code FileLocator} objects. An instance of this class is returned by
the
+ * {@code fileLocator()} method of {@code FileLocatorUtils}. It can be used
+ * to define the various components of the {@code FileLocator} object. By
+ * calling {@code create()} the new immutable {@code FileLocator} instance
+ * is created.
+ */
+ public static final class FileLocatorBuilder
+ {
+ /** The file name. */
+ private String fileName;
+
+ /** The base path. */
+ private String basePath;
+
+ /** The source URL. */
+ private URL sourceURL;
+
+ /** The encoding. */
+ private String encoding;
+
+ /** The file system. */
+ private FileSystem fileSystem;
+
+ /**
+ * Creates a new instance of {@code FileLocatorBuilder} and initializes
+ * the builder's properties from the passed in {@code FileLocator}
+ * object.
+ *
+ * @param src the source {@code FileLocator} (may be <b>null</b>)
+ */
+ private FileLocatorBuilder(FileLocator src)
+ {
+ if (src != null)
+ {
+ initBuilder(src);
+ }
+ }
+
+ /**
+ * Specifies the encoding of the new {@code FileLocator}.
+ *
+ * @param enc the encoding
+ * @return a reference to this builder for method chaining
+ */
+ public FileLocatorBuilder encoding(String enc)
+ {
+ encoding = enc;
+ return this;
+ }
+
+ /**
+ * Specifies the {@code FileSystem} of the new {@code FileLocator}.
+ *
+ * @param fs the {@code FileSystem}
+ * @return a reference to this builder for method chaining
+ */
+ public FileLocatorBuilder fileSystem(FileSystem fs)
+ {
+ fileSystem = fs;
+ return this;
+ }
+
+ /**
+ * Specifies the base path of the new {@code FileLocator}.
+ *
+ * @param path the base path
+ * @return a reference to this builder for method chaining
+ */
+ public FileLocatorBuilder basePath(String path)
+ {
+ basePath = path;
+ return this;
+ }
+
+ /**
+ * Specifies the file name of the new {@code FileLocator}.
+ *
+ * @param name the file name
+ * @return a reference to this builder for method chaining
+ */
+ public FileLocatorBuilder fileName(String name)
+ {
+ fileName = name;
+ return this;
+ }
+
+ /**
+ * Specifies the source URL of the new {@code FileLocator}.
+ *
+ * @param url the source URL
+ * @return a reference to this builder for method chaining
+ */
+ public FileLocatorBuilder sourceURL(URL url)
+ {
+ sourceURL = url;
+ return this;
+ }
+
+ /**
+ * Creates a new immutable {@code FileLocator} object based on the
+ * properties set so far for this builder.
+ *
+ * @return the newly created {@code FileLocator} object
+ */
+ public FileLocator create()
+ {
+ return new FileLocatorImpl(this);
+ }
+
+ /**
+ * Initializes the properties of this builder from the passed in
locator
+ * object.
+ *
+ * @param src the source {@code FileLocator}
+ */
+ private void initBuilder(FileLocator src)
+ {
+ basePath = src.getBasePath();
+ fileName = src.getFileName();
+ sourceURL = src.getSourceURL();
+ encoding = src.getEncoding();
+ fileSystem = src.getFileSystem();
+ }
+ }
+
+ /**
+ * A straight-forward immutable implementation of {@code FileLocator}.
+ */
+ private static class FileLocatorImpl implements FileLocator
+ {
+ /** The file name. */
+ private final String fileName;
+
+ /** The base path. */
+ private final String basePath;
+
+ /** The source URL. */
+ private final URL sourceURL;
+
+ /** The encoding. */
+ private final String encoding;
+
+ /** The file system. */
+ private final FileSystem fileSystem;
+
+ /**
+ * Creates a new instance of {@code FileLocatorImpl} and initializes it
+ * from the given builder instance
+ *
+ * @param builder the builder
+ */
+ public FileLocatorImpl(FileLocatorBuilder builder)
+ {
+ fileName = builder.fileName;
+ basePath = builder.basePath;
+ sourceURL = builder.sourceURL;
+ encoding = builder.encoding;
+ fileSystem = builder.fileSystem;
+ }
+
+ public String getFileName()
+ {
+ return fileName;
+ }
+
+ public String getBasePath()
+ {
+ return basePath;
+ }
+
+ public URL getSourceURL()
+ {
+ return sourceURL;
+ }
+
+ public String getEncoding()
+ {
+ return encoding;
+ }
+
+ public FileSystem getFileSystem()
+ {
+ return fileSystem;
+ }
+
+ /**
+ * Returns a hash code for this object.
+ *
+ * @return a hash code for this object
+ */
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder().append(getFileName())
+ .append(getBasePath()).append(sourceURLAsString())
+
.append(getEncoding()).append(getFileSystem()).toHashCode();
+ }
+
+ /**
+ * Compares this object with another one. Two instances of
+ * {@code FileLocatorImpl} are considered equal if all of their
+ * properties are equal.
+ *
+ * @param obj the object to compare to
+ * @return a flag whether these objects are equal
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (!(obj instanceof FileLocatorImpl))
+ {
+ return false;
+ }
+
+ FileLocatorImpl c = (FileLocatorImpl) obj;
+ return new EqualsBuilder().append(getFileName(), c.getFileName())
+ .append(getBasePath(), c.getBasePath())
+ .append(sourceURLAsString(), c.sourceURLAsString())
+ .append(getEncoding(), c.getEncoding())
+ .append(getFileSystem(), c.getFileSystem()).isEquals();
+ }
+
+ /**
+ * Returns a string representation of this object. This string contains
+ * the values of all properties.
+ *
+ * @return a string for this object
+ */
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this).append("fileName", getFileName())
+ .append("basePath", getBasePath())
+ .append("sourceURL", sourceURLAsString())
+ .append("encoding", getEncoding())
+ .append("fileSystem", getFileSystem()).toString();
+ }
+
+ /**
+ * Returns the source URL as a string. Result is never null.
Comparisons
+ * are done on this string to avoid blocking network calls.
+ *
+ * @return the source URL as a string (not null)
+ */
+ private String sourceURLAsString()
+ {
+ return (sourceURL != null) ? sourceURL.toExternalForm()
+ : StringUtils.EMPTY;
+ }
+ }
}
Modified:
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestFileLocatorUtils.java
URL:
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestFileLocatorUtils.java?rev=1523795&r1=1523794&r2=1523795&view=diff
==============================================================================
---
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestFileLocatorUtils.java
(original)
+++
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestFileLocatorUtils.java
Mon Sep 16 20:23:54 2013
@@ -16,13 +16,20 @@
*/
package org.apache.commons.configuration.io;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
+import org.apache.commons.configuration.ConfigurationAssert;
+import org.easymock.EasyMock;
+import org.junit.BeforeClass;
import org.junit.Test;
/**
@@ -32,6 +39,29 @@ import org.junit.Test;
*/
public class TestFileLocatorUtils
{
+ /** Constant for a file name. */
+ private static final String FILE_NAME = "testFile.dat";
+
+ /** Constant for a base path. */
+ private static final String BASE_PATH = "/etc/test/path/";
+
+ /** Constant for a test encoding. */
+ private static final String ENCODING = "utf-8";
+
+ /** A test URL. */
+ private static URL sourceURL;
+
+ /** A test file system. */
+ private static FileSystem fileSystem;
+
+ @BeforeClass
+ public static void setUpOnce() throws Exception
+ {
+ sourceURL = ConfigurationAssert.getTestURL("test.xml");
+ fileSystem = EasyMock.createMock(FileSystem.class);
+ EasyMock.replay(fileSystem);
+ }
+
/**
* Tests whether an encoded "%" character in the file name is handled
correctly by
* fileFromURL(). This test is related to CONFIGURATION-521.
@@ -132,4 +162,162 @@ public class TestFileLocatorUtils
Thread.currentThread().setContextClassLoader(cl);
}
}
+
+ /**
+ * Tests whether an undefined file locator can be created.
+ */
+ @Test
+ public void testCreateFileLocatorUndefined()
+ {
+ FileLocator locator = FileLocatorUtils.fileLocator().create();
+ assertNull("Got a base path", locator.getBasePath());
+ assertNull("Got a file name", locator.getFileName());
+ assertNull("Got a URL", locator.getSourceURL());
+ assertNull("Got an encoding", locator.getEncoding());
+ assertNull("Got a file system", locator.getFileSystem());
+ }
+
+ /**
+ * Tests whether a locator has the expected properties.
+ *
+ * @param locator the locator to check
+ */
+ private static void checkLocator(FileLocator locator)
+ {
+ assertEquals("Wrong base path", BASE_PATH, locator.getBasePath());
+ assertEquals("Wrong file name", FILE_NAME, locator.getFileName());
+ assertEquals("Wrong encoding", ENCODING, locator.getEncoding());
+ assertEquals("Wrong URL", sourceURL.toExternalForm(), locator
+ .getSourceURL().toExternalForm());
+ assertSame("Wrong file system", fileSystem, locator.getFileSystem());
+ }
+
+ /**
+ * Tests the creation of a file locator.
+ */
+ @Test
+ public void testCreateFileLocator()
+ {
+ FileLocator locator =
+ FileLocatorUtils.fileLocator().basePath(BASE_PATH)
+ .fileName(FILE_NAME).encoding(ENCODING)
+ .fileSystem(fileSystem).sourceURL(sourceURL).create();
+ checkLocator(locator);
+ }
+
+ /**
+ * Tests whether a file locator can be created from a source locator.
+ */
+ @Test
+ public void testCreateFileLocatorFromSource()
+ {
+ FileLocator locatorSrc =
+ FileLocatorUtils.fileLocator().basePath(BASE_PATH)
+ .fileName("someFile").encoding(ENCODING)
+ .fileSystem(fileSystem).sourceURL(sourceURL).create();
+ FileLocator locator =
+ FileLocatorUtils.fileLocator(locatorSrc).fileName(FILE_NAME)
+ .create();
+ checkLocator(locator);
+ }
+
+ /**
+ * Tests the equals() implementation of FileLocator if the expected result
+ * is true.
+ */
+ @Test
+ public void testFileLocatorEqualsTrue()
+ {
+ FileLocator loc1 = FileLocatorUtils.fileLocator().create();
+ ConfigurationAssert.checkEquals(loc1, loc1, true);
+ FileLocator loc2 = FileLocatorUtils.fileLocator().create();
+ ConfigurationAssert.checkEquals(loc1, loc2, true);
+ loc1 =
+ FileLocatorUtils.fileLocator().basePath(BASE_PATH)
+ .fileName(FILE_NAME).encoding(ENCODING)
+ .fileSystem(fileSystem).sourceURL(sourceURL).create();
+ loc2 =
+ FileLocatorUtils.fileLocator().basePath(BASE_PATH)
+ .fileName(FILE_NAME).encoding(ENCODING)
+ .fileSystem(fileSystem).sourceURL(sourceURL).create();
+ ConfigurationAssert.checkEquals(loc1, loc2, true);
+ }
+
+ /**
+ * Tests the equals() implementation of FileLocator if the expected result
+ * is false.
+ */
+ @Test
+ public void testFileLocatorEqualsFalse()
+ {
+ FileLocator loc1 =
+ FileLocatorUtils.fileLocator().basePath(BASE_PATH)
+ .fileName(FILE_NAME).encoding(ENCODING)
+ .fileSystem(fileSystem).sourceURL(sourceURL).create();
+ FileLocator loc2 =
+ FileLocatorUtils.fileLocator(loc1)
+ .basePath(BASE_PATH + "_other").create();
+ ConfigurationAssert.checkEquals(loc1, loc2, false);
+ loc2 =
+ FileLocatorUtils.fileLocator(loc1)
+ .fileName(FILE_NAME + "_other").create();
+ ConfigurationAssert.checkEquals(loc1, loc2, false);
+ loc2 =
+ FileLocatorUtils.fileLocator(loc1)
+ .encoding(ENCODING + "_other").create();
+ ConfigurationAssert.checkEquals(loc1, loc2, false);
+ loc2 =
+ FileLocatorUtils.fileLocator(loc1)
+ .fileSystem(EasyMock.createMock(FileSystem.class))
+ .create();
+ ConfigurationAssert.checkEquals(loc1, loc2, false);
+ loc2 =
+ FileLocatorUtils
+ .fileLocator(loc1)
+ .sourceURL(
+ ConfigurationAssert
+ .getTestURL("test.properties"))
+ .create();
+ ConfigurationAssert.checkEquals(loc1, loc2, false);
+ }
+
+ /**
+ * Tests equals() with a null object.
+ */
+ @Test
+ public void testFileLocatorEqualsNull()
+ {
+ FileLocator loc =
+ FileLocatorUtils.fileLocator().fileName(FILE_NAME).create();
+ assertFalse("Wrong result", loc.equals(null));
+ }
+
+ /**
+ * Tests equals() with an object from another class.
+ */
+ @Test
+ public void testFileLocatorEqualsOtherClass()
+ {
+ FileLocator loc =
+ FileLocatorUtils.fileLocator().fileName(FILE_NAME).create();
+ assertFalse("Wrong result", loc.equals(this));
+ }
+
+ /**
+ * Tests the string representation of a locator.
+ */
+ @Test
+ public void testFileLocatorToString()
+ {
+ FileLocator loc =
+ FileLocatorUtils.fileLocator().basePath(BASE_PATH)
+ .fileName(FILE_NAME).encoding(ENCODING)
+ .fileSystem(fileSystem).sourceURL(sourceURL).create();
+ String s = loc.toString();
+ assertThat(s, containsString("fileName=" + FILE_NAME));
+ assertThat(s, containsString("basePath=" + BASE_PATH));
+ assertThat(s, containsString("sourceURL=" + sourceURL));
+ assertThat(s, containsString("encoding=" + ENCODING));
+ assertThat(s, containsString("fileSystem=" + fileSystem));
+ }
}