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;
}
}
}