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 interfaceFileArchive.StaleFileManagerAPI which FileArchive methods should use for dealing with the StaleFileManager implementation.
-
Field Summary
Fields Modifier and Type Field Description static LoggerdeplLogger-
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 voidclearCache()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 memoryvoidclose()close the abstract archivevoidcloseEntry()Closes the current entryvoidcloseEntry(WritableArchive subArchive)Close a previously returned sub archivevoidcreate(URI uri)creates a new abstract archive with the given pathWritableArchivecreateSubArchive(String name)create or obtain an embedded archive within this abstraction.booleandelete()delete the archivebooleandeleteEntry(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)booleanexists()booleanexists(String name)Returns the existence of the given entry name The file name must be relative to the root of the module.longgetArchiveSize()Get the size of the archiveCollection<String>getDirectories()Returns the enumeration of first level directories in this archiveInputStreamgetEntry(String name)Returns the InputStream for the given entry name The file name must be relative to the root of the module.longgetEntrySize(String name)Returns the entry size for a given entry name or 0 if not knownManifestgetManifest()Returns the manifest information for this archiveStringgetName()Returns the name portion of the archive's URI.ReadableArchivegetSubArchive(String name)create or obtain an embedded archive within this abstraction.URIgetURI()Returns the URI used to create or open the underlyong archivebooleanisDirectory(String name)Returns true if the entry is a directory or a plain filevoidopen(String uri)voidopen(URI uri)Open an abstract archiveOutputStreamputNextEntry(String name)Create a new entry in the archivebooleanrenameTo(String name)rename the archivebooleansupportsElementsOverwriting()-
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:
openin 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, SecurityExceptionGet the size of the archive- Specified by:
getArchiveSizein interfaceArchive- Returns:
- tje the size of this archive or -1 on error
- Throws:
NullPointerExceptionSecurityException
-
create
public void create(URI uri) throws IOException
creates a new abstract archive with the given path- Specified by:
createin 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:
closeEntryin interfaceWritableArchive- Parameters:
subArchive- output stream to close- Throws:
IOException
-
close
public void close() throws IOExceptionclose the abstract archive- Specified by:
closein interfaceArchive- Throws:
IOException
-
delete
public boolean delete()
delete the archive- Specified by:
deletein interfaceReadableArchive
-
isDirectory
public boolean isDirectory(String name)
Description copied from interface:ArchiveReturns true if the entry is a directory or a plain file- Specified by:
isDirectoryin 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:ArchiveReturns 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:
getDirectoriesin 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:
existsin 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:
getSubArchivein 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:
createSubArchivein 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:
existsin 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:ReadableArchiveReturns the InputStream for the given entry name The file name must be relative to the root of the module.- Specified by:
getEntryin 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:
getEntrySizein interfaceReadableArchive- Parameters:
name- the entry name- Returns:
- the entry size
-
getManifest
public Manifest getManifest() throws IOException
Description copied from interface:ArchiveReturns the manifest information for this archive- Specified by:
getManifestin 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:
renameToin 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 IOExceptionCloses the current entry- Specified by:
closeEntryin interfaceWritableArchive- Throws:
IOException
-
putNextEntry
public OutputStream putNextEntry(String name) throws IOException
Description copied from interface:WritableArchiveCreate a new entry in the archive- Specified by:
putNextEntryin 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
-
-