/****************************************************************
* 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.stream;
import java.util.HashMap;
import java.util.Map;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.codec.DecodeMonitor;
import org.apache.james.mime4j.util.MimeUtil;
/**
* Encapsulates the values of the MIME-specific header fields
* (which starts with Parses a complex field value into a map of key/value pairs. You may
* use this, for example, to parse a definition like
* Content-
).
*/
public class DefaultBodyDescriptor implements MutableBodyDescriptor {
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 DecodeMonitor monitor;
private String mediaType = DEFAULT_MEDIA_TYPE;
private String subType = DEFAULT_SUB_TYPE;
private String mimeType = DEFAULT_MIME_TYPE;
private String boundary = null;
private String charset = US_ASCII;
private String transferEncoding = "7bit";
private MapBodyDescriptor
instance.
*/
public DefaultBodyDescriptor() {
this(null, null);
}
/**
* Creates a new BodyDescriptor
instance.
*
* @param parent the descriptor of the parent or null
if this
* is the root descriptor.
*/
public DefaultBodyDescriptor(final BodyDescriptor parent, final DecodeMonitor monitor) {
if (parent != null && MimeUtil.isSameMimeType("multipart/digest", parent.getMimeType())) {
this.mimeType = EMAIL_MESSAGE_MIME_TYPE;
this.subType = SUB_TYPE_EMAIL;
this.mediaType = MEDIA_TYPE_MESSAGE;
} else {
this.mimeType = DEFAULT_MIME_TYPE;
this.subType = DEFAULT_SUB_TYPE;
this.mediaType = DEFAULT_MEDIA_TYPE;
}
this.monitor = monitor != null ? monitor : DecodeMonitor.SILENT;
}
protected DecodeMonitor getDecodeMonitor() {
return monitor;
}
public MutableBodyDescriptor newChild() {
return new DefaultBodyDescriptor(this, getDecodeMonitor());
}
/**
* Should be called for each Content-
header field of
* a MIME message or part.
*
* @param field the MIME field.
*/
public void addField(RawField field) throws MimeException {
String name = field.getName();
String value = field.getBody();
name = name.trim().toLowerCase();
if (name.equals("content-transfer-encoding") && !contentTransferEncSet) {
contentTransferEncSet = true;
value = value.trim().toLowerCase();
if (value.length() > 0) {
transferEncoding = value;
}
} else if (name.equals("content-length") && contentLength == -1) {
try {
contentLength = Long.parseLong(value.trim());
} catch (NumberFormatException e) {
if (monitor.warn("Invalid content length: " + value,
"ignoring Content-Length header")) {
throw new MimeException("Invalid Content-Length header: " + value);
}
}
} else if (name.equals("content-type") && !contentTypeSet) {
parseContentType(value);
}
}
private void parseContentType(String value) throws MimeException {
contentTypeSet = true;
Map
* text/plain; charset=UTF-8; boundary=foobar
*
* The above example would return a map with the keys "", "charset",
* and "boundary", and the values "text/plain", "UTF-8", and "foobar".
*
* Header value will be unfolded and excess white space trimmed. *
* @param pValue The field value to parse. * @return The result map; use the key "" to retrieve the first value. */ public static Map