blob: 97239d021ffd3175f3d960c21770c86dcd00f523 [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.postage.mail;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Pattern;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.james.postage.PostageRunner;
import org.apache.james.postage.PostageRuntimeException;
import org.apache.james.postage.classloading.CachedInstanceFactory;
import org.apache.james.postage.result.MailProcessingRecord;
/**
* helps matching, analysing and validating result mails and sent test mails
*/
public class MailMatchingUtils {
private static Log log = LogFactory.getLog(MailMatchingUtils.class);
/**
* if this mail was created by postage, whatever run - but by startup check
*/
public static boolean isPostageStartupCheckMail(MimeMessage message) {
String headerValue = getMailIdHeader(message);
return HeaderConstants.JAMES_POSTAGE_STARTUPCHECK_HEADER_ID.equals(headerValue);
}
/**
* if this mail was created by postage, whatever run - but not by startup check
*/
public static boolean isPostageTestMail(MimeMessage message) {
return isPostageMail(message) && !isPostageStartupCheckMail(message);
}
/**
* if this mail was created by postage, whatever run - if startup check or live test
*/
public static boolean isPostageMail(MimeMessage message) {
return null != getUniqueHeader(message, HeaderConstants.JAMES_POSTAGE_HEADER);
}
public static boolean isPostageIdHeaderPresent(MimeMessage message) {
return null != getMailIdHeader(message);
}
public static String getMailIdHeader(MimeMessage message) {
return getUniqueHeader(message, HeaderConstants.MAIL_ID_HEADER);
}
/**
* if this mail was created by the currently running postage scenario - not by
* any of those before.
*/
public static boolean isCurrentRunnerMail(MimeMessage message) {
String headerValue = getMailIdHeader(message);
return headerValue != null && headerValue.startsWith(PostageRunner.getMessageIdPrefix());
}
public static boolean matchHeader(MimeMessage message, String header, String valueRegex) {
return Pattern.matches(valueRegex, getUniqueHeader(message, header));
}
public static String getUniqueHeader(MimeMessage message, String header) {
String[] idHeaders;
try {
idHeaders = message.getHeader(header);
} catch (MessagingException e) {
throw new PostageRuntimeException(e);
}
if (idHeaders != null && idHeaders.length > 0) {
return idHeaders[0]; // there should be exactly one.
}
return null;
}
public static boolean isMatchCandidate(MimeMessage message) {
try {
if (!isPostageIdHeaderPresent(message)) {
if (isPostageMail(message)) {
log.warn(HeaderConstants.MAIL_ID_HEADER + " header is missing from James test mail");
}
else log.info("skipping non-postage mail. remains on server. subject was: " + message.getSubject());
return false;
}
} catch (MessagingException e) {
log.info("failed to get mail subject for logging. remains on server. mails might be corrupt.");
return false;
}
if (MailMatchingUtils.isPostageStartupCheckMail(message)) return false;
return true;
}
public static boolean validateMail(MimeMessage message, MailProcessingRecord mailProcessingRecord) {
String classname = getUniqueHeader(message, HeaderConstants.JAMES_POSTAGE_VALIDATORCLASSNAME_HEADER);
MailValidator validator = (MailValidator)CachedInstanceFactory.createInstance(classname);
if (validator == null) return false;
boolean isValid = validator.validate(message, mailProcessingRecord);
if (isValid) mailProcessingRecord.setValid();
else log.warn("failed to validate mail");
return isValid;
}
public static MimeMultipart convertToMimeMultipart(MimeMessage message) {
try {
return new MimeMultipart(message.getDataHandler().getDataSource());
} catch (MessagingException e) {
throw new RuntimeException("could not convert MimeMessage to MimeMultipart", e);
}
}
public static int getMimePartSize(MimeMultipart parts, String mimeType) {
if (parts != null) {
try {
for (int i = 0; i < parts.getCount(); i++) {
BodyPart bodyPart = parts.getBodyPart(i);
if (bodyPart.getContentType().startsWith(mimeType)) {
try {
Object content = bodyPart.getContent();
if (content instanceof InputStream) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
IOUtils.copy(((InputStream) content), os);
return os.size();
} else if (content instanceof String) {
return ((String) content).length();
} else {
throw new IllegalStateException("Unsupported content: "+content.getClass().toString());
}
} catch (IOException e) {
throw new IllegalStateException("Unexpected IOException in getContent()");
}
}
}
} catch (MessagingException e) {
log.info("failed to process body parts.", e);
}
}
return 0;
}
}