Example usage for javax.mail.internet MimeMessage getMessageNumber

List of usage examples for javax.mail.internet MimeMessage getMessageNumber

Introduction

In this page you can find the example usage for javax.mail.internet MimeMessage getMessageNumber.

Prototype

public int getMessageNumber() 

Source Link

Document

Get the Message number for this Message.

Usage

From source file:edu.hawaii.soest.hioos.storx.StorXDispatcher.java

/**
 * A method that executes the reading of data from the email account to the
 * RBNB server after all configuration of settings, connections to hosts,
 * and thread initiatizing occurs. This method contains the detailed code
 * for reading the data and interpreting the data files.
 *///from   w w w  .  ja v a 2s. c o m
protected boolean execute() {
    logger.debug("StorXDispatcher.execute() called.");
    boolean failed = true; // indicates overall success of execute()
    boolean messageProcessed = false; // indicates per message success

    // declare the account properties that will be pulled from the
    // email.account.properties.xml file
    String accountName = "";
    String server = "";
    String username = "";
    String password = "";
    String protocol = "";
    String dataMailbox = "";
    String processedMailbox = "";
    String prefetch = "";

    // fetch data from each sensor in the account list
    List accountList = this.xmlConfiguration.getList("account.accountName");

    for (Iterator aIterator = accountList.iterator(); aIterator.hasNext();) {

        int aIndex = accountList.indexOf(aIterator.next());

        // populate the email connection variables from the xml properties
        // file
        accountName = (String) this.xmlConfiguration.getProperty("account(" + aIndex + ").accountName");
        server = (String) this.xmlConfiguration.getProperty("account(" + aIndex + ").server");
        username = (String) this.xmlConfiguration.getProperty("account(" + aIndex + ").username");
        password = (String) this.xmlConfiguration.getProperty("account(" + aIndex + ").password");
        protocol = (String) this.xmlConfiguration.getProperty("account(" + aIndex + ").protocol");
        dataMailbox = (String) this.xmlConfiguration.getProperty("account(" + aIndex + ").dataMailbox");
        processedMailbox = (String) this.xmlConfiguration
                .getProperty("account(" + aIndex + ").processedMailbox");
        prefetch = (String) this.xmlConfiguration.getProperty("account(" + aIndex + ").prefetch");

        logger.debug("\n\nACCOUNT DETAILS: \n" + "accountName     : " + accountName + "\n"
                + "server          : " + server + "\n" + "username        : " + username + "\n"
                + "password        : " + password + "\n" + "protocol        : " + protocol + "\n"
                + "dataMailbox     : " + dataMailbox + "\n" + "processedMailbox: " + processedMailbox + "\n"
                + "prefetch        : " + prefetch + "\n");

        // get a connection to the mail server
        Properties props = System.getProperties();
        props.setProperty("mail.store.protocol", protocol);
        props.setProperty("mail.imaps.partialfetch", prefetch);

        try {

            // create the imaps mail session
            this.mailSession = Session.getDefaultInstance(props, null);
            this.mailStore = mailSession.getStore(protocol);

        } catch (NoSuchProviderException nspe) {

            try {
                // pause for 10 seconds
                logger.debug(
                        "There was a problem connecting to the IMAP server. " + "Waiting 10 seconds to retry.");
                Thread.sleep(10000L);
                this.mailStore = mailSession.getStore(protocol);

            } catch (NoSuchProviderException nspe2) {

                logger.debug("There was an error connecting to the mail server. The " + "message was: "
                        + nspe2.getMessage());
                nspe2.printStackTrace();
                failed = true;
                return !failed;

            } catch (InterruptedException ie) {

                logger.debug("The thread was interrupted: " + ie.getMessage());
                failed = true;
                return !failed;

            }

        }

        try {

            this.mailStore.connect(server, username, password);

            // get folder references for the inbox and processed data box
            Folder inbox = mailStore.getFolder(dataMailbox);
            inbox.open(Folder.READ_WRITE);

            Folder processed = this.mailStore.getFolder(processedMailbox);
            processed.open(Folder.READ_WRITE);

            Message[] msgs;
            while (!inbox.isOpen()) {
                inbox.open(Folder.READ_WRITE);

            }
            msgs = inbox.getMessages();

            List<Message> messages = new ArrayList<Message>();
            Collections.addAll(messages, msgs);

            // sort the messages found in the inbox by date sent
            Collections.sort(messages, new Comparator<Message>() {

                public int compare(Message message1, Message message2) {
                    int value = 0;
                    try {
                        value = message1.getSentDate().compareTo(message2.getSentDate());
                    } catch (MessagingException e) {
                        e.printStackTrace();
                    }
                    return value;

                }

            });

            logger.debug("Number of messages: " + messages.size());
            for (Message message : messages) {

                // Copy the message to ensure we have the full attachment
                MimeMessage mimeMessage = (MimeMessage) message;
                MimeMessage copiedMessage = new MimeMessage(mimeMessage);

                // determine the sensor serial number for this message
                String messageSubject = copiedMessage.getSubject();
                Date sentDate = copiedMessage.getSentDate();
                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");

                // The subfolder of the processed mail folder (e.g. 2016-12);
                String destinationFolder = formatter.format(sentDate);
                logger.debug("Message date: " + sentDate + "\tNumber: " + copiedMessage.getMessageNumber());
                String[] subjectParts = messageSubject.split("\\s");
                String loggerSerialNumber = "SerialNumber";
                if (subjectParts.length > 1) {
                    loggerSerialNumber = subjectParts[2];

                }

                // Do we have a data attachment? If not, there's no data to
                // process
                if (copiedMessage.isMimeType("multipart/mixed")) {

                    logger.debug("Message size: " + copiedMessage.getSize());

                    MimeMessageParser parser = new MimeMessageParser(copiedMessage);
                    try {
                        parser.parse();

                    } catch (Exception e) {
                        logger.error("Failed to parse the MIME message: " + e.getMessage());
                        continue;
                    }
                    ByteBuffer messageAttachment = ByteBuffer.allocate(256); // init only

                    logger.debug("Has attachments: " + parser.hasAttachments());
                    for (DataSource dataSource : parser.getAttachmentList()) {
                        if (StringUtils.isNotBlank(dataSource.getName())) {
                            logger.debug(
                                    "Attachment: " + dataSource.getName() + ", " + dataSource.getContentType());

                            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                            IOUtils.copy(dataSource.getInputStream(), outputStream);
                            messageAttachment = ByteBuffer.wrap(outputStream.toByteArray());

                        }
                    }

                    // We now have the attachment and serial number. Parse the attachment 
                    // for the data components, look up the storXSource based on the serial 
                    // number, and push the data to the DataTurbine

                    // parse the binary attachment
                    StorXParser storXParser = new StorXParser(messageAttachment);

                    // iterate through the parsed framesMap and handle each
                    // frame
                    // based on its instrument type
                    BasicHierarchicalMap framesMap = (BasicHierarchicalMap) storXParser.getFramesMap();

                    Collection frameCollection = framesMap.getAll("/frames/frame");
                    Iterator framesIterator = frameCollection.iterator();

                    while (framesIterator.hasNext()) {

                        BasicHierarchicalMap frameMap = (BasicHierarchicalMap) framesIterator.next();

                        // logger.debug(frameMap.toXMLString(1000));

                        String frameType = (String) frameMap.get("type");
                        String sensorSerialNumber = (String) frameMap.get("serialNumber");

                        // handle each instrument type
                        if (frameType.equals("HDR")) {
                            logger.debug("This is a header frame. Skipping it.");

                        } else if (frameType.equals("STX")) {

                            try {

                                // handle StorXSource
                                StorXSource source = (StorXSource) sourceMap.get(sensorSerialNumber);
                                // process the data using the StorXSource
                                // driver
                                messageProcessed = source.process(this.xmlConfiguration, frameMap);

                            } catch (ClassCastException cce) {

                            }

                        } else if (frameType.equals("SBE")) {

                            try {

                                // handle CTDSource
                                CTDSource source = (CTDSource) sourceMap.get(sensorSerialNumber);

                                // process the data using the CTDSource
                                // driver
                                messageProcessed = source.process(this.xmlConfiguration, frameMap);

                            } catch (ClassCastException cce) {

                            }

                        } else if (frameType.equals("NLB")) {

                            try {

                                // handle ISUSSource
                                ISUSSource source = (ISUSSource) sourceMap.get(sensorSerialNumber);
                                // process the data using the ISUSSource
                                // driver
                                messageProcessed = source.process(this.xmlConfiguration, frameMap);

                            } catch (ClassCastException cce) {

                            }

                        } else if (frameType.equals("NDB")) {

                            try {

                                // handle ISUSSource
                                ISUSSource source = (ISUSSource) sourceMap.get(sensorSerialNumber);
                                // process the data using the ISUSSource
                                // driver
                                messageProcessed = source.process(this.xmlConfiguration, frameMap);

                            } catch (ClassCastException cce) {

                            }

                        } else {

                            logger.debug("The frame type " + frameType + " is not recognized. Skipping it.");
                        }

                    } // end while()

                    if (this.sourceMap.get(loggerSerialNumber) != null) {

                        // Note: Use message (not copiedMessage) when setting flags 

                        if (!messageProcessed) {
                            logger.info("Failed to process message: " + "Message Number: "
                                    + message.getMessageNumber() + "  " + "Logger Serial:"
                                    + loggerSerialNumber);
                            // leave it in the inbox, flagged as seen (read)
                            message.setFlag(Flags.Flag.SEEN, true);
                            logger.debug("Saw message " + message.getMessageNumber());

                        } else {

                            // message processed successfully. Create a by-month sub folder if it doesn't exist
                            // Copy the message and flag it deleted
                            Folder destination = processed.getFolder(destinationFolder);
                            boolean created = destination.create(Folder.HOLDS_MESSAGES);
                            inbox.copyMessages(new Message[] { message }, destination);
                            message.setFlag(Flags.Flag.DELETED, true);
                            logger.debug("Deleted message " + message.getMessageNumber());
                        } // end if()

                    } else {
                        logger.debug("There is no configuration information for " + "the logger serial number "
                                + loggerSerialNumber + ". Please add the configuration to the "
                                + "email.account.properties.xml configuration file.");

                    } // end if()

                } else {
                    logger.debug("This is not a data email since there is no "
                            + "attachment. Skipping it. Subject: " + messageSubject);

                } // end if()

            } // end for()

            // expunge messages and close the mail server store once we're
            // done
            inbox.expunge();
            this.mailStore.close();

        } catch (MessagingException me) {
            try {
                this.mailStore.close();

            } catch (MessagingException me2) {
                failed = true;
                return !failed;

            }
            logger.info(
                    "There was an error reading the mail message. The " + "message was: " + me.getMessage());
            me.printStackTrace();
            failed = true;
            return !failed;

        } catch (IOException me) {
            try {
                this.mailStore.close();

            } catch (MessagingException me3) {
                failed = true;
                return !failed;

            }
            logger.info("There was an I/O error reading the message part. The " + "message was: "
                    + me.getMessage());
            me.printStackTrace();
            failed = true;
            return !failed;

        } catch (IllegalStateException ese) {
            try {
                this.mailStore.close();

            } catch (MessagingException me4) {
                failed = true;
                return !failed;

            }
            logger.info("There was an error reading messages from the folder. The " + "message was: "
                    + ese.getMessage());
            failed = true;
            return !failed;

        } finally {

            try {
                this.mailStore.close();

            } catch (MessagingException me2) {
                logger.debug("Couldn't close the mail store: " + me2.getMessage());

            }

        }

    }

    return !failed;
}

