A class that manages persistence of an associated {@link FileBased} object.
Instances of this class can be used to load and save arbitrary objects implementing the {@code FileBased} interface in a convenient way from and tovarious locations. At construction time the {@code FileBased} object tomanage is passed in. Basically, this object is assigned a location from which it is loaded and to which it can be saved. The following possibilities exist to specify such a location:
- URLs: With the method {@code setURL()} a full URL to the configurationsource can be specified. This is the most flexible way. Note that the {@code save()} methods support only file: URLs.
- Files: The {@code setFile()} method allows to specify the configurationsource as a file. This can be either a relative or an absolute file. In the former case the file is resolved based on the current directory.
- As file paths in string form: With the {@code setPath()} method a fullpath to a configuration file can be provided as a string.
- Separated as base path and file name: The base path is a string defining either a local directory or a URL. It can be set using the {@code setBasePath()} method. The file name, non surprisingly, defines thename of the configuration file.
An instance stores a location. The {@code load()} and {@code save()} methodsthat do not take an argument make use of this internal location. Alternatively, it is also possible to use overloaded variants of {@code load()} and {@code save()} which expect a location. In these cases thelocation specified takes precedence over the internal one; the internal location is not changed.
The actual position of the file to be loaded is determined by a {@link FileLocationStrategy} based on the location information that has beenprovided. By providing a custom location strategy the algorithm for searching files can be adapted. Save operations require more explicit information. They cannot rely on a location strategy because the file to be written may not yet exist. So there may be some differences in the way location information is interpreted by load and save operations. In order to avoid this, the following approach is recommended:
- Use the desired {@code setXXX()} methods to define the location of thefile to be loaded.
- Call the {@code locate()} method. This method resolves the referencedfile (if possible) and fills out all supported location information.
- Later on, {@code save()} can be called. This method now has sufficientinformation to store the file at the correct location.
When loading or saving a {@code FileBased} object some additionalfunctionality is performed if the object implements one of the following interfaces:
- {@code FileLocatorAware}: In this case an object with the current file location is injected before the load or save operation is executed. This is useful for {@code FileBased} objects that depend on their current location,e.g. to resolve relative path names.
- {@code SynchronizerSupport}: If this interface is implemented, load and save operations obtain a write lock on the {@code FileBased} object beforethey access it. (In case of a save operation, a read lock would probably be sufficient, but because of the possible injection of a {@link FileLocator}object it is not allowed to perform multiple save operations in parallel; therefore, by obtaining a write lock, we are on the safe side.)
This class is thread-safe.
@version $Id: FileHandler.java 1606588 2014-06-29 19:45:14Z oheger $
@since 2.0