private void logMail(MimeMessagePreparator mimeMessagePreparator) {
   try {
     MimeMessage message = new MimeMessage((Session) null);
     mimeMessagePreparator.prepare(message);
     logMail(message);
   } catch (Exception e) {
     log.error(
         "Mail Test-Mode: couldn't send mail with MimeMessagePreparator="
             + mimeMessagePreparator.toString());
   }
 }
  private void prepareAndSendEmail(final Action ruleAction, final NodeRef actionedUponNodeRef) {
    // Create the mime mail message
    MimeMessagePreparator mailPreparer =
        new MimeMessagePreparator() {
          @SuppressWarnings("unchecked")
          public void prepare(MimeMessage mimeMessage) throws MessagingException {
            if (logger.isDebugEnabled()) {
              logger.debug(ruleAction.getParameterValues());
            }

            MimeMessageHelper message = new MimeMessageHelper(mimeMessage);

            // set header encoding if one has been supplied
            if (headerEncoding != null && headerEncoding.length() != 0) {
              mimeMessage.setHeader("Content-Transfer-Encoding", headerEncoding);
            }

            // set recipient
            String to = (String) ruleAction.getParameterValue(PARAM_TO);
            if (to != null && to.length() != 0) {
              message.setTo(to);
            } else {
              // see if multiple recipients have been supplied - as a list of authorities
              Serializable authoritiesValue = ruleAction.getParameterValue(PARAM_TO_MANY);
              List<String> authorities = null;
              if (authoritiesValue != null) {
                if (authoritiesValue instanceof String) {
                  authorities = new ArrayList<String>(1);
                  authorities.add((String) authoritiesValue);
                } else {
                  authorities = (List<String>) authoritiesValue;
                }
              }

              if (authorities != null && authorities.size() != 0) {
                List<String> recipients = new ArrayList<String>(authorities.size());
                for (String authority : authorities) {
                  AuthorityType authType = AuthorityType.getAuthorityType(authority);
                  if (authType.equals(AuthorityType.USER)) {
                    if (personService.personExists(authority) == true) {
                      NodeRef person = personService.getPerson(authority);
                      String address =
                          (String) nodeService.getProperty(person, ContentModel.PROP_EMAIL);
                      if (address != null && address.length() != 0 && validateAddress(address)) {
                        recipients.add(address);
                      }
                    }
                  } else if (authType.equals(AuthorityType.GROUP)
                      || authType.equals(AuthorityType.EVERYONE)) {
                    // Notify all members of the group
                    Set<String> users;
                    if (authType.equals(AuthorityType.GROUP)) {
                      users =
                          authorityService.getContainedAuthorities(
                              AuthorityType.USER, authority, false);
                    } else {
                      users = authorityService.getAllAuthorities(AuthorityType.USER);
                    }

                    for (String userAuth : users) {
                      if (personService.personExists(userAuth) == true) {
                        NodeRef person = personService.getPerson(userAuth);
                        String address =
                            (String) nodeService.getProperty(person, ContentModel.PROP_EMAIL);
                        if (address != null && address.length() != 0) {
                          recipients.add(address);
                        }
                      }
                    }
                  }
                }

                if (recipients.size() > 0) {
                  message.setTo(recipients.toArray(new String[recipients.size()]));
                } else {
                  // All recipients were invalid
                  throw new MailPreparationException(
                      "All recipients for the mail action were invalid");
                }
              } else {
                // No recipients have been specified
                throw new MailPreparationException(
                    "No recipient has been specified for the mail action");
              }
            }

            // from person
            NodeRef fromPerson = null;
            if (!authService.isCurrentUserTheSystemUser()) {
              fromPerson = personService.getPerson(authService.getCurrentUserName());
            }

            // set subject line
            message.setSubject((String) ruleAction.getParameterValue(PARAM_SUBJECT));

            // See if an email template has been specified
            String text = null;
            NodeRef templateRef = (NodeRef) ruleAction.getParameterValue(PARAM_TEMPLATE);
            if (templateRef != null) {
              Map<String, Object> suppliedModel = null;
              if (ruleAction.getParameterValue(PARAM_TEMPLATE_MODEL) != null) {
                Object m = ruleAction.getParameterValue(PARAM_TEMPLATE_MODEL);
                if (m instanceof Map) {
                  suppliedModel = (Map<String, Object>) m;
                } else {
                  logger.warn(
                      "Skipping unsupported email template model parameters of type "
                          + m.getClass().getName()
                          + " : "
                          + m.toString());
                }
              }

              // build the email template model
              Map<String, Object> model =
                  createEmailTemplateModel(actionedUponNodeRef, suppliedModel, fromPerson);

              // process the template against the model
              text = templateService.processTemplate("freemarker", templateRef.toString(), model);
            }

            // set the text body of the message

            boolean isHTML = false;
            if (text == null) {
              text = (String) ruleAction.getParameterValue(PARAM_TEXT);
            }

            if (text != null) {
              // Note: only simplistic match here - expects <html tag at the start of the text
              String htmlPrefix = "<html";
              if (text.length() >= htmlPrefix.length()
                  && text.substring(0, htmlPrefix.length()).equalsIgnoreCase(htmlPrefix)) {
                isHTML = true;
              }
            } else {
              text = (String) ruleAction.getParameterValue(PARAM_HTML);
              if (text != null) {
                // assume HTML
                isHTML = true;
              }
            }

            if (text != null) {
              message.setText(text, isHTML);
            }

            // set the from address
            String fromActualUser = null;
            if (fromPerson != null) {
              fromActualUser =
                  (String) nodeService.getProperty(fromPerson, ContentModel.PROP_EMAIL);
            }

            if (fromActualUser != null && fromActualUser.length() != 0) {
              message.setFrom(fromActualUser);
            } else {
              String from = (String) ruleAction.getParameterValue(PARAM_FROM);
              if (from == null || from.length() == 0) {
                message.setFrom(fromAddress);
              } else {
                message.setFrom(from);
              }
            }
          }
        };

    try {
      // Send the message unless we are in "testMode"
      if (!testMode) {
        javaMailSender.send(mailPreparer);
      } else {
        try {
          MimeMessage mimeMessage = javaMailSender.createMimeMessage();
          mailPreparer.prepare(mimeMessage);
          lastTestMessage = mimeMessage;
        } catch (Exception e) {
          System.err.println(e);
        }
      }
    } catch (MailException e) {
      String to = (String) ruleAction.getParameterValue(PARAM_TO);
      if (to == null) {
        Object obj = ruleAction.getParameterValue(PARAM_TO_MANY);
        if (obj != null) {
          to = obj.toString();
        }
      }

      // always log the failure
      logger.error("Failed to send email to " + to, e);

      // optionally ignore the throwing of the exception
      Boolean ignoreError = (Boolean) ruleAction.getParameterValue(PARAM_IGNORE_SEND_FAILURE);
      if (ignoreError == null || ignoreError.booleanValue() == false) {
        throw new AlfrescoRuntimeException("Failed to send email to:" + to, e);
      }
    }
  }