
org.bidib.wizard.mvc.ping.controller.PingTableController Maven / Gradle / Ivy
package org.bidib.wizard.mvc.ping.controller;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.List;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import org.apache.commons.collections4.CollectionUtils;
import org.bidib.jbidibc.core.DefaultMessageListener;
import org.bidib.jbidibc.core.Node;
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.comm.listener.CommunicationListener;
import org.bidib.wizard.mvc.common.view.DockKeys;
import org.bidib.wizard.mvc.main.controller.MainControllerInterface;
import org.bidib.wizard.mvc.main.model.listener.DefaultNodeListListener;
import org.bidib.wizard.mvc.main.model.listener.NodeListListener;
import org.bidib.wizard.mvc.ping.model.NodePingModel;
import org.bidib.wizard.mvc.ping.model.NodePingState;
import org.bidib.wizard.mvc.ping.model.PingTableModel;
import org.bidib.wizard.mvc.ping.view.PingTableView;
import org.bidib.wizard.utils.DockUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vlsolutions.swing.docking.Dockable;
import com.vlsolutions.swing.docking.DockableState;
import com.vlsolutions.swing.docking.DockingConstants;
import com.vlsolutions.swing.docking.DockingDesktop;
import com.vlsolutions.swing.docking.DockingUtilities;
import com.vlsolutions.swing.docking.RelativeDockablePosition;
import com.vlsolutions.swing.docking.TabbedDockableContainer;
import com.vlsolutions.swing.docking.event.DockableStateChangeEvent;
import com.vlsolutions.swing.docking.event.DockableStateChangeListener;
public class PingTableController {
private static final Logger LOGGER = LoggerFactory.getLogger(PingTableController.class);
private PingTableView pingTableView;
private PingTableModel pingTableModel;
private DefaultMessageListener messageListener;
private Timer pingTimer;
private Communication communication;
public void start(final DockingDesktop desktop, final MainControllerInterface mainController) {
// check if the ping view is already opened
String searchKey = DockKeys.PING_TABLE_VIEW;
LOGGER.info("Search for view with key: {}", searchKey);
Dockable view = desktop.getContext().getDockableByKey(searchKey);
if (view != null) {
LOGGER.info("Select the existing ping table view.");
DockUtils.selectWindow(view);
return;
}
LOGGER.info("Create new PingTableView.");
pingTableModel = new PingTableModel();
pingTableView = new PingTableView(pingTableModel);
// add the ping table panel next to the booster panel
DockableState[] dockables = desktop.getDockables();
LOGGER.info("Current dockables: {}", new Object[] { dockables });
if (dockables.length > 1) {
DockableState boosterTableView = null;
// search the booster table view
for (DockableState dockable : dockables) {
if (DockKeys.DOCKKEY_BOOSTER_TABLE_VIEW.equals(dockable.getDockable().getDockKey())) {
LOGGER.info("Found the booster table view dockable.");
boosterTableView = dockable;
break;
}
}
Dockable dock = desktop.getDockables()[1].getDockable();
if (boosterTableView != null) {
LOGGER.info("Add the ping table view to the booster table view panel.");
dock = boosterTableView.getDockable();
TabbedDockableContainer container = DockingUtilities.findTabbedDockableContainer(dock);
int order = 0;
if (container != null) {
order = container.getTabCount();
}
LOGGER.info("Add new ping table panel at order: {}", order);
desktop.createTab(dock, pingTableView, order, true);
}
else {
desktop.split(dock, pingTableView, DockingConstants.SPLIT_RIGHT);
}
}
else {
desktop.addDockable(pingTableView, RelativeDockablePosition.RIGHT);
}
// create the nodeList listener
final NodeListListener nodeListListener = new DefaultNodeListListener() {
@Override
public void listNodeAdded(org.bidib.wizard.mvc.main.model.Node node) {
LOGGER.info("The nodelist has a new node: {}", node);
nodeNew(node.getNode());
}
@Override
public void listNodeRemoved(org.bidib.wizard.mvc.main.model.Node node) {
LOGGER.info("The nodelist has a node removed: {}", node);
nodeLost(node.getNode());
}
};
// register as nodeList listener at the main controller
mainController.addNodeListListener(nodeListListener);
try {
CommunicationFactory.addCommunicationListener(new CommunicationListener() {
@Override
public void status(String statusText, int displayDuration) {
}
@Override
public void opened(String port) {
LOGGER.info("The communication was opened.");
if (pingTimer != null && !pingTimer.isRunning()) {
LOGGER.info("Start the ping timer.");
pingTimer.start();
}
}
@Override
public void initialized() {
}
@Override
public void closed(String port) {
LOGGER.info("The communication was closed.");
// stop the ping timer
if (pingTimer != null) {
LOGGER.info("Stop the ping timer.");
pingTimer.stop();
}
List boosters = new LinkedList<>(pingTableModel.getNodes());
for (NodePingModel booster : boosters) {
pingTableModel.removeNode(booster.getNode());
}
}
});
messageListener = new DefaultMessageListener() {
@Override
public void pong(final byte[] address, final int marker) {
LOGGER.debug("Set the pong marker: {}", marker);
if (SwingUtilities.isEventDispatchThread()) {
pingTableModel.setPongMarker(address, marker);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
pingTableModel.setPongMarker(address, marker);
}
});
}
}
};
CommunicationFactory.addMessageListener(messageListener);
final Communication communication = CommunicationFactory.getInstance();
// get the current nodes
List nodes = communication.getNodes();
if (CollectionUtils.isNotEmpty(nodes)) {
for (Node node : nodes) {
LOGGER.info("Initially add node.");
nodeNew(node);
}
}
}
catch (Exception ex) {
LOGGER.warn("Register controller as node listener failed.", ex);
}
// listen on window close
desktop.addDockableStateChangeListener(new DockableStateChangeListener() {
@Override
public void dockableStateChanged(DockableStateChangeEvent event) {
if (event.getNewState().getDockable().equals(pingTableView) && event.getNewState().isClosed()) {
LOGGER.info("PingTableView was closed, free resources.");
try {
// remove node listener from communication factory
if (nodeListListener != null) {
mainController.removeNodeListListener(nodeListListener);
}
if (messageListener != null) {
CommunicationFactory.removeMessageListener(messageListener);
}
}
catch (Exception ex) {
LOGGER.warn("Register controller as node listener failed.", ex);
}
// stop the ping timer
if (pingTimer != null) {
LOGGER.info("Stop the ping timer.");
pingTimer.stop();
pingTimer = null;
}
}
}
});
try {
communication = CommunicationFactory.getInstance();
// start the ping timer
pingTimer = new Timer(
1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LOGGER.trace("The ping timer has elapsed.");
long now = System.currentTimeMillis();
// trigger the model
List nodePingModels = pingTableModel.getNodes();
for (NodePingModel nodePingModel : nodePingModels) {
if (nodePingModel.getNodePingState() == NodePingState.ON
&& nodePingModel.getPingInterval() != null
&& nodePingModel.getLastPing() < (now - (nodePingModel.getPingInterval() * 1000))) {
// perform a ping
try {
int data = 12;
LOGGER.info("Ping the node: {}, data: {}", nodePingModel, data);
communication.ping(nodePingModel.getNode(), ByteUtils.getLowByte(data));
nodePingModel.setLastPing(now);
}
catch (Exception ex) {
LOGGER.warn("Ping node failed: {}", nodePingModel, ex);
}
}
}
}
}) {
private static final long serialVersionUID = 1L;
@Override
public void start() {
LOGGER.info("Fetch communication instance.");
communication = CommunicationFactory.getInstance();
super.start();
}
@Override
public void stop() {
super.stop();
LOGGER.info("Release communication instance.");
communication = null;
}
};
pingTimer.setCoalesce(true);
if (communication.isOpened()) {
LOGGER.info("Start the ping timer.");
communication = null;
pingTimer.start();
}
else {
LOGGER.info("The communication is not opened, the ping timer is not started.");
communication = null;
}
}
catch (Exception ex) {
LOGGER.warn("Start the ping timer failed.", ex);
}
}
private void nodeLost(final Node node) {
LOGGER.info("Remove node from model: {}", node);
if (SwingUtilities.isEventDispatchThread()) {
pingTableModel.removeNode(node);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
pingTableModel.removeNode(node);
}
});
}
}
private void nodeNew(final Node node) {
LOGGER.info("New node in system detected: {}", node);
if (SwingUtilities.isEventDispatchThread()) {
internalNewNode(node);
}
else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
internalNewNode(node);
}
});
}
// if the node is a hub then we must get it's subnodes ...
if (NodeUtils.hasSubNodesFunctions(node.getUniqueId())) {
final Communication communication = CommunicationFactory.getInstance();
List subNodes = new LinkedList<>(communication.getSubNodes(node));
if (CollectionUtils.isNotEmpty(subNodes)) {
for (Node subNode : subNodes) {
LOGGER.info("Found a subnode: {}", subNode);
nodeNew(subNode);
}
}
}
}
private void internalNewNode(final Node node) {
pingTableModel.addNode(node);
// trigger the first ping from timer
// CommunicationFactory.getInstance().ping(node, (byte) 1);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy