content: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.camel.component.mail;
  
  import java.util.Date;
  import java.util.Properties;
  
  import jakarta.mail.MessagingException;
  import jakarta.mail.NoSuchProviderException;
  import jakarta.mail.PasswordAuthentication;
  import jakarta.mail.Session;
  import jakarta.mail.Transport;
  import jakarta.mail.internet.MimeMessage;
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  /**
   * Default {@link JavaMailSender} which uses the JDK Mail API.
   */
  public class DefaultJavaMailSender implements JavaMailSender {
  
      private static final Logger LOG = LoggerFactory.getLogger(DefaultJavaMailSender.class);
  
      private Properties javaMailProperties;
      private String host;
      private String username;
      private String password;
      private MailAuthenticator authenticator;
      // -1 means using the default port to access the service
      private int port = -1;
      private String protocol;
      private Session session;
  
      @Override
      public String getHost() {
          return host;
      }
  
      @Override
      public void setHost(String host) {
          this.host = host;
      }
  
      @Override
      public Properties getJavaMailProperties() {
          if (javaMailProperties == null) {
              javaMailProperties = new Properties();
          }
          return javaMailProperties;
      }
  
      @Override
      public void setJavaMailProperties(Properties javaMailProperties) {
          this.javaMailProperties = javaMailProperties;
      }
  
      public void addAdditionalJavaMailProperty(String key, String value) {
          getJavaMailProperties().setProperty(key, value);
      }
  
      @Override
      public String getPassword() {
          return password;
      }
  
      @Override
      public void setPassword(String password) {
          this.password = password;
      }
  
      @Override
      public Session getSession() {
          if (session == null) {
              session = Session.getInstance(getJavaMailProperties(),
                      authenticator == null ? new DefaultAuthenticator(username, password) : authenticator);
          }
          return session;
      }
  
      @Override
      public void setSession(Session session) {
          this.session = session;
      }
  
      @Override
      public String getUsername() {
          return username;
      }
  
      @Override
      public void setUsername(String username) {
          this.username = username;
      }
  
      @Override
      public MailAuthenticator getAuthenticator() {
          return authenticator;
      }
  
      @Override
      public void setAuthenticator(MailAuthenticator authenticator) {
          this.authenticator = authenticator;
      }
  
      public int getPort() {
          return port;
      }
  
      @Override
      public void setPort(int port) {
          this.port = port;
      }
  
      @Override
      public String getProtocol() {
          return protocol;
      }
  
      @Override
      public void setProtocol(String protocol) {
          this.protocol = protocol;
      }
  
      /**
       * Returns the password authentication from the authenticator or from the parameters user and password.
       */
      public PasswordAuthentication getPasswordAuthentication() {
          // call authenticator so that the authenticator can dynamically determine the password or token
          return authenticator == null
                  ? new PasswordAuthentication(username, password) : authenticator.getPasswordAuthentication();
      }
  
      @Override
      public void send(MimeMessage mimeMessage) throws MessagingException {
          Transport transport = getTransport(getSession());
          LOG.debug("Connecting to {}:{}", host, port);
          PasswordAuthentication passwordAuth = getPasswordAuthentication();
          transport.connect(getHost(), getPort(), passwordAuth.getUserName(), passwordAuth.getPassword());
          try {
              if (mimeMessage.getSentDate() == null) {
                  mimeMessage.setSentDate(new Date());
              }
              String messageId = mimeMessage.getMessageID();
              mimeMessage.saveChanges();
              if (messageId != null) {
                  // preserve explicitly specified message id, as it may be lost on save
                  mimeMessage.setHeader("Message-ID", messageId);
              }
              LOG.debug("Sending MimeMessage: {} using host: {}", mimeMessage, host);
              transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
          } finally {
              try {
                  transport.close();
              } catch (MessagingException e) {
                  LOG.warn("Error closing transport to host {}. This exception will be ignored.", host, e);
              }
          }
      }
  
      /**
       * Strategy to get the {@link Transport} from the mail {@link Session}.
       */
      protected Transport getTransport(Session session) throws NoSuchProviderException {
          return session.getTransport(getProtocol());
      }
  
  }
  