blob: de8d5a2136f5a5a5ce1c25fbe686c2088fd63fca [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.message;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
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.ContentTypeField;
import org.apache.james.mime4j.dom.field.FieldName;
import org.apache.james.mime4j.dom.field.ParsedField;
import org.apache.james.mime4j.field.DefaultFieldParser;
import org.apache.james.mime4j.stream.BodyDescriptor;
import org.apache.james.mime4j.stream.BodyDescriptorBuilder;
import org.apache.james.mime4j.stream.Field;
import org.apache.james.mime4j.stream.RawField;
import org.apache.james.mime4j.util.MimeUtil;
/**
* Default {@link BodyDescriptorBuilder} implementation.
*/
public class DefaultBodyDescriptorBuilder implements BodyDescriptorBuilder {
private static final String CONTENT_TYPE = FieldName.CONTENT_TYPE.toLowerCase(Locale.US);
private static final String US_ASCII = "us-ascii";
private static final String SUB_TYPE_EMAIL = "rfc822";
private static final String MEDIA_TYPE_TEXT = "text";
private static final String MEDIA_TYPE_MESSAGE = "message";
private static final String EMAIL_MESSAGE_MIME_TYPE = MEDIA_TYPE_MESSAGE + "/" + SUB_TYPE_EMAIL;
private static final String DEFAULT_SUB_TYPE = "plain";
private static final String DEFAULT_MEDIA_TYPE = MEDIA_TYPE_TEXT;
private static final String DEFAULT_MIME_TYPE = DEFAULT_MEDIA_TYPE + "/" + DEFAULT_SUB_TYPE;
private final String parentMimeType;
private final DecodeMonitor monitor;
private final FieldParser<? extends ParsedField> fieldParser;
private final Map<String, ParsedField> fields;
/**
* Creates a new root <code>BodyDescriptor</code> instance.
*/
public DefaultBodyDescriptorBuilder() {
this(null);
}
public DefaultBodyDescriptorBuilder(final String parentMimeType) {
this(parentMimeType, null, null);
}
/**
* Creates a new <code>BodyDescriptor</code> instance.
*/
public DefaultBodyDescriptorBuilder(
final String parentMimeType,
final FieldParser<? extends ParsedField> fieldParser,
final DecodeMonitor monitor) {
super();
this.parentMimeType = parentMimeType;
this.fieldParser = fieldParser != null ? fieldParser : DefaultFieldParser.getParser();
this.monitor = monitor != null ? monitor : DecodeMonitor.SILENT;
this.fields = new HashMap<String, ParsedField>();
}
public void reset() {
fields.clear();
}
public Field addField(final RawField rawfield) throws MimeException {
ParsedField field = fieldParser.parse(rawfield, monitor);
String name = field.getNameLowerCase();
if (!fields.containsKey(name)) {
fields.put(name, field);
}
return field;
}
public BodyDescriptor build() {
String actualMimeType = null;
String actualMediaType = null;
String actualSubType = null;
String actualCharset = null;
String actualBoundary = null;
ContentTypeField contentTypeField = (ContentTypeField) fields.get(CONTENT_TYPE);
if (contentTypeField != null) {
actualMimeType = contentTypeField.getMimeType();
actualMediaType = contentTypeField.getMediaType();
actualSubType = contentTypeField.getSubType();
actualCharset = contentTypeField.getCharset();
actualBoundary = contentTypeField.getBoundary();
boolean multipart = actualMediaType != null && actualMediaType.equalsIgnoreCase("multipart");
if (multipart && actualBoundary == null) {
actualMimeType = null;
actualMediaType = null;
actualSubType = null;
}
}
if (actualMimeType == null) {
if (MimeUtil.isSameMimeType("multipart/digest", parentMimeType)) {
actualMimeType = EMAIL_MESSAGE_MIME_TYPE;
actualMediaType = MEDIA_TYPE_MESSAGE;
actualSubType = SUB_TYPE_EMAIL;
} else {
actualMimeType = DEFAULT_MIME_TYPE;
actualMediaType = DEFAULT_MEDIA_TYPE;
actualSubType = DEFAULT_SUB_TYPE;
}
}
if (actualCharset == null && MEDIA_TYPE_TEXT.equals(actualMediaType)) {
actualCharset = US_ASCII;
}
if (!MimeUtil.isMultipart(actualMimeType)) {
actualBoundary = null;
}
return new MaximalBodyDescriptor(
actualMimeType, actualMediaType, actualSubType, actualBoundary, actualCharset,
fields);
}
public BodyDescriptorBuilder newChild() {
String actualMimeType;
ContentTypeField contentTypeField = (ContentTypeField) fields.get(CONTENT_TYPE);
if (contentTypeField != null) {
actualMimeType = contentTypeField.getMimeType();
} else {
if (MimeUtil.isSameMimeType("multipart/digest", parentMimeType)) {
actualMimeType = EMAIL_MESSAGE_MIME_TYPE;
} else {
actualMimeType = DEFAULT_MIME_TYPE;
}
}
return new DefaultBodyDescriptorBuilder(actualMimeType, fieldParser, monitor);
}
}