Example usage for javax.mail.internet MimePart getEncoding

List of usage examples for javax.mail.internet MimePart getEncoding

Introduction

In this page you can find the example usage for javax.mail.internet MimePart getEncoding.

Prototype

public String getEncoding() throws MessagingException;

Source Link

Document

Get the transfer encoding of this part.

Usage

From source file:mitm.common.mail.MailUtils.java

/**
 * Converts any 8bit encoded parts to 7bit. Returns true if a part (or all parts) were converted from
 * 8bit to 7bit.// www.  j a v a  2 s.c  om
 * 
 * @param part
 * @throws MessagingException
 */
public static boolean convertTo7Bit(MimePart part) throws MessagingException, IOException {
    boolean converted = false;

    if (part.isMimeType("multipart/*")) {
        Multipart parts = (Multipart) part.getContent();

        int count = parts.getCount();

        for (int i = 0; i < count; i++) {
            boolean partConverted = convertTo7Bit((MimePart) parts.getBodyPart(i));

            if (partConverted) {
                converted = true;
            }
        }
    } else if ("8bit".equalsIgnoreCase(part.getEncoding())) {
        String encoding = part.isMimeType("text/*") ? "quoted-printable" : "base64";

        /*
         * We need to use a ByteArrayDataSource to make sure it will always be encoded
         */
        part.setDataHandler(
                new DataHandler(new ByteArrayDataSource(part.getInputStream(), part.getContentType())));

        part.setHeader("Content-Transfer-Encoding", encoding);
        part.addHeader("X-MIME-Autoconverted", "from 8bit to " + encoding + " by Djigzo");

        converted = true;
    }

    return converted;
}

From source file:com.zimbra.cs.mime.Mime.java

/**
 * Returns the size of this <tt>MimePart</tt>'s content.  If the content
 * is encoded, returns the size of the decoded content.
 *///from  www.  j  a v  a 2 s . c o  m
public static int getSize(MimePart part) throws MessagingException, IOException {
    int size = part.getSize();
    if (size > 0) {
        if ("base64".equalsIgnoreCase(part.getEncoding())) {
            // MimePart.getSize() returns the encoded size.
            int lines = (size + 77) / 78;
            size = (int) (0.75 * (size - 2 * lines));
        }
    } else {
        size = (int) ByteUtil.getDataLength(part.getInputStream());
    }
    return size;
}

From source file:com.stimulus.archiva.store.MessageStore.java

public void writeTo(MimePart part, OutputStream os, String[] includeList)
        throws IOException, MessagingException {
    LineOutputStream los = null;//from   w ww  .  j  a v  a  2 s. c o  m
    if (os instanceof LineOutputStream) {
        los = (LineOutputStream) os;
    } else {
        los = new LineOutputStream(os);
    }
    Enumeration hdrLines = part.getMatchingHeaderLines(includeList);
    while (hdrLines.hasMoreElements()) {
        String line = (String) hdrLines.nextElement();
        los.writeln(line);
    }
    los.writeln();
    os = MimeUtility.encode(os, part.getEncoding());
    part.getDataHandler().writeTo(os);
    os.flush();
}

From source file:com.duroty.utils.mail.MessageUtilities.java

/**
 * Get a textual description of a part./*from w ww. j  av  a 2 s.com*/
 *
 * @param part The part to interogate
 * @param buf a string buffer for the description
 * @param prefix a prefix for each line of the description
 * @param recurse boolean specifying wether to recurse through sub-parts or
 *        not
 *
 * @return StringBuffer containing the description of the part
 *
 * @throws MessagingException DOCUMENT ME!
 */
