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

org.bidib.jbidibc.netbidib.debug.NetBidibDebugClient Maven / Gradle / Ivy

package org.bidib.jbidibc.netbidib.debug;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.bidib.jbidibc.debug.DebugMessageReceiver;
import org.bidib.jbidibc.messages.ConnectionListener;
import org.bidib.jbidibc.messages.MessageReceiver;
import org.bidib.jbidibc.messages.exception.PortNotOpenedException;
import org.bidib.jbidibc.messages.utils.ThreadFactoryBuilder;
import org.bidib.jbidibc.netbidib.client.DefaultNetMessageHandler;
import org.bidib.jbidibc.netbidib.client.NetBidibClientPort;
import org.bidib.jbidibc.netbidib.client.NetBidibPort;
import org.bidib.jbidibc.netbidib.client.NetMessageHandler;
import org.bidib.jbidibc.netbidib.client.listener.NetBidibPortConnectionStatusListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NetBidibDebugClient implements NetBidibDebugClientInterface {

    private static final Logger LOGGER = LoggerFactory.getLogger(NetBidibDebugClient.class);

    private String connectedPortName;

    private InetAddress address;

    private int portNumber;

    private String protocol;

    private NetBidibPort port;

    private final DebugMessageReceiver messageReceiver;

    private NetMessageHandler netMessageHandler;

    private final ScheduledExecutorService portWorker =
        Executors
            .newScheduledThreadPool(1,
                new ThreadFactoryBuilder().setNameFormat("netBidibDebugPortWorkers-thread-%d").build());

    public NetBidibDebugClient(final DebugMessageReceiver debugMessageReceiver) {
        this.messageReceiver = debugMessageReceiver;

    }

    @Override
    public void open(String portName, final ConnectionListener connectionListener) throws PortNotOpenedException {

        LOGGER.info("Internal open port: {}", portName);

        String[] hostAndPort = portName.split(":");

        if (hostAndPort.length > 2) {
            // protocol provided
            protocol = hostAndPort[0];
            try {
                address = InetAddress.getByName(hostAndPort[1]);
            }
            catch (UnknownHostException ex) {
                throw new PortNotOpenedException("The provided host is not vaild.", hostAndPort[1]);
            }
            portNumber = Integer.parseInt(hostAndPort[2]);
        }
        else {
            protocol = "tcp";
            try {
                address = InetAddress.getByName(hostAndPort[0]);
            }
            catch (UnknownHostException ex) {
                throw new PortNotOpenedException("The provided host is not vaild.", hostAndPort[0]);
            }
            portNumber = Integer.parseInt(hostAndPort[1]);
        }

        this.connectedPortName = portName;

        LOGGER.info("Configured address: {}, portNumber: {}, protocol: {}", address, portNumber, protocol);

        final MessageReceiver messageReceiverDelegate = new MessageReceiver() {

            @Override
            public void cleanup() {

            }

            @Override
            public void receive(ByteArrayOutputStream data) {
                messageReceiver.processMessages(data);
            }
        };

        netMessageHandler =
            new DefaultNetMessageHandler(messageReceiverDelegate, address, portNumber, connectionListener);

        // open the port

        final CountDownLatch startupLock = new CountDownLatch(1);

        NetBidibPort netBidibPort;
        try {
            netBidibPort = new NetBidibClientPort(address, portNumber, netMessageHandler);
            netBidibPort.addConnectionStatusListener(new NetBidibPortConnectionStatusListener() {

                @Override
                public void opened() {
                    LOGGER.info("Opened with countDown latch.");
                    startupLock.countDown();

                    if (connectionListener != null) {
                        connectionListener.opened(connectedPortName);
                    }
                }

                @Override
                public void closed() {
                    LOGGER.info("The netBidib connection was closed.");

                    if (connectionListener != null) {
                        connectionListener.closed(connectedPortName);
                    }
                }

                @Override
                public void clientAccepted(String remoteAddress) {
                    LOGGER.info("Client accepted, remoteAddress: {}", remoteAddress);
                    // TODO Auto-generated method stub

                }
            });
            LOGGER.info("Prepare and start the port worker for netBidibPort: {}", netBidibPort);

            // prepare and start the port worker
            portWorker.submit(netBidibPort);
        }
        catch (IOException ex) {
            LOGGER.warn("Open netBidib port failed.", ex);

            throw new PortNotOpenedException("Open netBidib port failed.", ex.getMessage());
        }

        LOGGER.info("The netBidib port was opened: {}", netBidibPort);
        this.port = netBidibPort;
    }

    @Override
    public boolean isOpened() {
        return port != null;
    }

    @Override
    public void close() {

        LOGGER.info("Close the port.");

        if (port != null) {
            LOGGER.info("Stop the port.");
            final NetBidibPort portToClose = this.port;
            this.port = null;

            portToClose.stop();

            if (portWorker != null) {
                synchronized (portWorker) {
                    try {
                        portWorker.shutdown();
                        portWorker.awaitTermination(5000, TimeUnit.MILLISECONDS);
                    }
                    catch (InterruptedException ex) {
                        LOGGER.warn("Wait for termination of port worker failed.", ex);
                    }
                }
            }
        }
        else {
            LOGGER.info("No port to close available.");
        }
    }

    @Override
    public void send(byte[] data) {

        if (port != null) {

            try {
                port.send(data, address, portNumber);
            }
            catch (IOException ex) {
                LOGGER.warn("Send data to port failed.", ex);
            }
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy