KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 /**
18  * @author Rick Rineholt
19  * @author Wouter Cloetens (wouter@mind.be)
20  */

21 package org.apache.axis.attachments;
22
23 import org.apache.axis.AxisProperties;
24 import org.apache.axis.components.logger.LogFactory;
25 import org.apache.axis.transport.http.HTTPConstants;
26 import org.apache.axis.utils.Messages;
27 import org.apache.axis.utils.SessionUtils;
28 import org.apache.commons.logging.Log;
29
30 import java.util.Properties JavaDoc;
31
32
33 /**
34  * This class is defines utilities for mime.
35  */

36 public class MimeUtils {
37
38     /** Field log */
39     protected static Log log =
40         LogFactory.getLog(MimeUtils.class.getName());
41
42     /**
43      * Determine as efficiently as possible the content length for attachments in a mail Multipart.
44      * @param mp is the multipart to be serarched.
45      * @return the actual length.
46      *
47      * @throws javax.mail.MessagingException
48      * @throws java.io.IOException
49      */

50     public static long getContentLength(javax.mail.Multipart JavaDoc mp)
51             throws javax.mail.MessagingException JavaDoc, java.io.IOException JavaDoc {
52
53         int totalParts = mp.getCount();
54         long totalContentLength = 0;
55
56         for (int i = 0; i < totalParts; ++i) {
57             javax.mail.internet.MimeBodyPart JavaDoc bp =
58                     (javax.mail.internet.MimeBodyPart JavaDoc) mp.getBodyPart(i);
59
60             totalContentLength += getContentLength(bp);
61         }
62
63         String JavaDoc ctype = mp.getContentType();
64         javax.mail.internet.ContentType JavaDoc ct =
65                 new javax.mail.internet.ContentType JavaDoc(ctype);
66         String JavaDoc boundaryStr =
67                 ct.getParameter("boundary");
68         int boundaryStrLen =
69                 boundaryStr.length()
70                 + 4; // must add two for -- prefix and another two for crlf
71

72         // there is one more boundary than parts
73
// each parts data must have crlf after it.
74
// last boundary has an additional --crlf
75
return totalContentLength + boundaryStrLen * (totalParts + 1)
76                 + 2 * totalParts + +4;
77     }
78
79     /**
80      * Determine the length for the individual part.
81      * @param bp is the part to be searched.
82      * @return the length in bytes.
83      */

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

145     private static long getHeaderLength(javax.mail.internet.MimeBodyPart JavaDoc bp)
146             throws javax.mail.MessagingException JavaDoc, java.io.IOException JavaDoc {
147
148         javax.mail.internet.MimeBodyPart JavaDoc headersOnly =
149                 new javax.mail.internet.MimeBodyPart JavaDoc(
150                         new javax.mail.internet.InternetHeaders JavaDoc(), new byte[0]);
151
152         for (java.util.Enumeration JavaDoc en = bp.getAllHeaders();
153              en.hasMoreElements();) {
154             javax.mail.Header JavaDoc header = (javax.mail.Header JavaDoc) en.nextElement();
155
156             headersOnly.addHeader(header.getName(), header.getValue());
157         }
158
159         java.io.ByteArrayOutputStream JavaDoc bas =
160                 new java.io.ByteArrayOutputStream JavaDoc(1024 * 16);
161
162         headersOnly.writeTo(bas);
163         bas.close();
164
165         return (long) bas.size(); // This has header length plus the crlf part that seperates the data
166
}
167
168     // fixme: filter can be replaced as it is not final - is this intended? If
169
// so, document
170
// fixme: the fields in filter are not protected - they can be over-written
171
/** Field filter */
172     public static String JavaDoc[] filter = new String JavaDoc[]{"Message-ID", "Mime-Version",
173                                                  "Content-Type"};
174
175     /**
176      * This routine will the multi part type and write it out to a stream.
177      *
178      * <p>Note that is does *NOT* pass <code>AxisProperties</code>
179      * to <code>javax.mail.Session.getInstance</code>, but instead
180      * the System properties.
181      * </p>
182      * @param os is the output stream to write to.
183      * @param mp the multipart that needs to be written to the stream.
184      */

185     public static void writeToMultiPartStream(
186             java.io.OutputStream JavaDoc os, javax.mail.internet.MimeMultipart JavaDoc mp) {
187
188         try {
189             Properties props = AxisProperties.getProperties();
190
191             props.setProperty(
192                     "mail.smtp.host",
193                     "localhost"); // this is a bogus since we will never mail it.
194

195             javax.mail.Session JavaDoc session =
196                     javax.mail.Session.getInstance(props, null);
197             javax.mail.internet.MimeMessage JavaDoc message =
198                     new javax.mail.internet.MimeMessage JavaDoc(session);
199
200             message.setContent(mp);
201             message.saveChanges();
202             message.writeTo(os, filter);
203         } catch (javax.mail.MessagingException JavaDoc e) {
204             log.error(Messages.getMessage("javaxMailMessagingException00"), e);
205         } catch (java.io.IOException JavaDoc e) {
206             log.error(Messages.getMessage("javaIOException00"), e);
207         }
208     }
209
210     /**
211      * This routine will get the content type from a mulit-part mime message.
212      *
213      * @param mp the MimeMultipart
214      * @return the content type
215      */

216     public static String JavaDoc getContentType(javax.mail.internet.MimeMultipart JavaDoc mp) {
217         StringBuffer JavaDoc contentType = new StringBuffer JavaDoc(mp.getContentType());
218         // TODO (dims): Commons HttpClient croaks if we don't do this.
219
// Need to get Commons HttpClient fixed.
220
for(int i=0;i<contentType.length();){
221             char ch = contentType.charAt(i);
222             if(ch=='\r'||ch=='\n')
223                 contentType.deleteCharAt(i);
224             else
225                 i++;
226         }
227         return contentType.toString();
228     }
229
230     /**
231      * This routine will create a multipart object from the parts and the SOAP content.
232      * @param env should be the text for the main root part.
233      * @param parts contain a collection of the message parts.
234      *
235      * @return a new MimeMultipart object
236      *
237      * @throws org.apache.axis.AxisFault
238      */

239     public static javax.mail.internet.MimeMultipart JavaDoc createMP(
240             String JavaDoc env, java.util.Collection JavaDoc parts)
241             throws org.apache.axis.AxisFault {
242
243         javax.mail.internet.MimeMultipart JavaDoc multipart = null;
244
245         try {
246             String JavaDoc rootCID = SessionUtils.generateSessionId();
247
248             multipart = new javax.mail.internet.MimeMultipart JavaDoc(
249                     "related; type=\"text/xml\"; start=\"<" + rootCID + ">\"");
250
251             javax.mail.internet.MimeBodyPart JavaDoc messageBodyPart =
252                     new javax.mail.internet.MimeBodyPart JavaDoc();
253
254             messageBodyPart.setText(env, "UTF-8");
255             messageBodyPart.setHeader("Content-Type",
256                     "text/xml; charset=UTF-8");
257             messageBodyPart.setHeader("Content-Id", "<" + rootCID + ">");
258             messageBodyPart.setHeader(
259                     HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING, "binary");
260             multipart.addBodyPart(messageBodyPart);
261
262             for (java.util.Iterator JavaDoc it = parts.iterator(); it.hasNext();) {
263                 org.apache.axis.Part part =
264                         (org.apache.axis.Part) it.next();
265                 javax.activation.DataHandler JavaDoc dh =
266                         org.apache.axis.attachments.AttachmentUtils.getActivationDataHandler(
267                                 part);
268                 String JavaDoc contentID = part.getContentId();
269
270                 messageBodyPart = new javax.mail.internet.MimeBodyPart JavaDoc();
271
272                 messageBodyPart.setDataHandler(dh);
273
274                 String JavaDoc contentType = part.getContentType();
275                 if ((contentType == null)
276                         || (contentType.trim().length() == 0)) {
277                     contentType = dh.getContentType();
278                 }
279                 if ((contentType == null)
280                         || (contentType.trim().length() == 0)) {
281                     contentType = "application/octet-stream";
282                 }
283
284                 messageBodyPart.setHeader(HTTPConstants.HEADER_CONTENT_TYPE,
285                         contentType);
286                 messageBodyPart.setHeader(HTTPConstants.HEADER_CONTENT_ID,
287                         "<" + contentID + ">");
288                 messageBodyPart.setHeader(
289                         HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING,
290                         "binary"); // Safe and fastest for anything other than mail;
291

292                 for (java.util.Iterator JavaDoc i =
293                         part.getNonMatchingMimeHeaders(new String JavaDoc[]{
294                             HTTPConstants.HEADER_CONTENT_TYPE,
295                             HTTPConstants.HEADER_CONTENT_ID,
296                             HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING}); i.hasNext();) {
297                     javax.xml.soap.MimeHeader JavaDoc header = (javax.xml.soap.MimeHeader JavaDoc) i.next();
298
299                      messageBodyPart.setHeader(header.getName(), header.getValue());
300                 }
301
302                 multipart.addBodyPart(messageBodyPart);
303             }
304         } catch (javax.mail.MessagingException JavaDoc e) {
305             log.error(Messages.getMessage("javaxMailMessagingException00"), e);
306         }
307
308         return multipart;
309     }
310 }
311
Popular Tags