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