Class ArchiveURLConnection

java.lang.Object
java.net.URLConnection
org.eclipse.emf.common.archive.ArchiveURLConnection

public class ArchiveURLConnection extends URLConnection
A connection that can access an entry in an archive, and then recursively an entry in that archive, and so on. For example, it can be used just like jar: or zip:, only the archive paths can repeat, e.g.,
  archive:file:///c:/temp/example.zip!/org/example/nested.zip!/org/example/deeply-nested.html
The general recursive pattern is
  archive:$nestedURL${/!$archivePath$}+
So the nested URL for the example above is
  file:///c:/temp/example.zip

Since the nested URL may itself contain archive schemes, the subsequence of the archive paths that should be associated with the nested URL is determined by finding the nth archive separator, i.e., the nth !/, where n is the number of ":"s before the first "/" of the nested URL, i.e., the number of nested schemes. For example, for a more complex case where the nested URL is itself an archive-based scheme, e.g.,

  archive:jar:file:///c:/temp/example.zip!/org/example/nested.zip!/org/example/deeply-nested.html
the nested URL is correctly parsed to skip to the second archive separator as
  jar:file:///c:/temp/example.zip!/org/example/nested.zip

The logic for accessing archives can be tailored and reused independant from its usage as a URL connection. This is normally done by using the constructor ArchiveURLConnection(String) and overriding createInputStream(String) and createOutputStream(String). The behavior can be tailored by overriding emulateArchiveScheme() and useZipFile().

  • Field Details

    • urlString

      protected String urlString
      The cached string version of the URL.
  • Constructor Details

    • ArchiveURLConnection

      public ArchiveURLConnection(URL url)
      Constructs a new connection for the URL.
      Parameters:
      url - the URL of this connection.
    • ArchiveURLConnection

      protected ArchiveURLConnection(String url)
      Constructs a new archive accessor. This constructor forwards a null URL to be super constructor, so an instance built with this constructor cannot be used as a URLConnection. The logic for accessing archives and for delegating to the nested URL can be reused in other applications, without creating an URLs.
      Parameters:
      url - the URL of the archive.
  • Method Details

    • emulateArchiveScheme

      protected boolean emulateArchiveScheme()

      Returns whether the implementation will handle all the archive accessors directly. For example, whether
        archive:jar:file:///c:/temp/example.zip!/org/example/nested.zip!/org/example/deeply-nested.html
      
      will be handled as if it were specified as
        archive:file:///c:/temp/example.zip!/org/example/nested.zip!/org/example/deeply-nested.html
      
      Override this only if you are reusing the logic of retrieving an input stream into an archive and hence are likely to be overriding createInputStream, which is the point of delegation to the nested URL for recursive stream creation.

      Returns:
      whether the implementation will handle all the archive accessors directly.
    • useZipFile

      protected boolean useZipFile()
      Returns whether to handle the special case of a nested URL with file: schema using a ZipFile. This gives more efficient direct access to the root entry, e.g.,
        archive:file:///c:/temp/example.zip!/org/example/nested.html
      
      Returns:
      whether to handle the special case of a nested URL with file: schema using a ZipFile.
    • connect

      public void connect() throws IOException
      Record that this is connected.
      Specified by:
      connect in class URLConnection
      Throws:
      IOException
    • getNestedURL

      protected String getNestedURL() throws IOException
      Throws:
      IOException
    • getInputStream

      public InputStream getInputStream() throws IOException
      Creates the input stream for the URL.
      Overrides:
      getInputStream in class URLConnection
      Returns:
      the input stream for the URL.
      Throws:
      IOException
    • yield

      protected InputStream yield(ZipEntry zipEntry, InputStream inputStream) throws IOException
      Throws:
      IOException
    • createInputStream

      protected InputStream createInputStream(String nestedURL) throws IOException
      Creates an input stream for the nested URL by calling opening a stream on it.
      Parameters:
      nestedURL - the nested URL for which a stream is required.
      Returns:
      the open stream of the nested URL.
      Throws:
      IOException
    • getOutputStream

      public OutputStream getOutputStream() throws IOException
      Creates the output stream for the URL.
      Overrides:
      getOutputStream in class URLConnection
      Returns:
      the output stream for the URL.
      Throws:
      IOException
    • delete

      public void delete() throws IOException
      Throws:
      IOException
    • setTimeStamp

      public void setTimeStamp(long timeStamp) throws IOException
      Throws:
      IOException
    • yield

      protected OutputStream yield(ZipEntry zipEntry, OutputStream outputStream) throws IOException
      Throws:
      IOException
    • createOutputStream

      protected OutputStream createOutputStream(String nestedURL) throws IOException
      Creates an output stream for the nested URL by calling opening a stream on it.
      Parameters:
      nestedURL - the nested URL for which a stream is required.
      Returns:
      the open stream of the nested URL.
      Throws:
      IOException