1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.core5.http.nio.entity;
28
29 import java.io.IOException;
30 import java.nio.ByteBuffer;
31 import java.nio.CharBuffer;
32 import java.nio.charset.Charset;
33 import java.nio.charset.StandardCharsets;
34 import java.util.Set;
35 import java.util.concurrent.atomic.AtomicReference;
36
37 import org.apache.hc.core5.http.ContentType;
38 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
39 import org.apache.hc.core5.http.nio.DataStreamChannel;
40 import org.apache.hc.core5.util.Args;
41
42
43
44
45
46
47
48 public class BasicAsyncEntityProducer implements AsyncEntityProducer {
49
50 private final ByteBuffer bytebuf;
51 private final int length;
52 private final ContentType contentType;
53 private final boolean chunked;
54 private final AtomicReference<Exception> exception;
55
56 public BasicAsyncEntityProducer(final byte[] content, final ContentType contentType, final boolean chunked) {
57 Args.notNull(content, "Content");
58 this.bytebuf = ByteBuffer.wrap(content);
59 this.length = this.bytebuf.remaining();
60 this.contentType = contentType;
61 this.chunked = chunked;
62 this.exception = new AtomicReference<>();
63 }
64
65 public BasicAsyncEntityProducer(final byte[] content, final ContentType contentType) {
66 this(content, contentType, false);
67 }
68
69 public BasicAsyncEntityProducer(final byte[] content) {
70 this(content, ContentType.APPLICATION_OCTET_STREAM);
71 }
72
73 public BasicAsyncEntityProducer(final CharSequence content, final ContentType contentType, final boolean chunked) {
74 Args.notNull(content, "Content");
75 this.contentType = contentType;
76 final Charset charset = ContentType.getCharset(contentType, StandardCharsets.US_ASCII);
77 this.bytebuf = charset.encode(CharBuffer.wrap(content));
78 this.length = this.bytebuf.remaining();
79 this.chunked = chunked;
80 this.exception = new AtomicReference<>();
81 }
82
83 public BasicAsyncEntityProducer(final CharSequence content, final ContentType contentType) {
84 this(content, contentType, false);
85 }
86
87 public BasicAsyncEntityProducer(final CharSequence content) {
88 this(content, ContentType.TEXT_PLAIN);
89 }
90
91 @Override
92 public boolean isRepeatable() {
93 return true;
94 }
95
96 @Override
97 public final String getContentType() {
98 return contentType != null ? contentType.toString() : null;
99 }
100
101 @Override
102 public long getContentLength() {
103 return length;
104 }
105
106 @Override
107 public int available() {
108 return Integer.MAX_VALUE;
109 }
110
111 @Override
112 public String getContentEncoding() {
113 return null;
114 }
115
116 @Override
117 public boolean isChunked() {
118 return chunked;
119 }
120
121 @Override
122 public Set<String> getTrailerNames() {
123 return null;
124 }
125
126 @Override
127 public final void produce(final DataStreamChannel channel) throws IOException {
128 if (bytebuf.hasRemaining()) {
129 channel.write(bytebuf);
130 }
131 if (!bytebuf.hasRemaining()) {
132 channel.endStream();
133 }
134 }
135
136 @Override
137 public final void failed(final Exception cause) {
138 if (exception.compareAndSet(null, cause)) {
139 releaseResources();
140 }
141 }
142
143 public final Exception getException() {
144 return exception.get();
145 }
146
147 @Override
148 public void releaseResources() {
149 bytebuf.clear();
150 }
151
152 }