001/*
002 * ====================================================================
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 * ====================================================================
020 *
021 * This software consists of voluntary contributions made by many
022 * individuals on behalf of the Apache Software Foundation.  For more
023 * information on the Apache Software Foundation, please see
024 * <http://www.apache.org/>.
025 *
026 */
027
028package org.apache.http.nio.entity;
029
030import java.io.ByteArrayInputStream;
031import java.io.IOException;
032import java.io.InputStream;
033import java.io.OutputStream;
034import java.io.UnsupportedEncodingException;
035import java.nio.ByteBuffer;
036import java.nio.charset.Charset;
037
038import org.apache.http.entity.AbstractHttpEntity;
039import org.apache.http.entity.ContentType;
040import org.apache.http.nio.ContentEncoder;
041import org.apache.http.nio.IOControl;
042import org.apache.http.protocol.HTTP;
043import org.apache.http.util.Args;
044
045/**
046 * A simple, self contained, repeatable non-blocking entity that retrieves
047 * its content from a {@link String} object.
048 *
049 * @since 4.0
050 *
051 */
052@SuppressWarnings("deprecation")
053public class NStringEntity extends AbstractHttpEntity
054                           implements HttpAsyncContentProducer, ProducingNHttpEntity {
055
056    private final byte[] b;
057    private final ByteBuffer buf;
058    /**
059     * @deprecated (4.2)
060     */
061    @Deprecated
062    protected final byte[] content;
063    /**
064     * @deprecated (4.2)
065     */
066    @Deprecated
067    protected final ByteBuffer buffer;
068
069    /**
070     * Creates a NStringEntity with the specified content and content type.
071     *
072     * @param s content to be used. Not {@code null}.
073     * @param contentType content type to be used. May be {@code null}, in which case
074     * {@link ContentType#TEXT_PLAIN} is assumed.
075     *
076     * @throws IllegalArgumentException if the string parameter is null
077     *
078     * @since 4.2
079     */
080    public NStringEntity(final String s, final ContentType contentType) {
081        Args.notNull(s, "Source string");
082        Charset charset = contentType != null ? contentType.getCharset() : null;
083        if (charset == null) {
084            charset = HTTP.DEF_CONTENT_CHARSET;
085        }
086        this.b = s.getBytes(charset);
087        this.buf = ByteBuffer.wrap(this.b);
088        this.content = b;
089        this.buffer = this.buf;
090        if (contentType != null) {
091            setContentType(contentType.toString());
092        }
093    }
094
095    /**
096     * Creates a NStringEntity with the specified content and charset. The MIME type defaults
097     * to "text/plain".
098     *
099     * @param s content to be used. Not {@code null}.
100     * @param charset character set to be used. May be {@code null}, in which case the default
101     *   is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
102     *
103     * @throws IllegalArgumentException if the string parameter is null
104     * @throws UnsupportedEncodingException Thrown when the named charset is not available in
105     * this instance of the Java virtual machine
106     */
107    public NStringEntity(final String s, final String charset)
108            throws UnsupportedEncodingException {
109        this(s, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset));
110    }
111
112    /**
113     * Creates a NStringEntity with the specified content and charset. The MIME type defaults
114     * to "text/plain".
115     *
116     * @param s content to be used. Not {@code null}.
117     * @param charset character set to be used. May be {@code null}, in which case the default
118     *   is {@link HTTP#DEF_CONTENT_CHARSET} is assumed
119     *
120     * @throws IllegalArgumentException if the string parameter is null
121     *
122     * @since 4.2
123     */
124    public NStringEntity(final String s, final Charset charset) {
125        this(s, ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), charset));
126    }
127
128    /**
129     * Creates a NStringEntity with the specified content. The content type defaults to
130     * {@link ContentType#TEXT_PLAIN}.
131     *
132     * @param s content to be used. Not {@code null}.
133     *
134     * @throws IllegalArgumentException if the string parameter is null
135     * @throws UnsupportedEncodingException if the default HTTP charset is not supported.
136     */
137    public NStringEntity(final String s) throws UnsupportedEncodingException {
138        this(s, ContentType.DEFAULT_TEXT);
139    }
140
141    @Override
142    public boolean isRepeatable() {
143        return true;
144    }
145
146    @Override
147    public long getContentLength() {
148        return this.b.length;
149    }
150
151    /**
152     * {@inheritDoc}
153     *
154     * @since 4.2
155     */
156    @Override
157    public void close() {
158        this.buf.rewind();
159    }
160
161    /**
162     * {@inheritDoc}
163     *
164     * @deprecated (4.2) use {@link #close()}
165     */
166    @Override
167    @Deprecated
168    public void finish() {
169        close();
170    }
171
172    @Override
173    public void produceContent(
174            final ContentEncoder encoder, final IOControl ioctrl) throws IOException {
175        encoder.write(this.buf);
176        if (!this.buf.hasRemaining()) {
177            encoder.complete();
178        }
179    }
180
181    @Override
182    public boolean isStreaming() {
183        return false;
184    }
185
186    @Override
187    public InputStream getContent() {
188        return new ByteArrayInputStream(this.b);
189    }
190
191    @Override
192    public void writeTo(final OutputStream outstream) throws IOException {
193        Args.notNull(outstream, "Output stream");
194        outstream.write(this.b);
195        outstream.flush();
196    }
197
198}