package model.korrontea; import model.interfaces.control.IBusinessComponent; import model.StopBCException; import network.connectors.EncapsulatedSample; /** * Abstract class from which data circulation BCs of connectors inherit. * In order to create a different data circulation politic in a connector * it is possible to write a specific BC which extends this class * and has the same structure than an Osagaia BC. * This class offers methods for reading and writing samples.<br> * This class offers methods to: * <ul> * <li> Stop the BC * <li> Wait for the BC to terminate * <li> Read and write samples * </ul> * The model of a Korrontea BC is a thread which: * <ul> * <li> Calls the init method of the BC * <li> Calls the run_CM method of the BC (infinite loop) * <li> Calls the destroy method of the BC if an exception stops the BC. * This exception is raised when the BC try to read in the IU * or to write in the OU as the platform is removing the connector. * </ul> * * @author Dalmau */ // Classe abstraite permettant de creer ses propres CM de transfert de flux public abstract class ConnectorBCModel implements IBusinessComponent, Runnable { private Thread current = null; // thread java contenant le CM private InputUnit ue = null; // lien avec l'UE private OutputUnit us = null; // lien avec l'US private boolean enMarche; // indique si le CM de transfert est en marche // La methode run_CM doit etre surchagee elle contient la boucle de transfert de flux /** * This method need to be overwriten<br> * It is an infinite loop that transfers data inside the connector<br> * Called after init and before destroy * * @throws StopBCException when the BC is stopped by the platform */ abstract public void run_CM() throws StopBCException; // La methode levelStateQdS doit etre surchagee pour retourner la QdS du CM de transfert de flux /** * Method called by the platform to get the BC QoS level (0 to 1) * @return the BC's QoS level (0 for worst to 1 for best) */ abstract public float levelStateQoS(); // Methodes qui peuvent etre reecrites par le concepteur // par defaut elles ne font rien /** * Method called when the BC is started (to be writed) */ public void init() {} // appelee e la creation du CM de transfert /** * Method called when the BC is stopped (to be writed) */ public void destroy() {} // appelee e la suppression du CM de transfert /** * Test if a sample is available on the input stream<br> * * @return true if a sample is available * @throws StopBCException when the BC is stopped by the platform */ final public boolean isSampleAvailableOnInput() throws StopBCException { // Regerder si un echantillon est disponible dans l'UE return ue.isInputAvailable(); } /** * Waits for a sample of the class defined by the <b>setInputClassFilter</b> method in the input stream. * This method suspends the BC until a sample assignment-compatible with this class is available.<br> * The name of the class of samples to be read is the one previously defined by the * <b>setInputClassFilter</b> method of the BC. If the sample actually present in the connector * is not assignment-compatible with this class it is discarded and * the Input Unit waits for another one. * * @return the sample read * @throws StopBCException when the BC is stopped by the platform */ final public EncapsulatedSample readSample() throws StopBCException { // lire un echantillon dans l'UE return ue.readInInputUnit(); } /** * Writes a sample to the output stream * * @param sample the sample to write * @throws StopBCException when the BC is stopped by the platform */ final public void writeSample(EncapsulatedSample sample) throws StopBCException { // ecrire un echantillon dans l'US us.writeInOutputUnit(sample); } /** * Calls init, then run_CM. When the BC is stopped calls destroy */ final public void run() {// methode d'execution d'un CM de transfert // le lancement du CM appelle init puis run_CM // en cas d'exception provoquee par l'UE ou l'US appel de destroy init(); try { run_CM(); } catch (StopBCException scme) { destroy(); enMarche=false; // le CM est arrete } } /** * Starts the BC of the connector */ final public void start() { // lancement du CM (thread) enMarche=true; if (current==null) { current = new Thread(this); current.start(); // le CM est en marche } } /** * Waits for the connector's BC to terminate */ final public void join() { // attente de terminaison du CM if (current != null) { while (enMarche) {} // attendre la terminaison du run_CM } } /** * Set the input and ouput units of this connector's BC * @param inputUnit input unit * @param outputUnit output unit */ final public void setInputOutputUnits(InputUnit inputUnit, OutputUnit outputUnit) { // association du CM de transfert e son UE et son US this.ue = inputUnit; this.us = outputUnit; } // Methodes permettant au CM de transfert d'acceder e son UE et son US /** * Returns the Input Unit of the connector * * @return the Input Unit of the connector */ final public InputUnit getIU() { return (InputUnit)ue; } /** * Returns the Output Unit of the connector * * @return the Output Unit of the connector */ final public OutputUnit getOU() { return (OutputUnit)us; } }