KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > protomatter > util > MIMEAttachment


1 package com.protomatter.util;
2
3 /**
4  * {{{ The Protomatter Software License, Version 1.0
5  * derived from The Apache Software License, Version 1.1
6  *
7  * Copyright (c) 1998-2002 Nate Sammons. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed for the
24  * Protomatter Software Project
25  * (http://protomatter.sourceforge.net/)."
26  * Alternately, this acknowledgment may appear in the software itself,
27  * if and wherever such third-party acknowledgments normally appear.
28  *
29  * 4. The names "Protomatter" and "Protomatter Software Project" must
30  * not be used to endorse or promote products derived from this
31  * software without prior written permission. For written
32  * permission, please contact support@protomatter.com.
33  *
34  * 5. Products derived from this software may not be called "Protomatter",
35  * nor may "Protomatter" appear in their name, without prior written
36  * permission of the Protomatter Software Project
37  * (support@protomatter.com).
38  *
39  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42  * DISCLAIMED. IN NO EVENT SHALL THE PROTOMATTER SOFTWARE PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE. }}}
51  */

52
53 import java.io.*;
54 import java.util.*;
55
56 /**
57  * This class is used in conjunction with the MIMEMessage class
58  * to make a multipart MIME message. A MIMEAttachment enacpsulates
59  * a single attachment (i.e. an image, a document, etc). Attached
60  * binaries are encoded using the Base64 method.
61  *
62  * @see MIMEMessage
63  */

64 public class MIMEAttachment
65 implements Serializable
66 {
67   private Hashtable headers = new Hashtable();
68   private boolean isBinary = false;
69   private byte[] content = null;
70   private static String JavaDoc CRLF = "\r\n";
71
72   /**
73    * Create a MIMEAttachment object with the given MIME content type and
74    * description. The content will not be encoded using Base64.
75    */

76   public MIMEAttachment(String JavaDoc type, String JavaDoc description, String JavaDoc content)
77   {
78     this();
79     setHeader("Content-Type", type);
80     setHeader("Content-Description", description);
81     this.content = content.getBytes();
82     setBinary(false);
83   }
84
85   /**
86    * Create a MIMEAttachment object with the given MIME content type and
87    * description. The content will be encoded using Base64 if
88    * the <TT>isBinary</TT> flag is <tt>true</TT>.
89    */

90   public MIMEAttachment(String JavaDoc type, String JavaDoc description, byte[] data, boolean isBinary)
91   {
92     this(type, description, data);
93     setBinary(isBinary);
94   }
95
96   /**
97    * Create a MIMEAttachment object with the given MIME type and
98    * description. The content will be encoded using Base64.
99    */

100   public MIMEAttachment(String JavaDoc type, String JavaDoc description, byte[] data)
101   {
102     this();
103     setHeader("Content-Type", type);
104     setHeader("Content-Description", description);
105     this.content = data;
106     setBinary(true);
107   }
108
109   /**
110    * Create an empty attachment.
111    */

112   public MIMEAttachment()
113   {
114     super();
115   }
116
117   /**
118    * Set the headers. Keys and values in
119    * must be strings.
120    */

121   public void setHeaders(Hashtable headers)
122   {
123     this.headers = headers;
124   }
125
126   /**
127    * Set the flag to indicate that the content
128    * of this attachment is binary.
129    */

130   public void setBinary(boolean b)
131   {
132     isBinary = b;
133   }
134
135   /**
136    * Set the content of this attachment.
137    */

138   public void setContent(String JavaDoc content)
139   {
140     this.content = content.getBytes();
141   }
142
143   /**
144    * Set the content of this attachment.
145    */

146   public void setContent(byte[] content)
147   {
148     this.content = content;
149   }
150
151   /**
152    * Set a header value.
153    */

154   public void setHeader(String JavaDoc headerName, String JavaDoc headerVal)
155   {
156     headers.put(headerName, headerVal);
157   }
158
159   /**
160    * Remove a header value.
161    */

162   public void removeHeader(String JavaDoc headerName)
163   {
164     headers.remove(headerName);
165   }
166
167   /**
168    * Get a header value.
169    */

170   public String JavaDoc getHeader(String JavaDoc headerName)
171   {
172     String JavaDoc val = (String JavaDoc)headers.get(headerName);
173     return val;
174   }
175
176   /**
177    * Some headers (such as Content-Disposition) have multiple
178    * key="value" pairs associated with them. This method allows
179    * you to get at those values easily. For instance, to get
180    * the "filename" chunk of the "Content-Disposition" header,
181    * call getSubHeader("Content-Disposition", "filename");
182    * If you call it with sub = "", it will retrieve the first
183    * value (which doesn't have a name)
184    */

185   public String JavaDoc getSubHeader(String JavaDoc name, String JavaDoc sub)
186   {
187     String JavaDoc h = getHeader(name);
188     if (h == null) // not going to find much there.
189
return h;
190     StringTokenizer st = new StringTokenizer(h, ";");
191     if (sub.equals(""))
192       return stripSurroundingWhiteSpace(st.nextToken());
193     else
194       st.nextToken(); // skip the first one.
195
while (st.hasMoreTokens())
196     {
197       StringTokenizer nst = new StringTokenizer(stripSurroundingWhiteSpace(st.nextToken()), "=");
198       String JavaDoc key = nst.nextToken();
199       String JavaDoc val = nst.nextToken();
200       if (key.equals(sub))
201       {
202         if (val.startsWith("\"") && val.endsWith("\""))
203           return val.substring(1, val.length() -1);
204         else
205           return val;
206       }
207     }
208     // not found.
209
return "";
210   }
211
212   // used by getSubHeader
213
private static String JavaDoc stripSurroundingWhiteSpace(String JavaDoc s)
214   {
215     int i=0; // index of first non-whitespace char
216
int j=0; // index of last non-whitespace char
217
for (i=0; i<s.length() && Character.isWhitespace(s.charAt(i)); i++);
218     for (j=s.length()-1; j>=0 && Character.isWhitespace(s.charAt(j)); j--);
219     return s.substring(i, j+1);
220   }
221
222   /**
223    * Produces a chunk of text, including the encoded attachment object
224    */

225   public String JavaDoc toString()
226   {
227     StringWriter sw = new StringWriter();
228     PrintWriter pw = new PrintWriter(sw);
229     write(pw);
230     pw.flush();
231     return sw.toString();
232   }
233
234   /**
235    * Append the content of this attachment to
236    * the given StringBuffer.
237    */

238   public void write(PrintWriter w)
239   {
240     Enumeration e = headers.keys();
241     while (e.hasMoreElements())
242     {
243       String JavaDoc hName = (String JavaDoc)e.nextElement();
244       String JavaDoc hVal = getHeader(hName);
245       w.print(hName);
246       w.print(": ");
247       w.print(hVal);
248       w.print(CRLF);
249     }
250     if (isBinary())
251     {
252       if (getHeader("Content-Transfer-Encoding") == null)
253       {
254         w.print("Content-Transfer-Encoding: BASE64");
255         w.print(CRLF);
256       }
257       w.print(CRLF);
258       w.print(CRLF);
259       String JavaDoc encoded = Base64.encode(content);
260
261       // split the content up into 65 character wide blocks
262
int start = 0;
263       int end = 65;
264       while (start < encoded.length())
265       {
266         if (end >= encoded.length())
267           end = encoded.length();
268         w.print(encoded.substring(start, end));
269         w.print(CRLF);
270         start = end;
271         end += 65;
272       }
273     }
274     else // content == null, contentString != null
275
{
276       w.print(CRLF);
277       w.print(new String JavaDoc(content));
278     }
279   }
280
281   /**
282    * Return the content. If it's binary, it's a byte array
283    * of binary data, if it's ASCII, you can just call
284    * <TT>new String(attachmentgetContent())</TT>.
285    */

286   public byte[] getContent()
287   {
288     return content;
289   }
290
291   /**
292    * Get an Enumeration of the header names.
293    */

294   public Enumeration getHeaderNames()
295   {
296     return headers.keys();
297   }
298
299   /**
300    * Is the content of the attachment ascii or binary?
301    */

302   public boolean isBinary()
303   {
304     return isBinary;
305   }
306 }
307
Popular Tags