All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.sleroy.junit.mail.server.MailSaver Maven / Gradle / Ivy

There is a newer version: 0.1.1
Show newest version
/*
 *
 */
package com.github.sleroy.junit.mail.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Observable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.sleroy.fakesmtp.core.ServerConfiguration;
import com.github.sleroy.fakesmtp.model.EmailModel;
import com.github.sleroy.junit.mail.server.events.NewMailEvent;
import com.github.sleroy.junit.mail.server.events.RejectedMailEvent;

/**
 * Saves emails and notifies components so they can refresh their views with new
 * data.
 *
 * @author Nilhcem
 * @since 1.0
 */
public final class MailSaver extends Observable implements MailSaverInterface {

    /** The Constant LOGGER. */
    protected static final Logger LOGGER = LoggerFactory.getLogger(MailSaver.class);

    /** The Constant LINE_SEPARATOR. */
    private static final String LINE_SEPARATOR = System.getProperty("line.separator");

    /** The Constant SUBJECT_PATTERN. */
    // This can be a static variable since it is Thread Safe
    private static final Pattern SUBJECT_PATTERN = Pattern.compile("^Subject: (.*)$");

    protected Charset storageCharSet;

    /** The date format. */
    protected final SimpleDateFormat dateFormat = new SimpleDateFormat("ddMMyyhhmmssSSS");

    private final ServerConfiguration serverConfiguration;

    /**
     * Instantiates a new mail saver.
     *
     * @param serverConfiguration
     *            the server configuration
     */
    public MailSaver(final ServerConfiguration serverConfiguration) {

	this.serverConfiguration = serverConfiguration;
	storageCharSet = serverConfiguration.getStorageCharset();
	Validate.notNull(serverConfiguration);
	Validate.notNull(storageCharSet);

    }

    /**
     * Converts an {@code InputStream} into a {@code String} object.
     * 

* The method will not copy the first 4 lines of the input stream.
* These 4 lines are SubEtha SMTP additional information. *

* * @param is * the InputStream to be converted. * @return the converted string object, containing data from the InputStream * passed in parameters. */ private String convertStreamToString(final InputStream is) { final long lineNbToStartCopy = 4; // Do not copy the first 4 lines // (received part) final BufferedReader reader = new BufferedReader(new InputStreamReader(is, storageCharSet)); final StringBuilder sb = new StringBuilder(); String line; long lineNb = 0; try { while ((line = reader.readLine()) != null) { if (++lineNb > lineNbToStartCopy) { sb.append(line).append(LINE_SEPARATOR); } } } catch (final IOException e) { LOGGER.error("Could not convert the stream.", e); } return sb.toString(); } /** * Returns a lock object. *

* This lock will be used to make the application thread-safe, and avoid * receiving and deleting emails in the same time. *

* * @return a lock object (which is actually the current instance of the * {@code MailSaver} object). */ public Object getLock() { return this; } /** * Gets the subject from the email data passed in parameters. * * @param data * a string representing the email content. * @return the subject of the email, or an empty subject if not found. */ private String getSubjectFromStr(final String data) { try { final BufferedReader reader = new BufferedReader(new StringReader(data)); String line; while ((line = reader.readLine()) != null) { final Matcher matcher = SUBJECT_PATTERN.matcher(line); if (matcher.matches()) { return matcher.group(1); } } } catch (final IOException e) { LOGGER.error("Cannot obtain the subject", e); } return ""; } /** * Checks if is matching relay domains. * * @param to * the to * @param relayDomains * the relay domains * @return true, if is matching relay domains */ private boolean isMatchingRelayDomains(final String to, final List relayDomains) { if (relayDomains != null) { LOGGER.debug("Relay domains are defined : ", relayDomains); boolean matches = false; for (final String domain : relayDomains) { if (to.endsWith(domain)) { LOGGER.debug("The domain is matching : ", domain); matches = true; break; } } if (!matches) { LOGGER.debug("Destination {} doesn't match relay domains", to); return false; } } else { LOGGER.debug("No relay domain has been defined, no filtering"); } return true; } /* * (non-Javadoc) * * @see * com.github.sleroy.junit.mail.server.MailSaverInterface#saveEmailAndNotify * (java. lang.String, java.lang.String, java.io.InputStream) */ @Override public void saveEmailAndNotify(final String from, final String to, final InputStream data) { final List relayDomains = serverConfiguration.getRelayDomains(); // We move everything that we can move outside the synchronized block to // limit the impact final EmailModel model = new EmailModel(); model.setFrom(from); model.setTo(to); final String mailContent = convertStreamToString(data); model.setSubject(getSubjectFromStr(mailContent)); model.setEmailStr(mailContent); model.setReceivedDate(new Date()); // Controls the relay domain if (!isMatchingRelayDomains(to, relayDomains)) { setChanged(); notifyObservers(new RejectedMailEvent(model)); return; } synchronized (getLock()) { setChanged(); notifyObservers(new NewMailEvent(model)); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy