KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > attachments > MimeUtils


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the docs/licenses/apache-1.1.txt file.
7  */

8 package org.jboss.axis.attachments;
9
10 import org.jboss.axis.AxisFault;
11 import org.jboss.axis.AxisProperties;
12 import org.jboss.axis.Part;
13 import org.jboss.axis.transport.http.HTTPConstants;
14 import org.jboss.axis.utils.Messages;
15 import org.jboss.axis.utils.SessionUtils;
16 import org.jboss.logging.Logger;
17
18 import javax.activation.DataHandler JavaDoc;
19 import javax.activation.DataSource JavaDoc;
20 import javax.activation.FileDataSource JavaDoc;
21 import javax.mail.Header JavaDoc;
22 import javax.mail.MessagingException JavaDoc;
23 import javax.mail.Multipart JavaDoc;
24 import javax.mail.Session JavaDoc;
25 import javax.mail.internet.ContentType JavaDoc;
26 import javax.mail.internet.InternetHeaders JavaDoc;
27 import javax.mail.internet.MimeBodyPart JavaDoc;
28 import javax.mail.internet.MimeMessage JavaDoc;
29 import javax.mail.internet.MimeMultipart JavaDoc;
30 import java.io.ByteArrayOutputStream JavaDoc;
31 import java.io.File JavaDoc;
32 import java.io.IOException JavaDoc;
33 import java.io.InputStream JavaDoc;
34 import java.io.OutputStream JavaDoc;
35 import java.util.Collection JavaDoc;
36 import java.util.Enumeration JavaDoc;
37 import java.util.Iterator JavaDoc;
38 import java.util.Properties JavaDoc;
39
40
41 /**
42  * This class is defines utilities for mime.
43  */

