|
TrueZIP 6.8.2 | ||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Objectde.schlichtherle.io.ArchiveController
abstract class ArchiveController
This is the base class for any archive controller, providing all the
essential services required by the File class to implement its
behaviour.
Each instance of this class manages a globally unique archive file
(the target file) in order to allow random access to it as if it
were a regular directory in the real file system.
In terms of software patterns, an ArchiveController is
similar to a Director in a Builder pattern, with the ArchiveDriver
interface as its Builder or Abstract Factory.
However, an archive controller does not necessarily build a new archive.
It may also simply be used to access an existing archive for read-only
operations, such as listing its top level directory, or reading entry data.
Whatever type of operation it's used for, an archive controller provides
and controls all access to any particular archive file by the
client application and deals with the rather complex details of its
states and transitions.
Each instance of this class maintains a virtual file system, provides input
and output streams for the entries of the archive file and methods
to update the contents of the virtual file system to the target file
in the real file system.
In cooperation with the File class, it also knows how to deal with
nested archive files (such as "outer.zip/inner.tar.gz"
and false positives, i.e. plain files or directories or file or
directory entries in an enclosing archive file which have been incorrectly
recognized to be prospective archive files by the
ArchiveDetector interface.
To ensure that for each archive file there is at most one
{code ArchiveController}, the path name of the archive file (called
target) is canonicalized, so it doesn't matter whether the
File class addresses an archive file as "archive.zip"
or "/dir/archive.zip" if "/dir" is the client
application's current directory.
Note that in general all of its methods are reentrant on exceptions.
This is important because the File class may repeatedly call them,
triggered by the client application. Of course, depending on the context,
some or all of the archive file's data may be lost in this case.
For more information, please refer to File.umount() and
File.update().
This class is actually the abstract base class for any archive controller. It encapsulates all the code which is not depending on a particular entry synchronization strategy and the corresponding state of the controller. Though currently unused, this is intended to be helpful for future extensions of TrueZIP, where different synchronization strategies may be implemented.
| Nested Class Summary | |
|---|---|
(package private) class |
ArchiveController.ArchiveEntryFalsePositiveException
Thrown if a controller's target file is a false positive archive file which actually exists as a plain file or directory in an enclosing archive file. |
(package private) class |
ArchiveController.ArchiveEntryNotFoundException
Thrown if an archive entry does not exist or is not accessible. |
(package private) class |
ArchiveController.ArchiveFileNotFoundException
Thrown if a controller's target file does not exist or is not accessible. |
(package private) class |
ArchiveController.DirectoryArchiveEntryFalsePositiveException
Thrown if a controller's target file is a false positive archive file which actually exists as a plain directory in an enclosing archive file. |
(package private) class |
ArchiveController.FalsePositiveException
Thrown if a controller's target file is a false positive archive file which actually exists as a plain file or directory in the real file system or in an enclosing archive file. |
(package private) class |
ArchiveController.FileArchiveEntryFalsePositiveException
Thrown if a controller's target file is a false positive archive file which actually exists as a plain file in an enclosing archive file. |
(package private) class |
ArchiveController.RfsEntryFalsePositiveException
Thrown if a controller's target file is a false positive archive file which actually exists as a plain file or directory in the real file system. |
| Field Summary | |
|---|---|
private ArchiveDriver |
driver
The ArchiveDriver to use for this controller's target file. |
private ArchiveController |
enclController
The archive controller of the enclosing archive, if any. |
private String |
enclEntryName
The name of the entry for this archive in the enclosing archive, if any. |
private ReentrantLock |
readLock
|
private File |
target
The canonicalized or at least normalized absolute path name representation of the target file. |
private WeakReference |
weakThis
A weak reference to this archive controller. |
private ReentrantLock |
writeLock
|
| Fields inherited from interface de.schlichtherle.io.Entry |
|---|
ROOT_NAME, SEPARATOR, SEPARATOR_CHAR |
| Constructor Summary | |
|---|---|
ArchiveController(File target,
ArchiveController enclController,
String enclEntryName,
ArchiveDriver driver)
This constructor schedules this controller to be thrown away if no more File objects are referring to it. |
|
| Method Summary | |
|---|---|
(package private) abstract ArchiveFileSystem |
autoMount(boolean create)
Returns the virtual archive file system mounted from the target file. |
(package private) void |
autoUmount(String entryName)
Unmounts the archive file only if the archive file has already new data for entryName. |
(package private) boolean |
canRead(String entryName)
|
private boolean |
canRead0(String entryName)
|
(package private) boolean |
canWrite(String entryName)
|
private boolean |
canWrite0(String entryName)
|
(package private) abstract InputStream |
createInputStream(ArchiveEntry entry,
ArchiveEntry dstEntry)
Important: This controller's read or write lock must be acquired. |
(package private) InputStream |
createInputStream(String entryName)
A factory method returning an input stream which is positioned at the beginning of the given entry in the target archive file. |
(package private) InputStream |
createInputStream0(String entryName)
|
(package private) boolean |
createNewFile(String entryName,
boolean autoCreate)
|
private boolean |
createNewFile0(String entryName,
boolean autoCreate)
|
(package private) abstract OutputStream |
createOutputStream(ArchiveEntry entry,
ArchiveEntry srcEntry)
Important: This controller's write lock must be acquired. |
(package private) OutputStream |
createOutputStream(String entryName,
boolean append)
A factory method returning an OutputStream allowing to
(re)write the given entry in the target archive file. |
(package private) OutputStream |
createOutputStream0(String entryName,
boolean append)
|
(package private) boolean |
delete(String entryName)
|
private void |
delete0(String entryName)
|
(package private) String |
enclEntryName(String entryName)
|
(package private) boolean |
exists(String entryName)
|
private boolean |
exists0(String entryName)
|
(package private) Icon |
getClosedIcon(String entryName)
|
private Icon |
getClosedIcon0(String entryName)
|
(package private) ArchiveDriver |
getDriver()
Returns the driver instance which is used for the target archive. |
Archive |
getEnclArchive()
|
(package private) ArchiveController |
getEnclController()
Returns the ArchiveController of the enclosing archive file,
if any. |
(package private) String |
getEnclEntryName()
Returns the entry name of this controller within the enclosing archive file, if any. |
(package private) Icon |
getOpenIcon(String entryName)
|
private Icon |
getOpenIcon0(String entryName)
|
String |
getPath()
Returns the canonical path of the archive file. |
(package private) File |
getTarget()
Returns the canonical or at least normalized absolute java.io.File object for the archive file to control. |
(package private) abstract boolean |
hasNewData(String entryName)
Tests if the archive entry with the given name has received or is currently receiving new data via an output stream. |
(package private) boolean |
isDirectory(String entryName)
|
private boolean |
isDirectory0(String entryName)
|
private boolean |
isEnclosedBy(ArchiveController wannabe)
|
(package private) boolean |
isFile(String entryName)
|
private boolean |
isFile0(String entryName)
|
(package private) boolean |
isRfsEntryTarget()
Returns true if and only if the target file of this
controller should be considered to be a file or directory in the real
file system (RFS). |
(package private) static boolean |
isRoot(String entryName)
Returns true iff the given entry name refers to the
virtual root directory within this controller. |
(package private) abstract boolean |
isTouched()
Returns true if and only if the file system has been
touched. |
(package private) long |
lastModified(String entryName)
|
private long |
lastModified0(String entryName)
|
(package private) long |
length(String entryName)
|
private long |
length0(String entryName)
|
(package private) String[] |
list(String entryName)
|
(package private) String[] |
list(String entryName,
FilenameFilter filenameFilter,
File dir)
|
private String[] |
list0(String entryName)
|
private String[] |
list0(String entryName,
FilenameFilter filenameFilter,
File dir)
|
(package private) File[] |
listFiles(String entryName,
FileFilter fileFilter,
File dir,
FileFactory factory)
|
(package private) File[] |
listFiles(String entryName,
FilenameFilter filenameFilter,
File dir,
FileFactory factory)
|
private File[] |
listFiles0(String entryName,
FileFilter fileFilter,
File dir,
FileFactory factory)
|
private File[] |
listFiles0(String entryName,
FilenameFilter filenameFilter,
File dir,
FileFactory factory)
|
(package private) boolean |
mkdir(String entryName,
boolean autoCreate)
|
private void |
mkdir0(String entryName,
boolean autoCreate)
|
(package private) ReentrantLock |
readLock()
|
(package private) abstract void |
reset()
Resets the archive controller to its initial state - all changes to the archive file which have not yet been updated get lost! |
(package private) void |
runWriteLocked(IORunnable runnable)
Runs the given IORunnable while this controller has
acquired its write lock regardless of the state of its read lock. |
(package private) void |
setDriver(ArchiveDriver driver)
Sets the driver instance which is used for the target archive. |
(package private) boolean |
setLastModified(String entryName,
long time)
|
private boolean |
setLastModified0(String entryName,
long time)
|
(package private) boolean |
setReadOnly(String entryName)
|
private boolean |
setReadOnly0(String entryName)
|
(package private) void |
setScheduled(boolean scheduled)
(Re)schedules this archive controller for the next call to ArchiveControllers.umount(String, boolean, boolean, boolean, boolean, boolean). |
String |
toString()
|
(package private) abstract void |
umount(ArchiveException exceptionChain,
boolean waitInputStreams,
boolean closeInputStreams,
boolean waitOutputStreams,
boolean closeOutputStreams,
boolean umount,
boolean reassemble)
Synchronizes the contents of the target archive file managed by this archive controller to the real file system. |
(package private) abstract int |
waitAllInputStreamsByOtherThreads(long timeout)
|
(package private) abstract int |
waitAllOutputStreamsByOtherThreads(long timeout)
|
(package private) ReentrantLock |
writeLock()
|
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
| Field Detail |
|---|
private final WeakReference weakThis
setScheduled(boolean).
private final File target
private final ArchiveController enclController
private final String enclEntryName
private ArchiveDriver driver
ArchiveDriver to use for this controller's target file.
private final ReentrantLock readLock
private final ReentrantLock writeLock
| Constructor Detail |
|---|
ArchiveController(File target,
ArchiveController enclController,
String enclEntryName,
ArchiveDriver driver)
File objects are referring to it.
The subclass must update this schedule according to the controller's
state.
For example, if the controller has started to update some entry data,
it must call setScheduled(boolean) in order to force the
controller to be updated on the next call to umount(de.schlichtherle.io.ArchiveException, boolean, boolean, boolean, boolean, boolean, boolean) even if
no more File objects are referring to it.
Otherwise, all changes may get lost!
setScheduled(boolean)| Method Detail |
|---|
final ReentrantLock readLock()
final ReentrantLock writeLock()
final void runWriteLocked(IORunnable runnable)
throws IOException
IORunnable while this controller has
acquired its write lock regardless of the state of its read lock.
You must use this method if this controller may have acquired a
read lock in order to prevent a dead lock.
Warning: This method temporarily releases the read lock before the write lock is acquired and the runnable is run! Hence, the runnable should recheck the state of the controller before it proceeds with any write operations.
runnable - The IORunnable to run while the write
lock is acquired.
No read lock is acquired while it's running.
IOExceptionfinal File getTarget()
java.io.File object for the archive file to control.
public final String getPath()
ArchiveFile.separators.
This property may be used to determine some archive file specific parameters, such as passwords or similar. However, implementations must not assume that the file denoted by the path actually exists as a file in the native file system!
getPath in interface ArchiveString object
- never null.Archive.getEnclArchive()public final Archive getEnclArchive()
getEnclArchive in interface Archivenull if this archive is
not enclosed in another archivestatic final boolean isRoot(String entryName)
true iff the given entry name refers to the
virtual root directory within this controller.
final ArchiveController getEnclController()
ArchiveController of the enclosing archive file,
if any.
final String getEnclEntryName()
final String enclEntryName(String entryName)
private final boolean isEnclosedBy(ArchiveController wannabe)
final ArchiveDriver getDriver()
ArchiveDriver object
- never null.final void setDriver(ArchiveDriver driver)
driver - A valid reference to an ArchiveDriver object
- never null.final boolean isRfsEntryTarget()
true if and only if the target file of this
controller should be considered to be a file or directory in the real
file system (RFS).
Note that the target doesn't need to exist for this method to return
true.
abstract boolean isTouched()
true if and only if the file system has been
touched.
final void setScheduled(boolean scheduled)
ArchiveControllers.umount(String, boolean, boolean, boolean, boolean, boolean).
scheduled - If set to true, this controller and hence
its target archive file is guaranteed to get updated during the
next call to ArchiveControllers.umount() even if
there are no more File instances referring to it
meanwhile.
Call this method with this parameter value whenever the virtual
file system has been touched, i.e. modified.
If set to false, this controller is conditionally
scheduled to get updated.
In this case, the controller gets automatically removed from
the controllers weak hash map and discarded once the last file
object directly or indirectly referring to it has been discarded
unless setScheduled(true) has been called meanwhile.
Call this method if the archive controller has been newly created
or successfully updated.
abstract boolean hasNewData(String entryName)
umount(de.schlichtherle.io.ArchiveException, boolean, boolean, boolean, boolean, boolean, boolean).
Note that for directories this method will always return
false!
abstract ArchiveFileSystem autoMount(boolean create)
throws IOException
Warning: Either the read or the write lock of this controller must be acquired while this method is called! If only a read lock is acquired, but a write lock is required, this method will temporarily release all locks, so any preconditions must be checked again upon return to protect against concurrent modifications!
create - If the archive file does not exist and this is
true, a new file system with only a virtual root
directory is created with its last modification time set to the
system's current time.
null is never returned.
ArchiveController.FalsePositiveException
IOException - On any other I/O related issue with the target file
or the target file of any enclosing archive file's controller.
final void autoUmount(String entryName)
throws ArchiveException
entryName.
Warning: As a side effect, all data structures returned by this controller get reset (filesystem, entries, streams, etc.)! As an implication, this method requires external synchronization on this controller's write lock!
TODO: Consider adding configuration switch to allow overwriting an archive entry to the same output archive multiple times, whereby only the last written entry would be added to the central directory of the archive (unless the archive type doesn't support this).
ArchiveExceptionumount(ArchiveException, boolean, boolean, boolean, boolean, boolean, boolean),
ArchiveException
abstract void umount(ArchiveException exceptionChain,
boolean waitInputStreams,
boolean closeInputStreams,
boolean waitOutputStreams,
boolean closeOutputStreams,
boolean umount,
boolean reassemble)
throws ArchiveException
Warning: As a side effect, all data structures returned by this controller get reset (filesystem, entries, streams, etc.)! As an implication, this method requires external synchronization on this controller's write lock!
waitInputStreams - See ArchiveControllers.umount(java.lang.String, boolean, boolean, boolean, boolean, boolean).closeInputStreams - See ArchiveControllers.umount(java.lang.String, boolean, boolean, boolean, boolean, boolean).waitOutputStreams - See ArchiveControllers.umount(java.lang.String, boolean, boolean, boolean, boolean, boolean).closeOutputStreams - See ArchiveControllers.umount(java.lang.String, boolean, boolean, boolean, boolean, boolean).umount - See ArchiveControllers.umount(java.lang.String, boolean, boolean, boolean, boolean, boolean).reassemble - Let's assume this archive file is enclosed
in another archive file.
Then if this parameter is true, the updated archive
file is also written to its enclosing archive file.
Note that this parameter must be set if umount
is set as well. Failing to comply to this requirement may throw
a AssertionError and will incur loss of data!
ArchiveException - If any exception condition occurs throughout
the course of this method, an ArchiveException
is created, prepended to exceptionChain and finally
thrown.autoUmount(java.lang.String),
ArchiveExceptionabstract int waitAllInputStreamsByOtherThreads(long timeout)
abstract int waitAllOutputStreamsByOtherThreads(long timeout)
abstract void reset()
throws IOException
This method should be overridden by subclasses, but must still be called when doing so.
IOExceptionpublic String toString()
toString in class Object
final InputStream createInputStream(String entryName)
throws FileNotFoundException
entryName - An entry in the virtual archive file system
- null or "" is not permitted.
InputStream object
- null is never returned.
FileNotFoundException - If the entry cannot get read for
any reason.
InputStream createInputStream0(String entryName)
throws IOException
IOException
abstract InputStream createInputStream(ArchiveEntry entry,
ArchiveEntry dstEntry)
throws IOException
entry must not have received
new data.
IOException
final OutputStream createOutputStream(String entryName,
boolean append)
throws FileNotFoundException
OutputStream allowing to
(re)write the given entry in the target archive file.
entryName - An entry in the virtual archive file system
- null or "" is not permitted.
OutputStream object
- null is never returned.
FileNotFoundException - If the entry cannot get (re)written for
any reason.
OutputStream createOutputStream0(String entryName,
boolean append)
throws IOException
IOException
abstract OutputStream createOutputStream(ArchiveEntry entry,
ArchiveEntry srcEntry)
throws IOException
entry must not have received
new data.
IOException
final boolean exists(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final boolean exists0(String entryName)
throws IOException
IOException
final boolean isFile(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final boolean isFile0(String entryName)
throws IOException
IOException
final boolean isDirectory(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final boolean isDirectory0(String entryName)
throws IOException
IOException
final Icon getOpenIcon(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final Icon getOpenIcon0(String entryName)
throws IOException
IOException
final Icon getClosedIcon(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final Icon getClosedIcon0(String entryName)
throws IOException
IOException
final boolean canRead(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final boolean canRead0(String entryName)
throws IOException
IOException
final boolean canWrite(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final boolean canWrite0(String entryName)
throws IOException
IOException
final long length(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final long length0(String entryName)
throws IOException
IOException
final long lastModified(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final long lastModified0(String entryName)
throws IOException
IOException
final String[] list(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final String[] list0(String entryName)
throws IOException
IOException
final String[] list(String entryName,
FilenameFilter filenameFilter,
File dir)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final String[] list0(String entryName,
FilenameFilter filenameFilter,
File dir)
throws IOException
IOException
final File[] listFiles(String entryName,
FilenameFilter filenameFilter,
File dir,
FileFactory factory)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final File[] listFiles0(String entryName,
FilenameFilter filenameFilter,
File dir,
FileFactory factory)
throws IOException
IOException
final File[] listFiles(String entryName,
FileFilter fileFilter,
File dir,
FileFactory factory)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final File[] listFiles0(String entryName,
FileFilter fileFilter,
File dir,
FileFactory factory)
throws IOException
IOException
final boolean setReadOnly(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final boolean setReadOnly0(String entryName)
throws IOException
IOException
final boolean setLastModified(String entryName,
long time)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final boolean setLastModified0(String entryName,
long time)
throws IOException
IOException
final boolean createNewFile(String entryName,
boolean autoCreate)
throws IOException
IOException
private final boolean createNewFile0(String entryName,
boolean autoCreate)
throws IOException
IOException
final boolean mkdir(String entryName,
boolean autoCreate)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final void mkdir0(String entryName,
boolean autoCreate)
throws IOException
IOException
final boolean delete(String entryName)
throws ArchiveController.RfsEntryFalsePositiveException
ArchiveController.RfsEntryFalsePositiveException
private final void delete0(String entryName)
throws IOException
IOException
|
TrueZIP 6.8.2 | ||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||