public static StringBuffer getPartDescription(Part part, StringBuffer buf, String prefix, boolean recurse)
        throws MessagingException {
    if (buf == null) {
        return buf;
    }

    ContentType xctype = MessageUtilities.getContentType(part);

    String xvalue = xctype.toString();
    buf.append(prefix);
    buf.append("Content-Type: ");
    buf.append(xvalue);
    buf.append('\n');

    xvalue = part.getDisposition();
    buf.append(prefix);
    buf.append("Content-Disposition: ");
    buf.append(xvalue);
    buf.append('\n');

    xvalue = part.getDescription();
    buf.append(prefix);
    buf.append("Content-Description: ");
    buf.append(xvalue);
    buf.append('\n');

    xvalue = MessageUtilities.getFileName(part);
    buf.append(prefix);
    buf.append("Content-Filename: ");
    buf.append(xvalue);
    buf.append('\n');

    if (part instanceof MimePart) {
        MimePart xmpart = (MimePart) part;
        xvalue = xmpart.getContentID();
        buf.append(prefix);
        buf.append("Content-ID: ");
        buf.append(xvalue);
        buf.append('\n');

        String[] langs = xmpart.getContentLanguage();

        if (langs != null) {
            buf.append(prefix);
            buf.append("Content-Language: ");

            for (int pi = 0; pi < langs.length; ++pi) {
                if (pi > 0) {
                    buf.append(", ");
                }

                buf.append(xvalue);
            }

            buf.append('\n');
        }

        xvalue = xmpart.getContentMD5();
        buf.append(prefix);
        buf.append("Content-MD5: ");
        buf.append(xvalue);
        buf.append('\n');

        xvalue = xmpart.getEncoding();
        buf.append(prefix);
        buf.append("Content-Encoding: ");
        buf.append(xvalue);
        buf.append('\n');
    }

    buf.append('\n');

    if (recurse && xctype.match("multipart/*")) {
        Multipart xmulti = (Multipart) MessageUtilities.getPartContent(part);

        int xparts = xmulti.getCount();

        for (int xindex = 0; xindex < xparts; xindex++) {
            MessageUtilities.getPartDescription(xmulti.getBodyPart(xindex), buf, (prefix + "   "), true);
        }
    }

    return buf;
}

From source file:com.zimbra.cs.imap.ImapMessage.java

