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

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