/* * Copyright (c) 2002 Cunningham & Cunningham, Inc. * Copyright (c) 2009-2015 by Jochen Wierum & Cologne Intelligence * * This file is part of FitGoodies. * * FitGoodies 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, either version 3 of the License, or * (at your option) any later version. * * FitGoodies 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 FitGoodies. If not, see <http://www.gnu.org/licenses/>. */ package de.cologneintelligence.fitgoodies.mail; import javax.mail.*; import javax.mail.Flags.Flag; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimePart; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; /** * Implementation of {@link Mail} which processes JavaMail mails. */ public class JavaMailMail implements Mail { private final Message message; /** * Creates a new <code>JavaMailMail</code> object. * * @param innerMessage underlying message to process */ public JavaMailMail(final Message innerMessage) { message = innerMessage; } /** * Returns all headers of the type <code>headerName</code>. If such a header * does not exist, <code>null</code> should be returned. * * @param headerName header to read * @return list of header values * @throws MessagingException thrown by the underlying implementation */ @Override public String[] getHeader(final String headerName) throws MessagingException { return message.getHeader(headerName); } private boolean isMimeType(final String type) throws MessagingException { return message.isMimeType(type); } private boolean isMultipart() throws MessagingException { return isMimeType("multipart/*"); } @Override public boolean hasHTMLContent() throws MessagingException { return hasMimeContent("text/html"); } @Override public boolean hasPlainContent() throws MessagingException { return hasMimeContent("text/plain"); } private boolean hasMimeContent(final String mimeType) throws MessagingException { if (isMultipart()) { Part part = getPart(mimeType); return part != null; } else { return isMimeType(mimeType); } } private MimePart getPart(final String mimeType) { try { Multipart multipart = (Multipart) message.getContent(); for (int i = 0; i < multipart.getCount(); ++i) { BodyPart part = multipart.getBodyPart(i); if (isInline(part) && part.isMimeType(mimeType)) { return (MimeBodyPart) part; } } } catch (IOException | MessagingException e) { throw new RuntimeException(e); } return null; } private boolean isInline(final Part part) throws MessagingException { String disposition = part.getDisposition(); return disposition != null && disposition.equalsIgnoreCase(Part.INLINE); } @Override public String getHTMLContent() { return getMimeContent("text/html"); } @Override public String getPlainContent() { return getMimeContent("text/plain"); } private String getMimeContent(final String mimeType) { try { if (isMultipart()) { MimePart part = getPart(mimeType); if (part != null) { return readContent(part, part.getEncoding()); } } else if (isMimeType(mimeType)) { String encoding = "US-ASCII"; if (message instanceof MimePart) { encoding = ((MimePart) message).getEncoding(); } return readContent(message, encoding); } } catch (MessagingException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException("Error while receiving mail", e); } return null; } private String readContent(final Part part, final String encoding) throws MessagingException, IOException { byte[] content = new byte[part.getSize()]; String enc = encoding; if (encoding.equals("7bit")) { enc = "US-ASCII"; } try (InputStream stream = part.getInputStream()) { stream.read(content); } return new String(content, Charset.forName(enc)); } @Override public void delete() { try { message.setFlag(Flag.DELETED, true); } catch (MessagingException e) { } } }