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.net.URI; 020 import java.util.HashMap; 021 import java.util.Map; 022 import java.util.Properties; 023 import javax.mail.Authenticator; 024 import javax.mail.Message; 025 import javax.mail.PasswordAuthentication; 026 import javax.mail.Session; 027 028 import org.apache.camel.RuntimeCamelException; 029 import org.springframework.mail.javamail.JavaMailSender; 030 import org.springframework.mail.javamail.JavaMailSenderImpl; 031 032 /** 033 * Represents the configuration data for communicating over email 034 * 035 * @version $Revision: 800779 $ 036 */ 037 public class MailConfiguration implements Cloneable { 038 039 private JavaMailSender javaMailSender; 040 private Properties javaMailProperties; 041 private Properties additionalJavaMailProperties; 042 private String protocol; 043 private String host; 044 private int port = -1; 045 private String username; 046 private String password; 047 private Session session; 048 private String defaultEncoding; 049 private String from = MailConstants.MAIL_DEFAULT_FROM; 050 private String folderName = MailConstants.MAIL_DEFAULT_FOLDER; 051 private boolean delete; 052 private boolean unseen = true; 053 private boolean ignoreUriScheme; 054 private Map<Message.RecipientType, String> recipients = new HashMap<Message.RecipientType, String>(); 055 private int fetchSize = -1; 056 private boolean debugMode; 057 private long connectionTimeout = MailConstants.MAIL_DEFAULT_CONNECTION_TIMEOUT; 058 private boolean dummyTrustManager; 059 private String contentType = "text/plain"; 060 private String alternativeBodyHeader = MailConstants.MAIL_ALTERNATIVE_BODY; 061 private boolean useInlineAttachments; 062 private boolean ignoreUnsupportedCharset; 063 064 public MailConfiguration() { 065 } 066 067 /** 068 * Returns a copy of this configuration 069 */ 070 public MailConfiguration copy() { 071 try { 072 return (MailConfiguration) clone(); 073 } catch (CloneNotSupportedException e) { 074 throw new RuntimeCamelException(e); 075 } 076 } 077 078 public void configure(URI uri) { 079 String value = uri.getHost(); 080 if (value != null) { 081 setHost(value); 082 } 083 084 if (!isIgnoreUriScheme()) { 085 String scheme = uri.getScheme(); 086 if (scheme != null) { 087 setProtocol(scheme); 088 } 089 } 090 091 String userInfo = uri.getUserInfo(); 092 if (userInfo != null) { 093 setUsername(userInfo); 094 } 095 096 int port = uri.getPort(); 097 if (port > 0) { 098 setPort(port); 099 } else if (port <= 0 && this.port <= 0) { 100 // resolve default port if no port number was provided, and not already configured with a port number 101 setPort(MailUtils.getDefaultPortForProtocol(uri.getScheme())); 102 } 103 } 104 105 protected JavaMailSenderImpl createJavaMailSender() { 106 JavaMailSenderImpl answer = new JavaMailSenderImpl(); 107 108 // sets the debug mode of the underlying mail framework 109 answer.getSession().setDebug(debugMode); 110 111 if (javaMailProperties != null) { 112 answer.setJavaMailProperties(javaMailProperties); 113 } else { 114 // set default properties if none provided 115 answer.setJavaMailProperties(createJavaMailProperties()); 116 // add additional properties if provided 117 if (additionalJavaMailProperties != null) { 118 answer.getJavaMailProperties().putAll(additionalJavaMailProperties); 119 } 120 } 121 122 if (defaultEncoding != null) { 123 answer.setDefaultEncoding(defaultEncoding); 124 } 125 if (host != null) { 126 answer.setHost(host); 127 } 128 if (port >= 0) { 129 answer.setPort(port); 130 } 131 if (password != null) { 132 answer.setPassword(password); 133 } 134 if (protocol != null) { 135 answer.setProtocol(protocol); 136 } 137 if (session != null) { 138 answer.setSession(session); 139 } else { 140 // use our authenticator that does no live user interaction but returns the already configured username and password 141 Session session = Session.getDefaultInstance(answer.getJavaMailProperties(), getAuthenticator()); 142 answer.setSession(session); 143 } 144 if (username != null) { 145 answer.setUsername(username); 146 } 147 148 return answer; 149 } 150 151 private Properties createJavaMailProperties() { 152 // clone the system properties and set the java mail properties 153 Properties properties = (Properties)System.getProperties().clone(); 154 properties.put("mail." + protocol + ".connectiontimeout", connectionTimeout); 155 properties.put("mail." + protocol + ".timeout", connectionTimeout); 156 properties.put("mail." + protocol + ".host", host); 157 properties.put("mail." + protocol + ".port", "" + port); 158 if (username != null) { 159 properties.put("mail." + protocol + ".user", username); 160 properties.put("mail.user", username); 161 properties.put("mail." + protocol + ".auth", "true"); 162 } else { 163 properties.put("mail." + protocol + ".auth", "false"); 164 } 165 properties.put("mail." + protocol + ".rsetbeforequit", "true"); 166 properties.put("mail.transport.protocol", protocol); 167 properties.put("mail.store.protocol", protocol); 168 properties.put("mail.host", host); 169 170 if (debugMode) { 171 // add more debug for the SSL communication as well 172 properties.put("javax.net.debug", "all"); 173 } 174 175 if (dummyTrustManager && isSecureProtocol()) { 176 // set the custom SSL properties 177 properties.put("mail." + protocol + ".socketFactory.class", "org.apache.camel.component.mail.security.DummySSLSocketFactory"); 178 properties.put("mail." + protocol + ".socketFactory.fallback", "false"); 179 properties.put("mail." + protocol + ".socketFactory.port", "" + port); 180 } 181 182 return properties; 183 } 184 185 /** 186 * Is the used protocol to be secure or not 187 */ 188 public boolean isSecureProtocol() { 189 return this.protocol.equalsIgnoreCase("smtps") || this.protocol.equalsIgnoreCase("pop3s") 190 || this.protocol.equalsIgnoreCase("imaps"); 191 } 192 193 /** 194 * Returns an authenticator object for use in sessions 195 */ 196 public Authenticator getAuthenticator() { 197 return new Authenticator() { 198 protected PasswordAuthentication getPasswordAuthentication() { 199 return new PasswordAuthentication(getUsername(), getPassword()); 200 } 201 }; 202 } 203 204 public String getMailStoreLogInformation() { 205 String ssl = ""; 206 if (isSecureProtocol()) { 207 ssl = "(SSL enabled" + (dummyTrustManager ? " using DummyTrustManager)" : ")"); 208 } 209 210 return protocol + "//" + host + ":" + port + ssl + ", folder=" + folderName; 211 } 212 213 // Properties 214 // ------------------------------------------------------------------------- 215 216 public JavaMailSender getJavaMailSender() { 217 return javaMailSender; 218 } 219 220 public void setJavaMailSender(JavaMailSender javaMailSender) { 221 this.javaMailSender = javaMailSender; 222 } 223 224 public String getDefaultEncoding() { 225 return defaultEncoding; 226 } 227 228 public void setDefaultEncoding(String defaultEncoding) { 229 this.defaultEncoding = defaultEncoding; 230 } 231 232 public String getHost() { 233 return host; 234 } 235 236 public void setHost(String host) { 237 this.host = host; 238 } 239 240 public Properties getJavaMailProperties() { 241 return javaMailProperties; 242 } 243 244 /** 245 * Sets the java mail options. Will clear any default properties and only use the properties 246 * provided for this method. 247 */ 248 public void setJavaMailProperties(Properties javaMailProperties) { 249 this.javaMailProperties = javaMailProperties; 250 } 251 252 public Properties getAdditionalJavaMailProperties() { 253 if (additionalJavaMailProperties == null) { 254 additionalJavaMailProperties = new Properties(); 255 } 256 return additionalJavaMailProperties; 257 } 258 259 /** 260 * Sets additional java mail properties, that will append/override any default properties 261 * that is set based on all the other options. This is useful if you need to add some 262 * special options but want to keep the others as is. 263 */ 264 public void setAdditionalJavaMailProperties(Properties additionalJavaMailProperties) { 265 this.additionalJavaMailProperties = additionalJavaMailProperties; 266 } 267 268 public String getPassword() { 269 return password; 270 } 271 272 public void setPassword(String password) { 273 this.password = password; 274 } 275 276 public int getPort() { 277 return port; 278 } 279 280 public void setPort(int port) { 281 this.port = port; 282 } 283 284 public String getProtocol() { 285 return protocol; 286 } 287 288 public void setProtocol(String protocol) { 289 this.protocol = protocol; 290 } 291 292 public Session getSession() { 293 return session; 294 } 295 296 public void setSession(Session session) { 297 this.session = session; 298 } 299 300 public String getUsername() { 301 return username; 302 } 303 304 public void setUsername(String username) { 305 this.username = username; 306 if (getRecipients().size() == 0) { 307 // set default destination to username@host for backwards compatibility 308 // can be overridden by URI parameters 309 String address = username; 310 if (address.indexOf("@") == -1) { 311 address += "@" + host; 312 } 313 setTo(address); 314 } 315 } 316 317 public String getFrom() { 318 return from; 319 } 320 321 public void setFrom(String from) { 322 this.from = from; 323 } 324 325 public boolean isDelete() { 326 return delete; 327 } 328 329 public void setDelete(boolean delete) { 330 this.delete = delete; 331 } 332 333 public String getFolderName() { 334 return folderName; 335 } 336 337 public void setFolderName(String folderName) { 338 this.folderName = folderName; 339 } 340 341 public boolean isIgnoreUriScheme() { 342 return ignoreUriScheme; 343 } 344 345 public void setIgnoreUriScheme(boolean ignoreUriScheme) { 346 this.ignoreUriScheme = ignoreUriScheme; 347 } 348 349 public boolean isUnseen() { 350 return unseen; 351 } 352 353 public void setUnseen(boolean unseen) { 354 this.unseen = unseen; 355 } 356 357 /** 358 * Sets the <tt>To</tt> email address. Separate multiple email addresses with comma. 359 */ 360 public void setTo(String address) { 361 recipients.put(Message.RecipientType.TO, address); 362 } 363 364 /** 365 * Sets the <tt>CC</tt> email address. Separate multiple email addresses with comma. 366 */ 367 public void setCC(String address) { 368 recipients.put(Message.RecipientType.CC, address); 369 } 370 371 /** 372 * Sets the <tt>BCC</tt> email address. Separate multiple email addresses with comma. 373 */ 374 public void setBCC(String address) { 375 recipients.put(Message.RecipientType.BCC, address); 376 } 377 378 public Map<Message.RecipientType, String> getRecipients() { 379 return recipients; 380 } 381 382 public int getFetchSize() { 383 return fetchSize; 384 } 385 386 public void setFetchSize(int fetchSize) { 387 this.fetchSize = fetchSize; 388 } 389 390 public boolean isDebugMode() { 391 return debugMode; 392 } 393 394 public void setDebugMode(boolean debugMode) { 395 this.debugMode = debugMode; 396 } 397 398 public long getConnectionTimeout() { 399 return connectionTimeout; 400 } 401 402 public void setConnectionTimeout(long connectionTimeout) { 403 this.connectionTimeout = connectionTimeout; 404 } 405 406 public boolean isDummyTrustManager() { 407 return dummyTrustManager; 408 } 409 410 public void setDummyTrustManager(boolean dummyTrustManager) { 411 this.dummyTrustManager = dummyTrustManager; 412 } 413 414 public String getContentType() { 415 return contentType; 416 } 417 418 public void setContentType(String contentType) { 419 this.contentType = contentType; 420 } 421 422 public String getAlternativeBodyHeader() { 423 return alternativeBodyHeader; 424 } 425 426 public void setAlternativeBodyHeader(String alternativeBodyHeader) { 427 this.alternativeBodyHeader = alternativeBodyHeader; 428 } 429 430 public boolean isUseInlineAttachments() { 431 return useInlineAttachments; 432 } 433 434 public void setUseInlineAttachments(boolean useInlineAttachments) { 435 this.useInlineAttachments = useInlineAttachments; 436 } 437 438 public boolean isIgnoreUnsupportedCharset() { 439 return ignoreUnsupportedCharset; 440 } 441 442 public void setIgnoreUnsupportedCharset(boolean ignoreUnsupportedCharset) { 443 this.ignoreUnsupportedCharset = ignoreUnsupportedCharset; 444 } 445 }