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.entity;
029
030import java.io.IOException;
031
032import org.apache.http.Header;
033import org.apache.http.HttpEntity;
034import org.apache.http.message.BasicHeader;
035import org.apache.http.protocol.HTTP;
036
037/**
038 * Abstract base class for entities.
039 * Provides the commonly used attributes for streamed and self-contained
040 * implementations of {@link HttpEntity HttpEntity}.
041 *
042 * @since 4.0
043 */
044public abstract class AbstractHttpEntity implements HttpEntity {
045
046    /**
047     * Buffer size for output stream processing.
048     *
049     * @since 4.3
050     */
051    protected static final int OUTPUT_BUFFER_SIZE = 4096;
052
053    protected Header contentType;
054    protected Header contentEncoding;
055    protected boolean chunked;
056
057    /**
058     * Protected default constructor.
059     * The contentType, contentEncoding and chunked attributes of the created object are set to
060     * {@code null}, {@code null} and {@code false}, respectively.
061     */
062    protected AbstractHttpEntity() {
063        super();
064    }
065
066
067    /**
068     * Obtains the Content-Type header.
069     * The default implementation returns the value of the
070     * {@link #contentType contentType} attribute.
071     *
072     * @return  the Content-Type header, or {@code null}
073     */
074    @Override
075    public Header getContentType() {
076        return this.contentType;
077    }
078
079
080    /**
081     * Obtains the Content-Encoding header.
082     * The default implementation returns the value of the
083     * {@link #contentEncoding contentEncoding} attribute.
084     *
085     * @return  the Content-Encoding header, or {@code null}
086     */
087    @Override
088    public Header getContentEncoding() {
089        return this.contentEncoding;
090    }
091
092    /**
093     * Obtains the 'chunked' flag.
094     * The default implementation returns the value of the
095     * {@link #chunked chunked} attribute.
096     *
097     * @return  the 'chunked' flag
098     */
099    @Override
100    public boolean isChunked() {
101        return this.chunked;
102    }
103
104
105    /**
106     * Specifies the Content-Type header.
107     * The default implementation sets the value of the
108     * {@link #contentType contentType} attribute.
109     *
110     * @param contentType       the new Content-Type header, or
111     *                          {@code null} to unset
112     */
113    public void setContentType(final Header contentType) {
114        this.contentType = contentType;
115    }
116
117    /**
118     * Specifies the Content-Type header, as a string.
119     * The default implementation calls
120     * {@link #setContentType(Header) setContentType(Header)}.
121     *
122     * @param ctString     the new Content-Type header, or
123     *                     {@code null} to unset
124     */
125    public void setContentType(final String ctString) {
126        Header h = null;
127        if (ctString != null) {
128            h = new BasicHeader(HTTP.CONTENT_TYPE, ctString);
129        }
130        setContentType(h);
131    }
132
133
134    /**
135     * Specifies the Content-Encoding header.
136     * The default implementation sets the value of the
137     * {@link #contentEncoding contentEncoding} attribute.
138     *
139     * @param contentEncoding   the new Content-Encoding header, or
140     *                          {@code null} to unset
141     */
142    public void setContentEncoding(final Header contentEncoding) {
143        this.contentEncoding = contentEncoding;
144    }
145
146    /**
147     * Specifies the Content-Encoding header, as a string.
148     * The default implementation calls
149     * {@link #setContentEncoding(Header) setContentEncoding(Header)}.
150     *
151     * @param ceString     the new Content-Encoding header, or
152     *                     {@code null} to unset
153     */
154    public void setContentEncoding(final String ceString) {
155        Header h = null;
156        if (ceString != null) {
157            h = new BasicHeader(HTTP.CONTENT_ENCODING, ceString);
158        }
159        setContentEncoding(h);
160    }
161
162
163    /**
164     * Specifies the 'chunked' flag.
165     * <p>
166     * Note that the chunked setting is a hint only.
167     * If using HTTP/1.0, chunking is never performed.
168     * Otherwise, even if chunked is false, HttpClient must
169     * use chunk coding if the entity content length is
170     * unknown (-1).
171     * <p>
172     * The default implementation sets the value of the
173     * {@link #chunked chunked} attribute.
174     *
175     * @param b         the new 'chunked' flag
176     */
177    public void setChunked(final boolean b) {
178        this.chunked = b;
179    }
180
181
182    /**
183     * The default implementation does not consume anything.
184     *
185     * @deprecated (4.1) Either use {@link #getContent()} and call {@link java.io.InputStream#close()} on that;
186     * otherwise call {@link #writeTo(java.io.OutputStream)} which is required to free the resources.
187     */
188    @Override
189    @Deprecated
190    public void consumeContent() throws IOException {
191    }
192
193    @Override
194    public String toString() {
195        final StringBuilder sb = new StringBuilder();
196        sb.append('[');
197        if (contentType != null) {
198            sb.append("Content-Type: ");
199            sb.append(contentType.getValue());
200            sb.append(',');
201        }
202        if (contentEncoding != null) {
203            sb.append("Content-Encoding: ");
204            sb.append(contentEncoding.getValue());
205            sb.append(',');
206        }
207        final long len = getContentLength();
208        if (len >= 0) {
209            sb.append("Content-Length: ");
210            sb.append(len);
211            sb.append(',');
212        }
213        sb.append("Chunked: ");
214        sb.append(chunked);
215        sb.append(']');
216        return sb.toString();
217    }
218
219}