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.entity;
29  
30  import java.io.File;
31  import java.io.IOException;
32  import java.nio.ByteBuffer;
33  import java.nio.CharBuffer;
34  import java.nio.charset.Charset;
35  import java.util.ArrayList;
36  import java.util.Arrays;
37  import java.util.LinkedHashSet;
38  import java.util.List;
39  import java.util.Set;
40  
41  import org.apache.hc.core5.function.Callback;
42  import org.apache.hc.core5.http.ContentType;
43  import org.apache.hc.core5.http.Header;
44  import org.apache.hc.core5.http.NameValuePair;
45  import org.apache.hc.core5.http.nio.AsyncEntityProducer;
46  import org.apache.hc.core5.http.nio.DataStreamChannel;
47  import org.apache.hc.core5.http.nio.StreamChannel;
48  import org.apache.hc.core5.net.WWWFormCodec;
49  
50  /**
51   * {AsyncEntityProducer} factory methods.
52   *
53   * @since 5.0
54   */
55  public final class AsyncEntityProducers {
56  
57      private AsyncEntityProducers() {
58      }
59  
60      public static AsyncEntityProducer create(final String content, final ContentType contentType) {
61          return new BasicAsyncEntityProducer(content, contentType);
62      }
63  
64      public static AsyncEntityProducer create(final String content, final Charset charset) {
65          return new BasicAsyncEntityProducer(content, ContentType.TEXT_PLAIN.withCharset(charset));
66      }
67  
68      public static AsyncEntityProducer create(final String content) {
69          return new BasicAsyncEntityProducer(content, ContentType.TEXT_PLAIN);
70      }
71  
72      public static AsyncEntityProducer create(final byte[] content, final ContentType contentType) {
73          return new BasicAsyncEntityProducer(content, contentType);
74      }
75  
76      public static AsyncEntityProducer create(final File content, final ContentType contentType) {
77          return new FileEntityProducer(content, contentType);
78      }
79  
80      public static AsyncEntityProducer createUrlEncoded(
81              final Iterable <? extends NameValuePair> parameters, final Charset charset) {
82          final ContentType contentType = charset != null ?
83                  ContentType.APPLICATION_FORM_URLENCODED.withCharset(charset) :
84                  ContentType.APPLICATION_FORM_URLENCODED;
85          return create(WWWFormCodec.format(parameters, contentType.getCharset()), contentType);
86      }
87  
88      public static AsyncEntityProducer createBinary(
89              final Callback<StreamChannel<ByteBuffer>> callback,
90              final ContentType contentType) {
91          return new AbstractBinAsyncEntityProducer(0, contentType) {
92  
93              @Override
94              protected int availableData() {
95                  return Integer.MAX_VALUE;
96              }
97  
98              @Override
99              protected void produceData(final StreamChannel<ByteBuffer> channel) throws IOException {
100                 callback.execute(channel);
101             }
102 
103             @Override
104             public boolean isRepeatable() {
105                 return false;
106             }
107 
108             @Override
109             public void failed(final Exception cause) {
110             }
111 
112         };
113     }
114 
115     public static AsyncEntityProducer createText(
116             final Callback<StreamChannel<CharBuffer>> callback,
117             final ContentType contentType) {
118         return new AbstractCharAsyncEntityProducer(4096, 2048, contentType) {
119 
120             @Override
121             protected int availableData() {
122                 return Integer.MAX_VALUE;
123             }
124 
125             @Override
126             protected void produceData(final StreamChannel<CharBuffer> channel) throws IOException {
127                 callback.execute(channel);
128             }
129 
130             @Override
131             public boolean isRepeatable() {
132                 return false;
133             }
134 
135             @Override
136             public void failed(final Exception cause) {
137             }
138 
139         };
140     }
141 
142     public static AsyncEntityProducertyProducer.html#AsyncEntityProducer">AsyncEntityProducer withTrailers(final AsyncEntityProducer entity, final Header... trailers) {
143         return new AsyncEntityProducerWrapper(entity) {
144 
145             @Override
146             public boolean isChunked() {
147                 // Must be chunk coded
148                 return true;
149             }
150 
151             @Override
152             public long getContentLength() {
153                 return -1;
154             }
155 
156             @Override
157             public Set<String> getTrailerNames() {
158                 final Set<String> names = new LinkedHashSet<>();
159                 for (final Header trailer: trailers) {
160                     names.add(trailer.getName());
161                 }
162                 return names;
163             }
164 
165             @Override
166             public void produce(final DataStreamChannel channel) throws IOException {
167                 super.produce(new DataStreamChannel() {
168 
169                     @Override
170                     public void requestOutput() {
171                         channel.requestOutput();
172                     }
173 
174                     @Override
175                     public int write(final ByteBuffer src) throws IOException {
176                         return channel.write(src);
177                     }
178 
179                     @Override
180                     public void endStream(final List<? extends Header> p) throws IOException {
181                         final List<Header> allTrailers;
182                         if (p != null && !p.isEmpty()) {
183                             allTrailers = new ArrayList<>(p);
184                             allTrailers.addAll(Arrays.asList(trailers));
185                         } else {
186                             allTrailers = Arrays.asList(trailers);
187                         }
188                         channel.endStream(allTrailers);
189                     }
190 
191                     @Override
192                     public void endStream() throws IOException {
193                         channel.endStream();
194                     }
195 
196                 });
197             }
198         };
199     }
200 
201     public static AsyncEntityProducer create(final String content, final ContentType contentType, final Header... trailers) {
202         return withTrailers(create(content, contentType), trailers);
203     }
204 
205     public static AsyncEntityProducer create(final String content, final Charset charset, final Header... trailers) {
206         return withTrailers(create(content, charset), trailers);
207     }
208 
209     public static AsyncEntityProducer create(final String content, final Header... trailers) {
210         return withTrailers(create(content), trailers);
211     }
212 
213     public static AsyncEntityProducer create(final byte[] content, final ContentType contentType, final Header... trailers) {
214         return withTrailers(create(content, contentType), trailers);
215     }
216 
217     public static AsyncEntityProducer create(final File content, final ContentType contentType, final Header... trailers) {
218         return withTrailers(create(content, contentType), trailers);
219     }
220 
221     public static AsyncEntityProducer createBinary(
222             final Callback<StreamChannel<ByteBuffer>> callback,
223             final ContentType contentType,
224             final Header... trailers) {
225         return withTrailers(createBinary(callback, contentType), trailers);
226     }
227 
228     public static AsyncEntityProducer createText(
229             final Callback<StreamChannel<CharBuffer>> callback,
230             final ContentType contentType,
231             final Header... trailers) {
232         return withTrailers(createText(callback, contentType), trailers);
233     }
234 
235 }