001: package org.claros.commons.mail.parser;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.InputStream;
005: import java.io.UnsupportedEncodingException;
006: import java.util.ArrayList;
007: import java.util.Enumeration;
008:
009: import javax.mail.Header;
010: import javax.mail.Message;
011: import javax.mail.MessagingException;
012: import javax.mail.Multipart;
013: import javax.mail.Part;
014:
015: import org.apache.commons.logging.Log;
016: import org.apache.commons.logging.LogFactory;
017: import org.claros.commons.mail.models.Email;
018: import org.claros.commons.mail.models.EmailPart;
019: import org.claros.commons.mail.models.EmailHeader;
020: import org.claros.commons.mail.models.EmailSensitivity;
021: import org.claros.commons.mail.utility.Utility;
022: import org.claros.commons.utility.Formatter;
023:
024: /**
025: * @author Umut Gokbayrak
026: *
027: */
028: public class MessageParser {
029: private static Log log = LogFactory.getLog(MessageParser.class);
030:
031: /**
032: *
033: */
034: public MessageParser() {
035: super ();
036: }
037:
038: public static final Email parseMessage(Message pop3Msg) {
039: Email msg = new Email();
040:
041: // get base headers
042: try {
043: EmailHeader header = new EmailHeader();
044: header.setFrom(pop3Msg.getFrom());
045: header.setTo(pop3Msg
046: .getRecipients(Message.RecipientType.TO));
047: header.setCc(pop3Msg
048: .getRecipients(Message.RecipientType.CC));
049: header.setBcc(pop3Msg
050: .getRecipients(Message.RecipientType.BCC));
051: header.setReplyTo(pop3Msg.getReplyTo());
052: header.setDate(pop3Msg.getSentDate());
053: header.setSize(pop3Msg.getSize());
054: header.setSubject(pop3Msg.getSubject());
055: header
056: .setUnread(!pop3Msg
057: .isSet(javax.mail.Flags.Flag.SEEN));
058:
059: // now set the human readables.
060: header.setDateShown(Formatter.formatDate(header.getDate(),
061: "dd.MM.yyyy HH:mm"));
062: header.setFromShown(Utility.addressArrToString(header
063: .getFrom()));
064: header.setToShown(Utility
065: .addressArrToString(header.getTo()));
066: header.setCcShown(Utility
067: .addressArrToString(header.getCc()));
068: header.setSizeShown(Utility.sizeToHumanReadable(header
069: .getSize()));
070:
071: setHeaders(pop3Msg, header);
072:
073: msg.setBaseHeader(header);
074: } catch (Exception e) {
075: log
076: .error(
077: "Exception occured while parsing the message base headers",
078: e);
079: }
080:
081: ArrayList parts = new ArrayList();
082: parts = fetchParts(pop3Msg, parts);
083: if (parts != null) {
084: EmailPart part = null;
085: for (int i = 0; i < parts.size(); i++) {
086: part = (EmailPart) parts.get(i);
087: part.setId(i);
088: }
089: }
090: msg.setParts(parts);
091:
092: // store all headers
093: /*
094: try {
095: Enumeration en = pop3Msg.getAllHeaders();
096: String name, val = "";
097: Object tmp = null;
098: while (en.hasMoreElements()) {
099: tmp = en.nextElement();
100: name = (tmp == null) ? "" : tmp.toString();
101: tmp = pop3Msg.getHeader(name);
102: val = (tmp == null) ? "" : tmp.toString();
103: msg.addHeader(name, val);
104: }
105: } catch (MessagingException e1) {
106: log.error("Exception occured while parsing the message generic all headers", e1);
107: }
108: */
109: try {
110: Enumeration en = pop3Msg.getAllHeaders();
111: String name, val = "";
112: Header tmp = null;
113: while (en.hasMoreElements()) {
114: tmp = (Header) en.nextElement();
115: name = tmp.getName();
116: val = tmp.getValue();
117: /*
118: name = (tmp == null) ? "" : tmp.toString();
119: tmp = pop3Msg.getHeader(name);
120: val = (tmp == null) ? "" : tmp.toString();
121: */
122: msg.addHeader(name, val);
123: }
124: } catch (MessagingException e1) {
125: log
126: .error(
127: "Exception occured while parsing the message generic all headers",
128: e1);
129: }
130:
131: return msg;
132: }
133:
134: /**
135: * A recursive algorithm travelling through a MIME message, looking
136: * at the mime types of each part and decodes it into a text content.
137: * @param p
138: * @param parts
139: * @return ArrayList of EmailParts
140: */
141: private static ArrayList fetchParts(Part p, ArrayList parts) {
142: if (p == null)
143: return null;
144:
145: try {
146: if (!p.isMimeType("text/rfc822-headers")
147: && p.isMimeType("text/*")) {
148: try {
149: EmailPart myPart = new EmailPart();
150: myPart.setSize(p.getSize());
151: myPart.setContentType(p.getContentType());
152: myPart.setFileName(p.getFileName());
153: myPart.setDisposition(p.getDisposition());
154: Object pContent;
155: try {
156: pContent = p.getContent();
157: } catch (UnsupportedEncodingException e) {
158: pContent = "Message has an illegal encoding. "
159: + e.getLocalizedMessage();
160: }
161: if (pContent != null) {
162: myPart.setContent(pContent.toString());
163: } else {
164: myPart.setContent("Illegal content");
165: }
166: parts.add(myPart);
167: } catch (Exception e) {
168: log
169: .error(
170: "Part is mimeType text/rfc822-headers and is mimeType text/* but exception occured",
171: e);
172: }
173: } else if (p.isMimeType("multipart/*")) {
174: try {
175: Multipart mp = (Multipart) p.getContent();
176: int count = mp.getCount();
177: for (int i = 0; i < count; i++) {
178: fetchParts(mp.getBodyPart(i), parts);
179: }
180: } catch (Exception e) {
181: log
182: .error(
183: "Part is mimeType multipart/* but exception occured",
184: e);
185: }
186: } else if (p.isMimeType("message/rfc822")) {
187: fetchParts((Part) p.getContent(), parts);
188: } else {
189: try {
190: EmailPart myPart = new EmailPart();
191: myPart.setSize(p.getSize());
192: myPart.setContentType(p.getContentType());
193: myPart
194: .setFileName((p.getFileName() == null) ? "rfc822.txt"
195: : p.getFileName());
196: myPart.setDisposition(p.getDisposition());
197: String headContentID[] = p.getHeader("Content-ID");
198: if (headContentID != null) {
199: myPart.setContentId(headContentID[0]);
200: }
201: InputStream is = p.getInputStream();
202: ByteArrayOutputStream baos = new ByteArrayOutputStream();
203: int c;
204: while ((c = is.read()) != -1) {
205: baos.write(c);
206: }
207: myPart.setContent(baos);
208: parts.add(myPart);
209: is.close();
210: baos.close();
211: } catch (Exception e) {
212: log
213: .error(
214: "An exception occured while parsing this part.",
215: e);
216: }
217: }
218: } catch (Exception e) {
219: log
220: .error(
221: "An exception occured while parsing the parts of the message.",
222: e);
223: }
224: return parts;
225: }
226:
227: /**
228: * @param msg
229: * @param header
230: */
231: public static void setHeaders(Message msg, EmailHeader header)
232: throws javax.mail.MessagingException {
233: java.util.Enumeration msgHeaders = msg.getAllHeaders();
234: javax.mail.Header msgHeader;
235: String key;
236: String value;
237: while (msgHeaders.hasMoreElements()) {
238: msgHeader = (javax.mail.Header) msgHeaders.nextElement();
239: key = msgHeader.getName().toLowerCase();
240: if (key.equals("disposition-notification-to")) {
241: value = msgHeader.getValue().trim();
242: if (value != null && value.length() > 0) {
243: header.setRequestReceiptNotification(true);
244: header.setReceiptNotificationEmail(value);
245: }
246: } else if (key.equals("x-priority")) {
247: value = msgHeader.getValue().trim();
248: try {
249: header.setPriority(Short.valueOf(value)
250: .shortValue());
251: } catch (Exception e) {
252: }
253: } else if (key.equals("x-msmail-priority")) {
254: if (header.getPriority() == 0) {
255: value = msgHeader.getValue().trim();
256: try {
257: header.setPriority(Short.valueOf(value)
258: .shortValue());
259: } catch (Exception e) {
260: }
261: }
262: } else if (key.equals("sensitivity")) {
263: value = msgHeader.getValue().trim();
264: try {
265: header.setSensitivity(EmailSensitivity
266: .valueOf(value));
267: } catch (Exception e) {
268: }
269: }
270: }
271: }
272: }
|