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