001package org.kuali.common.httplib.api.model;
002
003import static com.google.common.base.Charsets.UTF_8;
004import static com.google.common.base.Optional.absent;
005import static com.google.common.collect.Lists.newArrayList;
006import static com.google.common.io.ByteSource.wrap;
007import static com.google.common.io.Files.asByteSource;
008import static org.kuali.common.httplib.api.model.HttpMethod.DELETE;
009import static org.kuali.common.httplib.api.model.HttpMethod.POST;
010import static org.kuali.common.httplib.api.model.HttpMethod.PUT;
011import static org.kuali.common.httplib.api.model.HttpStatusCodeType.SERVER_ERROR;
012import static org.kuali.common.jute.base.Precondition.checkMin;
013import static org.kuali.common.jute.reflect.Reflection.checkNoNulls;
014
015import java.io.File;
016import java.nio.charset.Charset;
017import java.util.List;
018
019import com.fasterxml.jackson.annotation.JsonSetter;
020import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
021import com.google.common.base.Optional;
022import com.google.common.collect.ImmutableList;
023import com.google.common.collect.Range;
024import com.google.common.io.ByteSource;
025
026@JsonDeserialize(builder = HttpOptions.Builder.class)
027public final class HttpOptions {
028
029    private final Optional<Long> maxBytes;
030    private final Optional<Integer> maxTimeMillis;
031    private final Optional<Integer> connectTimeoutMillis;
032    private final Optional<Integer> retryCount;
033    private final Optional<Integer> retryDelayMillis;
034    private final Optional<ByteSource> upload;
035    private final Optional<File> outputFile;
036    private final boolean cacheResponseInMemory;
037    private final boolean printResponseToStdout;
038    private final boolean followRedirects;
039    private final HttpMethod requestMethod;
040    private final Charset charset;
041    private final boolean ignoreSecurity;
042    private final boolean silent;
043    private final ImmutableList<NameValue> data;
044    private final Range<Integer> keepTryingRange;
045    private final Optional<SecurityContext> security;
046    private final ImmutableList<HeaderPair> headers;
047    private final Optional<String> contentType;
048
049    private HttpOptions(Builder builder) {
050        this.contentType = builder.contentType;
051        this.cacheResponseInMemory = builder.cacheResponseInMemory;
052        this.printResponseToStdout = builder.printResponseToStdout;
053        this.maxTimeMillis = builder.maxTimeMillis;
054        this.connectTimeoutMillis = builder.connectTimeoutMillis;
055        this.retryCount = builder.retryCount;
056        this.retryDelayMillis = builder.retryDelayMillis;
057        this.upload = builder.upload;
058        this.followRedirects = builder.followRedirects;
059        this.requestMethod = builder.requestMethod;
060        this.outputFile = builder.outputFile;
061        this.charset = builder.charset;
062        this.maxBytes = builder.maxBytes;
063        this.ignoreSecurity = builder.ignoreSecurity;
064        this.silent = builder.silent;
065        this.data = ImmutableList.copyOf(builder.data);
066        this.headers = ImmutableList.copyOf(builder.headers);
067        this.keepTryingRange = builder.keepTryingRange;
068        this.security = builder.security;
069    }
070
071    public static HttpOptions build() {
072        return builder().build();
073    }
074
075    public static Builder builder() {
076        return new Builder();
077    }
078
079    public static class Builder implements org.apache.commons.lang3.builder.Builder<HttpOptions> {
080
081        private Optional<Long> maxBytes = absent();
082        private Optional<Integer> maxTimeMillis = absent();
083        private Optional<Integer> connectTimeoutMillis = absent();
084        private Optional<Integer> retryCount = absent();
085        private Optional<Integer> retryDelayMillis = absent();
086        private Optional<ByteSource> upload = absent();
087        private boolean followRedirects = true;
088        private HttpMethod requestMethod = HttpMethod.GET;
089        private Optional<File> outputFile = absent();
090        private Charset charset = UTF_8;
091        private boolean ignoreSecurity = false;
092        private boolean silent = true;
093        private List<NameValue> data = newArrayList();
094        private Range<Integer> keepTryingRange = SERVER_ERROR.getRange();
095        private Optional<SecurityContext> security = absent();
096        private boolean cacheResponseInMemory = true;
097        private boolean printResponseToStdout = false;
098        private List<HeaderPair> headers = newArrayList();
099        private Optional<String> contentType = absent();
100
101        private static HttpOptions validate(HttpOptions instance) {
102            checkNoNulls(instance);
103            checkMin(instance.maxBytes, 0, "maxBytes");
104            checkMin(instance.maxTimeMillis, 0, "maxTimeMillis");
105            checkMin(instance.connectTimeoutMillis, 0, "connectTimeoutMillis");
106            checkMin(instance.retryCount, 0, "retryCount");
107            checkMin(instance.retryDelayMillis, 0, "retryDelayMillis");
108            return instance;
109        }
110
111        public Builder withContentType(Optional<String> contentType) {
112            this.contentType = contentType;
113            return this;
114        }
115
116        public Builder withContentType(String contentType) {
117            return withContentType(Optional.of(contentType));
118        }
119
120        public Builder withHeaders(List<HeaderPair> headers) {
121            this.headers = headers;
122            return this;
123        }
124
125        @JsonSetter
126        public Builder withSecurity(Optional<SecurityContext> security) {
127            this.security = security;
128            return this;
129        }
130
131        public Builder withSecurity(SecurityContext security) {
132            return withSecurity(Optional.of(security));
133        }
134
135        public Builder withCacheResponseInMemory(boolean cacheResponseInMemory) {
136            this.cacheResponseInMemory = cacheResponseInMemory;
137            return this;
138        }
139
140        public Builder cacheResponseInMemory() {
141            return withCacheResponseInMemory(true);
142        }
143
144        public Builder withPrintResponseToStdout(boolean printResponseToStdout) {
145            this.printResponseToStdout = printResponseToStdout;
146            return this;
147        }
148
149        public Builder printResponseToStdout() {
150            return withPrintResponseToStdout(true);
151        }
152
153        @JsonSetter
154        public Builder withOutputFile(Optional<File> outputFile) {
155            this.outputFile = outputFile;
156            return this;
157        }
158
159        public Builder withOutputFile(File outputFile) {
160            return withOutputFile(Optional.of(outputFile));
161        }
162
163        public Builder withKeepTryingRange(Range<Integer> keepTryingRange) {
164            this.keepTryingRange = keepTryingRange;
165            return this;
166        }
167
168        public Builder withData(List<NameValue> data) {
169            this.data = data;
170            return this;
171        }
172
173        public Builder withSilent(boolean silent) {
174            this.silent = silent;
175            return this;
176        }
177
178        public Builder ignoreSecurity() {
179            return withIgnoreSecurity(true);
180        }
181
182        public Builder withIgnoreSecurity(boolean ignoreSecurity) {
183            this.ignoreSecurity = ignoreSecurity;
184            return this;
185        }
186
187        @JsonSetter
188        public Builder withMaxBytes(Optional<Long> maxBytes) {
189            this.maxBytes = maxBytes;
190            return this;
191        }
192
193        public Builder withMaxBytes(long maxBytes) {
194            return withMaxBytes(Optional.of(maxBytes));
195        }
196
197        public Builder withCharset(Charset charset) {
198            this.charset = charset;
199            return this;
200        }
201
202        public Builder withEncoding(String encoding) {
203            return withCharset(Charset.forName(encoding));
204        }
205
206        public Builder post() {
207            return withRequestMethod(POST);
208        }
209
210        public Builder delete() {
211            return withRequestMethod(DELETE);
212        }
213
214        public Builder put() {
215            return withRequestMethod(PUT);
216        }
217
218        public Builder withRequestMethod(HttpMethod requestMethod) {
219            this.requestMethod = requestMethod;
220            return this;
221        }
222
223        @JsonSetter
224        public Builder withRetryCount(Optional<Integer> retries) {
225            this.retryCount = retries;
226            return this;
227        }
228
229        public Builder withRetryCount(int retries) {
230            return withRetryCount(Optional.of(retries));
231        }
232
233        public Builder withFollowRedirects(boolean followRedirects) {
234            this.followRedirects = followRedirects;
235            return this;
236        }
237
238        public Builder followRedirects() {
239            return withFollowRedirects(true);
240        }
241
242        @JsonSetter
243        public Builder withConnectTimeoutMillis(Optional<Integer> connectTimeoutMillis) {
244            this.connectTimeoutMillis = connectTimeoutMillis;
245            return this;
246        }
247
248        public Builder withConnectTimeoutMillis(int connectTimeoutMillis) {
249            return withConnectTimeoutMillis(Optional.of(connectTimeoutMillis));
250        }
251
252        @JsonSetter
253        public Builder withMaxTimeMillis(Optional<Integer> maxTimeMillis) {
254            this.maxTimeMillis = maxTimeMillis;
255            return this;
256        }
257
258        public Builder withMaxTimeMillis(int maxTimeMillis) {
259            return withMaxTimeMillis(Optional.of(maxTimeMillis));
260        }
261
262        @JsonSetter
263        public Builder withRetryDelayMillis(Optional<Integer> retryDelayMillis) {
264            this.retryDelayMillis = retryDelayMillis;
265            return this;
266        }
267
268        public Builder withRetryDelayMillis(int retryDelayMillis) {
269            return withRetryDelayMillis(Optional.of(retryDelayMillis));
270        }
271
272        @JsonSetter
273        public Builder withUpload(Optional<ByteSource> upload) {
274            this.upload = upload;
275            return this;
276        }
277
278        public Builder withUpload(ByteSource upload) {
279            return withUpload(Optional.of(upload));
280        }
281
282        public Builder upload(File file) {
283            return withUpload(asByteSource(file));
284        }
285
286        public Builder upload(String content, Charset charset) {
287            return withUpload(wrap(content.getBytes(charset)));
288        }
289
290        @Override
291        public HttpOptions build() {
292            return validate(new HttpOptions(this));
293        }
294
295    }
296
297    public Optional<Integer> getMaxTimeMillis() {
298        return maxTimeMillis;
299    }
300
301    public Optional<Integer> getConnectTimeoutMillis() {
302        return connectTimeoutMillis;
303    }
304
305    public Optional<Integer> getRetries() {
306        return retryCount;
307    }
308
309    public Optional<Integer> getRetryDelayMillis() {
310        return retryDelayMillis;
311    }
312
313    public Optional<ByteSource> getUpload() {
314        return upload;
315    }
316
317    public boolean isFollowRedirects() {
318        return followRedirects;
319    }
320
321    public HttpMethod getMethod() {
322        return requestMethod;
323    }
324
325    public Optional<Integer> getRetryCount() {
326        return retryCount;
327    }
328
329    public HttpMethod getRequestMethod() {
330        return requestMethod;
331    }
332
333    public Optional<Long> getMaxBytes() {
334        return maxBytes;
335    }
336
337    public boolean isIgnoreSecurity() {
338        return ignoreSecurity;
339    }
340
341    public boolean isSilent() {
342        return silent;
343    }
344
345    public List<NameValue> getData() {
346        return data;
347    }
348
349    public Charset getCharset() {
350        return charset;
351    }
352
353    public Range<Integer> getKeepTryingRange() {
354        return keepTryingRange;
355    }
356
357    public Optional<File> getOutputFile() {
358        return outputFile;
359    }
360
361    public boolean isCacheResponseInMemory() {
362        return cacheResponseInMemory;
363    }
364
365    public Optional<SecurityContext> getSecurity() {
366        return security;
367    }
368
369    public boolean isPrintResponseToStdout() {
370        return printResponseToStdout;
371    }
372
373    public List<HeaderPair> getHeaders() {
374        return headers;
375    }
376
377    public Optional<String> getContentType() {
378        return contentType;
379    }
380
381}