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.message;
021    
022    import org.apache.james.mime4j.MimeException;
023    import org.apache.james.mime4j.codec.Base64InputStream;
024    import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
025    import org.apache.james.mime4j.descriptor.BodyDescriptor;
026    import org.apache.james.mime4j.field.AbstractField;
027    import org.apache.james.mime4j.parser.AbstractContentHandler;
028    import org.apache.james.mime4j.parser.Field;
029    import org.apache.james.mime4j.util.MimeUtil;
030    
031    import java.io.InputStream;
032    import java.io.IOException;
033    
034    /**
035     * Abstract implementation of ContentHandler that automates common
036     * tasks. Currently performs header parsing and applies content-transfer
037     * decoding to body parts.
038     *
039     * 
040     */
041    public abstract class SimpleContentHandler extends  AbstractContentHandler {
042    
043        /**
044         * Called after headers are parsed.
045         */
046        public abstract void headers(Header header);
047    
048        /**
049         * Called when the body of a discrete (non-multipart) entity is encountered.
050    
051         * @param bd encapsulates the values (either read from the
052         *        message stream or, if not present, determined implictly
053         *        as described in the
054         *        MIME rfc:s) of the <code>Content-Type</code> and
055         *        <code>Content-Transfer-Encoding</code> header fields.
056         * @param is the contents of the body. Base64 or quoted-printable
057         *        decoding will be applied transparently.
058         * @throws IOException should be thrown on I/O errors.
059         */
060        public abstract void bodyDecoded(BodyDescriptor bd, InputStream is) throws IOException;
061    
062    
063        /* Implement introduced callbacks. */
064    
065        private Header currHeader;
066    
067        /**
068         * @see org.apache.james.mime4j.parser.AbstractContentHandler#startHeader()
069         */
070        @Override
071        public final void startHeader() {
072            currHeader = new Header();
073        }
074    
075        /**
076         * @see org.apache.james.mime4j.parser.AbstractContentHandler#field(Field)
077         */
078        @Override
079        public final void field(Field field) throws MimeException {
080            Field parsedField = AbstractField.parse(field.getRaw()); 
081            currHeader.addField(parsedField);
082        }
083    
084        /**
085         * @see org.apache.james.mime4j.parser.AbstractContentHandler#endHeader()
086         */
087        @Override
088        public final void endHeader() {
089            Header tmp = currHeader;
090            currHeader = null;
091            headers(tmp);
092        }
093    
094        /**
095         * @see org.apache.james.mime4j.parser.AbstractContentHandler#body(org.apache.james.mime4j.descriptor.BodyDescriptor, java.io.InputStream)
096         */
097        @Override
098        public final void body(BodyDescriptor bd, InputStream is) throws IOException {
099            if (MimeUtil.isBase64Encoding(bd.getTransferEncoding())) {
100                bodyDecoded(bd, new Base64InputStream(is));
101            }
102            else if (MimeUtil.isQuotedPrintableEncoded(bd.getTransferEncoding())) {
103                bodyDecoded(bd, new QuotedPrintableInputStream(is));
104            }
105            else {
106                bodyDecoded(bd, is);
107            }
108        }
109    }