1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/****************************************************************
2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Licensed to the Apache Software Foundation (ASF) under one   *
3bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * or more contributor license agreements.  See the NOTICE file *
4bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * distributed with this work for additional information        *
5bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * regarding copyright ownership.  The ASF licenses this file   *
6bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * to you under the Apache License, Version 2.0 (the            *
7bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * "License"); you may not use this file except in compliance   *
8bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * with the License.  You may obtain a copy of the License at   *
9bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *                                                              *
10bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *   http://www.apache.org/licenses/LICENSE-2.0                 *
11bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *                                                              *
12bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless required by applicable law or agreed to in writing,   *
13bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * software distributed under the License is distributed on an  *
14bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * KIND, either express or implied.  See the License for the    *
16bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * specific language governing permissions and limitations      *
17bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * under the License.                                           *
18bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook ****************************************************************/
19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpackage org.apache.james.mime4j.message;
21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.IOException;
23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.InputStream;
24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.OutputStream;
25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.util.Stack;
26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport org.apache.james.mime4j.BodyDescriptor;
28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport org.apache.james.mime4j.ContentHandler;
29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport org.apache.james.mime4j.MimeStreamParser;
30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport org.apache.james.mime4j.decoder.Base64InputStream;
31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport org.apache.james.mime4j.field.Field;
33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport org.apache.james.mime4j.field.UnstructuredField;
34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/**
37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Represents a MIME message. The following code parses a stream into a
38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>Message</code> object.
39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <pre>
41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *      Message msg = new Message(new BufferedInputStream(
42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *                                      new FileInputStream("mime.msg")));
43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * </pre>
44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @version $Id: Message.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */
49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpublic class Message extends Entity implements Body {
50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Creates a new empty <code>Message</code>.
53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public Message() {
55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Parses the specified MIME message stream into a <code>Message</code>
59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * instance.
60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param is the stream to parse.
62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException on I/O errors.
63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public Message(InputStream is) throws IOException {
65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        MimeStreamParser parser = new MimeStreamParser();
66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        parser.setContentHandler(new MessageBuilder());
67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        parser.parse(is);
68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Gets the <code>Subject</code> field.
73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return the <code>Subject</code> field or <code>null</code> if it
75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *         doesn't exist.
76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public UnstructuredField getSubject() {
78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return (UnstructuredField) getHeader().getField(Field.SUBJECT);
79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     *
83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @see org.apache.james.mime4j.message.Entity#writeTo(java.io.OutputStream)
84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    @Override
86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public void writeTo(OutputStream out) throws IOException {
87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        getHeader().writeTo(out);
88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        Body body = getBody();
90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        if (body instanceof Multipart) {
91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Multipart mp = (Multipart) body;
92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            mp.writeTo(out);
93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        } else {
94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            body.writeTo(out);
95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private class MessageBuilder implements ContentHandler {
100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        private Stack<Object> stack = new Stack<Object>();
101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public MessageBuilder() {
103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        private void expect(Class c) {
106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            if (!c.isInstance(stack.peek())) {
107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                throw new IllegalStateException("Internal stack error: "
108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                        + "Expected '" + c.getName() + "' found '"
109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                        + stack.peek().getClass().getName() + "'");
110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#startMessage()
115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void startMessage() {
117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            if (stack.isEmpty()) {
118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                stack.push(Message.this);
119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            } else {
120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                expect(Entity.class);
121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                Message m = new Message();
122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                ((Entity) stack.peek()).setBody(m);
123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                stack.push(m);
124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#endMessage()
129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void endMessage() {
131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(Message.class);
132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            stack.pop();
133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#startHeader()
137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void startHeader() {
139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            stack.push(new Header());
140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#field(java.lang.String)
144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void field(String fieldData) {
146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(Header.class);
147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            ((Header) stack.peek()).addField(Field.parse(fieldData));
148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#endHeader()
152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void endHeader() {
154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(Header.class);
155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Header h = (Header) stack.pop();
156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(Entity.class);
157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            ((Entity) stack.peek()).setHeader(h);
158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#startMultipart(org.apache.james.mime4j.BodyDescriptor)
162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void startMultipart(BodyDescriptor bd) {
164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(Entity.class);
165bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
166bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Entity e = (Entity) stack.peek();
167bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Multipart multiPart = new Multipart();
168bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            e.setBody(multiPart);
169bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            stack.push(multiPart);
170bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
171bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
172bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
173bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
174bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
175bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void body(BodyDescriptor bd, InputStream is) throws IOException {
176bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(Entity.class);
177bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
178bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            String enc = bd.getTransferEncoding();
179bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            if ("base64".equals(enc)) {
180bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                is = new Base64InputStream(is);
181bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            } else if ("quoted-printable".equals(enc)) {
182bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                is = new QuotedPrintableInputStream(is);
183bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
184bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
185bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Body body = null;
186bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            if (bd.getMimeType().startsWith("text/")) {
187bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                body = new MemoryTextBody(is, bd.getCharset());
188bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            } else {
189bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                body = new MemoryBinaryBody(is);
190bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
191bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
192bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            ((Entity) stack.peek()).setBody(body);
193bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
194bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
195bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
196bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#endMultipart()
197bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
198bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void endMultipart() {
199bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            stack.pop();
200bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
201bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
202bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
203bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#startBodyPart()
204bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
205bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void startBodyPart() {
206bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(Multipart.class);
207bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
208bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            BodyPart bodyPart = new BodyPart();
209bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            ((Multipart) stack.peek()).addBodyPart(bodyPart);
210bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            stack.push(bodyPart);
211bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
212bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
213bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
214bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#endBodyPart()
215bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
216bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void endBodyPart() {
217bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(BodyPart.class);
218bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            stack.pop();
219bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
220bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
221bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
222bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#epilogue(java.io.InputStream)
223bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
224bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void epilogue(InputStream is) throws IOException {
225bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(Multipart.class);
226bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            StringBuffer sb = new StringBuffer();
227bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            int b;
228bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            while ((b = is.read()) != -1) {
229bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                sb.append((char) b);
230bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
231bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            ((Multipart) stack.peek()).setEpilogue(sb.toString());
232bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
233bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
234bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
235bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#preamble(java.io.InputStream)
236bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
237bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void preamble(InputStream is) throws IOException {
238bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            expect(Multipart.class);
239bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            StringBuffer sb = new StringBuffer();
240bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            int b;
241bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            while ((b = is.read()) != -1) {
242bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                sb.append((char) b);
243bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            }
244bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            ((Multipart) stack.peek()).setPreamble(sb.toString());
245bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
246bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
247bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        /**
248bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * TODO: Implement me
249bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         *
250bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         * @see org.apache.james.mime4j.ContentHandler#raw(java.io.InputStream)
251bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook         */
252bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        public void raw(InputStream is) throws IOException {
253bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throw new UnsupportedOperationException("Not supported");
254bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
255bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
256bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
257bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook}
258