Class FileArchive

  • All Implemented Interfaces:
    org.glassfish.api.deployment.archive.Archive, org.glassfish.api.deployment.archive.ReadableArchive, org.glassfish.api.deployment.archive.WritableArchive

    @Service(name="file")
    @PerLookup
    public class FileArchive
    extends AbstractReadableArchive
    implements org.glassfish.api.deployment.archive.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
    • Field Detail

      • deplLogger

        public static final Logger deplLogger
    • Constructor Detail

      • FileArchive

        public FileArchive()
    • Method Detail

      • open

        public void open​(URI uri)
                  throws IOException
        Open an abstract archive
        Specified by:
        open in interface org.glassfish.api.deployment.archive.ReadableArchive
        Parameters:
        uri - path to the archive
        Throws:
        IOException
      • create

        public void create​(URI uri)
                    throws IOException
        creates a new abstract archive with the given path
        Specified by:
        create in interface org.glassfish.api.deployment.archive.WritableArchive
        Parameters:
        uri - path to create the archive
        Throws:
        IOException
      • closeEntry

        public void closeEntry​(org.glassfish.api.deployment.archive.WritableArchive subArchive)
                        throws IOException
        Close a previously returned sub archive
        Specified by:
        closeEntry in interface org.glassfish.api.deployment.archive.WritableArchive
        Parameters:
        subArchive - output stream to close
        Throws:
        IOException
      • close

        public void close()
                   throws IOException
        close the abstract archive
        Specified by:
        close in interface org.glassfish.api.deployment.archive.Archive
        Throws:
        IOException
      • delete

        public boolean delete()
        delete the archive
        Specified by:
        delete in interface org.glassfish.api.deployment.archive.ReadableArchive
      • isDirectory

        public boolean isDirectory​(String name)
        Specified by:
        isDirectory in interface org.glassfish.api.deployment.archive.Archive
      • entries

        public Enumeration entries()
        Specified by:
        entries in interface org.glassfish.api.deployment.archive.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 org.glassfish.api.deployment.archive.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 org.glassfish.api.deployment.archive.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 org.glassfish.api.deployment.archive.ReadableArchive
        Returns:
        true if this archive exists
      • getSubArchive

        public org.glassfish.api.deployment.archive.ReadableArchive getSubArchive​(String name)
                                                                           throws IOException
        create or obtain an embedded archive within this abstraction.
        Specified by:
        getSubArchive in interface org.glassfish.api.deployment.archive.ReadableArchive
        Parameters:
        name - name of the embedded archive.
        Throws:
        IOException
      • createSubArchive

        public org.glassfish.api.deployment.archive.WritableArchive createSubArchive​(String name)
                                                                              throws IOException
        create or obtain an embedded archive within this abstraction.
        Specified by:
        createSubArchive in interface org.glassfish.api.deployment.archive.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 org.glassfish.api.deployment.archive.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 org.glassfish.api.deployment.archive.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 org.glassfish.api.deployment.archive.ReadableArchive
        Parameters:
        name - the entry name
        Returns:
        the entry size
      • getManifest

        public Manifest getManifest()
                             throws IOException
        Specified by:
        getManifest in interface org.glassfish.api.deployment.archive.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 org.glassfish.api.deployment.archive.Archive
        Returns:
        the URI for this archive.
      • renameTo

        public boolean renameTo​(String name)
        rename the archive
        Specified by:
        renameTo in interface org.glassfish.api.deployment.archive.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 org.glassfish.api.deployment.archive.WritableArchive
        Throws:
        IOException
      • putNextEntry

        public OutputStream putNextEntry​(String name)
                                  throws IOException
        Specified by:
        putNextEntry in interface org.glassfish.api.deployment.archive.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:

        • /a/b/c/d/ -> d
        • /a/b/c/d -> d
        • /a/b/c.jar -> c.jar
        Specified by:
        getName in interface org.glassfish.api.deployment.archive.Archive
        Returns:
        the name of the archive