001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.mail;
018
019 import java.io.IOException;
020 import java.util.Map;
021
022 import javax.activation.DataHandler;
023 import javax.mail.Message;
024 import javax.mail.MessagingException;
025 import javax.mail.Multipart;
026 import javax.mail.Part;
027
028 import org.apache.camel.RuntimeCamelException;
029 import org.apache.camel.impl.DefaultMessage;
030 import org.apache.camel.util.CollectionHelper;
031 import org.apache.camel.util.ExchangeHelper;
032 import org.apache.commons.logging.Log;
033 import org.apache.commons.logging.LogFactory;
034
035 /**
036 * Represents a {@link org.apache.camel.Message} for working with Mail
037 *
038 * @version $Revision:520964 $
039 */
040 public class MailMessage extends DefaultMessage {
041 private static final transient Log LOG = LogFactory.getLog(MailMessage.class);
042 private Message mailMessage;
043
044 public MailMessage() {
045 }
046
047 public MailMessage(Message message) {
048 this.mailMessage = message;
049 }
050
051 @Override
052 public String toString() {
053 if (mailMessage != null) {
054 return "MailMessage: " + MailUtils.dumpMessage(mailMessage);
055 } else {
056 return "MailMessage: " + getBody();
057 }
058 }
059
060 public MailMessage copy() {
061 MailMessage answer = (MailMessage)super.copy();
062 answer.mailMessage = mailMessage;
063 return answer;
064 }
065
066 /**
067 * Returns the underlying Mail message
068 */
069 public Message getMessage() {
070 return mailMessage;
071 }
072
073 public void setMessage(Message mailMessage) {
074 this.mailMessage = mailMessage;
075 }
076
077 @Override
078 public MailMessage newInstance() {
079 return new MailMessage();
080 }
081
082 @Override
083 protected Object createBody() {
084 if (mailMessage != null) {
085 MailBinding binding = ExchangeHelper.getBinding(getExchange(), MailBinding.class);
086 return binding != null ? binding.extractBodyFromMail(getExchange(), mailMessage) : null;
087 }
088 return null;
089 }
090
091 @Override
092 protected void populateInitialHeaders(Map<String, Object> map) {
093 if (mailMessage != null) {
094 try {
095 MailBinding binding = ExchangeHelper.getBinding(getExchange(), MailBinding.class);
096 if (binding != null) {
097 map.putAll(binding.extractHeadersFromMail(mailMessage, getExchange()));
098 }
099 } catch (MessagingException e) {
100 throw new RuntimeCamelException("Error accessing headers due to: " + e.getMessage(), e);
101 }
102 }
103 }
104
105 @Override
106 protected void populateInitialAttachments(Map<String, DataHandler> map) {
107 if (mailMessage != null) {
108 try {
109 extractAttachments(mailMessage, map);
110 } catch (Exception e) {
111 throw new RuntimeCamelException("Error populating the initial mail message attachments", e);
112 }
113 }
114 }
115
116 public void copyFrom(org.apache.camel.Message that) {
117 super.copyFrom(that);
118 if (that instanceof MailMessage) {
119 MailMessage mailMessage = (MailMessage) that;
120 this.mailMessage = mailMessage.mailMessage;
121 }
122 }
123
124 /**
125 * Parses the attachments of the given mail message and adds them to the map
126 *
127 * @param message the mail message with attachments
128 * @param map the map to add found attachments (attachmentFilename is the key)
129 */
130 protected static void extractAttachments(Message message, Map<String, DataHandler> map)
131 throws javax.mail.MessagingException, IOException {
132
133 LOG.trace("Extracting attachments +++ start +++");
134
135 Object content = message.getContent();
136 if (content instanceof Multipart) {
137 extractFromMultipart((Multipart)content, map);
138 } else if (content != null) {
139 LOG.trace("No attachments to extract as content is not Multipart: " + content.getClass().getName());
140 }
141
142 LOG.trace("Extracting attachments +++ done +++");
143 }
144
145 protected static void extractFromMultipart(Multipart mp, Map<String, DataHandler> map)
146 throws javax.mail.MessagingException, IOException {
147
148 for (int i = 0; i < mp.getCount(); i++) {
149 Part part = mp.getBodyPart(i);
150 LOG.trace("Part #" + i + ": " + part);
151
152 if (part.isMimeType("multipart/*")) {
153 LOG.trace("Part #" + i + ": is mimetype: multipart/*");
154 extractFromMultipart((Multipart)part.getContent(), map);
155 } else {
156 String disposition = part.getDisposition();
157 if (LOG.isTraceEnabled()) {
158 LOG.trace("Part #" + i + ": Disposition: " + part.getDisposition());
159 LOG.trace("Part #" + i + ": Description: " + part.getDescription());
160 LOG.trace("Part #" + i + ": ContentType: " + part.getContentType());
161 LOG.trace("Part #" + i + ": FileName: " + part.getFileName());
162 LOG.trace("Part #" + i + ": Size: " + part.getSize());
163 LOG.trace("Part #" + i + ": LineCount: " + part.getLineCount());
164 }
165
166 if (disposition != null && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) {
167 // only add named attachments
168 String fileName = part.getFileName();
169 if (fileName != null) {
170 LOG.debug("Mail contains file attachment: " + fileName);
171 // Parts marked with a disposition of Part.ATTACHMENT are clearly attachments
172 CollectionHelper.appendValue(map, fileName, part.getDataHandler());
173 }
174 }
175 }
176 }
177 }
178
179 }