Home » openjdk-7 » java » util » jar » [javadoc | source]

    1   /*
    2    * Copyright (c) 2003,2010, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   package java.util.jar;
   26   
   27   import java.util.SortedMap;
   28   import java.io.InputStream;
   29   import java.io.OutputStream;
   30   import java.io.File;
   31   import java.io.IOException;
   32   import java.beans.PropertyChangeListener;
   33   
   34   
   35   
   36   
   37   /**
   38    * Transforms a JAR file to or from a packed stream in Pack200 format.
   39    * Please refer to Network Transfer Format JSR 200 Specification at
   40    * <a href=http://jcp.org/aboutJava/communityprocess/review/jsr200/index.html>http://jcp.org/aboutJava/communityprocess/review/jsr200/index.html</a>
   41    * <p>
   42    * Typically the packer engine is used by application developers
   43    * to deploy or host JAR files on a website.
   44    * The unpacker  engine is used by deployment applications to
   45    * transform the byte-stream back to JAR format.
   46    * <p>
   47    * Here is an example using  packer and unpacker:<p>
   48    * <blockquote><pre>
   49    *    import java.util.jar.Pack200;
   50    *    import java.util.jar.Pack200.*;
   51    *    ...
   52    *    // Create the Packer object
   53    *    Packer packer = Pack200.newPacker();
   54    *
   55    *    // Initialize the state by setting the desired properties
   56    *    Map p = packer.properties();
   57    *    // take more time choosing codings for better compression
   58    *    p.put(Packer.EFFORT, "7");  // default is "5"
   59    *    // use largest-possible archive segments (>10% better compression).
   60    *    p.put(Packer.SEGMENT_LIMIT, "-1");
   61    *    // reorder files for better compression.
   62    *    p.put(Packer.KEEP_FILE_ORDER, Packer.FALSE);
   63    *    // smear modification times to a single value.
   64    *    p.put(Packer.MODIFICATION_TIME, Packer.LATEST);
   65    *    // ignore all JAR deflation requests,
   66    *    // transmitting a single request to use "store" mode.
   67    *    p.put(Packer.DEFLATE_HINT, Packer.FALSE);
   68    *    // discard debug attributes
   69    *    p.put(Packer.CODE_ATTRIBUTE_PFX+"LineNumberTable", Packer.STRIP);
   70    *    // throw an error if an attribute is unrecognized
   71    *    p.put(Packer.UNKNOWN_ATTRIBUTE, Packer.ERROR);
   72    *    // pass one class file uncompressed:
   73    *    p.put(Packer.PASS_FILE_PFX+0, "mutants/Rogue.class");
   74    *    try {
   75    *        JarFile jarFile = new JarFile("/tmp/testref.jar");
   76    *        FileOutputStream fos = new FileOutputStream("/tmp/test.pack");
   77    *        // Call the packer
   78    *        packer.pack(jarFile, fos);
   79    *        jarFile.close();
   80    *        fos.close();
   81    *
   82    *        File f = new File("/tmp/test.pack");
   83    *        FileOutputStream fostream = new FileOutputStream("/tmp/test.jar");
   84    *        JarOutputStream jostream = new JarOutputStream(fostream);
   85    *        Unpacker unpacker = Pack200.newUnpacker();
   86    *        // Call the unpacker
   87    *        unpacker.unpack(f, jostream);
   88    *        // Must explicitly close the output.
   89    *        jostream.close();
   90    *    } catch (IOException ioe) {
   91    *        ioe.printStackTrace();
   92    *    }
   93    * </pre></blockquote>
   94    * <p>
   95    * A Pack200 file compressed with gzip can be hosted on HTTP/1.1 web servers.
   96    * The deployment applications can use "Accept-Encoding=pack200-gzip". This
   97    * indicates to the server that the client application desires a version of
   98    * the file encoded with Pack200 and further compressed with gzip. Please
   99    * refer to  <a href="{@docRoot}/../technotes/guides/deployment/deployment-guide/pack200.html">Java Deployment Guide</a> for more details and
  100    * techniques.
  101    * <p>
  102    * Unless otherwise noted, passing a <tt>null</tt> argument to a constructor or
  103    * method in this class will cause a {@link NullPointerException} to be thrown.
  104    *
  105    * @author John Rose
  106    * @author Kumar Srinivasan
  107    * @since 1.5
  108    */
  109   public abstract class Pack200 {
  110       private Pack200() {} //prevent instantiation
  111   
  112       // Static methods of the Pack200 class.
  113       /**
  114        * Obtain new instance of a class that implements Packer.
  115        *
  116        * <li><p>If the system property <tt>java.util.jar.Pack200.Packer</tt>
  117        * is defined, then the value is taken to be the fully-qualified name
  118        * of a concrete implementation class, which must implement Packer.
  119        * This class is loaded and instantiated.  If this process fails
  120        * then an unspecified error is thrown.</p></li>
  121        *
  122        * <li><p>If an implementation has not been specified with the system
  123        * property, then the system-default implementation class is instantiated,
  124        * and the result is returned.</p></li>
  125        *
  126        * <p>Note:  The returned object is not guaranteed to operate
  127        * correctly if multiple threads use it at the same time.
  128        * A multi-threaded application should either allocate multiple
  129        * packer engines, or else serialize use of one engine with a lock.
  130        *
  131        * @return  A newly allocated Packer engine.
  132        */
  133       public synchronized static Packer newPacker() {
  134           return (Packer) newInstance(PACK_PROVIDER);
  135       }
  136   
  137   
  138       /**
  139        * Obtain new instance of a class that implements Unpacker.
  140        *
  141        * <li><p>If the system property <tt>java.util.jar.Pack200.Unpacker</tt>
  142        * is defined, then the value is taken to be the fully-qualified
  143        * name of a concrete implementation class, which must implement Unpacker.
  144        * The class is loaded and instantiated.  If this process fails
  145        * then an unspecified error is thrown.</p></li>
  146        *
  147        * <li><p>If an implementation has not been specified with the
  148        * system property, then the system-default implementation class
  149        * is instantiated, and the result is returned.</p></li>
  150        *
  151        * <p>Note:  The returned object is not guaranteed to operate
  152        * correctly if multiple threads use it at the same time.
  153        * A multi-threaded application should either allocate multiple
  154        * unpacker engines, or else serialize use of one engine with a lock.
  155        *
  156        * @return  A newly allocated Unpacker engine.
  157        */
  158   
  159       public static Unpacker newUnpacker() {
  160           return (Unpacker) newInstance(UNPACK_PROVIDER);
  161       }
  162   
  163       // Interfaces
  164       /**
  165        * The packer engine applies various transformations to the input JAR file,
  166        * making the pack stream highly compressible by a compressor such as
  167        * gzip or zip. An instance of the engine can be obtained
  168        * using {@link #newPacker}.
  169   
  170        * The high degree of compression is achieved
  171        * by using a number of techniques described in the JSR 200 specification.
  172        * Some of the techniques are sorting, re-ordering and co-location of the
  173        * constant pool.
  174        * <p>
  175        * The pack engine is initialized to an initial state as described
  176        * by their properties below.
  177        * The initial state can be manipulated by getting the
  178        * engine properties (using {@link #properties}) and storing
  179        * the modified properties on the map.
  180        * The resource files will be passed through with no changes at all.
  181        * The class files will not contain identical bytes, since the unpacker
  182        * is free to change minor class file features such as constant pool order.
  183        * However, the class files will be semantically identical,
  184        * as specified in
  185        * <cite>The Java&trade; Virtual Machine Specification</cite>.
  186        * <p>
  187        * By default, the packer does not change the order of JAR elements.
  188        * Also, the modification time and deflation hint of each
  189        * JAR element is passed unchanged.
  190        * (Any other ZIP-archive information, such as extra attributes
  191        * giving Unix file permissions, are lost.)
  192        * <p>
  193        * Note that packing and unpacking a JAR will in general alter the
  194        * bytewise contents of classfiles in the JAR.  This means that packing
  195        * and unpacking will in general invalidate any digital signatures
  196        * which rely on bytewise images of JAR elements.  In order both to sign
  197        * and to pack a JAR, you must first pack and unpack the JAR to
  198        * "normalize" it, then compute signatures on the unpacked JAR elements,
  199        * and finally repack the signed JAR.
  200        * Both packing steps should
  201        * use precisely the same options, and the segment limit may also
  202        * need to be set to "-1", to prevent accidental variation of segment
  203        * boundaries as class file sizes change slightly.
  204        * <p>
  205        * (Here's why this works:  Any reordering the packer does
  206        * of any classfile structures is idempotent, so the second packing
  207        * does not change the orderings produced by the first packing.
  208        * Also, the unpacker is guaranteed by the JSR 200 specification
  209        * to produce a specific bytewise image for any given transmission
  210        * ordering of archive elements.)
  211        * <p>
  212        * In order to maintain backward compatibility, the pack file's version is
  213        * set to accommodate the class files present in the input JAR file. In
  214        * other words, the pack file version will be the latest, if the class files
  215        * are the latest and conversely the pack file version will be the oldest
  216        * if the class file versions are also the oldest. For intermediate class
  217        * file versions the corresponding pack file version will be used.
  218        * For example:
  219        *    If the input JAR-files are solely comprised of 1.5  (or  lesser)
  220        * class files, a 1.5 compatible pack file is  produced. This will also be
  221        * the case for archives that have no class files.
  222        *    If the input JAR-files contains a 1.6 class file, then the pack file
  223        * version will be set to 1.6.
  224        * <p>
  225        * Note: Unless otherwise noted, passing a <tt>null</tt> argument to a
  226        * constructor or method in this class will cause a {@link NullPointerException}
  227        * to be thrown.
  228        * <p>
  229        * @since 1.5
  230        */
  231       public interface Packer {
  232           /**
  233            * This property is a numeral giving the estimated target size N
  234            * (in bytes) of each archive segment.
  235            * If a single input file requires more than N bytes,
  236            * it will be given its own archive segment.
  237            * <p>
  238            * As a special case, a value of -1 will produce a single large
  239            * segment with all input files, while a value of 0 will
  240            * produce one segment for each class.
  241            * Larger archive segments result in less fragmentation and
  242            * better compression, but processing them requires more memory.
  243            * <p>
  244            * The size of each segment is estimated by counting the size of each
  245            * input file to be transmitted in the segment, along with the size
  246            * of its name and other transmitted properties.
  247            * <p>
  248            * The default is -1, which means the packer will always create a single
  249            * segment output file. In cases where extremely large output files are
  250            * generated, users are strongly encouraged to use segmenting or break
  251            * up the input file into smaller JARs.
  252            * <p>
  253            * A 10Mb JAR packed without this limit will
  254            * typically pack about 10% smaller, but the packer may require
  255            * a larger Java heap (about ten times the segment limit).
  256            */
  257           String SEGMENT_LIMIT    = "pack.segment.limit";
  258   
  259           /**
  260            * If this property is set to {@link #TRUE}, the packer will transmit
  261            * all elements in their original order within the source archive.
  262            * <p>
  263            * If it is set to {@link #FALSE}, the packer may reorder elements,
  264            * and also remove JAR directory entries, which carry no useful
  265            * information for Java applications.
  266            * (Typically this enables better compression.)
  267            * <p>
  268            * The default is {@link #TRUE}, which preserves the input information,
  269            * but may cause the transmitted archive to be larger than necessary.
  270            */
  271           String KEEP_FILE_ORDER = "pack.keep.file.order";
  272   
  273   
  274           /**
  275            * If this property is set to a single decimal digit, the packer will
  276            * use the indicated amount of effort in compressing the archive.
  277            * Level 1 may produce somewhat larger size and faster compression speed,
  278            * while level 9 will take much longer but may produce better compression.
  279            * <p>
  280            * The special value 0 instructs the packer to copy through the
  281            * original JAR file directly, with no compression.  The JSR 200
  282            * standard requires any unpacker to understand this special case
  283            * as a pass-through of the entire archive.
  284            * <p>
  285            * The default is 5, investing a modest amount of time to
  286            * produce reasonable compression.
  287            */
  288           String EFFORT           = "pack.effort";
  289   
  290           /**
  291            * If this property is set to {@link #TRUE} or {@link #FALSE}, the packer
  292            * will set the deflation hint accordingly in the output archive, and
  293            * will not transmit the individual deflation hints of archive elements.
  294            * <p>
  295            * If this property is set to the special string {@link #KEEP}, the packer
  296            * will attempt to determine an independent deflation hint for each
  297            * available element of the input archive, and transmit this hint separately.
  298            * <p>
  299            * The default is {@link #KEEP}, which preserves the input information,
  300            * but may cause the transmitted archive to be larger than necessary.
  301            * <p>
  302            * It is up to the unpacker implementation
  303            * to take action upon the hint to suitably compress the elements of
  304            * the resulting unpacked jar.
  305            * <p>
  306            * The deflation hint of a ZIP or JAR element indicates
  307            * whether the element was deflated or stored directly.
  308            */
  309           String DEFLATE_HINT     = "pack.deflate.hint";
  310   
  311           /**
  312            * If this property is set to the special string {@link #LATEST},
  313            * the packer will attempt to determine the latest modification time,
  314            * among all the available entries in the original archive or the latest
  315            * modification time of all the available entries in each segment.
  316            * This single value will be transmitted as part of the segment and applied
  317            * to all the entries in each segment, {@link #SEGMENT_LIMIT}.
  318            * <p>
  319            * This can marginally decrease the transmitted size of the
  320            * archive, at the expense of setting all installed files to a single
  321            * date.
  322            * <p>
  323            * If this property is set to the special string {@link #KEEP},
  324            * the packer transmits a separate modification time for each input
  325            * element.
  326            * <p>
  327            * The default is {@link #KEEP}, which preserves the input information,
  328            * but may cause the transmitted archive to be larger than necessary.
  329            * <p>
  330            * It is up to the unpacker implementation to take action to suitably
  331            * set the modification time of each element of its output file.
  332            * @see #SEGMENT_LIMIT
  333            */
  334           String MODIFICATION_TIME        = "pack.modification.time";
  335   
  336           /**
  337            * Indicates that a file should be passed through bytewise, with no
  338            * compression.  Multiple files may be specified by specifying
  339            * additional properties with distinct strings appended, to
  340            * make a family of properties with the common prefix.
  341            * <p>
  342            * There is no pathname transformation, except
  343            * that the system file separator is replaced by the JAR file
  344            * separator '/'.
  345            * <p>
  346            * The resulting file names must match exactly as strings with their
  347            * occurrences in the JAR file.
  348            * <p>
  349            * If a property value is a directory name, all files under that
  350            * directory will be passed also.
  351            * <p>
  352            * Examples:
  353            * <pre><code>
  354            *     Map p = packer.properties();
  355            *     p.put(PASS_FILE_PFX+0, "mutants/Rogue.class");
  356            *     p.put(PASS_FILE_PFX+1, "mutants/Wolverine.class");
  357            *     p.put(PASS_FILE_PFX+2, "mutants/Storm.class");
  358            *     # Pass all files in an entire directory hierarchy:
  359            *     p.put(PASS_FILE_PFX+3, "police/");
  360            * </pre></code>.
  361            */
  362           String PASS_FILE_PFX            = "pack.pass.file.";
  363   
  364           /// Attribute control.
  365   
  366           /**
  367            * Indicates the action to take when a class-file containing an unknown
  368            * attribute is encountered.  Possible values are the strings {@link #ERROR},
  369            * {@link #STRIP}, and {@link #PASS}.
  370            * <p>
  371            * The string {@link #ERROR} means that the pack operation
  372            * as a whole will fail, with an exception of type <code>IOException</code>.
  373            * The string
  374            * {@link #STRIP} means that the attribute will be dropped.
  375            * The string
  376            * {@link #PASS} means that the whole class-file will be passed through
  377            * (as if it were a resource file) without compression, with  a suitable warning.
  378            * This is the default value for this property.
  379            * <p>
  380            * Examples:
  381            * <pre><code>
  382            *     Map p = pack200.getProperties();
  383            *     p.put(UNKNOWN_ATTRIBUTE, ERROR);
  384            *     p.put(UNKNOWN_ATTRIBUTE, STRIP);
  385            *     p.put(UNKNOWN_ATTRIBUTE, PASS);
  386            * </pre></code>
  387            */
  388           String UNKNOWN_ATTRIBUTE        = "pack.unknown.attribute";
  389   
  390           /**
  391            * When concatenated with a class attribute name,
  392            * indicates the format of that attribute,
  393            * using the layout language specified in the JSR 200 specification.
  394            * <p>
  395            * For example, the effect of this option is built in:
  396            * <code>pack.class.attribute.SourceFile=RUH</code>.
  397            * <p>
  398            * The special strings {@link #ERROR}, {@link #STRIP}, and {@link #PASS} are
  399            * also allowed, with the same meaning as {@link #UNKNOWN_ATTRIBUTE}.
  400            * This provides a way for users to request that specific attributes be
  401            * refused, stripped, or passed bitwise (with no class compression).
  402            * <p>
  403            * Code like this might be used to support attributes for JCOV:
  404            * <pre><code>
  405            *     Map p = packer.properties();
  406            *     p.put(CODE_ATTRIBUTE_PFX+"CoverageTable",       "NH[PHHII]");
  407            *     p.put(CODE_ATTRIBUTE_PFX+"CharacterRangeTable", "NH[PHPOHIIH]");
  408            *     p.put(CLASS_ATTRIBUTE_PFX+"SourceID",           "RUH");
  409            *     p.put(CLASS_ATTRIBUTE_PFX+"CompilationID",      "RUH");
  410            * </code></pre>
  411            * <p>
  412            * Code like this might be used to strip debugging attributes:
  413            * <pre><code>
  414            *     Map p = packer.properties();
  415            *     p.put(CODE_ATTRIBUTE_PFX+"LineNumberTable",    STRIP);
  416            *     p.put(CODE_ATTRIBUTE_PFX+"LocalVariableTable", STRIP);
  417            *     p.put(CLASS_ATTRIBUTE_PFX+"SourceFile",        STRIP);
  418            * </code></pre>
  419            */
  420           String CLASS_ATTRIBUTE_PFX      = "pack.class.attribute.";
  421   
  422           /**
  423            * When concatenated with a field attribute name,
  424            * indicates the format of that attribute.
  425            * For example, the effect of this option is built in:
  426            * <code>pack.field.attribute.Deprecated=</code>.
  427            * The special strings {@link #ERROR}, {@link #STRIP}, and
  428            * {@link #PASS} are also allowed.
  429            * @see #CLASS_ATTRIBUTE_PFX
  430            */
  431           String FIELD_ATTRIBUTE_PFX      = "pack.field.attribute.";
  432   
  433           /**
  434            * When concatenated with a method attribute name,
  435            * indicates the format of that attribute.
  436            * For example, the effect of this option is built in:
  437            * <code>pack.method.attribute.Exceptions=NH[RCH]</code>.
  438            * The special strings {@link #ERROR}, {@link #STRIP}, and {@link #PASS}
  439            * are also allowed.
  440            * @see #CLASS_ATTRIBUTE_PFX
  441            */
  442           String METHOD_ATTRIBUTE_PFX     = "pack.method.attribute.";
  443   
  444           /**
  445            * When concatenated with a code attribute name,
  446            * indicates the format of that attribute.
  447            * For example, the effect of this option is built in:
  448            * <code>pack.code.attribute.LocalVariableTable=NH[PHOHRUHRSHH]</code>.
  449            * The special strings {@link #ERROR}, {@link #STRIP}, and {@link #PASS}
  450            * are also allowed.
  451            * @see #CLASS_ATTRIBUTE_PFX
  452            */
  453           String CODE_ATTRIBUTE_PFX       = "pack.code.attribute.";
  454   
  455           /**
  456            * The unpacker's progress as a percentage, as periodically
  457            * updated by the unpacker.
  458            * Values of 0 - 100 are normal, and -1 indicates a stall.
  459            * Observe this property with a {@link PropertyChangeListener}.
  460            * <p>
  461            * At a minimum, the unpacker must set progress to 0
  462            * at the beginning of a packing operation, and to 100
  463            * at the end.
  464            * @see  #addPropertyChangeListener
  465            */
  466           String PROGRESS                 = "pack.progress";
  467   
  468           /** The string "keep", a possible value for certain properties.
  469            * @see #DEFLATE_HINT
  470            * @see #MODIFICATION_TIME
  471            */
  472           String KEEP  = "keep";
  473   
  474           /** The string "pass", a possible value for certain properties.
  475            * @see #UNKNOWN_ATTRIBUTE
  476            * @see #CLASS_ATTRIBUTE_PFX
  477            * @see #FIELD_ATTRIBUTE_PFX
  478            * @see #METHOD_ATTRIBUTE_PFX
  479            * @see #CODE_ATTRIBUTE_PFX
  480            */
  481           String PASS  = "pass";
  482   
  483           /** The string "strip", a possible value for certain properties.
  484            * @see #UNKNOWN_ATTRIBUTE
  485            * @see #CLASS_ATTRIBUTE_PFX
  486            * @see #FIELD_ATTRIBUTE_PFX
  487            * @see #METHOD_ATTRIBUTE_PFX
  488            * @see #CODE_ATTRIBUTE_PFX
  489            */
  490           String STRIP = "strip";
  491   
  492           /** The string "error", a possible value for certain properties.
  493            * @see #UNKNOWN_ATTRIBUTE
  494            * @see #CLASS_ATTRIBUTE_PFX
  495            * @see #FIELD_ATTRIBUTE_PFX
  496            * @see #METHOD_ATTRIBUTE_PFX
  497            * @see #CODE_ATTRIBUTE_PFX
  498            */
  499           String ERROR = "error";
  500   
  501           /** The string "true", a possible value for certain properties.
  502            * @see #KEEP_FILE_ORDER
  503            * @see #DEFLATE_HINT
  504            */
  505           String TRUE = "true";
  506   
  507           /** The string "false", a possible value for certain properties.
  508            * @see #KEEP_FILE_ORDER
  509            * @see #DEFLATE_HINT
  510            */
  511           String FALSE = "false";
  512   
  513           /** The string "latest", a possible value for certain properties.
  514            * @see #MODIFICATION_TIME
  515            */
  516           String LATEST = "latest";
  517   
  518           /**
  519            * Get the set of this engine's properties.
  520            * This set is a "live view", so that changing its
  521            * contents immediately affects the Packer engine, and
  522            * changes from the engine (such as progress indications)
  523            * are immediately visible in the map.
  524            *
  525            * <p>The property map may contain pre-defined implementation
  526            * specific and default properties.  Users are encouraged to
  527            * read the information and fully understand the implications,
  528            * before modifying pre-existing properties.
  529            * <p>
  530            * Implementation specific properties are prefixed with a
  531            * package name associated with the implementor, beginning
  532            * with <tt>com.</tt> or a similar prefix.
  533            * All property names beginning with <tt>pack.</tt> and
  534            * <tt>unpack.</tt> are reserved for use by this API.
  535            * <p>
  536            * Unknown properties may be ignored or rejected with an
  537            * unspecified error, and invalid entries may cause an
  538            * unspecified error to be thrown.
  539            *
  540            * <p>
  541            * The returned map implements all optional {@link SortedMap} operations
  542            * @return A sorted association of property key strings to property
  543            * values.
  544            */
  545           SortedMap<String,String> properties();
  546   
  547           /**
  548            * Takes a JarFile and converts it into a Pack200 archive.
  549            * <p>
  550            * Closes its input but not its output.  (Pack200 archives are appendable.)
  551            * @param in a JarFile
  552            * @param out an OutputStream
  553            * @exception IOException if an error is encountered.
  554            */
  555           void pack(JarFile in, OutputStream out) throws IOException ;
  556   
  557           /**
  558            * Takes a JarInputStream and converts it into a Pack200 archive.
  559            * <p>
  560            * Closes its input but not its output.  (Pack200 archives are appendable.)
  561            * <p>
  562            * The modification time and deflation hint attributes are not available,
  563            * for the JAR manifest file and its containing directory.
  564            *
  565            * @see #MODIFICATION_TIME
  566            * @see #DEFLATE_HINT
  567            * @param in a JarInputStream
  568            * @param out an OutputStream
  569            * @exception IOException if an error is encountered.
  570            */
  571           void pack(JarInputStream in, OutputStream out) throws IOException ;
  572   
  573           /**
  574            * Registers a listener for PropertyChange events on the properties map.
  575            * This is typically used by applications to update a progress bar.
  576            *
  577            * @see #properties
  578            * @see #PROGRESS
  579            * @param listener  An object to be invoked when a property is changed.
  580            */
  581           void addPropertyChangeListener(PropertyChangeListener listener) ;
  582   
  583           /**
  584            * Remove a listener for PropertyChange events, added by
  585            * the {@link #addPropertyChangeListener}.
  586            *
  587            * @see #addPropertyChangeListener
  588            * @param listener  The PropertyChange listener to be removed.
  589            */
  590           void removePropertyChangeListener(PropertyChangeListener listener);
  591   
  592       }
  593   
  594       /**
  595        * The unpacker engine converts the packed stream to a JAR file.
  596        * An instance of the engine can be obtained
  597        * using {@link #newUnpacker}.
  598        * <p>
  599        * Every JAR file produced by this engine will include the string
  600        * "<tt>PACK200</tt>" as a zip file comment.
  601        * This allows a deployer to detect if a JAR archive was packed and unpacked.
  602        * <p>
  603        * Note: Unless otherwise noted, passing a <tt>null</tt> argument to a
  604        * constructor or method in this class will cause a {@link NullPointerException}
  605        * to be thrown.
  606        * <p>
  607        * This version of the unpacker is compatible with all previous versions.
  608        * @since 1.5
  609        */
  610       public interface Unpacker {
  611   
  612           /** The string "keep", a possible value for certain properties.
  613            * @see #DEFLATE_HINT
  614            */
  615           String KEEP  = "keep";
  616   
  617           /** The string "true", a possible value for certain properties.
  618            * @see #DEFLATE_HINT
  619            */
  620           String TRUE = "true";
  621   
  622           /** The string "false", a possible value for certain properties.
  623            * @see #DEFLATE_HINT
  624            */
  625           String FALSE = "false";
  626   
  627           /**
  628            * Property indicating that the unpacker should
  629            * ignore all transmitted values for DEFLATE_HINT,
  630            * replacing them by the given value, {@link #TRUE} or {@link #FALSE}.
  631            * The default value is the special string {@link #KEEP},
  632            * which asks the unpacker to preserve all transmitted
  633            * deflation hints.
  634            */
  635           String DEFLATE_HINT      = "unpack.deflate.hint";
  636   
  637   
  638   
  639           /**
  640            * The unpacker's progress as a percentage, as periodically
  641            * updated by the unpacker.
  642            * Values of 0 - 100 are normal, and -1 indicates a stall.
  643            * Observe this property with a {@link PropertyChangeListener}.
  644            * <p>
  645            * At a minimum, the unpacker must set progress to 0
  646            * at the beginning of a packing operation, and to 100
  647            * at the end.
  648            * @see #addPropertyChangeListener
  649            */
  650           String PROGRESS         = "unpack.progress";
  651   
  652           /**
  653            * Get the set of this engine's properties. This set is
  654            * a "live view", so that changing its
  655            * contents immediately affects the Packer engine, and
  656            * changes from the engine (such as progress indications)
  657            * are immediately visible in the map.
  658            *
  659            * <p>The property map may contain pre-defined implementation
  660            * specific and default properties.  Users are encouraged to
  661            * read the information and fully understand the implications,
  662            * before modifying pre-existing properties.
  663            * <p>
  664            * Implementation specific properties are prefixed with a
  665            * package name associated with the implementor, beginning
  666            * with <tt>com.</tt> or a similar prefix.
  667            * All property names beginning with <tt>pack.</tt> and
  668            * <tt>unpack.</tt> are reserved for use by this API.
  669            * <p>
  670            * Unknown properties may be ignored or rejected with an
  671            * unspecified error, and invalid entries may cause an
  672            * unspecified error to be thrown.
  673            *
  674            * @return A sorted association of option key strings to option values.
  675            */
  676           SortedMap<String,String> properties();
  677   
  678           /**
  679            * Read a Pack200 archive, and write the encoded JAR to
  680            * a JarOutputStream.
  681            * The entire contents of the input stream will be read.
  682            * It may be more efficient to read the Pack200 archive
  683            * to a file and pass the File object, using the alternate
  684            * method described below.
  685            * <p>
  686            * Closes its input but not its output.  (The output can accumulate more elements.)
  687            * @param in an InputStream.
  688            * @param out a JarOutputStream.
  689            * @exception IOException if an error is encountered.
  690            */
  691           void unpack(InputStream in, JarOutputStream out) throws IOException;
  692   
  693           /**
  694            * Read a Pack200 archive, and write the encoded JAR to
  695            * a JarOutputStream.
  696            * <p>
  697            * Does not close its output.  (The output can accumulate more elements.)
  698            * @param in a File.
  699            * @param out a JarOutputStream.
  700            * @exception IOException if an error is encountered.
  701            */
  702           void unpack(File in, JarOutputStream out) throws IOException;
  703   
  704           /**
  705            * Registers a listener for PropertyChange events on the properties map.
  706            * This is typically used by applications to update a progress bar.
  707            *
  708            * @see #properties
  709            * @see #PROGRESS
  710            * @param listener  An object to be invoked when a property is changed.
  711            */
  712           void addPropertyChangeListener(PropertyChangeListener listener) ;
  713   
  714           /**
  715            * Remove a listener for PropertyChange events, added by
  716            * the {@link #addPropertyChangeListener}.
  717            *
  718            * @see #addPropertyChangeListener
  719            * @param listener  The PropertyChange listener to be removed.
  720            */
  721           void removePropertyChangeListener(PropertyChangeListener listener);
  722       }
  723   
  724       // Private stuff....
  725   
  726       private static final String PACK_PROVIDER = "java.util.jar.Pack200.Packer";
  727       private static final String UNPACK_PROVIDER = "java.util.jar.Pack200.Unpacker";
  728   
  729       private static Class packerImpl;
  730       private static Class unpackerImpl;
  731   
  732       private synchronized static Object newInstance(String prop) {
  733           String implName = "(unknown)";
  734           try {
  735               Class impl = (PACK_PROVIDER.equals(prop))? packerImpl: unpackerImpl;
  736               if (impl == null) {
  737                   // The first time, we must decide which class to use.
  738                   implName = java.security.AccessController.doPrivileged(
  739                       new sun.security.action.GetPropertyAction(prop,""));
  740                   if (implName != null && !implName.equals(""))
  741                       impl = Class.forName(implName);
  742                   else if (PACK_PROVIDER.equals(prop))
  743                       impl = com.sun.java.util.jar.pack.PackerImpl.class;
  744                   else
  745                       impl = com.sun.java.util.jar.pack.UnpackerImpl.class;
  746               }
  747               // We have a class.  Now instantiate it.
  748               return impl.newInstance();
  749           } catch (ClassNotFoundException e) {
  750               throw new Error("Class not found: " + implName +
  751                                   ":\ncheck property " + prop +
  752                                   " in your properties file.", e);
  753           } catch (InstantiationException e) {
  754               throw new Error("Could not instantiate: " + implName +
  755                                   ":\ncheck property " + prop +
  756                                   " in your properties file.", e);
  757           } catch (IllegalAccessException e) {
  758               throw new Error("Cannot access class: " + implName +
  759                                   ":\ncheck property " + prop +
  760                                   " in your properties file.", e);
  761           }
  762       }
  763   
  764   }

Home » openjdk-7 » java » util » jar » [javadoc | source]