⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mimedecoder.java

📁 使用java编写的手机邮件系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * Mail4ME - Mail for the Java 2 Micro Edition * * A lightweight, J2ME- (and also J2SE-) compatible package for sending and * receiving Internet mail messages using the SMTP and POP3 protocols. * * Copyright (c) 2000-2002 J鰎g Pleumann <joerg@pleumann.de> * * Mail4ME is part of the EnhydraME family of projects. See the following web * sites for more information: * * -> http://mail4me.enhydra.org * -> http://me.enhydra.org * * Mail4ME is distributed under the Enhydra Public License (EPL), which is * discussed in great detail here: * * -> http://www.enhydra.org/software/license/index.html * * Have fun! ******************************************************************************/package de.trantor.mail;import java.io.ByteArrayOutputStream;import java.util.Vector;/** * Is a helper class for decoding MIME data contained in e-mail messages. As * the name implies, MimeDecoder allows a kind of read-only view of the MIME * parts contained in a message, giving access to textual as well as binary * content. * <p> * Every MimeDecoder works on and thus represents exactly one MIME part, which * according to RFC 2045 - RFC 2049 may be either of the following two: * <ul> *   <li> A single-part, meaning that it's a leaf in the tree-like hierarchy of *        MIME parts. In this case content may be retrieved directly using the *        getBodyLine() or getBodyBytes() methods. *   <li> A multi-part, meaning that it's an inner node in the hierarchy. In *        that case subordinate parts should be investigated. These parts may *        again be single-part as well as multi-part. * </ul> * To start working with a MimeDecoder, a new instance has to be created for * a given message, which results in a top-level MIME view of the message. * Subordinate parts can then be accessed using the getPart() method that serves * as a kind of factory method for MimeDecoders representing the lower MIME * levels of the message. * <p> * Please note that a MimeDecoder is not notified of any changes to the * underlying message it is working on, so changes to the message will make the * MimeDecoder invalid. A new MimeDecoder should be created after changes have * been applied. Otherwise the results are unpredictable and will most probably * result in some kind of Exception. * <p> * One could argue that there should be a closer integration between the Message * and the MimeDecoder classes that is able to handle these changes. The * rationale for the given implementation is - again - memory savings. The * MimeDecoder is actually an optional component that *can* be used on a Message * if the application demands it. The Message class, on the other hand, is not * dependent on the MimeDecoder at all, which means that the Message class can * be deployed without having to deploy the MimeDecoder class, too. * <p> * A short note for implementators that want to understand the internal * structure of the MimeDecoder class: The basic idea is that the MimeDecoder * holds a direct reference to the message's Vector of lines (both header and * body) as well as two integer fields telling where the part represented by * the MimeDecoder starts and ends. In case of multi-parts, an additonal * Vector holds all the occurences of the part boundary string, which makes * it quite easy to create additional MimeDecoders for the subordinate MIME * parts. * * @see Message * @see #MimeDecoder(Message) * @see #getBodyLine(int) * @see #getBodyBytes() * @see #getPart(int) */public class MimeDecoder {    /**     * Holds the header and body parts of the message this MimeDecoder is working     * on. This is a direct reference to the Vector used inside the corresponding     * message, not a copy of it.     */    private Vector lines;    /**     * Holds the line number where the body of the MIME part represented by this     * MimeDecoder instance begins (in the underlying message).     */    private int begin;    /**     * Holds the line number where the body of the MIME part represented by this     * MimeDecoder instance ends. Note that this is exclusive, so we're talking     * about the first line that does not belong to the body any more.     */    private int end;    /**     * Holds the type of the MIME part represented by this MimeDecoder instance.     * The type is deduced from the "Content-Type:" header field.     */    private String type;    /**     * Holds the name of the MIME part represented by this MimeDecoder instance.     * The name is deduced from the "name=" sub-field of the "Content-Type:"     * header field. Is is mainly used for binary attachments like pictures etc.     */    private String name;    /**     * Holds the encoding of the MIME part represented by this MimeDecoder     * instance. The encoding is deduced from the "Content-Transfer-Encoding:"     * header field.     */    private String encoding;    /**     * Holds all the line numbers where separators belonging to this MIME part are     * found, in case this is a multipart body. The line numbers are stored in     * Integer instances. Note that the actual subordinate MIME parts lie between     * the given lines (exclusive!), so if we have n values in this Vector, we     * actually have n-1 body parts.     */    private Vector parts;    /**     * Creates a new MimeDecoder for a given message. This constructor returns     * a new instance of the MimeDecoder class that grants access to a top-level     * MIME view of the message. Depending on the value returned by the getType()     * method, the message contains only this part -- in which case it can be     * accessed by the getBodyLine() or getBodyBytes() methods --, or it is     * constructed from a number of subordinate MIME parts which can be accessed     * one by one using the getPart() method.     *     * @see #getBodyLine(int)     * @see #getBodyBytes()     */    public MimeDecoder(Message message) {        init(message.getLines(), 0, message.getLines().size());    }    /**     * Creates a new MimeDecoder instance for a subordinate part of the part or     * message represented by the given MimeDecoder. The new part ranges from     * the given beginning to the given end. This is an internal constructor     * required by the getPart() method.     */    private MimeDecoder(MimeDecoder parent, int begin, int end) {        init(parent.lines, begin, end);    }    /**     * Initializes a newly created MimeDecoder. This is the most tricky method     * in the whole class, because it has to fetch all MIME information from     * the part's header and find all the occurences of the part boundary, in     * case it is a multipart body.     * <p>     * The method expects the messages line vector and the beginning of the     * part's header as well as the end (being the first line after the body).     * Note that during its operation the method advances the begin counter to     * the beginning of the part body, before it assigns the two counters to     * the private fields of the same names.     */    private void init(Vector lines, int begin, int end) {        this.lines = lines;        /**         * Walk through the whole header and look for the MIME-relevant fields.         * The end of the header is denoted by the usual empty line. Note that         * the begin counter advances while we're doing this, so that it points         * to the first line of the body later.         */        String s = (String)lines.elementAt(begin);        while (!s.equals("")) {            begin++;            /**             * Undo header folding, that is, put logical header lines that span             * multiple physical ones into one String. While this is superfluous             * for the main message header (because the Pop3Client class already             * does this) it is necessary for the headers of the various MIME parts             * (which the Pop3Client doesn't know about).             */            while (begin < end) {                String t = (String)lines.elementAt(begin);                if (t.startsWith(" ") || t.startsWith("\t")) {                    s = s + t;                    begin++;                }                else break;            }            /**             * Fetch a lower-case representation of the field name found in the             * current header line. Check if it is a MIME-relevant field. If so,             * extract additional information from the field and store it in the             * corresponding attributes of the MIME decoder.             */            String name = Message.getStringName(s).toLowerCase();            if (name.equals("content-type")) {                /**                 * The "Content-Type:" field usually contains several sub-fields, so                 * the first thing we do is split the list of sub-fields into a                 * String array. The first array entry must be the basic content type.                 * The other elements may contain additional information, so we walk                 * through the array starting from index 1.                 */                String[] elements = Message.getStringElements(Message.getStringValue(s), ';');                type = elements[0].toLowerCase();                for (int i = 1; i < elements.length; i++) {                    /**                     * If the MimeDecoder represents a multipart body *and* the part                     * boundary string is found, iterate through the whole body to find                     * all the occurences of the boundary string.                     */                    if (type.startsWith("multipart/") && getStringName(elements[i]).toLowerCase().equals("boundary")) {                        /**                         * The occurences of the boundary inside the body begin with two                         * additional hyphens.                         */                        String boundary = "--" + getStringValue(elements[i]);                        /**                         * Initialize and fill the part list.                         */                        parts = new Vector();                        for (int j = begin; j < end; j++) {                            if (getLine(j).startsWith(boundary)) {                                parts.addElement(new Integer(j));                            }                        }                    }                    /**                     * If the MimeDecoder represents a singlepart body, that is, a leaf                     * in the tree-like hierarchy of MIME parts, it may have a filename.                     */                    else if (getStringName(elements[i]).toLowerCase().equals("name")) {                        this.name = getStringValue(elements[i]);                    }                }            }            /**             * The "Content-Transfer-Encoding" attribute tells us how the MIME part             * is encoded. A common encoding that doesn't require any additional work             * is "text/plain", which is also the default encoding if none is             * specified explicitly. If the encoding is "base64", the part's data             * should be retrieved using the getBodyBytes() method.             */            else if (name.equals("content-transfer-encoding")) {                encoding = Message.getStringValue(s);            }            if (begin < end) {                s = (String)lines.elementAt(begin);            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -