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.field;
2196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
2296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.regex.Matcher;
2396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport java.util.regex.Pattern;
2496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
2596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/**
2696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * The base class of all field classes.
2796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
2896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
2996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @version $Id: Field.java,v 1.6 2004/10/25 07:26:46 ntherning Exp $
3096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */
3196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpublic abstract class Field {
3296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String SENDER = "Sender";
3396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String FROM = "From";
3496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String TO = "To";
3596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String CC = "Cc";
3696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String BCC = "Bcc";
3796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String REPLY_TO = "Reply-To";
3896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String RESENT_SENDER = "Resent-Sender";
3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String RESENT_FROM = "Resent-From";
4096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String RESENT_TO = "Resent-To";
4196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String RESENT_CC = "Resent-Cc";
4296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String RESENT_BCC = "Resent-Bcc";
4396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
4496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String DATE = "Date";
4596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String RESENT_DATE = "Resent-Date";
4696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
4796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String SUBJECT = "Subject";
4896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String CONTENT_TYPE = "Content-Type";
4996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static final String CONTENT_TRANSFER_ENCODING =
5096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                                        "Content-Transfer-Encoding";
5196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
5296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private static final String FIELD_NAME_PATTERN =
5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        "^([\\x21-\\x39\\x3b-\\x7e]+)[ \t]*:";
5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private static final Pattern fieldNamePattern =
5596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Pattern.compile(FIELD_NAME_PATTERN);
5696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
5796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private static final DefaultFieldParser parser = new DefaultFieldParser();
5896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
5996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private final String name;
6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private final String body;
6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private final String raw;
6296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
6396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    protected Field(final String name, final String body, final String raw) {
6496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        this.name = name;
6596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        this.body = body;
6696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        this.raw = raw;
6796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
6896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
6996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
7096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Parses the given string and returns an instance of the
7196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * <code>Field</code> class. The type of the class returned depends on
7296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * the field name:
7396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * <table>
7496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *      <tr>
7596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *          <td><em>Field name</em></td><td><em>Class returned</em></td>
7696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *          <td>Content-Type</td><td>org.apache.james.mime4j.field.ContentTypeField</td>
7796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *          <td>other</td><td>org.apache.james.mime4j.field.UnstructuredField</td>
7896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *      </tr>
7996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * </table>
8096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
8196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param s the string to parse.
8296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return a <code>Field</code> instance.
8396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @throws IllegalArgumentException on parse errors.
8496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
8596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static Field parse(final String raw) {
8696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
8796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        /*
8896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * Unfold the field.
8996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         */
9096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        final String unfolded = raw.replaceAll("\r|\n", "");
9196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
9296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        /*
9396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         * Split into name and value.
9496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project         */
9596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        final Matcher fieldMatcher = fieldNamePattern.matcher(unfolded);
9696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (!fieldMatcher.find()) {
9796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            throw new IllegalArgumentException("Invalid field in string");
9896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
9996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        final String name = fieldMatcher.group(1);
10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        String body = unfolded.substring(fieldMatcher.end());
10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (body.length() > 0 && body.charAt(0) == ' ') {
10396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            body = body.substring(1);
10496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
10596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
10696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return parser.parse(name, body, raw);
10796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
10896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
10996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
11096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Gets the default parser used to parse fields.
11196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return the default field parser
11296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
11396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public static DefaultFieldParser getParser() {
11496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return parser;
11596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
11696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
11796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
11896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Gets the name of the field (<code>Subject</code>,
11996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * <code>From</code>, etc).
12096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
12196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return the field name.
12296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
12396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public String getName() {
12496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return name;
12596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
12696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
12796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
12896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Gets the original raw field string.
12996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
13096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return the original raw field string.
13196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
13296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public String getRaw() {
13396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return raw;
13496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
13596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
13696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
13796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Gets the unfolded, unparsed and possibly encoded (see RFC 2047) field
13896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * body string.
13996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
14096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return the unfolded unparsed field body string.
14196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
14296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public String getBody() {
14396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return body;
14496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
14596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
14696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
14796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Determines if this is a <code>Content-Type</code> field.
14896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
14996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return <code>true</code> if this is a <code>Content-Type</code> field,
15096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *         <code>false</code> otherwise.
15196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
15296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public boolean isContentType() {
15396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return CONTENT_TYPE.equalsIgnoreCase(name);
15496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
15596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
15696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
15796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Determines if this is a <code>Subject</code> field.
15896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
15996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return <code>true</code> if this is a <code>Subject</code> field,
16096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *         <code>false</code> otherwise.
16196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
16296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public boolean isSubject() {
16396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return SUBJECT.equalsIgnoreCase(name);
16496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
16596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
16696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
16796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Determines if this is a <code>From</code> field.
16896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
16996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return <code>true</code> if this is a <code>From</code> field,
17096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *         <code>false</code> otherwise.
17196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
17296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public boolean isFrom() {
17396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return FROM.equalsIgnoreCase(name);
17496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
17596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
17696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
17796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Determines if this is a <code>To</code> field.
17896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *
17996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return <code>true</code> if this is a <code>To</code> field,
18096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *         <code>false</code> otherwise.
18196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
18296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public boolean isTo() {
18396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return TO.equalsIgnoreCase(name);
18496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
18596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
18696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
18796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @see #getRaw()
18896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
18996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public String toString() {
19096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return raw;
19196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
19296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project}
193