24
24
import org .metafacture .framework .annotations .Out ;
25
25
import org .metafacture .framework .helpers .DefaultObjectPipe ;
26
26
27
+ import java .io .ByteArrayInputStream ;
27
28
import java .io .IOException ;
29
+ import java .io .InputStream ;
28
30
import java .io .InputStreamReader ;
29
31
import java .io .Reader ;
32
+ import java .io .SequenceInputStream ;
33
+ import java .net .HttpURLConnection ;
30
34
import java .net .URL ;
31
- import java .net .URLConnection ;
32
35
import java .util .Arrays ;
33
36
import java .util .HashMap ;
34
37
import java .util .Map ;
35
38
import java .util .regex .Pattern ;
36
39
37
40
/**
38
- * Opens a {@link URLConnection } and passes a reader to the receiver.
41
+ * Opens an {@link HttpURLConnection } and passes a reader to the receiver.
39
42
*
40
43
* @author Christoph Böhme
41
44
* @author Jan Schnasse
@@ -55,14 +58,50 @@ public final class HttpOpener extends DefaultObjectPipe<String, ObjectReceiver<R
55
58
private static final String ACCEPT_DEFAULT = "*/*" ;
56
59
private static final String ENCODING_DEFAULT = "UTF-8" ;
57
60
61
+ private static final String INPUT_DESIGNATOR = "@-" ;
62
+
63
+ private static final Method DEFAULT_METHOD = Method .GET ;
64
+ private static final String DEFAULT_PREFIX = "ERROR: " ;
65
+
58
66
private final Map <String , String > headers = new HashMap <>();
59
67
68
+ private Method method ;
69
+ private String body ;
70
+ private String errorPrefix ;
71
+ private String url ;
72
+ private boolean inputUsed ;
73
+
74
+ public enum Method {
75
+
76
+ DELETE (false ),
77
+ GET (false ),
78
+ HEAD (false ),
79
+ OPTIONS (false ),
80
+ POST (true ),
81
+ PUT (true ),
82
+ TRACE (false );
83
+
84
+ private final boolean inputAsBody ;
85
+
86
+ Method (final boolean inputAsBody ) {
87
+ this .inputAsBody = inputAsBody ;
88
+ }
89
+
90
+ private boolean getInputAsBody () {
91
+ return inputAsBody ;
92
+ }
93
+
94
+ }
95
+
60
96
/**
61
97
* Creates an instance of {@link HttpOpener}.
62
98
*/
63
99
public HttpOpener () {
64
100
setAccept (ACCEPT_DEFAULT );
65
101
setEncoding (ENCODING_DEFAULT );
102
+ setErrorPrefix (DEFAULT_PREFIX );
103
+ setMethod (DEFAULT_METHOD );
104
+ setUrl (INPUT_DESIGNATOR );
66
105
}
67
106
68
107
/**
@@ -76,6 +115,15 @@ public void setAccept(final String accept) {
76
115
setHeader (ACCEPT_HEADER , accept );
77
116
}
78
117
118
+ /**
119
+ * Sets the HTTP request body.
120
+ *
121
+ * @param body the request body
122
+ */
123
+ public void setBody (final String body ) {
124
+ this .body = body ;
125
+ }
126
+
79
127
/**
80
128
* Sets the preferred encoding of the HTTP response. This value is in the
81
129
* accept-charset header. Additonally, the encoding is used for reading the
@@ -89,6 +137,15 @@ public void setEncoding(final String encoding) {
89
137
setHeader (ENCODING_HEADER , encoding );
90
138
}
91
139
140
+ /**
141
+ * Sets the error prefix.
142
+ *
143
+ * @param errorPrefix the error prefix
144
+ */
145
+ public void setErrorPrefix (final String errorPrefix ) {
146
+ this .errorPrefix = errorPrefix ;
147
+ }
148
+
92
149
/**
93
150
* Sets a request property, or multiple request properties separated by
94
151
* {@code \n}.
@@ -117,21 +174,85 @@ public void setHeader(final String key, final String value) {
117
174
headers .put (key .toLowerCase (), value );
118
175
}
119
176
177
+ /**
178
+ * Sets the HTTP request method.
179
+ *
180
+ * @param method the request method
181
+ */
182
+ public void setMethod (final Method method ) {
183
+ this .method = method ;
184
+ }
185
+
186
+ /**
187
+ * Sets the HTTP request URL.
188
+ *
189
+ * @param url the request URL
190
+ */
191
+ public void setUrl (final String url ) {
192
+ this .url = url ;
193
+ }
194
+
120
195
@ Override
121
- public void process (final String urlStr ) {
196
+ public void process (final String input ) {
122
197
try {
123
- final URL url = new URL (urlStr );
124
- final URLConnection con = url .openConnection ();
125
- headers .forEach (con ::addRequestProperty );
126
- String enc = con .getContentEncoding ();
127
- if (enc == null ) {
128
- enc = headers .get (ENCODING_HEADER );
198
+ final String requestUrl = getInput (input , url );
199
+ final String requestBody = getInput (input ,
200
+ body == null && method .getInputAsBody () ? INPUT_DESIGNATOR : body );
201
+
202
+ final HttpURLConnection connection =
203
+ (HttpURLConnection ) new URL (requestUrl ).openConnection ();
204
+
205
+ connection .setRequestMethod (method .name ());
206
+ headers .forEach (connection ::addRequestProperty );
207
+
208
+ if (requestBody != null ) {
209
+ connection .setDoOutput (true );
210
+ connection .getOutputStream ().write (requestBody .getBytes ());
211
+ }
212
+
213
+ final InputStream errorStream = connection .getErrorStream ();
214
+ final InputStream inputStream ;
215
+
216
+ if (errorStream != null ) {
217
+ if (errorPrefix != null ) {
218
+ final InputStream errorPrefixStream = new ByteArrayInputStream (errorPrefix .getBytes ());
219
+ inputStream = new SequenceInputStream (errorPrefixStream , errorStream );
220
+ }
221
+ else {
222
+ inputStream = errorStream ;
223
+ }
129
224
}
130
- getReceiver ().process (new InputStreamReader (con .getInputStream (), enc ));
225
+ else {
226
+ inputStream = connection .getInputStream ();
227
+ }
228
+
229
+ final String contentEncoding = getEncoding (connection .getContentEncoding ());
230
+ getReceiver ().process (new InputStreamReader (inputStream , contentEncoding ));
131
231
}
132
232
catch (final IOException e ) {
133
233
throw new MetafactureException (e );
134
234
}
135
235
}
136
236
237
+ private String getInput (final String input , final String value ) {
238
+ final String result ;
239
+
240
+ if (!INPUT_DESIGNATOR .equals (value )) {
241
+ result = value ;
242
+ }
243
+ else if (inputUsed ) {
244
+ result = null ;
245
+ }
246
+ else {
247
+ inputUsed = true ;
248
+ result = input ;
249
+ }
250
+
251
+ return result ;
252
+ }
253
+
254
+ private String getEncoding (final String contentEncoding ) {
255
+ return contentEncoding != null ? contentEncoding : headers .get (ENCODING_HEADER );
256
+ }
257
+
137
258
}
0 commit comments