[CONFIGURATION-634] Reworked createFullyInitializedLocatorFromURL().

After a locate() operation now only properties of a FileLocator are
set which are undefined. Values that had been set explicitly are
not changed. This fixes problems with the base path that is
evaluated by some location strategies.

Thanks to Raviteja Lokineni for the patch.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/configuration/trunk@1750126 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/commons/configuration2/io/FileLocatorUtils.java b/src/main/java/org/apache/commons/configuration2/io/FileLocatorUtils.java
index d1a0a62..a492d7f 100644
--- a/src/main/java/org/apache/commons/configuration2/io/FileLocatorUtils.java
+++ b/src/main/java/org/apache/commons/configuration2/io/FileLocatorUtils.java
@@ -650,8 +650,20 @@
     private static FileLocator createFullyInitializedLocatorFromURL(FileLocator src,
             URL url)
     {
-        return fileLocator(src).sourceURL(url).fileName(getFileName(url))
-                .basePath(getBasePath(url)).create();
+        FileLocator.FileLocatorBuilder fileLocatorBuilder = fileLocator(src);
+        if (src.getSourceURL() == null)
+        {
+            fileLocatorBuilder.sourceURL(url);
+        }
+        if (StringUtils.isBlank(src.getFileName()))
+        {
+            fileLocatorBuilder.fileName(getFileName(url));
+        }
+        if (StringUtils.isBlank(src.getBasePath()))
+        {
+            fileLocatorBuilder.basePath(getBasePath(url));
+        }
+        return fileLocatorBuilder.create();
     }
 
     /**
diff --git a/src/test/java/org/apache/commons/configuration2/builder/TestFileBasedConfigurationBuilder.java b/src/test/java/org/apache/commons/configuration2/builder/TestFileBasedConfigurationBuilder.java
index fb9ed95..0a69b22 100644
--- a/src/test/java/org/apache/commons/configuration2/builder/TestFileBasedConfigurationBuilder.java
+++ b/src/test/java/org/apache/commons/configuration2/builder/TestFileBasedConfigurationBuilder.java
@@ -33,14 +33,18 @@
 
 import org.apache.commons.configuration2.Configuration;
 import org.apache.commons.configuration2.ConfigurationAssert;
+import org.apache.commons.configuration2.FileBasedConfiguration;
 import org.apache.commons.configuration2.PropertiesConfiguration;
 import org.apache.commons.configuration2.XMLConfiguration;
 import org.apache.commons.configuration2.XMLPropertiesConfiguration;
 import org.apache.commons.configuration2.builder.fluent.Parameters;
+import org.apache.commons.configuration2.builder.fluent.PropertiesBuilderParameters;
+import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
 import org.apache.commons.configuration2.ex.ConfigurationException;
 import org.apache.commons.configuration2.io.FileHandler;
 import org.apache.commons.configuration2.io.FileLocator;
 import org.apache.commons.configuration2.io.FileLocatorUtils;
+import org.apache.commons.configuration2.io.HomeDirectoryLocationStrategy;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -508,4 +512,38 @@
         builder.initFileHandler(handler);
         assertEquals("Encoding was changed", encoding, handler.getEncoding());
     }
+
+    /**
+     * Tests whether HomeDirectoryLocationStrategy can be properly initialized
+     * and that it shouldn't throw <code>ConfigurationException</code> when
+     * everything is correctly in place. Without the code fix for
+     * <a href="https://issues.apache.org/jira/browse/CONFIGURATION-634">CONFIGURATION-634</a>,
+     * this test will throw <code>ConfigurationException</code>
+     * @throws IOException              Shouldn't happen
+     * @throws ConfigurationException   Shouldn't happen
+     */
+    @Test
+    public void testFileBasedConfigurationBuilderWithHomeDirectoryLocationStrategy()
+            throws IOException, ConfigurationException
+    {
+        String folderName = "test";
+        String fileName = "sample.properties";
+        folder.newFolder(folderName);
+        folder.newFile(folderName + File.separatorChar + fileName);
+        FileBasedConfigurationBuilder<FileBasedConfiguration> homeDirConfigurationBuilder =
+                new FileBasedConfigurationBuilder<FileBasedConfiguration>(
+                        PropertiesConfiguration.class);
+        PropertiesBuilderParameters homeDirProperties =
+                new Parameters().properties();
+        HomeDirectoryLocationStrategy strategy =
+                new HomeDirectoryLocationStrategy(
+                        folder.getRoot().getAbsolutePath(), true);
+        FileBasedConfigurationBuilder<FileBasedConfiguration> builder =
+                homeDirConfigurationBuilder.configure(homeDirProperties
+                        .setLocationStrategy(strategy).setBasePath(folderName)
+                        .setListDelimiterHandler(
+                                new DefaultListDelimiterHandler(','))
+                        .setFileName(fileName));
+        builder.getConfiguration();
+    }
 }