From source file:edu.stanford.muse.email.EmailFetcherStats.java

/**
 * fetch given message idx's in given folder -- @performance critical
 *
 * @param offset - the original offset of the first message in the messages array, important to initialize
 *               for proper assignment of unique id or doc Id
 *///from  w  ww  .  j  av  a2 s  .c  o  m
//private void fetchUncachedMessages(String sanitizedFName, Folder folder, DocCache cache, List<Integer> msgIdxs) throws MessagingException, FileNotFoundException, IOException, GeneralSecurityException {
private void fetchAndIndexMessages(Folder folder, Message[] messages, int offset, int totalMessages)
        throws MessagingException, IOException, GeneralSecurityException {
    //mark the processing of new batch
    if (offset == 0)
        fetchStartTime = System.currentTimeMillis();

    currentStatus = JSONUtils.getStatusJSON(
            (emailStore instanceof MboxEmailStore) ? "Parsing " + folder.getName() + " (can take a while)..."
                    : "Reading " + folder.getName() + "...");

    // bulk fetch of all message headers
    int n = messages.length;

    // eliminate any messages the archive already has
    messages = removeMessagesAlreadyInArchive(archive, messages);

    log.info(n - messages.length + " message(s) already in the archive");

    ArrayList<EmailDocument> emails = new ArrayList<EmailDocument>();

    // for performance, we need to do bulk prefetches, instead of fetching 1 message at a time
    // prefetchedMessages will be a temp cache of prefetched messages
    int first_i_prefetched = -1, last_i_prefetched = -1;
    List<?> prefetchedMessages = null; // the type of this can be either list<string> if text only, otherwise list<mimemmessage>

    long highestUID = archive.getLastUIDForFolder(fetchedFolderInfo.accountKey, fetchedFolderInfo.longName);
    long lastAssignedUID = highestUID;
    boolean bodyTextOnly = !fetchConfig.downloadAttachments;
    try {
        archive.openForWrite();
        for (int i = 0; i < messages.length; i++) {
            // critical step: (thanks, yourkit!)
            // null out the ref to the previous message, otherwise it stays in memory, and the heap effectively needs to be as big as the size of all messages
            if (i > 0)
                messages[i - 1] = null;

            if (isCancelled)
                break;

            Message m = messages[i];
            MimeMessage mm = (MimeMessage) m;

            if (i >= last_i_prefetched) {
                // critical perf. step: do a bulk imap prefetch
                // the prefetch will fetch as many messages as possible up to a max buffer size, and return the messages prefetched
                // last_i_prefetched tracks what is the last index into idxs that we have prefetched.
                // when we run out of prefetched messages, we do another bulk prefetch

                prefetchedMessages = do_imap_prefetch(messages, i, folder, bodyTextOnly);
                if (prefetchedMessages != null) {
                    first_i_prefetched = i;
                    last_i_prefetched = i + prefetchedMessages.size();
                }
            }

            int pctDone = ((i + offset) * 100) / totalMessages;
            long elapsedMillis = System.currentTimeMillis() - fetchStartTime;
            long unprocessedSecs = Util.getUnprocessedMessage(i + offset, totalMessages, elapsedMillis);
            int N_TEASERS = 50; // 50 ok here, because it takes a long time to fetch and process messages, so teaser computation is relatively not expensive
            int nTriesForThisMessage = 0;
            currentStatus = getStatusJSONWithTeasers(
                    "Reading " + Util.commatize(totalMessages) + " messages from " + folder.getName() + "...",
                    pctDone, elapsedMillis / 1000, unprocessedSecs, emails, N_TEASERS);

            int messageNum = mm.getMessageNumber();

            try {
                long unique_id;

                // if we have uid, that's even better
                // don't use uid's for mbox, it has a bug and always gives -1
                // see http://james.apache.org/server/rfclist/imap4/rfc2060.txt for uid spec
                if (folder instanceof UIDFolder && !(emailStore instanceof MboxEmailStore)) {
                    long uid = ((UIDFolder) folder).getUID(m);
                    unique_id = uid;
                } else
                    unique_id = lastAssignedUID + 1 + i + offset; // +1 since i starts from 0 (but lastAssignedUID can be -1 -- is that safe? -sgh)

                if (unique_id > highestUID)
                    highestUID = unique_id;

                String unique_id_as_string = Long.toString(unique_id);

                // well, we already converted to emaildoc above during removeMessagesAlreadyInArchive
                // not a serious perf. concern now, but revisit if needed
                EmailDocument ed = convertToEmailDocument(mm, unique_id_as_string); // this messageNum is mostly for debugging, it should not be used for equals etc.
                // need to check this again, because there might be duplicates such within the set we are currently processing.
                if (archive.containsDoc(ed)) {
                    stats.nMessagesAlreadyPresent++;
                    dataErrors.add("Duplicate message: " + ed); // note: report.jsp depends on this specific string
                    continue;
                }

                MimeMessage originalMessage = mm; // this is the mm that has all the headers etc.
                List<Blob> attachmentsList = new ArrayList<Blob>();

                // if we already have it prefetched, use the prefetched version
                List<String> contents = null;

                if (first_i_prefetched >= 0 && prefetchedMessages != null) {
                    if (!fetchConfig.downloadAttachments) {
                        // text only means the prefetchedMessages are stored directly as a list of strings
                        String content = (String) prefetchedMessages.get(i - first_i_prefetched); // note: this_mm only has the prefetched content, but not the headers
                        contents = new ArrayList<String>();

                        try {
                            // a special for yahoo which routinely uses quoted-printable. content looks like  =0A0D.... = etc.
                            if (mm.isMimeType("multipart/alternative")) {
                                Multipart mm_mp = (Multipart) mm.getContent();
                                Part p0 = mm_mp.getBodyPart(0);
                                if (p0 instanceof com.sun.mail.imap.IMAPBodyPart) {
                                    String encoding = ((com.sun.mail.imap.IMAPBodyPart) p0).getEncoding();
                                    if ("quoted-printable".equals(encoding)) {
                                        content = new String(
                                                Util.getBytesFromStream(javax.mail.internet.MimeUtility.decode(
                                                        new java.io.ByteArrayInputStream(content.getBytes()),
                                                        "quoted-printable")));
                                    }
                                }
                            }
                        } catch (Exception e) {
                            Util.print_exception("Error trying to parse encoding of multipart", e, log);
                        }

                        contents.add(content);
                    } else {
                        // subtle issue here: the contentType of the prefetchedMessage needs to be be set to the original_mm's content-type.
                        // this was found for cases where the original message is multipart-alternative with a text and html part.
                        // if we don't set prefetchedMessage's content type, it gets a mime type of text/plain and a body = the entire multipart including both parts.
                        // found on sgh's sent mail w/subject: "text to add in help" from  Fri, 7 Jun 2013
                        MimeMessage prefetchedMessage = (MimeMessage) prefetchedMessages
                                .get(i - first_i_prefetched);
                        String contentTypeHeaders[] = originalMessage.getHeader("Content-Type");
                        String contentTypeHeader = null;
                        if (contentTypeHeaders != null && contentTypeHeaders.length == 1)
                            contentTypeHeader = contentTypeHeaders[0];

                        if (!Util.nullOrEmpty(contentTypeHeader)) // we do care about body structure, hang on to it
                            prefetchedMessage.setHeader("Content-Type", contentTypeHeader);
                        mm = prefetchedMessage;
                    }
                    prefetchedMessages.set(i - first_i_prefetched, null); // null out to save memory
                }

                if (contents == null)
                    contents = processMessagePart(messageNum, originalMessage, mm, attachmentsList);

                // if mm is not prefetched, it is the same as original_mm
                // will also work, but will be slow as javamail accesses and fetches each mm separately, instead of using the bulk prefetched version
                // even when prefetched, the processMessagePart is somewhat expensive because the attachments have to be extracted etc.

                // we could overlap processMessagePart with do_imap_prefetch by prefetching in a separate thread, since prefetch is network limited.
                // but profiling shows processMessagePart takes only 1/4th the time of do_imap_prefetch so overlapping would be a relatively small gain.
                // not worth the effort right now.
                ed.attachments = attachmentsList;
                if (fetchConfig.downloadAttachments)
                    ed.attachmentsYetToBeDownloaded = false; // we've already downloaded our attachments

                // concat all the contents parts
                StringBuilder sb = new StringBuilder();
                for (String s : contents) {
                    sb.append(s);
                    sb.append("\n");
                }

                String contentStr = sb.toString();
                if (!messageLooksOk(contentStr)) {
                    dataErrors.add("Skipping message as it seems to have very long words: " + ed);
                    continue;
                }

                if (contentStr.length() > Config.MAX_TEXT_SIZE_TO_ANNOTATE) {
                    dataErrors.add("Skipping message as it seems to be very long: " + contentStr.length()
                            + " chars, while the max size message that will be annotated for display is "
                            + Config.MAX_TEXT_SIZE_TO_ANNOTATE + " chars. Message = " + ed);
                    // but we continue, don't skip the message entirely. See issue #111
                }

                contentStr = IndexUtils.normalizeNewlines(contentStr); // just get rid of \r's

                archive.addDoc(ed, contentStr);

                List<LinkInfo> linkList = new ArrayList<LinkInfo>();
                // linkList might be used only for slant
                IndexUtils.populateDocLinks(ed, contentStr, linkList, true);
                ed.links = linkList;
                stats.nMessagesAdded++;
            } catch (Exception ex) {
                // sometimes we get unexpected folder closed, so try again
                boolean retry = false;
                if (ex instanceof javax.mail.FolderClosedException) {
                    log.warn("Oops, thread " + threadID + " got the folder closed in its face! "
                            + ex.getMessage());

                    // sometimes we get this exception about folder closed
                    // retry up to 3 times, then give up
                    if (nTriesForThisMessage < 3) {
                        retry = true;
                        log.info("Re-opening email store; attempt #" + (nTriesForThisMessage + 1)
                                + " for message " + i);
                        nTriesForThisMessage++;
                        messages = openFolderAndGetMessages();
                        fetchHeaders(messages);
                        --i; // adjust the message index n try again
                    }
                }

                if (!retry) {
                    // we sometimes see UnsupportedEncodingException with x-utf8utf8 mime type and ParseException
                    // nothing much can be done, just create a dummy doc and add it to the cache
                    nErrors++;
                    stats.nErrors++;
                    EmailDocument ed = new EmailDocument(Integer.toString(messageNum));
                    log.warn("Exception reading message from " + folder_name() + " Message #" + messageNum + " "
                            + ex.getMessage() + "\n" + Util.stackTrace(ex));

                    ed.setErrorString(Util.stackTrace(ex));
                }
            }
        }
    } catch (Throwable t) {
        Util.print_exception(t, log);
    } finally {
        //            if (cancelled && false) // TODO: disable for now as currently only indexes are rolled back and allDocs/blobs are not rolled back in sync yet
        //               archive.rollbackIndexWrites();
        //            else
        currentStatus = JSONUtils.getStatusJSON("Saving archive...");
        archive.close();
    }

    fetchedFolderInfo.lastSeenUID = highestUID;
    log.info("at end of fetch, folder info is " + fetchedFolderInfo);

    log.info("emailfetcher thread completed, archive has " + archive.getAllDocs().size() + " docs");
}

