| /**************************************************************** |
| * Licensed to the Apache Software Foundation (ASF) under one * |
| * or more contributor license agreements. See the NOTICE file * |
| * distributed with this work for additional information * |
| * regarding copyright ownership. The ASF licenses this file * |
| * to you under the Apache License, Version 2.0 (the * |
| * "License"); you may not use this file except in compliance * |
| * with the License. You may obtain a copy of the License at * |
| * * |
| * http://www.apache.org/licenses/LICENSE-2.0 * |
| * * |
| * Unless required by applicable law or agreed to in writing, * |
| * software distributed under the License is distributed on an * |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * |
| * KIND, either express or implied. See the License for the * |
| * specific language governing permissions and limitations * |
| * under the License. * |
| ****************************************************************/ |
| |
| package org.apache.james.mime4j.field; |
| |
| import org.apache.james.mime4j.MimeException; |
| import org.apache.james.mime4j.codec.DecodeMonitor; |
| import org.apache.james.mime4j.dom.FieldParser; |
| import org.apache.james.mime4j.dom.field.AddressListField; |
| import org.apache.james.mime4j.dom.field.ContentDescriptionField; |
| import org.apache.james.mime4j.dom.field.ContentDispositionField; |
| import org.apache.james.mime4j.dom.field.ContentIdField; |
| import org.apache.james.mime4j.dom.field.ContentLanguageField; |
| import org.apache.james.mime4j.dom.field.ContentLengthField; |
| import org.apache.james.mime4j.dom.field.ContentLocationField; |
| import org.apache.james.mime4j.dom.field.ContentMD5Field; |
| import org.apache.james.mime4j.dom.field.ContentTransferEncodingField; |
| import org.apache.james.mime4j.dom.field.ContentTypeField; |
| import org.apache.james.mime4j.dom.field.DateTimeField; |
| import org.apache.james.mime4j.dom.field.FieldName; |
| import org.apache.james.mime4j.dom.field.MailboxField; |
| import org.apache.james.mime4j.dom.field.MailboxListField; |
| import org.apache.james.mime4j.dom.field.MimeVersionField; |
| import org.apache.james.mime4j.dom.field.ParsedField; |
| import org.apache.james.mime4j.dom.field.UnstructuredField; |
| import org.apache.james.mime4j.stream.Field; |
| import org.apache.james.mime4j.stream.RawField; |
| import org.apache.james.mime4j.stream.RawFieldParser; |
| import org.apache.james.mime4j.util.ByteSequence; |
| import org.apache.james.mime4j.util.ContentUtil; |
| |
| /** |
| * Lenient implementation of the {@link FieldParser} interface with a high degree of tolerance |
| * to non-severe MIME field format violations. |
| */ |
| public class LenientFieldParser extends DelegatingFieldParser { |
| |
| private static final FieldParser<ParsedField> PARSER = new LenientFieldParser(); |
| |
| /** |
| * Gets the default instance of this class. |
| * |
| * @return the default instance |
| */ |
| public static FieldParser<ParsedField> getParser() { |
| return PARSER; |
| } |
| |
| /** |
| * Parses the given byte sequence and returns an instance of the {@link ParsedField} class. |
| * The type of the class returned depends on the field name; see {@link #parse(String)} for |
| * a table of field names and their corresponding classes. |
| * |
| * @param raw the bytes to parse. |
| * @param monitor decoding monitor used while parsing/decoding. |
| * @return a parsed field. |
| * @throws MimeException if the raw string cannot be split into field name and body. |
| */ |
| public static ParsedField parse( |
| final ByteSequence raw, |
| final DecodeMonitor monitor) throws MimeException { |
| Field rawField = RawFieldParser.DEFAULT.parseField(raw); |
| return PARSER.parse(rawField, monitor); |
| } |
| |
| /** |
| * Parses the given string and returns an instance of the <code>Field</code> class. |
| * The type of the class returned depends on the field name. |
| * |
| * @param rawStr the string to parse. |
| * @param monitor a DecodeMonitor object used while parsing/decoding. |
| * @return a <code>ParsedField</code> instance. |
| * @throws MimeException if the raw string cannot be split into field name and body. |
| */ |
| public static ParsedField parse( |
| final String rawStr, |
| final DecodeMonitor monitor) throws MimeException { |
| ByteSequence raw = ContentUtil.encode(rawStr); |
| RawField rawField = RawFieldParser.DEFAULT.parseField(raw); |
| // Do not retain the original raw representation as the field |
| // may require folding |
| return PARSER.parse(rawField, monitor); |
| } |
| |
| /** |
| * <p> |
| * Parses the given string and returns an instance of the {@link ParsedField} class. |
| * The type of the class returned depends on the field name: |
| * </p> |
| * <table summary="Field names and corresponding classes"> |
| * <tr><th>Class returned</th><th>Field names</th></tr> |
| * <tr><td>{@link ContentTypeField}</td><td>Content-Type</td></tr> |
| * <tr><td>{@link ContentLengthField}</td><td>Content-Length</td></tr> |
| * <tr><td>{@link ContentTransferEncodingField}</td><td>Content-Transfer-Encoding</td></tr> |
| * <tr><td>{@link ContentDispositionField}</td><td>Content-Disposition</td></tr> |
| * <tr><td>{@link ContentDescriptionField}</td><td>Content-Description</td></tr> |
| * <tr><td>{@link ContentIdField}</td><td>Content-ID</td></tr> |
| * <tr><td>{@link ContentMD5Field}</td><td>Content-MD5</td></tr> |
| * <tr><td>{@link ContentLanguageField}</td><td>Content-Language</td></tr> |
| * <tr><td>{@link ContentLocationField}</td><td>Content-Location</td></tr> |
| * <tr><td>{@link MimeVersionField}</td><td>MIME-Version</td></tr> |
| * <tr><td>{@link DateTimeField}</td><td>Date, Resent-Date</td></tr> |
| * <tr><td>{@link MailboxField}</td><td>Sender, Resent-Sender</td></tr> |
| * <tr><td>{@link MailboxListField}</td><td>From, Resent-From</td></tr> |
| * <tr><td>{@link AddressListField}</td><td>To, Cc, Bcc, Reply-To, Resent-To, Resent-Cc, Resent-Bcc</td></tr> |
| * <tr><td>{@link UnstructuredField}</td><td>Subject and others</td></tr> |
| * </table> |
| * |
| * @param rawStr the string to parse. |
| * @return a parsed field. |
| * @throws MimeException if the raw string cannot be split into field name and body. |
| */ |
| public static ParsedField parse(final String rawStr) throws MimeException { |
| return parse(rawStr, DecodeMonitor.SILENT); |
| } |
| |
| public LenientFieldParser() { |
| super(UnstructuredFieldImpl.PARSER); |
| setFieldParser(FieldName.CONTENT_TYPE, |
| ContentTypeFieldLenientImpl.PARSER); // lenient |
| setFieldParser(FieldName.CONTENT_LENGTH, |
| ContentLengthFieldImpl.PARSER); // default |
| setFieldParser(FieldName.CONTENT_TRANSFER_ENCODING, |
| ContentTransferEncodingFieldImpl.PARSER); // default |
| setFieldParser(FieldName.CONTENT_DISPOSITION, |
| ContentDispositionFieldLenientImpl.PARSER); // lenient |
| setFieldParser(FieldName.CONTENT_ID, |
| ContentIdFieldImpl.PARSER); // default |
| setFieldParser(FieldName.CONTENT_MD5, |
| ContentMD5FieldImpl.PARSER); // default |
| setFieldParser(FieldName.CONTENT_DESCRIPTION, |
| ContentDescriptionFieldImpl.PARSER); // default |
| setFieldParser(FieldName.CONTENT_LANGUAGE, |
| ContentLanguageFieldLenientImpl.PARSER); // lenient |
| setFieldParser(FieldName.CONTENT_LOCATION, |
| ContentLocationFieldLenientImpl.PARSER); // lenient |
| setFieldParser(FieldName.MIME_VERSION, |
| MimeVersionFieldImpl.PARSER); // lenient |
| |
| FieldParser<DateTimeField> dateTimeParser = DateTimeFieldLenientImpl.PARSER; |
| setFieldParser(FieldName.DATE, dateTimeParser); |
| setFieldParser(FieldName.RESENT_DATE, dateTimeParser); |
| |
| FieldParser<MailboxListField> mailboxListParser = MailboxListFieldLenientImpl.PARSER; |
| setFieldParser(FieldName.FROM, mailboxListParser); |
| setFieldParser(FieldName.RESENT_FROM, mailboxListParser); |
| |
| FieldParser<MailboxField> mailboxParser = MailboxFieldLenientImpl.PARSER; |
| setFieldParser(FieldName.SENDER, mailboxParser); |
| setFieldParser(FieldName.RESENT_SENDER, mailboxParser); |
| |
| FieldParser<AddressListField> addressListParser = AddressListFieldLenientImpl.PARSER; |
| setFieldParser(FieldName.TO, addressListParser); |
| setFieldParser(FieldName.RESENT_TO, addressListParser); |
| setFieldParser(FieldName.CC, addressListParser); |
| setFieldParser(FieldName.RESENT_CC, addressListParser); |
| setFieldParser(FieldName.BCC, addressListParser); |
| setFieldParser(FieldName.RESENT_BCC, addressListParser); |
| setFieldParser(FieldName.REPLY_TO, addressListParser); |
| } |
| |
| } |