/**
   * @see org.apache.james.queue.jms.JMSMailQueue#populateMailMimeMessage(javax.jms.Message,
   *     org.apache.mailet.Mail)
   */
  protected void populateMailMimeMessage(Message message, Mail mail)
      throws MessagingException, JMSException {
    if (message instanceof BlobMessage) {
      try {
        BlobMessage blobMessage = (BlobMessage) message;
        try {
          // store URL and queueName for later usage
          mail.setAttribute(JAMES_BLOB_URL, blobMessage.getURL());
          mail.setAttribute(JAMES_QUEUE_NAME, queueName);
        } catch (MalformedURLException e) {
          // Ignore on error
          logger.debug("Unable to get url from blobmessage for mail " + mail.getName());
        }
        MimeMessageSource source = new MimeMessageBlobMessageSource(blobMessage);
        mail.setMessage(new MimeMessageCopyOnWriteProxy(source));

      } catch (JMSException e) {
        throw new MailQueueException(
            "Unable to populate MimeMessage for mail " + mail.getName(), e);
      }
    } else {
      super.populateMailMimeMessage(message, mail);
    }
  }
 private Mail getMockedMail(MimeMessage message) {
   Mail m = new FakeMail();
   m.setMessage(message);
   return m;
 }
  /** {@inheritDoc} */
  @SuppressWarnings("unchecked")
  @Override
  public void service(Mail mail) throws MessagingException {
    GatewayState.getInstance().lockForProcessing();
    try {

      Tx txToMonitor = null;

      LOGGER.trace("Entering service(Mail mail)");

      onPreprocessMessage(mail);

      final MimeMessage msg = mail.getMessage();

      final NHINDAddressCollection recipients = getMailRecipients(mail);

      // get the sender
      final NHINDAddress sender = getMailSender(mail);

      LOGGER.info("Proccessing incoming message from sender " + sender.toString());
      MessageProcessResult result = null;

      final boolean isOutgoing = this.isOutgoing(msg, sender);

      // if the message is outgoing, then the tracking information must be
      // gathered now before the message is transformed
      if (isOutgoing) txToMonitor = getTxToTrack(msg, sender, recipients);

      // recipients can get modified by the security and trust agent, so make a local copy
      // before processing
      final NHINDAddressCollection originalRecipList = NHINDAddressCollection.create(recipients);

      try {
        // process the message with the agent stack
        LOGGER.trace("Calling agent.processMessage");
        result = agent.processMessage(msg, recipients, sender);
        LOGGER.trace("Finished calling agent.processMessage");

        if (result == null) {
          LOGGER.error("Failed to process message.  processMessage returned null.");

          onMessageRejected(mail, originalRecipList, sender, isOutgoing, txToMonitor, null);

          mail.setState(Mail.GHOST);

          LOGGER.trace("Exiting service(Mail mail)");
          return;
        }
      } catch (Exception e) {
        // catch all

        LOGGER.error("Failed to process message: " + e.getMessage(), e);

        onMessageRejected(mail, originalRecipList, sender, isOutgoing, txToMonitor, e);

        mail.setState(Mail.GHOST);
        LOGGER.trace("Exiting service(Mail mail)");

        return;
      }

      if (result.getProcessedMessage() != null) {
        mail.setMessage(result.getProcessedMessage().getMessage());
      } else {
        /*
         * TODO: Handle exception... GHOST the message for now and eat it
         */
        LOGGER.debug("Processed message is null.  GHOST and eat the message.");

        onMessageRejected(mail, recipients, sender, null);

        mail.setState(Mail.GHOST);

        return;
      }

      // remove reject recipients from the RCTP headers
      if (result.getProcessedMessage().getRejectedRecipients() != null
          && result.getProcessedMessage().getRejectedRecipients().size() > 0
          && mail.getRecipients() != null
          && mail.getRecipients().size() > 0) {

        final Collection<MailAddress> newRCPTList = new ArrayList<MailAddress>();
        for (MailAddress rctpAdd : (Collection<MailAddress>) mail.getRecipients()) {
          if (!isRcptRejected(rctpAdd, result.getProcessedMessage().getRejectedRecipients())) {
            newRCPTList.add(rctpAdd);
          }
        }

        mail.setRecipients(newRCPTList);
      }

      /*
       * Handle sending MDN messages
       */
      final Collection<NotificationMessage> notifications = result.getNotificationMessages();
      if (notifications != null && notifications.size() > 0) {
        LOGGER.info("MDN messages requested.  Sending MDN \"processed\" messages");
        // create a message for each notification and put it on James "stack"
        for (NotificationMessage message : notifications) {
          try {
            this.getMailetContext().sendMail(message);
          } catch (Throwable t) {
            // don't kill the process if this fails
            LOGGER.error("Error sending MDN message.", t);
          }
        }
      }

      // track message
      trackMessage(txToMonitor, isOutgoing);

      onPostprocessMessage(mail, result, isOutgoing, txToMonitor);

      LOGGER.trace("Exiting service(Mail mail)");
    } finally {
      GatewayState.getInstance().unlockFromProcessing();
    }
  }