HOME PCB
..MessageFactory.javaMessageService.javaMessageSession.javaMessageSessionImpl.javaQueueSendingThread.javaReceivingThread.javaSendObject.javaSendingThread.javaStandardReceivingThread.java
package Communication.Messages.Service;

import Common.Utils;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.util.concurrent.ConcurrentHashMap;

public abstract class MessageSession
{
    private final ConcurrentHashMap messageHandlers = new ConcurrentHashMap<>();

    public final ConcurrentHashMap properties = new ConcurrentHashMap<>();

    public abstract boolean isClosed();

    public abstract DataInputStream getReceiveStream() throws IOException;

    protected abstract void sendImpl(final Object o, final Object messageHandler, final Method send) throws IOException, InvocationTargetException, IllegalAccessException;

    public abstract InetSocketAddress getSocketAddress();

    private Object getMessageHandler(Object data) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        return this.getMessageHandler(data.getClass());
    }

    private Object getMessageHandler(Class data) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        return this.getMessageHandlerObject(MessageFactory.getInstance().getMessageHandlerClass(data));
    }

    private Object getMessageHandler(String name) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        return this.getMessageHandlerObject(MessageFactory.getInstance().getMessageHandlerClass(name));
    }

    private Object getMessageHandlerObject(Class c) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Object o;

        if ((o = this.messageHandlers.get(c)) == null)
        {
            o = c.getConstructor().newInstance();
            this.messageHandlers.put(c, o);
        }

        return o;
    }

    public final synchronized void send(Object o) throws IOException
    {
        try {
            final Object messageHandler = this.getMessageHandler(o);
            Method send = MessageFactory.getInstance().getReceiveMethod(messageHandler.getClass());
            this.sendImpl(o, messageHandler, send);
        } catch (NoSuchMethodException | InstantiationException | InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public final synchronized void send(Object... objs) throws IOException
    {
        for (Object o : objs) {
            this.send(o);
        }
    }

    public void receive() throws IOException
    {
        final DataInputStream dis;
        try
        {
            dis = this.getReceiveStream();
            byte[] messageNameBytes = new byte[dis.readInt()];
            dis.read(messageNameBytes);
            final String messageName = new String(messageNameBytes, Utils.getDefaultCharset());
            final Object messageHandler = this.getMessageHandler(messageName);
            new Thread(() -> {
                try
                {
                    MessageFactory.getInstance().getReceiveMethod(messageHandler.getClass()).invoke(messageHandler, dis, this);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }).start();
        }
        catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | InstantiationException e)
        {
            // should not occur
            throw new RuntimeException(e);
        }
    }
}