package model.osagaia; import util.streams.samples.Sample; import model.StopBCException; import platform.servicesregister.ServicesRegisterManager; import platform.servicesregister.ServiceClosedException; import util.Commands; import network.connectors.EncapsulatedSample; import java.util.Vector; /** * Osagaia containeres Output Unit<br> * Offers methods to:<br> * <ul> * <li> Connect to the output connector. * That means waiting until this connector is available. * <li> Disconnect from the output connector * <li> Stop => raises an exception to the BC at the next try * of writing to output stream (that will stop the BC) * <li> Write a sample (class Sample or inherited) * in the output stream. Suspends the BC on a semaphore until either: * <ul> * <li> Sample is sent to the connector * <li> Output connector has been removed * <li> BCes output has been disconnected * <li> Output unit has been stopped * </ul></ul><br> * When BCes output is disconnected or when output connector is removed, * the output unit waits for a reconnection. * * @author Dalmau */ // Clase de l'US Osagaia public class OutputUnit { private Vector<String> nomsconnecteursSortie; // nom symbolique de ce connecteur private boolean arret; // indique si l'US est arretee private boolean connecte; // indique si l'US est connectee /** * Construction of an Output Unit */ public OutputUnit() { arret=false; // l'US est prete e fonctionner connecte=false; // l'US n'est pas connectee nomsconnecteursSortie = new Vector<String>(); } /** * Stops the output Unit<br> * raises an exception to the BC at the next try * of writing to output stream (that will stop the BC) */ public synchronized void stop() { /* utilise pour que l'US cesse de fonctionner * quand ce booleen est a true tout appel e une ecriture dans l'US * provoque une exception de classe StopCMException qui sera utilisee * par le CM pour s'arreter */ arret=true; notifyAll(); // debloquer le CM s'il est en attente de reconnexion } /** * Connects the Output Unit to a connector * * @param nom name of the connector to connect with */ public synchronized void connection(String nom) { if (!nom.equals(Commands.ES_NOT_USED)) { // ouverture du service de l'UE du connecteur en sortie model.korrontea.ControlUnit accesUE = (model.korrontea.ControlUnit)ServicesRegisterManager.platformWaitForService(nom); nomsconnecteursSortie.addElement(nom); connecte=true; // l'US est connectee notifyAll(); // debloquer le CM s'il est en attente de reconnexion } } /** * Disconnects the Output Unit from all connectors */ public synchronized void disconnection() { nomsconnecteursSortie.removeAllElements(); connecte=false; // l'US n'est plus connectee } /** * Writes a sample produced by the BC in the OU of the BC container * @param o the sample produced by the BC * @throws StopBCException if the OU is stopped, that will stop the BC if it tries to produce a sample */ public void writeInOutputUnit(Sample o) throws StopBCException { synchronized(this) { // semaphore debloque par une reconnexion ou un arret de l'US while (!connecte && !arret){ // attendre d'etre connecte ou arrete try { wait(); } catch(InterruptedException ie) {} } } // si l'US est arretee lever une exception pour arreter le CM if (arret) throw(new StopBCException("CM arrete lors d'une ecriture dans l'US")); else { // l'US n'est pas arretee boolean nonEnvoye=true; while((nonEnvoye) && connecte && (!arret)) { // tenter d'envoyer l'echantillon dans un connecteur en sortie // l'US peut ne pas pouvoir envoyer l'echantillon si aucun connecteur n'existe int i = 0; while (i<nomsconnecteursSortie.size()) { String nomconnecteurSortie = nomsconnecteursSortie.elementAt(i); try { // essayer de l'envoyer model.korrontea.ControlUnit accesUE = (model.korrontea.ControlUnit)ServicesRegisterManager.lookForService(nomconnecteurSortie); model.korrontea.InputUnit serveur = accesUE.getIU(); o.setExpeditor("localhost"); serveur.deposeSample(new EncapsulatedSample(o)); nonEnvoye=false; // l'envoi a ete fait i++; // on essaye le connecteur suivant } catch (ServiceClosedException ace) { // Le connecteur n'existe plus nomsconnecteursSortie.removeElementAt(i); // on l'enleve } } if (nonEnvoye) { // on n'a reussi e l'envoyer sur aucun connecteur connecte=false; // l'US n'est plus connectee => attendre une reconnexion ou un arret synchronized(this) { // semaphore debloque par une reconnexion ou un arret de l'US while (!connecte && !arret){ // attendre d'etre connecte ou arrete try { wait(); } catch(InterruptedException ie) {} } } } } // si l'US a ete arretee pendant une tentative de depet de l'echantillon il faut arreter le CM if (arret) throw(new StopBCException("CM arrete lors d'une ecriture dans l'US")); } } }