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