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.File;
23 import java.io.IOException;
24 import java.io.OutputStream;
25 import java.nio.file.Files;
26 import java.nio.file.Path;
27 import java.util.HashMap;
28 import java.util.Map;
29 import java.util.jar.JarFile;
30 import java.util.jar.JarOutputStream;
31
32 import org.apache.commons.compress.java.util.jar.Pack200;
33
34 /**
35 * Utility methods for Pack200.
36 *
37 * @ThreadSafe
38 * @since 1.3
39 */
40 public class Pack200Utils {
41 /**
42 * Normalizes a JAR archive in-place, so it can be safely signed and packed.
43 *
44 * <p>
45 * As stated in <a href="https://download.oracle.com/javase/1.5.0/docs/api/java/util/jar/Pack200.Packer.html">Pack200.Packer's</a> javadocs applying a
46 * Pack200 compression to a JAR archive will in general make its signatures invalid. In order to prepare a JAR for signing it should be "normalized" by
47 * packing and unpacking it. This is what this method does.
48 * </p>
49 *
50 * <p>
51 * Note this methods implicitly sets the segment length to -1.
52 * </p>
53 *
54 * @param jar the JAR archive to normalize
55 * @throws IOException if reading or writing fails
56 */
57 public static void normalize(final File jar) throws IOException {
58 normalize(jar, jar, null);
59 }
60
61 /**
62 * Normalizes a JAR archive, so it can be safely signed and packed.
63 *
64 * <p>
65 * As stated in <a href="https://download.oracle.com/javase/1.5.0/docs/api/java/util/jar/Pack200.Packer.html">Pack200.Packer's</a> javadocs applying a
66 * Pack200 compression to a JAR archive will in general make its signatures invalid. In order to prepare a JAR for signing it should be "normalized" by
67 * packing and unpacking it. This is what this method does.
68 * </p>
69 *
70 * <p>
71 * This method does not replace the existing archive but creates a new one.
72 * </p>
73 *
74 * <p>
75 * Note this methods implicitly sets the segment length to -1.
76 * </p>
77 *
78 * @param from the JAR archive to normalize
79 * @param to the normalized archive
80 * @throws IOException if reading or writing fails
81 */
82 public static void normalize(final File from, final File to) throws IOException {
83 normalize(from, to, null);
84 }
85
86 /**
87 * Normalizes a JAR archive, so it can be safely signed and packed.
88 *
89 * <p>
90 * As stated in <a href="https://download.oracle.com/javase/1.5.0/docs/api/java/util/jar/Pack200.Packer.html">Pack200.Packer's</a> javadocs applying a
91 * Pack200 compression to a JAR archive will in general make its signatures invalid. In order to prepare a JAR for signing it should be "normalized" by
92 * packing and unpacking it. This is what this method does.
93 * </p>
94 *
95 * <p>
96 * This method does not replace the existing archive but creates a new one.
97 * </p>
98 *
99 * @param from the JAR archive to normalize
100 * @param to the normalized archive
101 * @param props properties to set for the pack operation. This method will implicitly set the segment limit to -1.
102 * @throws IOException if reading or writing fails
103 */
104 public static void normalize(final File from, final File to, Map<String, String> props) throws IOException {
105 if (props == null) {
106 props = new HashMap<>();
107 }
108 props.put(Pack200.Packer.SEGMENT_LIMIT, "-1");
109 final Path tempFile = Files.createTempFile("commons-compress", "pack200normalize");
110 try {
111 try (OutputStream fos = Files.newOutputStream(tempFile);
112 JarFile jarFile = new JarFile(from)) {
113 final Pack200.Packer packer = Pack200.newPacker();
114 packer.properties().putAll(props);
115 packer.pack(jarFile, fos);
116 }
117 final Pack200.Unpacker unpacker = Pack200.newUnpacker();
118 try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(to.toPath()))) {
119 unpacker.unpack(tempFile.toFile(), jos);
120 }
121 } finally {
122 Files.delete(tempFile);
123 }
124 }
125
126 /**
127 * Normalizes a JAR archive in-place, so it can be safely signed and packed.
128 *
129 * <p>
130 * As stated in <a href="https://download.oracle.com/javase/1.5.0/docs/api/java/util/jar/Pack200.Packer.html">Pack200.Packer's</a> javadocs applying a
131 * Pack200 compression to a JAR archive will in general make its signatures invalid. In order to prepare a JAR for signing it should be "normalized" by
132 * packing and unpacking it. This is what this method does.
133 * </p>
134 *
135 * @param jar the JAR archive to normalize
136 * @param props properties to set for the pack operation. This method will implicitly set the segment limit to -1.
137 * @throws IOException if reading or writing fails
138 */
139 public static void normalize(final File jar, final Map<String, String> props) throws IOException {
140 normalize(jar, jar, props);
141 }
142
143 private Pack200Utils() {
144 }
145 }