package model.osagaia; /** * * @author Dalmau */ import util.Commands; import platform.ClassManager.KalimuchoClassLoader; import platform.ClassManager.ClassLoaderFromJarFile; import platform.ClassManager.LoadedClass; import model.interfaces.IContainer; import platform.servicesregister.ServicesRegisterManager; import platform.servicesregister.ServiceInUseException; // Classe du conteneur de CM (Osagaia) /** * BCContainer is created with its name, the name of the BC's class, * the name of its input connector and the name of its output connector * ("null" when no connector).<br> * The container creates an instance of the BC, creates the input units, * the output unit and the control unit of an Osagaia container.<br> * It is a thread waiting for inputs and output connections of the BC, * then it runs the BC and register the control unit as a service for the platform. * * @author Dalmau */ public class BCContainer implements IContainer, Runnable { private String monNom; // nom symbolique du composant private String classeCM; // classe du CM private String[] connecteurSortie; // noms symboliques des connecteurs en sortie private String[] connecteurEntree; // noms symboliques des connecteurs en entree private InputUnit[] ue; private OutputUnit us; private ControlUnit uc; private BCModel cm; private ClassLoaderFromJarFile classLoader; /** * Construction of a BC container whith the class name of the BC * * @param name symbolic name of the BC * @param classOfCM class of the BC * @param inputConnectors names of input connectors * @param outputConnector names of output connectors */ public BCContainer(String name, String classOfCM, String[] inputConnectors, String[] outputConnectors) { monNom = name; classeCM = classOfCM; connecteurEntree = inputConnectors; connecteurSortie = outputConnectors; // Creer les UE ue=new InputUnit[connecteurEntree.length]; for (int i=0; i<connecteurEntree.length; i++) { if (!connecteurEntree[i].equals(Commands.ES_NULL)) ue[i]=new InputUnit(i); else ue[i]=null; } // creer l'US us=null; int i=0; boolean usCree = false; while ((!usCree) && (i<connecteurSortie.length)) { if (!connecteurSortie[i].equals(Commands.ES_NULL)) { us=new OutputUnit(); usCree = true; } else i++; } uc=null; try { // creation d'une instance de CM d'apres le nom de la classe LoadedClass lc = KalimuchoClassLoader.loadOrCreateClass(classeCM); classLoader = lc.getChargeur(); if (classLoader instanceof ClassLoaderFromJarFile) classLoader.addLink(); Class<?> tmpClass = lc.getClasse(); cm = (BCModel)tmpClass.newInstance(); cm.setName(monNom); cm.setContainer(this); cm.setInputOutputUnits(ue, us); // lier le CM e son UE et son US // creer l'UC uc=new ControlUnit(connecteurEntree, connecteurSortie, ue, cm, us); cm.setControlUnit(uc); // lier le CM e son UC } catch (ClassNotFoundException cnfe) { System.err.println("Osagaia Container "+monNom+" : BC class unknown"); } catch (InstantiationException cnfe) { System.err.println("Osagaia Container "+monNom+" : BC class can't be instantiated"); } catch (IllegalAccessException cnfe) { System.err.println("Osagaia Container "+monNom+" : Illegal access to the BC class"); } // le reste de la construction du conteneur est fait dans un thread car // elle attend que les connecteurs d'entree et de sortie soient crees new Thread(this).start(); } /** * Construction of a BC container with a serialized BC * * @param name symbolic name of the BC * @param CM serialized BC * @param inputConnectors names of input connectors * @param outputConnector names of output connectors */ public BCContainer(String name, BCModel CM, ClassLoaderFromJarFile cl, String[] inputConnectors, String[] outputConnectors) { monNom = name; connecteurEntree = inputConnectors; connecteurSortie = outputConnectors; // Creer les UE ue=new InputUnit[connecteurEntree.length]; for (int i=0; i<connecteurEntree.length; i++) { if (!connecteurEntree[i].equals(Commands.ES_NULL)) ue[i]=new InputUnit(i); else ue[i]=null; } // creer l'US us=null; int i=0; boolean usCree = false; while ((!usCree) && (i<connecteurSortie.length)) { if (!connecteurSortie[i].equals(Commands.ES_NULL)) { us=new OutputUnit(); usCree = true; } else i++; } uc=null; cm = CM; classLoader = cl; classeCM = cm.getClass().getName(); cm.setName(monNom); cm.setContainer(this); cm.setInputOutputUnits(ue, us); // lier le CM e son UE et son US // creer l'UC uc=new ControlUnit(connecteurEntree, connecteurSortie, ue, cm, us); cm.setControlUnit(uc); // lier le CM e son UC cm.associateFilters(); // le reste de la construction du conteneur est fait dans un thread car // elle attend que les connecteurs d'entree et de sortie soient crees new Thread(this).start(); } /** * Returns the BC included in this container * @return BC included in this container */ public BCModel getBC() { return cm; } /** * Returns the class loader of the BC included in the container * @return the class loader of the BC included in the container */ public ClassLoaderFromJarFile getClassLoader() { return classLoader; } /** * Waits for inputs and output connections of the BC, * then runs the BC (start_CM method). * */ public void run() { // enregistrement du service de l'UC pour la PF try { ServicesRegisterManager.registerService(monNom, uc); } catch(ServiceInUseException siue) { System.err.println("Osagaia Container "+monNom+" : created twice"); } uc.connection(); // connecter ce composant aux connecteurs (attente de creation de ces connecteurs) uc.start_CM(); // lancer le CM (thread) } /** * Flags the BC as serialised (after a migration) */ public void setSerialized() { cm.setSerialized(); } }