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.text.DateFormat;
020 import java.util.Date;
021 import javax.mail.Address;
022 import javax.mail.Message;
023 import javax.mail.MessagingException;
024
025 import org.apache.camel.util.ObjectHelper;
026
027 /**
028 * Mail utility class.
029 * <p>
030 * Parts of the code copied from Apache ServiceMix.
031 *
032 * @version
033 */
034 public final class MailUtils {
035
036 public static final int DEFAULT_PORT_SMTP = 25;
037 public static final int DEFAULT_PORT_SMTPS = 465;
038 public static final int DEFAULT_PORT_POP3 = 110;
039 public static final int DEFAULT_PORT_POP3S = 995;
040 public static final int DEFAULT_PORT_NNTP = 119;
041 public static final int DEFAULT_PORT_IMAP = 143;
042 public static final int DEFAULT_PORT_IMAPS = 993;
043
044 public static final String PROTOCOL_SMTP = "smtp";
045 public static final String PROTOCOL_SMTPS = "smtps";
046 public static final String PROTOCOL_POP3 = "pop3";
047 public static final String PROTOCOL_POP3S = "pop3s";
048 public static final String PROTOCOL_NNTP = "nntp";
049 public static final String PROTOCOL_IMAP = "imap";
050 public static final String PROTOCOL_IMAPS = "imaps";
051
052 private MailUtils() {
053 }
054
055 /**
056 * Returns the default port for a given protocol.
057 * <p>
058 * If a protocol could not successfully be determined the default port number for SMTP protocol is returned.
059 *
060 * @param protocol the protocol
061 * @return the default port
062 */
063 public static int getDefaultPortForProtocol(final String protocol) {
064 int port = DEFAULT_PORT_SMTP;
065
066 if (protocol != null) {
067 if (protocol.equalsIgnoreCase(PROTOCOL_IMAP)) {
068 port = DEFAULT_PORT_IMAP;
069 } else if (protocol.equalsIgnoreCase(PROTOCOL_IMAPS)) {
070 port = DEFAULT_PORT_IMAPS;
071 } else if (protocol.equalsIgnoreCase(PROTOCOL_NNTP)) {
072 port = DEFAULT_PORT_NNTP;
073 } else if (protocol.equalsIgnoreCase(PROTOCOL_POP3)) {
074 port = DEFAULT_PORT_POP3;
075 } else if (protocol.equalsIgnoreCase(PROTOCOL_POP3S)) {
076 port = DEFAULT_PORT_POP3S;
077 } else if (protocol.equalsIgnoreCase(PROTOCOL_SMTP)) {
078 port = DEFAULT_PORT_SMTP;
079 } else if (protocol.equalsIgnoreCase(PROTOCOL_SMTPS)) {
080 port = DEFAULT_PORT_SMTPS;
081 } else {
082 port = DEFAULT_PORT_SMTP;
083 }
084 }
085
086 return port;
087 }
088
089 /**
090 * Gets a log dump of the given message that can be used for tracing etc.
091 *
092 * @param message the Mail message
093 * @return a log string with important fields dumped
094 */
095 public static String dumpMessage(Message message) {
096 if (message == null) {
097 return "null";
098 }
099
100 try {
101 StringBuilder sb = new StringBuilder();
102
103 int number = message.getMessageNumber();
104 sb.append("messageNumber=[").append(number).append("]");
105
106 Address[] from = message.getFrom();
107 if (from != null) {
108 for (Address adr : from) {
109 sb.append(", from=[").append(adr).append("]");
110 }
111 }
112
113 Address[] to = message.getRecipients(Message.RecipientType.TO);
114 if (to != null) {
115 for (Address adr : to) {
116 sb.append(", to=[").append(adr).append("]");
117 }
118 }
119
120 String subject = message.getSubject();
121 if (subject != null) {
122 sb.append(", subject=[").append(subject).append("]");
123 }
124
125 Date sentDate = message.getSentDate();
126 if (sentDate != null) {
127 sb.append(", sentDate=[").append(DateFormat.getDateTimeInstance().format(sentDate)).append("]");
128 }
129
130 Date receivedDate = message.getReceivedDate();
131 if (receivedDate != null) {
132 sb.append(", receivedDate=[").append(DateFormat.getDateTimeInstance().format(receivedDate)).append("]");
133 }
134
135 return sb.toString();
136 } catch (MessagingException e) {
137 // ignore the error and just return tostring
138 return message.toString();
139 }
140 }
141
142 /**
143 * Pads the content-type so it has a space after semi colon that separate pairs.
144 * <p/>
145 * This is needed as some mail servers will choke otherwise
146 *
147 * @param contentType the content type
148 * @return the padded content type
149 */
150 public static String padContentType(String contentType) {
151 StringBuilder sb = new StringBuilder();
152 String[] parts = contentType.split(";");
153 for (int i = 0; i < parts.length; i++) {
154 String part = parts[i];
155 if (ObjectHelper.isNotEmpty(part)) {
156 part = part.trim();
157 sb.append(part);
158 if (i < parts.length - 1) {
159 sb.append("; ");
160 }
161 }
162 }
163 return sb.toString();
164 }
165
166 /**
167 * Replaces the charset in the content-type
168 *
169 * @param contentType the content-type
170 * @param charset the charset to replace, can be <tt>null</tt> to remove charset
171 * @return the content-type with replaced charset
172 */
173 public static String replaceCharSet(String contentType, String charset) {
174 boolean replaced = false;
175 StringBuilder sb = new StringBuilder();
176 String[] parts = contentType.split(";");
177 for (int i = 0; i < parts.length; i++) {
178 String part = parts[i];
179 part = part.trim();
180 if (!part.startsWith("charset")) {
181 part = part.trim();
182 if (sb.length() > 0) {
183 sb.append("; ");
184 }
185 sb.append(part);
186 } else if (charset != null) {
187 // replace with new charset
188 if (sb.length() > 0) {
189 sb.append("; ");
190 }
191 sb.append("charset=");
192 sb.append(charset);
193 replaced = true;
194 }
195 }
196
197 // if we did not replace any existing charset, then append new charset at the end
198 if (!replaced && charset != null) {
199 if (sb.length() > 0) {
200 sb.append("; ");
201 }
202 sb.append("charset=");
203 sb.append(charset);
204 }
205
206 return sb.toString();
207 }
208
209 /**
210 * Gets the charset from the content-type
211 *
212 * @param contentType the content-type
213 * @return the charset, or <tt>null</tt> if no charset existed
214 */
215 public static String getCharSetFromContentType(String contentType) {
216 if (contentType == null) {
217 return null;
218 }
219
220 String[] parts = contentType.split(";");
221 for (int i = 0; i < parts.length; i++) {
222 String part = parts[i];
223 part = part.trim();
224 if (part.startsWith("charset")) {
225 return ObjectHelper.after(part, "charset=");
226 }
227 }
228 return null;
229 }
230
231 }