
org.bidib.wizard.comm.CommunicationFactory Maven / Gradle / Ivy
package org.bidib.wizard.comm;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.Semaphore;
import org.bidib.jbidibc.core.MessageListener;
import org.bidib.jbidibc.core.NodeListener;
import org.bidib.jbidibc.core.exception.NoAnswerException;
import org.bidib.jbidibc.core.node.listener.TransferListener;
import org.bidib.jbidibc.serial.scm.ScmSerialBidib;
import org.bidib.wizard.comm.bidib.BidibCommunication;
import org.bidib.wizard.comm.listener.CommunicationListener;
import org.bidib.wizard.locale.Resources;
import org.bidib.wizard.mvc.common.model.PreferencesPortType;
import org.bidib.wizard.mvc.preferences.model.Preferences;
import org.bidib.wizard.mvc.preferences.model.listener.PreferencesAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class CommunicationFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(CommunicationFactory.class.getName());
private static Communication instance = null;
private static Semaphore semaphore = new Semaphore(1);
private static Set listeners = new LinkedHashSet();
private static Set transferListeners = new LinkedHashSet();
private static Set messageListeners = new LinkedHashSet();
private static Set nodeListeners = new LinkedHashSet();
// private static boolean ignoreWaitTimeout = true;
static {
LOGGER.info("The CommunicationFactory is instantiated.");
Preferences.getInstance().addPropertyChangeListener(Preferences.PROPERTY_SELECTED_PORTTYPE,
new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
PreferencesPortType portType = Preferences.getInstance().getSelectedPortType();
LOGGER.info("The selected port type has changed: {}", portType);
PreferencesPortType connectedPort = null;
boolean portClosed = false;
// check if the comm port has changed
synchronized (CommunicationFactory.class) {
try {
semaphore.acquire();
if (instance != null) {
connectedPort = instance.getConnectedPortType();
if (instance instanceof BidibCommunication) {
// the real world communication
BidibCommunication communication = (BidibCommunication) instance;
if (!portType.equals(communication.getConnectedPortType())
|| (portType.getConnectionName() != null && !portType
.getConnectionName().equals(connectedPort.getConnectionName()))) {
// the comm port has changed
LOGGER.info("Close the Bidib port.");
try {
ScmSerialBidib.getInstance().close();
}
catch (Exception ex) {
LOGGER.warn("Close Bidib instance failed.", ex);
}
instance = null;
portClosed = true;
LOGGER.info("Released instance of BidibCommunication.");
}
else {
LOGGER.info("The connected port was not changed.");
}
}
}
}
catch (InterruptedException e) {
LOGGER.warn("Acquire semaphore failed.", e);
throw new RuntimeException(e);
}
finally {
semaphore.release();
}
}
if (connectedPort != null && portClosed) {
LOGGER.info("Port was closed: {}", connectedPort);
fireClosed(connectedPort.toString());
}
}
});
Preferences.getInstance().addPreferencesListener(new PreferencesAdapter() {
// @Override
// public void dmxMappingOffsetChanged(int dmxMappingOffset) {
// synchronized (CommunicationFactory.class) {
// try {
// semaphore.acquire();
// if (instance != null) {
// instance.setDmxMappingOffset(dmxMappingOffset);
// }
// }
// catch (Exception ex) {
// LOGGER.warn("Update DMX mapping offset failed.", ex);
// }
// finally {
// semaphore.release();
// }
// }
// }
@Override
public void resetReconnectDelayChanged(int resetReconnectDelay) {
synchronized (CommunicationFactory.class) {
try {
semaphore.acquire();
if (instance != null) {
instance.setResetReconnectDelay(resetReconnectDelay);
}
}
catch (Exception ex) {
LOGGER.warn("Update reset reconnect delay failed.", ex);
}
finally {
semaphore.release();
}
}
}
@Override
public void responseTimeoutChanged(int responseTimeout) {
synchronized (CommunicationFactory.class) {
try {
semaphore.acquire();
if (instance != null) {
instance.setResponseTimeout(responseTimeout);
}
}
catch (Exception ex) {
LOGGER.warn("Update the response timeout failed.", ex);
}
finally {
semaphore.release();
}
}
}
});
}
private CommunicationFactory() {
}
public synchronized static Communication getInstance() {
if (instance == null) {
try {
semaphore.acquire();
fireStatus(Resources.getString(CommunicationFactory.class, "open-port"), -1);
PreferencesPortType commPort = null;
try {
commPort = Preferences.getInstance().getSelectedPortType();
LOGGER.debug("Start to open the Bidib port: {}", commPort);
if (commPort != null) {
instance = new BidibCommunication(commPort);
for (TransferListener transferListener : transferListeners) {
instance.addTransferListener(transferListener);
}
for (MessageListener messageListener : messageListeners) {
instance.addMessageListener(messageListener);
}
for (NodeListener nodeListener : nodeListeners) {
instance.addNodeListener(nodeListener);
}
instance.addCommunicationListener(new CommunicationListener() {
@Override
public void opened(String port) {
fireOpened(port);
}
@Override
public void closed(String port) {
fireClosed(port);
}
@Override
public void initialized() {
fireInitialized();
}
@Override
public void status(String statusText, int displayDuration) {
fireStatus(statusText, displayDuration);
}
});
}
else {
LOGGER.info("No comm port selected, do not create BidibCommunication.");
fireStatus(Resources.getString(CommunicationFactory.class, "no-port-selected"), -1);
}
}
catch (NoAnswerException ex) {
LOGGER.warn("Establish communication with interface failed.");
fireStatus(Resources.getString(CommunicationFactory.class, "establish-communication-failed"), -1);
// release the instance
instance = null;
throw ex;
}
catch (Exception e) {
LOGGER.warn("Open Bidib failed.", e);
fireStatus(Resources.getString(CommunicationFactory.class, "open-port-failed") + " " + commPort, -1);
}
// }
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
finally {
semaphore.release();
}
}
return instance;
}
public static void addCommunicationListener(CommunicationListener listener) {
LOGGER.info("Adding communication listener: {}", listener);
synchronized (listeners) {
listeners.add(listener);
}
}
public static void addTransferListener(TransferListener listener) {
LOGGER.info("Adding transfer listener: {}", listener);
synchronized (transferListeners) {
transferListeners.add(listener);
}
}
public static void addMessageListener(MessageListener listener) {
LOGGER.info("Adding message listener: {}", listener);
synchronized (messageListeners) {
messageListeners.add(listener);
LOGGER.info("Currently registered messageListeners: {}", messageListeners);
// if the instance is already assigned we must add the listener there
try {
semaphore.acquire();
if (instance != null) {
LOGGER.info("Add the message listener to the exising instance.");
instance.addMessageListener(listener);
}
}
catch (InterruptedException ex) {
LOGGER.warn("Acquire semaphore to access instance failed.", ex);
}
finally {
semaphore.release();
}
}
}
public static void removeMessageListener(MessageListener listener) {
LOGGER.info("Remove message listener: {}", listener);
synchronized (messageListeners) {
messageListeners.remove(listener);
}
if (instance != null) {
instance.removeMessageListener(listener);
}
}
public static void addNodeListener(NodeListener listener) {
LOGGER.info("Adding node listener: {}", listener);
synchronized (nodeListeners) {
nodeListeners.add(listener);
}
if (instance != null) {
instance.addNodeListener(listener);
}
}
public static void removeNodeListener(NodeListener listener) {
LOGGER.info("Remove node listener: {}", listener);
synchronized (nodeListeners) {
nodeListeners.remove(listener);
}
if (instance != null) {
instance.removeNodeListener(listener);
}
}
public static void disconnect() {
synchronized (CommunicationFactory.class) {
LOGGER.info("Disconnect the communication.");
try {
semaphore.acquire();
if (instance != null) {
instance.close();
instance = null;
LOGGER.info("Released instance of BidibCommunication.");
}
}
catch (InterruptedException e) {
LOGGER.warn("Acquire semaphore failed.", e);
throw new RuntimeException(e);
}
finally {
semaphore.release();
}
}
}
private static void fireOpened(String port) {
for (CommunicationListener listener : listeners) {
listener.opened(port);
}
}
private static void fireClosed(String port) {
for (CommunicationListener listener : listeners) {
listener.closed(port);
}
}
private static void fireInitialized() {
for (CommunicationListener listener : listeners) {
listener.initialized();
}
}
private static void fireStatus(String statusText, int displayDuration) {
for (CommunicationListener listener : listeners) {
listener.status(statusText, displayDuration);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy