Skip to content
Permalink
Browse files
MIME4J-302 Use lowercase when looking up known headers
An optimization implemented in MaximalBodyDescriptor aims at reducing the costs of toLowerCase calls: upon known header names lookup the lowercase version of the field instead of the normal version to benefit optimizations (calling toLowerCase on a lowerCase string do not do allocation, it just iterates String content). It might be worth generalizing it.
  • Loading branch information
chibenwa committed Jun 18, 2021
1 parent a7a860d commit 128fdc383d39e84958ec3bf39a145c83eb3c93a8
Showing 6 changed files with 47 additions and 32 deletions.
@@ -442,7 +442,7 @@ public Builder setBody(byte[] bin, String mimeType) throws IOException {
* @return the identifier of this message.
*/
public String getMessageId() {
Field field = obtainField(FieldName.MESSAGE_ID);
Field field = obtainField(FieldName.MESSAGE_ID_LOWERCASE);
return field != null ? field.getBody() : null;
}

@@ -484,7 +484,7 @@ public Builder setMessageId(String messageId) {
* @return the subject of this message.
*/
public String getSubject() {
UnstructuredField field = obtainField(FieldName.SUBJECT);
UnstructuredField field = obtainField(FieldName.SUBJECT_LOWERCASE);
return field != null ? field.getValue() : null;
}

@@ -513,7 +513,7 @@ public Builder setSubject(String subject) {
* @return the date of this message.
*/
public Date getDate() {
DateTimeField field = obtainField(FieldName.DATE);
DateTimeField field = obtainField(FieldName.DATE_LOWERCASE);
return field != null ? field.getDate() : null;
}

@@ -558,7 +558,7 @@ public Builder setDate(Date date, TimeZone zone) {
* @return the sender of this message.
*/
public Mailbox getSender() {
return getMailbox(FieldName.SENDER);
return getMailbox(FieldName.SENDER_LOWERCASE);
}

/**
@@ -593,7 +593,7 @@ public Builder setSender(String sender) throws ParseException {
* @return value of the from field of this message.
*/
public MailboxList getFrom() {
return getMailboxList(FieldName.FROM);
return getMailboxList(FieldName.FROM_LOWERCASE);
}

/**
@@ -664,7 +664,7 @@ public Builder setFrom(Collection<Mailbox> from) {
* @return value of the to field of this message.
*/
public AddressList getTo() {
return getAddressList(FieldName.TO);
return getAddressList(FieldName.TO_LOWERCASE);
}

/**
@@ -735,7 +735,7 @@ public Builder setTo(Collection<? extends Address> to) {
* @return value of the cc field of this message.
*/
public AddressList getCc() {
return getAddressList(FieldName.CC);
return getAddressList(FieldName.CC_LOWERCASE);
}

/**
@@ -782,7 +782,7 @@ public Builder setCc(Collection<? extends Address> cc) {
* @return value of the bcc field of this message.
*/
public AddressList getBcc() {
return getAddressList(FieldName.BCC);
return getAddressList(FieldName.BCC_LOWERCASE);
}

/**
@@ -829,7 +829,7 @@ public Builder setBcc(Collection<? extends Address> bcc) {
* @return value of the reply to field of this message.
*/
public AddressList getReplyTo() {
return getAddressList(FieldName.REPLY_TO);
return getAddressList(FieldName.REPLY_TO_LOWERCASE);
}

/**
@@ -902,7 +902,7 @@ public Message build() {
MessageImpl message = new MessageImpl();
HeaderImpl header = new HeaderImpl();
message.setHeader(header);
if (!containsField(FieldName.MIME_VERSION)) {
if (!containsField(FieldName.MIME_VERSION_LOWERCASE)) {
header.setField(Fields.version("1.0"));
}
for (Field field : getFields()) {
@@ -19,32 +19,47 @@

package org.apache.james.mime4j.dom.field;

import java.util.Locale;

/**
* Constants for common header field names.
*/
public class FieldName {

public static final String CONTENT_TYPE = "Content-Type";
public static final String CONTENT_TYPE_LOWERCASE = CONTENT_TYPE.toLowerCase(Locale.US);
public static final String CONTENT_LENGTH = "Content-Length";
public static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
public static final String CONTENT_TRANSFER_ENCODING_LOWERCASE = CONTENT_TRANSFER_ENCODING.toLowerCase(Locale.US);
public static final String CONTENT_DISPOSITION = "Content-Disposition";
public static final String CONTENT_DISPOSITION_LOWERCASE = CONTENT_DISPOSITION.toLowerCase(Locale.US);
public static final String CONTENT_ID = "Content-ID";
public static final String CONTENT_MD5 = "Content-MD5";
public static final String CONTENT_DESCRIPTION = "Content-Description";
public static final String CONTENT_LANGUAGE = "Content-Language";
public static final String CONTENT_LOCATION = "Content-Location";

public static final String MIME_VERSION = "MIME-Version";
public static final String MIME_VERSION_LOWERCASE = MIME_VERSION.toLowerCase(Locale.US);
public static final String DATE = "Date";
public static final String DATE_LOWERCASE = DATE.toLowerCase(Locale.US);
public static final String MESSAGE_ID = "Message-ID";
public static final String MESSAGE_ID_LOWERCASE = MESSAGE_ID.toLowerCase(Locale.US);
public static final String SUBJECT = "Subject";
public static final String SUBJECT_LOWERCASE = SUBJECT.toLowerCase(Locale.US);

public static final String FROM = "From";
public static final String FROM_LOWERCASE = FROM.toLowerCase(Locale.US);
public static final String SENDER = "Sender";
public static final String SENDER_LOWERCASE = SENDER.toLowerCase(Locale.US);
public static final String TO = "To";
public static final String TO_LOWERCASE = TO.toLowerCase(Locale.US);
public static final String CC = "Cc";
public static final String CC_LOWERCASE = CC.toLowerCase(Locale.US);
public static final String BCC = "Bcc";
public static final String BCC_LOWERCASE = BCC.toLowerCase(Locale.US);
public static final String REPLY_TO = "Reply-To";
public static final String REPLY_TO_LOWERCASE = REPLY_TO.toLowerCase(Locale.US);

public static final String RESENT_DATE = "Resent-Date";

@@ -256,7 +256,7 @@ public <F extends ParsedField> F obtainField(String fieldName) {
* type has been set.
*/
public String getMimeType() {
ContentTypeField field = obtainField(FieldName.CONTENT_TYPE);
ContentTypeField field = obtainField(FieldName.CONTENT_TYPE_LOWERCASE);
return field != null ? field.getMimeType() : null;
}

@@ -267,7 +267,7 @@ public String getMimeType() {
* type has been set.
*/
public String getCharset() {
ContentTypeField field = obtainField(FieldName.CONTENT_TYPE);
ContentTypeField field = obtainField(FieldName.CONTENT_TYPE_LOWERCASE);
return field != null ? field.getCharset() : null;
}

@@ -293,7 +293,7 @@ public AbstractEntityBuilder setContentType(String mimeType, NameValuePair... pa
* @return the transfer encoding.
*/
public String getContentTransferEncoding() {
ContentTransferEncodingField field = obtainField(FieldName.CONTENT_TRANSFER_ENCODING);
ContentTransferEncodingField field = obtainField(FieldName.CONTENT_TRANSFER_ENCODING_LOWERCASE);
return field != null ? field.getEncoding() : null;
}

@@ -319,7 +319,7 @@ public AbstractEntityBuilder setContentTransferEncoding(String contentTransferEn
* type has been set.
*/
public String getDispositionType() {
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION_LOWERCASE);
return field != null ? field.getDispositionType() : null;
}

@@ -428,7 +428,7 @@ public AbstractEntityBuilder setContentDisposition(String dispositionType, Strin
* <code>null</code> if the filename has not been set.
*/
public String getFilename() {
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION_LOWERCASE);
return field != null ? field.getFilename() : null;
}

@@ -439,7 +439,7 @@ public String getFilename() {
* <code>-1</code> if the filename has not been set.
*/
public long getSize() {
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION_LOWERCASE);
return field != null ? field.getSize() : -1;
}

@@ -450,7 +450,7 @@ public long getSize() {
* <code>null</code> if the filename has not been set.
*/
public Date getCreationDate() {
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION_LOWERCASE);
return field != null ? field.getCreationDate() : null;
}

@@ -461,7 +461,7 @@ public Date getCreationDate() {
* <code>null</code> if the filename has not been set.
*/
public Date getModificationDate() {
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION_LOWERCASE);
return field != null ? field.getModificationDate() : null;
}

@@ -472,7 +472,7 @@ public Date getModificationDate() {
* <code>null</code> if the filename has not been set.
*/
public Date getReadDate() {
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION);
ContentDispositionField field = obtainField(FieldName.CONTENT_DISPOSITION_LOWERCASE);
return field != null ? field.getReadDate() : null;
}

@@ -126,12 +126,12 @@ public Body removeBody() {
public String getMimeType() {
ContentTypeField childType = getContentTypeField();
Entity parent = getParent();
ContentTypeField parentType = parent != null ? (ContentTypeField) (parent).getHeader().getField(FieldName.CONTENT_TYPE) : null;
ContentTypeField parentType = parent != null ? (ContentTypeField) (parent).getHeader().getField(FieldName.CONTENT_TYPE_LOWERCASE) : null;
return calcMimeType(childType, parentType);
}

private ContentTypeField getContentTypeField() {
return (ContentTypeField) getHeader().getField(FieldName.CONTENT_TYPE);
return (ContentTypeField) getHeader().getField(FieldName.CONTENT_TYPE_LOWERCASE);
}

/**
@@ -140,7 +140,7 @@ private ContentTypeField getContentTypeField() {
* @return the MIME character set encoding.
*/
public String getCharset() {
return calcCharset((ContentTypeField) getHeader().getField(FieldName.CONTENT_TYPE));
return calcCharset((ContentTypeField) getHeader().getField(FieldName.CONTENT_TYPE_LOWERCASE));
}

/**
@@ -45,7 +45,7 @@ public abstract class AbstractMessage extends AbstractEntity implements Message
* @return the identifier of this message.
*/
public String getMessageId() {
Field field = obtainField(FieldName.MESSAGE_ID);
Field field = obtainField(FieldName.MESSAGE_ID_LOWERCASE);
if (field == null)
return null;

@@ -59,7 +59,7 @@ public String getMessageId() {
* @return the subject of this message.
*/
public String getSubject() {
UnstructuredField field = obtainField(FieldName.SUBJECT);
UnstructuredField field = obtainField(FieldName.SUBJECT_LOWERCASE);
if (field == null)
return null;

@@ -73,7 +73,7 @@ public String getSubject() {
* @return the date of this message.
*/
public Date getDate() {
DateTimeField dateField = obtainField(FieldName.DATE);
DateTimeField dateField = obtainField(FieldName.DATE_LOWERCASE);
if (dateField == null)
return null;

@@ -88,7 +88,7 @@ public Date getDate() {
* @return the sender of this message.
*/
public Mailbox getSender() {
return getMailbox(FieldName.SENDER);
return getMailbox(FieldName.SENDER_LOWERCASE);
}

/**
@@ -99,7 +99,7 @@ public Mailbox getSender() {
* @return value of the from field of this message.
*/
public MailboxList getFrom() {
return getMailboxList(FieldName.FROM);
return getMailboxList(FieldName.FROM_LOWERCASE);
}

/**
@@ -110,7 +110,7 @@ public MailboxList getFrom() {
* @return value of the to field of this message.
*/
public AddressList getTo() {
return getAddressList(FieldName.TO);
return getAddressList(FieldName.TO_LOWERCASE);
}

/**
@@ -121,7 +121,7 @@ public AddressList getTo() {
* @return value of the cc field of this message.
*/
public AddressList getCc() {
return getAddressList(FieldName.CC);
return getAddressList(FieldName.CC_LOWERCASE);
}

/**
@@ -132,7 +132,7 @@ public AddressList getCc() {
* @return value of the bcc field of this message.
*/
public AddressList getBcc() {
return getAddressList(FieldName.BCC);
return getAddressList(FieldName.BCC_LOWERCASE);
}

/**
@@ -143,7 +143,7 @@ public AddressList getBcc() {
* @return value of the reply to field of this message.
*/
public AddressList getReplyTo() {
return getAddressList(FieldName.REPLY_TO);
return getAddressList(FieldName.REPLY_TO_LOWERCASE);
}

private Mailbox getMailbox(String fieldName) {
@@ -250,7 +250,7 @@ private ContentTypeField getContentType(Multipart multipart) {
"Missing header in parent entity");

ContentTypeField contentType = (ContentTypeField) header
.getField(FieldName.CONTENT_TYPE);
.getField(FieldName.CONTENT_TYPE_LOWERCASE);
if (contentType == null)
throw new IllegalArgumentException(
"Content-Type field not specified");

0 comments on commit 128fdc3

Please sign in to comment.