14ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira/****************************************************************
24ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Licensed to the Apache Software Foundation (ASF) under one   *
34ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * or more contributor license agreements.  See the NOTICE file *
44ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * distributed with this work for additional information        *
54ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * regarding copyright ownership.  The ASF licenses this file   *
64ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * to you under the Apache License, Version 2.0 (the            *
74ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * "License"); you may not use this file except in compliance   *
84ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * with the License.  You may obtain a copy of the License at   *
94ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira *                                                              *
104ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira *   http://www.apache.org/licenses/LICENSE-2.0                 *
114ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira *                                                              *
124ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * Unless required by applicable law or agreed to in writing,   *
134ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * software distributed under the License is distributed on an  *
144ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
154ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * KIND, either express or implied.  See the License for the    *
164ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * specific language governing permissions and limitations      *
174ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * under the License.                                           *
184ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira ****************************************************************/
194ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
204ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereirapackage org.apache.james.mime4j.message;
214ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
224ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.io.BufferedWriter;
234ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.io.IOException;
244ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.io.InputStream;
254ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.io.OutputStream;
264ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.io.OutputStreamWriter;
274ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.util.Collections;
284ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.util.HashMap;
294ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.util.Iterator;
304ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.util.LinkedList;
314ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport java.util.List;
324ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
334ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport org.apache.james.mime4j.AbstractContentHandler;
344ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport org.apache.james.mime4j.MimeStreamParser;
354ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport org.apache.james.mime4j.field.ContentTypeField;
364ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport org.apache.james.mime4j.field.Field;
374ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereiraimport org.apache.james.mime4j.util.CharsetUtil;
384ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
394ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
404ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira/**
414ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * The header of an entity (see RFC 2045).
424ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira *
434ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira *
444ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira * @version $Id: Header.java,v 1.3 2004/10/04 15:36:44 ntherning Exp $
454ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira */
464ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereirapublic class Header {
474ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    private List<Field> fields = new LinkedList<Field>();
484ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    private HashMap<String, List<Field>> fieldMap = new HashMap<String, List<Field>>();
494ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
504ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    /**
514ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * Creates a new empty <code>Header</code>.
524ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     */
534ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    public Header() {
544ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    }
554ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
564ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    /**
574ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * Creates a new <code>Header</code> from the specified stream.
584ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     *
594ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @param is the stream to read the header from.
604ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     */
614ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    public Header(InputStream is) throws IOException {
624ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        final MimeStreamParser parser = new MimeStreamParser();
634ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        parser.setContentHandler(new AbstractContentHandler() {
644ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            @Override
654ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            public void endHeader() {
664ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira                parser.stop();
674ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            }
684ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            @Override
694ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            public void field(String fieldData) {
704ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira                addField(Field.parse(fieldData));
714ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            }
724ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        });
734ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        parser.parse(is);
744ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    }
754ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
764ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    /**
774ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * Adds a field to the end of the list of fields.
784ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     *
794ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @param field the field to add.
804ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     */
814ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    public void addField(Field field) {
824ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        List<Field> values = fieldMap.get(field.getName().toLowerCase());
834ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        if (values == null) {
844ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            values = new LinkedList<Field>();
854ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            fieldMap.put(field.getName().toLowerCase(), values);
864ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        }
874ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        values.add(field);
884ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        fields.add(field);
894ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    }
904ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
914ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    /**
924ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * Gets the fields of this header. The returned list will not be
934ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * modifiable.
944ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     *
954ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @return the list of <code>Field</code> objects.
964ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     */
974ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    public List<Field> getFields() {
984ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        return Collections.unmodifiableList(fields);
994ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    }
1004ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
1014ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    /**
1024ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * Gets a <code>Field</code> given a field name. If there are multiple
1034ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * such fields defined in this header the first one will be returned.
1044ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     *
1054ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @param name the field name (e.g. From, Subject).
1064ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @return the field or <code>null</code> if none found.
1074ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     */
1084ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    public Field getField(String name) {
1094ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        List<Field> l = fieldMap.get(name.toLowerCase());
1104ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        if (l != null && !l.isEmpty()) {
1114ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            return l.get(0);
1124ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        }
1134ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        return null;
1144ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    }
1154ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
1164ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    /**
1174ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * Gets all <code>Field</code>s having the specified field name.
1184ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     *
1194ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @param name the field name (e.g. From, Subject).
1204ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @return the list of fields.
1214ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     */
1224ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    public List<Field> getFields(String name) {
1234ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        List<Field> l = fieldMap.get(name.toLowerCase());
1244ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        return Collections.unmodifiableList(l);
1254ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    }
1264ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
1274ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    /**
1284ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * Return Header Object as String representation. Each headerline is
1294ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * seperated by "\r\n"
1304ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     *
1314ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @return headers
1324ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     */
1334ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    @Override
1344ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    public String toString() {
1354ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        StringBuffer str = new StringBuffer();
1364ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        for (Iterator<Field> it = fields.iterator(); it.hasNext();) {
1374ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            str.append(it.next().toString());
1384ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira            str.append("\r\n");
1394ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        }
1404ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        return str.toString();
1414ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    }
1424ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
1434ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
1444ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    /**
1454ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * Write the Header to the given OutputStream
1464ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     *
1474ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @param out the OutputStream to write to
1484ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     * @throws IOException
1494ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira     */
1504ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    public void writeTo(OutputStream out) throws IOException {
1514ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        String charString = ((ContentTypeField) getField(Field.CONTENT_TYPE)).getCharset();
1524ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
1534ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, CharsetUtil.getCharset(charString)),8192);
1544ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        writer.write(toString()+ "\r\n");
1554ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira        writer.flush();
1564ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira    }
1574ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira
1584ebb916ddca5f59d4f854f104fca0de6e0dda706Mindy Pereira}
159