KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > petals > binding > mail > listeners > MimeMessageManager


1 /**
2  * PETALS - PETALS Services Platform.
3  * Copyright (c) 2006 EBM Websourcing, http://www.ebmwebsourcing.com/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * -------------------------------------------------------------------------
19  * $Id: MimeMessageManager.java 154 27 sept. 06 ofabre $
20  * -------------------------------------------------------------------------
21  */

22
23 package org.objectweb.petals.binding.mail.listeners;
24
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.util.Date JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Set JavaDoc;
30 import java.util.logging.Logger JavaDoc;
31
32 import javax.activation.DataHandler JavaDoc;
33 import javax.jbi.JBIException;
34 import javax.jbi.component.ComponentContext;
35 import javax.jbi.messaging.DeliveryChannel;
36 import javax.jbi.messaging.InOnly;
37 import javax.jbi.messaging.MessageExchange;
38 import javax.jbi.messaging.NormalizedMessage;
39 import javax.mail.Message JavaDoc;
40 import javax.mail.MessagingException JavaDoc;
41 import javax.mail.Multipart JavaDoc;
42 import javax.mail.Part JavaDoc;
43 import javax.mail.Session JavaDoc;
44 import javax.mail.internet.InternetAddress JavaDoc;
45 import javax.mail.internet.MimeBodyPart JavaDoc;
46 import javax.mail.internet.MimeMessage JavaDoc;
47 import javax.mail.internet.MimeMultipart JavaDoc;
48 import javax.xml.namespace.QName JavaDoc;
49 import javax.xml.transform.Source JavaDoc;
50
51 import org.objectweb.petals.component.common.PEtALSComponentSDKException;
52 import org.objectweb.petals.component.common.bc.AbstractBindingComponent;
53 import org.objectweb.petals.component.common.util.SourceHelper;
54 import org.objectweb.petals.tools.jbicommon.util.StringHelper;
55
56 /**
57  * This class is used to process (reading or creating) mail messages
58  *
59  * @author ofabre - EBM Websourcing
60  *
61  */

