Salome HOME
Synchronize adm files
[modules/kernel.git] / src / DSC / DSC_User / Superv_Component_i.hxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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
23 //  File   : Superv_Component_i.hxx
24 //  Author : André RIBES (EDF), Eric Fayolle (EDF)
25 //  Module : KERNEL
26 //
27 #ifndef _SUPERV_COMPONENT_I_HXX_
28 #define _SUPERV_COMPONENT_I_HXX_
29
30 #include "DSC_i.hxx"
31 #include "base_port.hxx"
32 #include "uses_port.hxx"
33 #include "provides_port.hxx"
34 #include "port_factory.hxx"
35
36 #include "DSC_Exception.hxx"
37 #include <vector>
38
39 //#define MYDEBUG
40
41 /*! \class Superv_Component_i
42  *  \brief This class implements DSC_User component.
43  *
44  *  This class allows a higher programming level than DSC_Basic. It enables
45  *  a programming level for service's developpers who want to use DSC ports.
46  *
47  *  This class has two level for using and declare ports. The higher level proposes
48  *  operations to add ports that are provided by default by SALOME like Calcium ports.
49  *  It provides too some methods to add their own DSC_User ports.
50  *
51  *  \note This class doesn't implement the init_service CORBA operation.
52  */
53 class Superv_Component_i :
54   public Engines_DSC_i,
55   virtual public POA_Engines::Superv_Component
56 {
57 public:
58   Superv_Component_i(CORBA::ORB_ptr orb,
59                      PortableServer::POA_ptr poa,
60                      PortableServer::ObjectId * contId,
61                      const char *instanceName,
62                      const char *interfaceName,
63                      bool notif = false);
64   Superv_Component_i(CORBA::ORB_ptr orb,
65                      PortableServer::POA_ptr poa,
66                      Engines::Container_ptr container, 
67                      const char *instanceName,
68                      const char *interfaceName,
69                      bool notif = false,
70          bool regist = true );
71   virtual ~Superv_Component_i();
72
73   // Exceptions declarations.
74   // There are defined on the Superv_Component_i.cxx to avoid problems
75   // from dlopen.
76   DSC_EXCEPTION(BadFabType);
77   DSC_EXCEPTION(BadType);
78   DSC_EXCEPTION(BadCast);
79   DSC_EXCEPTION(UnexpectedState);
80   DSC_EXCEPTION(PortAlreadyDefined);
81   DSC_EXCEPTION(PortNotDefined);
82   DSC_EXCEPTION(PortNotConnected);
83   DSC_EXCEPTION(NilPort);
84   DSC_EXCEPTION(BadProperty);
85   
86   /*!
87    * \warning currently disabled.
88    */
89   virtual provides_port * create_provides_control_port() 
90   {return NULL;}
91
92   /*!
93    * \warning currently disabled.
94    */
95   virtual provides_port * create_provides_data_and_control_port(const char* port_type) 
96   {return NULL;}
97
98   /*!
99    * \warning currently disabled.
100    */
101   virtual uses_port * create_uses_control_port()
102   {return NULL;}
103
104   /*!
105    * \warning currently disabled.
106    */
107   virtual uses_port * create_uses_data_and_control_port(const char* port_type)
108   {return NULL;}
109
110   /*!
111    * This method permits to create a provides port provided by the platform.
112    * (See documentation of DSC for knoing these ports).
113    *   
114    *
115    * \param port_fab_type type provides port.
116    * \return the provides port.
117    *
118    * \note It's user repsonsability to destroy the provides port.
119    */
120   virtual provides_port * create_provides_data_port(const std::string& port_fab_type)
121     throw (BadFabType);
122
123
124   /*!
125    * This method permits to create a uses port provided by the platform.
126    * (See documentation of DSC for knoing these ports).
127    *   
128    *
129    * \param port_fab_type type uses port.
130    * \return the uses port.
131    *
132    * \note It's user repsonsability to destroy the uses port.
133    */
134   virtual uses_port * create_uses_data_port(const std::string& port_fab_type)
135     throw (BadFabType); 
136
137   /*!
138    * Adds a port to the component. With this method only Salomé's provided DSC ports
139    * can be added.
140    *
141    * \param port_fab_type type of the port.
142    * \param port_type uses or provides.
143    * \param port_name the name of the port in the component.
144    */
145   virtual void add_port(const char * port_fab_type,
146                         const char * port_type,
147                         const char * port_name)
148     throw (PortAlreadyDefined, BadFabType, BadType, BadProperty);
149
150   /*!
151    * Adds a port to the component. With this method only Salomé's provided DSC ports
152    * can be added.
153    *
154    * \param port_fab_type type of the port.
155    * \param port_type uses or provides.
156    * \param port_name the name of the port in the component.
157    * \return the created port.   
158    */
159   template < typename SpecificPortType >  
160   SpecificPortType * add_port(const char * port_fab_type,
161                               const char * port_type,
162                               const char * port_name)
163     throw (PortAlreadyDefined, BadFabType, BadType, BadCast, BadProperty);
164
165   /*!
166    * Adds a created provides port to the component.
167    *
168    * \param port the provides port.
169    * \param provides_port_name the name of the port in the component.
170    */
171   virtual void add_port(provides_port * port, 
172                         const char* provides_port_name)
173     throw (PortAlreadyDefined, NilPort, BadProperty);
174
175   /*!
176    * Adds a created uses port to the component.
177    *
178    * \param port the uses port.
179    * \param uses_port_name the name of the port in the component.
180    */
181   virtual void add_port(uses_port * port, 
182                         const char* uses_port_name)
183     throw (PortAlreadyDefined, NilPort, BadProperty);
184
185   /*!
186    * Gets the provides port already added in the component.
187    *
188    * \param port the provides port pointer.
189    * \param provides_port_name the name of the port.
190    */
191   virtual void get_port(provides_port *& port, 
192                         const char* provides_port_name)
193     throw (PortNotDefined, PortNotConnected);
194   
195   /*!
196    * Gets the uses port already added in the component.
197    *
198    * \param port the uses port pointer.
199    * \param uses_port_name the name of the port.
200    */
201   virtual void get_port(uses_port *& port, 
202                         const char* uses_port_name)
203     throw (PortNotDefined, PortNotConnected);
204
205   /*!
206    * Gets the list of the ports of a service.
207    * If servicename is not set, all the ports of the component are 
208    * returned.
209    *
210    * \param port_names the ports's list.
211    * \param servicename service's name.
212    */
213   virtual void get_uses_port_names(std::vector<std::string> & port_names,
214                                    const std::string servicename="") const;
215
216   /*!
217    * Gets a port already added in the component.
218    *
219    * \param port_name the name of the port.
220    * \return a port's pointer.
221    */
222   template <typename SpecificPortType > 
223   SpecificPortType * get_port( const char * port_name)
224     throw (PortNotDefined, PortNotConnected, BadCast, UnexpectedState);
225  
226   /*!
227    * \see DSC_Callbacks::provides_port_changed
228    */
229   virtual void provides_port_changed(const char* provides_port_name,
230                                      int connection_nbr,
231                                      const Engines::DSC::Message message);
232
233   /*!
234    * \see DSC_Callbacks::uses_port_changed
235    */
236   virtual void uses_port_changed(const char* uses_port_name,
237                                  Engines::DSC::uses_port * new_uses_port,
238                                  const Engines::DSC::Message message);
239
240
241   /*!
242    * Add a factory the component. If the factory_name is already
243    * used, the new library is not added.
244    *
245    * \param factory_name name of the factory (used by Superv_Component_i::create_provides_data_port
246    * and Superv_Component_i::create_uses_data_port)
247    * \param factory_ptr factory pointer (destroyed by the component)
248    */
249   static void register_factory(const std::string & factory_name,
250                                 port_factory * factory_ptr);
251
252   /*!
253    * Get a factory from the component. 
254    *
255    * \param factory_name name of the factory.
256    * \return factory pointer, NULL if the factory doesn't exist.
257    */
258   virtual port_factory * get_factory(const std::string & factory_name);
259
260   /*!
261    */
262   static long dscTimeOut;
263   static void setTimeOut();
264   void beginService(const char *serviceName);
265
266
267   // This method is implemented by default since it is a very specific usage.
268   // It also permits to not break compatibility with older components.
269   virtual CORBA::Boolean init_service_with_multiple(const char* service_name,
270                                                     const Engines::Superv_Component::seq_multiple_param & params)
271   {
272     return true;
273   }
274
275 private:
276   // Factory map
277   typedef std::map<std::string, port_factory*> factory_map_t;
278   static factory_map_t _factory_map;
279
280   /*-------------------------------------------------*/
281   // A Superv_Component port.
282   struct superv_port_t {
283     superv_port_t():u_ref(NULL),p_ref(NULL){};
284     ~superv_port_t()
285     {
286       if(u_ref)delete u_ref;
287       if(p_ref)
288         {
289           // do not delete CORBA servant : deactivate it and then call _remove_ref or delete
290           PortableServer::ServantBase* servant=dynamic_cast<PortableServer::ServantBase*>(p_ref);
291           if(servant)
292             {
293               PortableServer::POA_var poa =servant->_default_POA();
294               PortableServer::ObjectId_var oid = poa->servant_to_id(servant);
295               poa->deactivate_object(oid);
296               servant->_remove_ref();
297             }
298         }
299     };
300     // For uses ports.
301     uses_port * u_ref;
302     // For provides ports.
303     provides_port * p_ref;
304   };
305
306   typedef std::map<std::string, superv_port_t *> superv_ports;
307
308   /*-------------------------------------------------*/
309   /*-------------------------------------------------*/
310
311   superv_ports my_superv_ports;
312   superv_ports::iterator my_superv_ports_it;
313 };
314
315
316
317 template < typename SpecificPortType >  SpecificPortType * 
318 Superv_Component_i::add_port(const char * port_fab_type,
319                              const char * port_type,
320                              const char * port_name)
321   throw (PortAlreadyDefined, BadFabType, BadType, BadCast, BadProperty)
322 {
323   assert(port_fab_type);
324   assert(port_type);
325   assert(port_name);
326   SpecificPortType * retPort; 
327
328 #ifdef MYDEBUG
329   std::cout << "---- Superv_Component_i::add_port :  Mark 0 ----  " << port_name << "----" << std::endl;
330 #endif
331     
332   std::string s_port_type(port_type);
333   if (s_port_type == "provides") {
334     provides_port * port = create_provides_data_port(port_fab_type);
335     add_port(port, port_name);
336     retPort = dynamic_cast<SpecificPortType *>(port);
337     if ( retPort == NULL ) { delete port;  
338       throw BadCast( LOC("Can't cast to asked port type " ));
339     }
340   }
341   else if (s_port_type == "uses") {
342     uses_port * port = create_uses_data_port(port_fab_type);
343     add_port(port, port_name);
344 #ifdef MYDEBUG
345     std::cout << "---- Superv_Component_i::add_port :  Mark 1 ----  " << port << "----" << std::endl;
346     std::cout << "---- Superv_Component_i::add_port :  Mark 1 ----   get_repository_id()" << port->get_repository_id() << std::endl;
347 #endif
348     retPort = dynamic_cast<SpecificPortType *>(port);
349 #ifdef MYDEBUG
350     std::cout << "---- Superv_Component_i::add_port :  Mark 2 ----  " << retPort << "----" << std::endl;
351 #endif
352     if ( retPort == NULL ) { delete port;  
353       throw BadCast( LOC("Can't cast to asked port type " ));
354     }
355   }
356   else
357     throw BadType(LOC(OSS()<< "port_type must be either 'provides' either 'uses' not "
358                       << port_type));
359   
360   return retPort;
361 };
362
363
364 template <typename SpecificPortType > SpecificPortType * 
365 Superv_Component_i::get_port( const char * port_name)
366   throw (PortNotDefined, PortNotConnected, BadCast, UnexpectedState)
367 {
368   assert(port_name);
369     
370   SpecificPortType * retPort;
371   base_port        * port;
372
373   my_superv_ports_it = my_superv_ports.find(port_name);
374   if (my_superv_ports_it == my_superv_ports.end())
375   {
376     throw PortNotDefined( LOC(OSS()<< "Port " << port_name <<" does not exist"));
377   }
378
379   superv_port_t * superv_port =  my_superv_ports[port_name];
380   try {
381     if ( superv_port->p_ref != NULL ) {
382       port = superv_port->p_ref;
383       Ports::Port_var portref=Engines_DSC_interface::get_provides_port(port_name, false); 
384     } 
385     else if ( superv_port->u_ref != NULL ) {
386       port = superv_port->u_ref;
387       Engines::DSC::uses_port * portseq=Engines_DSC_i::get_uses_port(port_name);
388       delete portseq;
389     } else {
390       throw UnexpectedState( LOC(OSS()<< "Internal Error superv_port struct is inconsistent "));
391     
392     }
393   } catch (const Engines::DSC::PortNotDefined&) {
394     throw PortNotDefined( LOC(OSS()<< "port "
395                               << port_name <<" does not exist."));
396   } catch (const Engines::DSC::PortNotConnected&) {
397     throw PortNotConnected( LOC(OSS()<< "port " << port_name 
398                                 << " is not connected."));
399   }
400   
401   retPort = dynamic_cast<SpecificPortType *>(port);
402   if ( retPort == NULL ) {
403     throw BadCast( LOC("Can't cast to required port type " ));
404   }
405
406   return retPort;
407 };
408
409
410 #endif