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