001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.configuration2.io; 018 019import java.net.URL; 020import java.util.Objects; 021 022/** 023 * <p> 024 * A class describing the location of a file. 025 * </p> 026 * <p> 027 * An instance of this class provides information for locating and accessing a file. The file location can be defined 028 * </p> 029 * <ul> 030 * <li>as a URL; this identifies a file in a unique way</li> 031 * <li>as a combination of base path and file name; if this variant is used, there may be an additional location step 032 * required in order to identify the referenced file (for instance, the file name may be interpreted as the name of a 033 * resource to be loaded from class path).</li> 034 * </ul> 035 * <p> 036 * In addition, other properties are available which are also needed for loading or saving a file, like the underlying 037 * {@link FileSystem}. The encoding to be used when accessing the represented data is also part of the data contained in 038 * an instance; if no encoding is set explicitly, the platform's default encoding is used. 039 * <p> 040 * Instances of this class are immutable and thus can be safely shared between arbitrary components. {@link FileHandler} 041 * also uses an instance to reference the associated file. Instances are created using a <em>builder</em>. 042 * {@link FileLocatorUtils} offers convenience methods for obtaining such a builder. 043 * </p> 044 * 045 * @since 2.0 046 */ 047public final class FileLocator { 048 049 /** 050 * A typical <em>builder</em> implementation for creating {@code FileLocator} objects. An instance of this class is 051 * returned by the {@code fileLocator()} method of {link FileLocatorUtils}. It can be used to define the various 052 * components of the {@code FileLocator} object. By calling {@code create()} the new immutable {@code FileLocator} 053 * instance is created. 054 */ 055 public static final class FileLocatorBuilder { 056 057 /** The base path. */ 058 private String basePath; 059 060 /** The encoding. */ 061 private String encoding; 062 063 /** The file name. */ 064 private String fileName; 065 066 /** The file system. */ 067 private FileSystem fileSystem; 068 069 /** The location strategy. */ 070 private FileLocationStrategy locationStrategy; 071 072 /** The URL. */ 073 private URL sourceURL; 074 075 /** The URL connection options. */ 076 private URLConnectionOptions urlConnectionOptions; 077 078 /** 079 * Creates a new instance of {@code FileLocatorBuilder} and initializes the builder's properties from the passed in 080 * {@code FileLocator} object. 081 * 082 * @param src the source {@code FileLocator} (may be <strong>null</strong>) 083 */ 084 FileLocatorBuilder(final FileLocator src) { 085 if (src != null) { 086 initBuilder(src); 087 } 088 } 089 090 /** 091 * Specifies the base path of the new {@code FileLocator}. 092 * 093 * @param path the base path 094 * @return a reference to this builder for method chaining 095 */ 096 public FileLocatorBuilder basePath(final String path) { 097 basePath = path; 098 return this; 099 } 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}