Home | History | Annotate | Download | only in jar
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 package java.util.jar;
     18 
     19 import java.beans.PropertyChangeListener;
     20 import java.io.File;
     21 import java.io.IOException;
     22 import java.io.InputStream;
     23 import java.io.OutputStream;
     24 import java.security.AccessController;
     25 import java.security.PrivilegedAction;
     26 import java.util.SortedMap;
     27 
     28 /**
     29  * Class factory for {@link Pack200.Packer} and {@link Pack200.Unpacker}.
     30  */
     31 public abstract class Pack200 {
     32 
     33     private static final String SYSTEM_PROPERTY_PACKER = "java.util.jar.Pack200.Packer";
     34 
     35     private static final String SYSTEM_PROPERTY_UNPACKER = "java.util.jar.Pack200.Unpacker";
     36 
     37     /**
     38      * Prevent this class from being instantiated.
     39      */
     40     private Pack200() {
     41         // do nothing
     42     }
     43 
     44     /**
     45      * Returns a new instance of a packer engine.
     46      * <p>
     47      * The implementation of the packer engine is defined by the system property
     48      * {@code 'java.util.jar.Pack200.Packer'}. If this system property is
     49      * defined an instance of the specified class is returned, otherwise the
     50      * system's default implementation is returned.
     51      *
     52      * @return an instance of {@code Packer}
     53      */
     54     public static Pack200.Packer newPacker() {
     55         return (Packer) AccessController
     56                 .doPrivileged(new PrivilegedAction<Object>() {
     57                     public Object run() {
     58                         String className = System
     59                                 .getProperty(SYSTEM_PROPERTY_PACKER,
     60                                         "org.apache.harmony.pack200.Pack200PackerAdapter");
     61                         try {
     62                             // TODO Not sure if this will cause problems with
     63                             // loading the packer
     64                             return ClassLoader.getSystemClassLoader()
     65                                     .loadClass(className).newInstance();
     66                         } catch (Exception e) {
     67                             throw new Error("Can't load class " + className, e);
     68                         }
     69                     }
     70                 });
     71 
     72     }
     73 
     74     /**
     75      * Returns a new instance of a unpacker engine.
     76      * <p>
     77      * The implementation of the unpacker engine is defined by the system
     78      * property {@code 'java.util.jar.Pack200.Unpacker'}. If this system
     79      * property is defined an instance of the specified class is returned,
     80      * otherwise the system's default implementation is returned.
     81      *
     82      * @return a instance of {@code Unpacker}.
     83      */
     84     public static Pack200.Unpacker newUnpacker() {
     85         return (Unpacker) AccessController
     86                 .doPrivileged(new PrivilegedAction<Object>() {
     87                     public Object run() {
     88                         String className = System
     89                                 .getProperty(SYSTEM_PROPERTY_UNPACKER,
     90                                         "org.apache.harmony.unpack200.Pack200UnpackerAdapter");
     91                         try {
     92                             return ClassLoader.getSystemClassLoader()
     93                                     .loadClass(className).newInstance();
     94                         } catch (Exception e) {
     95                             throw new Error("Can't load class " + className, e);
     96                         }
     97                     }
     98                 });
     99     }
    100 
    101     /**
    102      * The interface defining the API for converting a JAR file to an output
    103      * stream in the Pack200 format.
    104      */
    105     public static interface Packer {
    106 
    107         /**
    108          * the format of a class attribute name.
    109          */
    110         static final String CLASS_ATTRIBUTE_PFX = "pack.class.attribute.";
    111 
    112         /**
    113          * the format of a code attribute name.
    114          */
    115         static final String CODE_ATTRIBUTE_PFX = "pack.code.attribute.";
    116 
    117         /**
    118          * the deflation hint to set in the output archive.
    119          */
    120         static final String DEFLATE_HINT = "pack.deflate.hint";
    121 
    122         /**
    123          * the indicated amount of effort to use in compressing the archive.
    124          */
    125         static final String EFFORT = "pack.effort";
    126 
    127         /**
    128          * a String representation for {@code error}.
    129          */
    130         static final String ERROR = "error";
    131 
    132         /**
    133          * a String representation of {@code false}.
    134          */
    135         static final String FALSE = "false";
    136 
    137         /**
    138          * the format of a field attribute name.
    139          */
    140         static final String FIELD_ATTRIBUTE_PFX = "pack.field.attribute.";
    141 
    142         /**
    143          * a String representation for {@code keep}.
    144          */
    145         static final String KEEP = "keep";
    146 
    147         /**
    148          * decide if all elements shall transmit in their original order.
    149          */
    150         static final String KEEP_FILE_ORDER = "pack.keep.file.order";
    151 
    152         /**
    153          * a String representation for {@code latest}.
    154          */
    155         static final String LATEST = "latest";
    156 
    157         /**
    158          * the format of a method attribute name.
    159          */
    160         static final String METHOD_ATTRIBUTE_PFX = "pack.method.attribute.";
    161 
    162         /**
    163          * if it shall attempt to determine the latest modification time if this
    164          * is set to {@code LATEST}.
    165          */
    166         static final String MODIFICATION_TIME = "pack.modification.time";
    167 
    168         /**
    169          * a String representation of {@code pass}.
    170          */
    171         static final String PASS = "pass";
    172 
    173         /**
    174          * the file that will not be compressed.
    175          */
    176         static final String PASS_FILE_PFX = "pack.pass.file.";
    177 
    178         /**
    179          * packer progress as a percentage.
    180          */
    181         static final String PROGRESS = "pack.progress";
    182 
    183         /**
    184          * The number of bytes of each archive segment.
    185          */
    186         static final String SEGMENT_LIMIT = "pack.segment.limit";
    187 
    188         /**
    189          * a String representation of {@code strip}.
    190          */
    191         static final String STRIP = "strip";
    192 
    193         /**
    194          * a String representation of {@code true}.
    195          */
    196         static final String TRUE = "true";
    197 
    198         /**
    199          * the action to take if an unknown attribute is encountered.
    200          */
    201         static final String UNKNOWN_ATTRIBUTE = "pack.unknown.attribute";
    202 
    203         /**
    204          * Returns a sorted map of the properties of this packer.
    205          *
    206          * @return the properties of the packer.
    207          */
    208         SortedMap<String, String> properties();
    209 
    210         /**
    211          * Pack the specified JAR file to the specified output stream.
    212          *
    213          * @param in
    214          *            JAR file to be compressed.
    215          * @param out
    216          *            stream of compressed data.
    217          * @throws IOException
    218          *             if I/O exception occurs.
    219          */
    220         void pack(JarFile in, OutputStream out) throws IOException;
    221 
    222         /**
    223          * Pack the data from the specified jar input stream to the specified
    224          * output stream.
    225          *
    226          * @param in
    227          *            stream of uncompressed JAR data.
    228          * @param out
    229          *            stream of compressed data.
    230          * @throws IOException
    231          *             if I/O exception occurs.
    232          */
    233         void pack(JarInputStream in, OutputStream out) throws IOException;
    234 
    235         /**
    236          * add a listener for PropertyChange events
    237          *
    238          * @param listener
    239          *            the listener to listen if PropertyChange events occurs
    240          */
    241         void addPropertyChangeListener(PropertyChangeListener listener);
    242 
    243         /**
    244          * remove a listener
    245          *
    246          * @param listener
    247          *            listener to remove
    248          */
    249         void removePropertyChangeListener(PropertyChangeListener listener);
    250     }
    251 
    252     /**
    253      * The interface defining the API for converting a packed stream in the
    254      * Pack200 format to a JAR file.
    255      */
    256     public static interface Unpacker {
    257 
    258         /**
    259          * The String indicating if the unpacker should ignore all transmitted
    260          * values,can be replaced by either {@code true} or {@code false}.
    261          */
    262         static final String DEFLATE_HINT = "unpack.deflate.hint";
    263 
    264         /**
    265          * a String representation of {@code false}.
    266          */
    267         static final String FALSE = "false";
    268 
    269         /**
    270          * a String representation of {@code keep}.
    271          */
    272         static final String KEEP = "keep";
    273 
    274         /**
    275          * the progress as a {@code percentage}.
    276          */
    277         static final String PROGRESS = "unpack.progress";
    278 
    279         /**
    280          * a String representation of {@code true}.
    281          */
    282         static final String TRUE = "true";
    283 
    284         /**
    285          * Returns a sorted map of the properties of this unpacker.
    286          *
    287          * @return the properties of unpacker.
    288          */
    289         SortedMap<String, String> properties();
    290 
    291         /**
    292          * Unpack the specified stream to the specified JAR output stream.
    293          *
    294          * @param in
    295          *            stream to uncompressed.
    296          * @param out
    297          *            JAR output stream of uncompressed data.
    298          * @throws IOException
    299          *             if I/O exception occurs.
    300          */
    301         void unpack(InputStream in, JarOutputStream out) throws IOException;
    302 
    303         /**
    304          * Unpack the contents of the specified {@code File} to the specified
    305          * JAR output stream.
    306          *
    307          * @param in
    308          *            file to be uncompressed.
    309          * @param out
    310          *            JAR output stream of uncompressed data.
    311          * @throws IOException
    312          *             if I/O exception occurs.
    313          */
    314         void unpack(File in, JarOutputStream out) throws IOException;
    315 
    316         /**
    317          * add a listener for {@code PropertyChange} events.
    318          *
    319          * @param listener
    320          *            the listener to listen if {@code PropertyChange} events
    321          *            occurs.
    322          */
    323         void addPropertyChangeListener(PropertyChangeListener listener);
    324 
    325         /**
    326          * remove a listener.
    327          *
    328          * @param listener
    329          *            listener to remove.
    330          */
    331         void removePropertyChangeListener(PropertyChangeListener listener);
    332     }
    333 
    334 }
    335