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