blob: e5e7500f05f0515f3884185ead5871cecafb775b [file] [log] [blame]
/****************************************************************
* 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);
}
}