196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/****************************************************************
296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one   *
396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * or more contributor license agreements.  See the NOTICE file *
496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * distributed with this work for additional information        *
596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * regarding copyright ownership.  The ASF licenses this file   *
696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * to you under the Apache License, Version 2.0 (the            *
796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * "License"); you may not use this file except in compliance   *
896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * with the License.  You may obtain a copy of the License at   *
996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *                                                              *
1096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *   http://www.apache.org/licenses/LICENSE-2.0                 *
1196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *                                                              *
1296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Unless required by applicable law or agreed to in writing,   *
1396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * software distributed under the License is distributed on an  *
1496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
1596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * KIND, either express or implied.  See the License for the    *
1696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * specific language governing permissions and limitations      *
1796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * under the License.                                           *
1896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project ****************************************************************/
1996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
2096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpackage org.apache.james.mime4j.message;
2196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
2296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.BufferedWriter;
2396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.IOException;
2496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.InputStream;
2596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.OutputStream;
2696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.io.OutputStreamWriter;
2796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.Collections;
2896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.HashMap;
2996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.Iterator;
3096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.LinkedList;
3196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.List;
3296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
3396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport org.apache.james.mime4j.AbstractContentHandler;
3496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport org.apache.james.mime4j.MimeStreamParser;
3596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport org.apache.james.mime4j.field.ContentTypeField;
3696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport org.apache.james.mime4j.field.Field;
3796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport org.apache.james.mime4j.util.CharsetUtil;
3896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
4096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/**
4196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * The header of an entity (see RFC 2045).
4296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
438546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy *
4496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @version $Id: Header.java,v 1.3 2004/10/04 15:36:44 ntherning Exp $
4596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */
4696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpublic class Header {
478546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy    private List<Field> fields = new LinkedList<Field>();
488546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy    private HashMap<String, List<Field>> fieldMap = new HashMap<String, List<Field>>();
498546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy
5096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
5196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Creates a new empty <code>Header</code>.
5296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public Header() {
5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
5596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
5696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
5796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Creates a new <code>Header</code> from the specified stream.
588546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy     *
5996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param is the stream to read the header from.
6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public Header(InputStream is) throws IOException {
6296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        final MimeStreamParser parser = new MimeStreamParser();
6396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        parser.setContentHandler(new AbstractContentHandler() {
648546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy            @Override
6596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            public void endHeader() {
6696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                parser.stop();
6796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            }
688546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy            @Override
6996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            public void field(String fieldData) {
7096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                addField(Field.parse(fieldData));
7196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            }
7296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        });
7396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        parser.parse(is);
7496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
7596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
7696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
7796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Adds a field to the end of the list of fields.
788546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy     *
7996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param field the field to add.
8096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
8196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void addField(Field field) {
828546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        List<Field> values = fieldMap.get(field.getName().toLowerCase());
8396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (values == null) {
848546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy            values = new LinkedList<Field>();
8596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fieldMap.put(field.getName().toLowerCase(), values);
8696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
8796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        values.add(field);
8896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        fields.add(field);
8996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
908546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy
9196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
9296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Gets the fields of this header. The returned list will not be
9396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * modifiable.
948546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy     *
9596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return the list of <code>Field</code> objects.
9696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
978546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy    public List<Field> getFields() {
9896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return Collections.unmodifiableList(fields);
9996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Gets a <code>Field</code> given a field name. If there are multiple
10396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * such fields defined in this header the first one will be returned.
1048546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy     *
10596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param name the field name (e.g. From, Subject).
10696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return the field or <code>null</code> if none found.
10796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
10896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public Field getField(String name) {
1098546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        List<Field> l = fieldMap.get(name.toLowerCase());
11096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (l != null && !l.isEmpty()) {
1118546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy            return l.get(0);
11296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
11396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return null;
11496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
1158546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy
11696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
1178546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy     * Gets all <code>Field</code>s having the specified field name.
1188546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy     *
11996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param name the field name (e.g. From, Subject).
12096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return the list of fields.
12196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
1228546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy    public List<Field> getFields(String name) {
1238546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        List<Field> l = fieldMap.get(name.toLowerCase());
12496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return Collections.unmodifiableList(l);
12596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
1268546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy
12796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
12896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Return Header Object as String representation. Each headerline is
12996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * seperated by "\r\n"
1308546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy     *
13196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return headers
13296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
1338546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy    @Override
13496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public String toString() {
13596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        StringBuffer str = new StringBuffer();
1368546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        for (Iterator<Field> it = fields.iterator(); it.hasNext();) {
13796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            str.append(it.next().toString());
13896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            str.append("\r\n");
13996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
14096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return str.toString();
14196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
1428546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy
1438546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy
14496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
14596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Write the Header to the given OutputStream
1468546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy     *
14796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param out the OutputStream to write to
14896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @throws IOException
14996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
15096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void writeTo(OutputStream out) throws IOException {
15196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        String charString = ((ContentTypeField) getField(Field.CONTENT_TYPE)).getCharset();
1528546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy
15396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, CharsetUtil.getCharset(charString)),8192);
15496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        writer.write(toString()+ "\r\n");
15596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        writer.flush();
15696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
15796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
15896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project}
159