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.Exchange; 029 import org.apache.camel.RuntimeCamelException; 030 import org.apache.camel.impl.DefaultMessage; 031 import org.apache.camel.util.CollectionHelper; 032 import org.apache.camel.util.ExchangeHelper; 033 import org.apache.commons.logging.Log; 034 import org.apache.commons.logging.LogFactory; 035 036 /** 037 * Represents a {@link org.apache.camel.Message} for working with Mail 038 * 039 * @version $Revision:520964 $ 040 */ 041 public class MailMessage extends DefaultMessage { 042 private static final transient Log LOG = LogFactory.getLog(MailMessage.class); 043 private Message mailMessage; 044 045 public MailMessage() { 046 } 047 048 public MailMessage(Message message) { 049 this.mailMessage = message; 050 } 051 052 @Override 053 public String toString() { 054 if (mailMessage != null) { 055 return "MailMessage: " + MailUtils.dumpMessage(mailMessage); 056 } else { 057 return "MailMessage: " + getBody(); 058 } 059 } 060 061 public MailMessage copy() { 062 MailMessage answer = (MailMessage)super.copy(); 063 answer.mailMessage = mailMessage; 064 return answer; 065 } 066 067 /** 068 * Returns the underlying Mail message 069 */ 070 public Message getMessage() { 071 return mailMessage; 072 } 073 074 public void setMessage(Message mailMessage) { 075 this.mailMessage = mailMessage; 076 } 077 078 @Override 079 public Object getHeader(String name) { 080 Object answer = super.getHeader(name); 081 082 // mimic case insensitive search of mail message getHeader 083 if (answer == null) { 084 answer = super.getHeader(name.toLowerCase()); 085 } 086 return answer; 087 } 088 089 @Override 090 public MailMessage newInstance() { 091 return new MailMessage(); 092 } 093 094 @Override 095 protected Object createBody() { 096 if (mailMessage != null) { 097 MailBinding binding = ExchangeHelper.getBinding(getExchange(), MailBinding.class); 098 return binding != null ? binding.extractBodyFromMail(getExchange(), mailMessage) : null; 099 } 100 return null; 101 } 102 103 @Override 104 protected void populateInitialHeaders(Map<String, Object> map) { 105 if (mailMessage != null) { 106 try { 107 MailBinding binding = ExchangeHelper.getBinding(getExchange(), MailBinding.class); 108 if (binding != null) { 109 map.putAll(binding.extractHeadersFromMail(mailMessage, getExchange())); 110 } 111 } catch (MessagingException e) { 112 throw new RuntimeCamelException("Error accessing headers due to: " + e.getMessage(), e); 113 } 114 } 115 } 116 117 @Override 118 protected void populateInitialAttachments(Map<String, DataHandler> map) { 119 if (mailMessage != null) { 120 try { 121 extractAttachments(mailMessage, map); 122 } catch (Exception e) { 123 throw new RuntimeCamelException("Error populating the initial mail message attachments", e); 124 } 125 } 126 } 127 128 public void copyFrom(org.apache.camel.Message that) { 129 super.copyFrom(that); 130 if (that instanceof MailMessage) { 131 MailMessage mailMessage = (MailMessage) that; 132 this.mailMessage = mailMessage.mailMessage; 133 } 134 } 135 136 /** 137 * Parses the attachments of the given mail message and adds them to the map 138 * 139 * @param message the mail message with attachments 140 * @param map the map to add found attachments (attachmentFilename is the key) 141 */ 142 protected static void extractAttachments(Message message, Map<String, DataHandler> map) 143 throws javax.mail.MessagingException, IOException { 144 145 LOG.trace("Extracting attachments +++ start +++"); 146 147 Object content = message.getContent(); 148 if (content instanceof Multipart) { 149 extractFromMultipart((Multipart)content, map); 150 } else if (content != null) { 151 LOG.trace("No attachments to extract as content is not Multipart: " + content.getClass().getName()); 152 } 153 154 LOG.trace("Extracting attachments +++ done +++"); 155 } 156 157 protected static void extractFromMultipart(Multipart mp, Map<String, DataHandler> map) 158 throws javax.mail.MessagingException, IOException { 159 160 for (int i = 0; i < mp.getCount(); i++) { 161 Part part = mp.getBodyPart(i); 162 LOG.trace("Part #" + i + ": " + part); 163 164 if (part.isMimeType("multipart/*")) { 165 LOG.trace("Part #" + i + ": is mimetype: multipart/*"); 166 extractFromMultipart((Multipart)part.getContent(), map); 167 } else { 168 String disposition = part.getDisposition(); 169 if (LOG.isTraceEnabled()) { 170 LOG.trace("Part #" + i + ": Disposition: " + part.getDisposition()); 171 LOG.trace("Part #" + i + ": Description: " + part.getDescription()); 172 LOG.trace("Part #" + i + ": ContentType: " + part.getContentType()); 173 LOG.trace("Part #" + i + ": FileName: " + part.getFileName()); 174 LOG.trace("Part #" + i + ": Size: " + part.getSize()); 175 LOG.trace("Part #" + i + ": LineCount: " + part.getLineCount()); 176 } 177 178 if (disposition != null && (disposition.equalsIgnoreCase(Part.ATTACHMENT) || disposition.equalsIgnoreCase(Part.INLINE))) { 179 // only add named attachments 180 String fileName = part.getFileName(); 181 if (fileName != null) { 182 LOG.debug("Mail contains file attachment: " + fileName); 183 // Parts marked with a disposition of Part.ATTACHMENT are clearly attachments 184 CollectionHelper.appendValue(map, fileName, part.getDataHandler()); 185 } 186 } 187 } 188 } 189 } 190 191 }