static void serializeStructure(PrintStream ps, MimeMessage root, boolean extensions)
        throws IOException, MessagingException {
    LinkedList<LinkedList<MPartInfo>> queue = new LinkedList<LinkedList<MPartInfo>>();
    LinkedList<MPartInfo> level = new LinkedList<MPartInfo>();
    level.add(Mime.getParts(root).get(0));
    queue.add(level);// w w w  .j a va  2 s.com

    boolean pop = false;
    while (!queue.isEmpty()) {
        level = queue.getLast();
        if (level.isEmpty()) {
            queue.removeLast();
            pop = true;
            continue;
        }

        MPartInfo mpi = level.getFirst();
        MimePart mp = mpi.getMimePart();
        boolean hasChildren = mpi.getChildren() != null && !mpi.getChildren().isEmpty();

        // we used to force unset charsets on text/plain parts to US-ASCII, but that always seemed unwise...
        ContentType ctype = new ContentType(mp.getHeader("Content-Type", null))
                .setContentType(mpi.getContentType());
        String primary = nATOM(ctype.getPrimaryType()), subtype = nATOM(ctype.getSubType());

        if (!pop)
            ps.write('(');
        if (primary.equals("\"MULTIPART\"")) {
            if (!pop) {
                // 7.4.2: "Multiple parts are indicated by parenthesis nesting.  Instead of a body type
                //         as the first element of the parenthesized list, there is a sequence of one
                //         or more nested body structures.  The second element of the parenthesized
                //         list is the multipart subtype (mixed, digest, parallel, alternative, etc.)."
                if (!hasChildren) {
                    ps.print("NIL");
                } else {
                    queue.addLast(new LinkedList<MPartInfo>(mpi.getChildren()));
                    continue;
                }
            }
            ps.write(' ');
            ps.print(subtype);
            if (extensions) {
                // 7.4.2: "Extension data follows the multipart subtype.  Extension data is never
                //         returned with the BODY fetch, but can be returned with a BODYSTRUCTURE
                //         fetch.  Extension data, if present, MUST be in the defined order.  The
                //         extension data of a multipart body part are in the following order:
                //         body parameter parenthesized list, body disposition, body language,
                //         body location"
                ps.write(' ');
                nparams(ps, ctype);
                ps.write(' ');
                ndisposition(ps, mp.getHeader("Content-Disposition", null));
                ps.write(' ');
                nlist(ps, mp.getContentLanguage());
                ps.write(' ');
                nstring(ps, mp.getHeader("Content-Location", null));
            }
        } else {
            if (!pop) {
                // 7.4.2: "The basic fields of a non-multipart body part are in the following order:
                //         body type, body subtype, body parameter parenthesized list, body id, body
                //         description, body encoding, body size."
                String cte = mp.getEncoding();
                cte = (cte == null || cte.trim().equals("") ? "7bit" : cte);
                aSTRING(ps, ctype.getPrimaryType());
                ps.write(' ');
                aSTRING(ps, ctype.getSubType());
                ps.write(' ');
                nparams(ps, ctype);
                ps.write(' ');
                nstring(ps, mp.getContentID());
                ps.write(' ');
                nstring2047(ps, mp.getDescription());
                ps.write(' ');
                aSTRING(ps, cte);
                ps.write(' ');
                ps.print(Math.max(mp.getSize(), 0));
            }
            boolean rfc822 = primary.equals("\"MESSAGE\"") && subtype.equals("\"RFC822\"");
            if (rfc822) {
                // 7.4.2: "A body type of type MESSAGE and subtype RFC822 contains, immediately
                //         after the basic fields, the envelope structure, body structure, and
                //         size in text lines of the encapsulated message."
                if (!pop) {
                    if (!hasChildren) {
                        ps.print(" NIL NIL");
                    } else {
                        MimeMessage mm = (MimeMessage) mpi.getChildren().get(0).getMimePart();
                        ps.write(' ');
                        serializeEnvelope(ps, mm);
                        ps.write(' ');
                        queue.addLast(new LinkedList<MPartInfo>(mpi.getChildren()));
                        continue;
                    }
                }
                ps.write(' ');
                ps.print(getLineCount(mp));
            } else if (primary.equals("\"TEXT\"")) {
                // 7.4.2: "A body type of type TEXT contains, immediately after the basic fields, the
                //         size of the body in text lines.  Note that this size is the size in its
                //         content transfer encoding and not the resulting size after any decoding."
                ps.write(' ');
                ps.print(getLineCount(mp));
            }
            if (extensions) {
                // 7.4.2: "Extension data follows the basic fields and the type-specific fields
                //         listed above.  Extension data is never returned with the BODY fetch,
                //         but can be returned with a BODYSTRUCTURE fetch.  Extension data, if
                //         present, MUST be in the defined order.  The extension data of a
                //         non-multipart body part are in the following order: body MD5, body
                //         disposition, body language, body location"
                ps.write(' ');
                nstring(ps, mp.getContentMD5());
                ps.write(' ');
                ndisposition(ps, mp.getHeader("Content-Disposition", null));
                ps.write(' ');
                nlist(ps, mp.getContentLanguage());
                ps.write(' ');
                nstring(ps, mp.getHeader("Content-Location", null));
            }
        }
        ps.write(')');

        level.removeFirst();
        pop = false;
    }
}

From source file:com.icegreen.greenmail.store.SimpleMessageAttributes.java

/**
 * Parses key data items from a MimeMessage for seperate storage.
 * TODO this is a mess, and should be completely revamped.
 *///from ww  w.j  a v a 2s .c o  m
