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.File; 023import java.io.IOException; 024import java.io.OutputStream; 025import java.nio.file.Files; 026import java.util.HashMap; 027import java.util.Map; 028import java.util.jar.JarFile; 029import java.util.jar.JarOutputStream; 030 031import org.apache.commons.compress.java.util.jar.Pack200; 032 033/** 034 * Utility methods for Pack200. 035 * 036 * @ThreadSafe 037 * @since 1.3 038 */ 039public class Pack200Utils { 040 private Pack200Utils() { } 041 042 /** 043 * Normalizes a JAR archive in-place so it can be safely signed 044 * and packed. 045 * 046 * <p>As stated in <a 047 * href="https://download.oracle.com/javase/1.5.0/docs/api/java/util/jar/Pack200.Packer.html">Pack200.Packer's</a> 048 * javadocs applying a Pack200 compression to a JAR archive will 049 * in general make its signatures invalid. In order to prepare a 050 * JAR for signing it should be "normalized" by packing and 051 * unpacking it. This is what this method does.</p> 052 * 053 * <p>Note this methods implicitly sets the segment length to 054 * -1.</p> 055 * 056 * @param jar the JAR archive to normalize 057 * @throws IOException if reading or writing fails 058 */ 059 public static void normalize(final File jar) 060 throws IOException { 061 normalize(jar, jar, null); 062 } 063 064 /** 065 * Normalizes a JAR archive in-place so it can be safely signed 066 * and packed. 067 * 068 * <p>As stated in <a 069 * href="https://download.oracle.com/javase/1.5.0/docs/api/java/util/jar/Pack200.Packer.html">Pack200.Packer's</a> 070 * javadocs applying a Pack200 compression to a JAR archive will 071 * in general make its signatures invalid. In order to prepare a 072 * JAR for signing it should be "normalized" by packing and 073 * unpacking it. This is what this method does.</p> 074 * 075 * @param jar the JAR archive to normalize 076 * @param props properties to set for the pack operation. This 077 * method will implicitly set the segment limit to -1. 078 * @throws IOException if reading or writing fails 079 */ 080 public static void normalize(final File jar, final Map<String, String> props) 081 throws IOException { 082 normalize(jar, jar, props); 083 } 084 085 /** 086 * Normalizes a JAR archive so it can be safely signed and packed. 087 * 088 * <p>As stated in <a 089 * href="https://download.oracle.com/javase/1.5.0/docs/api/java/util/jar/Pack200.Packer.html">Pack200.Packer's</a> 090 * javadocs applying a Pack200 compression to a JAR archive will 091 * in general make its signatures invalid. In order to prepare a 092 * JAR for signing it should be "normalized" by packing and 093 * unpacking it. This is what this method does.</p> 094 * 095 * <p>This method does not replace the existing archive but creates 096 * a new one.</p> 097 * 098 * <p>Note this methods implicitly sets the segment length to 099 * -1.</p> 100 * 101 * @param from the JAR archive to normalize 102 * @param to the normalized archive 103 * @throws IOException if reading or writing fails 104 */ 105 public static void normalize(final File from, final File to) 106 throws IOException { 107 normalize(from, to, null); 108 } 109 110 /** 111 * Normalizes a JAR archive so it can be safely signed and packed. 112 * 113 * <p>As stated in <a 114 * href="https://download.oracle.com/javase/1.5.0/docs/api/java/util/jar/Pack200.Packer.html">Pack200.Packer's</a> 115 * javadocs applying a Pack200 compression to a JAR archive will 116 * in general make its signatures invalid. In order to prepare a 117 * JAR for signing it should be "normalized" by packing and 118 * unpacking it. This is what this method does.</p> 119 * 120 * <p>This method does not replace the existing archive but creates 121 * a new one.</p> 122 * 123 * @param from the JAR archive to normalize 124 * @param to the normalized archive 125 * @param props properties to set for the pack operation. This 126 * method will implicitly set the segment limit to -1. 127 * @throws IOException if reading or writing fails 128 */ 129 public static void normalize(final File from, final File to, Map<String, String> props) 130 throws IOException { 131 if (props == null) { 132 props = new HashMap<>(); 133 } 134 props.put(Pack200.Packer.SEGMENT_LIMIT, "-1"); 135 final File tempFile = File.createTempFile("commons-compress", "pack200normalize"); 136 try { 137 try (OutputStream fos = Files.newOutputStream(tempFile.toPath()); 138 JarFile jarFile = new JarFile(from)) { 139 final Pack200.Packer packer = Pack200.newPacker(); 140 packer.properties().putAll(props); 141 packer.pack(jarFile, fos); 142 } 143 final Pack200.Unpacker unpacker = Pack200.newUnpacker(); 144 try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(to.toPath()))) { 145 unpacker.unpack(tempFile, jos); 146 } 147 } finally { 148 if (!tempFile.delete()) { 149 tempFile.deleteOnExit(); 150 } 151 } 152 } 153}