Author: oheger
Date: Sun Sep 22 17:50:15 2013
New Revision: 1525400

URL: http://svn.apache.org/r1525400
Log:
Added HomeDirectoryLocationStrategy.

This FileLocationStrategy implementation searches for files in a configurable
home directory.

Added:
    
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/HomeDirectoryLocationStrategy.java
    
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestHomeDirectoryLocationStrategy.java
Modified:
    
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/FileLocatorUtils.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=1525400&r1=1525399&r2=1525400&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
 Sun Sep 22 17:50:15 2013
@@ -541,34 +541,46 @@ public final class FileLocatorUtils
         }
         else
         {
-            StringBuilder fName = new StringBuilder();
-            fName.append(basePath);
+            file = new File(appendPath(basePath, fileName));
+        }
+
+        return file;
+    }
 
-            // My best friend. Paranoia.
-            if (!basePath.endsWith(File.separator))
-            {
-                fName.append(File.separator);
-            }
-
-            //
-            // We have a relative path, and we have
-            // two possible forms here. If we have the
-            // "./" form then just strip that off first
-            // before continuing.
-            //
-            if (fileName.startsWith("." + File.separator))
-            {
-                fName.append(fileName.substring(2));
-            }
-            else
-            {
-                fName.append(fileName);
-            }
+    /**
+     * Extends a path by another component. The given extension is added to the
+     * already existing path adding a separator if necessary.
+     *
+     * @param path the path to be extended
+     * @param ext the extension of the path
+     * @return the extended path
+     */
+    static String appendPath(String path, String ext)
+    {
+        StringBuilder fName = new StringBuilder();
+        fName.append(path);
 
-            file = new File(fName.toString());
+        // My best friend. Paranoia.
+        if (!path.endsWith(File.separator))
+        {
+            fName.append(File.separator);
         }
 
-        return file;
+        //
+        // We have a relative path, and we have
+        // two possible forms here. If we have the
+        // "./" form then just strip that off first
+        // before continuing.
+        //
+        if (ext.startsWith("." + File.separator))
+        {
+            fName.append(ext.substring(2));
+        }
+        else
+        {
+            fName.append(ext);
+        }
+        return fName.toString();
     }
 
     /**

Added: 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/HomeDirectoryLocationStrategy.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/HomeDirectoryLocationStrategy.java?rev=1525400&view=auto
==============================================================================
--- 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/HomeDirectoryLocationStrategy.java
 (added)
+++ 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/io/HomeDirectoryLocationStrategy.java
 Sun Sep 22 17:50:15 2013
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.io;
+
+import java.io.File;
+import java.net.URL;
+
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * <p>
+ * A specialized implementation of {@code FileLocationStrategy} which searches
+ * for files in the user's home directory or another special configurable
+ * directory.
+ * </p>
+ * <p>
+ * This strategy implementation ignores the URL stored in the passed in
+ * {@link FileLocator}. It constructs a file path from the configured home
+ * directory (which is the user's home directory per default, but can be 
changed
+ * to another path), optionally the base path, and the file name. If the
+ * resulting path points to an existing file, its URL is returned.
+ * </p>
+ * <p>
+ * When constructing an instance it can be configured whether the base path
+ * should be taken into account. If this option is set, the base path is
+ * appended to the home directory if it is not <b>null</b>. This is useful for
+ * instance to select a specific sub directory of the user's home directory. If
+ * this option is set to <b>false</b>, the base path is always ignored, and 
only
+ * the file name is evaluated.
+ * </p>
+ *
+ * @version $Id: $
+ */
+public class HomeDirectoryLocationStrategy implements FileLocationStrategy
+{
+    /** Constant for the system property with the user's home directory. */
+    private static final String PROP_HOME = "user.home";
+
+    /** The home directory to be searched for the requested file. */
+    private final String homeDirectory;
+
+    /** The flag whether the base path is to be taken into account. */
+    private final boolean evaluateBasePath;
+
+    /**
+     * Creates a new instance of {@code HomeDirectoryLocationStrategy} and
+     * initializes it with the specified settings.
+     *
+     * @param homeDir the path to the home directory (can be <b>null</b>)
+     * @param withBasePath a flag whether the base path should be evaluated
+     */
+    public HomeDirectoryLocationStrategy(String homeDir, boolean withBasePath)
+    {
+        homeDirectory = fetchHomeDirectory(homeDir);
+        evaluateBasePath = withBasePath;
+    }
+
+    /**
+     * Creates a new instance of {@code HomeDirectoryLocationStrategy} and
+     * initializes the base path flag. The home directory is set to the user's
+     * home directory.
+     *
+     * @param withBasePath a flag whether the base path should be evaluated
+     */
+    public HomeDirectoryLocationStrategy(boolean withBasePath)
+    {
+        this(null, withBasePath);
+    }
+
+    /**
+     * Creates a new instance of {@code HomeDirectoryLocationStrategy} with
+     * default settings. The home directory is set to the user's home 
directory.
+     * The base path flag is set to <b>false</b> (which means that the base 
path
+     * is ignored).
+     */
+    public HomeDirectoryLocationStrategy()
+    {
+        this(false);
+    }
+
+    /**
+     * Returns the home directory. In this directory the strategy searches for
+     * files.
+     *
+     * @return the home directory used by this object
+     */
+    public String getHomeDirectory()
+    {
+        return homeDirectory;
+    }
+
+    /**
+     * Returns a flag whether the base path is to be taken into account when
+     * searching for a file.
+     *
+     * @return the flag whether the base path is evaluated
+     */
+    public boolean isEvaluateBasePath()
+    {
+        return evaluateBasePath;
+    }
+
+    /**
+     * {@inheritDoc} This implementation searches in the home directory for a
+     * file described by the passed in {@code FileLocator}. If the locator
+     * defines a base path and the {@code evaluateBasePath} property is
+     * <b>true</b>, a sub directory of the home directory is searched.
+     */
+    public URL locate(FileSystem fileSystem, FileLocator locator)
+    {
+        if (StringUtils.isNotEmpty(locator.getFileName()))
+        {
+            String basePath = fetchBasePath(locator);
+            File file =
+                    FileLocatorUtils.constructFile(basePath,
+                            locator.getFileName());
+            if (file.isFile())
+            {
+                return FileLocatorUtils.convertFileToURL(file);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Determines the base path to be used for the current locate() operation.
+     *
+     * @param locator the {@code FileLocator}
+     * @return the base path to be used
+     */
+    private String fetchBasePath(FileLocator locator)
+    {
+        if (isEvaluateBasePath()
+                && StringUtils.isNotEmpty(locator.getBasePath()))
+        {
+            return FileLocatorUtils.appendPath(getHomeDirectory(),
+                    locator.getBasePath());
+        }
+        else
+        {
+            return getHomeDirectory();
+        }
+    }
+
+    /**
+     * Obtains the home directory to be used by a new instance. If a directory
+     * name is provided, it is used. Otherwise, the user's home directory is
+     * looked up.
+     *
+     * @param homeDir the passed in home directory
+     * @return the directory to be used
+     */
+    private static String fetchHomeDirectory(String homeDir)
+    {
+        return (homeDir != null) ? homeDir : System.getProperty(PROP_HOME);
+    }
+}

Added: 
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestHomeDirectoryLocationStrategy.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestHomeDirectoryLocationStrategy.java?rev=1525400&view=auto
==============================================================================
--- 
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestHomeDirectoryLocationStrategy.java
 (added)
+++ 
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/io/TestHomeDirectoryLocationStrategy.java
 Sun Sep 22 17:50:15 2013
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.io;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Test class for {@code HomeDirectoryLocationStrategy}.
+ *
+ * @version $Id: $
+ */
+public class TestHomeDirectoryLocationStrategy
+{
+    /** Constant for a test file name. */
+    private static final String FILE_NAME = "test.tst";
+
+    /** Constant for a base path to be used. */
+    private static final String BASE_PATH = "sub";
+
+    /** An object for dealing with temporary files. */
+    @Rule
+    public TemporaryFolder folder = new TemporaryFolder();
+
+    /** A mock for the file system. */
+    private FileSystem fileSystem;
+
+    @Before
+    public void setUp() throws Exception
+    {
+        fileSystem = EasyMock.createMock(FileSystem.class);
+        EasyMock.replay(fileSystem);
+    }
+
+    /**
+     * Creates a strategy test object which uses the temporary root directory 
as
+     * its home directory.
+     *
+     * @param withBasePath the base path flag
+     * @return the test strategy
+     */
+    private HomeDirectoryLocationStrategy setUpStrategy(boolean withBasePath)
+    {
+        return new HomeDirectoryLocationStrategy(folder.getRoot()
+                .getAbsolutePath(), withBasePath);
+    }
+
+    /**
+     * Tests whether default values are correctly set by the constructor.
+     */
+    @Test
+    public void testInitDefaults()
+    {
+        HomeDirectoryLocationStrategy strategy =
+                new HomeDirectoryLocationStrategy();
+        assertEquals("Wrong home directory", System.getProperty("user.home"),
+                strategy.getHomeDirectory());
+        assertFalse("Wrong base path flag", strategy.isEvaluateBasePath());
+    }
+
+    /**
+     * Tests whether a file can be located if the base path is ignored.
+     */
+    @Test
+    public void testLocateSuccessIgnoreBasePath() throws IOException
+    {
+        File file = folder.newFile(FILE_NAME);
+        FileLocator locator =
+                FileLocatorUtils.fileLocator().basePath(BASE_PATH)
+                        .fileName(FILE_NAME).create();
+        HomeDirectoryLocationStrategy strategy = setUpStrategy(false);
+        URL url = strategy.locate(fileSystem, locator);
+        assertEquals("Wrong URL", file.getAbsoluteFile(), FileLocatorUtils
+                .fileFromURL(url).getAbsoluteFile());
+    }
+
+    /**
+     * Tests whether the base is actually evaluated if the flag is set.
+     */
+    @Test
+    public void testLocateFailedWithBasePath() throws IOException
+    {
+        folder.newFile(FILE_NAME);
+        FileLocator locator =
+                FileLocatorUtils.fileLocator().basePath(BASE_PATH)
+                        .fileName(FILE_NAME).create();
+        HomeDirectoryLocationStrategy strategy = setUpStrategy(true);
+        assertNull("Got a URL", strategy.locate(fileSystem, locator));
+    }
+
+    /**
+     * Tests whether a file in a sub folder can be located.
+     */
+    @Test
+    public void testLocateSuccessInSubFolder() throws IOException
+    {
+        File sub = folder.newFolder(BASE_PATH);
+        File file = new File(sub, FILE_NAME);
+        assertTrue("Could not create file", file.createNewFile());
+        FileLocator locator =
+                FileLocatorUtils.fileLocator().basePath(BASE_PATH)
+                        .fileName(FILE_NAME).create();
+        HomeDirectoryLocationStrategy strategy = setUpStrategy(true);
+        URL url = strategy.locate(fileSystem, locator);
+        assertEquals("Wrong URL", file.getAbsoluteFile(), FileLocatorUtils
+                .fileFromURL(url).getAbsoluteFile());
+    }
+
+    /**
+     * Tests a locate() operation which evaluates the base path if no base path
+     * is set.
+     */
+    @Test
+    public void testLocateSuccessNoBasePath() throws IOException
+    {
+        File file = folder.newFile(FILE_NAME);
+        FileLocator locator =
+                FileLocatorUtils.fileLocator().fileName(FILE_NAME).create();
+        HomeDirectoryLocationStrategy strategy = setUpStrategy(true);
+        URL url = strategy.locate(fileSystem, locator);
+        assertEquals("Wrong URL", file.getAbsoluteFile(), FileLocatorUtils
+                .fileFromURL(url).getAbsoluteFile());
+    }
+
+    /**
+     * Tests a locate() operation if no file name is specified.
+     */
+    @Test
+    public void testNoFileName()
+    {
+        FileLocator locator =
+                FileLocatorUtils.fileLocator().basePath(BASE_PATH).create();
+        HomeDirectoryLocationStrategy strategy = setUpStrategy(true);
+        assertNull("Got a URL", strategy.locate(fileSystem, locator));
+    }
+}


Reply via email to