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