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