1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.harmony.unpack200;
20
21 import java.io.BufferedInputStream;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FilterInputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.net.URISyntaxException;
28 import java.net.URL;
29 import java.nio.file.Files;
30 import java.nio.file.Path;
31 import java.nio.file.Paths;
32 import java.util.jar.JarOutputStream;
33
34 import org.apache.commons.compress.harmony.pack200.Pack200Adapter;
35 import org.apache.commons.compress.harmony.pack200.Pack200Exception;
36 import org.apache.commons.compress.java.util.jar.Pack200.Unpacker;
37 import org.apache.commons.io.input.BoundedInputStream;
38 import org.apache.commons.io.input.CloseShieldInputStream;
39 import org.apache.commons.lang3.reflect.FieldUtils;
40
41
42
43
44 public class Pack200UnpackerAdapter extends Pack200Adapter implements Unpacker {
45
46
47
48
49
50
51
52
53
54
55
56 static BoundedInputStream newBoundedInputStream(final File file) throws IOException {
57 return newBoundedInputStream(file.toPath());
58 }
59
60 private static BoundedInputStream newBoundedInputStream(final FileInputStream fileInputStream) throws IOException {
61 return newBoundedInputStream(readPathString(fileInputStream));
62 }
63
64 @SuppressWarnings("resource")
65 static BoundedInputStream newBoundedInputStream(final InputStream inputStream) throws IOException {
66 if (inputStream instanceof BoundedInputStream) {
67
68 return (BoundedInputStream) inputStream;
69 }
70 if (inputStream instanceof CloseShieldInputStream) {
71
72 return newBoundedInputStream(BoundedInputStream.builder().setInputStream(inputStream).get());
73 }
74 if (inputStream instanceof FilterInputStream) {
75 return newBoundedInputStream(unwrap((FilterInputStream) inputStream));
76 }
77 if (inputStream instanceof FileInputStream) {
78 return newBoundedInputStream((FileInputStream) inputStream);
79 }
80
81 return newBoundedInputStream(BoundedInputStream.builder().setInputStream(inputStream).get());
82 }
83
84
85
86
87
88
89
90
91
92
93
94 @SuppressWarnings("resource")
95 static BoundedInputStream newBoundedInputStream(final Path path) throws IOException {
96
97 return BoundedInputStream.builder()
98 .setInputStream(new BufferedInputStream(Files.newInputStream(path)))
99 .setMaxCount(Files.size(path))
100 .setPropagateClose(false)
101 .get();
102
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116 static BoundedInputStream newBoundedInputStream(final String first, final String... more) throws IOException {
117 return newBoundedInputStream(Paths.get(first, more));
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131 static BoundedInputStream newBoundedInputStream(final URL url) throws IOException, URISyntaxException {
132 return newBoundedInputStream(Paths.get(url.toURI()));
133 }
134
135 @SuppressWarnings("unchecked")
136 private static <T> T readField(final Object object, final String fieldName) {
137 try {
138 return (T) FieldUtils.readField(object, fieldName, true);
139 } catch (final IllegalAccessException e) {
140 return null;
141 }
142 }
143
144 static String readPathString(final FileInputStream fis) {
145 return readField(fis, "path");
146 }
147
148
149
150
151
152
153
154 static InputStream unwrap(final FilterInputStream filterInputStream) {
155 return readField(filterInputStream, "in");
156 }
157
158
159
160
161
162
163
164 static InputStream unwrap(final InputStream inputStream) {
165 return inputStream instanceof FilterInputStream ? unwrap((FilterInputStream) inputStream) : inputStream;
166 }
167
168 @Override
169 public void unpack(final File file, final JarOutputStream out) throws IOException {
170 if (file == null) {
171 throw new IllegalArgumentException("Must specify input file.");
172 }
173 if (out == null) {
174 throw new IllegalArgumentException("Must specify output stream.");
175 }
176 final long size = file.length();
177 final int bufferSize = size > 0 && size < DEFAULT_BUFFER_SIZE ? (int) size : DEFAULT_BUFFER_SIZE;
178 try (InputStream in = new BufferedInputStream(Files.newInputStream(file.toPath()), bufferSize)) {
179 unpack(in, out);
180 }
181 }
182
183 @Override
184 public void unpack(final InputStream in, final JarOutputStream out) throws IOException {
185 if (in == null) {
186 throw new IllegalArgumentException("Must specify input stream.");
187 }
188 if (out == null) {
189 throw new IllegalArgumentException("Must specify output stream.");
190 }
191 completed(0);
192 try {
193 new Archive(in, out).unpack();
194 } catch (final Pack200Exception e) {
195 throw new IOException("Failed to unpack Jar:" + e);
196 }
197 completed(1);
198 }
199 }