use of javax.mail.internet.MimePart in project zm-mailbox by Zimbra.
the class Mime method getMimePart.
public static MimePart getMimePart(MimePart mp, String part) throws IOException, MessagingException {
if (mp == null) {
return null;
}
if (part == null || part.trim().isEmpty()) {
return mp;
}
part = part.trim();
boolean digestParent = false;
String[] subpart = part.split("\\.");
for (int i = 0; i < subpart.length; i++) {
int index = Integer.parseInt(subpart[i]);
if (index <= 0) {
return null;
}
// the content-type determines the expected substructure
String ct = getContentType(mp, digestParent ? MimeConstants.CT_MESSAGE_RFC822 : MimeConstants.CT_DEFAULT);
if (ct == null) {
return null;
}
digestParent = ct.equals(MimeConstants.CT_MULTIPART_DIGEST);
if (ct.startsWith(MimeConstants.CT_MULTIPART_PREFIX)) {
MimeMultipart mmp = getMultipartContent(mp, ct);
if (mmp != null && mmp.getCount() >= index) {
BodyPart bp = mmp.getBodyPart(index - 1);
if (bp instanceof MimePart) {
mp = (MimePart) bp;
continue;
}
}
} else if (ct.equals(MimeConstants.CT_MESSAGE_RFC822) || (ct.equals(MimeConstants.CT_APPLICATION_OCTET_STREAM) && isEmlAttachment(mp))) {
MimeMessage content = getMessageContent(mp);
if (content != null) {
if (mp instanceof MimeMessage) {
// the top-level part of a non-multipart message is numbered "1"
if (index != 1) {
return null;
}
} else {
i--;
}
mp = content;
continue;
}
} else if (mp instanceof MimeMessage && index == 1 && i == subpart.length - 1) {
// the top-level part of a non-multipart message is numbered "1"
break;
}
return null;
}
return mp;
}
use of javax.mail.internet.MimePart in project zm-mailbox by Zimbra.
the class CreateContact method fetchItemPart.
static String fetchItemPart(ZimbraSoapContext zsc, OperationContext octxt, Mailbox mbox, ItemId iid, String part, String[] acceptableMimeTypes, String charsetWanted) throws ServiceException {
String text = null;
try {
if (iid.isLocal()) {
// fetch from local store
if (!mbox.getAccountId().equals(iid.getAccountId())) {
mbox = MailboxManager.getInstance().getMailboxByAccountId(iid.getAccountId());
}
Message msg = mbox.getMessageById(octxt, iid.getId());
MimePart mp = Mime.getMimePart(msg.getMimeMessage(), part);
String ctype = new ContentType(mp.getContentType()).getContentType();
String fname = mp.getFileName();
if (fname != null && (MimeConstants.CT_APPLICATION_OCTET_STREAM.equals(ctype) || MimeConstants.CT_APPLICATION_TNEF.equals(ctype))) {
String guess = MimeDetect.getMimeDetect().detect(fname);
if (guess != null) {
ctype = guess;
}
}
boolean typeAcceptable;
if (acceptableMimeTypes != null) {
typeAcceptable = false;
for (String type : acceptableMimeTypes) {
if (type != null && type.equalsIgnoreCase(ctype)) {
typeAcceptable = true;
break;
}
}
} else {
typeAcceptable = true;
}
if (!typeAcceptable)
throw MailServiceException.INVALID_CONTENT_TYPE(ctype);
text = Mime.getStringContent(mp, charsetWanted);
} else {
// fetch from remote store
Map<String, String> params = new HashMap<String, String>();
params.put(UserServlet.QP_PART, part);
byte[] content = UserServlet.getRemoteContent(zsc.getAuthToken(), iid, params);
text = new String(content, MimeConstants.P_CHARSET_UTF8);
}
} catch (IOException e) {
throw ServiceException.FAILURE("error fetching message part: iid=" + iid + ", part=" + part, e);
} catch (MessagingException e) {
throw ServiceException.FAILURE("error fetching message part: iid=" + iid + ", part=" + part, e);
}
return text;
}
use of javax.mail.internet.MimePart in project zm-mailbox by Zimbra.
the class ToXML method addContent.
/** Adds the decoded text content of a message part to the {@link Element}.
* The content is added as the value of a new <tt><content></tt>
* sub-element. <i>Note: This method will only extract the content of a
* <b>text/*</b> or <b>xml/*</b> message part.</i>
*
* @param elt The element to add the <tt><content></tt> to.
* @param mpi The message part to extract the content from.
* @param maxSize The maximum number of characters to inline (<=0 is unlimited).
* @param neuter Whether to "neuter" image <tt>src</tt> attributes.
* @parame defaultCharset The user's default charset preference.
* @throws MessagingException when message parsing or CTE-decoding fails
* @throws IOException on error during parsing or defanging
* @see HtmlDefang#defang(String, boolean) */
private static void addContent(Element elt, MPartInfo mpi, int maxSize, boolean neuter, String defaultCharset, MsgContent wantContent) throws IOException, MessagingException {
// TODO: support other parts
String ctype = mpi.getContentType();
if (!ctype.matches(MimeConstants.CT_TEXT_WILD) && !ctype.matches(MimeConstants.CT_XML_WILD)) {
return;
}
MimePart mp = mpi.getMimePart();
Mime.repairTransferEncoding(mp);
String data = null;
String originalContent = null;
wantContent = wantContent == null ? MsgContent.full : wantContent;
try {
if (maxSize <= 0) {
maxSize = (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize();
} else {
maxSize = Math.min(maxSize, (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize());
}
} catch (ServiceException e) {
ZimbraLog.soap.warn("Unable to determine max content size", e);
}
boolean wasTruncated = false;
if (ctype.equals(MimeConstants.CT_TEXT_HTML)) {
String charset = mpi.getContentTypeParameter(MimeConstants.P_CHARSET);
InputStream stream = null;
StringWriter sw = new StringWriter();
TruncatingWriter tw = null;
Writer out = sw;
if (maxSize > 0) {
tw = new TruncatingWriter(sw, maxSize + 1);
out = tw;
}
Reader reader = null;
try {
stream = mp.getInputStream();
if (charset != null && !charset.trim().isEmpty()) {
// make sure to feed getTextReader() a full Content-Type header, not just the primary/subtype portion
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
BrowserDefang defanger = DefangFactory.getDefanger(mp.getContentType());
defanger.defang(reader, neuter, out);
data = sw.toString();
} else {
String cte = mp.getEncoding();
if (cte != null && !cte.trim().toLowerCase().equals(MimeConstants.ET_7BIT)) {
try {
DefangFactory.getDefanger(ctype).defang(stream, neuter, out);
data = sw.toString();
} catch (IOException e) {
}
}
if (data == null) {
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
DefangFactory.getDefanger(ctype).defang(reader, neuter, out);
data = sw.toString();
}
}
if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
originalContent = removeQuotedText(data, true);
}
} finally {
if (tw != null) {
wasTruncated = tw.wasTruncated();
}
ByteUtil.closeStream(stream);
Closeables.closeQuietly(reader);
}
} else if (ctype.equals(MimeConstants.CT_TEXT_ENRICHED)) {
// Enriched text handling is a little funky because TextEnrichedHandler
// doesn't use Reader and Writer. As a result, we truncate
// the source before converting to HTML.
InputStream stream = mp.getInputStream();
Reader reader = null;
try {
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
String enriched = ByteUtil.getContent(reader, maxChars, false);
if (enriched.length() == maxChars) {
// The normal check for truncated data won't work because
// the length of the converted text is different than the length
// of the source, so set the attr here.
wasTruncated = true;
}
if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
originalContent = TextEnrichedHandler.convertToHTML(removeQuotedText(enriched, false));
}
data = TextEnrichedHandler.convertToHTML(enriched);
} finally {
ByteUtil.closeStream(stream);
Closeables.closeQuietly(reader);
}
} else {
InputStream stream = mp.getInputStream();
Reader reader = null;
try {
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
data = ByteUtil.getContent(reader, maxChars, false);
if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
originalContent = removeQuotedText(data, false);
}
if (data.length() == maxChars) {
wasTruncated = true;
}
} finally {
ByteUtil.closeStream(stream);
Closeables.closeQuietly(reader);
}
}
if (data != null && !wantContent.equals(MsgContent.original)) {
data = StringUtil.stripControlCharacters(data);
if (wasTruncated) {
elt.addAttribute(MailConstants.A_TRUNCATED_CONTENT, true);
if (data.length() > maxSize) {
data = data.substring(0, maxSize);
}
}
elt.addAttribute(MailConstants.E_CONTENT, data, Element.Disposition.CONTENT);
}
if (originalContent != null && (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both))) {
originalContent = StringUtil.stripControlCharacters(originalContent);
elt.addUniqueElement(MailConstants.E_ORIG_CONTENT).setText(originalContent);
}
// TODO: CDATA worth the effort?
}
use of javax.mail.internet.MimePart in project zm-mailbox by Zimbra.
the class ZimbraMailAdapter method getMatchingHeaderFromAllParts.
/**
* Scans all MIME parts and returns the values of any headers that
* match the given name.
*/
public Set<String> getMatchingHeaderFromAllParts(String name) throws SieveMailException {
MimeMessage msg;
Set<String> values = new HashSet<String>();
try {
msg = handler.getMimeMessage();
for (MPartInfo partInfo : Mime.getParts(msg)) {
MimePart part = partInfo.getMimePart();
values.addAll(Arrays.asList(Mime.getHeaders(part, name)));
}
} catch (Exception e) {
throw new SieveMailException("Unable to match attachment headers.", e);
}
return values;
}
use of javax.mail.internet.MimePart in project zm-mailbox by Zimbra.
the class AttachmentDataSource method getMimePart.
private MimePart getMimePart() throws MessagingException, ServiceException {
MimeMessage msg = mContact.getMimeMessage(false);
MimePart mp = null;
try {
mp = Mime.getMimePart(msg, mPartName);
} catch (IOException e) {
throw ServiceException.FAILURE("Unable to look up part " + mPartName + " for contact " + mContact.getId(), null);
}
if (mp == null) {
ZimbraLog.mailbox.warn("Unable to find part %s for contact %d.", mPartName, mContact.getId());
}
return mp;
}
Aggregations