void parseMimePart(MimePart part) throws MessagingException {
    size = GreenMailUtil.getBody(part).length();

    // Section 1 - Message Headers
    if (part instanceof MimeMessage) {
        try {
            subject = ((MimeMessage) part).getSubject();
        } catch (MessagingException me) {
            //                if (DEBUG) getLogger().debug("Messaging Exception for getSubject: " + me);
        }
    }
    try {
        from = part.getHeader("From");
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getHeader(From): " + me);
    }
    try {
        sender = part.getHeader("Sender");
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getHeader(Sender): " + me);
    }
    try {
        replyTo = part.getHeader("Reply To");
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getHeader(Reply To): " + me);
    }
    try {
        to = part.getHeader("To");
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getHeader(To): " + me);
    }
    try {
        cc = part.getHeader("Cc");
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getHeader(To): " + me);
    }
    try {
        bcc = part.getHeader("Bcc");
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getHeader(To): " + me);
    }
    try {
        inReplyTo = part.getHeader("In Reply To");
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getHeader(In Reply To): " + me);
    }
    try {
        date = part.getHeader("Date");
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getHeader(Date): " + me);
    }
    try {
        messageID = part.getHeader("Message-ID");
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getHeader(messageID): " + me);
    }
    String contentTypeLine = null;
    try {
        contentTypeLine = part.getContentType();
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getContentType(): " + me);
    }
    if (contentTypeLine != null) {
        decodeContentType(contentTypeLine);
    }
    try {
        contentID = part.getContentID();
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getContentUD(): " + me);
    }
    try {
        contentDesc = part.getDescription();
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getDescription(): " + me);
    }
    try {
        contentEncoding = part.getEncoding();
        // default value.
        if (contentEncoding == null) {
            contentEncoding = "7BIT";
        }
    } catch (MessagingException me) {
        //            if (DEBUG) getLogger().debug("Messaging Exception for getEncoding(): " + me);
    }

    try {
        //            contentDisposition = part.getDisposition();
        contentDisposition = Header.create(part.getHeader("Content-Disposition"));
    } catch (MessagingException me) {
        if (log.isDebugEnabled()) {
            log.debug("Can not create content disposition for part " + part, me);
        }
    }

    try {
        // TODO this doesn't work
        lineCount = getLineCount(part);
    } catch (Exception e) {
        if (log.isDebugEnabled()) {
            log.debug("Can not get line count for part " + part, e);
        }
    }

    // Recurse through any embedded parts
    if (primaryType.equalsIgnoreCase(MULTIPART)) {
        MimeMultipart container;
        try {
            container = (MimeMultipart) part.getContent();
            int count = container.getCount();
            parts = new SimpleMessageAttributes[count];
            for (int i = 0; i < count; i++) {
                BodyPart nextPart = container.getBodyPart(i);

                if (nextPart instanceof MimePart) {
                    SimpleMessageAttributes partAttrs = new SimpleMessageAttributes(null, receivedDate);
                    partAttrs.parseMimePart((MimePart) nextPart);
                    parts[i] = partAttrs;

                }
            }
        } catch (Exception e) {
            if (log.isDebugEnabled()) {
                log.debug("Can not recurse through multipart content", e);
            }
        }
    } else if (primaryType.equalsIgnoreCase("message")) {
        if (secondaryType.equalsIgnoreCase("RFC822")) {
            //try {

            /*
            MimeMessageWrapper message = new MimeMessageWrapper(part.getInputStream());
            SimpleMessageAttributes msgAttrs = new SimpleMessageAttributes();
            msgAttrs.setAttributesFor(message);
                    
            if (part instanceof MimeMessage) {
            Comments out because I don't know what it should do here
            MimeMessage msg1 = (MimeMessage) part;
            MimeMessageWrapper message2 = new MimeMessageWrapper(msg1);
            SimpleMessageAttributes msgAttrs2 = new SimpleMessageAttributes();
            msgAttrs.setAttributesFor(message2);
            }
                    
            parts = new SimpleMessageAttributes[1];
            parts[0] = msgAttrs;
            */
            //} catch (Exception e) {
            //getLogger().error("Error interpreting a message/rfc822: " + e);
            //e.printStackTrace();
            //}

            // TODO: Warn till fixed!
            log.warn("Unknown/unhandled subtype " + secondaryType + " of message encountered.");
        } else {
            log.warn("Unknown/unhandled subtype " + secondaryType + " of message encountered.");
        }
    }
}

