001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.http.entity;
014
015import static org.apache.juneau.common.internal.ArgUtils.*;
016import static org.apache.juneau.common.internal.IOUtils.*;
017
018import java.io.*;
019import java.nio.charset.*;
020import java.util.function.*;
021
022import org.apache.juneau.http.header.*;
023import org.apache.juneau.internal.*;
024
025/**
026 * A streamed, non-repeatable entity that obtains its content from an {@link Reader}.
027 *
028 * <h5 class='section'>See Also:</h5><ul>
029 *    <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-common">juneau-rest-common</a>
030 * </ul>
031 */
032@FluentSetters
033public class ReaderEntity extends BasicHttpEntity {
034
035   //-----------------------------------------------------------------------------------------------------------------
036   // Instance
037   //-----------------------------------------------------------------------------------------------------------------
038
039   private byte[] byteCache;
040   private String stringCache;
041
042   /**
043    * Constructor.
044    */
045   public ReaderEntity() {
046      super();
047   }
048
049   /**
050    * Constructor.
051    *
052    * @param contentType The entity content type.
053    * @param content The entity contents.
054    */
055   public ReaderEntity(ContentType contentType, Reader content) {
056      super(contentType, content);
057   }
058
059   /**
060    * Copy constructor.
061    *
062    * @param copyFrom The bean being copied.
063    */
064   protected ReaderEntity(ReaderEntity copyFrom) {
065      super(copyFrom);
066   }
067
068   @Override
069   public ReaderEntity copy() {
070      return new ReaderEntity(this);
071   }
072
073   //-----------------------------------------------------------------------------------------------------------------
074   // Other methods
075   //-----------------------------------------------------------------------------------------------------------------
076
077   private Reader content() {
078      Reader r = contentOrElse((Reader)null);
079      if (r == null)
080         throw new RuntimeException("Reader is null.");
081      return r;
082   }
083
084   @Override /* AbstractHttpEntity */
085   public String asString() throws IOException {
086      if (isCached() && stringCache == null)
087         stringCache = read(content(), getMaxLength());
088      if (stringCache != null)
089         return stringCache;
090      return read(content());
091   }
092
093   @Override /* AbstractHttpEntity */
094   public byte[] asBytes() throws IOException {
095      if (isCached() && byteCache == null)
096         byteCache = readBytes(content());
097      if (byteCache != null)
098         return byteCache;
099      return readBytes(content());
100   }
101
102   @Override /* HttpEntity */
103   public boolean isRepeatable() {
104      return isCached();
105   }
106
107   @Override /* HttpEntity */
108   public long getContentLength() {
109      if (isCached())
110         return asSafeBytes().length;
111      return super.getContentLength();
112   }
113
114   @Override /* HttpEntity */
115   public InputStream getContent() throws IOException {
116      if (isCached())
117         return new ByteArrayInputStream(asBytes());
118      return new ReaderInputStream(content(), getCharset());
119   }
120
121   /**
122    * Writes bytes from the {@code InputStream} this entity was constructed
123    * with to an {@code OutputStream}.  The content length
124    * determines how many bytes are written.  If the length is unknown ({@code -1}), the
125    * stream will be completely consumed (to the end of the stream).
126    */
127   @Override
128   public void writeTo(OutputStream out) throws IOException {
129      assertArgNotNull("out", out);
130
131      if (isCached()) {
132         out.write(asBytes());
133      } else {
134         OutputStreamWriter osw = new OutputStreamWriter(out, getCharset());
135         pipe(content(), osw);
136         osw.flush();
137      }
138      out.flush();
139   }
140
141   @Override /* HttpEntity */
142   public boolean isStreaming() {
143      return ! isCached();
144   }
145
146   // <FluentSetters>
147
148   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
149   public ReaderEntity setCached() throws IOException{
150      super.setCached();
151      return this;
152   }
153
154   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
155   public ReaderEntity setCharset(Charset value) {
156      super.setCharset(value);
157      return this;
158   }
159
160   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
161   public ReaderEntity setChunked() {
162      super.setChunked();
163      return this;
164   }
165
166   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
167   public ReaderEntity setChunked(boolean value) {
168      super.setChunked(value);
169      return this;
170   }
171
172   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
173   public ReaderEntity setContent(Object value) {
174      super.setContent(value);
175      return this;
176   }
177
178   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
179   public ReaderEntity setContent(Supplier<?> value) {
180      super.setContent(value);
181      return this;
182   }
183
184   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
185   public ReaderEntity setContentEncoding(String value) {
186      super.setContentEncoding(value);
187      return this;
188   }
189
190   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
191   public ReaderEntity setContentEncoding(ContentEncoding value) {
192      super.setContentEncoding(value);
193      return this;
194   }
195
196   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
197   public ReaderEntity setContentLength(long value) {
198      super.setContentLength(value);
199      return this;
200   }
201
202   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
203   public ReaderEntity setContentType(String value) {
204      super.setContentType(value);
205      return this;
206   }
207
208   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
209   public ReaderEntity setContentType(ContentType value) {
210      super.setContentType(value);
211      return this;
212   }
213
214   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
215   public ReaderEntity setMaxLength(int value) {
216      super.setMaxLength(value);
217      return this;
218   }
219
220   @Override /* GENERATED - org.apache.juneau.http.entity.BasicHttpEntity */
221   public ReaderEntity setUnmodifiable() {
222      super.setUnmodifiable();
223      return this;
224   }
225
226   // </FluentSetters>
227}