001/****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one   *
003 * or more contributor license agreements.  See the NOTICE file *
004 * distributed with this work for additional information        *
005 * regarding copyright ownership.  The ASF licenses this file   *
006 * to you under the Apache License, Version 2.0 (the            *
007 * "License"); you may not use this file except in compliance   *
008 * with the License.  You may obtain a copy of the License at   *
009 *                                                              *
010 *   http://www.apache.org/licenses/LICENSE-2.0                 *
011 *                                                              *
012 * Unless required by applicable law or agreed to in writing,   *
013 * software distributed under the License is distributed on an  *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015 * KIND, either express or implied.  See the License for the    *
016 * specific language governing permissions and limitations      *
017 * under the License.                                           *
018 ****************************************************************/
019
020package org.apache.james.mime4j.parser;
021
022import org.apache.james.mime4j.MimeException;
023import org.apache.james.mime4j.stream.BodyDescriptor;
024import org.apache.james.mime4j.stream.Field;
025
026import java.io.IOException;
027import java.io.InputStream;
028
029/**
030 * <p>
031 * Receives notifications of the content of a plain RFC822 or MIME message.
032 * Implement this interface and register an instance of that implementation
033 * with a <code>MimeStreamParser</code> instance using its
034 * {@link org.apache.james.mime4j.parser.MimeStreamParser#setContentHandler(ContentHandler)}
035 * method. The parser uses the <code>ContentHandler</code> instance to report
036 * basic message-related events like the start and end of the body of a
037 * part in a multipart MIME entity.
038 * </p>
039 * <p>
040 * Throwing an exception from an event method will terminate the message
041 * processing, i.e. no new events will be generated for that message.
042 * <p>
043 * Events will be generated in the order the corresponding elements occur in
044 * the message stream parsed by the parser. E.g.:
045 * <pre>
046 *      startMessage()
047 *          startHeader()
048 *              field(...)
049 *              field(...)
050 *              ...
051 *          endHeader()
052 *          startMultipart()
053 *              preamble(...)
054 *              startBodyPart()
055 *                  startHeader()
056 *                      field(...)
057 *                      field(...)
058 *                      ...
059 *                  endHeader()
060 *                  body()
061 *              endBodyPart()
062 *              startBodyPart()
063 *                  startHeader()
064 *                      field(...)
065 *                      field(...)
066 *                      ...
067 *                  endHeader()
068 *                  body()
069 *              endBodyPart()
070 *              epilogue(...)
071 *          endMultipart()
072 *      endMessage()
073 * </pre>
074 * The above shows an example of a MIME message consisting of a multipart
075 * body containing two body parts.
076 * </p>
077 * <p>
078 * See MIME RFCs 2045-2049 for more information on the structure of MIME
079 * messages and RFC 822 and 2822 for the general structure of Internet mail
080 * messages.
081 * </p>
082 */
083public interface ContentHandler {
084
085    /**
086     * Called when a new message starts (a top level message or an embedded
087     * rfc822 message).
088     *
089     * @throws MimeException on processing errors
090     */
091    void startMessage() throws MimeException;
092
093    /**
094     * Called when a message ends.
095     *
096     * @throws MimeException on processing errors
097     */
098    void endMessage() throws MimeException;
099
100    /**
101     * Called when a new body part starts inside a
102     * <code>multipart/*</code> entity.
103     *
104     * @throws MimeException on processing errors
105     */
106    void startBodyPart() throws MimeException;
107
108    /**
109     * Called when a body part ends.
110     *
111     * @throws MimeException on processing errors
112     */
113    void endBodyPart() throws MimeException;
114
115    /**
116     * Called when a header (of a message or body part) is about to be parsed.
117     *
118     * @throws MimeException on processing errors
119     */
120    void startHeader() throws MimeException;
121
122    /**
123     * Called for each field of a header.
124     *
125     * @param rawField the MIME field.
126     * @throws MimeException on processing errors
127     */
128    void field(Field rawField) throws MimeException;
129
130    /**
131     * Called when there are no more header fields in a message or body part.
132     *
133     * @throws MimeException on processing errors
134     */
135    void endHeader() throws MimeException;
136
137    /**
138     * Called for the preamble (whatever comes before the first body part)
139     * of a <code>multipart/*</code> entity.
140     *
141     * @param is used to get the contents of the preamble.
142     * @throws MimeException on processing errors
143     * @throws IOException should be thrown on I/O errors.
144     */
145    void preamble(InputStream is) throws MimeException, IOException;
146
147    /**
148     * Called for the epilogue (whatever comes after the final body part)
149     * of a <code>multipart/*</code> entity.
150     *
151     * @param is used to get the contents of the epilogue.
152     * @throws MimeException on processing errors
153     * @throws IOException should be thrown on I/O errors.
154     */
155    void epilogue(InputStream is) throws MimeException, IOException;
156
157    /**
158     * Called when the body of a multipart entity is about to be parsed.
159     *
160     * @param bd encapsulates the values (either read from the
161     *        message stream or, if not present, determined implictly
162     *        as described in the
163     *        MIME rfc:s) of the <code>Content-Type</code> and
164     *        <code>Content-Transfer-Encoding</code> header fields.
165     * @throws MimeException on processing errors
166     */
167    void startMultipart(BodyDescriptor bd) throws MimeException;
168
169    /**
170     * Called when the body of an entity has been parsed.
171     *
172     * @throws MimeException on processing errors
173     */
174    void endMultipart() throws MimeException;
175
176    /**
177     * Called when the body of a discrete (non-multipart) entity is about to
178     * be parsed.
179     *
180     * @param bd see {@link #startMultipart(BodyDescriptor)}
181     * @param is the contents of the body. NOTE: this is the raw body contents
182     *           - it will not be decoded if encoded. The <code>bd</code>
183     *           parameter should be used to determine how the stream data
184     *           should be decoded.
185     * @throws MimeException on processing errors
186     * @throws IOException should be thrown on I/O errors.
187     */
188    void body(BodyDescriptor bd, InputStream is)
189        throws MimeException, IOException;
190
191    /**
192     * Called when a new entity (message or body part) starts and the
193     * parser is in <code>raw</code> mode.
194     *
195     * @param is the raw contents of the entity.
196     * @throws MimeException on processing errors
197     * @throws IOException should be thrown on I/O errors.
198     * @see org.apache.james.mime4j.parser.MimeStreamParser#setRaw()
199     */
200    void raw(InputStream is) throws MimeException, IOException;
201
202}