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    *     https://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.net.URL;
20  import java.util.Objects;
21  
22  /**
23   * <p>
24   * A class describing the location of a file.
25   * </p>
26   * <p>
27   * An instance of this class provides information for locating and accessing a file. The file location can be defined
28   * </p>
29   * <ul>
30   * <li>as a URL; this identifies a file in a unique way</li>
31   * <li>as a combination of base path and file name; if this variant is used, there may be an additional location step
32   * required in order to identify the referenced file (for instance, the file name may be interpreted as the name of a
33   * resource to be loaded from class path).</li>
34   * </ul>
35   * <p>
36   * In addition, other properties are available which are also needed for loading or saving a file, like the underlying
37   * {@link FileSystem}. The encoding to be used when accessing the represented data is also part of the data contained in
38   * an instance; if no encoding is set explicitly, the platform's default encoding is used.
39   * <p>
40   * Instances of this class are immutable and thus can be safely shared between arbitrary components. {@link FileHandler}
41   * also uses an instance to reference the associated file. Instances are created using a <em>builder</em>.
42   * {@link FileLocatorUtils} offers convenience methods for obtaining such a builder.
43   * </p>
44   *
45   * @since 2.0
46   */
47  public final class FileLocator {
48  
49      /**
50       * A typical <em>builder</em> implementation for creating {@code FileLocator} objects. An instance of this class is
51       * returned by the {@code fileLocator()} method of {link FileLocatorUtils}. It can be used to define the various
52       * components of the {@code FileLocator} object. By calling {@code create()} the new immutable {@code FileLocator}
53       * instance is created.
54       */
55      public static final class FileLocatorBuilder {
56  
57          /** The base path. */
58          private String basePath;
59  
60          /** The encoding. */
61          private String encoding;
62  
63          /** The file name. */
64          private String fileName;
65  
66          /** The file system. */
67          private FileSystem fileSystem;
68  
69          /** The location strategy. */
70          private FileLocationStrategy locationStrategy;
71  
72          /** The URL. */
73          private URL sourceURL;
74  
75          /** The URL connection options. */
76          private URLConnectionOptions urlConnectionOptions;
77  
78          /**
79           * Creates a new instance of {@code FileLocatorBuilder} and initializes the builder's properties from the passed in
80           * {@code FileLocator} object.
81           *
82           * @param src the source {@code FileLocator} (may be <strong>null</strong>)
83           */
84          FileLocatorBuilder(final FileLocator src) {
85              if (src != null) {
86                  initBuilder(src);
87              }
88          }
89  
90          /**
91           * Specifies the base path of the new {@code FileLocator}.
92           *
93           * @param path the base path
94           * @return a reference to this builder for method chaining
95           */
96          public FileLocatorBuilder basePath(final String path) {
97              basePath = path;
98              return this;
99          }
100 
101         /**
102          * Creates a new immutable {@code FileLocatorImpl} object based on the properties set so far for this builder.
103          *
104          * @return the newly created {@code FileLocator} object, never null.
105          */
106         public FileLocator create() {
107             return new FileLocator(this);
108         }
109 
110         /**
111          * Specifies the encoding of the new {@code FileLocator}.
112          *
113          * @param enc the encoding
114          * @return a reference to this builder for method chaining
115          */
116         public FileLocatorBuilder encoding(final String enc) {
117             encoding = enc;
118             return this;
119         }
120 
121         /**
122          * Specifies the file name of the new {@code FileLocator}.
123          *
124          * @param name the file name
125          * @return a reference to this builder for method chaining
126          */
127         public FileLocatorBuilder fileName(final String name) {
128             fileName = name;
129             return this;
130         }
131 
132         /**
133          * Specifies the {@code FileSystem} of the new {@code FileLocator}.
134          *
135          * @param fs the {@code FileSystem}
136          * @return a reference to this builder for method chaining
137          */
138         public FileLocatorBuilder fileSystem(final FileSystem fs) {
139             fileSystem = fs;
140             return this;
141         }
142 
143         /**
144          * Initializes the properties of this builder from the passed in locator object.
145          *
146          * @param src the source {@code FileLocator}
147          */
148         private void initBuilder(final FileLocator src) {
149             basePath = src.getBasePath();
150             fileName = src.getFileName();
151             sourceURL = src.getSourceURL();
152             urlConnectionOptions = src.getURLConnectionOptions();
153             encoding = src.getEncoding();
154             fileSystem = src.getFileSystem();
155             locationStrategy = src.getLocationStrategy();
156         }
157 
158         /**
159          * Specifies the {@code FileLocationStrategy} to be used when the referenced file is to be located.
160          *
161          * @param strategy the {@code FileLocationStrategy}
162          * @return a reference to this builder for method chaining
163          */
164         public FileLocatorBuilder locationStrategy(final FileLocationStrategy strategy) {
165             locationStrategy = strategy;
166             return this;
167         }
168 
169         /**
170          * Specifies the source URL of the new {@code FileLocator}.
171          *
172          * @param url the source URL
173          * @return a reference to this builder for method chaining
174          */
175         public FileLocatorBuilder sourceURL(final URL url) {
176             this.sourceURL = url;
177             return this;
178         }
179 
180         /**
181          * Specifies the source URL connection options of the new {@code FileLocator}.
182          *
183          * @param urlConnectionOptions the source URL connection options.
184          * @return a reference to this builder for method chaining
185          */
186         public FileLocatorBuilder urlConnectionOptions(final URLConnectionOptions urlConnectionOptions) {
187             this.urlConnectionOptions = urlConnectionOptions;
188             return this;
189 
190         }
191     }
192 
193     /** The base path. */
194     private final String basePath;
195 
196     /** The encoding. */
197     private final String encoding;
198 
199     /** The file name. */
200     private final String fileName;
201 
202     /** The file system. */
203     private final FileSystem fileSystem;
204 
205     /** The file location strategy. */
206     private final FileLocationStrategy locationStrategy;
207 
208     /** The source URL. */
209     private final URL sourceURL;
210 
211     /** The source URL connection options. */
212     private final URLConnectionOptions urlConnectionOptions;
213 
214     /**
215      * Creates a new instance of {@code FileLocatorImpl} and initializes it from the given builder instance
216      *
217      * @param builder the builder
218      */
219     public FileLocator(final FileLocatorBuilder builder) {
220         fileName = builder.fileName;
221         basePath = builder.basePath;
222         sourceURL = builder.sourceURL;
223         urlConnectionOptions = builder.urlConnectionOptions;
224         encoding = builder.encoding;
225         fileSystem = builder.fileSystem;
226         locationStrategy = builder.locationStrategy;
227     }
228 
229     /**
230      * Compares this object with another one. Two instances of {@code FileLocatorImpl} are considered equal if all of their
231      * properties are equal.
232      *
233      * @param obj the object to compare to
234      * @return a flag whether these objects are equal
235      */
236     @Override
237     public boolean equals(final Object obj) {
238         if (this == obj) {
239             return true;
240         }
241         if (!(obj instanceof FileLocator)) {
242             return false;
243         }
244         final FileLocator other = (FileLocator) obj;
245         return Objects.equals(basePath, other.basePath) && Objects.equals(encoding, other.encoding) && Objects.equals(fileName, other.fileName)
246             && Objects.equals(fileSystem, other.fileSystem) && Objects.equals(locationStrategy, other.locationStrategy)
247             && Objects.equals(sourceURL, other.sourceURL) && Objects.equals(urlConnectionOptions, other.urlConnectionOptions);
248     }
249 
250     /**
251      * Gets the base path stored in this locator or <strong>null</strong> if it is undefined.
252      *
253      * @return the base path
254      */
255     public String getBasePath() {
256         return basePath;
257     }
258 
259     /**
260      * Gets the encoding stored in this locator or <strong>null</strong> if it is undefined.
261      *
262      * @return the encoding
263      */
264     public String getEncoding() {
265         return encoding;
266     }
267 
268     /**
269      * Gets the file name stored in this locator or <strong>null</strong> if it is undefined.
270      *
271      * @return the file name
272      */
273     public String getFileName() {
274         return fileName;
275     }
276 
277     /**
278      * Gets the {@code FileSystem} to be used for accessing the file referenced by this locator or <strong>null</strong> if it is
279      * undefined.
280      *
281      * @return the {@code FileSystem}
282      */
283     public FileSystem getFileSystem() {
284         return fileSystem;
285     }
286 
287     /**
288      * Gets the {@code FileLocationStrategy} to be used for locating the referenced file. If no specific
289      * {@code FileLocationStrategy} has been set, result is <strong>null</strong>. This means that the default strategy should be
290      * used.
291      *
292      * @return the {@code FileLocationStrategy} to be used
293      */
294     public FileLocationStrategy getLocationStrategy() {
295         return locationStrategy;
296     }
297 
298     /**
299      * Gets the URL pointing to the referenced source file or <strong>null</strong> if it is undefined.
300      *
301      * @return the source URL
302      */
303     public URL getSourceURL() {
304         return sourceURL;
305     }
306 
307     /**
308      * Gets the URLConnectionOptions
309      *
310      * @return the URLConnectionOptions
311      */
312     public URLConnectionOptions getURLConnectionOptions() {
313         return urlConnectionOptions;
314     }
315 
316     /**
317      * Returns a hash code for this object.
318      *
319      * @return a hash code for this object
320      */
321     @Override
322     public int hashCode() {
323         return Objects.hash(basePath, encoding, fileName, fileSystem, locationStrategy, sourceURL, urlConnectionOptions);
324     }
325 
326     @Override
327     public String toString() {
328         return "FileLocator [basePath=" + basePath + ", encoding=" + encoding + ", fileName=" + fileName + ", fileSystem=" + fileSystem + ", locationStrategy="
329             + locationStrategy + ", sourceURL=" + sourceURL + ", urlConnectionOptions=" + urlConnectionOptions + "]";
330     }
331 }