62 public class MimeMessageManager {
63
64     protected AbstractBindingComponent component;
65
66     protected Logger JavaDoc log;
67
68     protected String JavaDoc MEP = "mep";
69
70     protected String JavaDoc IN_ONLY_MEP = "in-only";
71
72     protected String JavaDoc ROBUST_IN_ONLY_MEP = "robust-in-only";
73
74     protected String JavaDoc IN_OUT_MEP = "in-out";
75
76     protected String JavaDoc IN_OPTIONAL_OUT_MEP = "in-optional-out";
77
78     protected String JavaDoc OPERATION = "operation";
79
80     /**
81      *
82      * @param context
83      * the {@link ComponentContext}
84      * @param log
85      * the component {@link Logger}
86      * @param component
87      * the component that instanciate this manager
88      * @param channel
89      * the component {@link DeliveryChannel}
90      */

91     public MimeMessageManager(Logger JavaDoc log, AbstractBindingComponent component) {
92         super();
93         this.log = log;
94         this.component = component;
95     }
96
97     /**
98      * Create a {@link MimeMessage} from the given {@link NormalizedMessage},
99      * including mail {@link Session} information.
100      *
101      * @param session
102      * the mail {@link Session}
103      * @param internetAddress
104      * the recipient {@link InternetAddress}
105      * @param in
106      * the mapped {@link NormalizedMessage}
107      * @return the created {@link MimeMessage}
108      * @throws JBIException
109      * if an error occurs during {@link MimeMessage} creation
110      */

111     public MimeMessage JavaDoc mapNormalizedMessageToMimeMessage(Session JavaDoc session,
112         InternetAddress JavaDoc internetAddress, NormalizedMessage in)
113         throws JBIException {
114
115         MimeMessage JavaDoc mimeMessage = new MimeMessage JavaDoc(session);
116
117         // Set MimeMessage attributes
118
setMimeMessageAttributes(mimeMessage, internetAddress);
119
120         Multipart JavaDoc multipart = new MimeMultipart JavaDoc();
121
122         // Set MimeMessage body
123
setMimeMessageBody(multipart, in);
124
125         // Set MimeMessage attachements
126
setMimeMessageAttachments(multipart, in);
127
128         try {
129             mimeMessage.setContent(multipart);
130         } catch (javax.mail.MessagingException JavaDoc e) {
131             String JavaDoc msg = "Error setting Mime message content "
132                 + "with all information collected from NormalizedMessage";
133             log.severe(msg);
134             throw new JBIException(msg, e);
135         }
136
137         return mimeMessage;
138     }
139
140     /**
141      * Add {@link NormalizedMessage} attachments to {@link MimeMessage}
142      * attachments. If an error occurs during the transmission of an attachment,
143      * it is skipped and the process continues with other attachments.
144      *
145      * @param multipart
146      * the {@link Multipart} used to handle attachments
147      * @param in
148      * the {@link NormalizedMessage} handling attachments that have
149      * to be transmitted
150      */

151     @SuppressWarnings JavaDoc("unchecked")
152     protected void setMimeMessageAttachments(Multipart JavaDoc multipart,
153         NormalizedMessage in) {
154         Set JavaDoc<String JavaDoc> attachmentIds = in.getAttachmentNames();
155         Set JavaDoc<DataHandler JavaDoc> attachments = new HashSet JavaDoc<DataHandler JavaDoc>();
156         if (attachmentIds != null) {
157             for (String JavaDoc id : attachmentIds) {
158                 attachments.add(in.getAttachment(id));
159             }
160         }
161         if (attachments != null && !attachments.isEmpty()) {
162             MimeBodyPart JavaDoc attachementBodyPart = null;
163             for (DataHandler JavaDoc handler : attachments) {
164                 attachementBodyPart = new MimeBodyPart JavaDoc();
165                 try {
166                     attachementBodyPart.setDataHandler(handler);
167                     attachementBodyPart.setFileName(handler.getName());
168                     multipart.addBodyPart(attachementBodyPart);
169                 } catch (javax.mail.MessagingException JavaDoc e) {
170                     String JavaDoc msg = "Error setting MimeMessage attachments";
171                     log.severe(msg);
172
173                 }
174             }
175         }
176     }
177
178     /**
179      * Set {@link MimeMessage} recipient, subject and date.
180      *
181      * @param mimeMessage
182      * the {@link MimeMessage} to set
183      * @param internetAddress
184      * the {@link InternetAddress} of the recipient
185      * @throws JBIException
186      * if an error occurs during {@link MimeMessage} setting
187      */

188     protected void setMimeMessageAttributes(MimeMessage JavaDoc mimeMessage,
189         InternetAddress JavaDoc internetAddress) throws JBIException {
190         try {
191             mimeMessage.setRecipient(Message.RecipientType.TO, internetAddress);
192
193             mimeMessage.setSubject(component.getContext().getComponentName());
194
195             mimeMessage.setSentDate(new Date JavaDoc());
196         } catch (javax.mail.MessagingException JavaDoc e) {
197             String JavaDoc msg = "Error setting MimeMessage attributes";
198             log.severe(msg);
199             throw new JBIException(msg, e);
200         }
201     }
202
203     /**
204      * Set the {@link MimeMessage} body from the {@link NormalizedMessage}
205      * content.
206      *
207      * @param multipart
208      * the {@link Multipart} that will handle the
209      * {@link NormalizedMessage} content
210      * @param in
211      * the {@link NormalizedMessage} that handle an xml content
212      * @throws JBIException
213      * if the {@link Multipart} body setting failed
214      */

215     protected void setMimeMessageBody(Multipart JavaDoc multipart, NormalizedMessage in)
216         throws JBIException {
217         MimeBodyPart JavaDoc messageBodyPart = new MimeBodyPart JavaDoc();
218         String JavaDoc content = null;
219         try {
220             if (in.getContent() != null) {
221                 content = SourceHelper.createString(in.getContent());
222             }
223         } catch (Exception JavaDoc e) {
224             throw new JBIException(e);
225         }
226
227         try {
228             messageBodyPart.setContent(content, "text/plain");
229             multipart.addBodyPart(messageBodyPart);
230         } catch (javax.mail.MessagingException JavaDoc e) {
231             throw new JBIException(e);
232         }
233     }
234
235     /**
236      * Create a {@link MessageExchange} from a mail {@link Message} and send it
237      * to the component linked to the given address. Operation and Message
238      * Exchange Pattern are specified in the mail {@link Message} subject,
239      * following this pattern :
240      * <p>
241      * operation=<op_value>;mep=<mep_value> For the moment, only InOnly mep is
242      * allowed. If no mep is specified, it is automaticaly set to InOnly
243      *
244      * @param message
245      * the mail {@link Message} to process
246      * @param address
247      * an external service address linked to an internal JBI
248      * component
249      * @throws JBIException
250      * if an error occurs during parameter retrieval from subject,
251      * during {@link MessageExchange} creation or during
252      * {@link MessageExchange} sending
253      */

254     public void process(Message message, String JavaDoc address) throws JBIException {
255         // Retrieve Operation and MEP (Message Exchange Pattern) from subject.
256
// Subject follows this pattern : operation=<op_value>;mep=<mep_value>
257
String JavaDoc subject;
258         try {
259             subject = message.getSubject();
260         } catch (MessagingException JavaDoc e1) {
261             String JavaDoc msg = "Error retrieving subject of a mail";
262             throw new JBIException(msg, e1);
263         }
264         String JavaDoc operation = StringHelper.extractValueForAttribute(subject,
265             OPERATION, ";");
266         String JavaDoc mep = StringHelper.extractValueForAttribute(subject, MEP, ";");
267
268         // For the moment, MailBC only accepts InOnly MEP. If provided mep is
269
// null or empty, it is automatically set to InOnly
270
if (!IN_ONLY_MEP.equalsIgnoreCase(mep)) {
271             if (!StringHelper.isNullOrEmpty(mep)) {
272                 String JavaDoc msg = "Message Exchange Pattern (MEP) not supported"
273                     + mep;
274                 throw new JBIException(msg);
275             } else {
276                 mep = IN_ONLY_MEP;
277             }
278         }
279
280         // Create jbi message content and attachments from mail message.
281
// Recursively call the following method to treat multipart messages.
282
StringBuffer JavaDoc jbiContent = new StringBuffer JavaDoc();
283         Set JavaDoc<DataHandler JavaDoc> attachments = new HashSet JavaDoc<DataHandler JavaDoc>();
284         try {
285             createJBIContentAndAttachments(message, jbiContent, attachments);
286         } catch (Exception JavaDoc e) {
287             // Mail Message is regarded as a whole, so if an error occurs during
288
// processing, the whole message is skipped
289
String JavaDoc msg = "Error during mail message processing, "
290                 + "cannot create jbi content and attachment";
291             throw new JBIException(msg, e);
292         }
293
294         // Create the JBI Message exchange
295
MessageExchange exchange = null;
296         try {
297             exchange = createJBIMessageExchange(operation, mep, jbiContent
298                 .toString(), attachments);
299         } catch (javax.jbi.messaging.MessagingException e) {
300             String JavaDoc msg = "Error during creation of the JBI "
301                 + "message exchange from mail information";
302             throw new JBIException(msg, e);
303         }
304
305         // Send the message
306
try {
307             component.sendMessage(address, exchange);
308         } catch (javax.jbi.messaging.MessagingException e) {
309             throw new JBIException(e);
310         }
311
312     }
313
314     /**
315      * Create a new Message exchange with the provided information. Create only
316      * InOnly Message exchange for the moment.
317      *
318      * @param operation
319      * @param mep
320      * @param jbiContent
321      * @param attachments
322      * @return
323      * @throws javax.jbi.messaging.MessagingException
324      */

325     protected MessageExchange createJBIMessageExchange(String JavaDoc operation,
326         String JavaDoc mep, String JavaDoc jbiContent, Set JavaDoc<DataHandler JavaDoc> attachments)
327         throws javax.jbi.messaging.MessagingException {
328         MessageExchange message = null;
329         if (IN_ONLY_MEP.equalsIgnoreCase(mep)) {
330             message = createInOnlyMessageExchange(operation, jbiContent,
331                 attachments);
332         }
333         return message;
334     }
335
336     /**
337      * Create an InOnly {@link MessageExchange}, then fill it with the given
338      * information (operation, content and attachments).
339      *
340      * @param operation
341      * the service operation to invoke
342      * @param jbiContent
343      * the {@link NormalizedMessage} content
344      * @param attachments
345      * the {@link NormalizedMessage} attachments
346      * @return the created InOnly {@link MessageExchange}
347      * @throws javax.jbi.messaging.MessagingException
348      * if an error occured during {@link MessageExchange} creation
349      * and filling
350      */

351     protected InOnly createInOnlyMessageExchange(String JavaDoc operation,
352         String JavaDoc jbiContent, Set JavaDoc<DataHandler JavaDoc> attachments)
353         throws javax.jbi.messaging.MessagingException {
354
355         // Create message exchange
356
InOnly msg = component.getChannel().createExchangeFactory().createInOnlyExchange();
357
358         // Create the "in" normalized message
359
NormalizedMessage nm = msg.createMessage();
360
361         // Fill content
362
Source JavaDoc source;
363         try {
364             source = SourceHelper.createSource(jbiContent);
365         } catch (PEtALSComponentSDKException e) {
366             throw new javax.jbi.messaging.MessagingException(
367                 "Can't create source from String content", e);
368         }
369         nm.setContent(source);
370
371         // Fill attachments
372
if (!attachments.isEmpty()) {
373             for (DataHandler JavaDoc handler : attachments) {
374                 nm.addAttachment(handler.getName(), handler);
375             }
376         }
377
378         // Add message to message exchange
379
msg.setMessage(nm, "IN");
380
381         // Set Operation
382
if (!StringHelper.isNullOrEmpty(operation)) {
383             msg.setOperation(new QName JavaDoc(operation));
384         }
385
386         return msg;
387     }
388
389     /**
390      * Create jbi content (StringBuffer) and jbi attachments (Set<DataHandler>)
391      * from a mail {@link Part}. If the given message {@link Part} is a
392      * {@link Multipart}, all sub part are recursively processed.
393      *
394      * @param message
395      * the mail {@link Part} to process
396      * @param jbiContent
397      * the resulting jbi content (a StringBuffer)
398      * @param attachments
399      * the resulting jbi attachments (Set<DataHandler>)
400      * @throws IOException
401      * if error occured during processing
402      * @throws MessagingException
403      * if error occured during processing
404      */

405     protected void createJBIContentAndAttachments(Part JavaDoc message,
406         StringBuffer JavaDoc jbiContent, Set JavaDoc<DataHandler JavaDoc> attachments)
407         throws IOException JavaDoc, MessagingException JavaDoc {
408         Object JavaDoc content = message.getContent();
409         if (content instanceof String JavaDoc) {
410             jbiContent.append(content);
411         } else if (content instanceof Multipart JavaDoc) {
412             Multipart JavaDoc mp = (Multipart JavaDoc) content;
413             int count = mp.getCount();
414             for (int i = 0; i < count; i++) {
415                 createJBIContentAndAttachments(mp.getBodyPart(i), jbiContent,
416                     attachments);
417             }
418         } else if (content instanceof InputStream JavaDoc) {
419             attachments.add(message.getDataHandler());
420         }
421     }
422 }
423
Popular Tags