com.sun.enterprise.deploy.shared
Class FileArchive

java.lang.Object
  extended by com.sun.enterprise.deploy.shared.AbstractReadableArchive
      extended by com.sun.enterprise.deploy.shared.FileArchive
All Implemented Interfaces:
Archive, ReadableArchive, WritableArchive

@Service(name="file")
@Scoped(value=org.jvnet.hk2.component.PerLookup.class)
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
static interface FileArchive.StaleFileManager
          API which FileArchive methods should use for dealing with the StaleFileManager implementation.
 
Field Summary
 
Fields inherited from class com.sun.enterprise.deploy.shared.AbstractReadableArchive
extraData, parentArchive
 
Constructor Summary
FileArchive()
           
 
Method Summary
 void close()
          close the abstract archive
 void closeEntry()
          Closes the current entry
 void closeEntry(WritableArchive subArchive)
          Close a previously returned sub archive
 void create(URI uri)
          creates a new abstract archive with the given path
 WritableArchive createSubArchive(String name)
          create or obtain an embedded archive within this abstraction.
 boolean delete()
          delete the archive
 boolean deleteEntry(String name)
          delete an entry in the archive
 Enumeration entries()
           
 Enumeration entries(Enumeration embeddedArchives)
           
 Enumeration<String> entries(String prefix)
          Returns an enumeration of the module file entries with the specified prefix.
 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 archive
 Collection<String> getDirectories()
          Returns the enumeration of first level directories in this archive
 InputStream getEntry(String name)
           
 long getEntrySize(String name)
          Returns the entry size for a given entry name or 0 if not known
 Manifest getManifest()
           
 String 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 archive
 boolean isDirectory(String name)
           
 void open(String uri)
           
 void open(URI uri)
          Open an abstract archive
 OutputStream putNextEntry(String name)
           
 boolean renameTo(String name)
          rename the archive
 boolean supportsElementsOverwriting()
           
 
Methods inherited from class com.sun.enterprise.deploy.shared.AbstractReadableArchive
getExtraData, getParentArchive, removeExtraData, setExtraData, setParentArchive
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

FileArchive

public FileArchive()
Method Detail

open

public void open(URI uri)
          throws IOException
Open an abstract archive

Specified by:
open in interface ReadableArchive
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 interface Archive
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 interface WritableArchive
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 interface WritableArchive
Parameters:
subArchive - output stream to close
Throws:
IOException

close

public void close()
           throws IOException
close the abstract archive

Specified by:
close in interface Archive
Throws:
IOException

delete

public boolean delete()
delete the archive

Specified by:
delete in interface ReadableArchive

isDirectory

public boolean isDirectory(String name)
Specified by:
isDirectory in interface Archive

entries

public Enumeration entries()
Specified by:
entries in interface Archive
Returns:
an @see java.util.Enumeration of entries in this abstract archive

getDirectories

public Collection<String> getDirectories()
                                  throws IOException
Returns the enumeration of first level directories in this archive

Specified by:
getDirectories in interface Archive
Returns:
enumeration of directories under the root of this archive
Throws:
IOException

entries

public Enumeration 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.

Specified by:
entries in interface Archive
Parameters:
prefix - the prefix of entries to be included
Returns:
an enumeration of the archive file entries.

exists

public boolean exists()
Specified by:
exists in interface ReadableArchive
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 interface ReadableArchive
Parameters:
name - name of the embedded archive.
Throws:
IOException

createSubArchive

public WritableArchive createSubArchive(String name)
                                 throws IOException
create or obtain an embedded archive within this abstraction.

Specified by:
createSubArchive in interface WritableArchive
Parameters:
name - name of the embedded archive.
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 interface ReadableArchive
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
Specified by:
getEntry in interface ReadableArchive
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 interface ReadableArchive
Parameters:
name - the entry name
Returns:
the entry size

getManifest

public Manifest getManifest()
                     throws IOException
Specified by:
getManifest in interface Archive
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

Specified by:
getURI in interface Archive
Returns:
the URI for this archive.

renameTo

public boolean renameTo(String name)
rename the archive

Specified by:
renameTo in interface ReadableArchive
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 interface WritableArchive
Throws:
IOException

putNextEntry

public OutputStream putNextEntry(String name)
                          throws IOException
Specified by:
putNextEntry in interface WritableArchive
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:

Specified by:
getName in interface Archive
Returns:
the name of the archive


Copyright © 2012 GlassFish Community. All Rights Reserved.