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

org.bidib.wizard.common.node.PortConfigHandler Maven / Gradle / Ivy

package org.bidib.wizard.common.node;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import org.bidib.jbidibc.messages.port.PortConfigValue;
import org.bidib.wizard.api.model.NodeChangePublisher;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.api.utils.PortListUtils;
import org.bidib.wizard.model.ports.BacklightPort;
import org.bidib.wizard.model.ports.GenericPort;
import org.bidib.wizard.model.ports.InputPort;
import org.bidib.wizard.model.ports.LightPort;
import org.bidib.wizard.model.ports.Port;
import org.bidib.wizard.model.ports.ServoPort;
import org.bidib.wizard.model.ports.SwitchPairPort;
import org.bidib.wizard.model.ports.SwitchPort;
import org.bidib.wizard.model.ports.event.PortConfigEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The {@code PortConfigHandler} handles the port config for generic ports.
 */
public class PortConfigHandler implements PropertyChangeListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(PortConfigHandler.class);

    private final ConnectionNodeAwarePublisher publisher;

    private List genericPorts = new LinkedList<>();

    private AtomicBoolean genericPortsSet = new AtomicBoolean();

    public PortConfigHandler(final NodeInterface node, final ConnectionNodeAwarePublisher publisher) {
        this.publisher = publisher;
    }

    private ConnectionNodeAwarePublisher getPublisher() {
        return publisher;
    }

    /**
     * @param genericPorts
     *            the genericPorts to set
     */
    public void setGenericPorts(List genericPorts) {

        synchronized (this.genericPorts) {
            LOGGER.info("Set the generic ports on the node: {}", this);

            // remove property change listener
            for (GenericPort port : this.genericPorts) {
                port.removePropertyChangeListener(this);
            }

            // set the new generic ports
            this.genericPorts.clear();
            this.genericPorts.addAll(genericPorts);

            // add property change listener
            for (GenericPort port : this.genericPorts) {
                port.addPropertyChangeListener(this);
            }

            // clearPortCache();

            genericPortsSet.set(true);
        }
    }

    /**
     * @return the flag returns {@code true} after the generic ports are set, {@code false} otherwise
     */
    public boolean isGenericPortsSet() {
        return genericPortsSet.get();
    }

    /**
     * @return the genericPorts
     */
    public List getGenericPorts() {
        LOGGER.debug("Get the generic ports.");
        synchronized (this.genericPorts) {
            return Collections.unmodifiableList(genericPorts);
        }
    }

    /**
     * Set the configuration of the port.
     * 
     * @param portNumber
     *            the port number
     * @param portConfig
     *            the new port configuration
     * @param nodeChangePublisher
     *            the node change publisher
     */
    public void setPortConfig(
        int portNumber, Map> portConfig, final PropertyChangeListener pcl,
        final NodeChangePublisher nodeChangePublisher) {
        // synchronize because the ports can be accessed from different threads
        try {
            GenericPort port = null;
            synchronized (this.genericPorts) {

                LOGGER.info("Set the port config, portNumber: {}", portNumber);

                try {
                    port = PortListUtils.findGenericPortByPortNumber(genericPorts, portNumber);

                    if (port != null) {
                        if (pcl != null) {
                            port.addPropertyChangeListener(pcl);
                        }

                        // set the new port config that signals the change to the registered listeners
                        port.setPortConfigX(portConfig);
                    }
                    else {
                        LOGGER.warn("No generic port available with portNumber: {}", portNumber);
                    }
                }
                finally {
                    if (port != null && pcl != null) {
                        port.removePropertyChangeListener(pcl);
                    }
                }

                if (port != null) {

                    if (port.getCurrentPortType() != null) {

                        // TODO remove the node change publisher
                        final Port portToPublish;
                        switch (port.getCurrentPortType()) {
                            case BACKLIGHTPORT:
                                portToPublish = new BacklightPort(port);
                                break;
                            case INPUTPORT:
                                portToPublish = new InputPort(port);
                                break;
                            case LIGHTPORT:
                                portToPublish = new LightPort(port);
                                break;
                            case SERVOPORT:
                                portToPublish = new ServoPort(port);
                                break;
                            case SWITCHPORT:
                                portToPublish = new SwitchPort(port);
                                break;
                            case SWITCHPAIRPORT:
                                portToPublish = new SwitchPairPort(port);
                                break;
                            default:
                                LOGGER.warn("Unknown port type for port with portNumber: {}", portNumber);
                                portToPublish = null;
                                break;
                        }
                        if (portToPublish != null) {
                            nodeChangePublisher.firePortConfigChanged(portToPublish);
                        }

                        getPublisher()
                            .getSubjectPortEvents().onNext(new PortConfigEvent(getPublisher().getConnectionId(),
                                getPublisher().getUniqueId(), port));
                    }
                    else {
                        LOGGER.warn("No port type available for port: {}", port);
                    }
                }
            }
        }
        catch (Exception ex) {
            LOGGER.warn("Set port config failed for portNumber: {}", portNumber, ex);
        }
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        LOGGER.info("The property has been changed, name: {}, new value: {}", evt.getPropertyName(), evt.getNewValue());

        // TODO signal changes and error to UI
        switch (evt.getPropertyName()) {
            case GenericPort.PROPERTY_PORT_CONFIG_ERRORCODE:
                break;
            case GenericPort.PROPERTY_PORT_CONFIG_CHANGED:
                break;
            case GenericPort.PROPERTY_PORT_TYPE_CHANGED:
                break;
            default:
                break;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy