View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.http.nio.support;
29  
30  import java.net.URI;
31  import java.net.URISyntaxException;
32  import java.nio.charset.Charset;
33  import java.util.Arrays;
34  import java.util.List;
35  
36  import org.apache.hc.core5.http.ContentType;
37  import org.apache.hc.core5.http.Header;
38  import org.apache.hc.core5.http.HttpHost;
39  import org.apache.hc.core5.http.Method;
40  import org.apache.hc.core5.http.NameValuePair;
41  import org.apache.hc.core5.http.ProtocolVersion;
42  import org.apache.hc.core5.http.message.BasicHttpRequest;
43  import org.apache.hc.core5.http.nio.AsyncEntityProducer;
44  import org.apache.hc.core5.http.nio.AsyncRequestProducer;
45  import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
46  import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
47  import org.apache.hc.core5.http.support.AbstractRequestBuilder;
48  import org.apache.hc.core5.net.URIAuthority;
49  import org.apache.hc.core5.net.URIBuilder;
50  import org.apache.hc.core5.net.WWWFormCodec;
51  import org.apache.hc.core5.util.Args;
52  import org.apache.hc.core5.util.TextUtils;
53  
54  /**
55   * Builder for {@link AsyncRequestProducer} instances.
56   * <p>
57   * Please note that this class treats parameters differently depending on composition
58   * of the request: if the request has a content entity explicitly set with
59   * {@link #setEntity(AsyncEntityProducer)} or it is not an entity enclosing method
60   * (such as POST or PUT), parameters will be added to the query component of the request URI.
61   * Otherwise, parameters will be added as a URL encoded entity.
62   * </p>
63   *
64   * @since 5.0
65   */
66  public class AsyncRequestBuilder extends AbstractRequestBuilder<AsyncRequestProducer> {
67  
68      private AsyncEntityProducer entityProducer;
69  
70      AsyncRequestBuilder(final String method) {
71          super(method);
72      }
73  
74      AsyncRequestBuilder(final Method method) {
75          super(method);
76      }
77  
78      AsyncRequestBuilder(final String method, final URI uri) {
79          super(method, uri);
80      }
81  
82      AsyncRequestBuilder(final Method method, final URI uri) {
83          this(method.name(), uri);
84      }
85  
86      AsyncRequestBuilder(final Method method, final String uri) {
87          this(method.name(), uri != null ? URI.create(uri) : null);
88      }
89  
90      AsyncRequestBuilder(final String method, final String uri) {
91          this(method, uri != null ? URI.create(uri) : null);
92      }
93  
94      public static AsyncRequestBuilder create(final String method) {
95          Args.notBlank(method, "HTTP method");
96          return new AsyncRequestBuilder(method);
97      }
98  
99      public static AsyncRequestBuilder get() {
100         return new AsyncRequestBuilder(Method.GET);
101     }
102 
103     public static AsyncRequestBuilder get(final URI uri) {
104         return new AsyncRequestBuilder(Method.GET, uri);
105     }
106 
107     public static AsyncRequestBuilder get(final String uri) {
108         return new AsyncRequestBuilder(Method.GET, uri);
109     }
110 
111     public static AsyncRequestBuilder head() {
112         return new AsyncRequestBuilder(Method.HEAD);
113     }
114 
115     public static AsyncRequestBuilder head(final URI uri) {
116         return new AsyncRequestBuilder(Method.HEAD, uri);
117     }
118 
119     public static AsyncRequestBuilder head(final String uri) {
120         return new AsyncRequestBuilder(Method.HEAD, uri);
121     }
122 
123     public static AsyncRequestBuilder patch() {
124         return new AsyncRequestBuilder(Method.PATCH);
125     }
126 
127     public static AsyncRequestBuilder patch(final URI uri) {
128         return new AsyncRequestBuilder(Method.PATCH, uri);
129     }
130 
131     public static AsyncRequestBuilder patch(final String uri) {
132         return new AsyncRequestBuilder(Method.PATCH, uri);
133     }
134 
135     public static AsyncRequestBuilder post() {
136         return new AsyncRequestBuilder(Method.POST);
137     }
138 
139     public static AsyncRequestBuilder post(final URI uri) {
140         return new AsyncRequestBuilder(Method.POST, uri);
141     }
142 
143     public static AsyncRequestBuilder post(final String uri) {
144         return new AsyncRequestBuilder(Method.POST, uri);
145     }
146 
147     public static AsyncRequestBuilder put() {
148         return new AsyncRequestBuilder(Method.PUT);
149     }
150 
151     public static AsyncRequestBuilder put(final URI uri) {
152         return new AsyncRequestBuilder(Method.PUT, uri);
153     }
154 
155     public static AsyncRequestBuilder put(final String uri) {
156         return new AsyncRequestBuilder(Method.PUT, uri);
157     }
158 
159     public static AsyncRequestBuilder delete() {
160         return new AsyncRequestBuilder(Method.DELETE);
161     }
162 
163     public static AsyncRequestBuilder delete(final URI uri) {
164         return new AsyncRequestBuilder(Method.DELETE, uri);
165     }
166 
167     public static AsyncRequestBuilder delete(final String uri) {
168         return new AsyncRequestBuilder(Method.DELETE, uri);
169     }
170 
171     public static AsyncRequestBuilder trace() {
172         return new AsyncRequestBuilder(Method.TRACE);
173     }
174 
175     public static AsyncRequestBuilder trace(final URI uri) {
176         return new AsyncRequestBuilder(Method.TRACE, uri);
177     }
178 
179     public static AsyncRequestBuilder trace(final String uri) {
180         return new AsyncRequestBuilder(Method.TRACE, uri);
181     }
182 
183     public static AsyncRequestBuilder options() {
184         return new AsyncRequestBuilder(Method.OPTIONS);
185     }
186 
187     public static AsyncRequestBuilder options(final URI uri) {
188         return new AsyncRequestBuilder(Method.OPTIONS, uri);
189     }
190 
191     public static AsyncRequestBuilder options(final String uri) {
192         return new AsyncRequestBuilder(Method.OPTIONS, uri);
193     }
194 
195     @Override
196     public AsyncRequestBuilder setVersion(final ProtocolVersion version) {
197         super.setVersion(version);
198         return this;
199     }
200 
201     @Override
202     public AsyncRequestBuilder setUri(final URI uri) {
203         super.setUri(uri);
204         return this;
205     }
206 
207     @Override
208     public AsyncRequestBuilder setUri(final String uri) {
209         super.setUri(uri);
210         return this;
211     }
212 
213     @Override
214     public AsyncRequestBuilder setScheme(final String scheme) {
215         super.setScheme(scheme);
216         return this;
217     }
218 
219     @Override
220     public AsyncRequestBuilder setAuthority(final URIAuthority authority) {
221         super.setAuthority(authority);
222         return this;
223     }
224 
225     /**
226      * @since 5.1
227      */
228     @Override
229     public AsyncRequestBuilder setHttpHost(final HttpHost httpHost) {
230         super.setHttpHost(httpHost);
231         return this;
232     }
233 
234     @Override
235     public AsyncRequestBuilder setPath(final String path) {
236         super.setPath(path);
237         return this;
238     }
239 
240     @Override
241     public AsyncRequestBuilder setHeaders(final Header... headers) {
242         super.setHeaders(headers);
243         return this;
244     }
245 
246     @Override
247     public AsyncRequestBuilder addHeader(final Header header) {
248         super.addHeader(header);
249         return this;
250     }
251 
252     @Override
253     public AsyncRequestBuilder addHeader(final String name, final String value) {
254         super.addHeader(name, value);
255         return this;
256     }
257 
258     @Override
259     public AsyncRequestBuilder removeHeader(final Header header) {
260         super.removeHeader(header);
261         return this;
262     }
263 
264     @Override
265     public AsyncRequestBuilder removeHeaders(final String name) {
266         super.removeHeaders(name);
267         return this;
268     }
269 
270     @Override
271     public AsyncRequestBuilder setHeader(final Header header) {
272         super.setHeader(header);
273         return this;
274     }
275 
276     @Override
277     public AsyncRequestBuilder setHeader(final String name, final String value) {
278         super.setHeader(name, value);
279         return this;
280     }
281 
282     @Override
283     public AsyncRequestBuilder setCharset(final Charset charset) {
284         super.setCharset(charset);
285         return this;
286     }
287 
288     @Override
289     public AsyncRequestBuilder addParameter(final NameValuePair nvp) {
290         super.addParameter(nvp);
291         return this;
292     }
293 
294     @Override
295     public AsyncRequestBuilder addParameter(final String name, final String value) {
296         super.addParameter(name, value);
297         return this;
298     }
299 
300     @Override
301     public AsyncRequestBuilder addParameters(final NameValuePair... nvps) {
302         super.addParameters(nvps);
303         return this;
304     }
305 
306     @Override
307     public AsyncRequestBuilder setAbsoluteRequestUri(final boolean absoluteRequestUri) {
308         super.setAbsoluteRequestUri(absoluteRequestUri);
309         return this;
310     }
311 
312     public AsyncEntityProducer getEntity() {
313         return entityProducer;
314     }
315 
316     public AsyncRequestBuilder setEntity(final AsyncEntityProducer entityProducer) {
317         this.entityProducer = entityProducer;
318         return this;
319     }
320 
321     public AsyncRequestBuilder setEntity(final String content, final ContentType contentType) {
322         this.entityProducer = new BasicAsyncEntityProducer(content, contentType);
323         return this;
324     }
325 
326     public AsyncRequestBuilder setEntity(final String content) {
327         this.entityProducer = new BasicAsyncEntityProducer(content);
328         return this;
329     }
330 
331     public AsyncRequestBuilder setEntity(final byte[] content, final ContentType contentType) {
332         this.entityProducer = new BasicAsyncEntityProducer(content, contentType);
333         return this;
334     }
335 
336     public AsyncRequestProducer build() {
337         String path = getPath();
338         if (TextUtils.isEmpty(path)) {
339             path = "/";
340         }
341         AsyncEntityProducer entityProducerCopy = entityProducer;
342         final String method = getMethod();
343         final List<NameValuePair> parameters = getParameters();
344         if (parameters != null && !parameters.isEmpty()) {
345             final Charset charset = getCharset();
346             if (entityProducerCopy == null && (Method.POST.isSame(method) || Method.PUT.isSame(method))) {
347                 final String content = WWWFormCodec.format(
348                         parameters,
349                         charset != null ? charset : ContentType.APPLICATION_FORM_URLENCODED.getCharset());
350                 entityProducerCopy = new StringAsyncEntityProducer(
351                         content,
352                         ContentType.APPLICATION_FORM_URLENCODED);
353             } else {
354                 try {
355                     final URI uri = new URIBuilder(path)
356                             .setCharset(charset)
357                             .addParameters(parameters)
358                             .build();
359                     path = uri.toASCIIString();
360                 } catch (final URISyntaxException ex) {
361                     // should never happen
362                 }
363             }
364         }
365 
366         if (entityProducerCopy != null && Method.TRACE.isSame(method)) {
367             throw new IllegalStateException(Method.TRACE + " requests may not include an entity");
368         }
369 
370         final BasicHttpRequestge/BasicHttpRequest.html#BasicHttpRequest">BasicHttpRequest request = new BasicHttpRequest(method, getScheme(), getAuthority(), path);
371         request.setVersion(getVersion());
372         request.setHeaders(getHeaders());
373         request.setAbsoluteRequestUri(isAbsoluteRequestUri());
374         return new BasicRequestProducer(request, entityProducerCopy);
375     }
376 
377     @Override
378     public String toString() {
379         final StringBuilder builder = new StringBuilder();
380         builder.append("AsyncRequestBuilder [method=");
381         builder.append(getMethod());
382         builder.append(", scheme=");
383         builder.append(getScheme());
384         builder.append(", authority=");
385         builder.append(getAuthority());
386         builder.append(", path=");
387         builder.append(getPath());
388         builder.append(", parameters=");
389         builder.append(getParameters());
390         builder.append(", headerGroup=");
391         builder.append(Arrays.toString(getHeaders()));
392         builder.append(", entity=");
393         builder.append(entityProducer != null ? entityProducer.getClass() : null);
394         builder.append("]");
395         return builder.toString();
396     }
397 
398 }