• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicLineFormatter.java $
3  * $Revision: 574185 $
4  * $Date: 2007-09-10 02:19:47 -0700 (Mon, 10 Sep 2007) $
5  *
6  * ====================================================================
7  * Licensed to the Apache Software Foundation (ASF) under one
8  * or more contributor license agreements.  See the NOTICE file
9  * distributed with this work for additional information
10  * regarding copyright ownership.  The ASF licenses this file
11  * to you under the Apache License, Version 2.0 (the
12  * "License"); you may not use this file except in compliance
13  * with the License.  You may obtain a copy of the License at
14  *
15  *   http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing,
18  * software distributed under the License is distributed on an
19  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20  * KIND, either express or implied.  See the License for the
21  * specific language governing permissions and limitations
22  * under the License.
23  * ====================================================================
24  *
25  * This software consists of voluntary contributions made by many
26  * individuals on behalf of the Apache Software Foundation.  For more
27  * information on the Apache Software Foundation, please see
28  * <http://www.apache.org/>.
29  *
30  */
31 
32 package org.apache.http.message;
33 
34 
35 import org.apache.http.ProtocolVersion;
36 import org.apache.http.RequestLine;
37 import org.apache.http.StatusLine;
38 import org.apache.http.Header;
39 import org.apache.http.FormattedHeader;
40 import org.apache.http.util.CharArrayBuffer;
41 
42 
43 /**
44  * Interface for formatting elements of the HEAD section of an HTTP message.
45  * This is the complement to {@link LineParser}.
46  * There are individual methods for formatting a request line, a
47  * status line, or a header line. The formatting does <i>not</i> include the
48  * trailing line break sequence CR-LF.
49  * The formatted lines are returned in memory, the formatter does not depend
50  * on any specific IO mechanism.
51  * Instances of this interface are expected to be stateless and thread-safe.
52  *
53  * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
54  * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
55  * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
56  * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
57  * @author and others
58  *
59  *
60  * <!-- empty lines above to avoid 'svn diff' context problems -->
61  * @version $Revision: 574185 $
62  *
63  * @since 4.0
64  */
65 public class BasicLineFormatter implements LineFormatter {
66 
67     /**
68      * A default instance of this class, for use as default or fallback.
69      * Note that {@link BasicLineFormatter} is not a singleton, there can
70      * be many instances of the class itself and of derived classes.
71      * The instance here provides non-customized, default behavior.
72      */
73     public final static BasicLineFormatter DEFAULT = new BasicLineFormatter();
74 
75 
76 
77     // public default constructor
78 
79 
80     /**
81      * Obtains a buffer for formatting.
82      *
83      * @param buffer    a buffer already available, or <code>null</code>
84      *
85      * @return  the cleared argument buffer if there is one, or
86      *          a new empty buffer that can be used for formatting
87      */
initBuffer(CharArrayBuffer buffer)88     protected CharArrayBuffer initBuffer(CharArrayBuffer buffer) {
89         if (buffer != null) {
90             buffer.clear();
91         } else {
92             buffer = new CharArrayBuffer(64);
93         }
94         return buffer;
95     }
96 
97 
98     /**
99      * Formats a protocol version.
100      *
101      * @param version           the protocol version to format
102      * @param formatter         the formatter to use, or
103      *                          <code>null</code> for the
104      *                          {@link #DEFAULT default}
105      *
106      * @return  the formatted protocol version
107      */
108     public final static
formatProtocolVersion(final ProtocolVersion version, LineFormatter formatter)109         String formatProtocolVersion(final ProtocolVersion version,
110                                      LineFormatter formatter) {
111         if (formatter == null)
112             formatter = BasicLineFormatter.DEFAULT;
113         return formatter.appendProtocolVersion(null, version).toString();
114     }
115 
116 
117     // non-javadoc, see interface LineFormatter
appendProtocolVersion(final CharArrayBuffer buffer, final ProtocolVersion version)118     public CharArrayBuffer appendProtocolVersion(final CharArrayBuffer buffer,
119                                                  final ProtocolVersion version) {
120         if (version == null) {
121             throw new IllegalArgumentException
122                 ("Protocol version may not be null");
123         }
124 
125         // can't use initBuffer, that would clear the argument!
126         CharArrayBuffer result = buffer;
127         final int len = estimateProtocolVersionLen(version);
128         if (result == null) {
129             result = new CharArrayBuffer(len);
130         } else {
131             result.ensureCapacity(len);
132         }
133 
134         result.append(version.getProtocol());
135         result.append('/');
136         result.append(Integer.toString(version.getMajor()));
137         result.append('.');
138         result.append(Integer.toString(version.getMinor()));
139 
140         return result;
141     }
142 
143 
144     /**
145      * Guesses the length of a formatted protocol version.
146      * Needed to guess the length of a formatted request or status line.
147      *
148      * @param version   the protocol version to format, or <code>null</code>
149      *
150      * @return  the estimated length of the formatted protocol version,
151      *          in characters
152      */
estimateProtocolVersionLen(final ProtocolVersion version)153     protected int estimateProtocolVersionLen(final ProtocolVersion version) {
154         return version.getProtocol().length() + 4; // room for "HTTP/1.1"
155     }
156 
157 
158     /**
159      * Formats a request line.
160      *
161      * @param reqline           the request line to format
162      * @param formatter         the formatter to use, or
163      *                          <code>null</code> for the
164      *                          {@link #DEFAULT default}
165      *
166      * @return  the formatted request line
167      */
formatRequestLine(final RequestLine reqline, LineFormatter formatter)168     public final static String formatRequestLine(final RequestLine reqline,
169                                                  LineFormatter formatter) {
170         if (formatter == null)
171             formatter = BasicLineFormatter.DEFAULT;
172         return formatter.formatRequestLine(null, reqline).toString();
173     }
174 
175 
176     // non-javadoc, see interface LineFormatter
formatRequestLine(CharArrayBuffer buffer, RequestLine reqline)177     public CharArrayBuffer formatRequestLine(CharArrayBuffer buffer,
178                                              RequestLine reqline) {
179         if (reqline == null) {
180             throw new IllegalArgumentException
181                 ("Request line may not be null");
182         }
183 
184         CharArrayBuffer result = initBuffer(buffer);
185         doFormatRequestLine(result, reqline);
186 
187         return result;
188     }
189 
190 
191     /**
192      * Actually formats a request line.
193      * Called from {@link #formatRequestLine}.
194      *
195      * @param buffer    the empty buffer into which to format,
196      *                  never <code>null</code>
197      * @param reqline   the request line to format, never <code>null</code>
198      */
doFormatRequestLine(final CharArrayBuffer buffer, final RequestLine reqline)199     protected void doFormatRequestLine(final CharArrayBuffer buffer,
200                                        final RequestLine reqline) {
201         final String method = reqline.getMethod();
202         final String uri    = reqline.getUri();
203 
204         // room for "GET /index.html HTTP/1.1"
205         int len = method.length() + 1 + uri.length() + 1 +
206             estimateProtocolVersionLen(reqline.getProtocolVersion());
207         buffer.ensureCapacity(len);
208 
209         buffer.append(method);
210         buffer.append(' ');
211         buffer.append(uri);
212         buffer.append(' ');
213         appendProtocolVersion(buffer, reqline.getProtocolVersion());
214     }
215 
216 
217 
218     /**
219      * Formats a status line.
220      *
221      * @param statline          the status line to format
222      * @param formatter         the formatter to use, or
223      *                          <code>null</code> for the
224      *                          {@link #DEFAULT default}
225      *
226      * @return  the formatted status line
227      */
formatStatusLine(final StatusLine statline, LineFormatter formatter)228     public final static String formatStatusLine(final StatusLine statline,
229                                                 LineFormatter formatter) {
230         if (formatter == null)
231             formatter = BasicLineFormatter.DEFAULT;
232         return formatter.formatStatusLine(null, statline).toString();
233     }
234 
235 
236     // non-javadoc, see interface LineFormatter
formatStatusLine(final CharArrayBuffer buffer, final StatusLine statline)237     public CharArrayBuffer formatStatusLine(final CharArrayBuffer buffer,
238                                             final StatusLine statline) {
239         if (statline == null) {
240             throw new IllegalArgumentException
241                 ("Status line may not be null");
242         }
243 
244         CharArrayBuffer result = initBuffer(buffer);
245         doFormatStatusLine(result, statline);
246 
247         return result;
248     }
249 
250 
251     /**
252      * Actually formats a status line.
253      * Called from {@link #formatStatusLine}.
254      *
255      * @param buffer    the empty buffer into which to format,
256      *                  never <code>null</code>
257      * @param statline  the status line to format, never <code>null</code>
258      */
doFormatStatusLine(final CharArrayBuffer buffer, final StatusLine statline)259     protected void doFormatStatusLine(final CharArrayBuffer buffer,
260                                       final StatusLine statline) {
261 
262         int len = estimateProtocolVersionLen(statline.getProtocolVersion())
263             + 1 + 3 + 1; // room for "HTTP/1.1 200 "
264         final String reason = statline.getReasonPhrase();
265         if (reason != null) {
266             len += reason.length();
267         }
268         buffer.ensureCapacity(len);
269 
270         appendProtocolVersion(buffer, statline.getProtocolVersion());
271         buffer.append(' ');
272         buffer.append(Integer.toString(statline.getStatusCode()));
273         buffer.append(' '); // keep whitespace even if reason phrase is empty
274         if (reason != null) {
275             buffer.append(reason);
276         }
277     }
278 
279 
280     /**
281      * Formats a header.
282      *
283      * @param header            the header to format
284      * @param formatter         the formatter to use, or
285      *                          <code>null</code> for the
286      *                          {@link #DEFAULT default}
287      *
288      * @return  the formatted header
289      */
formatHeader(final Header header, LineFormatter formatter)290     public final static String formatHeader(final Header header,
291                                             LineFormatter formatter) {
292         if (formatter == null)
293             formatter = BasicLineFormatter.DEFAULT;
294         return formatter.formatHeader(null, header).toString();
295     }
296 
297 
298     // non-javadoc, see interface LineFormatter
formatHeader(CharArrayBuffer buffer, Header header)299     public CharArrayBuffer formatHeader(CharArrayBuffer buffer,
300                                         Header header) {
301         if (header == null) {
302             throw new IllegalArgumentException
303                 ("Header may not be null");
304         }
305         CharArrayBuffer result = null;
306 
307         if (header instanceof FormattedHeader) {
308             // If the header is backed by a buffer, re-use the buffer
309             result = ((FormattedHeader)header).getBuffer();
310         } else {
311             result = initBuffer(buffer);
312             doFormatHeader(result, header);
313         }
314         return result;
315 
316     } // formatHeader
317 
318 
319     /**
320      * Actually formats a header.
321      * Called from {@link #formatHeader}.
322      *
323      * @param buffer    the empty buffer into which to format,
324      *                  never <code>null</code>
325      * @param header    the header to format, never <code>null</code>
326      */
doFormatHeader(final CharArrayBuffer buffer, final Header header)327     protected void doFormatHeader(final CharArrayBuffer buffer,
328                                   final Header header) {
329         final String name = header.getName();
330         final String value = header.getValue();
331 
332         int len = name.length() + 2;
333         if (value != null) {
334             len += value.length();
335         }
336         buffer.ensureCapacity(len);
337 
338         buffer.append(name);
339         buffer.append(": ");
340         if (value != null) {
341             buffer.append(value);
342         }
343     }
344 
345 
346 } // class BasicLineFormatter
347