From source file:net.wastl.webmail.server.WebMailSession.java

/**
 * Fetch a message from a folder./*w w w  . j av  a 2  s .  c om*/
 * Will put the messages parameters in the sessions environment
 *
 * @param foldername Name of the folder were the message should be fetched from
 * @param msgnum Number of the message to fetch
 * @param mode there are three different modes: standard, reply and forward. reply and forward will enter the message
 *             into the current work element of the user and set some additional flags on the message if the user
 *             has enabled this option.
 * @see net.wastl.webmail.server.WebMailSession.GETMESSAGE_MODE_STANDARD
 * @see net.wastl.webmail.server.WebMailSession.GETMESSAGE_MODE_REPLY
 * @see net.wastl.webmail.server.WebMailSession.GETMESSAGE_MODE_FORWARD
 */
public void getMessage(String folderhash, int msgnum, int mode) throws NoSuchFolderException, WebMailException {
    // security reasons:
    // attachments=null;

    try {
        TimeZone tz = TimeZone.getDefault();
        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT,
                user.getPreferredLocale());
        df.setTimeZone(tz);
        Folder folder = getFolder(folderhash);
        Element xml_folder = model.getFolder(folderhash);

        if (folder == null) {
            throw new NoSuchFolderException("No such folder: " + folderhash);
        }

        if (folder.isOpen() && folder.getMode() == Folder.READ_WRITE) {
            folder.close(false);
            folder.open(Folder.READ_ONLY);
        } else if (!folder.isOpen()) {
            folder.open(Folder.READ_ONLY);
        }

        MimeMessage m = (MimeMessage) folder.getMessage(msgnum);

        String messageid;
        try {
            StringTokenizer tok = new StringTokenizer(m.getMessageID(), "<>");
            messageid = tok.nextToken();
        } catch (NullPointerException ex) {
            // For mail servers that don't generate a Message-ID (Outlook et al)
            messageid = user.getLogin() + "." + msgnum + ".jwebmail@" + user.getDomain();
        }

        Element xml_current = model.setCurrentMessage(messageid);
        XMLMessage xml_message = model.getMessage(xml_folder, m.getMessageNumber() + "", messageid);

        /* Check whether we already cached this message (not only headers but complete)*/
        boolean cached = xml_message.messageCompletelyCached();
        /* If we cached the message, we don't need to fetch it again */
        if (!cached) {
            //Element xml_header=model.getHeader(xml_message);

            try {
                String from = MimeUtility.decodeText(Helper.joinAddress(m.getFrom()));
                String replyto = MimeUtility.decodeText(Helper.joinAddress(m.getReplyTo()));
                String to = MimeUtility
                        .decodeText(Helper.joinAddress(m.getRecipients(Message.RecipientType.TO)));
                String cc = MimeUtility
                        .decodeText(Helper.joinAddress(m.getRecipients(Message.RecipientType.CC)));
                String bcc = MimeUtility
                        .decodeText(Helper.joinAddress(m.getRecipients(Message.RecipientType.BCC)));
                Date date_orig = m.getSentDate();
                String date = getStringResource("no date");
                if (date_orig != null) {
                    date = df.format(date_orig);
                }
                String subject = "";
                if (m.getSubject() != null) {
                    subject = MimeUtility.decodeText(m.getSubject());
                }
                if (subject == null || subject.equals("")) {
                    subject = getStringResource("no subject");
                }

                try {
                    Flags.Flag[] sf = m.getFlags().getSystemFlags();
                    for (int j = 0; j < sf.length; j++) {
                        if (sf[j] == Flags.Flag.RECENT)
                            xml_message.setAttribute("recent", "true");
                        if (sf[j] == Flags.Flag.SEEN)
                            xml_message.setAttribute("seen", "true");
                        if (sf[j] == Flags.Flag.DELETED)
                            xml_message.setAttribute("deleted", "true");
                        if (sf[j] == Flags.Flag.ANSWERED)
                            xml_message.setAttribute("answered", "true");
                        if (sf[j] == Flags.Flag.DRAFT)
                            xml_message.setAttribute("draft", "true");
                        if (sf[j] == Flags.Flag.FLAGGED)
                            xml_message.setAttribute("flagged", "true");
                        if (sf[j] == Flags.Flag.USER)
                            xml_message.setAttribute("user", "true");
                    }
                } catch (NullPointerException ex) {
                }
                if (m.getContentType().toUpperCase().startsWith("MULTIPART/")) {
                    xml_message.setAttribute("attachment", "true");
                }

                int size = m.getSize();
                size /= 1024;
                xml_message.setAttribute("size", (size > 0 ? size + "" : "<1") + " kB");

                /* Set all of what we found into the DOM */
                xml_message.setHeader("FROM", from);
                xml_message.setHeader("SUBJECT", Fancyfier.apply(subject));
                xml_message.setHeader("TO", to);
                xml_message.setHeader("CC", cc);
                xml_message.setHeader("BCC", bcc);
                xml_message.setHeader("REPLY-TO", replyto);
                xml_message.setHeader("DATE", date);

                /* Decode MIME contents recursively */
                xml_message.removeAllParts();
                parseMIMEContent(m, xml_message, messageid);

            } catch (UnsupportedEncodingException e) {
                log.warn("Unsupported Encoding in parseMIMEContent: " + e.getMessage());
            }
        }
        /* Set seen flag (Maybe make that threaded to improve performance) */
        if (user.wantsSetFlags()) {
            if (folder.isOpen() && folder.getMode() == Folder.READ_ONLY) {
                folder.close(false);
                folder.open(Folder.READ_WRITE);
            } else if (!folder.isOpen()) {
                folder.open(Folder.READ_WRITE);
            }
            folder.setFlags(msgnum, msgnum, new Flags(Flags.Flag.SEEN), true);
            folder.setFlags(msgnum, msgnum, new Flags(Flags.Flag.RECENT), false);
            if ((mode & GETMESSAGE_MODE_REPLY) == GETMESSAGE_MODE_REPLY) {
                folder.setFlags(msgnum, msgnum, new Flags(Flags.Flag.ANSWERED), true);
            }
        }
        folder.close(false);

        /* In this part we determine whether the message was requested so that it may be used for
           further editing (replying or forwarding). In this case we set the current "work" message to the
           message we just fetched and then modifiy it a little (quote, add a "Re" to the subject, etc). */
        XMLMessage work = null;
        if ((mode & GETMESSAGE_MODE_REPLY) == GETMESSAGE_MODE_REPLY
                || (mode & GETMESSAGE_MODE_FORWARD) == GETMESSAGE_MODE_FORWARD) {
            log.debug("Setting work message!");
            work = model.setWorkMessage(xml_message);

            String newmsgid = WebMailServer.generateMessageID(user.getUserName());

            if (work != null && (mode & GETMESSAGE_MODE_REPLY) == GETMESSAGE_MODE_REPLY) {
                String from = work.getHeader("FROM");
                work.setHeader("FROM", user.getDefaultEmail());
                work.setHeader("TO", from);
                work.prepareReply(getStringResource("reply subject prefix"),
                        getStringResource("reply subject postfix"), getStringResource("reply message prefix"),
                        getStringResource("reply message postfix"));

            } else if (work != null && (mode & GETMESSAGE_MODE_FORWARD) == GETMESSAGE_MODE_FORWARD) {
                String from = work.getHeader("FROM");
                work.setHeader("FROM", user.getDefaultEmail());
                work.setHeader("TO", "");
                work.setHeader("CC", "");
                work.prepareForward(getStringResource("forward subject prefix"),
                        getStringResource("forward subject postfix"),
                        getStringResource("forward message prefix"),
                        getStringResource("forward message postfix"));

                /* Copy all references to MIME parts to the new message id */
                for (String key : getMimeParts(work.getAttribute("msgid"))) {
                    StringTokenizer tok2 = new StringTokenizer(key, "/");
                    tok2.nextToken();
                    String newkey = tok2.nextToken();
                    mime_parts_decoded.put(newmsgid + "/" + newkey, mime_parts_decoded.get(key));
                }
            }

            /* Clear the msgnr and msgid fields at last */
            work.setAttribute("msgnr", "0");
            work.setAttribute("msgid", newmsgid);
            prepareCompose();
        }
    } catch (MessagingException ex) {
        log.error("Failed to get message.  Doing nothing instead.", ex);
    }
}