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