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.entity;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.OutputStream;
35
36 import org.apache.http.HttpEntity;
37 import org.apache.http.util.Args;
38
39 /**
40 * A wrapping entity that buffers it content if necessary.
41 * The buffered entity is always repeatable.
42 * If the wrapped entity is repeatable itself, calls are passed through.
43 * If the wrapped entity is not repeatable, the content is read into a
44 * buffer once and provided from there as often as required.
45 *
46 * @since 4.0
47 */
48 public class BufferedHttpEntity extends HttpEntityWrapper {
49
50 private final byte[] buffer;
51
52 /**
53 * Creates a new buffered entity wrapper.
54 *
55 * @param entity the entity to wrap, not null
56 * @throws IllegalArgumentException if wrapped is null
57 */
58 public BufferedHttpEntity(final HttpEntity entity) throws IOException {
59 super(entity);
60 if (!entity.isRepeatable() || entity.getContentLength() < 0) {
61 final ByteArrayOutputStream out = new ByteArrayOutputStream();
62 entity.writeTo(out);
63 out.flush();
64 this.buffer = out.toByteArray();
65 } else {
66 this.buffer = null;
67 }
68 }
69
70 @Override
71 public long getContentLength() {
72 return this.buffer != null ? this.buffer.length : super.getContentLength();
73 }
74
75 @Override
76 public InputStream getContent() throws IOException {
77 return this.buffer != null ? new ByteArrayInputStream(this.buffer) : super.getContent();
78 }
79
80 /**
81 * Tells that this entity does not have to be chunked.
82 *
83 * @return {@code false}
84 */
85 @Override
86 public boolean isChunked() {
87 return (buffer == null) && super.isChunked();
88 }
89
90 /**
91 * Tells that this entity is repeatable.
92 *
93 * @return {@code true}
94 */
95 @Override
96 public boolean isRepeatable() {
97 return true;
98 }
99
100
101 @Override
102 public void writeTo(final OutputStream outStream) throws IOException {
103 Args.notNull(outStream, "Output stream");
104 if (this.buffer != null) {
105 outStream.write(this.buffer);
106 } else {
107 super.writeTo(outStream);
108 }
109 }
110
111
112 // non-javadoc, see interface HttpEntity
113 @Override
114 public boolean isStreaming() {
115 return (buffer == null) && super.isStreaming();
116 }
117
118 } // class BufferedHttpEntity