Salome HOME
29f8483f3d465aa011865cbd7383ec4161ca703e
[modules/kernel.git] / src / DSC / DSC_User / Superv_Component_i.hxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : Superv_Component_i.hxx
23 //  Author : André RIBES (EDF), Eric Fayolle (EDF)
24 //  Module : KERNEL
25 //
26 #ifndef _SUPERV_COMPONENT_I_HXX_
27 #define _SUPERV_COMPONENT_I_HXX_
28
29 #include "DSC_i.hxx"
30 #include "base_port.hxx"
31 #include "uses_port.hxx"
32 #include "provides_port.hxx"
33 #include "port_factory.hxx"
34
35 #include "DSC_Exception.hxx"
36 #include <vector>
37
38 //#define MYDEBUG
39
40 /*! \class Superv_Component_i
41  *  \brief This class implements DSC_User component.
42  *
43  *  This class allows a higher programming level than DSC_Basic. It enables
44  *  a programming level for service's developpers who want to use DSC ports.
45  *
46  *  This class has two level for using and declare ports. The higher level proposes
47  *  operations to add ports that are provided by default by Salomé like Calcium ports.
48  *  It provides too some methods to add their own DSC_User ports.
49  *
50  *  \note This class doesn't implement the init_service CORBA operation.
51  */
52 class Superv_Component_i :
53   public Engines_DSC_i,
54   virtual public POA_Engines::Superv_Component
55 {
56 public:
57   Superv_Component_i(CORBA::ORB_ptr orb,
58                      PortableServer::POA_ptr poa,
59                      PortableServer::ObjectId * contId,
60                      const char *instanceName,
61                      const char *interfaceName,
62                      bool notif = false);
63   Superv_Component_i(CORBA::ORB_ptr orb,
64                      PortableServer::POA_ptr poa,
65                      Engines::Container_ptr container, 
66                      const char *instanceName,
67                      const char *interfaceName,
68                      bool notif = false,
69          bool regist = true );
70   virtual ~Superv_Component_i();
71
72   // Exceptions declarations.
73   // There are defined on the Superv_Component_i.cxx to avoid problems
74   // from dlopen.
75   DSC_EXCEPTION(BadFabType);
76   DSC_EXCEPTION(BadType);
77   DSC_EXCEPTION(BadCast);
78   DSC_EXCEPTION(UnexpectedState);
79   DSC_EXCEPTION(PortAlreadyDefined);
80   DSC_EXCEPTION(PortNotDefined);
81   DSC_EXCEPTION(PortNotConnected);
82   DSC_EXCEPTION(NilPort);
83   DSC_EXCEPTION(BadProperty);
84   
85   /*!
86    * \warning currently disabled.
87    */
88   virtual provides_port * create_provides_control_port() 
89   {return NULL;}
90
91   /*!
92    * \warning currently disabled.
93    */
94   virtual provides_port * create_provides_data_and_control_port(const char* port_type) 
95   {return NULL;}
96
97   /*!
98    * \warning currently disabled.
99    */
100   virtual uses_port * create_uses_control_port()
101   {return NULL;}
102
103   /*!
104    * \warning currently disabled.
105    */
106   virtual uses_port * create_uses_data_and_control_port(const char* port_type)
107   {return NULL;}
108
109   /*!
110    * This method permits to create a provides port provided by the platform.
111    * (See documentation of DSC for knoing these ports).
112    *   
113    *
114    * \param port_fab_type type provides port.
115    * \return the provides port.
116    *
117    * \note It's user repsonsability to destroy the provides port.
118    */
119   virtual provides_port * create_provides_data_port(const std::string& port_fab_type)
120     throw (BadFabType);
121
122
123   /*!
124    * This method permits to create a uses port provided by the platform.
125    * (See documentation of DSC for knoing these ports).
126    *   
127    *
128    * \param port_fab_type type uses port.
129    * \return the uses port.
130    *
131    * \note It's user repsonsability to destroy the uses port.
132    */
133   virtual uses_port * create_uses_data_port(const std::string& port_fab_type)
134     throw (BadFabType); 
135
136   /*!
137    * Adds a port to the component. With this method only Salomé's provided DSC ports
138    * can be added.
139    *
140    * \param port_fab_type type of the port.
141    * \param port_type uses or provides.
142    * \param port_name the name of the port in the component.
143    */
144   virtual void add_port(const char * port_fab_type,
145                         const char * port_type,
146                         const char * port_name)
147     throw (PortAlreadyDefined, BadFabType, BadType, BadProperty);
148
149   /*!
150    * Adds a port to the component. With this method only Salomé's provided DSC ports
151    * can be added.
152    *
153    * \param port_fab_type type of the port.
154    * \param port_type uses or provides.
155    * \param port_name the name of the port in the component.
156    * \return the created port.   
157    */
158   template < typename SpecificPortType >  
159   SpecificPortType * add_port(const char * port_fab_type,
160                               const char * port_type,
161                               const char * port_name)
162     throw (PortAlreadyDefined, BadFabType, BadType, BadCast, BadProperty);
163
164   /*!
165    * Adds a created provides port to the component.
166    *
167    * \param port the provides port.
168    * \param provides_port_name the name of the port in the component.
169    */
170   virtual void add_port(provides_port * port, 
171                         const char* provides_port_name)
172     throw (PortAlreadyDefined, NilPort, BadProperty);
173
174   /*!
175    * Adds a created uses port to the component.
176    *
177    * \param port the uses port.
178    * \param uses_port_name the name of the port in the component.
179    */
180   virtual void add_port(uses_port * port, 
181                         const char* uses_port_name)
182     throw (PortAlreadyDefined, NilPort, BadProperty);
183
184   /*!
185    * Gets the provides port already added in the component.
186    *
187    * \param port the provides port pointer.
188    * \param provides_port_name the name of the port.
189    */
190   virtual void get_port(provides_port *& port, 
191                         const char* provides_port_name)
192     throw (PortNotDefined, PortNotConnected);
193   
194   /*!
195    * Gets the uses port already added in the component.
196    *
197    * \param port the uses port pointer.
198    * \param uses_port_name the name of the port.
199    */
200   virtual void get_port(uses_port *& port, 
201                         const char* uses_port_name)
202     throw (PortNotDefined, PortNotConnected);
203
204   /*!
205    * Gets the list of the ports of a service.
206    * If servicename is not set, all the ports of the component are 
207    * returned.
208    *
209    * \param port_names the ports's list.
210    * \param servicename service's name.
211    */
212   virtual void get_uses_port_names(std::vector<std::string> & port_names,
213                                    const std::string servicename="") const;
214
215   /*!
216    * Gets a port already added in the component.
217    *
218    * \param port_name the name of the port.
219    * \return a port's pointer.
220    */
221   template <typename SpecificPortType > 
222   SpecificPortType * get_port( const char * port_name)
223     throw (PortNotDefined, PortNotConnected, BadCast, UnexpectedState);
224  
225   /*!
226    * \see DSC_Callbacks::provides_port_changed
227    */
228   virtual void provides_port_changed(const char* provides_port_name,
229                                      int connection_nbr,
230                                      const Engines::DSC::Message message);
231
232   /*!
233    * \see DSC_Callbacks::uses_port_changed
234    */
235   virtual void uses_port_changed(const char* uses_port_name,
236                                  Engines::DSC::uses_port * new_uses_port,
237                                  const Engines::DSC::Message message);
238
239
240   /*!
241    * Add a factory the component. If the factory_name is already
242    * used, the new library is not added.
243    *
244    * \param factory_name name of the factory (used by Superv_Component_i::create_provides_data_port
245    * and Superv_Component_i::create_uses_data_port)
246    * \param factory_ptr factory pointer (destroyed by the component)
247    */
248   static void register_factory(const std::string & factory_name,
249                                 port_factory * factory_ptr);
250
251   /*!
252    * Get a factory from the component. 
253    *
254    * \param factory_name name of the factory.
255    * \return factory pointer, NULL if the factory doesn't exist.
256    */
257   virtual port_factory * get_factory(const std::string & factory_name);
258
259 private:   
260   // Factory map
261   typedef std::map<std::string, port_factory*> factory_map_t;
262   static factory_map_t _factory_map;
263
264   /*-------------------------------------------------*/
265   // A Superv_Component port.
266   struct superv_port_t {
267     superv_port_t():u_ref(NULL),p_ref(NULL){};
268     ~superv_port_t()
269     {
270       if(u_ref)delete u_ref;
271       if(p_ref)delete p_ref;
272     };
273     // For uses ports.
274     uses_port * u_ref;
275     // For provides ports.
276     provides_port * p_ref;
277   };
278
279   typedef std::map<std::string, superv_port_t *> superv_ports;
280
281   /*-------------------------------------------------*/
282   /*-------------------------------------------------*/
283
284   superv_ports my_superv_ports;
285   superv_ports::iterator my_superv_ports_it;
286 };
287
288
289
290 template < typename SpecificPortType >  SpecificPortType * 
291 Superv_Component_i::add_port(const char * port_fab_type,
292                              const char * port_type,
293                              const char * port_name)
294   throw (PortAlreadyDefined, BadFabType, BadType, BadCast, BadProperty)
295 {
296   assert(port_fab_type);
297   assert(port_type);
298   assert(port_name);
299   SpecificPortType * retPort; 
300
301 #ifdef MYDEBUG
302   std::cout << "---- Superv_Component_i::add_port :  Mark 0 ----  " << port_name << "----" << std::endl;
303 #endif
304     
305   std::string s_port_type(port_type);
306   if (s_port_type == "provides") {
307     provides_port * port = create_provides_data_port(port_fab_type);
308     add_port(port, port_name);
309     retPort = dynamic_cast<SpecificPortType *>(port);
310     if ( retPort == NULL ) { delete port;  
311       throw BadCast( LOC("La conversion vers le type de port demandé n'est pas possible " ));
312     }
313   }
314   else if (s_port_type == "uses") {
315     uses_port * port = create_uses_data_port(port_fab_type);
316     add_port(port, port_name);
317 #ifdef MYDEBUG
318     std::cout << "---- Superv_Component_i::add_port :  Mark 1 ----  " << port << "----" << std::endl;
319     std::cout << "---- Superv_Component_i::add_port :  Mark 1 ----   get_repository_id()" << port->get_repository_id() << std::endl;
320 #endif
321     retPort = dynamic_cast<SpecificPortType *>(port);
322 #ifdef MYDEBUG
323     std::cout << "---- Superv_Component_i::add_port :  Mark 2 ----  " << retPort << "----" << std::endl;
324 #endif
325     if ( retPort == NULL ) { delete port;  
326       throw BadCast( LOC("La conversion vers le type de port demandé n'est pas possible " ));
327     }
328   }
329   else
330     throw BadType(LOC(OSS()<< "Le port_type doit être soit 'provides' soit 'uses' not "
331                       << port_type));
332   
333   return retPort;
334 };
335
336
337 template <typename SpecificPortType > SpecificPortType * 
338 Superv_Component_i::get_port( const char * port_name)
339   throw (PortNotDefined, PortNotConnected, BadCast, UnexpectedState)
340 {
341   assert(port_name);
342     
343   SpecificPortType * retPort;
344   base_port        * port;
345
346   my_superv_ports_it = my_superv_ports.find(port_name);
347   if (my_superv_ports_it == my_superv_ports.end())
348   {
349     throw PortNotDefined( LOC(OSS()<< "Port " << port_name <<" does not exist"));
350   }
351
352   superv_port_t * superv_port =  my_superv_ports[port_name];
353   try {
354     if ( superv_port->p_ref != NULL ) {
355       port = superv_port->p_ref;
356       Ports::Port_var portref=Engines_DSC_interface::get_provides_port(port_name, false); 
357     } 
358     else if ( superv_port->u_ref != NULL ) {
359       port = superv_port->u_ref;
360       Engines::DSC::uses_port * portseq=Engines_DSC_i::get_uses_port(port_name);
361       delete portseq;
362     } else {
363       throw UnexpectedState( LOC(OSS()<< "Internal Error superv_port struct is inconsistent "));
364     
365     }
366   } catch (const Engines::DSC::PortNotDefined&) {
367     throw PortNotDefined( LOC(OSS()<< "Le port "
368                               << port_name <<" n'existe pas."));
369   } catch (const Engines::DSC::PortNotConnected&) {
370     throw PortNotConnected( LOC(OSS()<< "Le port " << port_name 
371                                 << " n'est pas connecté."));
372   }
373   
374   retPort = dynamic_cast<SpecificPortType *>(port);
375   if ( retPort == NULL ) {
376     delete port; 
377     throw BadCast( LOC("La conversion vers le type de port demandé n'est pas possible " ));
378   }
379
380   return retPort;
381 };
382
383
384 #endif