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 * http://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 * A typical <em>builder</em> implementation for creating {@code FileLocator} objects. An instance of this class is 050 * returned by the {@code fileLocator()} method of {link FileLocatorUtils}. It can be used to define the various 051 * components of the {@code FileLocator} object. By calling {@code create()} the new immutable {@code FileLocator} 052 * instance is created. 053 */ 054 public static final class FileLocatorBuilder { 055 /** The base path. */ 056 private String basePath; 057 058 /** The encoding. */ 059 private String encoding; 060 061 /** The file name. */ 062 private String fileName; 063 064 /** The file system. */ 065 private FileSystem fileSystem; 066 067 /** The location strategy. */ 068 private FileLocationStrategy locationStrategy; 069 070 /** The URL. */ 071 private URL sourceURL; 072 073 /** The URL connection options. */ 074 private URLConnectionOptions urlConnectionOptions; 075 076 /** 077 * Creates a new instance of {@code FileLocatorBuilder} and initializes the builder's properties from the passed in 078 * {@code FileLocator} object. 079 * 080 * @param src the source {@code FileLocator} (may be <b>null</b>) 081 */ 082 FileLocatorBuilder(final FileLocator src) { 083 if (src != null) { 084 initBuilder(src); 085 } 086 } 087 088 /** 089 * Specifies the base path of the new {@code FileLocator}. 090 * 091 * @param path the base path 092 * @return a reference to this builder for method chaining 093 */ 094 public FileLocatorBuilder basePath(final String path) { 095 basePath = path; 096 return this; 097 } 098 099 /** 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}