View Javadoc
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   * http://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 }