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

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

There is a newer version: 2.0.29
Show newest version
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 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());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy