
org.bidib.wizard.mvc.main.controller.NewNodeReader Maven / Gradle / Ivy
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