com.openexchange.mail.mime.utils
Class MIMEMessageUtility

java.lang.Object
  extended by com.openexchange.mail.mime.utils.MIMEMessageUtility

public final class MIMEMessageUtility
extends java.lang.Object

MIMEMessageUtility - Utilities for MIME messages.

Author:
Thorben Betten

Field Summary
static java.util.regex.Pattern PATTERN_REF_IMG
           
 
Method Summary
static java.lang.String checkNonAscii(java.lang.String rawHeader)
          Checks if given raw header contains non-ascii characters.
static java.lang.String decodeEnvelopeHeader(java.lang.String headerValue)
          Decodes a string header obtained from ENVELOPE fetch item.
static java.lang.String decodeMultiEncodedHeader(java.lang.String headerValue)
          Decodes a multi-mime-encoded header value using the algorithm specified in RFC 2047, Section 6.1.
static boolean equalsCID(java.lang.String contentId1, java.lang.String contentId2)
          Compares (case insensitive) the given values of message header "Content-ID".
static java.lang.String extractHeader(java.lang.String headerName, java.io.InputStream inputStream, boolean closeStream)
          Gets the matching header out of RFC 822 data input stream.
static java.lang.String fold(int used, java.lang.String foldMe)
          Folds a string at linear whitespace so that each line is no longer than 76 characters, if possible.
static java.lang.String foldContentDisposition(java.lang.String contentDisposition)
          Folds specified Content-Disposition value.
static java.lang.String foldContentType(java.lang.String contentType)
          Folds specified Content-Type value.
static java.util.List<java.lang.String> getContentIDs(java.lang.CharSequence htmlContent)
          Gathers all occurring content IDs in HTML content and returns them as a list
static javax.mail.internet.MailDateFormat getDefaultMailDateFormat()
          Gets the default MailDateFormat.
static java.lang.String getFileName(MailPart mailPart)
          Get the decoded filename associated with specified mail part.
static javax.mail.internet.MailDateFormat getMailDateFormat(com.openexchange.session.Session session)
          Gets the MailDateFormat for specified session.
static javax.mail.internet.MailDateFormat getMailDateFormat(java.lang.String timeZoneId)
          Gets the MailDateFormat for specified time zone identifier.
static java.lang.String getRealFilename(MailPart part)
          Determines specified part's real filename if any available.
static boolean hasAttachments(com.sun.mail.imap.protocol.BODYSTRUCTURE bodystructure)
          Checks if given BODYSTRUCTURE item indicates to contain (file) attachments
static boolean hasAttachments(javax.mail.Multipart mp, java.lang.String subtype)
          Checks if given multipart contains (file) attachments
static boolean hasEmbeddedImages(java.lang.CharSequence htmlContent)
          Detects if given HTML content contains inlined images Example: <img src="cid:s345asd845@12drg">
static boolean hasReferencedLocalImages(java.lang.CharSequence htmlContent, com.openexchange.session.Session session)
          Detects if given HTML content contains references to local image files Example for an uploaded image file referenced within a composed mail:
  <img src="/ajax/file?
static boolean isEmptyHeader(java.lang.String[] headers)
          Checks if specified headers are empty.
static javax.mail.internet.InternetAddress[] parseAddressList(java.lang.String addresslist, boolean strict)
          Parse the given sequence of addresses into InternetAddress objects by invoking InternetAddress.parse(String, boolean).
static javax.mail.internet.InternetAddress[] parseAddressList(java.lang.String addresslist, boolean strict, boolean failOnError)
          Parse the given sequence of addresses into InternetAddress objects by invoking InternetAddress.parse(String, boolean).
static java.lang.String quotePersonal(java.lang.String personal)
          Quotes given personal part of an Internet address according to RFC 822 syntax if needed; otherwise the personal is returned unchanged.
static java.lang.String quotePhrase(java.lang.String phrase, boolean encode)
          Quotes given phrase if needed.
static java.lang.String unfold(java.lang.String headerLine)
          Unfolds a folded header.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

PATTERN_REF_IMG

public static final java.util.regex.Pattern PATTERN_REF_IMG
Method Detail

getDefaultMailDateFormat

public static javax.mail.internet.MailDateFormat getDefaultMailDateFormat()
Gets the default MailDateFormat.

Note that returned instance of MailDateFormat is shared, therefore use a surrounding synchronized block to preserve thread safety:

 ...
 final MailDateFormat mdf = MIMEMessageUtility.getMailDateFormat(session);
 synchronized(mdf) {
  mimeMessage.setHeader("Date", mdf.format(sendDate));
 }
 ...
 

Returns:
The MailDateFormat for specified session

getMailDateFormat

public static javax.mail.internet.MailDateFormat getMailDateFormat(com.openexchange.session.Session session)
                                                            throws MailException
Gets the MailDateFormat for specified session.

