@Immutable public class ZipDriver extends FsCharsetArchiveDriver<ZipDriverEntry> implements ZipOutputStreamParameters, ZipFileParameters<ZipDriverEntry>
DateTimeConverter.ZIP
.
This configuration pretty much constraints the applicability of this driver
to North American and Western European countries.
However, this driver generally provides best interoperability with third
party tools like the Windows Explorer, WinZip, 7-Zip etc.
To some extent this applies even outside these countries.
Therefore, while you should use this driver to access plain old ZIP files,
you should not use it for custom application file formats - use the
JarDriver
instead in this case.
This driver does not check the CRC value of any entries in existing
archives - use CheckedZipDriver
instead.
Sub-classes must be thread-safe and should be immutable!
Modifier | Constructor and Description |
---|---|
|
ZipDriver(IOPoolProvider ioPoolProvider)
Constructs a new ZIP driver.
|
protected |
ZipDriver(IOPoolProvider provider,
Charset charset)
Constructs a new ZIP driver.
|
Modifier and Type | Method and Description |
---|---|
protected boolean |
check(ZipInputShop input,
ZipDriverEntry entry)
Whether or not the content of the given entry shall get
checked/authenticated when reading it.
|
<M extends FsModel> |
decorate(FsController<M> controller)
A hook which decorates the given file system controller chain with some
more file system controller(s).
|
protected KeyManagerProvider |
getKeyManagerProvider()
Returns the provider for key managers for accessing protected resources
(encryption).
|
protected KeyProviderSyncStrategy |
getKeyProviderSyncStrategy()
Returns the key provider sync strategy.
|
int |
getLevel()
Returns the compression level for entries.
|
int |
getMethod()
Returns the default compression method for entries.
|
OptionOutputSocket |
getOutputSocket(FsController<?> controller,
FsEntryName name,
BitField<FsOutputOption> options,
Entry template)
This implementation modifies
options in the following way before
it forwards the call to controller :
FsOutputOption.STORE is set. |
protected IOPool<?> |
getPool()
Returns the I/O buffer pool to use for allocating temporary I/O buffers.
|
boolean |
getPostambled()
Returns the flag for allowing a postamble of arbitrary length.
|
boolean |
getPreambled()
Returns the flag for allowing a preamble.
|
boolean |
getRedundantContentSupport()
Returns
true if and only if the archive files produced by this
archive driver may contain redundant archive entry contents. |
boolean |
getRedundantMetaDataSupport()
Returns
true if and only if the archive files produced by this
archive driver may contain redundant archive entry meta data. |
URI |
mountPointUri(FsModel model)
A template method which derives the URI which represents the mount point
of the given file system model as the base resource URI for looking up
KeyProvider s. |
FsController<?> |
newController(FsModel model,
FsController<?> parent)
Returns a new thread-safe file system controller for the mount point of
the given file system model and parent file system controller.
|
ZipDriverEntry |
newEntry(String name)
Returns a new ZIP archive entry with the given
name . |
ZipDriverEntry |
newEntry(String name,
Entry.Type type,
Entry template,
BitField<FsOutputOption> mknod)
Returns a new entry for the given name.
|
ZipDriverEntry |
newEntry(String name,
ZipEntry template)
Returns a new ZIP archive entry with the given
name and all
other properties copied from the given template. |
InputShop<ZipDriverEntry> |
newInputShop(FsModel model,
InputSocket<?> input)
Creates a new input shop for reading the archive entries for the
given
model from the given input socket's target. |
protected InputShop<ZipDriverEntry> |
newInputShop(FsModel model,
ReadOnlyFile rof) |
protected OutputShop<ZipDriverEntry> |
newOutputShop(FsModel model,
OptionOutputSocket output,
ZipInputShop source) |
OutputShop<ZipDriverEntry> |
newOutputShop(FsModel model,
OutputSocket<?> output,
InputShop<ZipDriverEntry> source)
This implementation first checks if
FsOutputOption.GROW is set
for the given output socket. |
protected OutputShop<ZipDriverEntry> |
newOutputShop(FsModel model,
OutputStream out,
ZipInputShop source) |
protected boolean |
process(ZipDriverEntry input,
ZipDriverEntry output)
Returns
true if and only if the content of the given input
target entry needs processing when it gets copied to the given output
target entry. |
URI |
resourceUri(FsModel model,
String name)
A template method which derives the resource URI for looking up a
KeyProvider from the given file system model and entry name. |
protected ZipCryptoParameters |
zipCryptoParameters(FsModel model,
Charset charset)
Returns the ZIP crypto parameters for the given file system model
and character set or
null if not available. |
assertEncodable, getCharset, toString, toZipOrTarEntryName
getInputSocket, isFederated, newController, newEntry
getPriority
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
getOverheadSize
getCharset
public ZipDriver(IOPoolProvider ioPoolProvider)
ZIP_CHARSET
for encoding entry names
and comments.ioPoolProvider
- the provider for I/O entry pools for allocating
temporary I/O entries (buffers).protected ZipDriver(IOPoolProvider provider, Charset charset)
provider
- the provider for the I/O buffer pool.charset
- the character set for encoding entry names and comments.protected boolean check(@WillNotClose ZipInputShop input, ZipDriverEntry entry)
true
and the check fails,
then an IOException
gets thrown.entry.isEncrypted()
.public <M extends FsModel> FsController<M> decorate(FsController<M> controller)
The implementation in the class ZipDriver
returns the expression
new ZipKeyController<M>(controller, this)
.
Overridde this method in order to return just the given
controller
if you are overriding
zipCryptoParameters(FsModel, Charset)
and do not want to use
a locatable key manager to resolve passwords for WinZip AES encryption.
M
- the file system model used by the given controller.controller
- the file system controller to decorate or return.
Note that this controller may throw RuntimeException
s
for non-local control flow!controller
.protected KeyManagerProvider getKeyManagerProvider()
The implementation in ZipDriver
always returns
KeyManagerLocator.SINGLETON
.
When overriding this method, subsequent calls must return the same
object.
protected KeyProviderSyncStrategy getKeyProviderSyncStrategy()
ZipDriver
returns
KeyProviderSyncStrategy.RESET_CANCELLED_KEY
.public int getLevel()
ZipEntry.DEFLATED
or ZipEntry.BZIP2
.
Legal values are Deflater.DEFAULT_COMPRESSION
or range from
Deflater#BEST_SPEED
to Deflater#BEST_COMPRESSION
.
The implementation in the class ZipDriver
returns Deflater#BEST_COMPRESSION
.
getLevel
in interface ZipOutputStreamParameters
Deflater#BEST_COMPRESSION
public int getMethod()
ZipEntry
does not specify a
compression method.
Legal values are ZipEntry.STORED
, ZipEntry.DEFLATED
and ZipEntry.BZIP2
.
The implementation in the class ZipDriver
returns ZipEntry#DEFLATED
.
getMethod
in interface ZipOutputStreamParameters
ZipEntry#DEFLATED
ZipEntry.getMethod()
public OptionOutputSocket getOutputSocket(FsController<?> controller, FsEntryName name, BitField<FsOutputOption> options, @CheckForNull Entry template)
options
in the following way before
it forwards the call to controller
:
FsOutputOption.STORE
is set.
FsOutputOption.GROW
is set, FsOutputOption.APPEND
gets set too, and FsOutputOption.CACHE
gets cleared.
The resulting output socket is then wrapped in a private nested class
for an upcast in newOutputShop(de.schlichtherle.truezip.fs.FsModel, de.schlichtherle.truezip.socket.OutputSocket<?>, de.schlichtherle.truezip.socket.InputShop<de.schlichtherle.truezip.fs.archive.zip.ZipDriverEntry>)
.
Thus, when overriding this method, newOutputShop(de.schlichtherle.truezip.fs.FsModel, de.schlichtherle.truezip.socket.OutputSocket<?>, de.schlichtherle.truezip.socket.InputShop<de.schlichtherle.truezip.fs.archive.zip.ZipDriverEntry>)
should get
overridden, too.
Otherwise, a class cast exception will get thrown in
newOutputShop(de.schlichtherle.truezip.fs.FsModel, de.schlichtherle.truezip.socket.OutputSocket<?>, de.schlichtherle.truezip.socket.InputShop<de.schlichtherle.truezip.fs.archive.zip.ZipDriverEntry>)
.
getOutputSocket
in class FsArchiveDriver<ZipDriverEntry>
controller
- the controller to use for writing an artifact of this
driver.name
- the entry name.options
- the options to use.template
- the template to use.protected final IOPool<?> getPool()
FsArchiveDriver
Multiple invocations should return the same I/O buffer pool. However, callers should cache the return value for subsequent use in case it isn't always the same.
getPool
in class FsArchiveDriver<ZipDriverEntry>
public boolean getPostambled()
If this method returns true
, then a ZIP file is allowed to
contain arbitrary data of arbitrary length as its postamble after the
actual ZIP file data.
Note that searching for an arbitrary length postamble can seriously
degrade the performance when reading a false positive ZIP file, i.e.
an arbitrary file which is not compatible to the ZIP File Format
Specification, because then the entire file needs to get searched for
an End Of Central Directory Record (EOCDR) signature.
A valid use case are self extracting ZIP files with very large
postambles to host the extraction code.
If this method returns false
, then a ZIP file may still have a
postamble, but it must not exceed 64KB size, including the End Of
Central Directory record with the ZIP file comment.
This causes the reading of a false positive ZIP file to fail fast.
The implementation in the class ZipDriver
returns false
.
getPostambled
in interface ZipFileParameters<ZipDriverEntry>
false
public boolean getPreambled()
If this method returns true
, then a ZIP file is allowed to
contain arbitrary data as its preamble before the actual ZIP file data.
Self Extracting Archives typically use a preamble to store the
application code that is required to extract the ZIP file contents.
If this method returns false
, the a ZIP file must start with
either a Local File Header (LFH) signature,
a ZIP64 End Of Central Directory Record (EOCDR) signature or an End Of
Central Directory Record (EOCDR) signature.
The implementation in the class ZipDriver
returns false
.
getPreambled
in interface ZipFileParameters<ZipDriverEntry>
false
public boolean getRedundantContentSupport()
true
if and only if the archive files produced by this
archive driver may contain redundant archive entry contents.
If the return value is true
, then an archive file may contain
redundant archive entry contents, but only the last contents written
should get used when reading the archive file.getRedundantContentSupport
in class FsArchiveDriver<ZipDriverEntry>
ZipDriver
returns
true
because when reading a ZIP file sequentially,
each ZIP entry should "override" any previously read
ZIP entry with an equal name.
This holds true even if the central directory is used to access
the ZIP entries in random order.public boolean getRedundantMetaDataSupport()
true
if and only if the archive files produced by this
archive driver may contain redundant archive entry meta data.
If the return value is true
, then an archive file may contain
redundant archive entry meta data, but only the last meta data written
should get used when reading the archive file.
This usually implies the existence of a central directory in the
resulting archive file.getRedundantMetaDataSupport
in class FsArchiveDriver<ZipDriverEntry>
ZipDriver
returns
true
because when reading a ZIP file sequentially,
each ZIP entry should "override" any previously read
ZIP entry with an equal name.
This holds true even if the central directory is used to access
the ZIP entries in random order.public URI mountPointUri(FsModel model)
KeyProvider
s.
The implementation in the class ZipDriver
returns the
expression model.getMountPoint().toHierarchicalUri()
in order to improve the readability of the URI in comparison to the
expression model.getMountPoint().toUri()
.
model
- the file system model.public FsController<?> newController(FsModel model, FsController<?> parent)
When called, you may assert the following precondition:
model.getParent().equals(parent.getModel())
Note that the parent file system controller of an archive file system is
never null
.
The implementation in the class FsArchiveDriver
calls
superNewController(de.schlichtherle.truezip.fs.FsModel, de.schlichtherle.truezip.fs.FsController<?>)
a
partial file system controller chain and passes the result to
decorate(de.schlichtherle.truezip.fs.FsController<M>)
for further decoration.
newController
in class FsArchiveDriver<ZipDriverEntry>
model
- the file system model.parent
- the non-null parent file system controller.FsCompositeDriver.newController(de.schlichtherle.truezip.fs.FsManager, de.schlichtherle.truezip.fs.FsModel, de.schlichtherle.truezip.fs.FsController<? extends de.schlichtherle.truezip.fs.FsModel>)
public ZipDriverEntry newEntry(String name)
name
.newEntry
in interface ZipEntryFactory<ZipDriverEntry>
name
- the entry name.new ZipDriverEntry(name)
public ZipDriverEntry newEntry(String name, Entry.Type type, @CheckForNull Entry template, BitField<FsOutputOption> mknod) throws CharConversionException
FsArchiveDriver
entry name
for their
particular requirements.
If template
is not null
, then the returned entry shall
inherit as much properties from this template as possible - with the
exception of its name and type.
Furthermore, if name
and type
are equal to the name and
type of this template, then the returned entry shall be a (deep) clone
of the template which shares no mutable state with the template.
newEntry
in class FsArchiveDriver<ZipDriverEntry>
name
- an entry name.type
- an entry type.template
- if not null
, then the new entry shall inherit
as much properties from this entry as possible - with the
exception of its name and type.mknod
- when called from FsController.mknod(de.schlichtherle.truezip.fs.FsEntryName, de.schlichtherle.truezip.entry.Entry.Type, de.schlichtherle.truezip.util.BitField<de.schlichtherle.truezip.fs.FsOutputOption>, de.schlichtherle.truezip.entry.Entry)
, this is its
options
parameter, otherwise it's typically an empty set.CharConversionException
- TODO: This has been deprecated and
should get removed.public ZipDriverEntry newEntry(String name, ZipEntry template)
name
and all
other properties copied from the given template.name
- the entry name.new ZipDriverEntry(name, template)
public InputShop<ZipDriverEntry> newInputShop(FsModel model, InputSocket<?> input) throws IOException
model
from the given input
socket's target.
Note that the returned input shop does not need to be thread-safe.
The implementation in the class ZipDriver
acquires a read only
file from the given socket and forwards the call to
newInputShop(de.schlichtherle.truezip.fs.FsModel, de.schlichtherle.truezip.socket.InputSocket<?>)
.
newInputShop
in class FsArchiveDriver<ZipDriverEntry>
model
- the file system model.input
- the input socket for reading the contents of the
archive file from its target.
This is guaranteed to be the product of this driver's
FsArchiveDriver.getInputSocket(de.schlichtherle.truezip.fs.FsController<?>, de.schlichtherle.truezip.fs.FsEntryName, de.schlichtherle.truezip.util.BitField<de.schlichtherle.truezip.fs.FsInputOption>)
method.IOException
- on any I/O error.
If the file system entry for the given model exists in the
parent file system and is not a Entry.Type.SPECIAL
type, then this exception is deemed to indicate a
persistent false positive archive file and gets cached
until the file system controller for the given model is
synced
again.
Otherwise, this exception is deemed to indicate a
transient false positive archive file and does not
get cached.@CreatesObligation protected InputShop<ZipDriverEntry> newInputShop(FsModel model, @WillCloseWhenClosed ReadOnlyFile rof) throws IOException
IOException
@CreatesObligation protected OutputShop<ZipDriverEntry> newOutputShop(FsModel model, OptionOutputSocket output, @CheckForNull @WillNotClose ZipInputShop source) throws IOException
IOException
public final OutputShop<ZipDriverEntry> newOutputShop(FsModel model, OutputSocket<?> output, InputShop<ZipDriverEntry> source) throws IOException
FsOutputOption.GROW
is set
for the given output
socket.
If this is the case and the given source
is not null
,
then it's marked for appending to it.
Then, an output stream is acquired from the given output
socket
and the parameters are forwarded to newOutputShop(FsModel, OptionOutputSocket, ZipInputShop)
and the result gets wrapped in a new MultiplexedOutputShop
which uses the current getPool()
.newOutputShop
in class FsArchiveDriver<ZipDriverEntry>
model
- the file system model.output
- the output socket for writing the contents of the
archive file to its target.
This is guaranteed to be the product of this driver's
FsArchiveDriver.getOutputSocket(de.schlichtherle.truezip.fs.FsController<?>, de.schlichtherle.truezip.fs.FsEntryName, de.schlichtherle.truezip.util.BitField<de.schlichtherle.truezip.fs.FsOutputOption>, de.schlichtherle.truezip.entry.Entry)
method.source
- the InputShop
if archive
is going to get
updated.
If not null
, this is guaranteed to be the product
of this driver's FsArchiveDriver.newInputShop(de.schlichtherle.truezip.fs.FsModel, de.schlichtherle.truezip.socket.InputSocket<?>)
factory method.
This feature could get used to copy some meta data which is
specific to the type of archive this driver supports,
e.g. the comment of a ZIP file.IOException
- on any I/O error.@CreatesObligation protected OutputShop<ZipDriverEntry> newOutputShop(FsModel model, @WillCloseWhenClosed OutputStream out, @CheckForNull @WillNotClose ZipInputShop source) throws IOException
IOException
protected boolean process(ZipDriverEntry input, ZipDriverEntry output)
true
if and only if the content of the given input
target entry needs processing when it gets copied to the given output
target entry.
This method gets called twice (once on each side of a copy operation)
and should return false
unless both target entries can mutually
agree on transferring raw (unprocessed) content.
Note that it is an error to compare the properties of the target entries
because this method may get called before the local output target gets
mutated to compare equal with the peer input target!
The implementation in the class ZipDriver
returns
local.isEncrypted() || peer.isEncrypted()
in order to cover the
typical case that the cipher keys of both targets are not the same.
Note that there is no safe way to explicitly test for this.
input
- the input target entry for copying the contents.output
- the output target entry for copying the contents.public URI resourceUri(FsModel model, String name)
KeyProvider
from the given file system model and entry name.
The implementation in the class ZipDriver
ignores the given
entry name and just returns the expression mountPointUri(model)
in order to lookup the same key provider for all entries in a ZIP file.
An alternative implementation in a sub-class could return the expression
mountPointUri(model).resolve("/" + name)
instead.
model
- the file system model.name
- the entry name.KeyProvider
.@CheckForNull protected ZipCryptoParameters zipCryptoParameters(FsModel model, Charset charset)
null
if not available.
To enable the use of this method when writing an archive entry with the
client APIs, you must use FsOutputOption.ENCRYPT
.
The implementation in the class ZipDriver
returns
new KeyManagerZipCryptoParameters(getKeyManagerProvider(), mountPointUri(model), charset)
.
model
- the file system model.charset
- charset the character set used for encoding entry names
and the file comment in the ZIP file.null
if not available.Copyright © 2005–2018 Schlichtherle IT Services. All rights reserved.