View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.configuration2.io;
18  
19  import java.io.File;
20  import java.net.URL;
21  
22  import org.apache.commons.lang3.StringUtils;
23  
24  /**
25   * <p>
26   * A specialized implementation of {@code FileLocationStrategy} which searches for files in the user's home directory or
27   * another special configurable directory.
28   * </p>
29   * <p>
30   * This strategy implementation ignores the URL stored in the passed in {@link FileLocator}. It constructs a file path
31   * from the configured home directory (which is the user's home directory per default, but can be changed to another
32   * path), optionally the base path, and the file name. If the resulting path points to an existing file, its URL is
33   * returned.
34   * </p>
35   * <p>
36   * When constructing an instance it can be configured whether the base path should be taken into account. If this option
37   * is set, the base path is appended to the home directory if it is not <b>null</b>. This is useful for instance to
38   * select a specific sub directory of the user's home directory. If this option is set to <b>false</b>, the base path is
39   * always ignored, and only the file name is evaluated.
40   * </p>
41   */
42  public class HomeDirectoryLocationStrategy implements FileLocationStrategy {
43      /** Constant for the system property with the user's home directory. */
44      private static final String PROP_HOME = "user.home";
45  
46      /** The home directory to be searched for the requested file. */
47      private final String homeDirectory;
48  
49      /** The flag whether the base path is to be taken into account. */
50      private final boolean evaluateBasePath;
51  
52      /**
53       * Creates a new instance of {@code HomeDirectoryLocationStrategy} and initializes it with the specified settings.
54       *
55       * @param homeDir the path to the home directory (can be <b>null</b>)
56       * @param withBasePath a flag whether the base path should be evaluated
57       */
58      public HomeDirectoryLocationStrategy(final String homeDir, final boolean withBasePath) {
59          homeDirectory = fetchHomeDirectory(homeDir);
60          evaluateBasePath = withBasePath;
61      }
62  
63      /**
64       * Creates a new instance of {@code HomeDirectoryLocationStrategy} and initializes the base path flag. The home
65       * directory is set to the user's home directory.
66       *
67       * @param withBasePath a flag whether the base path should be evaluated
68       */
69      public HomeDirectoryLocationStrategy(final boolean withBasePath) {
70          this(null, withBasePath);
71      }
72  
73      /**
74       * Creates a new instance of {@code HomeDirectoryLocationStrategy} with default settings. The home directory is set to
75       * the user's home directory. The base path flag is set to <b>false</b> (which means that the base path is ignored).
76       */
77      public HomeDirectoryLocationStrategy() {
78          this(false);
79      }
80  
81      /**
82       * Gets the home directory. In this directory the strategy searches for files.
83       *
84       * @return the home directory used by this object
85       */
86      public String getHomeDirectory() {
87          return homeDirectory;
88      }
89  
90      /**
91       * Returns a flag whether the base path is to be taken into account when searching for a file.
92       *
93       * @return the flag whether the base path is evaluated
94       */
95      public boolean isEvaluateBasePath() {
96          return evaluateBasePath;
97      }
98  
99      /**
100      * {@inheritDoc} This implementation searches in the home directory for a file described by the passed in
101      * {@code FileLocator}. If the locator defines a base path and the {@code evaluateBasePath} property is <b>true</b>, a
102      * sub directory of the home directory is searched.
103      */
104     @Override
105     public URL locate(final FileSystem fileSystem, final FileLocator locator) {
106         if (StringUtils.isNotEmpty(locator.getFileName())) {
107             final String basePath = fetchBasePath(locator);
108             final File file = FileLocatorUtils.constructFile(basePath, locator.getFileName());
109             if (file.isFile()) {
110                 return FileLocatorUtils.convertFileToURL(file);
111             }
112         }
113 
114         return null;
115     }
116 
117     /**
118      * Determines the base path to be used for the current locate() operation.
119      *
120      * @param locator the {@code FileLocator}
121      * @return the base path to be used
122      */
123     private String fetchBasePath(final FileLocator locator) {
124         if (isEvaluateBasePath() && StringUtils.isNotEmpty(locator.getBasePath())) {
125             return FileLocatorUtils.appendPath(getHomeDirectory(), locator.getBasePath());
126         }
127         return getHomeDirectory();
128     }
129 
130     /**
131      * Obtains the home directory to be used by a new instance. If a directory name is provided, it is used. Otherwise, the
132      * user's home directory is looked up.
133      *
134      * @param homeDir the passed in home directory
135      * @return the directory to be used
136      */
137     private static String fetchHomeDirectory(final String homeDir) {
138         return homeDir != null ? homeDir : System.getProperty(PROP_HOME);
139     }
140 }