Package net.suberic.pooka

Source Code of net.suberic.pooka.MessageInfo

package net.suberic.pooka;
import net.suberic.pooka.crypto.CryptoAttachment;
import net.suberic.pooka.crypto.SignedAttachment;
import net.suberic.pooka.filter.FilterAction;
import net.suberic.pooka.gui.MessageProxy;
import javax.mail.*;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.event.*;
import java.util.Vector;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.io.*;

public class MessageInfo {
  // the wrapped Message
  Message message;

  // the source FolderInfo
  FolderInfo folderInfo;

  // if the tableInfo has been loaded yet.
  boolean loaded = false;

  // if the message has been read
  boolean seen = false;

  // if the attachments have been loaded yet.
  boolean attachmentsLoaded = false;

  // the MessageProxy associated with this MessageInfo
  MessageProxy messageProxy;

  // the attachments on the message.
  AttachmentBundle attachments;

  // the CryptoInfo for this Message.
  MessageCryptoInfo cryptoInfo = new MessageCryptoInfo(this);

  // if the Message itself has been loaded via fetch()
  boolean fetched = false;

  public static int FORWARD_AS_ATTACHMENT = 0;
  public static int FORWARD_QUOTED = 1;
  public static int FORWARD_AS_INLINE = 2;

  protected MessageInfo() {
  }

  /**
   * This creates a new MessageInfo from the given FolderInfo and Message.
   */
  public MessageInfo(Message newMessage, FolderInfo newFolderInfo) {
    folderInfo = newFolderInfo;
    message = newMessage;
  }

  /**
   * This loads the Attachment information into the attachments vector.
   */
  public void loadAttachmentInfo() throws MessagingException {
    try {
      // FIXME
      attachments = MailUtilities.parseAttachments(getMessage());
      attachmentsLoaded = true;
      if (Pooka.getProperty("EncryptionManager.autoDecrypt", "false").equalsIgnoreCase("true") &&
          cryptoInfo.isEncrypted()) {
        UserProfile p = getDefaultProfile();
        if (p == null)
          p = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile();

        if (cryptoInfo.autoDecrypt(p)) {
          //attachments = MailUtilities.parseAttachments(getMessage());
        }
      }

      if (Pooka.getProperty("EncryptionManager.autoCheckSig", "false").equalsIgnoreCase("true") &&
          cryptoInfo.isSigned()) {
        if (cryptoInfo.autoCheckSignature((javax.mail.internet.InternetAddress) getMessage().getFrom()[0])) {
          //attachments = MailUtilities.parseAttachments(getMessage());
        }
      }

    } catch (MessagingException me) {
      // if we can't parse the message, try loading it as a single text
      // file.
      try {
        javax.mail.internet.MimeMessage mimeMessage = (javax.mail.internet.MimeMessage)getMessage();
        AttachmentBundle bundle = new AttachmentBundle(mimeMessage);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        java.util.List headerList = new java.util.ArrayList();
        java.util.Enumeration headerEnum = mimeMessage.getAllHeaders();
        while (headerEnum.hasMoreElements()) {
          Header hdr = (Header) headerEnum.nextElement();
          headerList.add(hdr.getName());
        }
        String[] excludeList = (String[]) headerList.toArray(new String[0]);
        mimeMessage.writeTo(baos, excludeList);
        String content = baos.toString("ISO-8859-1");
        MimeBodyPart mbp = new MimeBodyPart();
        mbp.setText(content);
        Attachment textPart = new Attachment(mbp);
        bundle.addAttachment(textPart);

        attachments = bundle;
      } catch (Exception e) {
        throw me;
      }
    } catch (java.io.IOException ioe) {
      throw new MessagingException("Error loading Message:  " + ioe.toString(), ioe);
    }

  }

  /**
   * This gets a Flag property from the Message.
   */
  public boolean flagIsSet(String flagName) throws MessagingException {
    if (Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) {
      Logger folderLogger = getFolderInfo().getLogger();
      if (folderLogger.isLoggable(Level.WARNING)) {
        folderLogger.log(Level.WARNING, "Accessing Message Flags not on Folder Thread.");
        Thread.currentThread().dumpStack();
      }
    }

    if (flagName.equals("FLAG.ANSWERED") )
      return getMessage().isSet(Flags.Flag.ANSWERED);
    else if (flagName.equals("FLAG.DELETED"))
      return getMessage().isSet(Flags.Flag.DELETED);
    else if (flagName.equals("FLAG.DRAFT"))
      return getMessage().isSet(Flags.Flag.DRAFT);
    else if (flagName.equals("FLAG.FLAGGED"))
      return getMessage().isSet(Flags.Flag.FLAGGED);
    else if (flagName.equals("FLAG.RECENT"))
      return getMessage().isSet(Flags.Flag.RECENT);
    else if (flagName.equals("FLAG.SEEN")) {
      if (folderInfo != null && ! folderInfo.tracksUnreadMessages())
        return true;
      else
        return getMessage().isSet(Flags.Flag.SEEN);
    }

    return false;
  }

