package eu.hgross.blaubot.core.statemachine; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import eu.hgross.blaubot.core.IBlaubotAdapter; import eu.hgross.blaubot.core.acceptor.ConnectionMetaDataDTO; import eu.hgross.blaubot.core.acceptor.IBlaubotConnectionAcceptor; import eu.hgross.blaubot.core.acceptor.IBlaubotListeningStateListener; import eu.hgross.blaubot.core.acceptor.discovery.BlaubotBeaconService; import eu.hgross.blaubot.core.acceptor.discovery.IBlaubotBeacon; import eu.hgross.blaubot.core.connector.IBlaubotConnector; import eu.hgross.blaubot.util.Log; /** * * @author Henning Gross {@literal (mail.to@henning-gross.de)} * */ public class BlaubotAdapterHelper { public static final String LOG_TAG = "BlaubotAdapterHelper"; /** * Traverses adapters to retrieve all acceptors. * * @param adapters the adapters * @return all connection acceptors contained by the list of adapters */ public static List<IBlaubotConnectionAcceptor> getConnectionAcceptors(List<IBlaubotAdapter> adapters) { ArrayList<IBlaubotConnectionAcceptor> out = new ArrayList<IBlaubotConnectionAcceptor>(); for(IBlaubotAdapter a : adapters) out.add(a.getConnectionAcceptor()); return out; } /** * Traverses adapters to retrieve all connectors from them. * * @param adapters the adapters to get the connectors from * @return all connectors contained by the list of adapters */ public static List<IBlaubotConnector> getConnectors(List<IBlaubotAdapter> adapters) { ArrayList<IBlaubotConnector> out = new ArrayList<IBlaubotConnector>(); for(IBlaubotAdapter a : adapters) out.add(a.getConnector()); return out; } /** * counts the number of started beacons and acceptors * @param acceptors null or list of acceptors * @param beacons null or list of beacons * @return the sum of started acceptors and beacons */ public static int startedCount(List<IBlaubotConnectionAcceptor> acceptors, List<IBlaubotBeacon> beacons) { int i = 0; if (acceptors != null) for (IBlaubotConnectionAcceptor acc : acceptors) if (acc.isStarted()) i++; if (beacons != null) for (IBlaubotConnectionAcceptor acc : beacons) if (acc.isStarted()) i++; return i; } /** * Calls setDiscoveryActivated on all beacons * * @param beaconService the beacon service * @param newState the new state */ public static void setDiscoveryActivated(BlaubotBeaconService beaconService, boolean newState) { for(IBlaubotBeacon beacon : beaconService.getBeacons()) { beacon.setDiscoveryActivated(newState); } }; public static void stopAcceptors(List<IBlaubotConnectionAcceptor> acceptors) { int cnt = startedCount(acceptors, null); final CountDownLatch countDown = new CountDownLatch(cnt); IBlaubotListeningStateListener listeningStateListener = new IBlaubotListeningStateListener() { @Override public void onListeningStopped(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Got listeningStopped from connectionAcceptor: " + connectionAcceptor); } countDown.countDown(); } @Override public void onListeningStarted(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logErrorMessages()) { Log.e(LOG_TAG, "Got listeningStarted from connectionAcceptor: " + connectionAcceptor); } throw new IllegalStateException("Got onListeningStarted while waiting for the acceptors to stop!"); } }; for (IBlaubotConnectionAcceptor acceptor : acceptors) { acceptor.setListeningStateListener(listeningStateListener); } if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Stopping blaubot acceptors ..."); } for (IBlaubotConnectionAcceptor acceptor : acceptors) { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "\tStopping acceptor: " + acceptor); } acceptor.stopListening(); } // TODO use timeout try { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Awaiting onListeningStopped of all acceptors"); } countDown.await(); if(Log.logDebugMessages()) { Log.d(LOG_TAG, "All acceptors are stopped now"); } } catch (InterruptedException e) { throw new RuntimeException(e); } for (IBlaubotConnectionAcceptor acceptor : acceptors) { acceptor.setListeningStateListener(null); } } /** * blocking until all acceptors and beacons are stopped (if started) * * @param acceptors the acceptors * @param beaconService the beacon service */ public static void stopAcceptorsAndBeacons(List<IBlaubotConnectionAcceptor> acceptors, BlaubotBeaconService beaconService) { List<IBlaubotBeacon> beacons = beaconService.getBeacons(); int cnt = startedCount(acceptors, beacons); final CountDownLatch countDown = new CountDownLatch(cnt); IBlaubotListeningStateListener listeningStateListener = new IBlaubotListeningStateListener() { @Override public void onListeningStopped(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Got listeningStopped from connectionAcceptor: " + connectionAcceptor); } countDown.countDown(); } @Override public void onListeningStarted(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logErrorMessages()) { Log.e(LOG_TAG, "Got listeningStarted from connectionAcceptor: " + connectionAcceptor); } throw new IllegalStateException("Got onListeningStarted while waiting for the acceptors to stop!"); } }; for (IBlaubotConnectionAcceptor acceptor : acceptors) { acceptor.setListeningStateListener(listeningStateListener); } for (IBlaubotConnectionAcceptor beacon : beacons) { beacon.setListeningStateListener(listeningStateListener); } if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Stopping beacon services ... "); } beaconService.stopBeaconInterfaces(); if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Stopping - going through all acceptors ..."); } for (IBlaubotConnectionAcceptor acceptor : acceptors) { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "\tStopping acceptor: " + acceptor); } acceptor.stopListening(); } // TODO use timeout try { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Awaiting onListeningStopped of all acceptors and beacons"); } countDown.await(); if(Log.logDebugMessages()) { Log.d(LOG_TAG, "All acceptors and beacons are stopped now"); } } catch (InterruptedException e) { throw new RuntimeException(e); } for (IBlaubotConnectionAcceptor acceptor : acceptors) { acceptor.setListeningStateListener(null); } for (IBlaubotConnectionAcceptor beacon : beacons) { beacon.setListeningStateListener(null); } } /** * blocking until all beacons are stopped (if started) * * @param beaconService the beacon service */ public static void stopBeacons(BlaubotBeaconService beaconService) { List<IBlaubotBeacon> beacons = beaconService.getBeacons(); int cnt = startedCount(null, beacons); final CountDownLatch countDown = new CountDownLatch(cnt); IBlaubotListeningStateListener listeningStateListener = new IBlaubotListeningStateListener() { @Override public void onListeningStopped(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Got listeningStopped from connectionAcceptor: " + connectionAcceptor); } countDown.countDown(); } @Override public void onListeningStarted(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logErrorMessages()) { Log.e(LOG_TAG, "Got listeningStarted from connectionAcceptor: " + connectionAcceptor); } throw new IllegalStateException("Got onListeningStarted while waiting for the acceptors to stop!"); } }; for (IBlaubotConnectionAcceptor beacon : beacons) { beacon.setListeningStateListener(listeningStateListener); } if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Stopping beacon services ... "); } beaconService.stopBeaconInterfaces(); // TODO use timeout try { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Awaiting onListeningStopped of all acceptors and beacons"); } countDown.await(); if(Log.logDebugMessages()) { Log.d(LOG_TAG, "All acceptors and beacons are stopped now"); } } catch (InterruptedException e) { throw new RuntimeException(e); } for (IBlaubotConnectionAcceptor beacon : beacons) { beacon.setListeningStateListener(null); } } public static void startAcceptors(List<IBlaubotConnectionAcceptor> acceptors) { int cnt = acceptors.size(); int startedCnt = startedCount(acceptors, null); final CountDownLatch countDown = new CountDownLatch(cnt - startedCnt); IBlaubotListeningStateListener listeningStateListener = new IBlaubotListeningStateListener() { @Override public void onListeningStopped(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logErrorMessages()) { Log.e(LOG_TAG, "Got listeningStopped from connectionAcceptor: " + connectionAcceptor); } throw new IllegalStateException("Got onListeningStopped while waiting for the acceptors to start!"); } @Override public void onListeningStarted(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Got listeningStarted from connectionAcceptor: " + connectionAcceptor); } countDown.countDown(); } }; if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Starting all acceptors ... "); } for (IBlaubotConnectionAcceptor acc : acceptors) { if(acc.isStarted()) continue; acc.setListeningStateListener(listeningStateListener); if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Starting acceptor: " + acc); } acc.startListening(); } try { // TODO: use a timeout here! if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Awaiting onListeningStarted of all acceptors"); } countDown.await(); if(Log.logDebugMessages()) { Log.d(LOG_TAG, "All acceptors are started properly"); } } catch (InterruptedException e) { throw new RuntimeException(e); } for (IBlaubotConnectionAcceptor acc : acceptors) { acc.setListeningStateListener(null); } } public static void startBeacons(BlaubotBeaconService beaconService) { List<IBlaubotBeacon> beacons = beaconService.getBeacons(); int cnt = beacons.size(); int startedCnt = startedCount(null, beacons); final CountDownLatch countDown = new CountDownLatch(cnt - startedCnt); IBlaubotListeningStateListener listeningStateListener = new IBlaubotListeningStateListener() { @Override public void onListeningStopped(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logErrorMessages()) { Log.e(LOG_TAG, "Got listeningStopped from connectionAcceptor: " + connectionAcceptor); } throw new IllegalStateException("Got onListeningStopped while waiting for the acceptors to start!"); } @Override public void onListeningStarted(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Got listeningStarted from connectionAcceptor: " + connectionAcceptor); } countDown.countDown(); } }; for (IBlaubotConnectionAcceptor beacon : beacons) { beacon.setListeningStateListener(listeningStateListener); } if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Starting beacon services ... "); } beaconService.startBeaconInterfaces(); try { // TODO: use a timeout here! if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Awaiting onListeningStarted of all beacons"); } countDown.await(); if(Log.logDebugMessages()) { Log.d(LOG_TAG, "All beacons are started now"); } } catch (InterruptedException e) { throw new RuntimeException(e); } for (IBlaubotConnectionAcceptor beacon : beacons) { beacon.setListeningStateListener(null); } } public static void startAcceptorsAndBeacons(List<IBlaubotConnectionAcceptor> acceptors, BlaubotBeaconService beaconService) { List<IBlaubotBeacon> beacons = beaconService.getBeacons(); int cnt = acceptors.size() + beacons.size(); int startedCnt = startedCount(acceptors, beacons); final CountDownLatch countDown = new CountDownLatch(cnt - startedCnt); IBlaubotListeningStateListener listeningStateListener = new IBlaubotListeningStateListener() { @Override public void onListeningStopped(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logErrorMessages()) { Log.e(LOG_TAG, "Got listeningStopped from connectionAcceptor: " + connectionAcceptor); } throw new IllegalStateException("Got onListeningStopped while waiting for the acceptors to start!"); } @Override public void onListeningStarted(IBlaubotConnectionAcceptor connectionAcceptor) { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Got listeningStarted from connectionAcceptor: " + connectionAcceptor); } countDown.countDown(); } }; for (IBlaubotConnectionAcceptor acceptor : acceptors) { acceptor.setListeningStateListener(listeningStateListener); } for (IBlaubotConnectionAcceptor beacon : beacons) { beacon.setListeningStateListener(listeningStateListener); } if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Starting beacon services ... "); } beaconService.startBeaconInterfaces(); if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Starting acceptors ... "); } for (IBlaubotConnectionAcceptor acceptor : acceptors) { if (!acceptor.isStarted()) { if(Log.logDebugMessages()) { Log.d(LOG_TAG, "\tStarting acceptor: " + acceptor); } acceptor.startListening(); } } try { // TODO: use a timeout here! if(Log.logDebugMessages()) { Log.d(LOG_TAG, "Awaiting onListeningStarted of all acceptors and beacons"); } countDown.await(); if(Log.logDebugMessages()) { Log.d(LOG_TAG, "All acceptors and beacons are started now"); } } catch (InterruptedException e) { throw new RuntimeException(e); } for (IBlaubotConnectionAcceptor acceptor : acceptors) { acceptor.setListeningStateListener(null); } for (IBlaubotConnectionAcceptor beacon : beacons) { beacon.setListeningStateListener(null); } } /** * Takes acceptors and retrieves their connection meta data objects as a list by * retrieving the meta data and putting them into a single list. * * @param acceptors the acceptors to gather the meta data from * @return the list of extracted connection meta data objects for the given acceptors */ public static List<ConnectionMetaDataDTO> getConnectionMetaDataList(List<IBlaubotConnectionAcceptor> acceptors) { final ArrayList<ConnectionMetaDataDTO> connectionMetaDataDTOs = new ArrayList<>(); for(IBlaubotConnectionAcceptor acceptor : acceptors) { connectionMetaDataDTOs.add(acceptor.getConnectionMetaData()); } return connectionMetaDataDTOs; } /** * Filters a list of connection meta data objects by a list of supported acceptor types (like intersect, but not a set) * @param connectionMetaDataList the list of acceptor meta data * @param supportedAcceptorTypes the list of supported acceptor types to filter ourAcceptorMetaDataList * @return new list containing only the meta data from ourAcceptorMetaDataList which acceptor type matches one of the strings in supportedAcceptorTypes */ public static List<ConnectionMetaDataDTO> filterBySupportedAcceptorTypes(List<ConnectionMetaDataDTO> connectionMetaDataList, List<String> supportedAcceptorTypes) { ArrayList<ConnectionMetaDataDTO> filtered = new ArrayList<>(); for(ConnectionMetaDataDTO metaData : connectionMetaDataList) { if(supportedAcceptorTypes.contains(metaData.getConnectionType())) { filtered.add(metaData); } } return filtered; } /** * Extracts all supported connection types from a list of connectors * @param connectors the connectors * @return a list of strings representing the connection types of each of the connectors */ public static List<String> extractSupportedConnectionTypes(List<IBlaubotConnector> connectors) { ArrayList<String> supportedConTypes = new ArrayList<>(); for(IBlaubotConnector connector : connectors) { for(String suppportedType : connector.getSupportedAcceptorTypes()) { supportedConTypes.add(suppportedType); } } return supportedConTypes; } }