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.http.nio.entity;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.OutputStream;
34 import java.io.UnsupportedEncodingException;
35 import java.nio.ByteBuffer;
36 import java.nio.charset.Charset;
37 import java.nio.charset.UnsupportedCharsetException;
38
39 import org.apache.http.annotation.NotThreadSafe;
40 import org.apache.http.entity.AbstractHttpEntity;
41 import org.apache.http.entity.ContentType;
42 import org.apache.http.nio.ContentEncoder;
43 import org.apache.http.nio.IOControl;
44 import org.apache.http.protocol.HTTP;
45
46 /**
47 * A simple, self contained, repeatable non-blocking entity that retrieves
48 * its content from a {@link String} object.
49 *
50 * @since 4.0
51 *
52 */
53 @SuppressWarnings("deprecation")
54 @NotThreadSafe
55 public class NStringEntity extends AbstractHttpEntity
56 implements HttpAsyncContentProducer, ProducingNHttpEntity {
57
58 private final byte[] b;
59 private final ByteBuffer buf;
60 /**
61 * @deprecated (4.2)
62 */
63 @Deprecated
64 protected final byte[] content;
65 /**
66 * @deprecated (4.2)
67 */
68 @Deprecated
69 protected final ByteBuffer buffer;
70
71 /**
72 * Creates a NStringEntity with the specified content and content type.
73 *
74 * @param s content to be used. Not {@code null}.
75 * @param contentType content type to be used. May be {@code null}, in which case
76 * {@link ContentType#TEXT_PLAIN} is assumed.
77 *
78 * @throws IllegalArgumentException if the string parameter is null
79 *
80 * @since 4.2
81 */
82 public NStringEntity(final String s, final ContentType contentType) {
83 if (s == null) {
84 throw new IllegalArgumentException("Source string may not be null");
85 }
86 Charset charset = contentType != null ? contentType.getCharset() : null;
87 if (charset == null) {
88 charset = HTTP.DEF_CONTENT_CHARSET;
89 }
90 try {
91 this.b = s.getBytes(charset.name());
92 } catch (UnsupportedEncodingException ex) {
93 // should never happen
94 throw new UnsupportedCharsetException(charset.name());
95 }
96 this.buf = ByteBuffer.wrap(this.b);
97 this.content = b;
98 this.buffer = this.buf;
99 if (contentType != null) {
100 setContentType(contentType.toString());
101 }
102 }
103
104 /**
105 * Creates a NStringEntity with the specified content and charset. The MIME type defaults
106 * to "text/plain".
107 *
108 * @param s content to be used. Not {@code null}.
109 * @param charset character set to be used. May be {@code null}, in which case the default
110 * is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
111 *
112 * @throws IllegalArgumentException if the string parameter is null
113 * @throws UnsupportedEncodingException if the charset is not supported.
114 */
115 public NStringEntity(final String s, final String charset)
116 throws UnsupportedEncodingException {
117 this(s, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset));
118 }
119
120 /**
121 * Creates a NStringEntity with the specified content and charset. The MIME type defaults
122 * to "text/plain".
123 *
124 * @param s content to be used. Not {@code null}.
125 * @param charset character set to be used. May be {@code null}, in which case the default
126 * is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
127 *
128 * @throws IllegalArgumentException if the string parameter is null
129 *
130 * @since 4.2
131 */
132 public NStringEntity(final String s, final Charset charset) {
133 this(s, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset));
134 }
135
136 /**
137 * Creates a NStringEntity with the specified content. The content type defaults to
138 * {@link ContentType#TEXT_PLAIN}.
139 *
140 * @param s content to be used. Not {@code null}.
141 *
142 * @throws IllegalArgumentException if the string parameter is null
143 * @throws UnsupportedEncodingException if the default HTTP charset is not supported.
144 */
145 public NStringEntity(final String s) throws UnsupportedEncodingException {
146 this(s, ContentType.DEFAULT_TEXT);
147 }
148
149 public boolean isRepeatable() {
150 return true;
151 }
152
153 public long getContentLength() {
154 return this.b.length;
155 }
156
157 /**
158 * {@inheritDoc}
159 *
160 * @since 4.2
161 */
162 public void close() {
163 this.buf.rewind();
164 }
165
166 /**
167 * {@inheritDoc}
168 *
169 * @deprecated (4.2) use {@link #close()}
170 */
171 public void finish() {
172 close();
173 }
174
175 public void produceContent(
176 final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
177 encoder.write(this.buf);
178 if (!this.buf.hasRemaining()) {
179 encoder.complete();
180 }
181 }
182
183 public boolean isStreaming() {
184 return false;
185 }
186
187 public InputStream getContent() {
188 return new ByteArrayInputStream(this.b);
189 }
190
191 public void writeTo(final OutputStream outstream) throws IOException {
192 if (outstream == null) {
193 throw new IllegalArgumentException("Output stream may not be null");
194 }
195 outstream.write(this.b);
196 outstream.flush();
197 }
198
199 }