  /**
   * This gets the Flags object for the wrapped Message.
   */
  public Flags getFlags() throws MessagingException {
    if (Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) {
      Logger folderLogger = getFolderInfo().getLogger();
      if (folderLogger.isLoggable(Level.WARNING)) {
        folderLogger.log(Level.WARNING, "Accessing Message Flags not on Folder Thread.");
        Thread.currentThread().dumpStack();

      }
    }
    return getMessage().getFlags();
  }

  /**
   * Refreshes the flags object.
   */
  public void refreshFlags() throws MessagingException {
    if (Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) {
      Logger folderLogger = getFolderInfo().getLogger();
      if (folderLogger.isLoggable(Level.WARNING)) {
        folderLogger.log(Level.WARNING, "Accessing Message Flags not on Folder Thread.");
        Thread.currentThread().dumpStack();

      }
    }
    getFolderInfo().refreshFlags(this);
  }

  /**
   * Refreshes the Headers object.
   */
  public void refreshHeaders() throws MessagingException {
    if (Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) {
      Logger folderLogger = getFolderInfo().getLogger();
      if (folderLogger.isLoggable(Level.WARNING)) {
        folderLogger.log(Level.WARNING, "Accessing Message Headers not on Folder Thread.");
        Thread.currentThread().dumpStack();

      }
    }
    getFolderInfo().refreshHeaders(this);
  }

  /**
   * This gets a particular property (From, To, Date, Subject, or just
   * about any Email Header) from the Message.
   */
  public Object getMessageProperty(String prop) throws MessagingException {
    if (getFolderInfo() != null && Thread.currentThread() != getFolderInfo().getFolderThread() && ! (Thread.currentThread() instanceof net.suberic.pooka.thread.LoadMessageThread)) {
      Logger folderLogger = getFolderInfo().getLogger();
      if (folderLogger.isLoggable(Level.WARNING)) {
        folderLogger.log(Level.WARNING, "Getting Message Property not on Folder Thread.");
        Thread.currentThread().dumpStack();

      }
    }
    Message msg = getMessage();
    if (prop.equals("From")) {
      try {
        Address[] fromAddr = msg.getFrom();
        return MailUtilities.decodeAddressString(fromAddr);
      } catch (javax.mail.internet.AddressException ae) {
        return ((MimeMessage) msg).getHeader("From", ",");
      }
    } else if (prop.equalsIgnoreCase("receivedDate")) {
      return msg.getReceivedDate();
    } else if (prop.equalsIgnoreCase("recipients")) {
      return msg.getAllRecipients();
    } else if (prop.equalsIgnoreCase("to")) {
      return MailUtilities.decodeAddressString(msg.getRecipients(Message.RecipientType.TO));
    } else if (prop.equalsIgnoreCase("cc")) {
      return MailUtilities.decodeAddressString(msg.getRecipients(Message.RecipientType.CC));
    } else if (prop.equalsIgnoreCase("bcc")) {
      return MailUtilities.decodeAddressString(msg.getRecipients(Message.RecipientType.BCC));
    } else if (prop.equalsIgnoreCase("Date")) {
      return msg.getSentDate();
    } else if (prop.equalsIgnoreCase("Subject")) {
      return MailUtilities.decodeText(msg.getSubject());
    }

    if (msg instanceof MimeMessage) {
      String hdrVal = ((MimeMessage)msg).getHeader(prop, ",");
      if (hdrVal != null && hdrVal.length() > 0)
        return MailUtilities.decodeText(hdrVal);
    }
    return "";
  }

