source: contrib/MailArchiver/sources/vendor/mime4j/apache-mime4j-0.7-SNAPSHOT-20110327.010440-17/core/src/main/java/org/apache/james/mime4j/parser/MimeStreamParser.java @ 6785

Revision 6785, 9.1 KB checked in by rafaelraymundo, 12 years ago (diff)

Ticket #2946 - Liberado codigo do MailArchiver?. Documentação na subpasta DOCS.

Line 
1/****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one   *
3 * or more contributor license agreements.  See the NOTICE file *
4 * distributed with this work for additional information        *
5 * regarding copyright ownership.  The ASF licenses this file   *
6 * to you under the Apache License, Version 2.0 (the            *
7 * "License"); you may not use this file except in compliance   *
8 * with the License.  You may obtain a copy of the License at   *
9 *                                                              *
10 *   http://www.apache.org/licenses/LICENSE-2.0                 *
11 *                                                              *
12 * Unless required by applicable law or agreed to in writing,   *
13 * software distributed under the License is distributed on an  *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15 * KIND, either express or implied.  See the License for the    *
16 * specific language governing permissions and limitations      *
17 * under the License.                                           *
18 ****************************************************************/
19
20package org.apache.james.mime4j.parser;
21
22import java.io.IOException;
23import java.io.InputStream;
24
25import org.apache.james.mime4j.MimeException;
26import org.apache.james.mime4j.codec.DecodeMonitor;
27import org.apache.james.mime4j.stream.BodyDescriptor;
28import org.apache.james.mime4j.stream.EntityState;
29import org.apache.james.mime4j.stream.MimeEntityConfig;
30import org.apache.james.mime4j.stream.MimeTokenStream;
31import org.apache.james.mime4j.stream.MutableBodyDescriptorFactory;
32import org.apache.james.mime4j.stream.RawField;
33import org.apache.james.mime4j.stream.RecursionMode;
34
35/**
36 * <p>
37 * Parses MIME (or RFC822) message streams of bytes or characters and reports
38 * parsing events to a <code>ContentHandler</code> instance.
39 * </p>
40 * <p>
41 * Typical usage:<br/>
42 * <pre>
43 *      ContentHandler handler = new MyHandler();
44 *      MimeStreamParser parser = new MimeStreamParser();
45 *      parser.setContentHandler(handler);
46 *      parser.parse(new FileInputStream("mime.msg"));
47 * </pre>
48 */
49public class MimeStreamParser {
50
51    private ContentHandler handler = null;
52    private boolean contentDecoding;
53    private final MimeEntityConfig mimeEntityConfig;
54   
55    private final MimeTokenStream mimeTokenStream;
56
57    public MimeStreamParser(MimeTokenStream tokenStream) {
58        super();
59        this.mimeTokenStream = tokenStream;
60        this.mimeEntityConfig = tokenStream.getConfig();
61        this.contentDecoding = false;
62    }
63
64    public MimeStreamParser(
65            final MimeEntityConfig config,
66            boolean clone,
67            final MutableBodyDescriptorFactory bodyDescFactory,
68            final DecodeMonitor monitor) {
69        this(new MimeTokenStream(clone ? config.clone() : config, bodyDescFactory, monitor));
70    }
71
72    public MimeStreamParser(final MimeEntityConfig config, boolean clone) {
73        this(new MimeTokenStream(clone ? config.clone() : config, null, null));
74    }
75
76    public MimeStreamParser(
77            final MimeEntityConfig config,
78            final MutableBodyDescriptorFactory bodyDescFactory,
79            final DecodeMonitor monitor) {
80        this(config != null ? config : new MimeEntityConfig(), config != null,
81                bodyDescFactory, monitor);
82    }
83
84    public MimeStreamParser(final MimeEntityConfig config) {
85        this(config, null, null);
86    }
87
88    public MimeStreamParser() {
89        this(new MimeEntityConfig(), false, null, null);
90    }
91   
92    /**
93     * Determines whether this parser automatically decodes body content
94     * based on the on the MIME fields with the standard defaults.
95     */
96    public boolean isContentDecoding() {
97        return contentDecoding;
98    }
99
100    /**
101     * Defines whether parser should automatically decode body content
102     * based on the on the MIME fields with the standard defaults.
103     */
104    public void setContentDecoding(boolean b) {
105        this.contentDecoding = b;
106    }
107
108    /**
109     * Parses a stream of bytes containing a MIME message. If the mime config of this
110     * object contains a not null defaultContentType
111     * ({@link MimeEntityConfig#getDefaultContentType()}) a headless parsing is performed.
112     *
113     * @param is the stream to parse.
114     * @throws MimeException if the message can not be processed
115     * @throws IOException on I/O errors.
116     */
117    public void parse(InputStream inputStream) throws MimeException, IOException {
118        if (mimeEntityConfig.getHeadlessParsing() != null) {
119            mimeTokenStream.parseHeadless(inputStream, mimeEntityConfig.getHeadlessParsing());
120            handler.startMessage();
121            handler.startHeader();
122            handler.field(new RawField("Content-Type", mimeEntityConfig.getHeadlessParsing()));
123            handler.endHeader();
124        } else {
125            mimeTokenStream.parse(inputStream);
126        }
127        OUTER: for (;;) {
128            EntityState state = mimeTokenStream.getState();
129            switch (state) {
130                case T_BODY:
131                    BodyDescriptor desc = mimeTokenStream.getBodyDescriptor();
132                    InputStream bodyContent;
133                    if (contentDecoding) {
134                        bodyContent = mimeTokenStream.getDecodedInputStream();
135                    } else {
136                        bodyContent = mimeTokenStream.getInputStream();
137                    }
138                    handler.body(desc, bodyContent);
139                    break;
140                case T_END_BODYPART:
141                    handler.endBodyPart();
142                    break;
143                case T_END_HEADER:
144                    handler.endHeader();
145                    break;
146                case T_END_MESSAGE:
147                    handler.endMessage();
148                    break;
149                case T_END_MULTIPART:
150                    handler.endMultipart();
151                    break;
152                case T_END_OF_STREAM:
153                    break OUTER;
154                case T_EPILOGUE:
155                    handler.epilogue(mimeTokenStream.getInputStream());
156                    break;
157                case T_FIELD:
158                    handler.field(mimeTokenStream.getField());
159                    break;
160                case T_PREAMBLE:
161                    handler.preamble(mimeTokenStream.getInputStream());
162                    break;
163                case T_RAW_ENTITY:
164                    handler.raw(mimeTokenStream.getInputStream());
165                    break;
166                case T_START_BODYPART:
167                    handler.startBodyPart();
168                    break;
169                case T_START_HEADER:
170                    handler.startHeader();
171                    break;
172                case T_START_MESSAGE:
173                    handler.startMessage();
174                    break;
175                case T_START_MULTIPART:
176                    handler.startMultipart(mimeTokenStream.getBodyDescriptor());
177                    break;
178                default:
179                    throw new IllegalStateException("Invalid state: " + state);
180            }
181            state = mimeTokenStream.next();
182        }
183    }
184   
185    /**
186     * Determines if this parser is currently in raw mode.
187     *
188     * @return <code>true</code> if in raw mode, <code>false</code>
189     *         otherwise.
190     * @see #setRaw(boolean)
191     */
192    public boolean isRaw() {
193        return mimeTokenStream.isRaw();
194    }
195   
196    /**
197     * Enables raw mode. In raw mode all future entities (messages
198     * or body parts) in the stream will be reported to the
199     * {@link ContentHandler#raw(InputStream)} handler method only.
200     * The stream will contain the entire unparsed entity contents
201     * including header fields and whatever is in the body.
202     */
203    public void setRaw() {
204        mimeTokenStream.setRecursionMode(RecursionMode.M_RAW);
205    }
206   
207    /**
208     * Enables flat mode. In flat mode rfc822 parts are not recursively
209     * parsed and multipart content is handled as a single "simple" stream.
210     */
211    public void setFlat() {
212        mimeTokenStream.setRecursionMode(RecursionMode.M_FLAT);
213    }
214   
215    /**
216     * Enables recursive mode. In tihs mode rfc822 parts are recursively
217     * parsed.
218     */
219    public void setRecurse() {
220        mimeTokenStream.setRecursionMode(RecursionMode.M_RECURSE);
221    }
222
223    /**
224     * Finishes the parsing and stops reading lines.
225     * NOTE: No more lines will be parsed but the parser
226     * will still call
227     * {@link ContentHandler#endMultipart()},
228     * {@link ContentHandler#endBodyPart()},
229     * {@link ContentHandler#endMessage()}, etc to match previous calls
230     * to
231     * {@link ContentHandler#startMultipart(BodyDescriptor)},
232     * {@link ContentHandler#startBodyPart()},
233     * {@link ContentHandler#startMessage()}, etc.
234     */
235    public void stop() {
236        mimeTokenStream.stop();
237    }
238   
239    /**
240     * Sets the <code>ContentHandler</code> to use when reporting
241     * parsing events.
242     *
243     * @param h the <code>ContentHandler</code>.
244     */
245    public void setContentHandler(ContentHandler h) {
246        this.handler = h;
247    }
248
249}
Note: See TracBrowser for help on using the repository browser.