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 * https://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
27 import org.apache.commons.compress.compressors.CompressorOutputStream;
28 import org.apache.commons.compress.java.util.jar.Pack200;
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<OutputStream> {
37 private final AbstractStreamBridge abstractStreamBridge;
38 private final Map<String, String> properties;
39
40 /**
41 * Compresses the given stream, caching the compressed data in memory.
42 *
43 * @param out the stream to write to
44 * @throws IOException if writing fails
45 */
46 public Pack200CompressorOutputStream(final OutputStream out) throws IOException {
47 this(out, Pack200Strategy.IN_MEMORY);
48 }
49
50 /**
51 * Compresses the given stream, caching the compressed data in memory and using the given properties.
52 *
53 * @param out the stream to write to
54 * @param props Pack200 properties to use
55 * @throws IOException if writing fails
56 */
57 public Pack200CompressorOutputStream(final OutputStream out, final Map<String, String> props) throws IOException {
58 this(out, Pack200Strategy.IN_MEMORY, props);
59 }
60
61 /**
62 * Compresses the given stream using the given strategy to cache the results.
63 *
64 * @param out the stream to write to
65 * @param mode the strategy to use
66 * @throws IOException if writing fails
67 */
68 public Pack200CompressorOutputStream(final OutputStream out, final Pack200Strategy mode) throws IOException {
69 this(out, mode, null);
70 }
71
72 /**
73 * Compresses the given stream using the given strategy to cache the results and the given properties.
74 *
75 * @param out the stream to write to
76 * @param mode the strategy to use
77 * @param props Pack200 properties to use
78 * @throws IOException if writing fails
79 */
80 public Pack200CompressorOutputStream(final OutputStream out, final Pack200Strategy mode, final Map<String, String> props) throws IOException {
81 super(out);
82 abstractStreamBridge = mode.newStreamBridge();
83 properties = props;
84 }
85
86 @Override
87 public void close() throws IOException {
88 try {
89 finish();
90 } finally {
91 try {
92 abstractStreamBridge.stop();
93 } finally {
94 super.close();
95 }
96 }
97 }
98
99 @Override
100 public void finish() throws IOException {
101 if (!isFinished()) {
102 super.finish();
103 final Pack200.Packer p = Pack200.newPacker();
104 if (properties != null) {
105 p.properties().putAll(properties);
106 }
107 try (JarInputStream ji = new JarInputStream(abstractStreamBridge.getInputStream())) {
108 p.pack(ji, out);
109 }
110 }
111 }
112
113 @Override
114 public void write(final byte[] b) throws IOException {
115 abstractStreamBridge.write(b);
116 }
117
118 @Override
119 public void write(final byte[] b, final int from, final int length) throws IOException {
120 abstractStreamBridge.write(b, from, length);
121 }
122
123 @Override
124 public void write(final int b) throws IOException {
125 abstractStreamBridge.write(b);
126 }
127 }