org.rifidi.emulator.io.comm.ip.tcpserver.TCPServerCommunicationIncomingMessageHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.rifidi.emulator.io.comm.ip.tcpserver.TCPServerCommunicationIncomingMessageHandler.java

Source

/*
 *  @(#)TCPServerCommunicationIncomingMessageHandler.java
 *
 *  Created:   Sep 28, 2006
 *  Project:   RiFidi Emulator - A Software Simulation Tool for RFID Devices
 *              http://www.rifidi.org
 *              http://rifidi.sourceforge.net
 *  Copyright:   Pramari LLC and the Rifidi Project
 *  License:   Lesser GNU Public License (LGPL)
 *              http://www.opensource.org/licenses/lgpl-license.html
 */

package org.rifidi.emulator.io.comm.ip.tcpserver;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rifidi.emulator.common.DataBufferInterruptedException;
import org.rifidi.emulator.io.comm.streamreader.AbstractStreamReader;
import org.rifidi.emulator.io.protocol.ProtocolValidationException;

/**
 * A runnable which monitors for incoming messages from a
 * TCPServerCommunication's client and stores the them as they arrive. Runs
 * until the client socket is closed.
 * 
 * @author John Olender - john@pramari.com
 * @since <$INITIAL_VERSION$>
 * @version <$CURRENT_VERSION$>
 * 
 */
public class TCPServerCommunicationIncomingMessageHandler implements Runnable {

    /**
     * The logger for this class.
     */
    private static Log logger = LogFactory.getLog(TCPServerCommunicationIncomingMessageHandler.class);

    /**
     * The TCPServerCommunication this object is bound to.
     */
    private TCPServerCommunication hostCommunication;

    /**
     * The Abstract stream Reader class to use
     */
    @SuppressWarnings("unchecked")
    private Class readerClass;

    /**
     * Creates a TCPServerCommunicationIncomingMessageHandler which is bound to
     * the passed TCPServerCommunication. This constructor has default access so
     * that only tcpserver-package classes can create these.
     * 
     * It also takes in a class which implements the AbstractStreamReader class
     * that is used to parse the bytes on the input socket in a way required by
     * the specific RFID reader being emulated.
     * 
     * @param hostCommunication
     *            The TCPServerCommunication this object is bound to.
     * @param reader
     *            The AbstractStreamReader with an overridden read() method.
     */
    @SuppressWarnings("unchecked")
    public TCPServerCommunicationIncomingMessageHandler(TCPServerCommunication hostCommunication) {

        this.hostCommunication = hostCommunication;

        Class reader = hostCommunication.getAbstractStreamReader();

        Class[] interfaces = reader.getInterfaces();
        boolean interfaceFound = false;
        for (Class i : interfaces) {
            if (i.equals(AbstractStreamReader.class)) {
                interfaceFound = true;
            }
        }
        if (interfaceFound) {
            this.readerClass = reader;
        } else {
            logger.error("Expected class that implemets AbstractStreamReader, but got class of type: "
                    + reader.getClass());
            throw (new RuntimeException(
                    "Expected class that implemets AbstractStreamReader, but got class of type: "
                            + reader.getClass()));
        }
    }

    /**
     * The main logic of the monitor. Reads in data from the client socket until
     * the client socket is closed/disconnected.
     * 
     * @see java.lang.Runnable#run()
     */
    @SuppressWarnings("unchecked")
    public void run() {
        Socket clientSocket = this.hostCommunication.getClientSocket();

        /* Make a reader to get data from the client socket. */
        AbstractStreamReader socketIn = null;

        Constructor c = null;
        try {
            /* The class has to have a single paramater of type InputStream */
            c = readerClass.getConstructor(new Class[] { InputStream.class });
        } catch (SecurityException e1) {
            logger.error("Security exception while getting the Constructor\n" + e1.getMessage());
            throw (new RuntimeException("Security exception while getting constructor"));
        } catch (NoSuchMethodException e1) {
            logger.error("No such method exception while getting the constructor.  "
                    + "Make sure that the class has a signle paramater of type Input Stream\n " + e1.getMessage());
            throw (new RuntimeException("No such method exception while getting the constructor"));
        }

        try {
            socketIn = (AbstractStreamReader) c.newInstance(clientSocket.getInputStream());
        } catch (IllegalArgumentException e1) {
            logger.error("Arugment of type java.io.Reader expected, but not found\n " + e1.getMessage());
            throw (new RuntimeException("Arugment of type java.io.Reader expected, but not found"));
        } catch (InstantiationException e1) {
            logger.error("Instantion exception while instantiating a new bufferedreader\n " + e1.getMessage());
            throw (new RuntimeException("Instantion exception while instantiating a new bufferedreader"));
        } catch (IllegalAccessException e1) {
            logger.error("Illegal Access Exception while instantiating a new bufferedreader\n " + e1.getMessage());
            throw (new RuntimeException("Illegal Access Exception while instantiating a new bufferedreader\n"));
        } catch (InvocationTargetException e1) {
            logger.error(
                    "Invocation Target Exception while instantiating a new bufferedreader\n " + e1.getMessage());
            throw (new RuntimeException("Invocation Target Exception while instantiating a new bufferedreader\n"));
        } catch (IOException e1) {
            logger.error(
                    "IO exception while opening the input stelse return bytes.toArray();ream\n " + e1.getMessage());
            throw (new RuntimeException("IO exception while opening the input stream\n"));
        }

        /* Only proceed if we grabbed a valid reader */
        if (socketIn != null) {

            /* Variable to control reading. */
            boolean keepRunning = true;

            /* Read in while this connection is open. */
            while (keepRunning) {
                // synchronized (synch) {

                /* Some buffers to hold single line and whole message */
                byte[] buffer = null;

                /* Read lines into the buffer */
                if (socketIn != null) {

                    /* Read the first line in */
                    try {
                        buffer = socketIn.read();
                    } catch (IOException e) {
                        /* Drop the socket */
                        buffer = null;
                    }
                }

                /* Throw the received data into the received buffer */
                if (buffer != null) {
                    /* Grab the bytes of the received data */
                    /* Remove protocol before throwing in the buffer. */
                    try {

                        List<byte[]> listOfBytes = this.hostCommunication.getProtocol().removeProtocol(buffer);
                        for (byte[] b : listOfBytes) {

                            String message = this.hostCommunication.getLogFormatter().formatMessage(b);

                            this.hostCommunication.getConsoleLogger().info("<INPUT> " + message + "</INPUT>");

                            this.hostCommunication.getReceiveBuffer().addToBuffer(b);
                        }
                    } catch (DataBufferInterruptedException e) {
                        /* The DataBuffer has been interrupted, close client */
                        keepRunning = false;

                    } catch (ProtocolValidationException e) {
                        /*
                         * Received a malformed message, report to debug logs
                         */
                        logger.debug(e.getMessage());

                    }

                } else {
                    keepRunning = false;

                }
                // }

            } /* end: while(isDisconnected) */

            /* Socket disconnected/closed -- disconnect the communication. */
            this.hostCommunication.disconnect();

        } /* end: if(socketIn != null)... */

    }
}