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