List of usage examples for javax.mail.internet MimeMessage isMimeType
@Override public boolean isMimeType(String mimeType) throws MessagingException
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 *//* www. ja v a2s . 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:org.apache.james.transport.mailets.SMIMEDecrypt.java
/** * @see org.apache.mailet.Mailet#service(org.apache.mailet.Mail) *//* ww w .j a v a 2 s . c om*/ @SuppressWarnings("unchecked") public void service(Mail mail) throws MessagingException { MimeMessage message = mail.getMessage(); Part strippedMessage = null; log("Starting message decryption.."); if (message.isMimeType("application/x-pkcs7-mime") || message.isMimeType("application/pkcs7-mime")) { try { SMIMEEnveloped env = new SMIMEEnveloped(message); RecipientInformationStore informationStore = env.getRecipientInfos(); Collection<RecipientInformation> recipients = informationStore.getRecipients(); for (RecipientInformation info : recipients) { RecipientId id = info.getRID(); if (id.match(certificateHolder)) { try { JceKeyTransEnvelopedRecipient recipient = new JceKeyTransEnvelopedRecipient( keyHolder.getPrivateKey()); // strippedMessage contains the decrypted message. strippedMessage = SMIMEUtil.toMimeBodyPart(info.getContent(recipient)); log("Encrypted message decrypted"); } catch (Exception e) { throw new MessagingException("Error during the decryption of the message", e); } } else { log("Found an encrypted message but it isn't encrypted for the supplied key"); } } } catch (CMSException e) { throw new MessagingException("Error during the decryption of the message", e); } } // if the decryption has been successful.. if (strippedMessage != null) { // I put the private key's public certificate as a mailattribute. // I create a list of certificate because I want to minic the // behavior of the SMIMEVerifySignature mailet. In that way // it is possible to reuse the same matchers to analyze // the result of the operation. ArrayList<X509Certificate> list = new ArrayList<X509Certificate>(1); list.add(keyHolder.getCertificate()); mail.setAttribute(mailAttribute, list); // I start the message stripping. try { MimeMessage newMessage = new MimeMessage(message); newMessage.setText(text(strippedMessage), Charsets.UTF_8.name()); if (!strippedMessage.isMimeType("multipart/*")) { newMessage.setDisposition(null); } newMessage.saveChanges(); mail.setMessage(newMessage); } catch (IOException e) { log("Error during the strip of the encrypted message"); throw new MessagingException("Error during the stripping of the encrypted message", e); } } }
From source file:org.apache.james.transport.mailets.StripAttachment.java
/** * Service the mail: scan it for attchemnts matching the pattern, store the * content of a matchin attachment in the given directory. * /* ww w . ja va 2s . c o m*/ * @param mail * The mail to service * @throws MailetException * Thrown when an error situation is encountered. */ public void service(Mail mail) throws MailetException { MimeMessage message; try { message = mail.getMessage(); } catch (MessagingException e) { throw new MailetException("Could not retrieve message from Mail object", e); } // All MIME messages with an attachment are multipart, so we do nothing // if it is not mutlipart try { if (message.isMimeType("multipart/*")) { analyseMultipartPartMessage(message, mail); } } catch (MessagingException e) { throw new MailetException("Could not retrieve contenttype of message.", e); } catch (Exception e) { throw new MailetException("Could not analyse message.", e); } }
From source file:org.apache.jmeter.assertions.SMIMEAssertion.java
public static AssertionResult getResult(SMIMEAssertionTestElement testElement, SampleResult response, String name) {/* w w w .j a va2 s.c om*/ checkForBouncycastle(); AssertionResult res = new AssertionResult(name); try { MimeMessage msg = null; final int msgPos = testElement.getSpecificMessagePositionAsInt(); if (msgPos < 0) { // means counting from end SampleResult[] subResults = response.getSubResults(); final int pos = subResults.length + msgPos; if (log.isDebugEnabled()) { log.debug("Getting message number: " + pos + " of " + subResults.length); } msg = getMessageFromResponse(response, pos); } else { if (log.isDebugEnabled()) { log.debug("Getting message number: " + msgPos); } msg = getMessageFromResponse(response, msgPos); } SMIMESignedParser s = null; if (log.isDebugEnabled()) { log.debug("Content-type: " + msg.getContentType()); } if (msg.isMimeType("multipart/signed")) { // $NON-NLS-1$ MimeMultipart multipart = (MimeMultipart) msg.getContent(); s = new SMIMESignedParser(new BcDigestCalculatorProvider(), multipart); } else if (msg.isMimeType("application/pkcs7-mime") // $NON-NLS-1$ || msg.isMimeType("application/x-pkcs7-mime")) { // $NON-NLS-1$ s = new SMIMESignedParser(new BcDigestCalculatorProvider(), msg); } if (null != s) { log.debug("Found signature"); if (testElement.isNotSigned()) { res.setFailure(true); res.setFailureMessage("Mime message is signed"); } else if (testElement.isVerifySignature() || !testElement.isSignerNoCheck()) { res = verifySignature(testElement, s, name); } } else { log.debug("Did not find signature"); if (!testElement.isNotSigned()) { res.setFailure(true); res.setFailureMessage("Mime message is not signed"); } } } catch (MessagingException e) { String msg = "Cannot parse mime msg: " + e.getMessage(); log.warn(msg, e); res.setFailure(true); res.setFailureMessage(msg); } catch (CMSException e) { res.setFailure(true); res.setFailureMessage("Error reading the signature: " + e.getMessage()); } catch (SMIMEException e) { res.setFailure(true); res.setFailureMessage("Cannot extract signed body part from signature: " + e.getMessage()); } catch (IOException e) { // should never happen log.error("Cannot read mime message content: " + e.getMessage(), e); res.setError(true); res.setFailureMessage(e.getMessage()); } return res; }