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

org.bidib.wizard.mvc.main.controller.NewNodeReader Maven / Gradle / Ivy

There is a newer version: 2.0.0-M1
Show newest version
package org.bidib.wizard.mvc.main.controller;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.commons.collections4.CollectionUtils;
import org.bidib.jbidibc.core.node.RootNode;
import org.bidib.jbidibc.core.utils.ByteUtils;
import org.bidib.jbidibc.core.utils.NodeUtils;
import org.bidib.wizard.comm.Communication;
import org.bidib.wizard.comm.CommunicationFactory;
import org.bidib.wizard.locale.Resources;
import org.bidib.wizard.mvc.main.model.MainModel;
import org.bidib.wizard.mvc.main.model.Node;
import org.bidib.wizard.mvc.main.view.MainView;
import org.bidib.wizard.mvc.main.view.statusbar.StatusBar;
import org.bidib.wizard.mvc.postprocess.dccdevices.LocoDecoderInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class NewNodeReader implements Runnable {

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

    final private org.bidib.jbidibc.core.Node commNode;

    final private MainView view;

    final private Map newNodeCreatedThreadRegistry;

    private final MainModel model;

    private final MainController mainController;

    public NewNodeReader(MainController mainController, MainView view, final MainModel model,
        Map newNodeCreatedThreadRegistry, org.bidib.jbidibc.core.Node node) {
        commNode = node;
        this.view = view;
        this.newNodeCreatedThreadRegistry = newNodeCreatedThreadRegistry;
        this.model = model;
        this.mainController = mainController;
    }

    @Override
    public void run() {

        LOGGER.info("New node created in system: {}", commNode);
        final List nodesToEnable = new LinkedList();

        try {
            Thread.sleep(100);
        }
        catch (InterruptedException e) {
            LOGGER.warn("Sleep was interrupted.", e);
        }

        LOGGER.info("Start communication with new node: {}", commNode);

        try {
            // get the subnodes
            Communication communication = CommunicationFactory.getInstance();
            recursiveCreateSubNodes(communication, commNode, nodesToEnable);

            if (CollectionUtils.isNotEmpty(nodesToEnable)) {
                for (Node nodeToEnable : nodesToEnable) {
                    LOGGER.info("sysEnable node: {}", nodeToEnable);
                    try {
                        communication.enable(nodeToEnable.getNode());
                        LOGGER.info("sysEnable finished, node: {}", nodeToEnable);
                    }
                    catch (IllegalArgumentException ex) {
                        // thrown if the node is not available
                        LOGGER.warn("Enable new node failed: {}", nodeToEnable, ex);

                        nodeToEnable.setNodeHasError(true);

                        view.setStatusText(
                            String.format(Resources.getString(MainController.class, "new-node-with-error"), commNode),
                            StatusBar.DISPLAY_ERROR);
                    }
                }
            }
            else {
                LOGGER.warn("No new nodes to enable available.");
            }

            view.setStatusText(String.format(Resources.getString(MainController.class, "new-node-added"), commNode),
                StatusBar.DISPLAY_NORMAL);
        }
        catch (Exception ex) {
            LOGGER.warn("Get the new node and subnodes failed.", ex);
            view.setStatusText(
                String.format(Resources.getString(MainController.class, "new-node-with-error"), commNode),
                StatusBar.DISPLAY_ERROR);
        }

        synchronized (newNodeCreatedThreadRegistry) {
            LOGGER.info("The new node is registered in the system, remove registration thread from registry, node: {}",
                commNode);
            newNodeCreatedThreadRegistry.remove(commNode);
        }

        if (ByteUtils.arrayEquals(commNode.getAddr(), RootNode.ROOTNODE_ADDR)) {
            LOGGER.info("The root node was processed. Fire initial read of nodes finished.");

            // Use the AWT thread to initialize the locos
            Runnable worker = new Runnable() {

                @Override
                public void run() {
                    LOGGER.info("Start the LocoDecoderInitializer.");
                    try {
                        Collection nodes = model.getNodes();
                        if (CollectionUtils.isNotEmpty(nodes)) {
                            // search the command station nodes
                            List commandStations = new LinkedList();
                            for (Node currentNode : nodes) {

                                if (NodeUtils.hasCommandStationFunctions(currentNode.getUniqueId())) {
                                    LOGGER.info("Found a command station node: {}", currentNode);
                                    commandStations.add(currentNode);
                                }
                            }

                            if (CollectionUtils.isNotEmpty(commandStations)) {

                                LocoDecoderInitializer locoDecoderInitializer = LocoDecoderInitializer.getDefault();
                                AtomicBoolean initializerFinishedLock =
                                    locoDecoderInitializer.getInitializerFinishedLock();
                                locoDecoderInitializer.start(commandStations);

                                synchronized (initializerFinishedLock) {
                                    if (!initializerFinishedLock.get()) {
                                        LOGGER.info("Wait for initializerFinishedLock to be signalled.");
                                        initializerFinishedLock.wait(20000);
                                    }

                                    LOGGER.info("Current initializerFinishedLock: {}", initializerFinishedLock.get());

                                }
                            }
                            else {
                                LOGGER.info("No command stations in system detected.");
                            }
                        }
                        LOGGER.info("Start the LocoDecoderInitializer has passed.");
                    }
                    catch (Exception ex) {
                        LOGGER.warn("Start the LocoDecoderInitializer failed.", ex);
                    }

                    model.signalInitialLoadFinished();
                }
            };
            new Thread(worker).start();
        }
    }

    private void recursiveCreateSubNodes(
        final Communication communication, final org.bidib.jbidibc.core.Node node, final List nodesToEnable) {
        LOGGER.info("recursiveCreateSubNodes, current node: {}", node);

        // create the node instance
        Node newNode = mainController.createNode(communication, node);

        LOGGER.info("recursiveCreateSubNodes, new created node: {}", newNode);

        if (newNode != null) {
            LOGGER.info("Add new created node to model: {}", newNode);

            model.addNode(newNode);
            nodesToEnable.add(newNode);

            LOGGER.info("New node was added to model: {}", newNode);

            // get the subnodes if the node is a hub ... this must be called recursive
            if (NodeUtils.hasSubNodesFunctions(newNode.getUniqueId())) {
                LOGGER.info("The new node has subnodes functions. Check for subnodes.");
                Collection subNodes = communication.loadSubNodes(newNode.getNode());
                LOGGER.info("Subnodes of the current node: {}", subNodes);
                for (org.bidib.jbidibc.core.Node subNode : subNodes) {
                    LOGGER.info("Call recursiveCreateSubNodes on subNode: {}", subNode);
                    recursiveCreateSubNodes(communication, subNode, nodesToEnable);
                }
            }

        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy