Home | History | Annotate | Download | only in pack200
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one
      3  * or more contributor license agreements.  See the NOTICE file
      4  * distributed with this work for additional information
      5  * regarding copyright ownership.  The ASF licenses this file
      6  * to you under the Apache License, Version 2.0 (the
      7  * "License"); you may not use this file except in compliance
      8  * with the License.  You may obtain a copy of the License at
      9  *
     10  * http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing,
     13  * software distributed under the License is distributed on an
     14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     15  * KIND, either express or implied.  See the License for the
     16  * specific language governing permissions and limitations
     17  * under the License.
     18  */
     19 
     20 package org.apache.commons.compress.compressors.pack200;
     21 
     22 import java.io.IOException;
     23 import java.io.OutputStream;
     24 import java.util.Map;
     25 import java.util.jar.JarInputStream;
     26 import java.util.jar.Pack200;
     27 
     28 import org.apache.commons.compress.compressors.CompressorOutputStream;
     29 
     30 /**
     31  * An output stream that compresses using the Pack200 format.
     32  *
     33  * @NotThreadSafe
     34  * @since 1.3
     35  */
     36 public class Pack200CompressorOutputStream extends CompressorOutputStream {
     37     private boolean finished = false;
     38     private final OutputStream originalOutput;
     39     private final StreamBridge streamBridge;
     40     private final Map<String, String> properties;
     41 
     42     /**
     43      * Compresses the given stream, caching the compressed data in
     44      * memory.
     45      *
     46      * @param out the stream to write to
     47      * @throws IOException if writing fails
     48      */
     49     public Pack200CompressorOutputStream(final OutputStream out)
     50         throws IOException {
     51         this(out, Pack200Strategy.IN_MEMORY);
     52     }
     53 
     54     /**
     55      * Compresses the given stream using the given strategy to cache
     56      * the results.
     57      *
     58      * @param out the stream to write to
     59      * @param mode the strategy to use
     60      * @throws IOException if writing fails
     61      */
     62     public Pack200CompressorOutputStream(final OutputStream out,
     63                                          final Pack200Strategy mode)
     64         throws IOException {
     65         this(out, mode, null);
     66     }
     67 
     68     /**
     69      * Compresses the given stream, caching the compressed data in
     70      * memory and using the given properties.
     71      *
     72      * @param out the stream to write to
     73      * @param props Pack200 properties to use
     74      * @throws IOException if writing fails
     75      */
     76     public Pack200CompressorOutputStream(final OutputStream out,
     77                                          final Map<String, String> props)
     78         throws IOException {
     79         this(out, Pack200Strategy.IN_MEMORY, props);
     80     }
     81 
     82     /**
     83      * Compresses the given stream using the given strategy to cache
     84      * the results and the given properties.
     85      *
     86      * @param out the stream to write to
     87      * @param mode the strategy to use
     88      * @param props Pack200 properties to use
     89      * @throws IOException if writing fails
     90      */
     91     public Pack200CompressorOutputStream(final OutputStream out,
     92                                          final Pack200Strategy mode,
     93                                          final Map<String, String> props)
     94         throws IOException {
     95         originalOutput = out;
     96         streamBridge = mode.newStreamBridge();
     97         properties = props;
     98     }
     99 
    100     @Override
    101     public void write(final int b) throws IOException {
    102         streamBridge.write(b);
    103     }
    104 
    105     @Override
    106     public void write(final byte[] b) throws IOException {
    107         streamBridge.write(b);
    108     }
    109 
    110     @Override
    111     public void write(final byte[] b, final int from, final int length) throws IOException {
    112         streamBridge.write(b, from, length);
    113     }
    114 
    115     @Override
    116     public void close() throws IOException {
    117         try {
    118             finish();
    119         } finally {
    120             try {
    121                 streamBridge.stop();
    122             } finally {
    123                 originalOutput.close();
    124             }
    125         }
    126     }
    127 
    128     public void finish() throws IOException {
    129         if (!finished) {
    130             finished = true;
    131             final Pack200.Packer p = Pack200.newPacker();
    132             if (properties != null) {
    133                 p.properties().putAll(properties);
    134             }
    135             try (JarInputStream ji = new JarInputStream(streamBridge.getInput())) {
    136                 p.pack(ji, originalOutput);
    137             }
    138         }
    139     }
    140 }
    141