@ThreadSafe @DefaultAnnotation(value=edu.umd.cs.findbugs.annotations.NonNull.class) public final class TConfig extends Object implements Closeable
A client application can use push() to create a new
inheritable thread local configuration by copying the
current configuration and pushing the copy on top of an inheritable
thread local stack.
A client application can use pop() or close() to
pop the current configuration or this configuration respectively
from the top of the inheritable thread local stack.
Finally, a client application can use get() to get access to the
current configuration.
If no configuration has been pushed on the inheritable thread local stack
before, the global configuration is returned.
Whenever a child thread is started, it will share the current configuration with its parent thread.
If no push() without a corresponding close() or
pop() has been called before, then the get() method will
return the global configuration.
This feature is intended to get used during the application setup to change
some configuration options with a global scope like this:
class MyApplication extends TApplication<IOException> {
//@Override
protected void setup() {
// This should obtain the global configuration.
TConfig config = TConfig.get();
// Configure custom application file format.
config.setArchiveDetector(new TArchiveDetector("aff",
new JarDriver(IOPoolLocator.SINGLETON)));
// Set FsOutputOption.GROW for appending-to rather than reassembling
// existing archive files.
config.setOutputPreferences(
config.getOutputPreferences.set(FsOutputOption.GROW));
}
...
}
If an application needs to change the configuration of just the current
thread rather than changing the global configuration, then the
push() method needs to get called like this:
TFile file1 = new TFile("file.aff");
assert !file1.isArchive();
// First, push a new current configuration onto the inheritable thread local
// stack.
TConfig config = TConfig.push();
try {
// Configure custom application file format "aff".
config.setArchiveDetector(new TArchiveDetector("aff",
new JarDriver(IOPoolLocator.SINGLETON)));
// Now use the current configuration.
TFile file2 = new TFile("file.aff");
assert file2.isArchive();
// Do some I/O here.
...
} finally {
// Pop the current configuration off the inheritable thread local stack.
config.close();
}
Using try-with-resources in JSE 7, this can get shortened to:
TFile file1 = new TFile("file.aff");
assert !file1.isArchive();
// First, push a new current configuration onto the inheritable thread local
// stack.
try (TConfig config = TConfig.push()) {
// Configure custom application file format "aff".
config.setArchiveDetector(new TArchiveDetector("aff",
new JarDriver(IOPoolLocator.SINGLETON)));
// Now use the current configuration.
TFile file2 = new TFile("file.aff");
assert file2.isArchive();
// Do some I/O here.
...
}
By default, TrueZIP is configured to produce the smallest possible archive files. This is achieved by selecting the maximum compression ratio in the archive drivers and by performing an archive update whenever an existing archive entry is going to get overwritten with new contents or updated with new meta data in order to avoid the writing of redundant data to the resulting archive file. An archive update is basically a copy operation where all archive entries which haven't been written yet get copied from the input archive file to the output archive file. However, while this strategy produces the smallest possible archive files, it may yield bad performance if the number and contents of the archive entries to create or update are pretty small compared to the total size of the resulting archive file.
Therefore, you can change this strategy by setting the
FsOutputOption.GROW output option preference when writing archive
entry contents or updating their meta data.
When set, this output option allows archive files to grow by appending new
or updated archive entries to their end and inhibiting archive update
operations.
You can set this preference in the global configuration as shown above or
you can set it on a case-by-case basis as follows:
// We are going to append "entry" to "archive.zip".
TFile file = new TFile("archive.zip/entry");
// First, push a new current configuration on the inheritable thread local
// stack.
TConfig config = TConfig.push();
try {
// Set FsOutputOption.GROW for appending-to rather than reassembling
// existing archive files.
config.setOutputPreferences(
config.getOutputPreferences.set(FsOutputOption.GROW));
// Now use the current configuration and append the entry to the archive
// file even if it's already present.
TFileOutputStream out = new TFileOutputStream(file);
try {
// Do some output here.
...
} finally {
out.close();
}
} finally {
// Pop the current configuration off the inheritable thread local stack.
config.close();
}
Note that it's specific to the archive file system driver if this output option preference is supported or not. If it's not supported, then it gets silently ignored, thereby falling back to the default strategy of performing an archive update whenever required to avoid writing redundant archive entry data. Currently, the situation is like this:
| Modifier and Type | Class and Description |
|---|---|
private static class |
TConfig.Global
Holds the global configuration.
|
private static class |
TConfig.InheritableThreadLocalConfigStack
An inheritable thread local configuration stack.
|
| Modifier and Type | Field and Description |
|---|---|
private static TConfig.InheritableThreadLocalConfigStack |
configs |
static BitField<FsInputOption> |
DEFAULT_INPUT_PREFERENCES
The default value of the
input preferences property, which is
FsInputOptions.NO_INPUT_OPTIONS. |
static BitField<FsOutputOption> |
DEFAULT_OUTPUT_PREFERENCES
The default value of the
output preferences property, which is
. |
private TArchiveDetector |
detector |
private static BitField<FsInputOption> |
INPUT_PREFERENCES_COMPLEMENT_MASK |
private BitField<FsInputOption> |
inputPreferences |
private static BitField<FsOutputOption> |
OUTPUT_PREFERENCES_COMPLEMENT_MASK |
private BitField<FsOutputOption> |
outputPreferences |
| Modifier | Constructor and Description |
|---|---|
private |
TConfig()
Default constructor for the global configuration.
|
private |
TConfig(TConfig template)
Copy constructor for inheritable thread local configurations.
|
| Modifier and Type | Method and Description |
|---|---|
void |
close()
Pops this configuration off the inheritable thread local stack.
|
static TConfig |
get()
Returns the current configuration.
|
TArchiveDetector |
getArchiveDetector()
Returns the default
TArchiveDetector to use for scanning path
names for prospective archive files if no TArchiveDetector has
been explicitly provided to a constructor. |
BitField<FsInputOption> |
getInputPreferences()
Returns the input preferences.
|
(package private) FsManager |
getManager()
Returns the file system manager to use within this package.
|
BitField<FsOutputOption> |
getOutputPreferences()
Returns the output preferences.
|
boolean |
isLenient()
Returns the value of the property
lenient. |
static void |
pop()
Pops the current configuration off the inheritable thread local stack.
|
private static void |
pop(TConfig config) |
static TConfig |
push()
Creates a new current configuration by copying the current configuration
and pushing the copy onto the inheritable thread local stack.
|
void |
setArchiveDetector(TArchiveDetector detector)
Sets the default
TArchiveDetector to use for scanning path
names for prospective archive files if no TArchiveDetector has
been explicitly provided to a constructor. |
void |
setInputPreferences(BitField<FsInputOption> preferences)
Sets the input preferences.
|
void |
setLenient(boolean lenient)
Sets the value of the property
lenient. |
void |
setOutputPreferences(BitField<FsOutputOption> preferences)
Sets the output preferences.
|
@CheckForNull private static volatile TConfig.InheritableThreadLocalConfigStack configs
public static final BitField<FsInputOption> DEFAULT_INPUT_PREFERENCES
input preferences property, which is
FsInputOptions.NO_INPUT_OPTIONS.public static final BitField<FsOutputOption> DEFAULT_OUTPUT_PREFERENCES
output preferences property, which is
BitField.of(FsOutputOption.CREATE_PARENTS).private TArchiveDetector detector
private static final BitField<FsInputOption> INPUT_PREFERENCES_COMPLEMENT_MASK
private BitField<FsInputOption> inputPreferences
private static final BitField<FsOutputOption> OUTPUT_PREFERENCES_COMPLEMENT_MASK
private BitField<FsOutputOption> outputPreferences
private TConfig()
private TConfig(TConfig template)
public void close()
close in interface Closeableclose in interface AutoCloseableIllegalStateException - If this configuration is not the top
element of the inheritable thread local stack.public static TConfig get()
pushed yet, the global
configuration is returned.
Mind that the global configuration is shared by all threads.push()public TArchiveDetector getArchiveDetector()
TArchiveDetector to use for scanning path
names for prospective archive files if no TArchiveDetector has
been explicitly provided to a constructor.TArchiveDetector to use for scanning
path names for prospective archive files.setArchiveDetector(de.schlichtherle.truezip.file.TArchiveDetector)public BitField<FsInputOption> getInputPreferences()
FsManager getManager()
FsManagerLocator.SINGLETON.get(), but this is considered to be
an implementation detail which may be subject to change.public BitField<FsOutputOption> getOutputPreferences()
public boolean isLenient()
lenient.lenient.setLenient(boolean)public static void pop()
IllegalStateException - If the current configuration is the global
configuration.private static void pop(TConfig config)
public static TConfig push()
get()public void setArchiveDetector(TArchiveDetector detector)
TArchiveDetector to use for scanning path
names for prospective archive files if no TArchiveDetector has
been explicitly provided to a constructor.
Changing the value of this property affects the scanning of path names
of subsequently constructed TFile objects only.
Any existing TFile objects are not affected.detector - the default TArchiveDetector to use for scanning
path names for prospective archive files.getArchiveDetector()public void setInputPreferences(BitField<FsInputOption> preferences)
preferences - the input preferences.IllegalArgumentException - if an option is present in
preferences which is not present in
FsInputOptions.INPUT_PREFERENCES_MASK.public void setLenient(boolean lenient)
lenient.
This property controls whether archive files and their member
directories get automatically created whenever required.
By default, the value of this class property is true!
Consider the following path: a/outer.zip/b/inner.zip/c.
Now let's assume that a exists as a plain directory in the
platform file system, while all other segments of this path don't, and
that the module TrueZIP Driver ZIP is present on the run-time class path
in order to detect outer.zip and inner.zip as ZIP files
according to the initial setup.
Now, if this property is set to false, then an application
needs to call new TFile("a/outer.zip/b/inner.zip").mkdirs()
before it can actually create the innermost c entry as a file
or directory.
More formally, before an application can access an entry in a federated file system, all its parent directories need to exist, including archive files. This emulates the behaviour of the platform file system.
If this property is set to true however, then any missing
parent directories (including archive files) up to the outermost archive
file outer.zip get automatically created when using operations
to create the innermost element of the path c.
This enables applications to succeed with doing this:
new TFile("a/outer.zip/b/inner.zip/c").createNewFile(),
or that:
new TFileOutputStream("a/outer.zip/b/inner.zip/c").
Note that in either case the parent directory of the outermost archive
file a must exist - TrueZIP does not automatically create
directories in the platform file system!
lenient - the value of the property lenient.isLenient()public void setOutputPreferences(BitField<FsOutputOption> preferences)
preferences - the output preferences.IllegalArgumentException - if an option is present in
preferences which is not present in
FsOutputOptions.OUTPUT_PREFERENCES_MASK or if both
FsOutputOption.STORE and
FsOutputOption.COMPRESS have been set.Copyright © 2004-2011 Schlichtherle IT Services. All Rights Reserved.