Note that returned instance of MailDateFormat is shared, therefore use a surrounding synchronized block to preserve thread safety:

 ...
 final MailDateFormat mdf = MIMEMessageUtility.getMailDateFormat(session);
 synchronized(mdf) {
  mimeMessage.setHeader("Date", mdf.format(sendDate));
 }
 ...
 

Parameters:
session - The user session
Returns:
The MailDateFormat for specified session
Throws:
MailException - If MailDateFormat cannot be returned

getMailDateFormat

public static javax.mail.internet.MailDateFormat getMailDateFormat(java.lang.String timeZoneId)
                                                            throws MailException
Gets the MailDateFormat for specified time zone identifier.

Note that returned instance of MailDateFormat is shared, therefore use a surrounding synchronized block to preserve thread safety:

 ...
 final MailDateFormat mdf = MIMEMessageUtility.getMailDateFormat(timeZoneId);
 synchronized(mdf) {
  mimeMessage.setHeader("Date", mdf.format(sendDate));
 }
 ...
 

Parameters:
timeZoneId - The time zone identifier
Returns:
The MailDateFormat for specified time zone identifier
Throws:
MailException - If MailDateFormat cannot be returned

isEmptyHeader

public static boolean isEmptyHeader(java.lang.String[] headers)
Checks if specified headers are empty. The passed headers are considered as all the values for a certain header or null if no headers exist.

Parameters:
headers - The values for a certain header
Returns:
true if specified headers are empty; otherwise false

hasEmbeddedImages

public static boolean hasEmbeddedImages(java.lang.CharSequence htmlContent)
Detects if given HTML content contains inlined images

Example:

 <img src="cid:s345asd845@12drg">
 

Parameters:
htmlContent - The HTML content
Returns:
true if given HTML content contains inlined images; otherwise false

getContentIDs

public static java.util.List<java.lang.String> getContentIDs(java.lang.CharSequence htmlContent)
Gathers all occurring content IDs in HTML content and returns them as a list

Parameters:
htmlContent - The HTML content
Returns:
an instance of List containing all occurring content IDs

equalsCID

public static boolean equalsCID(java.lang.String contentId1,
                                java.lang.String contentId2)
Compares (case insensitive) the given values of message header "Content-ID". The leading/trailing characters '<' and ' >' are ignored during comparison

Parameters:
contentId1 - The first content ID
contentId2 - The second content ID
Returns:
true if both are equal; otherwise false

hasReferencedLocalImages

public static boolean hasReferencedLocalImages(java.lang.CharSequence htmlContent,
                                               com.openexchange.session.Session session)
Detects if given HTML content contains references to local image files

Parameters:
htmlContent - The HTML content
session - The user session
Returns:
true if given HTML content contains references to local image files; otherwise false

getRealFilename

public static java.lang.String getRealFilename(MailPart part)
Determines specified part's real filename if any available.

Parameters:
part - The part whose filename shall be determined
Returns:
The part's real filename or null if none present

hasAttachments

public static boolean hasAttachments(javax.mail.Multipart mp,
                                     java.lang.String subtype)
                              throws javax.mail.MessagingException,
                                     MailException,
                                     java.io.IOException
Checks if given multipart contains (file) attachments

Parameters:
mp - The multipart to examine
subtype - The multipart's subtype
Returns:
true if given multipart contains (file) attachments; otherwise false
Throws:
javax.mail.MessagingException - If a messaging error occurs
MailException - If a mail error occurs
java.io.IOException - If an I/O error occurs

hasAttachments

public static boolean hasAttachments(com.sun.mail.imap.protocol.BODYSTRUCTURE bodystructure)
Checks if given BODYSTRUCTURE item indicates to contain (file) attachments

Parameters:
bodystructure - The BODYSTRUCTURE item
Returns:
true if given BODYSTRUCTURE item indicates to contain (file) attachments; otherwise false

decodeEnvelopeHeader

public static java.lang.String decodeEnvelopeHeader(java.lang.String headerValue)
Decodes a string header obtained from ENVELOPE fetch item.

Parameters:
headerValue - The header value
Returns:
The decoded header value

decodeMultiEncodedHeader

public static java.lang.String decodeMultiEncodedHeader(java.lang.String headerValue)
Decodes a multi-mime-encoded header value using the algorithm specified in RFC 2047, Section 6.1.

If the charset-conversion fails for any sequence, an UnsupportedEncodingException is thrown.

If the String is not a RFC 2047 style encoded header, it is returned as-is

Parameters:
headerValue - The possibly encoded header value
Returns:
The possibly decoded header value

checkNonAscii

public static java.lang.String checkNonAscii(java.lang.String rawHeader)
Checks if given raw header contains non-ascii characters.

Parameters:
rawHeader - The raw header
Returns:
The proper unicode string

getFileName

public static java.lang.String getFileName(MailPart mailPart)
Get the decoded filename associated with specified mail part.

Returns the value of the "filename" parameter from the "Content-Disposition" header field. If its not available, returns the value of the "name" parameter from the "Content-Type" header field. Returns null if both are absent.

