jcsp-master/src/main/java/jcsp/net2/Node.java

//////////////////////////////////////////////////////////////////////
//                                                                  //
//  JCSP ("CSP for Java") Libraries                                 //
//  Copyright (C) 1996-2018 Peter Welch, Paul Austin and Neil Brown //
//                2001-2004 Quickstone Technologies Limited         //
//                2005-2018 Kevin Chalmers                          //
//                                                                  //
//  You may use this work under the terms of either                 //
//  1. The Apache License, Version 2.0                              //
//  2. or (at your option), the GNU Lesser General Public License,  //
//       version 2.1 or greater.                                    //
//                                                                  //
//  Full licence texts are included in the LICENCE file with        //
//  this library.                                                   //
//                                                                  //
//  Author contacts: P.H.Welch@kent.ac.uk K.Chalmers@napier.ac.uk   //
//                                                                  //
//////////////////////////////////////////////////////////////////////

package jcsp.net2;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Date;

import jcsp.lang.AltingChannelInput;
import jcsp.net2.bns.BNS;
import jcsp.net2.cns.CNS;

/**
 * @author Kevin Chalmers
 */
public final class Node
{
    /**
     * 
     */
    private NodeID nodeID;

    /**
     * 
     */
    private boolean initialized = false;

    /**
     * 
     */
    private NodeKey nk;

    /**
     * 
     */
    private static Node instance = new Node();

    /**
     * 
     */
    public static Logger log = new Logger();

    /**
     * 
     */
    public static Logger err = new Logger();

    /**
     * @return The singleton instance of the Node
     */
    public static Node getInstance()
    {
        return instance;
    }

    /**
     * @return The NodeID of this Node
     */
    public NodeID getNodeID()
    {
        return this.nodeID;
    }

    /**
     * @param aNodeID
     */
    void setNodeID(NodeID aNodeID)
    {
        this.nodeID = aNodeID;
    }

    /**
     * 
     */
    private Node()
    {
        // Empty constructor
    }

    /**
     * @param addr
     * @return NodeKey for this Node
     * @throws JCSPNetworkException
     */
    public NodeKey init(NodeAddress addr)
        throws JCSPNetworkException
    {
        return this.init("", addr);
    }

    /**
     * @param name
     * @param addr
     * @return NodeKey for this Node
     * @throws JCSPNetworkException
     */
    public NodeKey init(String name, NodeAddress addr)
        throws JCSPNetworkException
    {
        Node.log.log(this.getClass(), "Node initialisation begun");
        if (this.initialized)
            throw new JCSPNetworkException("Node already initialised");
        this.initialized = true;
        LinkServer.start(addr);
        this.nodeID = new NodeID(name, addr);
        this.nk = new NodeKey();
        NodeAddress.installProtocol(addr.getProtocol(), addr.getProtocolID());
        Node.log.log(this.getClass(), "Node initialisation complete");
        return this.nk;
    }

    /**
     * @param factory
     * @return NodeKey for this Node
     * @throws JCSPNetworkException
     */
    public NodeKey init(NodeFactory factory)
        throws JCSPNetworkException
    {
        Node.log.log(this.getClass(), "Node initialisation begun");
        if (this.initialized)
            throw new JCSPNetworkException("Node already initialised");
        NodeAddress localAddr = factory.initNode(this);
        this.nodeID = new NodeID("", localAddr);
        this.initialized = true;
        this.nk = new NodeKey();
        Link toServer = LinkFactory.getLink(factory.cnsAddress);
        CNS.initialise(toServer.remoteID);
        BNS.initialise(toServer.remoteID);
        return this.nk;
    }

    /**
     * @return A channel to receive disconnect events on
     */
    public AltingChannelInput getLinkLostEventChannel()
    {
        return LinkManager.getInstance().getLinkLostEventChannel();
    }

    /**
     * @param stream
     */
    public void setLog(OutputStream stream)
    {
        log = new Logger(stream);
    }

    /**
     * @param stream
     */
    public void setErr(OutputStream stream)
    {
        err = new Logger(stream);
    }

    /**
     * @author Kevin Chalmers
     */
    public static class Logger
    {
        /**
         * 
         */
        private final PrintWriter logger;

        /**
         * 
         */
        Logger()
        {
            this.logger = null;
        }

        /**
         * @param stream
         */
        Logger(OutputStream stream)
        {
            this.logger = new PrintWriter(stream);
        }

        /**
         * @param clazz
         * @param message
         */
        public synchronized void log(Class clazz, String message)
        {
            if (this.logger == null)
                return;
            Date date = new Date(System.currentTimeMillis());
            try
            {
                this.logger.println("(" + date.toString() + ")-" + clazz.getName() + ":");
                this.logger.println("\t\"" + message + "\"");
                this.logger.flush();
            }
            catch (Exception e)
            {
                // Do nothing
            }
        }
    }
}
