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.http.client.entity;
29  
30  import java.io.File;
31  import java.io.InputStream;
32  import java.io.Serializable;
33  import java.util.Arrays;
34  import java.util.List;
35  
36  import org.apache.http.HttpEntity;
37  import org.apache.http.NameValuePair;
38  import org.apache.http.annotation.NotThreadSafe;
39  import org.apache.http.entity.AbstractHttpEntity;
40  import org.apache.http.entity.BasicHttpEntity;
41  import org.apache.http.entity.ByteArrayEntity;
42  import org.apache.http.entity.ContentType;
43  import org.apache.http.entity.FileEntity;
44  import org.apache.http.entity.InputStreamEntity;
45  import org.apache.http.entity.SerializableEntity;
46  import org.apache.http.entity.StringEntity;
47  
48  /**
49   * Builder for {@link HttpEntity} instances.
50   * <p>
51   * Several setter methods of this builder are mutually exclusive. In case of multiple invocations
52   * of the following methods only the last one will have effect:
53   * </p>
54   * <ul>
55   *   <li>{@link #setText(String)}</li>
56   *   <li>{@link #setBinary(byte[])}</li>
57   *   <li>{@link #setStream(java.io.InputStream)}</li>
58   *   <li>{@link #setSerializable(java.io.Serializable)}</li>
59   *   <li>{@link #setParameters(java.util.List)}</li>
60   *   <li>{@link #setParameters(org.apache.http.NameValuePair...)}</li>
61   *   <li>{@link #setFile(java.io.File)}</li>
62   * </ul>
63   *
64   * @since 4.3
65   */
66  @NotThreadSafe
67  public class EntityBuilder {
68  
69      private String text;
70      private byte[] binary;
71      private InputStream stream;
72      private List<NameValuePair> parameters;
73      private Serializable serializable;
74      private File file;
75      private ContentType contentType;
76      private String contentEncoding;
77      private boolean chunked;
78      private boolean gzipCompress;
79  
80      EntityBuilder() {
81          super();
82      }
83  
84      public static EntityBuilder create() {
85          return new EntityBuilder();
86      }
87  
88      private void clearContent() {
89          this.text = null;
90          this.binary = null;
91          this.stream = null;
92          this.parameters = null;
93          this.serializable = null;
94          this.file = null;
95      }
96  
97      /**
98       * Returns entity content as a string if set using {@link #setText(String)} method.
99       */
100     public String getText() {
101         return text;
102     }
103 
104     /**
105      * Sets entity content as a string. This method is mutually exclusive with
106      * {@link #setBinary(byte[])},
107      * {@link #setStream(java.io.InputStream)} ,
108      * {@link #setSerializable(java.io.Serializable)} ,
109      * {@link #setParameters(java.util.List)},
110      * {@link #setParameters(org.apache.http.NameValuePair...)}
111      * {@link #setFile(java.io.File)} methods.
112      */
113     public EntityBuilder setText(final String text) {
114         clearContent();
115         this.text = text;
116         return this;
117     }
118 
119     /**
120      * Returns entity content as a byte array if set using
121      * {@link #setBinary(byte[])} method.
122      */
123     public byte[] getBinary() {
124         return binary;
125     }
126 
127     /**
128      * Sets entity content as a byte array. This method is mutually exclusive with
129      * {@link #setText(String)},
130      * {@link #setStream(java.io.InputStream)} ,
131      * {@link #setSerializable(java.io.Serializable)} ,
132      * {@link #setParameters(java.util.List)},
133      * {@link #setParameters(org.apache.http.NameValuePair...)}
134      * {@link #setFile(java.io.File)} methods.
135      */
136     public EntityBuilder setBinary(final byte[] binary) {
137         clearContent();
138         this.binary = binary;
139         return this;
140     }
141 
142     /**
143      * Returns entity content as a {@link InputStream} if set using
144      * {@link #setStream(java.io.InputStream)} method.
145      */
146     public InputStream getStream() {
147         return stream;
148     }
149 
150     /**
151      * Sets entity content as a {@link InputStream}. This method is mutually exclusive with
152      * {@link #setText(String)},
153      * {@link #setBinary(byte[])},
154      * {@link #setSerializable(java.io.Serializable)} ,
155      * {@link #setParameters(java.util.List)},
156      * {@link #setParameters(org.apache.http.NameValuePair...)}
157      * {@link #setFile(java.io.File)} methods.
158      */
159     public EntityBuilder setStream(final InputStream stream) {
160         clearContent();
161         this.stream = stream;
162         return this;
163     }
164 
165     /**
166      * Returns entity content as a parameter list if set using
167      * {@link #setParameters(java.util.List)} or
168      * {@link #setParameters(org.apache.http.NameValuePair...)} methods.
169      */
170     public List<NameValuePair> getParameters() {
171         return parameters;
172     }
173 
174     /**
175      * Sets entity content as a parameter list. This method is mutually exclusive with
176      * {@link #setText(String)},
177      * {@link #setBinary(byte[])},
178      * {@link #setStream(java.io.InputStream)} ,
179      * {@link #setSerializable(java.io.Serializable)} ,
180      * {@link #setFile(java.io.File)} methods.
181      */
182     public EntityBuilder setParameters(final List<NameValuePair> parameters) {
183         clearContent();
184         this.parameters = parameters;
185         return this;
186     }
187 
188     /**
189      * Sets entity content as a parameter list. This method is mutually exclusive with
190      * {@link #setText(String)},
191      * {@link #setBinary(byte[])},
192      * {@link #setStream(java.io.InputStream)} ,
193      * {@link #setSerializable(java.io.Serializable)} ,
194      * {@link #setFile(java.io.File)} methods.
195      */
196     public EntityBuilder setParameters(final NameValuePair... parameters) {
197         return setParameters(Arrays.asList(parameters));
198     }
199 
200     /**
201      * Returns entity content as a {@link Serializable} if set using
202      * {@link #setSerializable(java.io.Serializable)} method.
203      */
204     public Serializable getSerializable() {
205         return serializable;
206     }
207 
208     /**
209      * Sets entity content as a {@link Serializable}. This method is mutually exclusive with
210      * {@link #setText(String)},
211      * {@link #setBinary(byte[])},
212      * {@link #setStream(java.io.InputStream)} ,
213      * {@link #setParameters(java.util.List)},
214      * {@link #setParameters(org.apache.http.NameValuePair...)}
215      * {@link #setFile(java.io.File)} methods.
216      */
217     public EntityBuilder setSerializable(final Serializable serializable) {
218         clearContent();
219         this.serializable = serializable;
220         return this;
221     }
222 
223     /**
224      * Returns entity content as a {@link File} if set using
225      * {@link #setFile(java.io.File)} method.
226      */
227     public File getFile() {
228         return file;
229     }
230 
231     /**
232      * Sets entity content as a {@link File}. This method is mutually exclusive with
233      * {@link #setText(String)},
234      * {@link #setBinary(byte[])},
235      * {@link #setStream(java.io.InputStream)} ,
236      * {@link #setParameters(java.util.List)},
237      * {@link #setParameters(org.apache.http.NameValuePair...)}
238      * {@link #setSerializable(java.io.Serializable)} methods.
239      */
240     public EntityBuilder setFile(final File file) {
241         clearContent();
242         this.file = file;
243         return this;
244     }
245 
246     /**
247      * Returns {@link ContentType} of the entity, if set.
248      */
249     public ContentType getContentType() {
250         return contentType;
251     }
252 
253     /**
254      * Sets {@link ContentType} of the entity.
255      */
256     public EntityBuilder setContentType(final ContentType contentType) {
257         this.contentType = contentType;
258         return this;
259     }
260 
261     /**
262      * Returns content encoding of the entity, if set.
263      */
264     public String getContentEncoding() {
265         return contentEncoding;
266     }
267 
268     /**
269      * Sets content encoding of the entity.
270      */
271     public EntityBuilder setContentEncoding(final String contentEncoding) {
272         this.contentEncoding = contentEncoding;
273         return this;
274     }
275 
276     /**
277      * Returns {@code true} if entity is to be chunk coded, {@code false} otherwise.
278      */
279     public boolean isChunked() {
280         return chunked;
281     }
282 
283     /**
284      * Makes entity chunk coded.
285      */
286     public EntityBuilder chunked() {
287         this.chunked = true;
288         return this;
289     }
290 
291     /**
292      * Returns {@code true} if entity is to be GZIP compressed, {@code false} otherwise.
293      */
294     public boolean isGzipCompress() {
295         return gzipCompress;
296     }
297 
298     /**
299      * Makes entity GZIP compressed.
300      */
301     public EntityBuilder gzipCompress() {
302         this.gzipCompress = true;
303         return this;
304     }
305 
306     private ContentType getContentOrDefault(final ContentType def) {
307         return this.contentType != null ? this.contentType : def;
308     }
309 
310     /**
311      * Creates new instance of {@link HttpEntity} based on the current state.
312      */
313     public HttpEntity build() {
314         final AbstractHttpEntity e;
315         if (this.text != null) {
316             e = new StringEntity(this.text, getContentOrDefault(ContentType.DEFAULT_TEXT));
317         } else if (this.binary != null) {
318             e = new ByteArrayEntity(this.binary, getContentOrDefault(ContentType.DEFAULT_BINARY));
319         } else if (this.stream != null) {
320             e = new InputStreamEntity(this.stream, 1, getContentOrDefault(ContentType.DEFAULT_BINARY));
321         } else if (this.parameters != null) {
322             e = new UrlEncodedFormEntity(this.parameters,
323                     this.contentType != null ? this.contentType.getCharset() : null);
324         } else if (this.serializable != null) {
325             e = new SerializableEntity(this.serializable);
326             e.setContentType(ContentType.DEFAULT_BINARY.toString());
327         } else if (this.file != null) {
328             e = new FileEntity(this.file, getContentOrDefault(ContentType.DEFAULT_BINARY));
329         } else {
330             e = new BasicHttpEntity();
331         }
332         if (e.getContentType() != null && this.contentType != null) {
333             e.setContentType(this.contentType.toString());
334         }
335         e.setContentEncoding(this.contentEncoding);
336         e.setChunked(this.chunked);
337         if (this.gzipCompress) {
338             return new GzipCompressingEntity(e);
339         }
340         return e;
341     }
342 
343 }