/** This function initializes the fax client SPI. */
  @Override
  protected void initializeImpl() {
    // initialize
    super.initializeImpl();

    // initialize templates
    this.initializeMailTemplates();

    // get logger
    Logger logger = this.getLogger();

    // validate mail address template
    if (this.mailAddressTemplate == null) {
      throw new FaxException(
          "Mail address template not defined in fax4j.properties. Property: "
              + FaxClientSpiConfigurationConstants.MAIL_ADDRESS_TEMPLATE_PROPERTY_KEY);
    }
    logger.logDebug(new Object[] {"Using mail address template: ", this.mailAddressTemplate}, null);

    // validate mail subject template
    if (this.mailSubjectTemplate == null) {
      throw new FaxException(
          "Mail subject template not defined in fax4j.properties. Property: "
              + FaxClientSpiConfigurationConstants.MAIL_SUBJECT_TEMPLATE_PROPERTY_KEY);
    }
    logger.logDebug(new Object[] {"Using mail subject template: ", this.mailSubjectTemplate}, null);
  }
  /**
   * This function will create the message used to invoke the fax job action.<br>
   * If this method returns null, the SPI will throw an UnsupportedOperationException.
   *
   * @param faxJob The fax job object containing the needed information
   * @param mailResourcesHolder The mail resources holder
   * @return The message to send (if null, the SPI will throw an UnsupportedOperationException)
   */
  @Override
  protected Message createSubmitFaxJobMessage(
      FaxJob faxJob, MailResourcesHolder mailResourcesHolder) {
    // get logger
    Logger logger = this.getLogger();

    // get target address
    String targetAddress = faxJob.getTargetAddress();

    // format TO value
    String toAddress = MessageFormat.format(this.mailAddressTemplate, new Object[] {targetAddress});
    logger.logDebug(new Object[] {"Formatted TO address: ", toAddress}, null);

    // format subject value
    String subject = MessageFormat.format(this.mailSubjectTemplate, new Object[] {targetAddress});
    logger.logDebug(new Object[] {"Formatted subject: ", subject}, null);

    // get session
    Session session = mailResourcesHolder.getSession();

    // create message
    Message message = new MimeMessage(session);

    // set from
    String from = faxJob.getSenderEmail();
    if ((from != null) && (from.length() > 0)) {
      try {
        message.setFrom(new InternetAddress(from));
      } catch (Exception exception) {
        throw new FaxException("Error while setting from address: " + from, exception);
      }
    }

    try {
      // add message recipient
      message.addRecipient(RecipientType.TO, new InternetAddress(toAddress));
    } catch (Exception exception) {
      throw new FaxException("Error while setting TO address: " + toAddress, exception);
    }

    try {
      // set message subject
      message.setSubject(subject);
    } catch (Exception exception) {
      throw new FaxException("Error while setting subject: " + subject, exception);
    }

    // create multi part
    Multipart multipart = new MimeMultipart();

    // init body part
    BodyPart messageFileAttachmentBodyPart = new MimeBodyPart();

    // init data source
    File file = faxJob.getFile();
    DataSource source = new FileDataSource(file);

    try {
      // set data
      messageFileAttachmentBodyPart.setDataHandler(new DataHandler(source));
      messageFileAttachmentBodyPart.setFileName(file.getName());

      // add to body
      multipart.addBodyPart(messageFileAttachmentBodyPart);

      // set content
      message.setContent(multipart);
    } catch (Exception exception) {
      throw new FaxException("Error while setting attachment.", exception);
    }

    return message;
  }