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