6 Replies Latest reply on Jun 30, 2010 2:49 PM by Andrew Rubinger

    ArchiveAsset and Exporters

    Andrew Rubinger Master



      We never really got it right with ArchiveAsset.


      The Asset contract states that anything may be added to an archive, so long as it may be represented as a stream of bytes (ie. InputStream).  Archives simply cannot fulfill this contract; they may be a stream of bytes in any number of export formats: ZIP, TAR, TAR.GZ, TAR.BZ2.  Or they may be exploded into a directory structure, which is not a stream at all.  In the exploded case, this is more closely covered by archive.merge(), where the contents of an archive can be placed into another.


      Asset.openStream is used in the following cases:


      1. Exporting an archive
      2. GlassFish Extension (ShrinkwrapReadableArchiveImpl)
      3. VFS3 Extension


      Technically archives should be able to hold *any* object-based content.  It's only when the content is read that we need some mechanism to convert this to a stream.


      So we've discussed a bit in #jbosstesting the idea of adding any "Storable" type, and at the time it's read out again let the user supply some converter/exporter for each path.  The more I think on this, though technically workable, it sounds complex/involved/not worth it.  User code would be able to add anything, but have to supply some converter to read it out or export.  However this is more versatile; the user could add any content and export it in any number of different combinations.


      The path I think we should take is this:


      Explicitly define the exporter used for a nested archive when adding it to another archive.  It's contents would be exported on add, and changes to the nested archive would no longer be reflected in the parent.


      It's the least flexible solution, but IMO the most deterministic and simplest from an API perspective.  Honestly I think the main use cases say that the developer will know the target export type of the nested archive when it's added, so it's no problem for them to specify it at that time, and do the export of the nested archive as part of the addition operation:



          * Add an archive under a specific context and maintain the archive name as 
          * context path.
          * @param path to use 
          * @param archive to add
          * @param exporter Exporter type to use in fulfilling the {@link Asset#openStream()} contract for 
          *   the added (nested) archive.  
          * @return
          * @throws IllegalArgumentException If any argument is not specified
         T add(Archive<?> archive, ArchivePath path, Class<? extends StreamExporter> exporter) throws IllegalArgumentException;