1 package com.atlassian.httpclient.apache.httpcomponents;
2
3 import com.atlassian.fugue.Option;
4 import com.atlassian.httpclient.api.Response;
5 import com.google.common.base.Function;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8
9 import java.io.InputStream;
10 import java.util.Map;
11
12 public final class DefaultResponse extends DefaultMessage implements Response {
13 private int statusCode;
14 private String statusText;
15 private Logger log = LoggerFactory.getLogger(DefaultResponse.class);
16
17 public DefaultResponse(Headers headers, InputStream entityStream, Option<Long> maxEntitySize, int statusCode, String statusText) {
18 super(headers, entityStream, maxEntitySize);
19 this.statusCode = statusCode;
20 this.statusText = statusText;
21 }
22
23 public static DefaultResponseBuilder builder() {
24 return new DefaultResponseBuilder();
25 }
26
27 @Override
28 public int getStatusCode() {
29 return statusCode;
30 }
31
32 @Override
33 public String getStatusText() {
34 return statusText;
35 }
36
37 @Override
38 public boolean isInformational() {
39 return statusCode >= 100 && statusCode < 200;
40 }
41
42 @Override
43 public boolean isSuccessful() {
44 return statusCode >= 200 && statusCode < 300;
45 }
46
47 @Override
48 public boolean isOk() {
49 return statusCode == 200;
50 }
51
52 @Override
53 public boolean isCreated() {
54 return statusCode == 201;
55 }
56
57 @Override
58 public boolean isNoContent() {
59 return statusCode == 204;
60 }
61
62 @Override
63 public boolean isRedirection() {
64 return statusCode >= 300 && statusCode < 400;
65 }
66
67 @Override
68 public boolean isSeeOther() {
69 return statusCode == 303;
70 }
71
72 @Override
73 public boolean isNotModified() {
74 return statusCode == 304;
75 }
76
77 @Override
78 public boolean isClientError() {
79 return statusCode >= 400 && statusCode < 500;
80 }
81
82 @Override
83 public boolean isBadRequest() {
84 return statusCode == 400;
85 }
86
87 @Override
88 public boolean isUnauthorized() {
89 return statusCode == 401;
90 }
91
92 @Override
93 public boolean isForbidden() {
94 return statusCode == 403;
95 }
96
97 @Override
98 public boolean isNotFound() {
99 return statusCode == 404;
100 }
101
102 @Override
103 public boolean isConflict() {
104 return statusCode == 409;
105 }
106
107 @Override
108 public boolean isServerError() {
109 return statusCode >= 500 && statusCode < 600;
110 }
111
112 @Override
113 public boolean isInternalServerError() {
114 return statusCode == 500;
115 }
116
117 @Override
118 public boolean isServiceUnavailable() {
119 return statusCode == 503;
120 }
121
122 @Override
123 public boolean isError() {
124 return isClientError() || isServerError();
125 }
126
127 @Override
128 public boolean isNotSuccessful() {
129 return isInformational() || isRedirection() || isError();
130 }
131
132 @Override
133 public Option<Long> getContentLength() {
134 String lengthString = getHeader(Headers.Names.CONTENT_LENGTH);
135 if (lengthString != null) {
136 try {
137 Option<Long> parsedLength = Option.some(Long.parseLong(lengthString));
138 return parsedLength.flatMap(
139 new Function<Long, Option<Long>>() {
140 @Override
141 public Option<Long> apply(Long aLong) {
142 if (aLong < 0) {
143 log.warn("Unable to parse content length. Received out of range value {}", aLong);
144 return Option.none();
145 } else {
146 return Option.some(aLong);
147 }
148 }
149 });
150 } catch (NumberFormatException e) {
151 log.warn("Unable to parse content length {}", lengthString);
152 return Option.none();
153 }
154 } else {
155 return Option.none();
156 }
157 }
158
159 public static class DefaultResponseBuilder implements Builder {
160 private final CommonBuilder<DefaultResponse> commonBuilder;
161
162 private String statusText;
163 private int statusCode;
164 private long maxEntitySize;
165
166 private DefaultResponseBuilder() {
167 this.commonBuilder = new CommonBuilder<DefaultResponse>();
168 }
169
170 @Override
171 public DefaultResponseBuilder setContentType(final String contentType) {
172 commonBuilder.setContentType(contentType);
173 return this;
174 }
175
176 @Override
177 public DefaultResponseBuilder setContentCharset(final String contentCharset) {
178 commonBuilder.setContentCharset(contentCharset);
179 return this;
180 }
181
182 @Override
183 public DefaultResponseBuilder setHeaders(final Map<String, String> headers) {
184 commonBuilder.setHeaders(headers);
185 return this;
186 }
187
188 @Override
189 public DefaultResponseBuilder setHeader(final String name, final String value) {
190 commonBuilder.setHeader(name, value);
191 return this;
192 }
193
194 @Override
195 public DefaultResponseBuilder setEntity(final String entity) {
196 commonBuilder.setEntity(entity);
197 return this;
198 }
199
200 @Override
201 public DefaultResponseBuilder setEntityStream(final InputStream entityStream, final String encoding) {
202 commonBuilder.setEntityStream(entityStream);
203 commonBuilder.setContentCharset(encoding);
204 return this;
205 }
206
207 @Override
208 public DefaultResponseBuilder setEntityStream(final InputStream entityStream) {
209 commonBuilder.setEntityStream(entityStream);
210 return this;
211 }
212
213 @Override
214 public DefaultResponseBuilder setStatusText(final String statusText) {
215 this.statusText = statusText;
216 return this;
217 }
218
219 @Override
220 public DefaultResponseBuilder setStatusCode(final int statusCode) {
221 this.statusCode = statusCode;
222 return this;
223 }
224
225 public DefaultResponseBuilder setMaxEntitySize(long maxEntitySize) {
226 this.maxEntitySize = maxEntitySize;
227 return this;
228 }
229
230 @Override
231 public DefaultResponse build() {
232 return new DefaultResponse(commonBuilder.getHeaders(), commonBuilder.getEntityStream(),
233 Option.option(maxEntitySize), statusCode, statusText);
234 }
235 }
236 }