Search in sources :

Example 21 with ZMimeMultipart

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;
}
Also used : IndexDocument(com.zimbra.cs.index.IndexDocument) MessagingException(javax.mail.MessagingException) MimeTypeTokenStream(com.zimbra.cs.index.analysis.MimeTypeTokenStream) ArrayList(java.util.ArrayList) IOException(java.io.IOException) Document(org.apache.lucene.document.Document) IndexDocument(com.zimbra.cs.index.IndexDocument) RFC822AddressTokenStream(com.zimbra.cs.index.analysis.RFC822AddressTokenStream) Header(javax.mail.Header) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) Part(javax.mail.Part) FieldTokenStream(com.zimbra.cs.index.analysis.FieldTokenStream) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ObjectHandlerException(com.zimbra.cs.object.ObjectHandlerException)

Example 22 with ZMimeMultipart

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;
}
Also used : ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) BodyPart(javax.mail.BodyPart) ContentType(com.zimbra.common.mime.ContentType) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) TNEFInputStream(net.freeutils.tnef.TNEFInputStream) InputStream(java.io.InputStream) TNEFInputStream(net.freeutils.tnef.TNEFInputStream) DefaultTnefToICalendar(com.zimbra.cs.util.tnef.DefaultTnefToICalendar) ICalTok(com.zimbra.common.calendar.ZCalendar.ICalTok) ZCalendar(com.zimbra.common.calendar.ZCalendar) ZVCalendar(com.zimbra.common.calendar.ZCalendar.ZVCalendar) StringWriter(java.io.StringWriter) ServiceException(com.zimbra.common.service.ServiceException) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) TnefToICalendar(com.zimbra.cs.util.tnef.TnefToICalendar) DefaultTnefToICalendar(com.zimbra.cs.util.tnef.DefaultTnefToICalendar) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) StringWriter(java.io.StringWriter) Writer(java.io.Writer)

Aggregations

ZMimeMultipart (com.zimbra.common.zmime.ZMimeMultipart)22 MimeMultipart (javax.mail.internet.MimeMultipart)19 ZMimeBodyPart (com.zimbra.common.zmime.ZMimeBodyPart)18 MimeBodyPart (javax.mail.internet.MimeBodyPart)17 MimeMessage (javax.mail.internet.MimeMessage)17 MessagingException (javax.mail.MessagingException)14 ZMimeMessage (com.zimbra.common.zmime.ZMimeMessage)9 JavaMailInternetAddress (com.zimbra.common.mime.shim.JavaMailInternetAddress)7 IOException (java.io.IOException)7 Date (java.util.Date)7 DataHandler (javax.activation.DataHandler)7 SMTPMessage (com.sun.mail.smtp.SMTPMessage)5 Account (com.zimbra.cs.account.Account)5 InternetAddress (javax.mail.internet.InternetAddress)5 ContentDisposition (com.zimbra.common.mime.ContentDisposition)4 Locale (java.util.Locale)4 ByteArrayDataSource (javax.mail.util.ByteArrayDataSource)4 Element (com.zimbra.common.soap.Element)3 Message (com.zimbra.cs.mailbox.Message)3 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)3