  /**
   * Gets the Content and inline text content for the Message.
   */
  public String getTextAndTextInlines(String attachmentSeparator, boolean withHeaders, boolean showFullHeaders, int maxLength, String truncationMessage) throws MessagingException, OperationCancelledException {
    try {
      if (!hasLoadedAttachments())
        loadAttachmentInfo();
      return attachments.getTextAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, maxLength, truncationMessage);
    } catch (FolderClosedException fce) {
      try {
        if (getFolderInfo().shouldBeConnected()) {
          getFolderInfo().openFolder(Folder.READ_WRITE);
          loadAttachmentInfo();
          return attachments.getTextAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, maxLength, truncationMessage);
        } else {
          throw fce;
        }
      } catch (java.io.IOException ioe) {
        throw new MessagingException(ioe.getMessage());
      }
    } catch (java.io.IOException ioe) {
      ioe.printStackTrace();
      throw new MessagingException(ioe.getMessage());
    }
  }

  /**
   * Gets the Content and inline text content for the Message.
   */
  public String getTextAndTextInlines(String attachmentSeparator, boolean withHeaders, boolean showFullHeaders) throws MessagingException, OperationCancelledException  {
    return getTextAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getTruncationMessage());
  }

  /**
   * Gets the Content and inline text content for the Message.
   */
  public String getTextAndTextInlines(boolean withHeaders, boolean showFullHeaders) throws MessagingException, OperationCancelledException  {
    return getTextAndTextInlines(getAttachmentSeparator(), withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getTruncationMessage());
  }

  /**
   * Gets the Text part of the Content of this Message.  If no real text
   * content is found, returns the html content.  If there's none of that,
   * either, then returns null.
   */
  public String getTextPart(boolean withHeaders, boolean showFullHeaders, int maxLength, String truncationMessage) throws MessagingException, OperationCancelledException {
    try {
      if (!hasLoadedAttachments())
        loadAttachmentInfo();
      String returnValue = attachments.getTextPart(withHeaders, showFullHeaders, maxLength, truncationMessage);
      if (returnValue != null)
        return returnValue;
      else
        return getHtmlPart(withHeaders, showFullHeaders, maxLength, getHtmlTruncationMessage());
    } catch (FolderClosedException fce) {
      try {
        if (getFolderInfo().shouldBeConnected()) {
          getFolderInfo().openFolder(Folder.READ_WRITE);
          loadAttachmentInfo();
          String returnValue = attachments.getTextPart(withHeaders, showFullHeaders, maxLength, truncationMessage);
          if (returnValue != null)
            return returnValue;
          else
            return getHtmlPart(withHeaders, showFullHeaders, maxLength, getHtmlTruncationMessage());
        } else {
          throw fce;
        }
      } catch (java.io.IOException ioe) {
        throw new MessagingException(ioe.getMessage());
      }
    } catch (java.io.IOException ioe) {
      throw new MessagingException(ioe.getMessage());
    }
  }

  /**
   * Gets the Text part of the Content of this Message.  If no real text
   * content is found, returns the html content.  If there's none of that,
   * either, then returns null.
   */
  public String getTextPart(boolean withHeaders, boolean showFullHeaders) throws MessagingException, OperationCancelledException  {
    return getTextPart(withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getTruncationMessage());
  }

  /**
   * Gets the Html part of the Content of this Message.
   */
  public String getHtmlPart(boolean withHeaders, boolean showFullHeaders, int maxLength, String truncationMessage) throws MessagingException, OperationCancelledException  {
    try {
      if (!hasLoadedAttachments())
        loadAttachmentInfo();
      return attachments.getHtmlPart(withHeaders, showFullHeaders, maxLength, truncationMessage);
    } catch (FolderClosedException fce) {
      try {
        if (getFolderInfo().shouldBeConnected()) {
          getFolderInfo().openFolder(Folder.READ_WRITE);
          loadAttachmentInfo();
          return attachments.getHtmlPart(withHeaders, showFullHeaders, maxLength, truncationMessage);
        } else {
          throw fce;
        }
      } catch (java.io.IOException ioe) {
        throw new MessagingException(ioe.getMessage());
      }
    } catch (java.io.IOException ioe) {
      throw new MessagingException(ioe.getMessage());
    }
  }

  /**
   * Gets the Html part of the Content of this Message.
   */
  public String getHtmlPart(boolean withHeaders, boolean showFullHeaders) throws MessagingException, OperationCancelledException  {
    return getHtmlPart(withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getTruncationMessage());
  }

  /**
   * Gets the Content and inline text content for the Message.
   */
  public String getHtmlAndTextInlines(String attachmentSeparator, boolean withHeaders, boolean showFullHeaders, int maxLength, String truncationMessage) throws MessagingException, OperationCancelledException  {
    try {
      if (!hasLoadedAttachments())
        loadAttachmentInfo();
      return attachments.getHtmlAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, maxLength, truncationMessage);
    } catch (FolderClosedException fce) {
      try {
        if (getFolderInfo().shouldBeConnected()) {
          getFolderInfo().openFolder(Folder.READ_WRITE);
          loadAttachmentInfo();
          return attachments.getHtmlAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, maxLength, truncationMessage);
        } else {
          throw fce;
        }
      } catch (java.io.IOException ioe) {
        throw new MessagingException(ioe.getMessage());
      }
    } catch (java.io.IOException ioe) {
      throw new MessagingException(ioe.getMessage());
    }
  }

  /**
   * Gets the Content and inline text content for the Message.
   */
  public String getHtmlAndTextInlines(String attachmentSeparator, boolean withHeaders, boolean showFullHeaders) throws MessagingException, OperationCancelledException  {
    return getHtmlAndTextInlines(attachmentSeparator, withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getHtmlTruncationMessage());
  }

  /**
   * Gets the Content and inline text content for the Message.
   */
  public String getHtmlAndTextInlines(boolean withHeaders, boolean showFullHeaders) throws MessagingException, OperationCancelledException  {
    return getHtmlAndTextInlines(getHtmlAttachmentSeparator(), withHeaders, showFullHeaders, getMaxMessageDisplayLength(), getHtmlTruncationMessage());
  }

  /**
   * Gets the raw RFC 822 message.
   */
  public String getRawText() throws MessagingException {
    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      MimeMessage mm = (MimeMessage) getMessage();
      mm.writeTo(baos);
      return baos.toString();
    } catch (IOException ioe) {
      MessagingException returnValue = new MessagingException("Error reading Message Stream", ioe);
      throw returnValue;
    }
  }

  /**
   * Moves the Message into the target Folder.
   */
  public void moveMessage(FolderInfo targetFolder, boolean expunge) throws MessagingException, OperationCancelledException  {
    try {
      folderInfo.copyMessages(new MessageInfo[] { this }, targetFolder);
    } catch (MessagingException me) {
      MessagingException returnValue = new MessagingException (Pooka.getProperty("error.Message.CopyErrorMessage", "Error:  could not copy messages to folder:  ") + targetFolder.toString() +"\n", me);
      throw returnValue;
    }

    try {
      remove(expunge);
    } catch (MessagingException me) {
      MessagingException returnValue = new MessagingException(Pooka.getProperty("error.Message.RemoveErrorMessage", "Error:  could not remove messages from folder:  ") + targetFolder.toString() +"\n", me);
      throw returnValue;
    }
  }

  /**
   * Copies the Message into the target Folder.
   */
  public void copyMessage(FolderInfo targetFolder) throws MessagingException, OperationCancelledException  {
    try {
      folderInfo.copyMessages(new MessageInfo[] { this }, targetFolder);
    } catch (MessagingException me) {
      MessagingException returnValue = new MessagingException (Pooka.getProperty("error.Message.CopyErrorMessage", "Error:  could not copy messages to folder:  ") + targetFolder.toString() +"\n", me);
      throw returnValue;
    }

  }

  /**
   * A convenience method which sets autoExpunge by the value of
   * Pooka.autoExpunge, and then calls moveMessage(targetFolder, autoExpunge)
   * with that value.
   */
  public void moveMessage(FolderInfo targetFolder) throws MessagingException, OperationCancelledException  {
    moveMessage(targetFolder, Pooka.getProperty("Pooka.autoExpunge", "true").equals("true"));
  }

  /**
   * Bounces this message to another user.
   */
  public void bounceMessage(Address[] recipientList) throws javax.mail.MessagingException {

    MimeMessage mm = (MimeMessage)getMessage();
    MimeMessage mmClone = new MimeMessage(mm);

    NewMessageInfo nmi = new NewMessageInfo(mmClone);
    net.suberic.pooka.gui.NewMessageProxy nmp = new net.suberic.pooka.gui.NewMessageProxy(nmi);
    java.util.HashMap messageMap = new java.util.HashMap();
    messageMap.put(mmClone, recipientList);

    nmi.setSendMessageMap(messageMap);

    final NewMessageInfo final_nmi = nmi;

    UserProfile p = getDefaultProfile();
    if (p == null)
      p = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile();

    if (p != null && p.getMailServer() != null) {
      final OutgoingMailServer mailServer = p.getMailServer();
      mailServer.mailServerThread.addToQueue(new javax.swing.AbstractAction() {
          public void actionPerformed(java.awt.event.ActionEvent ae) {
            mailServer.sendMessage(final_nmi);
          }
        }, new java.awt.event.ActionEvent(this, 0, "message-send"));
    }
  }

  /**
   * Deletes the Message from the current Folder.  If a Trash folder is
   * set, this method moves the message into the Trash folder.  If no
   * Trash folder is set, this marks the message as deleted.  In addition,
   * if the autoExpunge variable is set to true, it also expunges
   * the message from the mailbox.
   */
  public void deleteMessage(boolean autoExpunge) throws MessagingException, OperationCancelledException  {
    FolderInfo trashFolder = getFolderInfo().getTrashFolder();
    if ((getFolderInfo().useTrashFolder()) && (trashFolder != null) && (trashFolder != getFolderInfo())) {
      try {
        moveMessage(trashFolder, autoExpunge);
      } catch (MessagingException me) {
        throw new MessagingException(Pooka.getProperty("error.Messsage.DeleteNoTrashFolder", "No trash folder available."),  me);
      }
    } else {

      // actually remove the message, if we haven't already moved it.

      try {
        remove(autoExpunge);
      } catch (MessagingException me) {
        me.printStackTrace();
        throw new MessagingException(Pooka.getProperty("error.Message.DeleteErrorMessage", "Error:  could not delete message.") +"\n", me);
      }
    }

    if (getMessageProxy() != null)
      getMessageProxy().close();
  }

  /**
   * A convenience method which sets autoExpunge by the value of
   * Pooka.autoExpunge, and then calls deleteMessage(boolean autoExpunge)
   * with that value.
   */
  public void deleteMessage() throws MessagingException, OperationCancelledException {
    deleteMessage(Pooka.getProperty("Pooka.autoExpunge", "true").equals("true"));
  }

  /**
   * This actually marks the message as deleted, and, if autoexpunge is
   * set to true, expunges the folder.
   *
   * This should not be called directly; rather, deleteMessage() should
   * be used in order to ensure that the delete is done properly (using
   * trash folders, for instance).  If, however, the deleteMessage()
   * throws an Exception, it may be necessary to follow up with a call
   * to remove().
   */
  public void remove(boolean autoExpunge) throws MessagingException, OperationCancelledException {
    Message m = getMessage();
    if (m != null) {
      m.setFlag(Flags.Flag.DELETED, true);
      if ( autoExpunge ) {
        folderInfo.expunge();
      }
    }
  }

  /**
   * This puts the reply prefix 'prefix' in front of each line in the
   * body of the Message.
   */
  public String prefixMessage(String originalMessage, String prefix, String intro) {
    StringBuffer newValue = new StringBuffer(originalMessage);

    int currentCR = originalMessage.lastIndexOf('\n', originalMessage.length());
    while (currentCR != -1) {
      newValue.insert(currentCR+1, prefix);
      currentCR=originalMessage.lastIndexOf('\n', currentCR-1);
    }
    newValue.insert(0, prefix);
    newValue.insert(0, intro);

    return newValue.toString();
  }

  /**
   * This parses a message line using the current Message as a model.
   * The introTemplate will be of the form 'On %d, %n wrote', or
   * something similar.  This method uses the Pooka.parsedString
   * characters to decide which strings to substitute for which
   * characters.
   */
  public String parseMsgString(MimeMessage m, String introTemplate, boolean addLF) {
    StringBuffer intro = new StringBuffer(introTemplate);
    int index = introTemplate.lastIndexOf('%', introTemplate.length());
    try {
      while (index > -1) {
        try {
          char nextChar = introTemplate.charAt(index + 1);
          String replaceMe = null;
          if (nextChar == Pooka.getProperty("Pooka.parsedString.nameChar", "n").charAt(0)) {

            Address[] fromAddresses = m.getFrom();
            if (fromAddresses.length > 0 && fromAddresses[0] != null) {
              replaceMe = MailUtilities.decodeAddressString(fromAddresses);
              if (replaceMe == null)
                replaceMe = "";
              intro.replace(index, index +2, replaceMe);
            }
          } else if (nextChar == Pooka.getProperty("Pooka.parsedString.dateChar", "d").charAt(0)) {
            replaceMe = Pooka.getDateFormatter().fullDateFormat.format(m.getSentDate());
            if (replaceMe == null)
              replaceMe = "";
            intro.replace(index, index + 2, replaceMe);
          } else if (nextChar == Pooka.getProperty("Pooka.parsedString.subjChar", "s").charAt(0)) {
            replaceMe = m.getSubject();
            if (replaceMe == null)
              replaceMe = "";
            intro.replace(index, index + 2, replaceMe);
          } else if (nextChar == '%') {
            intro.replace(index, index+1, "%");
          }
          index = introTemplate.lastIndexOf('%', index -1);
        } catch (StringIndexOutOfBoundsException e) {
          index = introTemplate.lastIndexOf('%', index -1);
        }
      }
    } catch (MessagingException me) {
      return null;
    }

    if (addLF)
      if (intro.charAt(intro.length()-1) != '\n')
        intro.append('\n');

    return intro.toString();
  }

  /**
   * This populates a message which is a reply to the current
   * message.
   */
  public NewMessageInfo populateReply(boolean replyAll, boolean withAttachments)
    throws MessagingException, OperationCancelledException  {
    MimeMessage newMsg = (MimeMessage) getMessage().reply(replyAll);

    MimeMessage mMsg = (MimeMessage) getMessage();

    String textPart = getTextPart(false, false, getMaxMessageDisplayLength(), getTruncationMessage());
    if (textPart == null) {
      textPart = "";
    }

    if (isHtml()) {
      net.suberic.pooka.htmlparser.PookaStringBean psb = new net.suberic.pooka.htmlparser.PookaStringBean();
      psb.setContent(textPart, null);
      textPart = psb.getStrings();
    }

    if (textPart == null) {
      textPart = "";
    }

    UserProfile up = getDefaultProfile();
    if (up == null)
      up = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile();

    String parsedText;
    String replyPrefix;
    String parsedIntro;

    if (up != null && up.getMailProperties() != null) {
      replyPrefix = up.getMailProperties().getProperty("replyPrefix", Pooka.getProperty("Pooka.replyPrefix", "> "));
      parsedIntro = parseMsgString(mMsg, up.getMailProperties().getProperty("replyIntro", Pooka.getProperty("Pooka.replyIntro", "On %d, %n wrote:")), true);
    } else {
      replyPrefix = Pooka.getProperty("Pooka.replyPrefix", "> ");
      parsedIntro = parseMsgString(mMsg, Pooka.getProperty("Pooka.replyIntro", "On %d, %n wrote:"), true);
    }
    parsedText = prefixMessage(textPart, replyPrefix, parsedIntro);
    newMsg.setText(parsedText);

    if (replyAll && Pooka.getProperty("Pooka.excludeSelfInReply", "true").equalsIgnoreCase("true")) {
      up.removeFromAddress(newMsg);
    }

    NewMessageInfo returnValue = new NewMessageInfo(newMsg);

    if (withAttachments) {
      returnValue.attachments = new AttachmentBundle();
      returnValue.attachments.addAll(attachments);
      returnValue.attachmentsLoaded=true;
    }

    return returnValue;
  }

  /**
   * This populates a message which is a reply to the current
   * message.
   */
  public NewMessageInfo populateReply(boolean replyAll)
    throws MessagingException, OperationCancelledException  {
    return populateReply(replyAll, false);
  }

  /**
   * This populates a new message which is a forwarding of the
   * current message.
   */
  public NewMessageInfo populateForward(boolean withAttachments, int method)
    throws MessagingException, OperationCancelledException  {
    MimeMessage mMsg = (MimeMessage) getMessage();
    MimeMessage newMsg = new MimeMessage(Pooka.getDefaultSession());

    String parsedText = "";

    if (method == FORWARD_QUOTED) {
      String textPart = getTextPart(false, false, getMaxMessageDisplayLength(), getTruncationMessage());

      UserProfile up = getDefaultProfile();
      if (up == null) {
        up = Pooka.getPookaManager().getUserProfileManager().getDefaultProfile();
      }

      String forwardPrefix;
      String parsedIntro;

      if (up != null && up.getMailProperties() != null) {
        forwardPrefix = up.getMailProperties().getProperty("forwardPrefix", Pooka.getProperty("Pooka.forwardPrefix", "> "));
        parsedIntro = parseMsgString(mMsg, up.getMailProperties().getProperty("forwardIntro", Pooka.getProperty("Pooka.forwardIntro", "Forwarded message from %n:")), true);
      } else {
        forwardPrefix = Pooka.getProperty("Pooka.forwardPrefix", "> ");
        parsedIntro = parseMsgString(mMsg, Pooka.getProperty("Pooka.forwardIntro", "Forwarded message from %n:"), true);
      }
      parsedText = prefixMessage(textPart, forwardPrefix, parsedIntro);

    } else if (method == FORWARD_AS_INLINE) {

      String textPart = getTextPart(true, false, getMaxMessageDisplayLength(), getTruncationMessage());

      parsedText = Pooka.getProperty("Pooka.forwardInlineIntro", "----------  Original Message  ----------\n") + textPart;

    }

    newMsg.setText(parsedText);
    newMsg.setSubject(parseMsgString(mMsg, Pooka.getProperty("Pooka.forwardSubject", "Fwd:  %s"), false));

    NewMessageInfo returnValue = new NewMessageInfo(newMsg);

    // handle attachments.
    if (method == FORWARD_AS_ATTACHMENT) {
      UpdatableMBP mbp = new UpdatableMBP();
      mbp.setContent(getRealMessage(), "message/rfc822");
      mbp.updateMyHeaders();
      String subject = (String) getMessageProperty("Subject");
      if (subject != null && subject.length() > 0) {
        mbp.setFileName(subject);
      } else {
        mbp.setFileName("forwarded message");
      }
      mbp.setDisposition(Part.ATTACHMENT);

      AttachmentBundle returnAttachments = returnValue.getAttachmentBundle();
      Attachment messageAttachment = new MBPAttachment(mbp);
      returnAttachments.addAttachment(messageAttachment, false);


    } else if (withAttachments) {
      returnValue.attachments = new AttachmentBundle();
      Vector fromAttachments = attachments.getAttachments();
      if (fromAttachments != null) {
        AttachmentBundle returnAttachments = returnValue.getAttachmentBundle();
        for (int i = 0; i < fromAttachments.size(); i++) {
          Attachment current = (Attachment) fromAttachments.elementAt(i);
          Attachment newAttachment = null;

          MimeBodyPart mbp = new MimeBodyPart();
          mbp.setDataHandler(current.getDataHandler());
          newAttachment = new MBPAttachment(mbp);
          returnAttachments.addAttachment(newAttachment, false);
        }
      }
    }

    return returnValue;
  }

  /**
   * This populates a new message which is a forwarding of the
   * current message.
   */
  public NewMessageInfo populateForward()
    throws MessagingException, OperationCancelledException  {
    return populateForward(false, FORWARD_QUOTED);
  }

  /**
   * Runs folder filters on this MessageInfo.
   */
  public void runBackendFilters() {
    FolderInfo fi = getFolderInfo();
    java.util.LinkedList list = new java.util.LinkedList();
    list.add(getMessageProxy());
    fi.applyFilters(list);
  }

  /**
   * Runs the configured spam action on this message.
   */
  public void runSpamAction() {
    FilterAction spamFilter = null;
    try {
      spamFilter = MessageFilter.generateFilterAction("Pooka.spamAction");
    } catch (Exception e) {
      int configureNow = Pooka.getUIFactory().showConfirmDialog("Spam action currently not configured.  Would you like to configure it now?", "Configure Spam action", javax.swing.JOptionPane.YES_NO_OPTION);
      if (configureNow == javax.swing.JOptionPane.YES_OPTION) {
        // show configure screen.
        Pooka.getUIFactory().showEditorWindow(Pooka.getProperty("Preferences.Spam.label", "Spam"), "Pooka.spamAction");
      }

    }
    if (spamFilter != null) {
      Vector v = new Vector();
      v.add(this.getMessageProxy());
      java.util.List removed = spamFilter.performFilter(v);
      if (removed != null && removed.size() > 0) {
        try {
          getFolderInfo().expunge();
        } catch (Exception me) {
          // throw it away
        }
      }
      return;
    }
  }

  /**
   *  Caches the current messages.
   */
  public void cacheMessage() throws MessagingException {
    FolderInfo fi = getFolderInfo();
    if (fi != null && fi instanceof net.suberic.pooka.cache.CachingFolderInfo) {
      ((net.suberic.pooka.cache.CachingFolderInfo) fi).cacheMessage(this, net.suberic.pooka.cache.MessageCache.MESSAGE);

    }
  }

  /**
   * As specified by interface net.suberic.pooka.UserProfileContainer.
   *
   * If the MessageInfo's folderInfo is set, this returns the
   * DefaultProfile of that folderInfo.  If not, returns null.
   */
  public UserProfile getDefaultProfile() {
    if (getFolderInfo() != null) {
      return getFolderInfo().getDefaultProfile();
    } else
      return null;
  }

  /**
   * Saves the message to the given filename.
   */
  public void saveMessageAs(File saveFile) throws MessagingException{
    try {
      FileOutputStream fos = new FileOutputStream(saveFile);
      ((MimeMessage)getMessage()).writeTo(fos);
    } catch (IOException ioe) {
      MessagingException me = new MessagingException(Pooka.getProperty("error.errorCreatingAttachment", "Error attaching message"));
      me.setNextException(ioe);
      throw me;

    }
  }

  /**
   * Adds the sender of the message to the current AddressBook, if any.
   */
  public String addAddress(AddressBook book, boolean useVcard) throws MessagingException {
    String returnValue = null;
    boolean found = false;
    if (useVcard) {
      Attachment vcard = null;

      // see if there's a Vcard attachment on here.
      Vector attachList = getAttachments();
      if (attachList != null) {
        for (int i = 0; i < attachList.size() && vcard==null; i++) {
          Attachment current = (Attachment)attachList.get(i);
          if (current.getMimeType().match("text/x-vcard")) {
            vcard = current;
          }
        }

        if (vcard != null) {
          try {
            String vcardText = (String) vcard.getContent();
            BufferedReader reader = new BufferedReader(new StringReader(vcardText));
            net.suberic.pooka.vcard.Vcard addressEntry = net.suberic.pooka.vcard.Vcard.parse(reader);
            book.addAddress(addressEntry);
            returnValue = addressEntry.getID();

            found = true;
          } catch (Exception e) {
            // if we get any exceptions parsing the Vcard, just fall back to
            // using the fromAddress.  do print out a debugging message,
            // though.
            getMessageProxy().showError(Pooka.getProperty("error.parsingVcard", "Error parsing Vcard"), e);
          }
        }
      }
    }

    if (!found) {
      Address[] fromAddresses = getMessage().getFrom();
      javax.mail.internet.InternetAddress addr = (javax.mail.internet.InternetAddress) fromAddresses[0];

      // let's not support multiple froms.
      //AddressBookEntry entry = new net.suberic.pooka.vcard.Vcard(new java.util.Properties());
      AddressBookEntry entry = book.newAddressBookEntry();

      String personalName = addr.getPersonal();
      if (personalName == null)
        personalName = addr.getAddress();

      entry.setPersonalName(personalName);
      entry.setAddress(addr);
      book.addAddress(entry);
      returnValue = entry.getID();
    }

    return returnValue;
  }

  /**
   * Returns the Message that this MessageInfo is wrapping.
   */
  public Message getMessage() {
    return message;
  }

  /**
   * Returns the real, modifiable message that this MessageInfo is
   * wrapping.
   */
  public Message getRealMessage() throws MessagingException {
    if (getFolderInfo() != null) {
      return getFolderInfo().getRealMessage(this);
    }
    return message;
  }

  /**
   * Returns the FolderInfo to which this message belongs.
   */
  public FolderInfo getFolderInfo() {
    return folderInfo;
  }

  /**
   * Convenience method.  Returns whether or not that message has been
   * seen.
   */
  public boolean isSeen() {

    if (folderInfo != null && ! folderInfo.tracksUnreadMessages()) {
      return true;
    } else
      try {
        return flagIsSet("FLAG.SEEN");
      } catch (MessagingException me) {
        return true;
      }
  }

  /**
   * Sets the seen parameter to the newValue.  This basically calls
   * setFlag(Flags.Flag.SEEN, newValue) on the wrapped Message.
   */
  public void setSeen(boolean newValue) throws MessagingException {
    if (folderInfo != null && ! folderInfo.tracksUnreadMessages())
      return;
    else {
      boolean seen = isSeen();
      if (newValue != seen) {
        //Message m = getRealMessage();
        Message m = getMessage();
        m.setFlag(Flags.Flag.SEEN, newValue);
        getFolderInfo().fireMessageChangedEvent(new MessageChangedEvent(this, MessageChangedEvent.FLAGS_CHANGED, getMessage()));
      }
    }
  }

  public boolean isLoaded() {
    return loaded;
  }

  /**
   * This sets the loaded value for the MessageInfo to false.   This
   * should be called only if the TableInfo of the Message has been
   * changed and needs to be reloaded.
   */
  public void unloadTableInfo() {
    loaded=false;
  }

  public boolean hasLoadedAttachments() {
    return attachmentsLoaded;
  }

  boolean mHasAttachments = false;
  boolean mHasCheckedAttachments = false;

  /**
   * Returns whether or not this message has attachments.
   */
  public boolean hasAttachments() throws MessagingException {
    return hasAttachments(true);
  }

  /**
   * Returns whether or not this message has attachments.
   */
  public boolean hasAttachments(boolean inclusiveCryptoAttach) throws MessagingException {
      //if (mHasCheckedAttachments) {
      //  return mHasAttachments;
      //} else {
        if (hasLoadedAttachments()) {
          Vector attachs = getAttachments(inclusiveCryptoAttach);

          if (attachs != null && attachs.size() > 0)
            mHasAttachments = true;

          mHasCheckedAttachments = true;

          return mHasAttachments;

        } else {
          try {
            javax.mail.internet.ContentType type = new javax.mail.internet.ContentType(getMessage().getContentType());
            if (new String("multipart").equalsIgnoreCase(type.getPrimaryType()) && ! new String("alternative").equalsIgnoreCase(type.getSubType())) {
              return true;
            } else {
              return false;
            }
          } catch (javax.mail.internet.ParseException pe) {
            if (Pooka.isDebug()) {
              System.out.println("unable to parse content-type:  " + getMessage().getContentType());
            }
            mHasAttachments = false;
          }
        }
      //}

      return mHasAttachments;
    }

  /**
   * Returns whether or not this message has encryption on it.
   */
  public boolean hasEncryption() throws MessagingException {
    return (cryptoInfo.isEncrypted() || cryptoInfo.isSigned());
  }

  /**
   * Returns the cryptoInfo object for this MessageInfo.
   */
  public MessageCryptoInfo getCryptoInfo() {
    return cryptoInfo;
  }

  /**
   * Returns the attachments for this MessageInfo.  If the attachments
   * have not yet been loaded, attempts to load the attachments.
   * are considered.
   */
  public Vector getAttachments() throws MessagingException {
    return getAttachments(true);
  }

  /**
   * Returns the attachments for this MessageInfo.  If the attachments
   * have not yet been loaded, attempts to load the attachments.
   * @param inclusiveCryptoAttach: indicates whether the crypto attachments
   * are considered.
   */
  public Vector getAttachments(boolean inclusiveCryptoAttach) throws MessagingException {
    if (!hasLoadedAttachments())
      loadAttachmentInfo();

    Vector atts = attachments.getAttachments(getMaxMessageDisplayLength());

    if ((!inclusiveCryptoAttach) && atts != null && atts.size() > 0) {
        for (int i = 0; i < atts.size() ; i++) {
          Attachment attach = (Attachment) atts.elementAt(i);
          if(attach instanceof CryptoAttachment || attach instanceof SignedAttachment){
            atts.remove(attach);
            i--;
          }
        }
    }

    return atts;

  }

  /**
   * Returns the AttachmentBundle for this MessageInfo.
   */
  AttachmentBundle getAttachmentBundle() throws MessagingException {
    if (hasLoadedAttachments())
      return attachments;
    else {
      loadAttachmentInfo();
      return attachments;
    }
  }

  /**
   * Returns the MessageProxy for this MessageInfo, if any.
   */
  public MessageProxy getMessageProxy() {
    return messageProxy;
  }

  /**
   * Sets the primary MessageProxy for this MessageInfo.
   */
  public void setMessageProxy(MessageProxy newMp) {
    messageProxy = newMp;
  }

  /**
   * Returns the default maximum display length for this MessageInfo.
   */
  public int getMaxMessageDisplayLength() {
    int displayLength = 10000;
    try {
      displayLength = Integer.parseInt(Pooka.getProperty("Pooka.attachmentDisplayMaxLength", "100000"));
    } catch (NumberFormatException nfe) {
    }
    return displayLength;
  }

  /**
   * Returns the message to use if the message is displayed truncated (if the
   * MaxMessageDisplayLenght is exceeded.
   */
  public String getTruncationMessage() {
    return Pooka.getProperty("Pooka.messageTruncation", "------ Message truncated ------");
  }

  /**
   * Returns the message to use if the message is displayed truncated (if the
   * MaxMessageDisplayLenght is exceeded.
   */
  public String getHtmlTruncationMessage() {
    return Pooka.getProperty("Pooka.html.messageTruncation", "<br><br><b>------ Message truncated ------</b><br><br>");
  }

  public String getAttachmentSeparator() {
    return Pooka.getProperty("Pooka.attachmentSeparator", "\n\n");
  }

  public String getHtmlAttachmentSeparator() {
    return Pooka.getProperty("Pooka.html.attachmentSeparator", "<br><hr><br>");
  }

  /**
   * Returns whether or not this message has an HTML version available.
   */
  public boolean containsHtml() throws MessagingException {
    if (!hasLoadedAttachments())
      loadAttachmentInfo();

    return attachments.containsHtml();
  }

  /**
   * Returns true if the main content of this message exists only as
   * HTML.
   */
  public boolean isHtml() throws MessagingException {
    if (!hasLoadedAttachments())
      loadAttachmentInfo();

    return attachments.isHtml();
  }

  /**
   * Returns whether or not the underlying Message object has been
   * fetch()ed from the server yet.
   */
  public boolean hasBeenFetched() {
    return fetched;
  }

  /**
   * Sets whether or not the underlying Message has been fetch()ed from
   * the server.
   */
  public void setFetched(boolean newValue) {
    fetched = newValue;
  }

  /**
   * Returns the headerlines of the contained message
   */
  public Vector getHeaderLines() throws MessagingException{
      if (!hasLoadedAttachments())
        loadAttachmentInfo();

    return attachments.headerLines;
  }
}






TOP

Related Classes of net.suberic.pooka.MessageInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.