Parameters:
mailPart - The mail part whose filename shall be returned
Returns:
The mail part's decoded filename or null.

parseAddressList

public static javax.mail.internet.InternetAddress[] parseAddressList(java.lang.String addresslist,
                                                                     boolean strict)
Parse the given sequence of addresses into InternetAddress objects by invoking InternetAddress.parse(String, boolean). If strict is false, simple email addresses separated by spaces are also allowed. If strict is true, many (but not all) of the RFC822 syntax rules are enforced. In particular, even if strict is true, addresses composed of simple names (with no "@domain" part) are allowed. Such "illegal" addresses are not uncommon in real messages.

Non-strict parsing is typically used when parsing a list of mail addresses entered by a human. Strict parsing is typically used when parsing address headers in mail messages.

Additionally the personal parts are MIME encoded using default MIME charset.

Parameters:
addresslist - - comma separated address strings
strict - - true to enforce RFC822 syntax; otherwise false
Returns:
An array of InternetAddress objects

parseAddressList

public static javax.mail.internet.InternetAddress[] parseAddressList(java.lang.String addresslist,
                                                                     boolean strict,
                                                                     boolean failOnError)
                                                              throws javax.mail.internet.AddressException
Parse the given sequence of addresses into InternetAddress objects by invoking InternetAddress.parse(String, boolean). If strict is false, simple email addresses separated by spaces are also allowed. If strict is true, many (but not all) of the RFC822 syntax rules are enforced. In particular, even if strict is true, addresses composed of simple names (with no "@domain" part) are allowed. Such "illegal" addresses are not uncommon in real messages.

Non-strict parsing is typically used when parsing a list of mail addresses entered by a human. Strict parsing is typically used when parsing address headers in mail messages.

Additionally the personal parts are MIME encoded using default MIME charset.

Parameters:
addresslist - - comma separated address strings
strict - - true to enforce RFC822 syntax; otherwise false
failOnError - - true to fail if parsing fails; otherwise false to get a plain-text representation
Returns:
An array of InternetAddress objects
Throws:
javax.mail.internet.AddressException - If parsing fails and failOnError is true

quotePersonal

public static java.lang.String quotePersonal(java.lang.String personal)
Quotes given personal part of an Internet address according to RFC 822 syntax if needed; otherwise the personal is returned unchanged.

This method guarantees that the resulting string can be used to build an Internet address according to RFC 822 syntax so that the InternetAddress.parse(String) constructor won't throw an instance of AddressException.

 final String quotedPersonal = quotePersonal("Doe, Jane");
 
 final String buildAddr = quotedPersonal + " <someone@somewhere.com>";
 System.out.println(buildAddr);
 //Plain Address: "=?UTF-8?Q?Doe=2C_Jan=C3=A9?=" <someone@somewhere.com>
 
 final InternetAddress ia = new InternetAddress(buildAddr);
 System.out.println(ia.toUnicodeString());
 //Unicode Address: "Doe, Jane" <someone@somewhere.com>
 

Parameters:
personal - The personal's string representation
Returns:
The properly quoted personal for building an Internet address according to RFC 822 syntax

quotePhrase

public static java.lang.String quotePhrase(java.lang.String phrase,
                                           boolean encode)
Quotes given phrase if needed.

Parameters:
phrase - The phrase
encode - true to encode phrase according to RFC 822 syntax if needed; otherwise false
Returns:
The quoted phrase

foldContentType

public static java.lang.String foldContentType(java.lang.String contentType)
Folds specified Content-Type value.

Parameters:
contentDisposition - The Content-Type value
Returns:
The folded Content-Type value

foldContentDisposition

public static java.lang.String foldContentDisposition(java.lang.String contentDisposition)
Folds specified Content-Disposition value.

Parameters:
contentDisposition - The Content-Disposition value
Returns:
The folded Content-Disposition value

fold

public static java.lang.String fold(int used,
                                    java.lang.String foldMe)
Folds a string at linear whitespace so that each line is no longer than 76 characters, if possible. If there are more than 76 non-whitespace characters consecutively, the string is folded at the first whitespace after that sequence. The parameter used indicates how many characters have been used in the current line; it is usually the length of the header name.

Note that line breaks in the string aren't escaped; they probably should be.

Parameters:
used - The characters used in line so far
foldMe - The string to fold
Returns:
The folded string

unfold

public static java.lang.String unfold(java.lang.String headerLine)
Unfolds a folded header. Any line breaks that aren't escaped and are followed by whitespace are removed.

Parameters:
headerLine - The header line to unfold
Returns:
The unfolded string

extractHeader

public static java.lang.String extractHeader(java.lang.String headerName,
                                             java.io.InputStream inputStream,
                                             boolean closeStream)
                                      throws java.io.IOException
Gets the matching header out of RFC 822 data input stream.

Parameters:
headerName - The header name
inputStream - The input stream
closeStream - true to close the stream on finish; otherwise false
Returns:
The value of first appeared matching header
Throws:
java.io.IOException - If reading input stream fails