de.schlichtherle.io
Class DefaultArchiveDetector

java.lang.Object
  extended by de.schlichtherle.io.AbstractArchiveDetector
      extended by de.schlichtherle.io.DefaultArchiveDetector
All Implemented Interfaces:
ArchiveDetector, FileFactory, Serializable

public class DefaultArchiveDetector
extends AbstractArchiveDetector
implements Serializable

An ArchiveDetector which matches file paths against a pattern of archive file suffixes in order to detect prospective archive files and look up their corresponding ArchiveDriver in its registry.

When this class is loaded, it uses the current thread's context class loader to enumerate all instances of the relative path META-INF/services/de.schlichtherle.io.registry.properties on the class path (this is to ensure that TrueZIP is compatible with JNLP / Java Web Start and can be safely added to the boot class path or extension class path). These configuration files are processed in arbitrary order to configure the global registry of archive file suffixes and archive drivers. This allows archive drivers to be "plugged in" by simply providing their own configuration file somewhere on the class path. One such instance is located inside the JAR for TrueZIP itself and contains TrueZIP's default configuration (please refer to this file for full details on the syntax). Likewise, client applications may provide their own configuration file somewhere on the class path in order to extend or override the settings configured by TrueZIP and any optional plug-in drivers.

Each instance has a local registry. Constructors are provided which allow an instance to:

  1. Filter the set of archive file suffixes in the global registry. For example, "tar|zip" could be accepted by the filter in order to recognize only the TAR and ZIP file formats.
  2. Add custom archive file suffixes for supported archive types to the local registry in order to create pseudo archive types. For example, "myapp" could be added as an custom archive file suffix for the JAR file format.
  3. Add custom archive file suffixes and archive drivers to the local registry in order to support new archive types. For example, the suffix "7z" could be associated to a custom archive driver which supports the 7z file format.
  4. Put multiple instances in a chain of responsibility: The first instance which holds a mapping for any given archive file suffix in its registry determines the archive driver to be used.

Altogether, this enables to build arbitrary complex configurations with very few lines of Java code or properties in the configuration file(s).

Where a constructor expects a suffix list as a parameter, this string must have the form "suffix[|suffix]*", where suffix is a combination of case insensitive letters. Empty or duplicated suffixes and leading dots are silently ignored and null is interpreted as an empty list. As an example, the parameter "zip|jar" would cause the archive detector to recognize ZIP and JAR files in a path. The same would be true for "||.ZIP||.JAR||ZIP||JAR||", but this notation is discouraged because it's not in canonical form (see getSuffixes().

ArchiveDriver classes are loaded on demand by the getArchiveDriver(java.lang.String) method using the current thread's context class loader. This usually happens when a client application instantiates the File class.

This implementation is (virtually) immutable and thread safe.

Since TrueZIP 6.4, this class is serializable in order to meet the requirements of the File class. However, it's not recommended to serialize DefaultArchiveDetector instances: Together with the instance, all associated archive drivers are serialized, too, which is pretty inefficient for a single instance.

Since:
TrueZIP 6.0
Version:
TrueZIP 6.7
Author:
Christian Schlichtherle
See Also:
ArchiveDetector.NULL, ArchiveDetector.DEFAULT, ArchiveDetector.ALL, Serialized Form

Field Summary
static String ALL_SUFFIXES
          Deprecated. This field is not for public use and will vanish private access in the next major release. Use ArchiveDetector.ALL.getSuffixes() instead.
static String DEFAULT_SUFFIXES
          Deprecated. This field is not for public use and will vanish private access in the next major release. Use ArchiveDetector.DEFAULT.getSuffixes() instead.
 
Fields inherited from interface de.schlichtherle.io.ArchiveDetector
ALL, DEFAULT, NULL
 
Constructor Summary
DefaultArchiveDetector(DefaultArchiveDetector delegate, Map config)
          Creates a new DefaultArchiveDetector by decorating the configuration of delegate with mappings for all entries in config.
DefaultArchiveDetector(DefaultArchiveDetector delegate, Object[] config)
          Creates a new DefaultArchiveDetector by decorating the configuration of delegate with mappings for all entries in config.
DefaultArchiveDetector(DefaultArchiveDetector delegate, String list, ArchiveDriver driver)
          Creates a new DefaultArchiveDetector by decorating the configuration of delegate with mappings for all canonicalized suffixes in list to driver.
DefaultArchiveDetector(String list)
          Creates a new DefaultArchiveDetector by filtering the global registry for all canonicalized suffixes in list.
DefaultArchiveDetector(String list, ArchiveDriver driver)
          Equivalent to DefaultArchiveDetector(ArchiveDetector.NULL, list, driver).
 
Method Summary
 ArchiveDriver getArchiveDriver(String path)
          Looks up a registered archive driver for the given (file) path by matching it against the set of configured archive file suffixes.
 String getSuffixes()
          Returns the set of archive file suffixes recognized by this archive detector in canonical form.
 
Methods inherited from class de.schlichtherle.io.AbstractArchiveDetector
createFile, createFile, createFile, createFile, createFile, createFile, createFile, createFileInputStream, createFileOutputStream
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_SUFFIXES

