001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020package org.apache.commons.compress.compressors.pack200; 021 022import java.io.IOException; 023import java.io.OutputStream; 024import java.util.Map; 025import java.util.jar.JarInputStream; 026 027import org.apache.commons.compress.compressors.CompressorOutputStream; 028import org.apache.commons.compress.java.util.jar.Pack200; 029 030/** 031 * An output stream that compresses using the Pack200 format. 032 * 033 * @NotThreadSafe 034 * @since 1.3 035 */ 036public class Pack200CompressorOutputStream extends CompressorOutputStream<OutputStream> { 037 private final AbstractStreamBridge abstractStreamBridge; 038 private final Map<String, String> properties; 039 040 /** 041 * Compresses the given stream, caching the compressed data in memory. 042 * 043 * @param out the stream to write to 044 * @throws IOException if writing fails 045 */ 046 public Pack200CompressorOutputStream(final OutputStream out) throws IOException { 047 this(out, Pack200Strategy.IN_MEMORY); 048 } 049 050 /** 051 * Compresses the given stream, caching the compressed data in memory and using the given properties. 052 * 053 * @param out the stream to write to 054 * @param props Pack200 properties to use 055 * @throws IOException if writing fails 056 */ 057 public Pack200CompressorOutputStream(final OutputStream out, final Map<String, String> props) throws IOException { 058 this(out, Pack200Strategy.IN_MEMORY, props); 059 } 060 061 /** 062 * Compresses the given stream using the given strategy to cache the results. 063 * 064 * @param out the stream to write to 065 * @param mode the strategy to use 066 * @throws IOException if writing fails 067 */ 068 public Pack200CompressorOutputStream(final OutputStream out, final Pack200Strategy mode) throws IOException { 069 this(out, mode, null); 070 } 071 072 /** 073 * Compresses the given stream using the given strategy to cache the results and the given properties. 074 * 075 * @param out the stream to write to 076 * @param mode the strategy to use 077 * @param props Pack200 properties to use 078 * @throws IOException if writing fails 079 */ 080 public Pack200CompressorOutputStream(final OutputStream out, final Pack200Strategy mode, final Map<String, String> props) throws IOException { 081 super(out); 082 abstractStreamBridge = mode.newStreamBridge(); 083 properties = props; 084 } 085 086 @Override 087 public void close() throws IOException { 088 try { 089 finish(); 090 } finally { 091 try { 092 abstractStreamBridge.stop(); 093 } finally { 094 super.close(); 095 } 096 } 097 } 098 099 @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}