use of com.zimbra.common.zmime.ZMimeMultipart in project zm-mailbox by Zimbra.
the class ParsedMessage method getMainBodyLuceneDocument.
private IndexDocument getMainBodyLuceneDocument(StringBuilder fullContent) throws MessagingException, ServiceException {
IndexDocument doc = new IndexDocument(new Document());
doc.addMimeType(new MimeTypeTokenStream("message/rfc822"));
doc.addPartName(LuceneFields.L_PARTNAME_TOP);
doc.addFrom(getFromTokenStream());
doc.addTo(getToTokenStream());
doc.addCc(getCcTokenStream());
try {
doc.addEnvFrom(new RFC822AddressTokenStream(getMimeMessage().getHeader("X-Envelope-From", ",")));
} catch (MessagingException ignore) {
}
try {
doc.addEnvTo(new RFC822AddressTokenStream(getMimeMessage().getHeader("X-Envelope-To", ",")));
} catch (MessagingException ignore) {
}
String msgId = Strings.nullToEmpty(Mime.getHeader(getMimeMessage(), "message-id"));
if (msgId.length() > 0) {
if (msgId.charAt(0) == '<') {
msgId = msgId.substring(1);
}
if (msgId.charAt(msgId.length() - 1) == '>') {
msgId = msgId.substring(0, msgId.length() - 1);
}
if (msgId.length() > 0) {
doc.addMessageId(msgId);
}
}
// iterate all the message headers, add them to the structured-field data in the index
FieldTokenStream fields = new FieldTokenStream();
MimeMessage mm = getMimeMessage();
List<Part> parts = new ArrayList<Part>();
parts.add(mm);
try {
if (mm.getContent() instanceof ZMimeMultipart) {
ZMimeMultipart content = (ZMimeMultipart) mm.getContent();
int numParts = content.getCount();
for (int i = 0; i < numParts; i++) {
parts.add(content.getBodyPart(i));
}
}
} catch (IOException ignore) {
}
for (Part part : parts) {
Enumeration<?> en = part.getAllHeaders();
while (en.hasMoreElements()) {
Header h = (Header) en.nextElement();
String key = h.getName().trim();
String value = h.getValue();
if (value != null) {
value = MimeUtility.unfold(value).trim();
} else {
value = "";
}
if (key.length() > 0) {
if (value.length() == 0) {
// low-level tokenizer can't deal with blank header value, so we'll index
// some dummy value just so the header appears in the index.
// Users can query for the existence of the header with a query
// like #headername:*
fields.add(key, "_blank_");
} else {
fields.add(key, value);
}
}
}
}
// add key:value pairs to the structured FIELD lucene field
doc.addField(fields);
String subject = getSubject();
doc.addSubject(subject);
// add subject and from to main content for better searching
StringBuilder contentPrepend = new StringBuilder(subject);
// Bug 583: add all of the TOKENIZED versions of the email addresses to our CONTENT field...
appendToContent(contentPrepend, StringUtil.join(" ", getFromTokenStream().getAllTokens()));
appendToContent(contentPrepend, StringUtil.join(" ", getToTokenStream().getAllTokens()));
appendToContent(contentPrepend, StringUtil.join(" ", getCcTokenStream().getAllTokens()));
// bug 33461: add filenames to our CONTENT field
for (String fn : filenames) {
appendToContent(contentPrepend, ZimbraAnalyzer.getAllTokensConcatenated(LuceneFields.L_FILENAME, fn));
// also add the non-tokenized form, so full-filename searches match
appendToContent(contentPrepend, fn);
}
String text = contentPrepend.toString() + " " + fullContent.toString();
doc.addContent(text);
try {
MimeHandler.getObjects(text, doc);
} catch (ObjectHandlerException e) {
ZimbraLog.index.warn("Unable to recognize searchable objects in message: msgid=%s,subject=%s", getMessageID(), getSubject(), e);
}
// Get the list of attachment content types from this message and any TNEF attachments
doc.addAttachments(new MimeTypeTokenStream(Mime.getAttachmentTypeList(messageParts)));
return doc;
}
use of com.zimbra.common.zmime.ZMimeMultipart in project zm-mailbox by Zimbra.
the class TnefConverter method expandTNEF.
/**
* Performs the TNEF->MIME conversion on any TNEF body parts that
* make up the given message.
* @throws ServiceException
*/
private MimeMultipart expandTNEF(MimeBodyPart bp) throws MessagingException, IOException {
if (!TNEFUtils.isTNEFMimeType(bp.getContentType()))
return null;
MimeMessage converted = null;
// convert TNEF to a MimeMessage and remove it from the parent
InputStream is = null;
try {
TNEFInputStream tnefis = new TNEFInputStream(is = bp.getInputStream());
converted = TNEFMime.convert(JMSession.getSession(), tnefis);
// XXX bburtin: nasty hack. Don't handle OOME since JTNEF can allocate a huge byte
// array when the TNEF file is malformed. See bug 42649.
// } catch (OutOfMemoryError e) {
// Zimbra.halt("Ran out of memory while expanding TNEF attachment", e);
} catch (Throwable t) {
ZimbraLog.extensions.warn("Conversion failed. TNEF attachment will not be expanded.", t);
return null;
} finally {
ByteUtil.closeStream(is);
}
Object convertedContent = converted.getContent();
if (!(convertedContent instanceof MimeMultipart)) {
ZimbraLog.extensions.debug("TNEF attachment doesn't contain valid MimeMultiPart");
return null;
}
MimeMultipart convertedMulti = (MimeMultipart) convertedContent;
// make sure that all the attachments are marked as attachments
for (int i = 0; i < convertedMulti.getCount(); i++) {
BodyPart subpart = convertedMulti.getBodyPart(i);
if (subpart.getHeader("Content-Disposition") == null)
subpart.setHeader("Content-Disposition", Part.ATTACHMENT);
}
// Create a MimeBodyPart for the converted data. Currently we're throwing
// away the top-level message because its content shows up as blank after
// the conversion.
MimeBodyPart convertedPart = new ZMimeBodyPart();
convertedPart.setContent(convertedMulti);
// If the TNEF object contains calendar data, create an iCalendar version.
MimeBodyPart icalPart = null;
if (DebugConfig.enableTnefToICalendarConversion) {
try {
TnefToICalendar calConverter = new DefaultTnefToICalendar();
ZCalendar.DefaultContentHandler icalHandler = new ZCalendar.DefaultContentHandler();
if (calConverter.convert(mMimeMessage, bp.getInputStream(), icalHandler)) {
if (icalHandler.getNumCals() > 0) {
List<ZVCalendar> cals = icalHandler.getCals();
Writer writer = new StringWriter(1024);
ICalTok method = null;
for (ZVCalendar cal : cals) {
cal.toICalendar(writer);
if (method == null)
method = cal.getMethod();
}
writer.close();
icalPart = new ZMimeBodyPart();
icalPart.setText(writer.toString());
ContentType ct = new ContentType(MimeConstants.CT_TEXT_CALENDAR);
ct.setCharset(MimeConstants.P_CHARSET_UTF8);
if (method != null)
ct.setParameter("method", method.toString());
icalPart.setHeader("Content-Type", ct.toString());
}
}
} catch (ServiceException e) {
throw new MessagingException("TNEF to iCalendar conversion failure: " + e.getMessage(), e);
} catch (Throwable t) {
//don't allow TNEF errors to crash server
ZimbraLog.extensions.warn("Failed to convert TNEF to iCal", t);
throw new MessagingException("TNEF to iCalendar conversion failure");
}
}
// create a multipart/alternative for the TNEF and its MIME version
MimeMultipart altMulti = new ZMimeMultipart("alternative");
// altMulti.addBodyPart(bp);
altMulti.addBodyPart(convertedPart);
if (icalPart != null)
altMulti.addBodyPart(icalPart);
return altMulti;
}
Aggregations