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