1 package com.atlassian.httpclient.apache.httpcomponents;
2
3 import com.atlassian.fugue.Option;
4 import com.atlassian.httpclient.api.EntityBuilder;
5 import com.atlassian.httpclient.api.HttpClient;
6 import com.atlassian.httpclient.api.Request;
7 import com.atlassian.httpclient.api.ResponsePromise;
8 import com.google.common.base.Preconditions;
9
10 import java.io.InputStream;
11 import java.net.URI;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.Map;
15
16 import static com.atlassian.httpclient.api.Request.Method.DELETE;
17 import static com.atlassian.httpclient.api.Request.Method.GET;
18 import static com.atlassian.httpclient.api.Request.Method.HEAD;
19 import static com.atlassian.httpclient.api.Request.Method.OPTIONS;
20 import static com.atlassian.httpclient.api.Request.Method.POST;
21 import static com.atlassian.httpclient.api.Request.Method.PUT;
22 import static com.atlassian.httpclient.api.Request.Method.TRACE;
23 import static com.google.common.base.Preconditions.checkNotNull;
24
25 public class DefaultRequest extends DefaultMessage implements Request {
26 private final URI uri;
27 private final boolean cacheDisabled;
28 private final Map<String, String> attributes;
29 private final Method method;
30 private final Option<Long> contentLength;
31
32 private DefaultRequest(URI uri, boolean cacheDisabled, Map<String, String> attributes,
33 Headers headers, Method method, InputStream entityStream, Option<Long> contentLength) {
34 super(headers, entityStream, Option.<Long>none());
35 this.uri = uri;
36 this.cacheDisabled = cacheDisabled;
37 this.attributes = attributes;
38 this.method = method;
39 this.contentLength = contentLength;
40 }
41
42 public static DefaultRequestBuilder builder(HttpClient httpClient) {
43 return new DefaultRequestBuilder(httpClient);
44 }
45
46 @Override
47 public Method getMethod() {
48 return method;
49 }
50
51 @Override
52 public URI getUri() {
53 return uri;
54 }
55
56 @Override
57 public String getAccept() {
58 return super.getAccept();
59 }
60
61 @Override
62 public String getAttribute(String name) {
63 return attributes.get(name);
64 }
65
66 @Override
67 public Map<String, String> getAttributes() {
68 return Collections.unmodifiableMap(attributes);
69 }
70
71 @Override
72 public Option<Long> getContentLength() {
73 return contentLength;
74 }
75
76 public boolean isCacheDisabled() {
77 return cacheDisabled;
78 }
79
80 public Request validate() {
81 super.validate();
82
83 checkNotNull(uri);
84 checkNotNull(method);
85
86 switch (method) {
87 case GET:
88 case DELETE:
89 case HEAD:
90 if (hasEntity()) {
91 throw new IllegalStateException("Request method " + method + " does not support an entity");
92 }
93 break;
94 case POST:
95 case PUT:
96 case TRACE:
97
98 break;
99 }
100 return this;
101 }
102
103 public static class DefaultRequestBuilder implements Request.Builder {
104 private final HttpClient httpClient;
105 private final Map<String, String> attributes;
106 private final CommonBuilder<DefaultRequest> commonBuilder;
107
108 private URI uri;
109 private boolean cacheDisabled;
110 private Method method;
111 private Option<Long> contentLength;
112
113 public DefaultRequestBuilder(final HttpClient httpClient) {
114 this.httpClient = httpClient;
115 this.attributes = new HashMap<String, String>();
116 commonBuilder = new CommonBuilder<DefaultRequest>();
117 setAccept("*/*");
118 contentLength = Option.none();
119 }
120
121 @Override
122 public DefaultRequestBuilder setUri(final URI uri) {
123 this.uri = uri;
124 return this;
125 }
126
127 @Override
128 public DefaultRequestBuilder setAccept(final String accept) {
129 setHeader("Accept", accept);
130 return this;
131 }
132
133 @Override
134 public DefaultRequestBuilder setCacheDisabled() {
135 this.cacheDisabled = true;
136 return this;
137 }
138
139 @Override
140 public DefaultRequestBuilder setAttribute(final String name, final String value) {
141 attributes.put(name, value);
142 return this;
143 }
144
145 @Override
146 public DefaultRequestBuilder setAttributes(final Map<String, String> properties) {
147 attributes.putAll(properties);
148 return this;
149 }
150
151 @Override
152 public DefaultRequestBuilder setEntity(final EntityBuilder entityBuilder) {
153 EntityBuilder.Entity entity = entityBuilder.build();
154 final Map<String, String> headers = entity.getHeaders();
155 for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
156 setHeader(headerEntry.getKey(), headerEntry.getValue());
157 }
158 setEntityStream(entity.getInputStream());
159 return this;
160 }
161
162 @Override
163 public DefaultRequestBuilder setHeader(final String name, final String value) {
164 commonBuilder.setHeader(name, value);
165 return this;
166 }
167
168 @Override
169 public DefaultRequestBuilder setHeaders(final Map<String, String> headers) {
170 commonBuilder.setHeaders(headers);
171 return this;
172 }
173
174 @Override
175 public DefaultRequestBuilder setEntity(final String entity) {
176 commonBuilder.setEntity(entity);
177 setContentLength(entity.length());
178 return this;
179 }
180
181 @Override
182 public DefaultRequestBuilder setEntityStream(final InputStream entityStream) {
183 commonBuilder.setEntityStream(entityStream);
184 return this;
185 }
186
187 @Override
188 public DefaultRequestBuilder setContentCharset(final String contentCharset) {
189 commonBuilder.setContentCharset(contentCharset);
190 return this;
191 }
192
193 @Override
194 public DefaultRequestBuilder setContentType(final String contentType) {
195 commonBuilder.setContentType(contentType);
196 return this;
197 }
198
199 @Override
200 public DefaultRequestBuilder setEntityStream(final InputStream entityStream, final String charset) {
201 setEntityStream(entityStream);
202 commonBuilder.setContentCharset(charset);
203 return this;
204 }
205
206 @Override
207 public DefaultRequestBuilder setContentLength(final long contentLength) {
208 Preconditions.checkArgument(contentLength >= 0, "Content length must be greater than or equal to 0");
209 this.contentLength = Option.some(contentLength);
210 return this;
211 }
212
213 @Override
214 public DefaultRequest build() {
215 return new DefaultRequest(uri, cacheDisabled, attributes, commonBuilder.getHeaders(),
216 method, commonBuilder.getEntityStream(), contentLength);
217 }
218
219 @Override
220 public ResponsePromise get() {
221 return execute(GET);
222 }
223
224 @Override
225 public ResponsePromise post() {
226 return execute(POST);
227 }
228
229 @Override
230 public ResponsePromise put() {
231 return execute(PUT);
232 }
233
234 @Override
235 public ResponsePromise delete() {
236 return execute(DELETE);
237 }
238
239 @Override
240 public ResponsePromise options() {
241 return execute(OPTIONS);
242 }
243
244 @Override
245 public ResponsePromise head() {
246 return execute(HEAD);
247 }
248
249 @Override
250 public ResponsePromise trace() {
251 return execute(TRACE);
252 }
253
254 @Override
255 public ResponsePromise execute(Method method) {
256 checkNotNull(method, "HTTP method must not be null");
257 setMethod(method);
258 return httpClient.execute(build().validate());
259 }
260
261 public void setMethod(final Method method) {
262 this.method = method;
263 }
264 }
265 }