-
Notifications
You must be signed in to change notification settings - Fork 445
/
DbxDownloader.java
172 lines (157 loc) · 5.08 KB
/
DbxDownloader.java
1
2
3
4
5
6
7
8
9
10
11
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package com.dropbox.core;
import com.dropbox.core.util.IOUtil;
import com.dropbox.core.util.ProgressOutputStream;
import java.io.Closeable;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* Class for handling download requests.
*
* This class provides methods for downloading a request body and reading the server response.
*
* Example usage:
*
* <pre><code>
* FileOutputStream out = new FileOutputStream("test.txt");
* try {
* response = downloader.download(out);
* } finally {
* out.close();
* }
*</code></pre>
*
* Example using {@link #getInputStream}:
*
* <pre><code>
* FileOutputStream out = new FileOutputStream("test.txt");
* response = downloader.getResult();
* try {
* InputStream in = downloader.getInputStream();
* // read from in, write to out
* } finally {
* downloader.close();
* }
*</code></pre>
*/
public class DbxDownloader<R> implements Closeable {
private final R result;
private final InputStream body;
private final String contentType;
private boolean closed;
public DbxDownloader(R result, InputStream body, String contentType) {
this.result = result;
this.body = body;
this.contentType = contentType;
this.closed = false;
}
public DbxDownloader(R result, InputStream body) {
this(result, body, null);
}
/**
* Returns the server response.
*
* Returns the response from the server that is separate from the response body (data to be
* downloaded).
*
* @return Response from server
*/
public R getResult() {
return result;
}
/**
* Returns the value of the content-type header field.
*
* @return the content type, or null if not known.
*/
public String getContentType() {
return contentType;
}
/**
* Returns the {@link InputStream} containing the response body bytes. Remember to call {@link
* #close} after reading the stream to properly free up resources.
*
* @return Response body input stream.
*
* @see #download(OutputStream)
*
* @throws IllegalStateException if this downloader has already been closed (see {@link #close})
*/
public InputStream getInputStream() {
assertOpen();
return body;
}
/**
* Downloads the response body to the given {@link OutputStream} and returns the server
* response.
*
* This method manages closing this downloader's resources, so no further calls to {@link
* #close} are necessary. The underlying {@code InputStream} returned by {@link #getInputStream}
* will be closed by this method.
*
* This method is the equivalent of
*
* <pre><code>
* try {
* InputStream in = downloader.getInputStream();
* // read from in, write to out
* return downloader.getResult();
* } finally {
* downloader.close();
* }
* </code></pre>
*
* @param out {@code OutputStream} to write response body to
*
* @return Response from server
*
* @throws DbxException if an error occurs reading the response or response body
* @throws IOException if an error occurs writing the response body to the output stream.
* @throws IllegalStateException if this downloader has already been closed (see {@link #close})
*/
public R download(OutputStream out) throws DbxException, IOException {
try {
IOUtil.copyStreamToStream(getInputStream(), out);
} catch (IOUtil.WriteException ex) {
// write exceptions should be IOException
throw ex.getCause();
} catch (IOException ex) {
// everything else is a Network I/O problem
throw new NetworkIOException(ex);
} finally {
close();
}
return result;
}
/**
* This method is the same as {@link #download(OutputStream)} except for allowing to track
* download progress.
*
* @param out {@code OutputStream} to write response body to
* @param progressListener {@code IOUtil.ProgressListener} to track the download progress.
* @return Response from server
* @throws DbxException if an error occurs reading the response or response body.
* @throws IOException if an error occurs writing the response body to the output stream.
*/
public R download(OutputStream out, IOUtil.ProgressListener progressListener)
throws DbxException, IOException {
return download(new ProgressOutputStream(out, progressListener));
}
/**
* Closes this downloader and releases its underlying resources.
*
* After calling this method, calls to {@link getInputStream} will fail.
*/
@Override
public void close() {
if (!closed) {
IOUtil.closeQuietly(body);
closed = true;
}
}
private void assertOpen() {
if (closed) {
throw new IllegalStateException("This downloader is already closed.");
}
}
}