Index: trunk/http-core/src/contrib/org/apache/http/contrib/compress/GzipCompressingEntity.java =================================================================== --- trunk/http-core/src/contrib/org/apache/http/contrib/compress/GzipCompressingEntity.java (revision 374885) +++ trunk/http-core/src/contrib/org/apache/http/contrib/compress/GzipCompressingEntity.java (working copy) @@ -36,35 +36,28 @@ import org.apache.http.Header; import org.apache.http.HttpEntity; +import org.apache.http.entity.HttpEntityWrapper; import org.apache.http.protocol.HTTP; /** - *

- *

+ * Wrapping entity that compresses content when {@link #writeTo writing}. + * * @author Oleg Kalnichevski * * @version $Revision$ * * @since 4.0 */ -public class GzipCompressingEntity implements HttpEntity { +public class GzipCompressingEntity extends HttpEntityWrapper + implements HttpEntity { private static final String GZIP_CODEC = "gzip"; + - private final HttpEntity entity; - public GzipCompressingEntity(final HttpEntity entity) { - super(); - if (entity == null) { - throw new IllegalArgumentException("HTTP entity may not be null"); - } - this.entity = entity; + super(entity); } - public InputStream getContent() throws IOException { - return this.entity.getContent(); - } - public Header getContentEncoding() { return new Header(HTTP.CONTENT_ENCODING, GZIP_CODEC, true); } @@ -73,25 +66,17 @@ return -1; } - public Header getContentType() { - return this.entity.getContentType(); - } - public boolean isChunked() { // force content chunking return true; } - public boolean isRepeatable() { - return this.entity.isRepeatable(); - } - public boolean writeTo(final OutputStream outstream) throws IOException { if (outstream == null) { throw new IllegalArgumentException("Output stream may not be null"); } GZIPOutputStream gzip = new GZIPOutputStream(outstream); - InputStream in = this.entity.getContent(); + InputStream in = wrappedEntity.getContent(); byte[] tmp = new byte[2048]; int l; while ((l = in.read(tmp)) != -1) { @@ -102,4 +87,4 @@ return true; } -} +} // class GzipCompressingEntity Index: trunk/http-core/src/contrib/org/apache/http/contrib/compress/GzipDecompressingEntity.java =================================================================== --- trunk/http-core/src/contrib/org/apache/http/contrib/compress/GzipDecompressingEntity.java (revision 374885) +++ trunk/http-core/src/contrib/org/apache/http/contrib/compress/GzipDecompressingEntity.java (working copy) @@ -36,58 +36,40 @@ import org.apache.http.Header; import org.apache.http.HttpEntity; +import org.apache.http.entity.HttpEntityWrapper; /** - *

- *

+ * Wrapping entity that decompresses {@link #getContent content}. + * * @author Oleg Kalnichevski * * @version $Revision$ * * @since 4.0 */ -public class GzipDecompressingEntity implements HttpEntity { - - private final HttpEntity entity; +public class GzipDecompressingEntity extends HttpEntityWrapper + implements HttpEntity { + private InputStream instream = null; public GzipDecompressingEntity(final HttpEntity entity) { - super(); - if (entity == null) { - throw new IllegalArgumentException("HTTP entity may not be null"); - } - this.entity = entity; + super(entity); } public InputStream getContent() throws IOException { if (this.instream == null) { - this.instream = new GZIPInputStream(this.entity.getContent()); + this.instream = new GZIPInputStream(wrappedEntity.getContent()); } return this.instream; } - public Header getContentEncoding() { - return this.entity.getContentEncoding(); - } - public long getContentLength() { return -1; } - public Header getContentType() { - return this.entity.getContentType(); - } - - public boolean isChunked() { - return this.entity.isChunked(); - } - public boolean isRepeatable() { - return this.entity.isRepeatable(); + // not repeatable, GZIPInputStream is created only once + return false; } - public boolean writeTo(final OutputStream outstream) throws IOException { - return this.entity.writeTo(outstream); - } - -} +} // class GzipDecompressingEntity Index: trunk/http-core/src/java/org/apache/http/HttpEntity.java =================================================================== --- trunk/http-core/src/java/org/apache/http/HttpEntity.java (revision 374885) +++ trunk/http-core/src/java/org/apache/http/HttpEntity.java (working copy) @@ -34,8 +34,34 @@ import java.io.OutputStream; /** + * An entity that can be sent or received with an HTTP message. + * Entities can be found in some + * {@link HttpEntityEnclosingRequest requests} and in + * {@link HttpResponse responses}, where they are optional. *

- *

+ * In some places, the JavaDoc distinguishes three kinds of entities, + * depending on where their {@link #getContent content} originates: + * + * This distinction is important for connection management with incoming + * entities. For entities that are created by an application and only sent + * using the HTTP components framework, the difference between streamed + * and self-contained is of little importance. In that case, it is suggested + * to consider non-repeatable entities as streamed, and those that are + * repeatable (without a huge effort) as self-contained. + * * @author Oleg Kalnichevski * * @version $Revision$ @@ -52,27 +78,74 @@ */ boolean isRepeatable(); + + /** + * Tells about chunked encoding for this entity. + * The primary purpose of this method is to indicate whether + * chunked encoding should be used when the entity is sent. + * For entities that are received, it can also indicate whether + * the entity was received with chunked encoding. + *
+ * The behavior of wrapping entities is implementation dependent, + * but should respect the primary purpose. + * + * @return true if chunked encoding is preferred for this + * entity, or false if it is not + */ boolean isChunked(); + + /** + * Tells the length of the content, if known. + * + * @return the number of bytes of the content, or + * a negative number if unknown. If the content length is known + * but exceeds {@link java.lang.Long#MAX_VALUE Long.MAX_VALUE}, + * a negative number is returned. + */ long getContentLength(); - + + + /** + * Obtains the Content-Type header, if known. + * This is the header that should be used when sending the entity, + * or the one that was received with the entity. It can include a + * charset attribute. + * + * @return the Content-Type header for this entity, or + * null if the content type is unknown + */ Header getContentType(); - + + + /** + * Obtains the Content-Encoding header, if known. + * This is the header that should be used when sending the entity, + * or the one that was received with the entity. + * Wrapping entities that modify the content encoding should + * adjust this header accordingly. + * + * @return the Content-Encoding header for this entity, or + * null if the content encoding is unknown + */ Header getContentEncoding(); - + + /** - * Creates a new InputStream object of the entity. It is a programming error + * Creates a new InputStream object of the entity. + * It is a programming error * to return the same InputStream object more than once. * @return a new input stream that returns the entity data. * @throws IOException if the stream could not be created */ InputStream getContent() throws IOException; + /** * Writes the entity content to the output stream either partially or entirely. * This method may either write the entire content in one go, if it is feasible * to do so, or store the output stream as a local variable and use it internally - * to write the content in parts. If the former case this method MUST return + * to write the content in parts. In the former case this method MUST return * true to indicate that the output stream can be closed. In the latter * case the output stream MUST be closed once the last content part is written * in order to ensure that content codings that emit a closing chunk are properly @@ -84,5 +157,46 @@ * @throws IOException if an I/O error occurs */ boolean writeTo(OutputStream outstream) throws IOException; - -} + + + /** + * Tells whether this entity depends on an underlying stream. + * Streamed entities should return true until the + * content has been consumed, false afterwards. + * Self-contained entities should return false. + * Wrapping entities should delegate this call to the wrapped entity. + *
+ * The content of a streamed entity is consumed when the stream + * returned by {@link #getContent getContent} has been read to EOF, + * or after {@link #consumeContent consumeContent} has been called. + * If a streamed entity can not detect whether the stream has been + * read to EOF, it should return true until + * {@link #consumeContent consumeContent} is called. + * + * @return true if the entity content is streamed and + * not yet consumed, false otherwise + */ + public boolean isStreaming(); // don't expect an exception here + + + /** + * Consumes the remaining content of a streamed entity. + * This method is called to indicate that the content of this entity + * is no longer required. + * Streamed entities should dispose of the remaining content, if any. + * Self-contained entities can release allocated resources, but + * are not required to do anything. + * Wrapping entities should delegate this call to the wrapped entity. + *
+ * This method is of particular importance for entities being + * received from a {@link HttpConnection connection}. The entity + * needs to be consumed completely in order to re-use the connection + * with keep-alive. + * + * @throws IOException if an I/O error occurs. + * This indicates that connection keep-alive is not possible. + */ + public void consumeContent() throws IOException; + + +} // interface HttpEntity Index: trunk/http-core/src/java/org/apache/http/entity/BufferedHttpEntity.java =================================================================== --- trunk/http-core/src/java/org/apache/http/entity/BufferedHttpEntity.java (revision 374885) +++ trunk/http-core/src/java/org/apache/http/entity/BufferedHttpEntity.java (working copy) @@ -39,25 +39,26 @@ import org.apache.http.util.EntityUtils; /** - *

- *

+ * A wrapping entity that buffers it content if necessary. + * The buffered entity is always repeatable. + * If the wrapped entity is repeatable itself, calls are passed through. + * If the wrapped entity is not repeatable, the content is read into a + * buffer once and provided from there as often as required. + * * @author Oleg Kalnichevski * * @version $Revision$ * * @since 4.0 */ -public class BufferedHttpEntity implements HttpEntity { +public class BufferedHttpEntity extends HttpEntityWrapper + implements HttpEntity { - private final HttpEntity source; private final byte[] buffer; public BufferedHttpEntity(final HttpEntity entity) throws IOException { - super(); - if (entity == null) { - throw new IllegalArgumentException("HTTP entity may not be null"); - } - this.source = entity; + super(entity); + if (entity.isChunked() || !entity.isRepeatable() ) { this.buffer = EntityUtils.toByteArray(entity); } else { @@ -69,33 +70,36 @@ if (this.buffer != null) { return this.buffer.length; } else { - return this.source.getContentLength(); + return wrappedEntity.getContentLength(); } } - - public Header getContentType() { - return this.source.getContentType(); - } - public Header getContentEncoding() { - return this.source.getContentEncoding(); - } - public InputStream getContent() throws IOException { if (this.buffer != null) { return new ByteArrayInputStream(this.buffer); } else { - return this.source.getContent(); + return wrappedEntity.getContent(); } } - + + /** + * Tells that this entity does not have to be chunked. + * + * @return false + */ public boolean isChunked() { return false; } + /** + * Tells that this entity is repeatable. + * + * @return true + */ public boolean isRepeatable() { return true; } + public boolean writeTo(final OutputStream outstream) throws IOException { if (outstream == null) { @@ -105,8 +109,14 @@ outstream.write(this.buffer); return true; } else { - return this.source.writeTo(outstream); + return wrappedEntity.writeTo(outstream); } } + + + // non-javadoc, see interface HttpEntity + public boolean isStreaming() { + return (buffer == null) && wrappedEntity.isStreaming(); + } -} +} // class BufferedHttpEntity Index: trunk/http-core/src/java/org/apache/http/entity/ByteArrayEntity.java =================================================================== --- trunk/http-core/src/java/org/apache/http/entity/ByteArrayEntity.java (revision 374885) +++ trunk/http-core/src/java/org/apache/http/entity/ByteArrayEntity.java (working copy) @@ -36,23 +36,20 @@ import org.apache.http.Header; import org.apache.http.HttpEntity; -import org.apache.http.protocol.HTTP; + /** - *

- *

+ * A self-contained entity obtaining content from a byte array. + * * @author Oleg Kalnichevski * * @version $Revision$ * * @since 4.0 */ -public class ByteArrayEntity implements HttpEntity { +public class ByteArrayEntity extends AbstractHttpEntity implements HttpEntity { private final byte[] content; - private String contentType = HTTP.DEFAULT_CONTENT_TYPE; - private String contentEncoding = null; - private boolean chunked = false; public ByteArrayEntity(final byte[] b) { super(); @@ -66,42 +63,10 @@ return true; } - public boolean isChunked() { - return this.chunked; - } - - public void setChunked(boolean b) { - this.chunked = b; - } - public long getContentLength() { return this.content.length; } - - public Header getContentType() { - if (this.contentType != null) { - return new Header(HTTP.CONTENT_TYPE, this.contentType); - } else { - return null; - } - } - public void setContentType(final String contentType) { - this.contentType = contentType; - } - - public Header getContentEncoding() { - if (this.contentEncoding != null) { - return new Header(HTTP.CONTENT_ENCODING, this.contentEncoding); - } else { - return null; - } - } - - public void setContentEncoding(final String contentEncoding) { - this.contentEncoding = contentEncoding; - } - public InputStream getContent() { return new ByteArrayInputStream(this.content); } @@ -115,4 +80,15 @@ return true; } -} + + /** + * Tells that this entity is not streaming. + * + * @return false + */ + public boolean isStreaming() { + return false; + } + + +} // class ByteArrayEntity Index: trunk/http-core/src/java/org/apache/http/entity/AbstractHttpEntity.java =================================================================== --- trunk/http-core/src/java/org/apache/http/entity/AbstractHttpEntity.java (revision 0) +++ trunk/http-core/src/java/org/apache/http/entity/AbstractHttpEntity.java (revision 0) @@ -0,0 +1,214 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Copyright 1999-2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.protocol.HTTP; + + + +/** + * Abstract base class for entities. + * Provides the commonly used attributes for streamed and self-contained + * implementations of {@link HttpEntity HttpEntity}. + * + * @author Oleg Kalnichevski + * + * @version $Revision$ + * + * @since 4.0 + */ +public abstract class AbstractHttpEntity implements HttpEntity { + + /** + * The Content-Type header. + * Returned by {@link #getContentType getContentType}, + * unless that method is overridden. + */ + protected Header contentType; + + /** + * The Content-Encoding header. + * Returned by {@link #getContentEncoding getContentEncoding}, + * unless that method is overridden. + */ + protected Header contentEncoding; + + /** + * The 'chunked' flag. + * Returned by {@link #isChunked isChunked}, + * unless that method is overridden. + */ + protected boolean chunked; + + + /** + * Protected default constructor. + * The attributes of the created object remain + * null and false, respectively. + */ + protected AbstractHttpEntity() { + super(); + } + + + /** + * Obtains the Content-Type header. + * The default implementation returns the value of the + * {@link #contentType contentType} attribute. + * + * @return the Content-Type header, or null + */ + public Header getContentType() { + return this.contentType; + } + + + /** + * Obtains the Content-Encoding header. + * The default implementation returns the value of the + * {@link #contentEncoding contentEncoding} attribute. + * + * @return the Content-Encoding header, or null + */ + public Header getContentEncoding() { + return this.contentEncoding; + } + + /** + * Obtains the 'chunked' flag. + * The default implementation returns the value of the + * {@link #chunked chunked} attribute. + * + * @return the 'chunked' flag + */ + public boolean isChunked() { + return this.chunked; + } + + + /** + * Specifies the Content-Type header. + * The default implementation sets the value of the + * {@link #contentType contentType} attribute. + * + * @param contentType the new Content-Encoding header, or + * null to unset + */ + public void setContentType(final Header contentType) { + this.contentType = contentType; + } + + /** + * Specifies the Content-Type header, as a string. + * The default implementation calls + * {@link #setContentType(Header) setContentType(Header)}. + * + * @param ctString the new Content-Type header, or + * null to unset + */ + public void setContentType(final String ctString) { + Header h = null; + if (ctString != null) { + h = new Header(HTTP.CONTENT_TYPE, ctString); + } + setContentType(h); + } + + + /** + * Specifies the Content-Encoding header. + * The default implementation sets the value of the + * {@link #contentEncoding contentEncoding} attribute. + * + * @param contentEncoding the new Content-Encoding header, or + * null to unset + */ + public void setContentEncoding(final Header contentEncoding) { + this.contentEncoding = contentEncoding; + } + + /** + * Specifies the Content-Encoding header, as a string. + * The default implementation calls + * {@link #setContentEncoding(Header) setContentEncoding(Header)}. + * + * @param ceString the new Content-Encoding header, or + * null to unset + */ + public void setContentEncoding(final String ceString) { + Header h = null; + if (ceString != null) { + h = new Header(HTTP.CONTENT_ENCODING, ceString); + } + setContentEncoding(h); + } + + + /** + * Specifies the 'chunked' flag. + * The default implementation sets the value of the + * {@link #chunked chunked} attribute. + * + * @param b the new 'chunked' flag + */ + public void setChunked(boolean b) { + this.chunked = b; + } + + + /** + * Does not consume anything. + * The default implementation does nothing if + * {@link HttpEntity#isStreaming isStreaming} + * returns false, and throws an exception + * if it returns true. + * This removes the burden of implementing + * an empty method for non-streaming entities. + * + * @throws IOException in case of an I/O problem + * @throws UnsupportedOperationException + * if a streaming subclass does not override this method + */ + public void consumeContent() + throws IOException, UnsupportedOperationException{ + if (isStreaming()) { + throw new UnsupportedOperationException + ("streaming entity does not implement consumeContent()"); + } + } // consumeContent + + +} // class AbstractHttpEntity Property changes on: trunk/http-core/src/java/org/apache/http/entity/AbstractHttpEntity.java ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Date Author Id Revision HeadURL Name: svn:eol-style + native Index: trunk/http-core/src/java/org/apache/http/entity/StringEntity.java =================================================================== --- trunk/http-core/src/java/org/apache/http/entity/StringEntity.java (revision 374885) +++ trunk/http-core/src/java/org/apache/http/entity/StringEntity.java (working copy) @@ -39,21 +39,19 @@ import org.apache.http.HttpEntity; import org.apache.http.protocol.HTTP; + /** - *

- *

+ * A self-contained entity obtaining content from a string. + * * @author Oleg Kalnichevski * * @version $Revision$ * * @since 4.0 */ -public class StringEntity implements HttpEntity { +public class StringEntity extends AbstractHttpEntity implements HttpEntity { private final byte[] content; - private String contentType = null; - private String contentEncoding = null; - private boolean chunked = false; public StringEntity(final String s, String charset) throws UnsupportedEncodingException { @@ -64,8 +62,8 @@ if (charset == null) { charset = HTTP.DEFAULT_CONTENT_CHARSET; } - this.contentType = HTTP.PLAIN_TEXT_TYPE + HTTP.CHARSET_PARAM + charset; this.content = s.getBytes(charset); + setContentType(HTTP.PLAIN_TEXT_TYPE + HTTP.CHARSET_PARAM + charset); } public StringEntity(final String s) @@ -77,42 +75,10 @@ return true; } - public boolean isChunked() { - return this.chunked; - } - - public void setChunked(boolean b) { - this.chunked = b; - } - public long getContentLength() { return this.content.length; } - public Header getContentType() { - if (this.contentType != null) { - return new Header(HTTP.CONTENT_TYPE, this.contentType); - } else { - return null; - } - } - - public void setContentType(final String contentType) { - this.contentType = contentType; - } - - public Header getContentEncoding() { - if (this.contentEncoding != null) { - return new Header(HTTP.CONTENT_ENCODING, this.contentEncoding); - } else { - return null; - } - } - - public void setContentEncoding(final String contentEncoding) { - this.contentEncoding = contentEncoding; - } - public InputStream getContent() throws IOException { return new ByteArrayInputStream(this.content); } @@ -126,4 +92,15 @@ return true; } -} + + /** + * Tells that this entity is not streaming. + * + * @return false + */ + public boolean isStreaming() { + return false; + } + + +} // class StringEntity Index: trunk/http-core/src/java/org/apache/http/entity/InputStreamEntity.java =================================================================== --- trunk/http-core/src/java/org/apache/http/entity/InputStreamEntity.java (revision 374885) +++ trunk/http-core/src/java/org/apache/http/entity/InputStreamEntity.java (working copy) @@ -35,26 +35,25 @@ import org.apache.http.Header; import org.apache.http.HttpEntity; -import org.apache.http.protocol.HTTP; + /** - *

- *

+ * A streamed entity obtaining content from an {@link InputStream InputStream}. + * * @author Oleg Kalnichevski * * @version $Revision$ * * @since 4.0 */ -public class InputStreamEntity implements HttpEntity { +public class InputStreamEntity extends AbstractHttpEntity + implements HttpEntity { private final static int BUFFER_SIZE = 2048; private final InputStream content; private final long length; - private String contentType = HTTP.DEFAULT_CONTENT_TYPE; - private String contentEncoding = null; - private boolean chunked = false; + private boolean consumed = false; public InputStreamEntity(final InputStream instream, long length) { super(); @@ -69,42 +68,10 @@ return false; } - public boolean isChunked() { - return this.chunked; - } - - public void setChunked(boolean b) { - this.chunked = b; - } - public long getContentLength() { return this.length; } - - public Header getContentType() { - if (this.contentType != null) { - return new Header(HTTP.CONTENT_TYPE, this.contentType); - } else { - return null; - } - } - public void setContentType(final String contentType) { - this.contentType = contentType; - } - - public Header getContentEncoding() { - if (this.contentEncoding != null) { - return new Header(HTTP.CONTENT_ENCODING, this.contentEncoding); - } else { - return null; - } - } - - public void setContentEncoding(final String contentEncoding) { - this.contentEncoding = contentEncoding; - } - public InputStream getContent() throws IOException { return this.content; } @@ -126,5 +93,19 @@ } return true; } + + + // non-javadoc, see interface HttpEntity + public boolean isStreaming() { + return !consumed; + } + + // non-javadoc, see interface HttpEntity + public void consumeContent() throws IOException { + consumed = true; + // If the input stream is from a connection, closing it will read to + // the end of the content. Otherwise, we don't care what it does. + content.close(); + } -} +} // class InputStreamEntity Index: trunk/http-core/src/java/org/apache/http/entity/FileEntity.java =================================================================== --- trunk/http-core/src/java/org/apache/http/entity/FileEntity.java (revision 374885) +++ trunk/http-core/src/java/org/apache/http/entity/FileEntity.java (working copy) @@ -37,23 +37,20 @@ import org.apache.http.Header; import org.apache.http.HttpEntity; -import org.apache.http.protocol.HTTP; + /** - *

- *

+ * A self-contained entity obtaining content from a file. + * * @author Oleg Kalnichevski * * @version $Revision$ * * @since 4.0 */ -public class FileEntity implements HttpEntity { +public class FileEntity extends AbstractHttpEntity implements HttpEntity { private final File file; - private String contentType = null; - private String contentEncoding = null; - private boolean chunked = false; public FileEntity(final File file, final String contentType) { super(); @@ -61,49 +58,17 @@ throw new IllegalArgumentException("File may not be null"); } this.file = file; - this.contentType = contentType; + setContentType(contentType); } public boolean isRepeatable() { return true; } - public boolean isChunked() { - return this.chunked; - } - - public void setChunked(boolean b) { - this.chunked = b; - } - public long getContentLength() { return this.file.length(); } - public Header getContentType() { - if (this.contentType != null) { - return new Header(HTTP.CONTENT_TYPE, this.contentType); - } else { - return null; - } - } - - public void setContentType(final String contentType) { - this.contentType = contentType; - } - - public Header getContentEncoding() { - if (this.contentEncoding != null) { - return new Header(HTTP.CONTENT_ENCODING, this.contentEncoding); - } else { - return null; - } - } - - public void setContentEncoding(final String contentEncoding) { - this.contentEncoding = contentEncoding; - } - public InputStream getContent() throws IOException { return new FileInputStream(this.file); } @@ -122,4 +87,15 @@ return true; } -} + + /** + * Tells that this entity is not streaming. + * + * @return false + */ + public boolean isStreaming() { + return false; + } + + +} // class FileEntity Index: trunk/http-core/src/java/org/apache/http/entity/HttpEntityWrapper.java =================================================================== --- trunk/http-core/src/java/org/apache/http/entity/HttpEntityWrapper.java (revision 0) +++ trunk/http-core/src/java/org/apache/http/entity/HttpEntityWrapper.java (revision 0) @@ -0,0 +1,116 @@ +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * Copyright 1999-2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.entity; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.protocol.HTTP; + + + +/** + * Base class for wrapping entities. + * Keeps a {@link #wrappedEntity wrappedEntity} and delegates all + * calls to it. Implementations of wrapping entities can derive + * from this class and need to override only those methods that + * should not be delegated to the wrapped entity. + * + * @author Oleg Kalnichevski + * + * @version $Revision$ + * + * @since 4.0 + */ +public class HttpEntityWrapper implements HttpEntity { + + /** The wrapped entity. */ + protected HttpEntity wrappedEntity; + + /** + * Creates a new entity wrapper. + * + * @param wrapped the entity to wrap + */ + public HttpEntityWrapper(HttpEntity wrapped) { + super(); + + if (wrapped == null) { + throw new IllegalArgumentException + ("wrapped entity must not be null"); + } + wrappedEntity = wrapped; + + } // constructor + + + public boolean isRepeatable() { + return wrappedEntity.isRepeatable(); + } + + public boolean isChunked() { + return wrappedEntity.isChunked(); + } + + public long getContentLength() { + return wrappedEntity.getContentLength(); + } + + public Header getContentType() { + return wrappedEntity.getContentType(); + } + + public Header getContentEncoding() { + return wrappedEntity.getContentEncoding(); + } + + public InputStream getContent() + throws IOException { + return wrappedEntity.getContent(); + } + + public boolean writeTo(OutputStream outstream) + throws IOException { + return wrappedEntity.writeTo(outstream); + } + + public boolean isStreaming() { + return wrappedEntity.isStreaming(); + } + + public void consumeContent() + throws IOException { + wrappedEntity.consumeContent(); + } + +} // class HttpEntityWrapper Property changes on: trunk/http-core/src/java/org/apache/http/entity/HttpEntityWrapper.java ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Date Author Id Revision HeadURL Name: svn:eol-style + native Index: trunk/http-core/src/java/org/apache/http/entity/BasicHttpEntity.java =================================================================== --- trunk/http-core/src/java/org/apache/http/entity/BasicHttpEntity.java (revision 374885) +++ trunk/http-core/src/java/org/apache/http/entity/BasicHttpEntity.java (working copy) @@ -116,5 +116,19 @@ } return true; } + + + // non-javadoc, see interface HttpEntity + public boolean isStreaming() { + return (content != null); + } + + // non-javadoc, see interface HttpEntity + public void consumeContent() throws IOException { + if (content != null) { + content.close(); // reads to the end of the entity + content = null; + } + } -} +} // class BasicHttpEntity