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 }