Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/kernel.git] / src / DSC / DSC_Basic / DSC_interface.cxx
1 //  Copyright (C) 2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 // 
4 //  This library is free software; you can redistribute it and/or 
5 //  modify it under the terms of the GNU Lesser General Public 
6 //  License as published by the Free Software Foundation; either 
7 //  version 2.1 of the License. 
8 // 
9 //  This library is distributed in the hope that it will be useful, 
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 //  Lesser General Public License for more details. 
13 // 
14 //  You should have received a copy of the GNU Lesser General Public 
15 //  License along with this library; if not, write to the Free Software 
16 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
17 // 
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //
21 //
22 //  File   : DSC_interface.cxx
23 //  Author : AndrĂ© RIBES (EDF)
24 //  Module : KERNEL
25
26 #include <string>
27 #include "DSC_interface.hxx"
28
29 Engines_DSC_interface::Engines_DSC_interface() {}
30
31 Engines_DSC_interface::~Engines_DSC_interface() 
32 {
33   my_ports_it = my_ports.begin();
34   for(;my_ports_it != my_ports.end();my_ports_it++)
35     delete my_ports_it->second;
36
37 }
38
39 void
40 Engines_DSC_interface::add_provides_port(Ports::Port_ptr ref, 
41                                  const char* provides_port_name,
42                                  Ports::PortProperties_ptr port_prop) 
43 throw (Engines::DSC::PortAlreadyDefined,
44        Engines::DSC::NilPort,
45        Engines::DSC::BadProperty) 
46 {
47   // Method args test
48   assert(provides_port_name);
49   if (CORBA::is_nil(ref))
50     throw Engines::DSC::NilPort();
51   if (CORBA::is_nil(port_prop))
52     throw Engines::DSC::BadProperty();
53
54   my_ports_it = my_ports.find(provides_port_name);
55   if (my_ports_it ==  my_ports.end()) {
56     // Creating a new port provides
57     port_t * new_port = new port_t();
58     new_port->type = provides;
59     new_port->connection_nbr = 0;
60     new_port->provides_port_ref = Ports::Port::_duplicate(ref);
61     new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
62
63     // Port into the port's map
64     my_ports[provides_port_name] = new_port;
65   }
66   else
67     throw Engines::DSC::PortAlreadyDefined();
68 }
69
70 void
71 Engines_DSC_interface::add_uses_port(const char* repository_id, 
72                              const char* uses_port_name,
73                              Ports::PortProperties_ptr port_prop) 
74 throw (Engines::DSC::PortAlreadyDefined,
75        Engines::DSC::BadProperty) 
76 {
77   // Method args test
78   // Note : We can't be shure that repository id
79   // is a correct CORBA id.
80   assert(repository_id);
81   assert(uses_port_name);
82   if (CORBA::is_nil(port_prop))
83     throw Engines::DSC::BadProperty();
84
85   my_ports_it = my_ports.find(uses_port_name);
86   if (my_ports_it ==  my_ports.end()) {
87     // Creating a new uses port
88     port_t * new_port = new port_t();
89     new_port->type = uses;
90     new_port->connection_nbr = 0;
91     new_port->uses_port_refs.length(0);
92     new_port->repository_id = repository_id;
93     new_port->port_prop = Ports::PortProperties::_duplicate(port_prop);
94
95     // Port into port's map
96     my_ports[uses_port_name] = new_port;
97   }
98   else
99     throw Engines::DSC::PortAlreadyDefined();
100 }
101
102 Ports::Port_ptr
103 Engines_DSC_interface::get_provides_port(const char* provides_port_name,
104                                  const CORBA::Boolean connection_error) 
105   throw (Engines::DSC::PortNotDefined,
106          Engines::DSC::PortNotConnected, 
107          Engines::DSC::BadPortType) 
108 {
109   // Method arg test
110   assert(provides_port_name);
111
112   Ports::Port_ptr rtn_port = Ports::Port::_nil();
113 //   std::cout << "---- DSC_Interface : MARK 1 ---- Recherche de : " << provides_port_name << "----" << std::endl;
114 //   ports::iterator it;
115 //   std::cout << "----> ";
116 //   for(it=my_ports.begin();it!=my_ports.end();++it) 
117 //     std::cout << "|"<<(*it).first<<"|, ";
118 //   std::cout << std::endl;
119  
120   // Searching the port
121   my_ports_it = my_ports.find(provides_port_name);
122   if (my_ports_it ==  my_ports.end())
123     throw Engines::DSC::PortNotDefined();
124   if (my_ports[provides_port_name]->type != provides) {
125     Engines::DSC::BadPortType BPT;
126     BPT.expected = CORBA::string_dup("Expected a provides port");
127     BPT.received = CORBA::string_dup((std::string("Received a uses/none port : ")+provides_port_name).c_str());
128     throw BPT;
129   }
130
131   if (my_ports[provides_port_name]->connection_nbr == 0 && connection_error)
132     throw Engines::DSC::PortNotConnected();
133
134   rtn_port = Ports::Port::_duplicate(my_ports[provides_port_name]->provides_port_ref);
135   return rtn_port;
136 }
137
138 Engines::DSC::uses_port * 
139 Engines_DSC_interface::get_uses_port(const char* uses_port_name) 
140   throw (Engines::DSC::PortNotDefined,
141          Engines::DSC::PortNotConnected,
142          Engines::DSC::BadPortType) 
143 {
144   // Method arg test
145   assert(uses_port_name);
146
147   Engines::DSC::uses_port * rtn_port = NULL;  
148
149   // Searching the uses port
150   my_ports_it = my_ports.find(uses_port_name);
151   if (my_ports_it == my_ports.end())
152     throw Engines::DSC::PortNotDefined();
153   if (my_ports[uses_port_name]->type != uses){
154     Engines::DSC::BadPortType BPT;
155     BPT.expected = CORBA::string_dup("Expected a uses port");
156     BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
157    std::cout << "---- DSC_Interface : MARK 1 ---- exception : " << uses_port_name << "----" << std::endl;
158     throw BPT;
159   }
160
161   // Is the port connected ?
162   if (my_ports[uses_port_name]->connection_nbr > 0) {
163     rtn_port = new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs);
164   }
165   else
166     {
167    std::cout << "---- DSC_Interface : MARK 2 ---- exception : " << uses_port_name << "----" << std::endl;
168     throw Engines::DSC::PortNotConnected();
169     }
170   
171   return rtn_port;
172 }
173
174 void
175 Engines_DSC_interface::connect_provides_port(const char* provides_port_name)
176     throw (Engines::DSC::PortNotDefined)
177 {
178   // Method arg test
179   assert(provides_port_name);
180
181   // Searching the provides port
182   my_ports_it = my_ports.find(provides_port_name);
183   if (my_ports_it ==  my_ports.end())
184     throw Engines::DSC::PortNotDefined();
185   if (my_ports[provides_port_name]->type != provides)
186     throw Engines::DSC::PortNotDefined();
187
188
189   // Adding a new connection
190   my_ports[provides_port_name]->connection_nbr += 1;
191   // User code is informed
192   provides_port_changed(provides_port_name, 
193                         my_ports[provides_port_name]->connection_nbr,
194                         Engines::DSC::AddingConnection
195                        );
196 }
197
198 void
199 Engines_DSC_interface::connect_uses_port(const char* uses_port_name,
200                                          Ports::Port_ptr provides_port_ref) 
201   throw (Engines::DSC::PortNotDefined,
202          Engines::DSC::BadPortType,
203          Engines::DSC::NilPort)
204 {
205   // Method arg test
206   assert(uses_port_name);
207
208   if (CORBA::is_nil(provides_port_ref))
209     throw Engines::DSC::NilPort();
210
211   // Searching the uses port
212   my_ports_it = my_ports.find(uses_port_name);
213   if (my_ports_it ==  my_ports.end())
214     throw Engines::DSC::PortNotDefined();
215   if (my_ports[uses_port_name]->type != uses) {
216     Engines::DSC::BadPortType BPT;
217     BPT.expected = CORBA::string_dup("Expected a uses port");
218     BPT.received = CORBA::string_dup((std::string("Received a provides/none port : ")+uses_port_name).c_str());
219     throw BPT;
220   }
221
222   // repository_id test
223   const char * repository_id = my_ports[uses_port_name]->repository_id.c_str();
224   if (provides_port_ref->_is_a(repository_id)) 
225   {
226     // Adding provides port into the uses port sequence
227     CORBA::ULong lgth = my_ports[uses_port_name]->uses_port_refs.length();
228     my_ports[uses_port_name]->
229       uses_port_refs.length(lgth + 1);
230     my_ports[uses_port_name]->uses_port_refs[lgth] = 
231       Ports::Port::_duplicate(provides_port_ref);
232
233     // Adding a new connection
234     my_ports[uses_port_name]->connection_nbr += 1;
235     // User code is informed
236     uses_port_changed(uses_port_name,
237                       new Engines::DSC::uses_port(my_ports[uses_port_name]->uses_port_refs),
238                       Engines::DSC::AddingConnection);
239   }
240   else {
241     Engines::DSC::BadPortType BPT;
242     BPT.expected = CORBA::string_dup("Expected ...");
243     BPT.received = CORBA::string_dup((std::string("Received an incorrect repository id type ")+
244                                       repository_id).c_str());
245     throw BPT;
246   }
247
248 }
249
250 CORBA::Boolean
251 Engines_DSC_interface::is_connected(const char* port_name) 
252   throw (Engines::DSC::PortNotDefined) 
253 {
254   CORBA::Boolean rtn = false;
255
256   // Method arg test
257   assert(port_name);
258
259   my_ports_it = my_ports.find(port_name);
260   if (my_ports_it ==  my_ports.end())
261     throw Engines::DSC::PortNotDefined();
262
263   // Is it connected ?
264   if (my_ports[port_name]->connection_nbr > 0)
265     rtn = true;
266
267   return rtn;
268 }
269
270 void
271 Engines_DSC_interface::disconnect_provides_port(const char* provides_port_name,
272                                         const Engines::DSC::Message message)
273 throw (Engines::DSC::PortNotDefined,
274        Engines::DSC::PortNotConnected)
275 {
276   // Method args test
277   assert(provides_port_name);
278
279   my_ports_it = my_ports.find(provides_port_name);
280   if (my_ports_it ==  my_ports.end())
281     throw Engines::DSC::PortNotDefined();
282   if (my_ports[provides_port_name]->type != provides)
283     throw Engines::DSC::PortNotDefined();
284
285   // Is it connected ?
286   if (my_ports[provides_port_name]->connection_nbr > 0) 
287   {
288     my_ports[provides_port_name]->connection_nbr -= 1;
289     provides_port_changed(provides_port_name,
290                           my_ports[provides_port_name]->connection_nbr,
291                           message);
292   }
293   else
294     throw Engines::DSC::PortNotConnected();
295 }
296
297 void
298 Engines_DSC_interface::disconnect_uses_port(const char* uses_port_name,
299                                     Ports::Port_ptr provides_port_ref,
300                                     const Engines::DSC::Message message)
301 throw (Engines::DSC::PortNotDefined,
302        Engines::DSC::PortNotConnected,
303        Engines::DSC::BadPortReference) 
304 {
305   // Method args test
306   assert(uses_port_name);
307
308   my_ports_it = my_ports.find(uses_port_name);
309   if (my_ports_it ==  my_ports.end())
310     throw Engines::DSC::PortNotDefined();
311   if (my_ports[uses_port_name]->type != uses)
312     throw Engines::DSC::PortNotDefined();
313
314   if (CORBA::is_nil(provides_port_ref))
315     throw Engines::DSC::BadPortReference();
316
317   // Is it connected ?
318   if (my_ports[uses_port_name]->connection_nbr > 0) {
319     CORBA::Long port_index = -1;
320     CORBA::ULong seq_length = my_ports[uses_port_name]->uses_port_refs.length(); 
321     for(int i = 0; i < seq_length; i++)
322     {
323       if (my_ports[uses_port_name]->uses_port_refs[i]->_is_equivalent(provides_port_ref))
324       {
325         port_index = i;
326         break;
327       }
328     }
329     if (port_index == -1)
330       throw Engines::DSC::BadPortReference();
331
332     my_ports[uses_port_name]->connection_nbr -= 1;
333     Engines::DSC::uses_port * new_uses_port = 
334       new Engines::DSC::uses_port();
335     new_uses_port->length(seq_length - 1);
336
337     int index_ancien = 0;
338     int index_nouveau = 0;
339     for(;index_ancien < seq_length;) {
340       if (index_ancien == port_index) 
341       {
342         // Rien a faire !
343         // On ne change pas le index du nouveau tableau
344         index_ancien += 1;
345       }
346       else 
347       {
348         (*new_uses_port)[index_nouveau] = my_ports[uses_port_name]->uses_port_refs[index_ancien];
349         index_ancien += 1;
350         index_nouveau += 1;
351       }
352     }
353
354     // New uses port's sequence
355     my_ports[uses_port_name]->uses_port_refs = *new_uses_port;
356
357     // The user code is informed
358     uses_port_changed(uses_port_name,
359                       new_uses_port,
360                       message);
361   }
362   else
363     throw Engines::DSC::PortNotConnected();
364 }
365
366 Ports::PortProperties_ptr
367 Engines_DSC_interface::get_port_properties(const char* port_name) 
368   throw (Engines::DSC::PortNotDefined) 
369 {
370   Ports::PortProperties_ptr rtn_properties = Ports::PortProperties::_nil();
371
372   // Method arg test
373   assert(port_name);
374
375   my_ports_it = my_ports.find(port_name);
376   if (my_ports_it ==  my_ports.end())
377     throw Engines::DSC::PortNotDefined();
378
379   rtn_properties = Ports::PortProperties::_duplicate(my_ports[port_name]->port_prop);
380   return rtn_properties;
381 }