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 * http://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 boolean finished; 038 private final AbstractStreamBridge abstractStreamBridge; 039 private final Map<String, String> properties; 040 041 /** 042 * Compresses the given stream, caching the compressed data in memory. 043 * 044 * @param out the stream to write to 045 * @throws IOException if writing fails 046 */ 047 public Pack200CompressorOutputStream(final OutputStream out) throws IOException { 048 this(out, Pack200Strategy.IN_MEMORY); 049 } 050 051 /** 052 * Compresses the given stream, caching the compressed data in memory and using the given properties. 053 * 054 * @param out the stream to write to 055 * @param props Pack200 properties to use 056 * @throws IOException if writing fails 057 */ 058 public Pack200CompressorOutputStream(final OutputStream out, final Map<String, String> props) throws IOException { 059 this(out, Pack200Strategy.IN_MEMORY, props); 060 } 061 062 /** 063 * Compresses the given stream using the given strategy to cache the results. 064 * 065 * @param out the stream to write to 066 * @param mode the strategy to use 067 * @throws IOException if writing fails 068 */ 069 public Pack200CompressorOutputStream(final OutputStream out, final Pack200Strategy mode) throws IOException { 070 this(out, mode, null); 071 } 072 073 /** 074 * Compresses the given stream using the given strategy to cache the results and the given properties. 075 * 076 * @param out the stream to write to 077 * @param mode the strategy to use 078 * @param props Pack200 properties to use 079 * @throws IOException if writing fails 080 */ 081 public Pack200CompressorOutputStream(final OutputStream out, final Pack200Strategy mode, final Map<String, String> props) throws IOException { 082 super(out); 083 abstractStreamBridge = mode.newStreamBridge(); 084 properties = props; 085 } 086 087 @Override 088 public void close() throws IOException { 089 try { 090 finish(); 091 } finally { 092 try { 093 abstractStreamBridge.stop(); 094 } finally { 095 out.close(); 096 } 097 } 098 } 099 100 public void finish() throws IOException { 101 if (!finished) { 102 finished = true; 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}