44 public class MimeUtils
45 {
46
47    /**
48     * Field log
49     */

50    private static Logger log = Logger.getLogger(MimeUtils.class.getName());
51
52    /**
53     * Determine as efficiently as possible the content length for attachments in a mail Multipart.
54     *
55     * @param mp is the multipart to be serarched.
56     * @return the actual length.
57     * @throws MessagingException
58     */

59    public static long getContentLength(Multipart JavaDoc mp)
60            throws MessagingException JavaDoc
61    {
62
63       int totalParts = mp.getCount();
64       long totalContentLength = 0;
65
66       for (int i = 0; i < totalParts; ++i)
67       {
68          MimeBodyPart JavaDoc bp = (MimeBodyPart JavaDoc)mp.getBodyPart(i);
69          totalContentLength += getContentLength(bp);
70       }
71
72       String JavaDoc ctype = mp.getContentType();
73       ContentType JavaDoc ct = new ContentType JavaDoc(ctype);
74       String JavaDoc boundaryStr = ct.getParameter("boundary");
75       // must add two for -- prefix and another two for crlf
76
int boundaryStrLen = boundaryStr.length() + 4;
77
78       // there is one more boundary than parts
79
// each parts data must have crlf after it.
80
// last boundary has an additional --crlf
81
return totalContentLength + boundaryStrLen * (totalParts + 1) + 2 * totalParts + +4;
82    }
83
84    /**
85     * Determine the length for the individual part.
86     *
87     * @param bp is the part to be searched.
88     * @return the length in bytes.
89     */

90    protected static long getContentLength(MimeBodyPart JavaDoc bp)
91    {
92
93       long headerLength = -1L;
94       long dataSize = -1L;
95
96       try
97       {
98          headerLength = getHeaderLength(bp);
99
100          DataHandler JavaDoc dh = bp.getDataHandler();
101          DataSource JavaDoc ds = dh.getDataSource();
102
103          // Do files our selfs since this is costly to read in. Ask the file system.
104
// This is 90% of the use of attachments.
105
if (ds instanceof FileDataSource JavaDoc)
106          {
107             FileDataSource JavaDoc fdh = (FileDataSource JavaDoc)ds;
108             File JavaDoc df = fdh.getFile();
109
110             if (!df.exists())
111             {
112                throw new RuntimeException JavaDoc(Messages.getMessage("noFile", df.getAbsolutePath()));
113             }
114
115             dataSize = df.length();
116          }
117          else
118          {
119             dataSize = bp.getSize();
120
121             if (-1 == dataSize)
122             { // Data size is not known so read it the hard way...
123
dataSize = 0;
124
125                InputStream JavaDoc in = ds.getInputStream();
126                byte[] readbuf = new byte[64 * 1024];
127                int bytesread;
128
129                do
130                {
131                   bytesread = in.read(readbuf);
132
133                   if (bytesread > 0)
134                   {
135                      dataSize += bytesread;
136                   }
137                }
138                while (bytesread > -1);
139
140                in.close();
141             }
142          }
143       }
144       catch (Exception JavaDoc e)
145       {
146          log.error(Messages.getMessage("exception00"), e);
147       }
148
149       return dataSize + headerLength;
150    }
151
152    /**
153     * Gets the header length for any part.
154     *
155     * @param bp the part to determine the header length for.
156     * @return the length in bytes.
157     * @throws MessagingException
158     * @throws IOException
159     */

160    private static long getHeaderLength(MimeBodyPart JavaDoc bp)
161            throws MessagingException JavaDoc, IOException JavaDoc
162    {
163
164       MimeBodyPart JavaDoc headersOnly = new MimeBodyPart JavaDoc(new InternetHeaders JavaDoc(), new byte[0]);
165
166       for (Enumeration JavaDoc en = bp.getAllHeaders(); en.hasMoreElements();)
167       {
168          Header JavaDoc header = (Header JavaDoc)en.nextElement();
169          headersOnly.addHeader(header.getName(), header.getValue());
170       }
171
172       ByteArrayOutputStream JavaDoc bas = new ByteArrayOutputStream JavaDoc(1024 * 16);
173
174       headersOnly.writeTo(bas);
175       bas.close();
176
177       return (long)bas.size(); // This has header length plus the crlf part that seperates the data
178
}
179
180    /**
181     * Field filter
182     */

183    public static String JavaDoc[] filter = new String JavaDoc[]{"Message-ID", "Mime-Version",
184                                                 "Content-Type"};
185
186    /**
187     * This routine will the multi part type and write it out to a stream.
188     * <p/>
189     * <p>Note that is does *NOT* pass <code>AxisProperties</code>
190     * to <code> Session.getInstance</code>, but instead
191     * the System properties.
192     * </p>
193     *
194     * @param os is the output stream to write to.
195     * @param mp the multipart that needs to be written to the stream.
196     */

197    public static void writeToMultiPartStream(OutputStream JavaDoc os, MimeMultipart JavaDoc mp)
198    {
199
200       try
201       {
202          Properties props = AxisProperties.getProperties();
203
204          // this is a bogus since we will never mail it.
205
props.setProperty("mail.smtp.host", "localhost");
206
207          Session JavaDoc session = Session.getInstance(props, null);
208          MimeMessage JavaDoc message = new MimeMessage JavaDoc(session);
209
210          message.setContent(mp);
211          message.saveChanges();
212          message.writeTo(os, filter);
213       }
214       catch (MessagingException JavaDoc e)
215       {
216          log.error(Messages.getMessage("javaxMailMessagingException00"), e);
217       }
218       catch (IOException JavaDoc e)
219       {
220          log.error(Messages.getMessage("javaIOException00"), e);
221       }
222    }
223
224    /**
225     * This routine will get the content type.
226     *
227     * @param mp
228     * @return
229     */

230    public static String JavaDoc getContentType(MimeMultipart JavaDoc mp)
231    {
232       StringBuffer JavaDoc contentType = new StringBuffer JavaDoc(mp.getContentType());
233       // TODO (dims): Commons HttpClient croaks if we don't do this.
234
// Need to get Commons HttpClient fixed.
235
for (int i = 0; i < contentType.length();)
236       {
237          char ch = contentType.charAt(i);
238          if (ch == '\r' || ch == '\n')
239             contentType.deleteCharAt(i);
240          else
241             i++;
242       }
243       return contentType.toString();
244    }
245
246    /**
247     * This routine will create a multipart object from the parts and the SOAP content.
248     *
249     * @param env should be the text for the main root part.
250     * @param parts contain a collection of the message parts.
251     * @return a new MimeMultipart object
252     * @throws AxisFault
253     */

254    public static MimeMultipart JavaDoc createMP(String JavaDoc env, Collection JavaDoc parts)
255            throws AxisFault
256    {
257
258       MimeMultipart JavaDoc multipart = null;
259
260       try
261       {
262          String JavaDoc rootCID = SessionUtils.generateSessionId();
263
264          multipart = new MimeMultipart JavaDoc("related; type=\"text/xml\"; start=\"<" + rootCID + ">\"");
265
266          MimeBodyPart JavaDoc messageBodyPart = new MimeBodyPart JavaDoc();
267
268          messageBodyPart.setText(env, "UTF-8");
269          messageBodyPart.setHeader("Content-Type", "text/xml; charset=UTF-8");
270          messageBodyPart.setHeader("Content-Id", "<" + rootCID + ">");
271          messageBodyPart.setHeader(HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING, "binary");
272          multipart.addBodyPart(messageBodyPart);
273
274          for (Iterator JavaDoc it = parts.iterator(); it.hasNext();)
275          {
276             Part part = (Part)it.next();
277             DataHandler JavaDoc dh = AttachmentUtils.getActivationDataHandler(part);
278             String JavaDoc contentID = part.getContentId();
279
280             messageBodyPart = new MimeBodyPart JavaDoc();
281             messageBodyPart.setDataHandler(dh);
282
283             String JavaDoc contentType = part.getContentType();
284             if (contentType == null)
285                contentType = dh.getContentType();
286
287             if (contentType == null || contentType.trim().length() == 0)
288                contentType = "application/octet-stream";
289
290             messageBodyPart.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, contentType);
291             messageBodyPart.setHeader(HTTPConstants.HEADER_CONTENT_ID, "<" + contentID + ">");
292             // Safe and fastest for anything other than mail;
293
messageBodyPart.setHeader(HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING, "binary");
294
295             for (Iterator JavaDoc i = part.getNonMatchingMimeHeaders(new String JavaDoc[]{
296                HTTPConstants.HEADER_CONTENT_TYPE,
297                HTTPConstants.HEADER_CONTENT_ID,
298                HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING}); i.hasNext();)
299             {
300                javax.xml.soap.MimeHeader JavaDoc header = (javax.xml.soap.MimeHeader JavaDoc)i.next();
301                messageBodyPart.setHeader(header.getName(), header.getValue());
302             }
303
304             multipart.addBodyPart(messageBodyPart);
305          }
306       }
307       catch (MessagingException JavaDoc e)
308       {
309          log.error(Messages.getMessage("javaxMailMessagingException00"), e);
310       }
311
312       return multipart;
313    }
314 }
315
Popular Tags