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

org.bidib.wizard.nodes.client.controller.NodesClientController Maven / Gradle / Ivy

package org.bidib.wizard.nodes.client.controller;

import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.bidib.api.json.types.dccmapping.AccessoryAspectMapping;
import org.bidib.api.json.types.dccmapping.BidibAccessoryAspect;
import org.bidib.api.json.types.dccmapping.DccAccessoryAspect;
import org.bidib.api.json.types.dccmapping.DccAccessoryAspectMapping;
import org.bidib.api.json.types.dccmapping.DccAccessoryAspectMapping.ValidState;
import org.bidib.jbidibc.core.InbandProtocolHandler;
import org.bidib.jbidibc.core.node.ConfigurationVariable;
import org.bidib.jbidibc.messages.VendorData;
import org.bidib.jbidibc.messages.utils.ProductUtils;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.api.model.NodeProvider;
import org.bidib.wizard.api.model.listener.NodeSelectionListener;
import org.bidib.wizard.api.service.node.NodeService;
import org.bidib.wizard.client.common.controller.NodeSelectionProvider;
import org.bidib.wizard.client.common.view.DockKeys;
import org.bidib.wizard.client.common.view.DockUtils;
import org.bidib.wizard.common.labels.WizardLabelWrapper;
import org.bidib.wizard.common.service.SettingsService;
import org.bidib.wizard.nodes.client.controller.listener.NodesClientControllerListener;
import org.bidib.wizard.nodes.client.view.NodesClientView;
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;

public class NodesClientController implements NodesClientControllerListener {

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

    private final DockingDesktop desktop;

    private final Supplier nodeProviderSupplier;

    private final SettingsService settingsSevice;

    private NodesClientView nodesClientView;

    private final Supplier nodeSelectionProviderSupplier;

    private NodeSelectionListener nodeSelectionListener;

    private final NodeService nodeService;

    private final String connectionId;

    private final WizardLabelWrapper wizardLabelWrapper;

    public NodesClientController(final DockingDesktop desktop, final Supplier nodeProviderSupplier,
        final Supplier nodeSelectionProviderSupplier, final SettingsService settingsSevice,
        final NodeService nodeService, String connectionId, WizardLabelWrapper wizardLabelWrapper) {
        this.desktop = desktop;
        this.nodeProviderSupplier = nodeProviderSupplier;
        this.nodeSelectionProviderSupplier = nodeSelectionProviderSupplier;
        this.settingsSevice = settingsSevice;
        this.nodeService = nodeService;
        this.connectionId = connectionId;
        this.wizardLabelWrapper = wizardLabelWrapper;
    }

    public void start() {
        // check if the nodes client view is already opened
        String searchKey = DockKeys.NODES_CLIENT_VIEW;
        LOGGER.info("Search for view with key: {}", searchKey);
        Dockable view = desktop.getContext().getDockableByKey(searchKey);
        if (view != null) {
            LOGGER.info("Select the existing nodes client view instead of open a new one.");
            DockUtils.selectWindow(view);
            return;
        }

        LOGGER.info("Create new NodesClientView.");
        this.nodesClientView =
            new NodesClientView(desktop, this, this.settingsSevice.getMiscSettings(), wizardLabelWrapper);
        this.nodesClientView.initComponents();

        // add dockable
        DockableState[] dockables = desktop.getDockables();
        LOGGER.info("Current dockables: {}", new Object[] { dockables });
        if (dockables.length > 1) {

            DockableState tabPanelNodeDetails = null;
            // search the node details tab panel
            for (DockableState dockable : dockables) {

                if (DockKeys.DOCKKEY_TAB_PANEL.equals(dockable.getDockable().getDockKey())) {
                    LOGGER.info("Found the tab panel dockable.");
                    tabPanelNodeDetails = dockable;

                    break;
                }
            }

            Dockable dock = desktop.getDockables()[1].getDockable();
            if (tabPanelNodeDetails != null) {
                LOGGER.info("Add the nodesClientView next to the node details panel.");
                dock = tabPanelNodeDetails.getDockable();

                TabbedDockableContainer container = DockingUtilities.findTabbedDockableContainer(dock);
                int order = 0;
                if (container != null) {
                    order = container.getTabCount();
                }
                LOGGER.info("Add new nodesClientView at order: {}", order);

                desktop.createTab(dock, nodesClientView, order, true);
            }
            else {
                desktop.split(dock, nodesClientView, DockingConstants.SPLIT_RIGHT);
            }
        }
        else {
            desktop.addDockable(nodesClientView, RelativeDockablePosition.RIGHT);
        }

        // add the node selection listener
        this.nodeSelectionListener = new NodeSelectionListener() {

            @Override
            public void selectedNodeChanged(final NodeInterface selectedNode) {

                LOGGER.info("The selected node has changed: {}", selectedNode);

                if (selectedNode != null && ProductUtils.isNodeAccessSupported(selectedNode.getUniqueId())) {
                    nodesClientView.setNodeAccessSupported(true);
                }
                else {
                    nodesClientView.setNodeAccessSupported(false);
                }
            }

        };
        nodeSelectionProviderSupplier.get().addNodeSelectionListener(this.nodeSelectionListener);

        this.nodesClientView.prepareModel(this.nodeProviderSupplier.get());

        final NodeInterface selectedNode = nodeSelectionProviderSupplier.get().getSelectedNode();
        nodesClientView
            .setNodeAccessSupported(
                selectedNode != null && ProductUtils.isNodeAccessSupported(selectedNode.getUniqueId()));

    }

    @Override
    public void viewClosed() {
        LOGGER.info("The view is closed.");

        if (this.nodeSelectionListener != null) {
            LOGGER.info("Remove the nodeSelectionListener.");
            nodeSelectionProviderSupplier.get().removeNodeSelectionListener(this.nodeSelectionListener);

            this.nodeSelectionListener = null;
        }

    }

    @Override
    public AccessoryAspectMapping writeAccessoryMapping(final List configVariables) {
        LOGGER.info("Store the CV values on the selected node: {}", configVariables);

        // get the selected node
        final NodeInterface selectedNode = nodeSelectionProviderSupplier.get().getSelectedNode();
        if (selectedNode != null && ProductUtils.isNodeAccessSupported(selectedNode.getUniqueId())) {

            final InbandProtocolHandler handler = new InbandProtocolHandler() {

                private int pendingMessages;

                @Override
                public void setPendingMessages(int pendingMessages) {
                    this.pendingMessages = pendingMessages;
                }

                @Override
                public void reset() {

                }

                @Override
                public boolean handleMessageData(VendorData data) {
                    switch (data.getName()) {
                        case MAPPING_AMR_ALL:
                            LOGGER
                                .info("Received AMR * answer. Wait for number of following entry messages: {}",
                                    data.getValue());

                            if (StringUtils.isNotEmpty(data.getValue())) {
                                try {
                                    int numOfMessages = Integer.parseInt(data.getValue());
                                    if (numOfMessages > 0) {
                                        pendingMessages = numOfMessages;
                                        return true;
                                    }
                                }
                                catch (NumberFormatException ex) {
                                    LOGGER.warn("Parse number of following entry messages failed.", ex);
                                }
                            }
                            break;

                        default:
                            if (data.getName().startsWith(MAPPING_PREFIX_AME)) {
                                LOGGER.info("Received AME: {}, value: {}", data.getName(), data.getValue());
                                pendingMessages--;

                                if (pendingMessages > 0) {
                                    // wait for more messages
                                    return true;
                                }
                            }
                            break;
                    }
                    return false;
                }
            };

            // reset the handler
            handler.reset();

            handler.setPendingMessages(configVariables.size());

            final List resultData =
                nodeService.setConfigVariables(this.connectionId, selectedNode, configVariables, handler);
            LOGGER.info("Received data: {}", resultData);

            // iterate over the mapping entries and search the nodes
            if (resultData != null) {

                return prepareAccessoryAspectMapping(resultData);
            }

        }
        else {
            LOGGER.warn("Store the CV values is skipped because no node selected or the node is not a ReadyXP node.");
        }
        return new AccessoryAspectMapping();
    }

