From 7d631c2f8df6c9c3901a5d9bb4e3e9bce1784cb2 Mon Sep 17 00:00:00 2001 From: ribes Date: Tue, 27 Feb 2007 10:05:51 +0000 Subject: [PATCH] Adding DSC's basic layer. Needs to fix CORBA headers declarations and fix debug infos. --- configure.ac | 2 + src/DSC/DSC_Basic/ConnectionManager_i.cxx | 77 ++++ src/DSC/DSC_Basic/ConnectionManager_i.hxx | 61 +++ src/DSC/DSC_Basic/DSC_Callbacks.hxx | 47 +++ src/DSC/DSC_Basic/DSC_i.cxx | 19 + src/DSC/DSC_Basic/DSC_i.hxx | 141 +++++++ src/DSC/DSC_Basic/DSC_interface.cxx | 389 ++++++++++++++++++ src/DSC/DSC_Basic/DSC_interface.hxx | 132 ++++++ src/DSC/DSC_Basic/Makefile.am | 89 ++++ src/DSC/DSC_Basic/PortProperties_i.cxx | 25 ++ src/DSC/DSC_Basic/PortProperties_i.hxx | 23 ++ .../SALOME_ConnectionManagerServer.cxx | 37 ++ src/DSC/Makefile.am | 26 ++ src/Makefile.am | 3 +- 14 files changed, 1070 insertions(+), 1 deletion(-) create mode 100644 src/DSC/DSC_Basic/ConnectionManager_i.cxx create mode 100644 src/DSC/DSC_Basic/ConnectionManager_i.hxx create mode 100644 src/DSC/DSC_Basic/DSC_Callbacks.hxx create mode 100644 src/DSC/DSC_Basic/DSC_i.cxx create mode 100644 src/DSC/DSC_Basic/DSC_i.hxx create mode 100644 src/DSC/DSC_Basic/DSC_interface.cxx create mode 100644 src/DSC/DSC_Basic/DSC_interface.hxx create mode 100644 src/DSC/DSC_Basic/Makefile.am create mode 100644 src/DSC/DSC_Basic/PortProperties_i.cxx create mode 100644 src/DSC/DSC_Basic/PortProperties_i.hxx create mode 100644 src/DSC/DSC_Basic/SALOME_ConnectionManagerServer.cxx diff --git a/configure.ac b/configure.ac index 1a623565e..39f269516 100644 --- a/configure.ac +++ b/configure.ac @@ -518,6 +518,8 @@ AC_OUTPUT([ \ ./src/Communication/Makefile \ ./src/Communication_SWIG/Makefile \ ./src/Container/Makefile \ + ./src/DSC/Makefile \ + ./src/DSC/DSC_Basic/Makefile \ ./src/GenericObj/Makefile \ ./src/HDFPersist/Makefile \ ./src/KERNEL_PY/Makefile \ diff --git a/src/DSC/DSC_Basic/ConnectionManager_i.cxx b/src/DSC/DSC_Basic/ConnectionManager_i.cxx new file mode 100644 index 000000000..66dd032fa --- /dev/null +++ b/src/DSC/DSC_Basic/ConnectionManager_i.cxx @@ -0,0 +1,77 @@ +// André Ribes EDF R&D - 2006 +// +#include "ConnectionManager_i.hxx" +#include "SALOME_NamingService.hxx" + +ConnectionManager_i::ConnectionManager_i(CORBA::ORB_ptr orb) { + SALOME_NamingService * ns = new SALOME_NamingService(orb); + const char * ConnectionManagerNameInNS = "/ConnectionManager"; + ns->Register(_this(), ConnectionManagerNameInNS); + + current_id = 0; + pthread_mutex_init(&mutex, NULL); +} + +ConnectionManager_i::~ConnectionManager_i() {} + +/* Cette méthode connecte deux ports ensembles. + * Elle permet de rendre plus simple l'utilisation du modèle de programmation + * à base de ports. + */ +Engines::ConnectionManager::connectionId +ConnectionManager_i::connect(Engines::DSC_ptr uses_component, + const char* uses_port_name, + Engines::DSC_ptr provides_component, + const char* provides_port_name) +throw (Engines::DSC::PortNotDefined, + Engines::DSC::BadPortType, + Engines::DSC::NilPort) +{ + + Ports::Port_ptr p_port = provides_component->get_provides_port(provides_port_name, false); + uses_component->connect_uses_port(uses_port_name, p_port); + provides_component->connect_provides_port(provides_port_name); + + // Ajout de l'id dans la map comme tout s'est bien passé + // + // Protection du current_id pour récupérer un id unique + pthread_mutex_lock(&mutex); + Engines::ConnectionManager::connectionId rtn_id = current_id; + current_id += 1; + pthread_mutex_unlock(&mutex); + + // Creation de la structure et ajout dans la map + connection_infos * infos = new connection_infos(); + infos->uses_component = Engines::DSC::_duplicate(uses_component); + infos->uses_port_name = uses_port_name; + infos->provides_component = Engines::DSC::_duplicate(provides_component); + infos->provides_port_name = provides_port_name; + infos->provides_port = Ports::Port::_duplicate(p_port); + + // Ajout dans la map + ids[rtn_id] = infos; + + return rtn_id; +} + +void +ConnectionManager_i::disconnect(const Engines::ConnectionManager::connectionId id, + Engines::DSC::Message message) +throw (Engines::ConnectionManager::BadId) +{ + // Verification que l'id existe + ids_it = ids.find(id); + if (ids_it == ids.end()) + throw Engines::ConnectionManager::BadId(); + + // Recuperation des infos + connection_infos * infos = ids[id]; + infos->provides_component->disconnect_provides_port(infos->provides_port_name.c_str(), + message); + infos->uses_component->disconnect_uses_port(infos->uses_port_name.c_str(), + Ports::Port::_duplicate(infos->provides_port), + message); + // Nettoyage + delete infos; + ids.erase(id); +} diff --git a/src/DSC/DSC_Basic/ConnectionManager_i.hxx b/src/DSC/DSC_Basic/ConnectionManager_i.hxx new file mode 100644 index 000000000..f872d8748 --- /dev/null +++ b/src/DSC/DSC_Basic/ConnectionManager_i.hxx @@ -0,0 +1,61 @@ +// André Ribes EDF R&D - 2006 +// +#ifndef _CONNECTION_MANAGER_I_HXX_ +#define _CONNECTION_MANAGER_I_HXX_ + +#include +#include +#include "DSC_Engines.hh" +#include + +/*! \class ConnectionManager_i + * \brief This class implements the interface Engines::ConnectionManager. + */ +class ConnectionManager_i : + public virtual POA_Engines::ConnectionManager +{ + public : + ConnectionManager_i(CORBA::ORB_ptr orb); + ~ConnectionManager_i(); + + /*! + * \see Engines::ConnectionManager::connect + */ + Engines::ConnectionManager::connectionId connect(Engines::DSC_ptr uses_component, + const char* uses_port_name, + Engines::DSC_ptr provides_component, + const char* provides_port_name) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::BadPortType, + Engines::DSC::NilPort); + + /*! + * \see Engines::ConnectionManager::disconnect + */ + void disconnect(const Engines::ConnectionManager::connectionId id, + Engines::DSC::Message message) + throw (Engines::ConnectionManager::BadId); + + private : + + struct connection_infos { + Engines::DSC_ptr uses_component; + std::string uses_port_name; + Engines::DSC_ptr provides_component; + std::string provides_port_name; + Ports::Port_ptr provides_port; + }; + + typedef std::map ids_type; + typedef std::map::iterator ids_it_type; + + ids_type ids; + ids_it_type ids_it; + + int current_id; + pthread_mutex_t mutex; +}; + +#endif diff --git a/src/DSC/DSC_Basic/DSC_Callbacks.hxx b/src/DSC/DSC_Basic/DSC_Callbacks.hxx new file mode 100644 index 000000000..b5019813f --- /dev/null +++ b/src/DSC/DSC_Basic/DSC_Callbacks.hxx @@ -0,0 +1,47 @@ +// André Ribes EDF R&D - 2006 +// +#ifndef _DSC_CALLBACKS_HXX_ +#define _DSC_CALLBACKS_HXX_ + +#include "DSC_Engines.hh" + +/*! \class DSC_Callbacks + * \brief this is an abstract that defines the methods that the component + * uses to prevent the component user code that the state of the component has changed. + * Currently only port's connection modifications are signaled. + */ +class DSC_Callbacks +{ + public: + virtual ~DSC_Callbacks() {} + + /*! + * \brief This method is used by the component when the number of connection + * on a provides port changes. This information helps the user code to detect + * operation on his ports. + * + * + * \param provides_port_name the name of the provides name that has changed. + * \param connection_nbr the new number of connection on the provides port. + * \param message contains informations about the modification of the port. + */ + virtual void provides_port_changed(const char* provides_port_name, + int connection_nbr, + const Engines::DSC::Message message) = 0; + + /*! + * \brief This method is used by the component when the number of connection + * on a uses port changes. This information helps the user code to detect + * operation on his ports. + * + * + * \param uses_port_name the name of the uses name that has changed. + * \param connection_nbr the new sequence representing the uses port. + * \param message contains informations about the modification of the port. + */ + virtual void uses_port_changed(const char* uses_port_name, + Engines::DSC::uses_port * new_uses_port, + const Engines::DSC::Message message) = 0; +}; + +#endif diff --git a/src/DSC/DSC_Basic/DSC_i.cxx b/src/DSC/DSC_Basic/DSC_i.cxx new file mode 100644 index 000000000..b84a496f1 --- /dev/null +++ b/src/DSC/DSC_Basic/DSC_i.cxx @@ -0,0 +1,19 @@ +// André Ribes EDF R&D - 2006 +// + +#include "DSC_i.hxx" + +Engines_DSC_i:: +Engines_DSC_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName, + bool notif) : Engines_Component_i(orb, + poa, + contId, + instanceName, + interfaceName) {} + +Engines_DSC_i::~Engines_DSC_i() {} + diff --git a/src/DSC/DSC_Basic/DSC_i.hxx b/src/DSC/DSC_Basic/DSC_i.hxx new file mode 100644 index 000000000..a97b9d78e --- /dev/null +++ b/src/DSC/DSC_Basic/DSC_i.hxx @@ -0,0 +1,141 @@ +// André Ribes EDF R&D - 2006 +// +#ifndef _DSC_I_HXX_ +#define _DSC_I_HXX_ + +#include +#include +#include +#include + +#include "SALOME_Component_i.hxx" +#include "DSC_interface.hxx" + +/*! \class Engines_DSC_i + * \brief This class implements the interface Engines::DSC + */ +class Engines_DSC_i: + public Engines_Component_i, // On ne met pas virtual afin que ce soit cette classe + // qui appelle le bon constructeur de Engines_Component_i. + // Si on mettait virtual ce serait a la classe dérivée + // de Engines_DSC_i qui devrait appeler le bon constructeur + // de Engines_Component_i. + public virtual POA_Engines::DSC, + public Engines_DSC_interface +{ +public: + Engines_DSC_i(CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableServer::ObjectId * contId, + const char *instanceName, + const char *interfaceName, + bool notif = false); + + virtual ~Engines_DSC_i(); + + /*! + * \see Engines::DSC::add_provides_port + */ + virtual void add_provides_port(Ports::Port_ptr ref, + const char* provides_port_name, + Ports::PortProperties_ptr port_prop) + throw (Engines::DSC::PortAlreadyDefined, + Engines::DSC::NilPort, + Engines::DSC::BadProperty) { + Engines_DSC_interface::add_provides_port(ref, + provides_port_name, + port_prop); + } + + /*! + * \see Engines::DSC::add_uses_port + */ + virtual void add_uses_port(const char* repository_id, + const char* uses_port_name, + Ports::PortProperties_ptr port_prop) + throw (Engines::DSC::PortAlreadyDefined, + Engines::DSC::BadProperty) { + Engines_DSC_interface::add_uses_port(repository_id, + uses_port_name, + port_prop); + } + + /*! + * \see Engines::DSC::get_provides_port + */ + virtual Ports::Port_ptr get_provides_port(const char* provides_port_name, + const CORBA::Boolean connection_error) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected) { + return Engines_DSC_interface::get_provides_port(provides_port_name, + connection_error); + } + + /*! + * \see Engines::DSC::get_uses_port + */ + virtual Engines::DSC::uses_port * get_uses_port(const char* uses_port_name) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected) { + return Engines_DSC_interface::get_uses_port(uses_port_name); + } + + /*! + * \see Engines::DSC::connect_provides_port + */ + virtual void connect_provides_port(const char* provides_port_name) + throw (Engines::DSC::PortNotDefined) { + Engines_DSC_interface::connect_provides_port(provides_port_name); + } + + /*! + * \see Engines::DSC::connect_uses_port + */ + virtual void connect_uses_port(const char* uses_port_name, + Ports::Port_ptr provides_port_ref) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::BadPortType, + Engines::DSC::NilPort) { + Engines_DSC_interface::connect_uses_port(uses_port_name, + provides_port_ref); + } + + /*! + * \see Engines::DSC::is_connected + */ + virtual CORBA::Boolean is_connected(const char* port_name) + throw (Engines::DSC::PortNotDefined) { + return Engines_DSC_interface::is_connected(port_name); + } + + /*! + * \see Engines::DSC::disconnect_provides_port + */ + virtual void disconnect_provides_port(const char* provides_port_name, + const Engines::DSC::Message message) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected) { + Engines_DSC_interface::disconnect_provides_port(provides_port_name, + message); + } + + /*! + * \see Engines::DSC::disconnect_uses_port + */ + virtual void disconnect_uses_port(const char* uses_port_name, + Ports::Port_ptr provides_port_ref, + const Engines::DSC::Message message) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected, + Engines::DSC::BadPortReference) { + Engines_DSC_interface::disconnect_uses_port(uses_port_name, + provides_port_ref, + message); + } + virtual Ports::PortProperties_ptr get_port_properties(const char* port_name) + throw (Engines::DSC::PortNotDefined) { + return Engines_DSC_interface::get_port_properties(port_name); + } +}; + +#endif diff --git a/src/DSC/DSC_Basic/DSC_interface.cxx b/src/DSC/DSC_Basic/DSC_interface.cxx new file mode 100644 index 000000000..69b7f3021 --- /dev/null +++ b/src/DSC/DSC_Basic/DSC_interface.cxx @@ -0,0 +1,389 @@ + +// André Ribes EDF R&D - 2006 +// + +#include "DSC_interface.hxx" + +Engines_DSC_interface::Engines_DSC_interface() {} + +Engines_DSC_interface::~Engines_DSC_interface() {} + +/* Ajoute le provides port "name" avec sa reference "ref". + * Lève PortAlreadyDefined si le port est déjà défini. + * Lève NilPort si la reference du port est nil. + */ +void +Engines_DSC_interface::add_provides_port(Ports::Port_ptr ref, + const char* provides_port_name, + Ports::PortProperties_ptr port_prop) +throw (Engines::DSC::PortAlreadyDefined, + Engines::DSC::NilPort, + Engines::DSC::BadProperty) +{ + // Test des arguments de la méthode + assert(provides_port_name); + if (CORBA::is_nil(ref)) + throw Engines::DSC::NilPort(); + if (CORBA::is_nil(port_prop)) + throw Engines::DSC::BadProperty(); + + my_ports_it = my_ports.find(provides_port_name); + if (my_ports_it == my_ports.end()) { + // Creation d'un nouveau port de type provides. + port_t * new_port = new port_t(); + new_port->type = provides; + new_port->connection_nbr = 0; + new_port->provides_port_ref = Ports::Port::_duplicate(ref); + new_port->port_prop = Ports::PortProperties::_duplicate(port_prop); + + // Enregistrement du port dans la map. + my_ports[provides_port_name] = new_port; + } + else + throw Engines::DSC::PortAlreadyDefined(); +} + +/* Ajoute le uses port "name" avec son repository_id Corba. + * Lève PortAlreadyDefined si le port est déjà défini. + */ +void +Engines_DSC_interface::add_uses_port(const char* repository_id, + const char* uses_port_name, + Ports::PortProperties_ptr port_prop) +throw (Engines::DSC::PortAlreadyDefined, + Engines::DSC::BadProperty) +{ + // Test des arguments de la méthode + // Note : Il est difficile de tester si la chaîne du + // repository_id est valide ... + assert(repository_id); + assert(uses_port_name); + if (CORBA::is_nil(port_prop)) + throw Engines::DSC::BadProperty(); + + my_ports_it = my_ports.find(uses_port_name); + if (my_ports_it == my_ports.end()) { + // Creation d'un nouveau port de type uses. + port_t * new_port = new port_t(); + new_port->type = uses; + new_port->connection_nbr = 0; + new_port->uses_port_refs.length(0); + new_port->repository_id = repository_id; + new_port->port_prop = Ports::PortProperties::_duplicate(port_prop); + + // Enregistrement du port dans la map. + my_ports[uses_port_name] = new_port; + } + else + throw Engines::DSC::PortAlreadyDefined(); +} + +/* Fournit le port provides qui a le nom "provides_port_name" dans les my_ports. + * Lève l'exception Engines::DSC::PortNotDefined s'il ne trouve + * pas le port. + * Le booleen permet de savoir s'il faut donner ou non le port s'il est connecté + * ou non. + */ +Ports::Port_ptr +Engines_DSC_interface::get_provides_port(const char* provides_port_name, + const CORBA::Boolean connection_error) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected, + Engines::DSC::BadPortType) +{ + // Test des arguments de la méthode + assert(provides_port_name); + + Ports::Port_ptr rtn_port = Ports::Port::_nil(); +// std::cout << "---- DSC_Interface : MARK 1 ---- Recherche de : " << provides_port_name << "----" << std::endl; +// ports::iterator it; +// std::cout << "----> "; +// for(it=my_ports.begin();it!=my_ports.end();++it) +// std::cout << "|"<<(*it).first<<"|, "; +// std::cout << std::endl; + + my_ports_it = my_ports.find(provides_port_name); + if (my_ports_it == my_ports.end()) + throw Engines::DSC::PortNotDefined(); + if (my_ports[provides_port_name]->type != provides) { + Engines::DSC::BadPortType BPT; + BPT.expected = CORBA::string_dup("Expected a provides port"); + BPT.received = CORBA::string_dup((std::string("Received a uses/none port : ")+provides_port_name).c_str()); + throw BPT; + } + + if (my_ports[provides_port_name]->connection_nbr == 0 && connection_error) + throw Engines::DSC::PortNotConnected(); + + rtn_port = Ports::Port::_duplicate(my_ports[provides_port_name]->provides_port_ref); + return rtn_port; +} + +/* Fournit le port uses qui a le nom "uses_port_name" s'il existe et s'il est + * connecté. + * Dans le cas contraire lève les exceptions : + * PortNotDefined, PortNotConnected. + */ +Engines::DSC::uses_port * +Engines_DSC_interface::get_uses_port(const char* uses_port_name) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected, + Engines::DSC::BadPortType) +{ + // Test des arguments de la méthode + assert(uses_port_name); + + Engines::DSC::uses_port * rtn_port = NULL; + // On commence par tester si le port existe + my_ports_it = my_ports.find(uses_port_name); + if (my_ports_it == my_ports.end()) + throw Engines::DSC::PortNotDefined(); + if (my_ports[uses_port_name]->type != uses){ + Engines::DSC::BadPortType BPT; + BPT.expected = CORBA::string_dup("Expected a uses port"); + BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str()); + throw BPT; + } + + // On regarde maintenant si le port est connecté + if (my_ports[uses_port_name]->connection_nbr > 0) { + rtn_port = new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs); + } + else + throw Engines::DSC::PortNotConnected(); + + return rtn_port; +} + + +/* + * Cette méthode prévient par le biais de l'attribut connection_nbr + * que le port provides est connecté à un uses port de plus. + * Notons que pour le moment le provides_port n'a pas de référence sur le composant + * qui détient le uses port. Le modèle actuel considère que c'est au + * "framework" ou a l'application de gérer les connexions et les déconnexions. + * Il n'y a donc pas de callback entre deux ports connectés. + * + */ +void +Engines_DSC_interface::connect_provides_port(const char* provides_port_name) + throw (Engines::DSC::PortNotDefined) +{ + assert(provides_port_name); + + // Le port uses existe t'il ? + my_ports_it = my_ports.find(provides_port_name); + if (my_ports_it == my_ports.end()) + throw Engines::DSC::PortNotDefined(); + if (my_ports[provides_port_name]->type != provides) + throw Engines::DSC::PortNotDefined(); + + + // Augmentation du nombre de connexions + my_ports[provides_port_name]->connection_nbr += 1; + // On prévient le code utilisateur + provides_port_changed(provides_port_name, + my_ports[provides_port_name]->connection_nbr, + Engines::DSC::AddingConnection + ); +} + +/* Cette méthode permet d'ajouter une connexion à un port uses. + * Elle appelle ensuite une méthode abstraite que le composant doit + * implémenter afin d'être averti lorsque les connexions changent. + * En effet, l'utilisateur doit ensuite prendre le nouveau uses_port + * fournit dans le callback. + * + */ +void +Engines_DSC_interface::connect_uses_port(const char* uses_port_name, + Ports::Port_ptr provides_port_ref) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::BadPortType, + Engines::DSC::NilPort) +{ + assert(uses_port_name); + + // Le port uses existe t'il ? + my_ports_it = my_ports.find(uses_port_name); + if (my_ports_it == my_ports.end()) + throw Engines::DSC::PortNotDefined(); + if (my_ports[uses_port_name]->type != uses) { + Engines::DSC::BadPortType BPT; + BPT.expected = CORBA::string_dup("Expected a uses port"); + BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str()); + throw BPT; + } + + // La reference est-elle nulle ? + if (CORBA::is_nil(provides_port_ref)) + throw Engines::DSC::NilPort(); + + // Le type est-il correct ? + const char * repository_id = my_ports[uses_port_name]->repository_id.c_str(); + if (provides_port_ref->_is_a(repository_id)) + { + // Ajout dans la sequence + CORBA::ULong lgth = my_ports[uses_port_name]->uses_port_refs.length(); + my_ports[uses_port_name]-> + uses_port_refs.length(lgth + 1); + my_ports[uses_port_name]->uses_port_refs[lgth] = + Ports::Port::_duplicate(provides_port_ref); + + // Augmentation du nombre de connexions + my_ports[uses_port_name]->connection_nbr += 1; + + // Appel du callback pour prévenir le uses port a été modifié + uses_port_changed(uses_port_name, + new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs), + Engines::DSC::AddingConnection); + } + else { + Engines::DSC::BadPortType BPT; + BPT.expected = CORBA::string_dup("Expected ..."); + BPT.received = CORBA::string_dup((std::string("Received an incorrect repository id type ")+ + repository_id).c_str()); + throw BPT; + } + +} + +/* Cette méthode teste si le uses port "name" est connecté. + * Léve PortNotDefined si le port n'existe pas. + */ +CORBA::Boolean +Engines_DSC_interface::is_connected(const char* port_name) + throw (Engines::DSC::PortNotDefined) +{ + assert(port_name); + + CORBA::Boolean rtn = false; + + // Le port existe t-il ? + my_ports_it = my_ports.find(port_name); + if (my_ports_it == my_ports.end()) + throw Engines::DSC::PortNotDefined(); + + // Le port est-il connecté ? + if (my_ports[port_name]->connection_nbr > 0) + rtn = true; + + return rtn; +} + +void +Engines_DSC_interface::disconnect_provides_port(const char* provides_port_name, + const Engines::DSC::Message message) +throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected) +{ + assert(provides_port_name); + + // Le port existe t-il ? + my_ports_it = my_ports.find(provides_port_name); + if (my_ports_it == my_ports.end()) + throw Engines::DSC::PortNotDefined(); + if (my_ports[provides_port_name]->type != provides) + throw Engines::DSC::PortNotDefined(); + + // Le port est-il connecté ? + if (my_ports[provides_port_name]->connection_nbr > 0) + { + my_ports[provides_port_name]->connection_nbr -= 1; + provides_port_changed(provides_port_name, + my_ports[provides_port_name]->connection_nbr, + message); + } + else + throw Engines::DSC::PortNotConnected(); +} + +void +Engines_DSC_interface::disconnect_uses_port(const char* uses_port_name, + Ports::Port_ptr provides_port_ref, + const Engines::DSC::Message message) +throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected, + Engines::DSC::BadPortReference) +{ + assert(uses_port_name); + + // Le port existe t-il ? + my_ports_it = my_ports.find(uses_port_name); + if (my_ports_it == my_ports.end()) + throw Engines::DSC::PortNotDefined(); + if (my_ports[uses_port_name]->type != uses) + throw Engines::DSC::PortNotDefined(); + + // Le port est-il connecté ? + if (my_ports[uses_port_name]->connection_nbr > 0) { + // On cherche le port dans la sequence representant le + // uses port. + if (CORBA::is_nil(provides_port_ref)) + throw Engines::DSC::BadPortReference(); + + CORBA::Long port_index = -1; + CORBA::ULong seq_length = my_ports[uses_port_name]->uses_port_refs.length(); + for(int i = 0; i < seq_length; i++) + { + if (my_ports[uses_port_name]->uses_port_refs[i]->_is_equivalent(provides_port_ref)) + { + port_index = i; + break; + } + } + + if (port_index == -1) + throw Engines::DSC::BadPortReference(); + + my_ports[uses_port_name]->connection_nbr -= 1; + Engines::DSC::uses_port * new_uses_port = + new Engines::DSC::uses_port(); + new_uses_port->length(seq_length - 1); + + int index_ancien = 0; + int index_nouveau = 0; + for(;index_ancien < seq_length;) { + if (index_ancien == port_index) + { + // Rien a faire ! + // On ne change pas le index du nouveau tableau + index_ancien += 1; + } + else + { + (*new_uses_port)[index_nouveau] = my_ports[uses_port_name]->uses_port_refs[index_ancien]; + index_ancien += 1; + index_nouveau += 1; + } + } + + // On remplace la sequence ... + my_ports[uses_port_name]->uses_port_refs = *new_uses_port; + + // Rq c'est à l'utilisateur de détruire + // la sequence s'il n'en veut pas !!! + uses_port_changed(uses_port_name, + new_uses_port, + message); + } + else + throw Engines::DSC::PortNotConnected(); +} + +Ports::PortProperties_ptr +Engines_DSC_interface::get_port_properties(const char* port_name) + throw (Engines::DSC::PortNotDefined) +{ + assert(port_name); + + Ports::PortProperties_ptr rtn_properties = Ports::PortProperties::_nil(); + + // Le port existe t-il ? + my_ports_it = my_ports.find(port_name); + if (my_ports_it == my_ports.end()) + throw Engines::DSC::PortNotDefined(); + + rtn_properties = Ports::PortProperties::_duplicate(my_ports[port_name]->port_prop); + return rtn_properties; +} diff --git a/src/DSC/DSC_Basic/DSC_interface.hxx b/src/DSC/DSC_Basic/DSC_interface.hxx new file mode 100644 index 000000000..2bcda6385 --- /dev/null +++ b/src/DSC/DSC_Basic/DSC_interface.hxx @@ -0,0 +1,132 @@ + +// André Ribes EDF R&D - 2006 +// +#ifndef _DSC_INTERFACE_HXX_ +#define _DSC_INTERFACE_HXX_ + +#include +#include +#include +#include + +#include "DSC_Callbacks.hxx" + +/*! \class Engines_DSC_interface + * \brief This class implements the interface Engines::DSC + */ +class Engines_DSC_interface: + public DSC_Callbacks +{ +public: + Engines_DSC_interface(); + virtual ~Engines_DSC_interface(); + + /*! + * \see Engines::DSC::add_provides_port + */ + virtual void add_provides_port(Ports::Port_ptr ref, + const char* provides_port_name, + Ports::PortProperties_ptr port_prop) + throw (Engines::DSC::PortAlreadyDefined, + Engines::DSC::NilPort, + Engines::DSC::BadProperty); + + /*! + * \see Engines::DSC::add_uses_port + */ + virtual void add_uses_port(const char* repository_id, + const char* uses_port_name, + Ports::PortProperties_ptr port_prop) + throw (Engines::DSC::PortAlreadyDefined, + Engines::DSC::BadProperty); + + /*! + * \see Engines::DSC::get_provides_port + */ + virtual Ports::Port_ptr get_provides_port(const char* provides_port_name, + const CORBA::Boolean connection_error) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected, + Engines::DSC::BadPortType); + + /*! + * \see Engines::DSC::get_uses_port + */ + virtual Engines::DSC::uses_port * get_uses_port(const char* uses_port_name) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected, + Engines::DSC::BadPortType); + + /*! + * \see Engines::DSC::connect_provides_port + */ + virtual void connect_provides_port(const char* provides_port_name) + throw (Engines::DSC::PortNotDefined); + + /*! + * \see Engines::DSC::connect_uses_port + */ + virtual void connect_uses_port(const char* uses_port_name, + Ports::Port_ptr provides_port_ref) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::BadPortType, + Engines::DSC::NilPort); + + /*! + * \see Engines::DSC::is_connected + */ + virtual CORBA::Boolean is_connected(const char* port_name) + throw (Engines::DSC::PortNotDefined); + + /*! + * \see Engines::DSC::disconnect_provides_port + */ + virtual void disconnect_provides_port(const char* provides_port_name, + const Engines::DSC::Message message) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected); + + /*! + * \see Engines::DSC::disconnect_uses_port + */ + virtual void disconnect_uses_port(const char* uses_port_name, + Ports::Port_ptr provides_port_ref, + const Engines::DSC::Message message) + throw (Engines::DSC::PortNotDefined, + Engines::DSC::PortNotConnected, + Engines::DSC::BadPortReference); + + virtual Ports::PortProperties_ptr get_port_properties(const char* port_name) + throw (Engines::DSC::PortNotDefined); + +protected: + + /*-------------------------------------------------*/ + /* Definition des types pour le stockage des ports */ + + enum port_type {uses, provides, none}; + + struct port_t { + port_type type; + int connection_nbr; + + // Specifique aux uses port + Engines::DSC::uses_port uses_port_refs; + std::string repository_id; + + // Specifique aux provides port; + Ports::Port_ptr provides_port_ref; + + Ports::PortProperties_ptr port_prop; + }; + + typedef std::map ports; + + /*-------------------------------------------------*/ + /*-------------------------------------------------*/ + + ports my_ports; + ports::iterator my_ports_it; +}; + +#endif diff --git a/src/DSC/DSC_Basic/Makefile.am b/src/DSC/DSC_Basic/Makefile.am new file mode 100644 index 000000000..d0dc85c8d --- /dev/null +++ b/src/DSC/DSC_Basic/Makefile.am @@ -0,0 +1,89 @@ +# Copyright (C) 2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# +# +# File : Makefile.am +# Author : André RIBES (EDF) +# Module : KERNEL + +include $(top_srcdir)/salome_adm/unix/make_common_starter.am + +# +# =============================================================== +# Header to be installed +# =============================================================== +# +# header files +salomeinclude_HEADERS = ConnectionManager_i.hxx \ + DSC_Callbacks.hxx \ + DSC_i.hxx \ + DSC_interface.hxx \ + PortProperties_i.hxx +# +# =============================================================== +# Local definitions +# =============================================================== +# + +# This local variable defines the list of CPPFLAGS common to all target in this package. +COMMON_CPPFLAGS= -I$(top_srcdir)/src/Container \ + -I$(top_srcdir)/src/Notification \ + -I$(top_srcdir)/src/SALOMELocalTrace \ + -I$(top_srcdir)/src/Basics \ + -I$(top_srcdir)/src/NamingService \ + -I$(top_srcdir)/src/Utils \ + -I$(top_builddir)/salome_adm/unix \ + -I$(top_builddir)/idl \ + @CORBA_CXXFLAGS@ @CORBA_INCLUDES@ + +# This local variable defines the list of dependant libraries common to all target in this package. +COMMON_LIBS = $(top_builddir)/src/Container/libSalomeContainer.la \ + @CORBA_LIBS@ + +# +# =============================================================== +# Libraries targets +# =============================================================== +# +lib_LTLIBRARIES = libSalomeDSCContainer.la + +libSalomeDSCContainer_la_SOURCES = DSC_i.cxx \ + ConnectionManager_i.cxx \ + DSC_interface.cxx \ + PortProperties_i.cxx + +libSalomeDSCContainer_la_CXXFLAGS = -no-undefined -version-info=0:0:0 \ + $(COMMON_CPPFLAGS) + +libSalomeDSCContainer_la_LIBADD = $(COMMON_LIBS) + +# +# =============================================================== +# Executables targets +# =============================================================== +# +bin_PROGRAMS = SALOME_ConnectionManagerServer + +SALOME_ConnectionManagerServer_SOURCES = SALOME_ConnectionManagerServer.cxx + +SALOME_ConnectionManagerServer_CXXFLAGS = $(COMMON_CPPFLAGS) + +SALOME_ConnectionManagerServer_LDADD = libSalomeDSCContainer.la \ + $(COMMON_LIBS) diff --git a/src/DSC/DSC_Basic/PortProperties_i.cxx b/src/DSC/DSC_Basic/PortProperties_i.cxx new file mode 100644 index 000000000..b70d0c82d --- /dev/null +++ b/src/DSC/DSC_Basic/PortProperties_i.cxx @@ -0,0 +1,25 @@ +// André Ribes EDF R&D - 2006 +// + +#include "PortProperties_i.hxx" + +PortProperties_i::PortProperties_i() {} + +PortProperties_i::~PortProperties_i() {} + +void +PortProperties_i::set_property(const char * name, const CORBA::Any& value) + throw (Ports::NotDefined, Ports::BadType) +{ + // Default ... + throw Ports::NotDefined(); +} + +CORBA::Any* +PortProperties_i::get_property(const char* name) + throw (Ports::NotDefined) +{ + // Default ... + throw Ports::NotDefined(); +} + diff --git a/src/DSC/DSC_Basic/PortProperties_i.hxx b/src/DSC/DSC_Basic/PortProperties_i.hxx new file mode 100644 index 000000000..71bffef2f --- /dev/null +++ b/src/DSC/DSC_Basic/PortProperties_i.hxx @@ -0,0 +1,23 @@ +// André Ribes EDF R&D - 2007 +// +#ifndef _PORTPROPERTIES_I_HXX_ +#define _PORTPROPERTIES_I_HXX_ + +#include "SALOME_Ports.hh" + +class PortProperties_i: + public virtual POA_Ports::PortProperties +{ + public: + PortProperties_i(); + virtual ~PortProperties_i(); + + virtual void set_property(const char * name, const CORBA::Any& value) + throw (Ports::NotDefined, Ports::BadType); + virtual CORBA::Any* get_property(const char* name) + throw (Ports::NotDefined); +}; + +#endif + + diff --git a/src/DSC/DSC_Basic/SALOME_ConnectionManagerServer.cxx b/src/DSC/DSC_Basic/SALOME_ConnectionManagerServer.cxx new file mode 100644 index 000000000..df894db65 --- /dev/null +++ b/src/DSC/DSC_Basic/SALOME_ConnectionManagerServer.cxx @@ -0,0 +1,37 @@ +#include "ConnectionManager_i.hxx" +#include "utilities.h" +#include + +using namespace std; + +int main(int argc, char* argv[]) +{ + PortableServer::POA_var root_poa; + PortableServer::POAManager_var pman; + CORBA::Object_var obj; + CORBA::ORB_var orb = CORBA::ORB_init( argc , argv ) ; + try{ + obj = orb->resolve_initial_references("RootPOA"); + if(!CORBA::is_nil(obj)) + root_poa = PortableServer::POA::_narrow(obj); + if(!CORBA::is_nil(root_poa)) + pman = root_poa->the_POAManager(); + ConnectionManager_i * serv = new ConnectionManager_i(orb); + pman->activate(); + orb->run(); + }catch(CORBA::SystemException&){ + MESSAGE("Caught CORBA::SystemException."); + }catch(PortableServer::POA::WrongPolicy&){ + MESSAGE("Caught CORBA::WrongPolicyException."); + }catch(PortableServer::POA::ServantAlreadyActive&){ + MESSAGE("Caught CORBA::ServantAlreadyActiveException"); + }catch(CORBA::Exception&){ + MESSAGE("Caught CORBA::Exception."); + }catch(std::exception& exc){ + MESSAGE("Caught std::exception - "<