KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > ristretto > message > Header


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is Ristretto Mail API.
15  *
16  * The Initial Developers of the Original Code are
17  * Timo Stich and Frederik Dietz.
18  * Portions created by the Initial Developers are Copyright (C) 2004
19  * All Rights Reserved.
20  *
21  * Contributor(s):
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */

36 package org.columba.ristretto.message;
37
38 import java.io.InputStream JavaDoc;
39 import java.util.Enumeration JavaDoc;
40 import java.util.Hashtable JavaDoc;
41
42 import org.columba.ristretto.io.CharSequenceSource;
43 import org.columba.ristretto.io.SourceInputStream;
44 import org.columba.ristretto.io.Streamable;
45
46 /**
47  * Datastructure that stores headers. This is basically
48  * comparable to a java.util.Map structure.
49  *
50  * @author tstich
51  *
52  */

53 public class Header implements Streamable {
54     private static final int MAXLINELENGTH = 78;
55     private Hashtable JavaDoc header;
56
57     private static final String JavaDoc[] unlimitedFields = {
58             "received", "x-"
59     };
60     
61
62     /**
63      * Constructs the Header.
64      */

65     public Header() {
66         header = new Hashtable JavaDoc();
67     }
68     
69     /**
70      * Set the header with the specified key.
71      *
72      * @param key
73      * @param value
74      */

75     public void set(String JavaDoc key, Object JavaDoc value) {
76         if( value instanceof String JavaDoc)
77             header.put( key, value);
78         else
79             header.put( key, value.toString());
80     }
81     
82     /**
83      * Append the value to the header with the specified key.
84      *
85      * @param key
86      * @param value
87      */

88     public void append(String JavaDoc key, String JavaDoc value) {
89         String JavaDoc oldvalue = (String JavaDoc) header.get(key);
90         if( oldvalue == null || !isUnlimited(key)) {
91             header.put(key, value);
92         } else {
93             header.put(key, oldvalue + value);
94         }
95     }
96     
97     /**
98      * Get the header with the specified key.
99      *
100      * @param key
101      * @return the header
102      */

103     public String JavaDoc get( String JavaDoc key ) {
104         return (String JavaDoc) header.get(key);
105     }
106     
107     /**
108      *
109      *
110      * @return the number of headers
111      */

112     public int length() {
113         return header.size();
114     }
115     
116     /**
117      * @see java.lang.Object#clone()
118      */

119     public Object JavaDoc clone() {
120         Header cloneHeader = new Header();
121         cloneHeader.header = (Hashtable JavaDoc) this.header.clone();
122         return cloneHeader;
123     }
124     
125     /**
126      * @return the number of headers
127      */

128     public int count() {
129         return header.size();
130     }
131
132     /**
133      * @see java.lang.Object#toString()
134      */

135     public String JavaDoc toString() {
136         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
137         Enumeration JavaDoc keys = header.keys();
138         while( keys.hasMoreElements() ) {
139             String JavaDoc key = (String JavaDoc) keys.nextElement();
140             result.append(key);
141             result.append(": ");
142             result.append( foldLine(get(key), MAXLINELENGTH - key.length() - 2) );
143             result.append( "\r\n" );
144         }
145         result.append("\r\n");
146         return result.toString();
147     }
148     
149     /**
150      * Merge the given header with this header.
151      *
152      * @param arg
153      */

154     public void merge( Header arg ) {
155         Object JavaDoc key;
156         Enumeration JavaDoc keys = arg.header.keys();
157         while( keys.hasMoreElements() ) {
158             key = keys.nextElement();
159             this.header.put( key, arg.header.get(key));
160         }
161     }
162     
163     private CharSequence JavaDoc foldLine(String JavaDoc line, int firstMaxLength) {
164         // If line must not be broken or key was too long return line as is
165
if( line.length() <= firstMaxLength || firstMaxLength <= 0) {
166             return line;
167         }
168         
169         // Try to find possible fold pos else return complete line
170
int foldPos = line.indexOf(' ', firstMaxLength);
171         if( foldPos == -1 ) {
172             return line;
173         }
174         
175         StringBuffer JavaDoc result = new StringBuffer JavaDoc( line.length() + 3);
176         result.append( line.subSequence(0, foldPos));
177         result.append("\r\n ");
178         int lastFoldPos = foldPos;
179         
180         foldPos += MAXLINELENGTH;
181         if( foldPos < line.length() ) {
182             foldPos = line.indexOf(' ', foldPos);
183         }
184         
185         while( foldPos != -1 && foldPos < line.length() ) {
186             result.append( line.subSequence(0, foldPos));
187             result.append("\r\n ");
188             lastFoldPos = foldPos;
189
190             foldPos += MAXLINELENGTH;
191             if( foldPos < line.length() ) {
192                 foldPos = line.indexOf(' ', foldPos);
193             }
194         }
195         
196         result.append(line.substring(lastFoldPos));
197         
198         return result;
199     }
200
201     /**
202      * @see org.columba.ristretto.io.Streamable#getInputStream()
203      */

204     public InputStream JavaDoc getInputStream() {
205         return new SourceInputStream( new CharSequenceSource( toString() ));
206     }
207     
208     /**
209      * Gets the keys that are stored in the header.
210      *
211      * @return the Enumeration of keys
212      */

213     public Enumeration JavaDoc getKeys() {
214         return header.keys();
215     }
216
217     private static boolean isUnlimited( String JavaDoc key) {
218         String JavaDoc ignoredCase = key.toLowerCase();
219         for( int i=0; i<unlimitedFields.length; i++) {
220             if( ignoredCase.startsWith(unlimitedFields[i])) {
221                 return true;
222             }
223         }
224         return false;
225     }
226     
227     
228 }
229
Popular Tags