Class FileArchive
- java.lang.Object
-
- com.sun.enterprise.deploy.shared.AbstractReadableArchive
-
- com.sun.enterprise.deploy.shared.FileArchive
-
- All Implemented Interfaces:
Archive
,ReadableArchive
,WritableArchive
@Service(name="file") @PerLookup public class FileArchive extends AbstractReadableArchive implements WritableArchive
This implementation of the Archive interface maps to a directory/file structure.If the directory underlying the FileArchive is created by GlassFish then FileArchive filters its contents so only those files more recent than the creation of the archive itself are visible to consumers.
The main motivation is to hide unwanted "left-over" files from previous deployments that might linger, especially on Windows, after the previous app had been undeployed. (Deployment uses a FileArchive to extract the user's JAR-based archive into the applications directory.) Historically such left-over files arise after GlassFish expands an archive into its exploded form but then some code opens but does not close a file in that exploded directory tree.
An open left-over file can be overwritten-in-place on Windows, and this happens when a caller invokes
putNextEntry(java.lang.String)
to create a new entry (file) inside the archive. But a left-over file that is not in the new app but is still open by GlassFish cannot be deleted or renamed on Windows and so it will remain in the expansion directory. Such left-over files, if not filtered out, can confuse GlassFish and the application. By "stamping" the archive creation date we can filter out such old, left-over files.To support this feature, when FileArchive creates a directory it stores a marker file there, the contents of which records the creation date/time of the archive. We cannot just use the lastModified value for the top-level directory. Users might legitimately use "touch .reload" in the applications/appName directory to trigger a dynamic reload of the app. If .reload does not already exist then touch creates it, and this would update the lastModified of the directory file.
- Author:
- Jerome Dochez, Tim Quinn
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
FileArchive.StaleFileManager
API which FileArchive methods should use for dealing with the StaleFileManager implementation.
-
Field Summary
Fields Modifier and Type Field Description static Logger
deplLogger
-
Fields inherited from class com.sun.enterprise.deploy.shared.AbstractReadableArchive
archiveMetaData, extraData, parentArchive
-
-
Constructor Summary
Constructors Constructor Description FileArchive()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static void
clearCache()
Empty the cache of file entries This should be called at the end of deployment to ensure that it isn't retained if an application is redeployed and to clear up the memoryvoid
close()
close the abstract archivevoid
closeEntry()
Closes the current entryvoid
closeEntry(WritableArchive subArchive)
Close a previously returned sub archivevoid
create(URI uri)
creates a new abstract archive with the given pathWritableArchive
createSubArchive(String name)
create or obtain an embedded archive within this abstraction.boolean
delete()
delete the archiveboolean
deleteEntry(String name)
delete an entry in the archiveEnumeration<String>
entries()
Returns an enumeration of the module file entries.Enumeration<String>
entries(String prefix)
Returns an enumeration of the module file entries with the specified prefix.Enumeration<String>
entries(Enumeration embeddedArchives)
boolean
exists()
boolean
exists(String name)
Returns the existence of the given entry name The file name must be relative to the root of the module.long
getArchiveSize()
Get the size of the archiveCollection<String>
getDirectories()
Returns the enumeration of first level directories in this archiveInputStream
getEntry(String name)
Returns the InputStream for the given entry name The file name must be relative to the root of the module.long
getEntrySize(String name)
Returns the entry size for a given entry name or 0 if not knownManifest
getManifest()
Returns the manifest information for this archiveString
getName()
Returns the name portion of the archive's URI.ReadableArchive
getSubArchive(String name)
create or obtain an embedded archive within this abstraction.URI
getURI()
Returns the URI used to create or open the underlyong archiveboolean
isDirectory(String name)
Returns true if the entry is a directory or a plain filevoid
open(String uri)
void
open(URI uri)
Open an abstract archiveOutputStream
putNextEntry(String name)
Create a new entry in the archiveboolean
renameTo(String name)
rename the archiveboolean
supportsElementsOverwriting()
-
Methods inherited from class com.sun.enterprise.deploy.shared.AbstractReadableArchive
addArchiveMetaData, getArchiveMetaData, getExtraData, getParentArchive, removeArchiveMetaData, removeExtraData, setExtraData, setParentArchive
-
-
-
-
Field Detail
-
deplLogger
public static final Logger deplLogger
-
-
Method Detail
-
open
public void open(URI uri) throws IOException
Open an abstract archive- Specified by:
open
in interfaceReadableArchive
- Parameters:
uri
- path to the archive- Throws:
IOException
-
open
public void open(String uri) throws IOException
- Parameters:
uri
- a string representing URI- Throws:
IOException
- See Also:
open(URI)
-
getArchiveSize
public long getArchiveSize() throws NullPointerException, SecurityException
Get the size of the archive- Specified by:
getArchiveSize
in interfaceArchive
- Returns:
- tje the size of this archive or -1 on error
- Throws:
NullPointerException
SecurityException
-
create
public void create(URI uri) throws IOException
creates a new abstract archive with the given path- Specified by:
create
in interfaceWritableArchive
- Parameters:
uri
- path to create the archive- Throws:
IOException
-
closeEntry
public void closeEntry(WritableArchive subArchive) throws IOException
Close a previously returned sub archive- Specified by:
closeEntry
in interfaceWritableArchive
- Parameters:
subArchive
- output stream to close- Throws:
IOException
-
close
public void close() throws IOException
close the abstract archive- Specified by:
close
in interfaceArchive
- Throws:
IOException
-
delete
public boolean delete()
delete the archive- Specified by:
delete
in interfaceReadableArchive
-
isDirectory
public boolean isDirectory(String name)
Description copied from interface:Archive
Returns true if the entry is a directory or a plain file- Specified by:
isDirectory
in interfaceArchive
- Parameters:
name
- name is one of the entries returned byArchive.entries()
- Returns:
- true if the entry denoted by the passed name is a directory
-
entries
public Enumeration<String> entries()
Description copied from interface:Archive
Returns an enumeration of the module file entries. All elements in the enumeration are of type String. Each String represents a file name relative to the root of the module.
-
getDirectories
public Collection<String> getDirectories() throws IOException
Returns the enumeration of first level directories in this archive- Specified by:
getDirectories
in interfaceArchive
- Returns:
- enumeration of directories under the root of this archive
- Throws:
IOException
-
entries
public Enumeration<String> entries(Enumeration embeddedArchives)
- Returns:
- an @see java.util.Enumeration of entries in this abstract archive, providing the list of embedded archive to not count their entries as part of this archive
-
entries
public Enumeration<String> entries(String prefix)
Returns an enumeration of the module file entries with the specified prefix. All elements in the enumeration are of type String. Each String represents a file name relative to the root of the module.
-
exists
public boolean exists()
- Specified by:
exists
in interfaceReadableArchive
- Returns:
- true if this archive exists
-
getSubArchive
public ReadableArchive getSubArchive(String name) throws IOException
create or obtain an embedded archive within this abstraction.- Specified by:
getSubArchive
in interfaceReadableArchive
- Parameters:
name
- name of the embedded archive.- Returns:
- the Archive instance for this abstraction, or null if no such entry exists.
- Throws:
IOException
-
createSubArchive
public WritableArchive createSubArchive(String name) throws IOException
create or obtain an embedded archive within this abstraction.- Specified by:
createSubArchive
in interfaceWritableArchive
- Parameters:
name
- name of the embedded archive.- Returns:
- the Archive instance for this abstraction
- Throws:
IOException
-
exists
public boolean exists(String name) throws IOException
Returns the existence of the given entry name The file name must be relative to the root of the module.- Specified by:
exists
in interfaceReadableArchive
- Parameters:
name
- the file name relative to the root of the module.- Returns:
- the existence the given entry name.
- Throws:
IOException
-
getEntry
public InputStream getEntry(String name) throws IOException
Description copied from interface:ReadableArchive
Returns the InputStream for the given entry name The file name must be relative to the root of the module.- Specified by:
getEntry
in interfaceReadableArchive
- Parameters:
name
- the entry name- Returns:
- a @see java.io.InputStream for an existing entry in the current abstract archive
- Throws:
IOException
-
getEntrySize
public long getEntrySize(String name)
Returns the entry size for a given entry name or 0 if not known- Specified by:
getEntrySize
in interfaceReadableArchive
- Parameters:
name
- the entry name- Returns:
- the entry size
-
getManifest
public Manifest getManifest() throws IOException
Description copied from interface:Archive
Returns the manifest information for this archive- Specified by:
getManifest
in interfaceArchive
- Returns:
- the manifest information for this abstract archive
- Throws:
IOException
-
getURI
public URI getURI()
Returns the URI used to create or open the underlyong archive
-
renameTo
public boolean renameTo(String name)
rename the archive- Specified by:
renameTo
in interfaceReadableArchive
- Parameters:
name
- the archive name
-
supportsElementsOverwriting
public boolean supportsElementsOverwriting()
- Returns:
- true if this archive abstraction supports overwriting of elements
-
deleteEntry
public boolean deleteEntry(String name)
delete an entry in the archive- Parameters:
name
- the entry name- Returns:
- true if the entry was successfully deleted
-
closeEntry
public void closeEntry() throws IOException
Closes the current entry- Specified by:
closeEntry
in interfaceWritableArchive
- Throws:
IOException
-
putNextEntry
public OutputStream putNextEntry(String name) throws IOException
Description copied from interface:WritableArchive
Create a new entry in the archive- Specified by:
putNextEntry
in interfaceWritableArchive
- Parameters:
name
- the entry name- Throws:
IOException
-
getName
public String getName()
Returns the name portion of the archive's URI.For FileArhive the name is all of the path that follows the last slash (ignoring a slash at the end of the path).
Here are some example archive names for the specified FileArchive paths:
- /a/b/c/d/ -> d
- /a/b/c/d -> d
- /a/b/c.jar -> c.jar
-
clearCache
public static void clearCache()
Empty the cache of file entries This should be called at the end of deployment to ensure that it isn't retained if an application is redeployed and to clear up the memory
-
-