@PublicAtsApi public List<InputStream> getAllStreams() throws PackageException { boolean storeReconnected = false; try { // store should be opened for actions including getting InputStream. storeReconnected = reconnectStoreIfClosed(); ArrayList<InputStream> streams = new ArrayList<InputStream>(); try { for (MimePart part : parts) { streams.add(part.getInputStream()); } } finally { closeStoreConnection(storeReconnected); } return streams; } catch (MessagingException me) { throw new PackageException("Could not read mime parts", me); } catch (IOException ioe) { throw new PackageException("Could not read mime parts", ioe); } }
/** * Get the specified header value from a specified MIME part * * @param headerName * @param partNum * @param headerIndex * @return * @throws PackageException */ @PublicAtsApi public String getPartHeader( String headerName, int partNum, int headerIndex ) throws PackageException { try { String[] headers; if (partNum >= parts.size()) { throw new NoSuchMimePartException("No MIME part at position '" + partNum + "'"); } MimePart part = parts.get(partNum); headers = part.getHeader(headerName); if ( (headers != null) && (headers.length > headerIndex)) { return headers[headerIndex]; } else { throw new NoSuchHeaderException(headerName, partNum, headerIndex); } } catch (MessagingException me) { throw new PackageException(me); } }
/** * Get all header values from a specified MIME part * * @param headerName * @param partNum * @return * @throws PackageException */ @PublicAtsApi public String[] getPartHeaderValues( String headerName, int partNum ) throws PackageException { try { String[] headers; if (partNum >= parts.size()) { throw new NoSuchMimePartException("No MIME part at position '" + partNum + "'"); } MimePart part = parts.get(partNum); headers = part.getHeader(headerName); if ( (headers != null) && (headers.length > 0)) { return headers; } else { throw new NoSuchHeaderException(headerName, partNum); } } catch (MessagingException me) { throw new PackageException(me); } }
/** * Get a MIME part based on it's index and type * * @param partIndex * the index of the MIME part * @param isAttachment * the type - true if the part is attachment, false otherwise * @return the mime part * @throws NoSuchMimePartException * if there is no such part */ @PublicAtsApi public MimePart getPart( int partIndex, boolean isAttachment ) throws NoSuchMimePartException { // first check if there is part at this position at all if (isAttachment) { if (partIndex >= attachmentPartIndices.size()) { throw new NoSuchMimePartException("No attachment at position '" + partIndex + "'"); } } else { if (partIndex >= regularPartIndices.size()) { throw new NoSuchMimePartException("No regular part at position '" + partIndex + "'"); } } MimePart part; if (isAttachment) { part = getPart(attachmentPartIndices.get(partIndex)); } else { part = getPart(regularPartIndices.get(partIndex)); } return part; }
/** * Get the content type of a regular part * * @param partIndex * the index of the regular part * @return the content type as string * @throws PackageException */ @PublicAtsApi public String getRegularPartContentType( int partIndex ) throws PackageException { // first check if there is part at this position at all if (partIndex >= regularPartIndices.size()) { throw new NoSuchMimePartException("No regular part at position '" + partIndex + "'"); } try { MimePart part = getPart(regularPartIndices.get(partIndex)); // get the content type header ContentType contentType = new ContentType(part.getContentType()); return contentType.getBaseType(); } catch (MessagingException me) { throw new PackageException(me); } }
/** * Get the character set of a regular part * * @param partIndex * the index of the part * @return the charset * @throws PackageException */ @PublicAtsApi public String getRegularPartCharset( int partIndex ) throws PackageException { // first check if there is part at this position at all if (partIndex >= regularPartIndices.size()) { throw new NoSuchMimePartException("No regular part at position '" + partIndex + "'"); } try { MimePart part = getPart(regularPartIndices.get(partIndex)); // get the content type header ContentType contentType = new ContentType(part.getContentType()); return contentType.getParameter("charset"); } catch (MessagingException me) { throw new PackageException(me); } }
/** * Set/modify attachment file name * * @param attachmentPartIndex index among attachment parts only * @param fileName the file name. Add one or reset existing one * @throws NoSuchMimePartException if not such attachment part is found * @throws PackageException in case of other mail messaging exception */ @PublicAtsApi public void setAttachmentFileName( int attachmentPartIndex, String fileName ) throws PackageException { // first check if there is part at this position at all if (attachmentPartIndex >= attachmentPartIndices.size()) { throw new NoSuchMimePartException("No attachment at position '" + attachmentPartIndex + "'"); } try { MimePart part = getPart(attachmentPartIndices.get(attachmentPartIndex)); // set the attachment file name part.setFileName(fileName); // must save now this.message.saveChanges(); } catch (MessagingException me) { throw new PackageException(me); } }
/** * Get an attachment's file name * * @param partIndex * @return * @throws PackageException */ @PublicAtsApi public String getAttachmentFileName( int partIndex ) throws PackageException { // first check if there is part at this position at all if (partIndex >= attachmentPartIndices.size()) { throw new NoSuchMimePartException("No attachment at position '" + partIndex + "'"); } try { MimePart part = getPart(attachmentPartIndices.get(partIndex)); // get the attachment file name String fileName = part.getFileName(); if (fileName == null) { throw new PackageException("Could not determine file name for attachment at position " + partIndex); } return fileName; } catch (MessagingException me) { throw new PackageException(me); } }
/** * Get the attachment content type * * @param partIndex * @return * @throws PackageException */ @PublicAtsApi public String getAttachmentContentType( int partIndex ) throws PackageException { // first check if there is part at this position at all if (partIndex >= attachmentPartIndices.size()) { throw new NoSuchMimePartException("No attachment at position '" + partIndex + "'"); } try { MimePart part = getPart(attachmentPartIndices.get(partIndex)); // get the content type header ContentType contentType = new ContentType(part.getContentType()); return contentType.getBaseType(); } catch (MessagingException me) { throw new PackageException(me); } }
/** * Get the attachment character set * * @param partIndex * the index of the attachment * @return the character set for this attachment, null if there is no such * @throws PackageException */ @PublicAtsApi public String getAttachmentCharset( int partIndex ) throws PackageException { // first check if there is part at this position at all if (partIndex >= attachmentPartIndices.size()) { throw new NoSuchMimePartException("No attachment at position '" + partIndex + "'"); } try { MimePart part = getPart(attachmentPartIndices.get(partIndex)); // get the content type header ContentType contentType = new ContentType(part.getContentType()); return contentType.getParameter("charset"); } catch (MessagingException me) { throw new PackageException(me); } }
/** * Return the attachment data * * @param partIndex * the index of the attachment * @return an InputStream with the attachment data * @throws PackageException */ @PublicAtsApi public InputStream getAttachmentPartData( int partIndex ) throws PackageException { try { boolean storeReconnected = reconnectStoreIfClosed(); // store should be opened for actions including getting InputStream. Hence store open is not in getPart try { MimePart part = getPart(partIndex, true); return part.getInputStream(); } finally { closeStoreConnection(storeReconnected); } } catch (MessagingException me) { throw new PackageException("Error getting attachment data for part " + partIndex, me); } catch (IOException ioe) { throw new PackageException("Error getting attachment data for part " + partIndex, ioe); } }
@Test public void setBody_multiParts_with_textPart_only() throws Exception { // create a new message and add TEXT part to it MimePackage newMailMessage = new MimePackage(); newMailMessage.addPart("text plain body", MimePackage.PART_TYPE_TEXT_PLAIN); MimePart textPart = newMailMessage.getPart(0, false); assertEquals(textPart.getContent(), "text plain body"); assertEquals(textPart.getContentType(), "text/plain; charset=us-ascii"); // modify the only part newMailMessage.setBody("new body"); // verify the modifications MimePart newTextPart = newMailMessage.getPart(0, false); assertEquals(newTextPart.getContent(), "new body"); assertEquals(newTextPart.getContentType(), "text/plain; charset=us-ascii"); // verify there are no more parts try { newMailMessage.getPart(1, false); assertTrue("There is more than 1 part, while we expect to have just 1", false); } catch (NoSuchMimePartException e) {} }
@Test public void setBody_multiParts_with_htmlPart_only() throws Exception { // create a new message and add HTML part to it MimePackage newMailMessage = new MimePackage(); newMailMessage.addPart("html body", MimePackage.PART_TYPE_TEXT_HTML); MimePart htmlPart = newMailMessage.getPart(0, false); assertEquals(htmlPart.getContent(), "html body"); assertEquals(htmlPart.getContentType(), "text/html; charset=us-ascii"); // modify the only part newMailMessage.setBody("new body"); // verify the modifications MimePart newHtmlPart = newMailMessage.getPart(0, false); assertEquals(newHtmlPart.getContent(), "new body"); assertEquals(newHtmlPart.getContentType(), "text/html; charset=us-ascii"); // verify there are no more parts try { newMailMessage.getPart(1, false); assertTrue("There is more than 1 part, while we expect to have just 1", false); } catch (NoSuchMimePartException e) {} }
/** * Set the given text directly as content in non-multipart mode * or as default body part in multipart mode. * The "html" flag determines the content type to apply. * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> {@code setText}; * else, mail readers might not be able to resolve inline references correctly. * @param text the text for the message * @param html whether to apply content type "text/html" for an * HTML mail, using default content type ("text/plain") else * @throws MessagingException in case of errors */ public void setText(String text, boolean html) throws MessagingException { Assert.notNull(text, "Text must not be null"); MimePart partToUse; if (isMultipart()) { partToUse = getMainPart(); } else { partToUse = this.mimeMessage; } if (html) { setHtmlTextToMimePart(partToUse, text); } else { setPlainTextToMimePart(partToUse, text); } }
/** * Attempt to repair the given contentType if broken. * @param mp Mimepart holding the contentType * @param contentType ContentType * @return fixed contentType String * @throws MessagingException */ public static String cleanContentType(MimePart mp, String contentType) throws MessagingException { ContentType ct = parseContentType(contentType); if (ct == null) { ct = getParsableContentType(contentType); } if (ct.getBaseType().equalsIgnoreCase("text/plain") || ct.getBaseType().equalsIgnoreCase("text/html")) { Charset charset = parseCharset(ct); if (charset == null) { Logger.debug("Charset of the ContentType could not be read, try to decode the contentType as quoted-printable"); ContentType ctTmp = decodeContentTypeAsQuotedPrintable(contentType); if (parseCharset(ctTmp) != null) { ct = ctTmp; } else { ct.setParameter("charset", ContentTypeCleaner.DEFAULT_CHARSET); } } } return ct.toString(); }
private void save(Store store, String wheretobackup, String f) throws MessagingException, IOException { System.out.println("opening folder " + f); Folder folder = store.getFolder(f); folder.open(Folder.READ_ONLY); FileUtils.forceMkdir(new File(wheretobackup)); // Get directory Message message[] = folder.getMessages(); for (int i = 0, n = message.length; i < n; i++) { // String from = (message[i].getFrom()[0]).toString(); String subj = (message[i].getSubject()).toString(); String nota = (message[i].getContent()).toString(); if (message[i].getContent() instanceof MimeMultipart) { MimeMultipart multipart = (MimeMultipart) message[i].getContent(); for (int j = 0; j < multipart.getCount(); j++) { BodyPart bodyPart = multipart.getBodyPart(j); if (bodyPart.isMimeType("text/html")) { nota = bodyPart.getContent().toString(); generals.writeFile(wheretobackup + "/" + generals.makeFilename(subj).trim() + ".html", nota, message[i].getSentDate()); } else if (bodyPart.isMimeType("IMAGE/PNG")) { String imagecid = ((MimePart) bodyPart).getContentID(); InputStream is = bodyPart.getInputStream(); FileUtils.forceMkdir(new File(wheretobackup + "/images/")); File fimg = new File(wheretobackup + "/images/" + bodyPart.getFileName()); System.out.println("saving " + wheretobackup + "/images/" + bodyPart.getFileName()); FileOutputStream fos = new FileOutputStream(fimg); byte[] buf = new byte[4096]; int bytesRead; while((bytesRead = is.read(buf))!=-1) { fos.write(buf, 0, bytesRead); } fos.close(); // devi fare il replace 0DA094B7-933A-4B19-947F-2FC42FA9DABD System.out.println("html replace file name : " + imagecid); System.out.println("into file name : " + bodyPart .getFileName()); } } } else { generals.writeFile(wheretobackup + "/" + generals.makeFilename(subj).trim() + ".html", nota, message[i].getSentDate()); } } folder.close(false); }
/** * Converts a message to 7 bit. * * @param part */ private void convertTo7Bit(MimePart part) throws MessagingException, IOException { if (part.isMimeType("multipart/*")) { MimeMultipart parts = (MimeMultipart) part.getContent(); int count = parts.getCount(); for (int i = 0; i < count; i++) { convertTo7Bit((MimePart) parts.getBodyPart(i)); } } else if ("8bit".equals(part.getEncoding())) { // The content may already be in encoded the form (likely with mail // created from a // stream). In that case, just changing the encoding to // quoted-printable will mangle // the result when this is transmitted. We must first convert the // content into its // native format, set it back, and only THEN set the transfer // encoding to force the // content to be encoded appropriately. // if the part doesn't contain text it will be base64 encoded. String contentTransferEncoding = part.isMimeType("text/*") ? "quoted-printable" : "base64"; part.setContent(part.getContent(), part.getContentType()); part.setHeader("Content-Transfer-Encoding", contentTransferEncoding); part.addHeader("X-MIME-Autoconverted", "from 8bit to " + contentTransferEncoding + " by " + getMailetContext().getServerInfo()); } }
private boolean isPartAttachment( MimePart part ) throws PackageException { try { String disposition = part.getDisposition(); if (disposition != null && disposition.equalsIgnoreCase(Part.ATTACHMENT)) { return true; } } catch (MessagingException me) { throw new PackageException("Could not determine if part is an attachment", me); } return false; }
private MimePart getPart( int index ) throws NoSuchMimePartException { if (index >= parts.size()) { throw new NoSuchMimePartException("No MIME part at position '" + index + "'"); } MimePart part = this.parts.get(index); if (part != null) { return part; } else { throw new NoSuchMimePartException("No part at position '" + index + "'"); } }
@Test public void setBody_multiParts_with_textAndHtmlParts() throws Exception { // create a new message and add TEXT and HTML parts to it MimePackage newMailMessage = new MimePackage(); newMailMessage.addPart("text plain body", MimePackage.PART_TYPE_TEXT_PLAIN); newMailMessage.addPart("html body", MimePackage.PART_TYPE_TEXT_HTML); MimePart textPart = newMailMessage.getPart(0, false); assertEquals(textPart.getContent(), "text plain body"); assertEquals(textPart.getContentType(), "text/plain; charset=us-ascii"); MimePart htmlPart = newMailMessage.getPart(1, false); assertEquals(htmlPart.getContent(), "html body"); assertEquals(htmlPart.getContentType(), "text/html; charset=us-ascii"); // modify both parts newMailMessage.setBody("new body"); // verify the modifications MimePart newTextPart = newMailMessage.getPart(0, false); assertEquals(newTextPart.getContent(), "new body"); assertEquals(newTextPart.getContentType(), "text/plain; charset=us-ascii"); MimePart newHtmlPart = newMailMessage.getPart(1, false); assertEquals(newHtmlPart.getContent(), "new body"); assertEquals(newHtmlPart.getContentType(), "text/html; charset=us-ascii"); // verify there are no more parts try { newMailMessage.getPart(2, false); assertTrue("There is more than 2 parts, while we expect to have just 2", false); } catch (NoSuchMimePartException e) {} }
/** * Test is parsing mail with no nested parts. It get the plain/text part on level 1. * * - multipart/mixed; * - text/plain * - application/octet-stream * - message/rfc822 */ @Test public void parse1Reg2Att() throws Exception { String mailMessagePath = Test_MimePackage.class.getResource("RFC822-headers-1_Regular_2_Attachments.eml") .getPath(); MimePackage mimeMessage = PackageLoader.loadMimePackageFromFile(mailMessagePath); assertEquals(1, mimeMessage.getRegularPartCount()); assertEquals(1, mimeMessage.getAttachmentPartCount()); // first attachment exists and is parsed MimePart part = mimeMessage.getPart(0, true); assertTrue(part != null); // one regular part with text assertTrue(mimeMessage.getPlainTextBody() .startsWith("This report relates to a message you sent")); // nested MimePackage - the RFC822-headers MimePackage nestedPackWithHeadersOnly = mimeMessage.getNeededMimePackage(new int[]{ 0 }); List<PackageHeader> headers = nestedPackWithHeadersOnly.getAllHeaders(); assertTrue(headers.size() == 31); /* For test debugging int i = 0; for( PackageHeader packageHeader : headers ) { log.info("header[" + i + "] name: [" + packageHeader.getName() +"] value: [" + packageHeader.getValue() + "]"); i++; } */ }
public MimePart nextPart(OutputStream os) throws IOException, MessagingException { MimeBodyPart bodyPart = readHeaders(); if (bodyPart != null) { IOUtils.copy(pis, os); pis.nextPart(); } return bodyPart; }
public MimePart nextPart(File file) throws IOException, MessagingException { MimeBodyPart bodyPart = readHeaders(); if (bodyPart != null) { FileUtils.copyInputStreamToFile(pis, file); pis.nextPart(); } return bodyPart; }
private void setPlainTextToMimePart(MimePart mimePart, String text) throws MessagingException { if (getEncoding() != null) { mimePart.setText(text, getEncoding()); } else { mimePart.setText(text); } }
private void setHtmlTextToMimePart(MimePart mimePart, String text) throws MessagingException { if (getEncoding() != null) { mimePart.setContent(text, CONTENT_TYPE_HTML + CONTENT_TYPE_CHARSET_SUFFIX + getEncoding()); } else { mimePart.setContent(text, CONTENT_TYPE_HTML); } }
private static void parseMimePartTree(@Nonnull final MimePart currentPart, @Nonnull final ParsedMimeMessageComponents parsedComponents) { for (final Header header : retrieveAllHeaders(currentPart)) { parseHeader(header, parsedComponents); } final String disposition = parseDisposition(currentPart); if (isMimeType(currentPart, "text/plain") && parsedComponents.plainContent == null && !Part.ATTACHMENT.equalsIgnoreCase(disposition)) { parsedComponents.plainContent = parseContent(currentPart); } else if (isMimeType(currentPart, "text/html") && parsedComponents.htmlContent == null && !Part.ATTACHMENT.equalsIgnoreCase(disposition)) { parsedComponents.htmlContent = parseContent(currentPart); } else if (isMimeType(currentPart, "multipart/*")) { final Multipart mp = parseContent(currentPart); for (int i = 0, count = countBodyParts(mp); i < count; i++) { parseMimePartTree(getBodyPartAtIndex(mp, i), parsedComponents); } } else { final DataSource ds = createDataSource(currentPart); // If the diposition is not provided, the part should be treated as attachment if (disposition == null || Part.ATTACHMENT.equalsIgnoreCase(disposition)) { parsedComponents.attachmentList.put(parseResourceName(parseContentID(currentPart), parseFileName(currentPart)), ds); } else if (Part.INLINE.equalsIgnoreCase(disposition)) { if (parseContentID(currentPart) != null) { parsedComponents.cidMap.put(parseContentID(currentPart), ds); } else { // contentID missing -> treat as standard attachment parsedComponents.attachmentList.put(parseResourceName(null, parseFileName(currentPart)), ds); } } else { throw new IllegalStateException("invalid attachment type"); } } }
@SuppressWarnings("WeakerAccess") @Nullable public static String parseContentID(@Nonnull final MimePart currentPart) { try { return currentPart.getContentID(); } catch (final MessagingException e) { throw new MimeMessageParseException(MimeMessageParseException.ERROR_GETTING_CONTENT_ID, e); } }
@SuppressWarnings("WeakerAccess") public static <T> T parseContent(@Nonnull final MimePart currentPart) { try { //noinspection unchecked return (T) currentPart.getContent(); } catch (IOException | MessagingException e) { throw new MimeMessageParseException(MimeMessageParseException.ERROR_PARSING_CONTENT, e); } }
@SuppressWarnings("WeakerAccess") public static String parseDisposition(@Nonnull final MimePart currentPart) { try { return currentPart.getDisposition(); } catch (final MessagingException e) { throw new MimeMessageParseException(MimeMessageParseException.ERROR_PARSING_DISPOSITION, e); } }
@SuppressWarnings("WeakerAccess") @Nonnull public static List<Header> retrieveAllHeaders(@Nonnull final MimePart part) { try { return Collections.list(part.getAllHeaders()); } catch (final MessagingException e) { throw new MimeMessageParseException(MimeMessageParseException.ERROR_GETTING_ALL_HEADERS, e); } }
/** * Checks whether the MimePart contains an object of the given mime type. * * @param part the current MimePart * @param mimeType the mime type to check * @return {@code true} if the MimePart matches the given mime type, {@code false} otherwise */ @SuppressWarnings("WeakerAccess") public static boolean isMimeType(@Nonnull final MimePart part, @Nonnull final String mimeType) { // Do not use part.isMimeType(String) as it is broken for MimeBodyPart // and does not really check the actual content type. try { final ContentType contentType = new ContentType(retrieveDataHandler(part).getContentType()); return contentType.match(mimeType); } catch (final ParseException ex) { return retrieveContentType(part).equalsIgnoreCase(mimeType); } }
@SuppressWarnings("WeakerAccess") public static String retrieveContentType(@Nonnull final MimePart part) { try { return part.getContentType(); } catch (final MessagingException e) { throw new MimeMessageParseException(MimeMessageParseException.ERROR_GETTING_CONTENT_TYPE, e); } }
@SuppressWarnings("WeakerAccess") public static DataHandler retrieveDataHandler(@Nonnull final MimePart part) { try { return part.getDataHandler(); } catch (final MessagingException e) { throw new MimeMessageParseException(MimeMessageParseException.ERROR_GETTING_DATAHANDLER, e); } }
/** * Parses the MimePart to create a DataSource. * * @param part the current part to be processed * @return the DataSource */ @Nonnull private static DataSource createDataSource(@Nonnull final MimePart part) { final DataHandler dataHandler = retrieveDataHandler(part); final DataSource dataSource = dataHandler.getDataSource(); final String contentType = parseBaseMimeType(dataSource.getContentType()); final byte[] content = readContent(retrieveInputStream(dataSource)); final ByteArrayDataSource result = new ByteArrayDataSource(content, contentType); final String dataSourceName = parseDataSourceName(part, dataSource); result.setName(dataSourceName); return result; }
private final void setMessageContent(final MimePart part) throws MessagingException { final String charSetName = getCharsetName(); final String messageHtml = getMessageHTML(); if (Check.isEmpty(messageHtml, true)) { part.setText(getMessageCRLF(), charSetName, "plain"); // just explicitly adding "plain" for better contrast with "html" } else { part.setText(messageHtml, charSetName, "html"); // #107 FRESH-445: this call solves the issue } }
@Override public void setContent(MimePart message, Multipart multipart, Email email, Content content) throws ContentHandlerException { JavaMailContentHandler contentHandler = map.get(content.getClass()); if (contentHandler == null) { throw new NoContentHandlerException("there is no content handler defined for managing " + content.getClass().getSimpleName() + " content class", content); } contentHandler.setContent(message, multipart, email, content); }