Methods Summary |
---|
public static void | collectParts(com.android.email.mail.Part part, java.util.ArrayList viewables, java.util.ArrayList attachments)An unfortunately named method that makes decisions about a Part (usually a Message)
as to which of it's children will be "viewable" and which will be attachments.
The method recursively sorts the viewables and attachments into seperate
lists for further processing.
String disposition = part.getDisposition();
String dispositionType = null;
String dispositionFilename = null;
if (disposition != null) {
dispositionType = MimeUtility.getHeaderParameter(disposition, null);
dispositionFilename = MimeUtility.getHeaderParameter(disposition, "filename");
}
/*
* A best guess that this part is intended to be an attachment and not inline.
*/
boolean attachment = ("attachment".equalsIgnoreCase(dispositionType))
|| (dispositionFilename != null)
&& (!"inline".equalsIgnoreCase(dispositionType));
/*
* If the part is Multipart but not alternative it's either mixed or
* something we don't know about, which means we treat it as mixed
* per the spec. We just process it's pieces recursively.
*/
if (part.getBody() instanceof Multipart) {
Multipart mp = (Multipart)part.getBody();
for (int i = 0; i < mp.getCount(); i++) {
collectParts(mp.getBodyPart(i), viewables, attachments);
}
}
/*
* If the part is an embedded message we just continue to process
* it, pulling any viewables or attachments into the running list.
*/
else if (part.getBody() instanceof Message) {
Message message = (Message)part.getBody();
collectParts(message, viewables, attachments);
}
/*
* If the part is HTML and it got this far it's part of a mixed (et
* al) and should be rendered inline.
*/
else if ((!attachment) && (part.getMimeType().equalsIgnoreCase("text/html"))) {
viewables.add(part);
}
/*
* If the part is plain text and it got this far it's part of a
* mixed (et al) and should be rendered inline.
*/
else if ((!attachment) && (part.getMimeType().equalsIgnoreCase("text/plain"))) {
viewables.add(part);
}
/*
* Finally, if it's nothing else we will include it as an attachment.
*/
else {
attachments.add(part);
}
|
public static java.lang.String | decode(java.lang.String s)
if (s == null) {
return null;
}
return DecoderUtil.decodeEncodedWords(s);
|
public static com.android.email.mail.Body | decodeBody(java.io.InputStream in, java.lang.String contentTransferEncoding)Removes any content transfer encoding from the stream and returns a Body.
/*
* We'll remove any transfer encoding by wrapping the stream.
*/
if (contentTransferEncoding != null) {
contentTransferEncoding =
MimeUtility.getHeaderParameter(contentTransferEncoding, null);
if ("quoted-printable".equalsIgnoreCase(contentTransferEncoding)) {
in = new QuotedPrintableInputStream(in);
}
else if ("base64".equalsIgnoreCase(contentTransferEncoding)) {
in = new Base64InputStream(in);
}
}
BinaryTempFileBody tempBody = new BinaryTempFileBody();
OutputStream out = tempBody.getOutputStream();
IOUtils.copy(in, out);
out.close();
return tempBody;
|
public static com.android.email.mail.Part | findFirstPartByMimeType(com.android.email.mail.Part part, java.lang.String mimeType)
if (part.getBody() instanceof Multipart) {
Multipart multipart = (Multipart)part.getBody();
for (int i = 0, count = multipart.getCount(); i < count; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
Part ret = findFirstPartByMimeType(bodyPart, mimeType);
if (ret != null) {
return ret;
}
}
}
else if (part.getMimeType().equalsIgnoreCase(mimeType)) {
return part;
}
return null;
|
public static com.android.email.mail.Part | findPartByContentId(com.android.email.mail.Part part, java.lang.String contentId)
if (part.getBody() instanceof Multipart) {
Multipart multipart = (Multipart)part.getBody();
for (int i = 0, count = multipart.getCount(); i < count; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
Part ret = findPartByContentId(bodyPart, contentId);
if (ret != null) {
return ret;
}
}
}
String cid = part.getContentId();
if (contentId.equals(cid)) {
return part;
}
return null;
|
public static java.lang.String | fold(java.lang.String s, int usedCharacters)INTERIM: From newer version of org.apache.james (but we don't want to import
the entire MimeUtil class).
Splits the specified string into a multiple-line representation with
lines no longer than 76 characters (because the line might contain
encoded words; see RFC
2047 section 2). If the string contains non-whitespace sequences
longer than 76 characters a line break is inserted at the whitespace
character following the sequence resulting in a line longer than 76
characters.
final int maxCharacters = 76;
final int length = s.length();
if (usedCharacters + length <= maxCharacters)
return s;
StringBuilder sb = new StringBuilder();
int lastLineBreak = -usedCharacters;
int wspIdx = indexOfWsp(s, 0);
while (true) {
if (wspIdx == length) {
sb.append(s.substring(Math.max(0, lastLineBreak)));
return sb.toString();
}
int nextWspIdx = indexOfWsp(s, wspIdx + 1);
if (nextWspIdx - lastLineBreak > maxCharacters) {
sb.append(s.substring(Math.max(0, lastLineBreak), wspIdx));
sb.append("\r\n");
lastLineBreak = wspIdx;
}
wspIdx = nextWspIdx;
}
|
public static java.lang.String | foldAndEncode(java.lang.String s)
return s;
|
public static java.lang.String | foldAndEncode2(java.lang.String s, int usedCharacters)INTERIM version of foldAndEncode that will be used only by Subject: headers.
This is safer than implementing foldAndEncode() (see above) and risking unknown damage
to other headers.
TODO: Copy this code to foldAndEncode(), get rid of this function, confirm all working OK.
// james.mime4j.codec.EncoderUtil.java
// encode: encodeIfNecessary(text, usage, numUsedInHeaderName)
// Usage.TEXT_TOKENlooks like the right thing for subjects
// use WORD_ENTITY for address/names
String encoded = EncoderUtil.encodeIfNecessary(s, EncoderUtil.Usage.TEXT_TOKEN,
usedCharacters);
return fold(encoded, usedCharacters);
|
public static java.lang.String | getHeaderParameter(java.lang.String header, java.lang.String name)Returns the named parameter of a header field. If name is null the first
parameter is returned, or if there are no additional parameters in the
field the entire field is returned. Otherwise the named parameter is
searched for in a case insensitive fashion and returned. If the parameter
cannot be found the method returns null.
TODO: quite inefficient with the inner trimming & splitting.
TODO: Also has a latent bug: uses "startsWith" to match the name, which can false-positive.
TODO: The doc says that for a null name you get the first param, but you get the header.
Should probably just fix the doc, but if other code assumes that behavior, fix the code.
if (header == null) {
return null;
}
String[] parts = unfold(header).split(";");
if (name == null) {
return parts[0];
}
String lowerCaseName = name.toLowerCase();
for (String part : parts) {
if (part.trim().toLowerCase().startsWith(lowerCaseName)) {
String parameter = part.split("=", 2)[1].trim();
if (parameter.startsWith("\"") && parameter.endsWith("\"")) {
return parameter.substring(1, parameter.length() - 1);
}
else {
return parameter;
}
}
}
return null;
|
public static java.lang.String | getTextFromPart(com.android.email.mail.Part part)Reads the Part's body and returns a String based on any charset conversion that needed
to be done.
try {
if (part != null && part.getBody() != null) {
InputStream in = part.getBody().getInputStream();
String mimeType = part.getMimeType();
if (mimeType != null && MimeUtility.mimeTypeMatches(mimeType, "text/*")) {
/*
* Now we read the part into a buffer for further processing. Because
* the stream is now wrapped we'll remove any transfer encoding at this point.
*/
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out);
byte[] bytes = out.toByteArray();
in.close();
out.close();
String charset = getHeaderParameter(part.getContentType(), "charset");
/*
* We've got a text part, so let's see if it needs to be processed further.
*/
if (charset != null) {
/*
* See if there is conversion from the MIME charset to the Java one.
*/
charset = CharsetUtil.toJavaCharset(charset);
}
if (charset != null) {
/*
* We've got a charset encoding, so decode using it.
*/
return new String(bytes, 0, bytes.length, charset);
}
else {
/*
* No encoding, so use us-ascii, which is the standard.
*/
return new String(bytes, 0, bytes.length, "ASCII");
}
}
}
}
catch (Exception e) {
/*
* If we are not able to process the body there's nothing we can do about it. Return
* null and let the upper layers handle the missing content.
*/
Log.e(Email.LOG_TAG, "Unable to getTextFromPart", e);
}
return null;
|
private static int | indexOfWsp(java.lang.String s, int fromIndex)INTERIM: From newer version of org.apache.james (but we don't want to import
the entire MimeUtil class).
Search for whitespace.
final int len = s.length();
for (int index = fromIndex; index < len; index++) {
char c = s.charAt(index);
if (c == ' " || c == '\t")
return index;
}
return len;
|
public static boolean | mimeTypeMatches(java.lang.String mimeType, java.lang.String matchAgainst)Returns true if the given mimeType matches the matchAgainst specification. The comparison
ignores case and the matchAgainst string may include "*" for a wildcard (e.g. "image/*").
Pattern p = Pattern.compile(matchAgainst.replaceAll("\\*", "\\.\\*"),
Pattern.CASE_INSENSITIVE);
return p.matcher(mimeType).matches();
|
public static boolean | mimeTypeMatches(java.lang.String mimeType, java.lang.String[] matchAgainst)Returns true if the given mimeType matches any of the matchAgainst specifications. The
comparison ignores case and the matchAgainst strings may include "*" for a wildcard
(e.g. "image/*").
for (String matchType : matchAgainst) {
if (mimeTypeMatches(mimeType, matchType)) {
return true;
}
}
return false;
|
public static java.lang.String | unfold(java.lang.String s)Replace sequences of CRLF+WSP with WSP. Tries to preserve original string
object whenever possible.
if (s == null) {
return null;
}
Matcher patternMatcher = PATTERN_CR_OR_LF.matcher(s);
if (patternMatcher.find()) {
patternMatcher.reset();
s = patternMatcher.replaceAll("");
}
return s;
|
public static java.lang.String | unfoldAndDecode(java.lang.String s)
return decode(unfold(s));
|