org.bidib.wizard.mvc.main.controller.MacroPanelController Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bidibwizard-client Show documentation
Show all versions of bidibwizard-client Show documentation
jBiDiB BiDiB Wizard Client Application POM
package org.bidib.wizard.mvc.main.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntFunction;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.bidib.jbidibc.messages.enums.LcMacroState;
import org.bidib.jbidibc.messages.enums.LcOutputType;
import org.bidib.jbidibc.messages.exception.InvalidConfigurationException;
import org.bidib.wizard.api.event.MacroChangedEvent;
import org.bidib.wizard.api.model.Macro;
import org.bidib.wizard.api.model.MacroSaveState;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.api.model.function.Function;
import org.bidib.wizard.api.model.function.PortAction;
import org.bidib.wizard.api.service.node.SwitchingNodeService;
import org.bidib.wizard.api.utils.PortListUtils;
import org.bidib.wizard.client.common.view.DefaultBusyFrame;
import org.bidib.wizard.client.common.view.statusbar.StatusBar;
import org.bidib.wizard.common.labels.DefaultWizardLabelFactory;
import org.bidib.wizard.common.labels.LabelsChangedEvent;
import org.bidib.wizard.common.labels.WizardLabelWrapper;
import org.bidib.wizard.common.service.SettingsService;
import org.bidib.wizard.core.model.connection.ConnectionRegistry;
import org.bidib.wizard.model.ports.Port;
import org.bidib.wizard.model.status.BidibStatus;
import org.bidib.wizard.mvc.main.controller.listener.MacroPanelListener;
import org.bidib.wizard.mvc.main.model.MainModel;
import org.bidib.wizard.mvc.main.view.panel.MacroListPanel;
import org.bidib.wizard.mvc.main.view.panel.listener.TabVisibilityListener;
import org.bushe.swing.event.annotation.AnnotationProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
public class MacroPanelController implements MacroPanelListener {
private static final Logger LOGGER = LoggerFactory.getLogger(MacroPanelController.class);
private final MainModel mainModel;
private final StatusBar statusBar;
private MacroListPanel macroListPanel;
@Autowired
private SwitchingNodeService switchingNodeService;
@Autowired
private SettingsService settingsService;
@Autowired
private WizardLabelWrapper wizardLabelWrapper;
@Autowired
private DefaultWizardLabelFactory bidibLabelFactory;
public MacroPanelController(final MainModel mainModel, final StatusBar statusBar) {
this.mainModel = mainModel;
this.statusBar = statusBar;
// add the eventbus processing
AnnotationProcessor.process(this);
}
public MacroListPanel createMacroListPanel(final TabVisibilityListener tabVisibilityListener) {
macroListPanel =
new MacroListPanel(this, mainModel, tabVisibilityListener, settingsService, wizardLabelWrapper,
bidibLabelFactory, this.statusBar);
macroListPanel.setMacroPanelListener(this);
macroListPanel.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
final DefaultTableModel macroList = (DefaultTableModel) e.getSource();
try {
DefaultBusyFrame.setWaitCursor(macroListPanel.getComponent());
int selectedRow = e.getFirstIndex();
if (selectedRow > -1) {
Object value = macroList.getValueAt(selectedRow, 0);
LOGGER.info("The selected macro has changed: {}, selectedRow: {}", value, selectedRow);
if (!(value instanceof Macro)) {
// do not react on change of label
LOGGER.info("Discard change of label.");
return;
}
Macro macro = (Macro) value;
if (macro != null) {
if (macro.getMacroSaveState() == MacroSaveState.NOT_LOADED_FROM_NODE) {
// This loads the macro content effectively ...
LOGGER.info("Load the macro content from the node.");
try {
macro =
switchingNodeService
.getMacroContent(ConnectionRegistry.CONNECTION_ID_MAIN,
mainModel.getSelectedNode().getSwitchingNode(), macro);
mainModel.setSelectedMacro(macro);
}
catch (InvalidConfigurationException ex) {
LOGGER.warn("Restore macro content failed.", ex);
// set an empty macro
macro.setContainsError(true);
mainModel.setSelectedMacro(macro);
mainModel.setNodeHasError(mainModel.getSelectedNode(), true);
}
catch (Exception ex) {
LOGGER.warn("Get the content of the selected macro failed.", ex);
}
}
else {
mainModel.setSelectedMacro(macro);
}
}
}
}
finally {
DefaultBusyFrame.setDefaultCursor(macroListPanel.getComponent());
}
}
}
});
this.mainModel.addNodeSelectionListener(selectedNode -> {
LOGGER.info("Selected node changed: {}", selectedNode);
macroListPanel.selectedNodeChanged(selectedNode);
});
return macroListPanel;
}
/**
* Move the ports in all macros
*
* @param model
* the model
* @param node
* the node
* @param port
* the start port
* @param allPorts
* the ports
* @param portsCount
* number of ports to move
*/
public > void movePortsInAllMacros(
final MainModel model, final NodeInterface node, E port, List allPorts, int portsCount,
final IntFunction portNumCalculator) {
movePortsInMacros(model, node, port, allPorts, portsCount, portNumCalculator);
}
public > void movePortsInMacros(
final MainModel model, final NodeInterface node, E port, List allPorts, int portsCount,
final IntFunction portNumCalculator) {
LcOutputType outputType = Port.getPortType(port);
// iterate over the macros of the node
for (Macro macro : node.getMacros()) {
processMacro(model, node, macro, outputType, port, allPorts, portsCount, portNumCalculator);
}
}
protected > void processMacro(
final MainModel model, final NodeInterface node, final Macro macro, LcOutputType outputType, final E port,
List allPorts, int portsCount, final IntFunction portNumCalculator) {
List portsToMove = new ArrayList<>();
// check which ports are in use behind the provided port in macros
for (Function extends BidibStatus> step : macro.getFunctions()) {
if (step instanceof PortAction) {
PortAction> portAction = (PortAction>) step;
if (Port.getPortType(portAction.getPort()).equals(outputType)
&& portAction.getPort().getId() >= port.getId()) {
// only matching ports
LOGGER.info("Add port to move: {}", portAction.getPort());
MacroStepPortEntry entry = new MacroStepPortEntry(portAction.getPort(), portAction);
portsToMove.add(entry);
}
}
}
if (CollectionUtils.isNotEmpty(portsToMove)) {
LOGGER.info("Found macro steps to manipulate: {}", portsToMove);
// from the highest port number backwards to the lowest replace the port numbers
for (MacroStepPortEntry entry : portsToMove) {
E currentPort = (E) entry.getPort();
int portNum = currentPort.getId();
int replacedPortNum = portNumCalculator.apply(portNum);
LOGGER.info("Current 'old' port with portNum: {}, replacedPortNum: {}", portNum, replacedPortNum);
// get the port with the next id
Port> replacedPort = PortListUtils.findPortByPortNumber(allPorts, replacedPortNum);
if (replacedPort != null) {
LOGGER.info("Set the replaced port: {}, portNum: {}", replacedPort, replacedPort.getId());
entry.getStep().setPort(replacedPort);
}
else {
LOGGER.info("Replaced port is not available, replacedPortNum: {}", replacedPortNum);
}
}
// save the macro permanent on the node
switchingNodeService.saveMacro(ConnectionRegistry.CONNECTION_ID_MAIN, node.getSwitchingNode(), macro);
}
else {
LOGGER.info("No ports to move in macros found.");
}
}
private static final class MacroStepPortEntry {
private PortAction> step;
private Port> port;
public MacroStepPortEntry(Port> port, PortAction> step) {
this.port = port;
this.step = step;
}
public Port> getPort() {
return port;
}
public PortAction> getStep() {
return step;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
@Override
public void storeMacroOnNode(Macro macro) {
LOGGER.info("Store the macro on the node: {}", macro);
// create a clone of the macro
final Macro macroClone = Macro.cloneMacro(macro);
switchingNodeService
.saveMacro(ConnectionRegistry.CONNECTION_ID_MAIN, mainModel.getSelectedNode().getSwitchingNode(),
macroClone);
}
@Override
public LcMacroState reloadMacro(Macro macro) {
LcMacroState lcMacroState =
switchingNodeService
.reloadMacro(ConnectionRegistry.CONNECTION_ID_MAIN, mainModel.getSelectedNode().getSwitchingNode(),
macro);
return lcMacroState;
}
@Override
public LcMacroState saveMacro(final Macro macro) {
// create a clone of the macro
final Macro macroClone = Macro.cloneMacro(macro);
LcMacroState lcMacroState =
switchingNodeService
.saveMacro(ConnectionRegistry.CONNECTION_ID_MAIN, mainModel.getSelectedNode().getSwitchingNode(),
macroClone);
return lcMacroState;
}
@Override
public LcMacroState startMacro(Macro macro, boolean transferBeforeStart) {
LcMacroState lcMacroState =
switchingNodeService
.startMacro(ConnectionRegistry.CONNECTION_ID_MAIN, mainModel.getSelectedNode().getSwitchingNode(),
macro, transferBeforeStart);
return lcMacroState;
}
@Override
public LcMacroState stopMacro(Macro macro) {
LcMacroState lcMacroState =
switchingNodeService
.stopMacro(ConnectionRegistry.CONNECTION_ID_MAIN, mainModel.getSelectedNode().getSwitchingNode(),
macro);
return lcMacroState;
}
@Override
public void transferMacro(Macro macro) {
// create a clone of the macro
final Macro macroClone = Macro.cloneMacro(macro);
switchingNodeService
.transferMacro(ConnectionRegistry.CONNECTION_ID_MAIN, mainModel.getSelectedNode().getSwitchingNode(),
macroClone);
}
@EventListener(LabelsChangedEvent.class)
public void labelsChangedEvent(LabelsChangedEvent labelsChangedEvent) {
LOGGER.info("The labels have changed, node: {}", labelsChangedEvent);
if (this.macroListPanel != null) {
SwingUtilities.invokeLater(() -> macroListPanel.refreshView());
}
}
@EventListener(MacroChangedEvent.class)
public void macroChangedEvent(MacroChangedEvent macroChangedEvent) {
LOGGER.info("The macros have changed, node: {}", macroChangedEvent);
if (this.macroListPanel != null) {
SwingUtilities.invokeLater(() -> macroListPanel.notifyMacrosChanged());
}
}
}