Package org.projectforge.mail

Source Code of org.projectforge.mail.MailAccount

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.mail;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.FetchProfile;
import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.FlagTerm;

import org.projectforge.core.ConfigXml;

/**
* Connects to a mail server and receives mails.
* @author Kai Reinhard (k.reinhard@micromata.de)
*/
public class MailAccount
{
  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(MailAccount.class);

  public static final String INBOX = "INBOX";

  private Folder folder;

  private Store store;

  private MailAccountConfig mailAcccountConfig;

  public MailAccount(final MailAccountConfig mailAccountConfig)
  {
    this.mailAcccountConfig = mailAccountConfig;
  }

  /** Gets the stored email of the given user. */
  public Mail getMail(final int mailId)
  {
    final Mail mail = new Mail();
    try {
      setEnvelope(mail, folder.getMessage(mailId));
      mail.setContent(getContent(mail.getMessage()));
      disconnect();
    } catch (IndexOutOfBoundsException ex) {
      log.warn("Message number out of range: " + mailId);
    } catch (MessagingException ex) {
      log.warn("", ex);
    } catch (IOException ex) {
      log.warn("", ex);
    }
    return mail;
  }

  /**
   * Gets a list of all Emails matching the given filter.
   * @return ArrayList of all found Email.
   */
  public Mail[] getMails(final MailFilter filter)
  {
    if (folder == null || folder.isOpen() == false) {
      log.error("Folder is not opened, can't get mails: "
          + this.mailAcccountConfig.getUsername()
          + "@"
          + this.mailAcccountConfig.getHostname()
          + " via "
          + this.mailAcccountConfig.getProtocol());
      return null;
    }
    final List<Mail> table = new ArrayList<Mail>();
    try {
      int totalMessages = folder.getMessageCount();
      log.debug("New messages: " + folder.getNewMessageCount());
      log.debug("Total messages: " + totalMessages);
      if (totalMessages == 0) {
        return new Mail[0];
      }
      // Attributes & Flags for all messages ..
      final Message[] msgs;
      if (filter.isOnlyRecent() == true) {
        msgs = folder.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false));
      } else {
        msgs = folder.getMessages();
      }
      // Use a suitable FetchProfile
      final FetchProfile fp = new FetchProfile();
      fp.add(FetchProfile.Item.ENVELOPE);
      fp.add(FetchProfile.Item.FLAGS);
      fp.add("X-Mailer");
      folder.fetch(msgs, fp);

      for (int i = 0; i < msgs.length; i++) {
        final Mail mail = new Mail();
        setEnvelope(mail, msgs[i]);
        mail.setContent(getContent(mail.getMessage()));
        // if (filter == null || (mail.isRecent() == true && filter.isRecent() == true)
        // || (mail.isSeen() == true && filter.isSeen() == true)
        // || (mail.isDeleted() == true && filter.isDeleted() == true)) {
        table.add(mail);
        // }
      }
      // No sort the table by date:
      final Mail[] mailArray = new Mail[table.size()];
      table.toArray(mailArray);
      Arrays.sort(mailArray);
      return mailArray;
    } catch (javax.mail.MessagingException ex) {
      log.info(ex.getMessage(), ex);
      throw new RuntimeException(ex);
    } catch (IOException ex) {
      log.info(ex.getMessage(), ex);
      throw new RuntimeException(ex);
    }
  }

  /**
   * Opens the connection to the mailserver. Don't forget to call disconnect if this method returns true!
   * @param mbox The folder name to open. If null then the default folder will be opened.
   * @param readwrite If false then the mbox is connected in readonly mode.
   * @return true on success, otherwise false.
   */
  public boolean connect(final String mbox, final boolean readwrite)
  {
    try {
      // Get a Properties object
      final Properties props = new Properties();
      if (ConfigXml.getInstance().getUsersSSLSocketFactory() != null) {
        props
            .put("mail." + mailAcccountConfig.getProtocol() + ".ssl.socketFactory", ConfigXml.getInstance().getUsersSSLSocketFactory());
      }
      final Session session = Session.getDefaultInstance(props, null);

      // Get a Store object
      store = null;
      try {
        store = session.getStore(mailAcccountConfig.getProtocol());
      } catch (javax.mail.NoSuchProviderException ex) {
        log.error(ex.getMessage(), ex);
        // serverData.setErrorMessageKey("mail.error.noSuchProviderException");
        return false;
      }
      if (mailAcccountConfig.getPort() > 0) {
        store.connect(mailAcccountConfig.getHostname(), mailAcccountConfig.getPort(), mailAcccountConfig.getUsername(), mailAcccountConfig
            .getPassword());
      } else {
        store.connect(mailAcccountConfig.getHostname(), mailAcccountConfig.getUsername(), mailAcccountConfig.getPassword());
      }
      // Open the Folder

      folder = store.getDefaultFolder();
      if (folder == null) {
        // serverData.setErrorMessageKey("mail.error.noDefaultFolder");
        return false;
      }

      if (mbox != null) {
        folder = folder.getFolder(mbox);
        if (folder == null) {
          // serverData.setErrorMessageKey("mail.error.invalidFolder");
          return false;
        }
      }
      if (readwrite == true) {
        // try to open read/write and if that fails try read-only
        try {
          folder.open(Folder.READ_WRITE);
        } catch (MessagingException ex) {
          log.error("Can't open mbox in read-write mode, try to open folder in read-only mode instead: " + ex.getMessage());
          folder.open(Folder.READ_ONLY);
        }
      } else {
        folder.open(Folder.READ_ONLY);
      }
    } catch (javax.mail.MessagingException ex) {
      // serverData.setErrorMessageKey("mail.error.messagingException");
      // serverData.setOriginalErrorMessage(ex.getMessage());
      log.info(ex.getMessage(), ex);
      return false;
    }
    return true;
  }

  /**
   * Disconnects the folder and store if given and is opened yet.
   * @return
   */
  public boolean disconnect()
  {
    boolean success = true;
    if (folder != null && folder.isOpen() == true) {
      try {
        folder.close(false);
      } catch (MessagingException ex) {
        log.error("Exception encountered while trying tho close the folder: " + ex, ex);
        success = false;
      }
    }
    if (store != null && store.isConnected() == true) {
      try {
        store.close();
      } catch (MessagingException ex) {
        log.error("Exception encountered while trying to close the store: " + ex, ex);
        success = false;
      }
    }
    return success;
  }

  protected void setEnvelope(final Mail mail, final Message message) throws javax.mail.MessagingException
  {
    mail.setMessage(message);
    Address[] addr;
    // ID
    mail.setMessageNumber(message.getMessageNumber());

    // FROM
    StringBuffer buf = new StringBuffer();
    addr = message.getFrom();
    if (addr != null) {
      for (int j = 0; j < addr.length; j++) {
        if (j > 0)
          buf.append(",");
        buf.append(addr[j].toString());
      }
    }
    mail.setFrom(buf.toString());

    // TO
    addr = message.getRecipients(Message.RecipientType.TO);
    buf = new StringBuffer();
    if (addr != null) {
      for (int j = 0; j < addr.length; j++) {
        if (j > 0)
          buf.append(",");
        buf.append(addr[j].toString());
      }
    }
    mail.setTo(buf.toString());

    // SUBJECT
    mail.setSubject(message.getSubject());

    // DATE
    final Date date = message.getSentDate();
    if (date != null) {
      mail.setDate(date);
    } else { // Needed for compareTo (assume 1.1.1970)
      mail.setDate(new Date(0));
    } // FLAGS
    final Flags flags = message.getFlags();
    final Flags.Flag[] systemFlags = flags.getSystemFlags(); // get the system flags

    for (int i = 0; i < systemFlags.length; i++) {
      final Flags.Flag flag = systemFlags[i];
      if (flag == Flags.Flag.ANSWERED) {
        // Ignore this flag
      } else if (flag == Flags.Flag.DELETED) {
        mail.setDeleted(true);
      } else if (flag == Flags.Flag.DRAFT) {
        // Ignore this flag
      } else if (flag == Flags.Flag.FLAGGED) {
        // Ignore this flag
      } else if (flag == Flags.Flag.RECENT) {
        mail.setRecent(true);
      } else if (flag == Flags.Flag.SEEN) {
        mail.setSeen(true);
      } else {
        // skip it
      }
    }
  }

  private String getContent(final Part msg) throws MessagingException, IOException
  {
    final StringBuffer buf = new StringBuffer();
    getContent(msg, buf);
    return buf.toString();
  }

  private void getContent(final Part msg, final StringBuffer buf) throws MessagingException, IOException
  {
    if (log.isDebugEnabled() == true) {
      log.debug("CONTENT-TYPE: " + msg.getContentType());
    }
    String filename = msg.getFileName();
    if (filename != null) {
      log.debug("FILENAME: " + filename);
    }
    // Using isMimeType to determine the content type avoids
    // fetching the actual content data until we need it.
    if (msg.isMimeType("text/plain")) {
      log.debug("This is plain text");
      try {
        buf.append(msg.getContent());
      } catch (UnsupportedEncodingException ex) {
        buf.append("Unsupported charset by java mail, sorry: " + "CONTENT-TYPE=[" + msg.getContentType() + "]");
      }
    } else if (msg.isMimeType("text/html")) {
      log.debug("This is html text");
      buf.append(msg.getContent());
    } else if (msg.isMimeType("multipart/*")) {
      log.debug("This is a Multipart");
      final Multipart multiPart = (Multipart) msg.getContent();
      int count = multiPart.getCount();
      for (int i = 0; i < count; i++) {
        if (i > 0) {
          buf.append("\n----------\n");
        }
        getContent(multiPart.getBodyPart(i), buf);
      }
    } else if (msg.isMimeType("message/rfc822")) {
      log.debug("This is a Nested Message");
      buf.append(msg.getContent());
    } else {
      log.debug("This is an unknown type");
      // If we actually want to see the data, and it's not a
      // MIME type we know, fetch it and check its Java type.
      final Object obj = msg.getContent();
      if (obj instanceof String) {
        buf.append(obj);
      } else if (obj instanceof InputStream) {
        log.debug("Inputstream");
        buf.append("Attachement: ");
        if (filename != null) {
          buf.append(filename);
        } else {
          buf.append("Unsupported format (not a file).");
        }
      } else {
        log.error("Should not occur");
        buf.append("Unsupported type");
      }
    }
  }
}
TOP

Related Classes of org.projectforge.mail.MailAccount

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.