    @Override
    public AccessoryAspectMapping readAccessoryMapping(List configVariables) {
        // get the selected node
        final NodeInterface selectedNode = nodeSelectionProviderSupplier.get().getSelectedNode();
        if (selectedNode != null && ProductUtils.isNodeAccessSupported(selectedNode.getUniqueId())) {

            final InbandProtocolHandler handler = new InbandProtocolHandler() {

                private int pendingMessages;

                @Override
                public void reset() {

                }

                @Override
                public boolean handleMessageData(VendorData data) {
                    switch (data.getName()) {
                        case MAPPING_AMR_ALL:
                            LOGGER
                                .info("Received AMR * answer. Wait for number of following entry messages: {}",
                                    data.getValue());
                            try {
                                int numOfMessages = Integer.parseInt(data.getValue());
                                if (numOfMessages > 0) {
                                    pendingMessages = numOfMessages;
                                    // wait for more messages
                                    return true;
                                }
                            }
                            catch (NumberFormatException ex) {
                                LOGGER.warn("Parse number of following entry messages failed.", ex);
                            }
                            break;

                        default:
                            if (data.getName().startsWith(MAPPING_PREFIX_AME)) {
                                pendingMessages--;

                                if (pendingMessages > 0) {
                                    // wait for more messages
                                    return true;
                                }
                            }
                            break;
                    }
                    return false;
                }
            };

            // reset the handler
            handler.reset();
            final List resultData =
                nodeService.queryConfigVariables(this.connectionId, selectedNode, configVariables, handler);

            LOGGER.info("Received data: {}", resultData);

            // iterate over the mapping entries and search the nodes
            if (resultData != null) {
                return prepareAccessoryAspectMapping(resultData);
            }
        }
        else {
            LOGGER.warn("Store the CV values is skipped because no node selected or the node is not a ReadyXP node.");
        }
        return new AccessoryAspectMapping();
    }

    private AccessoryAspectMapping prepareAccessoryAspectMapping(final List resultData) {
        final AccessoryAspectMapping accessoryAspectMapping = new AccessoryAspectMapping();

        final Pattern amePattern = Pattern.compile("AME\\s(\\w+)\\s(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)");
        for (ConfigurationVariable cv : resultData) {

            LOGGER.info("Current cv.name: {}, cv.value: {}", cv.getName(), cv.getValue());
            if (cv.getName().startsWith(MAPPING_PREFIX_AME)) {
                // parse the mapping
                try {
                    Matcher matcher = amePattern.matcher(cv.getName());
                    if (matcher.matches()) {
                        String uniqueId = matcher.group(1);
                        int bidibAccessory = Integer.valueOf(matcher.group(2));
                        int bidibAspect = Integer.valueOf(matcher.group(3));
                        int dccAccessory = Integer.valueOf(matcher.group(4));
                        int dccAspect = Integer.valueOf(matcher.group(5));
                        LOGGER
                            .info("UniqueId: {}, bidibAccessory: {}, bidibAspect: {}, dccAccessory: {}, dccAspect: {}",
                                uniqueId, bidibAccessory, bidibAspect, dccAccessory, dccAspect);

                        final DccAccessoryAspectMapping dccAccessoryAspectMapping =
                            new DccAccessoryAspectMapping()
                                .withBidibAccessoryAspect(new BidibAccessoryAspect()
                                    .withUniqueId(uniqueId).withAccessoryNumber(bidibAccessory)
                                    .withAspectNumber(bidibAspect))
                                .withDccAccessoryAspect(new DccAccessoryAspect()
                                    .withDccAccessoryAddress(dccAccessory).withAspectNumber(dccAspect));

                        dccAccessoryAspectMapping
                            .withValidState(cv.isInvalid() ? ValidState.INVALID : ValidState.VALID);
                        if (cv.isInvalid()) {
                            LOGGER.warn("Received invalid answer for cv name: {}", cv.getName());
                        }
                        else {
                            // TODO if the entry was deleted we must remove the dcc address and dcc aspect
                            if (MAPPING_DELETE.equals(cv.getValue())) {
                                LOGGER.info("Delete the mapping.");
                                dccAccessoryAspectMapping
                                    .getDccAccessoryAspect().withDccAccessoryAddress(null).withAspectNumber(null);
                            }
                        }

                        accessoryAspectMapping.getMappings().add(dccAccessoryAspectMapping);
                    }
                }
                catch (Exception ex) {
                    LOGGER.warn("Parse AME line failed. Current line: {}", cv.getName(), ex);
                }
            }
            else if (MAPPING_AMR_ALL.equals(cv.getName())) {
                // delete all mappings
                final DccAccessoryAspectMapping dccAccessoryAspectMapping =
                    new DccAccessoryAspectMapping().withAdditionalProperty(cv.getName(), cv.getValue());
                accessoryAspectMapping.getMappings().add(dccAccessoryAspectMapping);
            }
        }
        return accessoryAspectMapping;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy