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