package model.korrontea; import network.connectors.EncapsulatedSample; import util.Parameters; import model.StopBCException; import platform.servicesregister.ServiceClosedException; import network.connectors.ConnectorEmissionThread; /** * Class of the Output Unit of a connector<br> * Offers services for: * <ul> * <li> Run / stop the OU (when OU is stopped trying to write in it raises an exception * (class StopCMException) which will stop the BC doing data circulation in the connector) * <li> Accept a connection from an IU Osagaia or from a reseau emitter thread * <li> Accept a disconnection from an IU Osagaia or from a reseau emitter thread. * That allows a consumer suspended waiting a sample in the OU to be freed * without a sample (used when a BC or a connector is removed). * <li> Return the size of the buffer of the OU * <li> Depose a sample in the buffer of the OU * (object of class Sample or inherited class) * <li> Get a sample in the buffer of the OU * (object of class Sample or inherited class) * </ul> * * @author Dalmau */ // Classe generique de l'US Korrontea public class OutputUnit { /** * Symbolic name of the connector */ protected String monNom; // nom symbolique du connecteur /** * Contol Unit of the connector */ protected ControlUnit uc; // UC du connecteur (pour signaler les alarmes) /** * Indicate if the Output Unit is running */ protected boolean arret; // indique si l'US est arretee /** * Buffer of the Output Unit */ protected ConnectorBuffer buffer; // buffer qui reeoit les echantillons en attente dans l'US du connecteur private ConnectorEmissionThread sortieReseau; private model.osagaia.ControlUnit ucCMEnSortie; /** * Construction of a Input Unit * * @param nom symbolic name of the connector */ public OutputUnit(String nom) { monNom=nom; sortieReseau = null; ucCMEnSortie = null; uc=null; arret = true; // l'US n'est pas encore demarree // creation du buffer de l'US buffer = new ConnectorBuffer("sortie", Parameters.WARNING_LEVEL_FOR_BUFFER, Parameters.SATURATION_LEVEL_FOR_BUFFER); } // Methode de retrait d'un echantillon dans l'US /** * Get a sample in the buffer of the OU (object of class Sample or inherited class) * * @return the sample read * @throws ServiceClosedException when the connector is not available */ public EncapsulatedSample getSample() throws ServiceClosedException { // Si l'US est arretee lever une exception if (arret) throw new ServiceClosedException("US Korrontea "+monNom+" deconnectee"); attendreConnecte(); // ce retrait peut lever une exception ServiceClosedException lors d'une deconnexion return buffer.getSample(); } private synchronized void attendreConnecte() { while ((ucCMEnSortie == null) && (sortieReseau == null)) { try { wait(); } catch(InterruptedException ie) {} } } /** * Accept a connection from an IU Osagaia or from a network emitter thread * @param consumer the Osagaia IU or the emitter thread that connects * @param number number of the connected IU */ // Cette methode doit s'executer en exclusion mutuelle de celle de deconnexion et de la conversion d'echantillon public synchronized void consumerConnection(Object consumer, int number) { // methode utilise par le consommateur pour indiquer qu'il est connecte if (consumer instanceof model.osagaia.ControlUnit) { ucCMEnSortie = (model.osagaia.ControlUnit)consumer; buffer.consumerConnection(ucCMEnSortie, number); sortieReseau = null; } else { buffer.consumerConnection(null, number); sortieReseau = (ConnectorEmissionThread)consumer; ucCMEnSortie = null; } notifyAll(); // debloquer le consommateur en attente dans getSample (appel de attendreConnecte) } /** * Accept a disconnection from an IU Osagaia or from a reseau emitter thread */ // Cette methode doit s'executer en exclusion mutuelle de celle de connexion et de la conversion d'echantillon public synchronized void consumerDisconnection() {// methode utilise par le consommateur pour indiquer qu'il se deconnecte buffer.consumerDisconnection(); sortieReseau = null; ucCMEnSortie = null; } /** * Accept a connection from a listener * @param uc control unit * @param number number of the connected IU */ public void listenerConnection(model.osagaia.ControlUnit uc, int number) { // methode utilise par le consommateur pour indiquer q'un ecouteur d'entree est connecte buffer.listenerConnection(uc, number); } // Association de l'UC du connecteur e cette US (pour signaler les evenements) /** * Associate the Control Unit of the connector * * @param uc Control Unit of the connector */ final public void setUC(ControlUnit uc) { this.uc=uc; buffer.setUC(uc); } /** * Start the Output Unit */ final public void start() { // lancement de l'US buffer.start(); // lancement du buffer arret = false; // l'US est lancee } /** * Stops the OU of the connectror */ final public void stop() { // Arret de l'US. buffer.stop(); // arret du buffer arret=true; // 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 // Desenregistrer le service offert par l'US // Si elle est connectee e un thread d'emission ceci terminera ce thread } /** * Return the size of the buffer of the Input Unit * * @return size of the buffer of the Input Unit * (number of samples waiting in this buffer) */ public int getBufferSize() { return buffer.getSize(); } /** * Returns the output buffer of the connector * @return the output buffer of the connector */ public ConnectorBuffer getBuffer() { return buffer; } // Methode permettant au CM d'ecrire un echantillon dans l'US // Utilisable par les CM qui doivent faire des traitements sur le flux // Cette methode peut lever une exception si le CM doit etre arrete /** * Write an encapsulated sample or a sample in the output connector's buffer * @param ech the encapsulated sample to put in the connector's buffer * @throws StopBCException */ public void writeInOutputUnit(EncapsulatedSample ech) throws StopBCException { if (arret) { // Si l'US est arretee lever une exception pour arreter le CM throw(new StopBCException("CM arrete lors d'une lecture dans l'UE")); } else { buffer.deposeSample(ech); // deposer l'echantillon dans le buffer } } }