eu.smeny.jpapercut.smtp.Processor.java Source code

Java tutorial

Introduction

Here is the source code for eu.smeny.jpapercut.smtp.Processor.java

Source

/*
 *  Processor
 *
 *  [C#]   Papercut  - Copyright  2008-2012 Ken Robertson
 *  [Java] JPapercut - Copyright  2014      Stphane Meny
 *
 *  Licensed 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 eu.smeny.jpapercut.smtp;

import static org.apache.commons.lang3.StringUtils.isEmpty;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import eu.smeny.jpapercut.smtp.command.CommandEnum;
import eu.smeny.jpapercut.smtp.command.CommandLine;
import eu.smeny.jpapercut.smtp.command.handler.Handler;

public class Processor {

    private static final String DEFAULT_ENCODING = "US-ASCII";
    private static final String SPACE = " ";

    /**
     * The connection used for this processing.
     */
    private Connection connection;
    /**
     * Indicates if the processor is waiting for command, else expects data.
     */
    private boolean waitingForData;
    /**
     * Logger used in this class.
     */
    private final Logger logger = LogManager.getLogger(getClass());

    public Processor(Connection connection) {
        this.connection = connection;
        waitingForData = true;
    }

    public void processData(ByteArrayOutputStream data) {
        // Checks if we are waiting for data, else we process data as a command
        if (waitingForData) {

        } else {
            // Waiting for a command
            CommandLine commandLine = decodeCommandLine(data);
            String command = commandLine.getCommand();
            if (isEmpty(command)) {
                // Impossible to read command, send an error to client
                sendCommandError();
            } else {
                processCommandLine(commandLine);
            }
        }
    }

    private void sendCommandError() {
        connection.send("500 Command not recognized");
    }

    private CommandLine decodeCommandLine(ByteArrayOutputStream data) {
        CommandLine commandLine = new CommandLine();
        try {
            String lineReceived = data.toString(DEFAULT_ENCODING);
            int commandEnd = lineReceived.indexOf(SPACE);
            if (commandEnd > 0) {
                String command = lineReceived.substring(0, commandEnd).toUpperCase();
                String parameter = lineReceived.substring(commandEnd);
                commandLine.setCommand(command);
                commandLine.setParameter(parameter);
            }
        } catch (UnsupportedEncodingException uee) {
            logger.error("Error while encoding data into command", uee);
        }
        return commandLine;
    }

    private void processCommandLine(CommandLine commandLine) {
        String command = commandLine.getCommand();

        CommandEnum commandEnum;
        try {
            commandEnum = Enum.valueOf(CommandEnum.class, command);
        } catch (IllegalArgumentException iae) {
            // Command is invalid
            logger.error("Error while retrieving SMTP command " + command, iae);
            commandEnum = CommandEnum.UNKNOWN;
        }

        Handler handler = commandEnum.getHandler();
        handler.setConnection(connection);
        handler.setLine(commandLine);
        handler.execute();
    }

}