001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-main/src/main/java/org/apache/http/message/BasicLineFormatter.java $
003: * $Revision: 574185 $
004: * $Date: 2007-09-10 11:19:47 +0200 (Mon, 10 Sep 2007) $
005: *
006: * ====================================================================
007: * Licensed to the Apache Software Foundation (ASF) under one
008: * or more contributor license agreements. See the NOTICE file
009: * distributed with this work for additional information
010: * regarding copyright ownership. The ASF licenses this file
011: * to you under the Apache License, Version 2.0 (the
012: * "License"); you may not use this file except in compliance
013: * with the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing,
018: * software distributed under the License is distributed on an
019: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020: * KIND, either express or implied. See the License for the
021: * specific language governing permissions and limitations
022: * under the License.
023: * ====================================================================
024: *
025: * This software consists of voluntary contributions made by many
026: * individuals on behalf of the Apache Software Foundation. For more
027: * information on the Apache Software Foundation, please see
028: * <http://www.apache.org/>.
029: *
030: */
031:
032: package org.apache.http.message;
033:
034: import org.apache.http.ProtocolVersion;
035: import org.apache.http.RequestLine;
036: import org.apache.http.StatusLine;
037: import org.apache.http.Header;
038: import org.apache.http.FormattedHeader;
039: import org.apache.http.util.CharArrayBuffer;
040:
041: /**
042: * Interface for formatting elements of the HEAD section of an HTTP message.
043: * This is the complement to {@link LineParser}.
044: * There are individual methods for formatting a request line, a
045: * status line, or a header line. The formatting does <i>not</i> include the
046: * trailing line break sequence CR-LF.
047: * The formatted lines are returned in memory, the formatter does not depend
048: * on any specific IO mechanism.
049: * Instances of this interface are expected to be stateless and thread-safe.
050: *
051: * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
052: * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
053: * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
054: * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
055: * @author and others
056: *
057: *
058: * <!-- empty lines above to avoid 'svn diff' context problems -->
059: * @version $Revision: 574185 $
060: *
061: * @since 4.0
062: */
063: public class BasicLineFormatter implements LineFormatter {
064:
065: /**
066: * A default instance of this class, for use as default or fallback.
067: * Note that {@link BasicLineFormatter} is not a singleton, there can
068: * be many instances of the class itself and of derived classes.
069: * The instance here provides non-customized, default behavior.
070: */
071: public final static BasicLineFormatter DEFAULT = new BasicLineFormatter();
072:
073: // public default constructor
074:
075: /**
076: * Obtains a buffer for formatting.
077: *
078: * @param buffer a buffer already available, or <code>null</code>
079: *
080: * @return the cleared argument buffer if there is one, or
081: * a new empty buffer that can be used for formatting
082: */
083: protected CharArrayBuffer initBuffer(CharArrayBuffer buffer) {
084: if (buffer != null) {
085: buffer.clear();
086: } else {
087: buffer = new CharArrayBuffer(64);
088: }
089: return buffer;
090: }
091:
092: /**
093: * Formats a protocol version.
094: *
095: * @param version the protocol version to format
096: * @param formatter the formatter to use, or
097: * <code>null</code> for the
098: * {@link #DEFAULT default}
099: *
100: * @return the formatted protocol version
101: */
102: public final static String formatProtocolVersion(
103: final ProtocolVersion version, LineFormatter formatter) {
104: if (formatter == null)
105: formatter = BasicLineFormatter.DEFAULT;
106: return formatter.appendProtocolVersion(null, version)
107: .toString();
108: }
109:
110: // non-javadoc, see interface LineFormatter
111: public CharArrayBuffer appendProtocolVersion(
112: final CharArrayBuffer buffer, final ProtocolVersion version) {
113: if (version == null) {
114: throw new IllegalArgumentException(
115: "Protocol version may not be null");
116: }
117:
118: // can't use initBuffer, that would clear the argument!
119: CharArrayBuffer result = buffer;
120: final int len = estimateProtocolVersionLen(version);
121: if (result == null) {
122: result = new CharArrayBuffer(len);
123: } else {
124: result.ensureCapacity(len);
125: }
126:
127: result.append(version.getProtocol());
128: result.append('/');
129: result.append(Integer.toString(version.getMajor()));
130: result.append('.');
131: result.append(Integer.toString(version.getMinor()));
132:
133: return result;
134: }
135:
136: /**
137: * Guesses the length of a formatted protocol version.
138: * Needed to guess the length of a formatted request or status line.
139: *
140: * @param version the protocol version to format, or <code>null</code>
141: *
142: * @return the estimated length of the formatted protocol version,
143: * in characters
144: */
145: protected int estimateProtocolVersionLen(
146: final ProtocolVersion version) {
147: return version.getProtocol().length() + 4; // room for "HTTP/1.1"
148: }
149:
150: /**
151: * Formats a request line.
152: *
153: * @param reqline the request line to format
154: * @param formatter the formatter to use, or
155: * <code>null</code> for the
156: * {@link #DEFAULT default}
157: *
158: * @return the formatted request line
159: */
160: public final static String formatRequestLine(
161: final RequestLine reqline, LineFormatter formatter) {
162: if (formatter == null)
163: formatter = BasicLineFormatter.DEFAULT;
164: return formatter.formatRequestLine(null, reqline).toString();
165: }
166:
167: // non-javadoc, see interface LineFormatter
168: public CharArrayBuffer formatRequestLine(CharArrayBuffer buffer,
169: RequestLine reqline) {
170: if (reqline == null) {
171: throw new IllegalArgumentException(
172: "Request line may not be null");
173: }
174:
175: CharArrayBuffer result = initBuffer(buffer);
176: doFormatRequestLine(result, reqline);
177:
178: return result;
179: }
180:
181: /**
182: * Actually formats a request line.
183: * Called from {@link #formatRequestLine}.
184: *
185: * @param buffer the empty buffer into which to format,
186: * never <code>null</code>
187: * @param reqline the request line to format, never <code>null</code>
188: */
189: protected void doFormatRequestLine(final CharArrayBuffer buffer,
190: final RequestLine reqline) {
191: final String method = reqline.getMethod();
192: final String uri = reqline.getUri();
193:
194: // room for "GET /index.html HTTP/1.1"
195: int len = method.length()
196: + 1
197: + uri.length()
198: + 1
199: + estimateProtocolVersionLen(reqline
200: .getProtocolVersion());
201: buffer.ensureCapacity(len);
202:
203: buffer.append(method);
204: buffer.append(' ');
205: buffer.append(uri);
206: buffer.append(' ');
207: appendProtocolVersion(buffer, reqline.getProtocolVersion());
208: }
209:
210: /**
211: * Formats a status line.
212: *
213: * @param statline the status line to format
214: * @param formatter the formatter to use, or
215: * <code>null</code> for the
216: * {@link #DEFAULT default}
217: *
218: * @return the formatted status line
219: */
220: public final static String formatStatusLine(
221: final StatusLine statline, LineFormatter formatter) {
222: if (formatter == null)
223: formatter = BasicLineFormatter.DEFAULT;
224: return formatter.formatStatusLine(null, statline).toString();
225: }
226:
227: // non-javadoc, see interface LineFormatter
228: public CharArrayBuffer formatStatusLine(
229: final CharArrayBuffer buffer, final StatusLine statline) {
230: if (statline == null) {
231: throw new IllegalArgumentException(
232: "Status line may not be null");
233: }
234:
235: CharArrayBuffer result = initBuffer(buffer);
236: doFormatStatusLine(result, statline);
237:
238: return result;
239: }
240:
241: /**
242: * Actually formats a status line.
243: * Called from {@link #formatStatusLine}.
244: *
245: * @param buffer the empty buffer into which to format,
246: * never <code>null</code>
247: * @param statline the status line to format, never <code>null</code>
248: */
249: protected void doFormatStatusLine(final CharArrayBuffer buffer,
250: final StatusLine statline) {
251:
252: int len = estimateProtocolVersionLen(statline
253: .getProtocolVersion()) + 1 + 3 + 1; // room for "HTTP/1.1 200 "
254: final String reason = statline.getReasonPhrase();
255: if (reason != null) {
256: len += reason.length();
257: }
258: buffer.ensureCapacity(len);
259:
260: appendProtocolVersion(buffer, statline.getProtocolVersion());
261: buffer.append(' ');
262: buffer.append(Integer.toString(statline.getStatusCode()));
263: buffer.append(' '); // keep whitespace even if reason phrase is empty
264: if (reason != null) {
265: buffer.append(reason);
266: }
267: }
268:
269: /**
270: * Formats a header.
271: *
272: * @param header the header to format
273: * @param formatter the formatter to use, or
274: * <code>null</code> for the
275: * {@link #DEFAULT default}
276: *
277: * @return the formatted header
278: */
279: public final static String formatHeader(final Header header,
280: LineFormatter formatter) {
281: if (formatter == null)
282: formatter = BasicLineFormatter.DEFAULT;
283: return formatter.formatHeader(null, header).toString();
284: }
285:
286: // non-javadoc, see interface LineFormatter
287: public CharArrayBuffer formatHeader(CharArrayBuffer buffer,
288: Header header) {
289: if (header == null) {
290: throw new IllegalArgumentException("Header may not be null");
291: }
292: CharArrayBuffer result = null;
293:
294: if (header instanceof FormattedHeader) {
295: // If the header is backed by a buffer, re-use the buffer
296: result = ((FormattedHeader) header).getBuffer();
297: } else {
298: result = initBuffer(buffer);
299: doFormatHeader(result, header);
300: }
301: return result;
302:
303: } // formatHeader
304:
305: /**
306: * Actually formats a header.
307: * Called from {@link #formatHeader}.
308: *
309: * @param buffer the empty buffer into which to format,
310: * never <code>null</code>
311: * @param header the header to format, never <code>null</code>
312: */
313: protected void doFormatHeader(final CharArrayBuffer buffer,
314: final Header header) {
315: final String name = header.getName();
316: final String value = header.getValue();
317:
318: int len = name.length() + 2;
319: if (value != null) {
320: len += value.length();
321: }
322: buffer.ensureCapacity(len);
323:
324: buffer.append(name);
325: buffer.append(": ");
326: if (value != null) {
327: buffer.append(value);
328: }
329: }
330:
331: } // class BasicLineFormatter
|