From source file:com.zimbra.cs.service.mail.ToXML.java

/** Adds the decoded text content of a message part to the {@link Element}.
 *  The content is added as the value of a new <tt>&lt;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>&lt;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;//from www  . ja va  2 s.c  o m
    }
    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?
}

From source file:davmail.imap.ImapConnection.java

protected void appendBodyStructure(StringBuilder buffer, MimePart bodyPart)
        throws IOException, MessagingException {
    String contentType = MimeUtility.unfold(bodyPart.getContentType());
    int slashIndex = contentType.indexOf('/');
    if (slashIndex < 0) {
        throw new DavMailException("EXCEPTION_INVALID_CONTENT_TYPE", contentType);
    }//ww w.ja  v a  2s.c  o  m
    String type = contentType.substring(0, slashIndex).toUpperCase();
    buffer.append("(\"").append(type).append("\" \"");
    int semiColonIndex = contentType.indexOf(';');
    if (semiColonIndex < 0) {
        buffer.append(contentType.substring(slashIndex + 1).toUpperCase()).append("\" NIL");
    } else {
        // extended content type
        buffer.append(contentType.substring(slashIndex + 1, semiColonIndex).trim().toUpperCase()).append('\"');
        int charsetindex = contentType.indexOf("charset=");
        int nameindex = contentType.indexOf("name=");
        if (charsetindex >= 0 || nameindex >= 0) {
            buffer.append(" (");

            if (charsetindex >= 0) {
                buffer.append("\"CHARSET\" ");
                int charsetSemiColonIndex = contentType.indexOf(';', charsetindex);
                int charsetEndIndex;
                if (charsetSemiColonIndex > 0) {
                    charsetEndIndex = charsetSemiColonIndex;
                } else {
                    charsetEndIndex = contentType.length();
                }
                String charSet = contentType.substring(charsetindex + "charset=".length(), charsetEndIndex);
                if (!charSet.startsWith("\"")) {
                    buffer.append('"');
                }
                buffer.append(charSet.trim().toUpperCase());
                if (!charSet.endsWith("\"")) {
                    buffer.append('"');
                }
            }

            if (nameindex >= 0) {
                if (charsetindex >= 0) {
                    buffer.append(' ');
                }

                buffer.append("\"NAME\" ");
                int nameSemiColonIndex = contentType.indexOf(';', nameindex);
                int nameEndIndex;
                if (nameSemiColonIndex > 0) {
                    nameEndIndex = nameSemiColonIndex;
                } else {
                    nameEndIndex = contentType.length();
                }
                String name = contentType.substring(nameindex + "name=".length(), nameEndIndex).trim();
                if (!name.startsWith("\"")) {
                    buffer.append('"');
                }
                buffer.append(name.trim());
                if (!name.endsWith("\"")) {
                    buffer.append('"');
                }
            }
            buffer.append(')');
        } else {
            buffer.append(" NIL");
        }
    }
    appendBodyStructureValue(buffer, bodyPart.getContentID());
    appendBodyStructureValue(buffer, bodyPart.getDescription());
    appendBodyStructureValue(buffer, bodyPart.getEncoding());
    appendBodyStructureValue(buffer, bodyPart.getSize());
    if ("MESSAGE".equals(type) || "TEXT".equals(type)) {
        // line count not implemented in JavaMail, return fake line count
        appendBodyStructureValue(buffer, bodyPart.getSize() / 80);
    } else {
        // do not send line count for non text bodyparts
        appendBodyStructureValue(buffer, -1);
    }
    buffer.append(')');
}