public static final String DEFAULT_SUFFIXES
Deprecated. This field is not for public use and will vanish private access in the next major release. Use ArchiveDetector.DEFAULT.getSuffixes() instead.
The canonical list of archive file suffixes in the global registry which have been configured to be recognized by default.


ALL_SUFFIXES

public static final String ALL_SUFFIXES
Deprecated. This field is not for public use and will vanish private access in the next major release. Use ArchiveDetector.ALL.getSuffixes() instead.
The canonical list of all archive file suffixes in the global registry.

Constructor Detail

DefaultArchiveDetector

public DefaultArchiveDetector(String list)
Creates a new DefaultArchiveDetector by filtering the global registry for all canonicalized suffixes in list.

Parameters:
list - A list of suffixes which shall identify prospective archive files. May be null or empty, but must obeye the usual syntax.
Throws:
IllegalArgumentException - If any of the suffixes in the suffix list names a suffix for which no ArchiveDriver is configured in the global registry.
See Also:
Syntax Definition for Suffix Lists

DefaultArchiveDetector

public DefaultArchiveDetector(String list,
                              ArchiveDriver driver)
Equivalent to DefaultArchiveDetector(ArchiveDetector.NULL, list, driver).


DefaultArchiveDetector

public DefaultArchiveDetector(DefaultArchiveDetector delegate,
                              String list,
                              ArchiveDriver driver)
Creates a new DefaultArchiveDetector by decorating the configuration of delegate with mappings for all canonicalized suffixes in list to driver.

Parameters:
delegate - The DefaultArchiveDetector which's configuration is to be virtually inherited.
list - A non-null, non-empty archive file suffix list, obeying the usual syntax.
driver - The archive driver to map for the suffix list. This must either be an archive driver instance or null. A null archive driver may be used to shadow a mapping for the same archive driver in delegate, effectively removing it.
Throws:
NullPointerException - If delegate or list is null.
IllegalArgumentException - If any other parameter precondition does not hold or an illegal keyword is found in the suffix list.
See Also:
Syntax Definition for Suffix Lists

DefaultArchiveDetector

public DefaultArchiveDetector(DefaultArchiveDetector delegate,
                              Object[] config)
Creates a new DefaultArchiveDetector by decorating the configuration of delegate with mappings for all entries in config.

Parameters:
delegate - The DefaultArchiveDetector which's configuration is to be virtually inherited.
config - An array of suffix lists and archive driver IDs. Each key in this map must be a non-null, non-empty archive file suffix list, obeying the usual syntax. Each value must either be an archive driver instance, an archive driver class, a string with the fully qualified name name of an archive driver class, or null. A null archive driver may be used to shadow a mapping for the same archive driver in delegate, effectively removing it.
Throws:
NullPointerException - If any parameter or configuration element other than an archive driver is null.
IllegalArgumentException - If any other parameter precondition does not hold or an illegal keyword is found in the configuration.
See Also:
Syntax Definition for Suffix Lists

DefaultArchiveDetector

public DefaultArchiveDetector(DefaultArchiveDetector delegate,
                              Map config)
Creates a new DefaultArchiveDetector by decorating the configuration of delegate with mappings for all entries in config.

Parameters:
delegate - The DefaultArchiveDetector which's configuration is to be virtually inherited.
config - A map of suffix lists and archive drivers. Each key in this map must be a non-null, non-empty archive file suffix list, obeying the usual syntax. Each value must either be an archive driver instance, an archive driver class, a string with the fully qualified name name of an archive driver class, or null. A null archive driver may be used to shadow a mapping for the same archive driver in delegate, effectively removing it.
Throws:
NullPointerException - If any parameter or configuration element other than an archive driver is null.
IllegalArgumentException - If any other parameter precondition does not hold or an illegal keyword is found in the configuration.
See Also:
Syntax Definition for Suffix Lists
Method Detail

getArchiveDriver

public ArchiveDriver getArchiveDriver(String path)
Looks up a registered archive driver for the given (file) path by matching it against the set of configured archive file suffixes. An archive driver is looked up in the registry as follows:
  1. If the registry holds a string, it's supposed to be the fully qualified class name of an ArchiveDriver implementation. The class will be loaded using the context class loader of the current thread and stored in the registry.
  2. If the registry then holds a class instance, it's instantiated with its no-arguments constructor, cast to the ArchiveDriver type and stored in the registry.
  3. If the registry then holds an instance of an ArchiveDriver implementation, it's returned.
  4. Otherwise, null is returned.

Specified by:
getArchiveDriver in interface ArchiveDetector
Parameters:
path - The (not necessarily absolute) path of the prospective archive file. This does not actually need to be accessible in the real file system!
Returns:
An ArchiveDriver instance for this archive file or null if the path does not denote an archive file (i.e. the path does not have a known suffix) or an appropriate ArchiveDriver is not available for some reason.
Throws:
RuntimeException - A subclass is thrown if loading or instantiating an archive driver class fails.

getSuffixes

public String getSuffixes()
Returns the set of archive file suffixes recognized by this archive detector in canonical form.

Returns:
Either "" to indicate an empty set or a string of the form "suffix[|suffix]*", where suffix is a combination of lower case letters which does not start with a dot. The string never contains empty or duplicated suffixes and the suffixes are sorted in natural order.
See Also:
DefaultArchiveDetector(String)