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 Charset charset = contentType != null ? contentType.getCharset() : null;
77 if (charset == null) {
78 charset = StandardCharsets.US_ASCII;
79 }
80 this.bytebuf = charset.encode(CharBuffer.wrap(content));
81 this.length = this.bytebuf.remaining();
82 this.chunked = chunked;
83 this.exception = new AtomicReference<>();
84 }
85
86 public BasicAsyncEntityProducer(final CharSequence content, final ContentType contentType) {
87 this(content, contentType, false);
88 }
89
90 public BasicAsyncEntityProducer(final CharSequence content) {
91 this(content, ContentType.TEXT_PLAIN);
92 }
93
94 @Override
95 public boolean isRepeatable() {
96 return true;
97 }
98
99 @Override
100 public final String getContentType() {
101 return contentType != null ? contentType.toString() : null;
102 }
103
104 @Override
105 public long getContentLength() {
106 return length;
107 }
108
109 @Override
110 public int available() {
111 return Integer.MAX_VALUE;
112 }
113
114 @Override
115 public String getContentEncoding() {
116 return null;
117 }
118
119 @Override
120 public boolean isChunked() {
121 return chunked;
122 }
123
124 @Override
125 public Set<String> getTrailerNames() {
126 return null;
127 }
128
129 @Override
130 public final void produce(final DataStreamChannel channel) throws IOException {
131 if (bytebuf.hasRemaining()) {
132 channel.write(bytebuf);
133 }
134 if (!bytebuf.hasRemaining()) {
135 channel.endStream();
136 }
137 }
138
139 @Override
140 public final void failed(final Exception cause) {
141 if (exception.compareAndSet(null, cause)) {
142 releaseResources();
143 }
144 }
145
146 public final Exception getException() {
147 return exception.get();
148 }
149
150 @Override
151 public void releaseResources() {
152 bytebuf.clear();
153 }
154
155 }