• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
Pack200CompressorOutputStream(final OutputStream out)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      */
Pack200CompressorOutputStream(final OutputStream out, final Pack200Strategy mode)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      */
Pack200CompressorOutputStream(final OutputStream out, final Map<String, String> props)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      */
Pack200CompressorOutputStream(final OutputStream out, final Pack200Strategy mode, final Map<String, String> props)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
write(final int b)101     public void write(final int b) throws IOException {
102         streamBridge.write(b);
103     }
104 
105     @Override
write(final byte[] b)106     public void write(final byte[] b) throws IOException {
107         streamBridge.write(b);
108     }
109 
110     @Override
write(final byte[] b, final int from, final int length)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
close()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 
finish()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