1 package nom.tam.fits.compress;
2
3 import java.io.BufferedInputStream;
4 import java.io.ByteArrayOutputStream;
5 import java.io.FilterInputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.OutputStream;
9 import java.nio.charset.Charset;
10 import java.util.logging.Level;
11 import java.util.logging.Logger;
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 import static nom.tam.util.LoggerHelper.getLogger;
45
46
47
48
49
50
51
52
53
54
55
56
57 @Deprecated
58 public class CloseIS extends FilterInputStream {
59
60 private static final Logger LOG = getLogger(CloseIS.class);
61
62 private static final int COPY_BUFFER_SIZE = 64 * 1024;
63
64 private InputStream output;
65
66 private OutputStream input;
67
68 private String errorText;
69
70 private IOException exception;
71
72 private final Thread stdError;
73
74 private final Thread copier;
75
76 private final Process proc;
77
78
79
80
81
82
83
84 @SuppressWarnings("resource")
85 public CloseIS(Process proc, final InputStream compressed) {
86 super(new BufferedInputStream(proc.getInputStream(), CompressionManager.ONE_MEGABYTE));
87 if (compressed == null) {
88 throw new NullPointerException();
89 }
90 this.proc = proc;
91 final InputStream error = proc.getErrorStream();
92 output = proc.getInputStream();
93 input = proc.getOutputStream();
94 stdError = new Thread(new Runnable() {
95
96 @Override
97 public void run() {
98 try {
99 ByteArrayOutputStream bytes = new ByteArrayOutputStream();
100 byte[] buffer = new byte[COPY_BUFFER_SIZE];
101 int len;
102 while ((len = error.read(buffer, 0, buffer.length)) >= 0) {
103 bytes.write(buffer, 0, len);
104 }
105 error.close();
106 errorText = new String(bytes.toByteArray(), Charset.defaultCharset());
107 } catch (IOException e) {
108 exception = e;
109 }
110 }
111 });
112
113 copier = new Thread(new Runnable() {
114
115 @Override
116 public void run() {
117 try {
118 byte[] buffer = new byte[COPY_BUFFER_SIZE];
119 int len;
120 while ((len = compressed.read(buffer, 0, buffer.length)) >= 0) {
121 input.write(buffer, 0, len);
122 }
123 input.close();
124 } catch (IOException e) {
125 exception = e;
126 }
127 try {
128 compressed.close();
129 } catch (IOException e) {
130 if (exception == null) {
131 exception = e;
132 }
133 }
134 }
135 });
136 start();
137 }
138
139
140
141
142 private void start() {
143 stdError.start();
144 copier.start();
145 }
146
147 @Override
148 public int read() throws IOException {
149 int result = 0;
150 try {
151 result = super.read();
152 return result;
153 } catch (IOException e) {
154 result = -1;
155 throw e;
156 } finally {
157 handledOccuredException(result);
158 }
159 }
160
161 private void handledOccuredException(int result) throws IOException {
162 int exitValue = 0;
163 if (result < 0) {
164 try {
165 stdError.join();
166 copier.join();
167 exitValue = proc.exitValue();
168 } catch (Exception e) {
169 LOG.log(Level.WARNING, "could not join the stream processes", e);
170 }
171 }
172 if (exception != null || exitValue != 0) {
173 if (errorText != null && !errorText.trim().isEmpty()) {
174 throw new IOException(errorText, exception);
175 }
176 if (exception == null) {
177 throw new IOException("exit value was " + exitValue);
178 }
179 throw exception;
180 }
181 }
182
183 @Override
184 public int read(byte[] b, int off, int len) throws IOException {
185 int result = 0;
186 try {
187 result = super.read(b, off, len);
188 return result;
189 } catch (IOException e) {
190 throw e;
191 } finally {
192 handledOccuredException(result);
193 }
194 }
195
196 @Override
197 public void close() throws IOException {
198 super.close();
199 input.close();
200 output.close();
201 }
202
203 }