Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / runtime / StudyNodes.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "RuntimeSALOME.hxx"
20 #include "StudyNodes.hxx"
21 #include "StudyPorts.hxx"
22 #include "Visitor.hxx"
23
24 #include "SALOME_NamingService.hxx"
25 #include "SALOMEDS.hh"
26 #include "SALOMEDS_Attributes.hh"
27
28 #include <iostream>
29 #include <sstream>
30 #include <string>
31 #include <list>
32
33 //#define _DEVDEBUG_
34 #include "YacsTrace.hxx"
35
36 namespace YACS
37 {
38 namespace ENGINE
39 {
40
41 const char StudyInNode::IMPL_NAME[]="XML";
42
43 StudyInNode::StudyInNode(const std::string& name)
44   : DataNode(name)
45 {
46   _implementation=IMPL_NAME;
47 }
48
49 StudyInNode::StudyInNode(const StudyInNode& other, ComposedNode *father)
50   : DataNode(other, father)
51 {
52 }
53
54 Node *StudyInNode::simpleClone(ComposedNode *father, bool editionOnly) const
55 {
56   return new StudyInNode(*this,father);
57 }
58
59 OutputPort* StudyInNode::createOutputPort(const std::string& outputPortName, TypeCode* type)
60 {
61   return new OutputStudyPort(outputPortName, this, type);
62 }
63
64 void StudyInNode::setData(OutputPort* port, const std::string& data)
65 {
66   OutputStudyPort *outp = dynamic_cast<OutputStudyPort *>(port);
67   outp->setData(data);
68 }
69
70 void StudyInNode::execute()
71 {
72   DEBTRACE("+++++++ StudyInNode::execute +++++++++++");
73   SALOME_NamingService NS(getSALOMERuntime()->getOrb());
74   CORBA::Object_var obj=NS.Resolve("/myStudyManager");
75   if(CORBA::is_nil(obj)) 
76     {
77       _errorDetails="Execution problem: no naming service";
78       throw Exception(_errorDetails);
79     }
80
81   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(obj);
82   if(CORBA::is_nil(aStudyManager)) 
83     {
84       _errorDetails="Execution problem: no naming service";
85       throw Exception(_errorDetails);
86     }
87
88   int studyid=1;
89   if (_propertyMap.find("StudyID") != _propertyMap.end())
90     {
91       // StudyId is specified
92       studyid=atoi(_propertyMap["StudyID"].c_str());
93     }
94
95   SALOMEDS::Study_var myStudy =aStudyManager->GetStudyByID(studyid);
96   if(CORBA::is_nil(myStudy)) 
97     {
98       std::stringstream msg;
99       msg << "Execution problem: no study with id " << studyid;
100       _errorDetails=msg.str();
101       throw Exception(_errorDetails);
102     }
103
104   std::list<OutputPort *>::const_iterator iter;
105   for(iter = _setOfOutputPort.begin(); iter != _setOfOutputPort.end(); iter++)
106     {
107       OutputStudyPort *outp = dynamic_cast<OutputStudyPort *>(*iter);
108       std::string data = outp->getData();
109       DEBTRACE("data: " << data );
110       //try an id
111       SALOMEDS::SObject_var aSO = myStudy->FindObjectID(data.c_str());
112       if(CORBA::is_nil(aSO)) 
113         {
114           //try a path
115           aSO=myStudy->FindObjectByPath(data.c_str());
116           if(CORBA::is_nil(aSO)) 
117             {
118               _errorDetails="Execution problem: no id or path: ";
119               _errorDetails=_errorDetails+data+" in study";
120               throw Exception(_errorDetails);
121             }
122         }
123
124       CORBA::String_var path=myStudy->GetObjectPath(aSO);
125       DEBTRACE(path);
126       CORBA::String_var id=aSO->GetID();
127       DEBTRACE(id);
128       //CORBA::Object_var sobj=aSO->GetObject();
129       SALOMEDS::GenericAttribute_var aGAttr;
130
131       CORBA::String_var value;
132       if ( aSO->FindAttribute( aGAttr, "AttributeIOR" ) )
133         {
134           SALOMEDS::AttributeIOR_var anAttr = SALOMEDS::AttributeIOR::_narrow( aGAttr );
135           value=anAttr->Value();
136         }
137       else
138         {
139           //Problem !!!
140           _errorDetails="Execution problem: no AttributeIOR in study object: ";
141           _errorDetails=_errorDetails+data;
142           throw Exception(_errorDetails);
143         }
144       outp->putIOR((const char*)value);
145     }
146   DEBTRACE("+++++++ end StudyInNode::execute +++++++++++" );
147 }
148
149 void StudyInNode::checkBasicConsistency() const throw(Exception)
150 {
151   DEBTRACE("StudyInNode::checkBasicConsistency");
152   if (! _setOfInputPort.empty())
153     {
154       std::string what = "StudyNode ";
155       what += getName();
156       what += " only accepts OutputStudyPort, no InputPort";
157       throw Exception(what);
158     }
159
160   std::list<OutputPort *>::const_iterator iter;
161   for(iter=_setOfOutputPort.begin();iter!=_setOfOutputPort.end();iter++)
162     {
163       OutputStudyPort *inp = dynamic_cast<OutputStudyPort*>(*iter);
164       if (!inp)
165         {
166           std::string what("Output port: ");
167           what += (*iter)->getName();
168           what += " is not an OutputStudyPort. StudyNode ";
169           what += getName();
170           what += " only accepts OutputStudyPorts";
171           throw Exception(what);
172         }
173
174       std::string data = inp->getData();
175       DEBTRACE(data);
176       if (data.empty())
177         {
178           std::string what("OutputStudyPort: ");
179           what += (*iter)->getName();
180           what += " is not initialised";
181           throw Exception(what);
182         }
183     }
184 }
185
186 void StudyInNode::accept(Visitor *visitor)
187 {
188   visitor->visitStudyInNode(this);
189 }
190
191 const char StudyOutNode::IMPL_NAME[]="XML";
192
193 StudyOutNode::StudyOutNode(const std::string& name)
194   : DataNode(name)
195 {
196   _implementation=IMPL_NAME;
197 }
198
199 StudyOutNode::StudyOutNode(const StudyOutNode& other, ComposedNode *father)
200   : DataNode(other, father)
201 {
202 }
203
204 Node *StudyOutNode::simpleClone(ComposedNode *father, bool editionOnly) const
205 {
206   return new StudyOutNode(*this,father);
207 }
208
209 InputPort* StudyOutNode::createInputPort(const std::string& inputPortName, TypeCode* type)
210 {
211   return new InputStudyPort(inputPortName, this, type);
212 }
213
214 void StudyOutNode::setData(InputPort* port, const std::string& data)
215 {
216   InputStudyPort *inp = dynamic_cast<InputStudyPort *>(port);
217   inp->setData(data);
218 }
219
220 SALOMEDS::SObject_ptr findOrCreateSoWithName(SALOMEDS::Study_ptr study, SALOMEDS::StudyBuilder_ptr builder,
221                                              SALOMEDS::SObject_ptr sobj, const std::string& name)
222 {
223   SALOMEDS::ChildIterator_var anIterator= study->NewChildIterator(sobj);
224   SALOMEDS::GenericAttribute_var anAttr;
225   SALOMEDS::AttributeName_var namAttr ;
226   SALOMEDS::SObject_var result=SALOMEDS::SObject::_nil();
227
228   for (; anIterator->More(); anIterator->Next())
229     {
230       SALOMEDS::SObject_var anObj=anIterator->Value();
231       if(anObj->FindAttribute(anAttr, "AttributeName"))
232         {
233           namAttr = SALOMEDS::AttributeName::_narrow( anAttr );
234           CORBA::String_var value=namAttr->Value();
235           if(name == (const char*)value)
236             {
237               result=anObj;
238               break;
239             }
240         }
241     }
242   if(CORBA::is_nil(result))
243     {
244       //create it
245       result = builder->NewObject( sobj );
246       anAttr=builder->FindOrCreateAttribute(result,"AttributeName");
247       namAttr = SALOMEDS::AttributeName::_narrow( anAttr );
248       namAttr->SetValue(name.c_str());
249     }
250   return result._retn();
251 }
252
253 void StudyOutNode::execute()
254 {
255   DEBTRACE("+++++++ StudyOutNode::execute +++++++++++");
256   SALOME_NamingService NS(getSALOMERuntime()->getOrb());
257   CORBA::Object_var obj=NS.Resolve("/myStudyManager");
258   if(CORBA::is_nil(obj))
259     {
260       _errorDetails="Execution problem: no naming service";
261       throw Exception(_errorDetails);
262     }
263
264   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(obj);
265   if(CORBA::is_nil(aStudyManager))
266     {
267       _errorDetails="Execution problem: no naming service";
268       throw Exception(_errorDetails);
269     }
270
271   int studyid=1;
272   if (_propertyMap.find("StudyID") != _propertyMap.end())
273     {
274       // StudyId is specified
275       studyid=atoi(_propertyMap["StudyID"].c_str());
276     }
277
278   SALOMEDS::Study_var myStudy =aStudyManager->GetStudyByID(studyid);
279   if(CORBA::is_nil(myStudy))
280     {
281       //open a new one
282       std::stringstream msg;
283       msg << "Study" << studyid;
284       myStudy=aStudyManager->NewStudy(msg.str().c_str());
285       if(CORBA::is_nil(myStudy))
286         {
287           _errorDetails="Execution problem: can not create new study " + msg.str();
288           throw Exception(_errorDetails);
289         }
290     }
291   DEBTRACE(myStudy->StudyId());
292
293   SALOMEDS::StudyBuilder_var aBuilder =myStudy->NewBuilder() ;
294   if(CORBA::is_nil(aBuilder))
295     {
296       _errorDetails="Execution problem: can not create StudyBuilder";
297       throw Exception(_errorDetails);
298     }
299
300   SALOMEDS::GenericAttribute_var aGAttr;
301   SALOMEDS::SObject_var aSO ;
302   SALOMEDS::AttributeName_var anAttr ;
303   SALOMEDS::AttributeIOR_var iorAttr ;
304
305   std::list<InputPort *>::const_iterator iter;
306   for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
307     {
308       InputStudyPort *inp = dynamic_cast<InputStudyPort *>(*iter);
309       std::string data = inp->getData();
310       DEBTRACE("data: " << data );
311       //try to find an id
312       aSO = myStudy->FindObjectID(data.c_str());
313       if(CORBA::is_nil(aSO)) 
314         {
315           // the id does not exist. Try to create it by id
316           aSO=myStudy->CreateObjectID(data.c_str());
317           if(!CORBA::is_nil(aSO)) 
318             {
319               aGAttr=aBuilder->FindOrCreateAttribute(aSO,"AttributeName");
320               anAttr = SALOMEDS::AttributeName::_narrow( aGAttr );
321               anAttr->SetValue(inp->getName().c_str());
322             }
323         }
324       if(CORBA::is_nil(aSO)) 
325         {
326           // try a path
327           aSO=myStudy->FindObjectByPath(data.c_str());
328         }
329       if(CORBA::is_nil(aSO)) 
330         {
331           //try to create it by path
332           std::string name;
333           std::string::size_type begin = data.find_first_not_of("/");
334           std::string::size_type pos=data.find_first_of("/", begin);
335           if (pos != std::string::npos)
336             name=data.substr(begin,pos-begin);
337           else
338             name=data.substr(begin);
339           name="/"+name;
340           DEBTRACE(name);
341           aSO=myStudy->FindObjectByPath(name.c_str());
342           if(CORBA::is_nil(aSO)) 
343             {
344               DEBTRACE("Create an entry " << name);
345               //create a container component
346               aSO=aBuilder->NewComponent(name.c_str());
347               if(CORBA::is_nil(aSO)) 
348                 {
349                   std::cerr << "Execution problem: can not create component: " + data << std::endl;
350                   continue;
351                 }
352               aGAttr=aBuilder->FindOrCreateAttribute(aSO,"AttributeIOR");
353               iorAttr = SALOMEDS::AttributeIOR::_narrow( aGAttr );
354               iorAttr->SetValue(name.c_str());
355             }
356           begin=data.find_first_not_of("/",pos);
357           while (begin != std::string::npos)
358             {
359               pos = data.find_first_of("/", begin);
360               if (pos != std::string::npos)
361                 name=data.substr(begin,pos-begin);
362               else
363                 name=data.substr(begin);
364               aSO=findOrCreateSoWithName(myStudy,aBuilder,aSO,name);
365               begin=data.find_first_not_of("/",pos);
366             }
367         }
368       if(CORBA::is_nil(aSO)) 
369         {
370           std::cerr << "Execution problem: can not create id or path: " + data + " in study" << std::endl;
371           continue;
372         }
373       std::string value=inp->getIOR();
374       DEBTRACE(value);
375       aGAttr=aBuilder->FindOrCreateAttribute(aSO,"AttributeIOR");
376       iorAttr = SALOMEDS::AttributeIOR::_narrow( aGAttr );
377       iorAttr->SetValue(value.c_str());
378     }
379
380   // save in file if ref is given
381   if(_ref != "")
382     {
383       aStudyManager->SaveAs(_ref.c_str(),myStudy, false);
384     }
385   DEBTRACE("+++++++ end StudyOutNode::execute +++++++++++" );
386 }
387
388 void StudyOutNode::checkBasicConsistency() const throw(Exception)
389 {
390   DEBTRACE("StudyOutNode::checkBasicConsistency");
391   if (! _setOfOutputPort.empty())
392     {
393       std::string what = "StudyNode ";
394       what += getName();
395       what += " only accepts InputStudyPort, no OutputPort";
396       throw Exception(what);
397     }
398
399   std::list<InputPort *>::const_iterator iter;
400   for(iter=_setOfInputPort.begin();iter!=_setOfInputPort.end();iter++)
401     {
402       InputStudyPort *inp = dynamic_cast<InputStudyPort*>(*iter);
403       if (!inp)
404         {
405           std::string what("Input port: ");
406           what += (*iter)->getName();
407           what += " is not an InputStudyPort. StudyNode ";
408           what += getName();
409           what += " only accepts InputStudyPorts";
410           throw Exception(what);
411         }
412       inp->checkBasicConsistency();
413
414       std::string data = inp->getData();
415       DEBTRACE(data);
416       if (data.empty())
417         {
418           std::string what("InputStudyPort: ");
419           what += (*iter)->getName();
420           what += " is not initialised";
421           throw Exception(what);
422         }
423     }
424
425 }
426
427 void StudyOutNode::accept(Visitor *visitor)
428 {
429   visitor->visitStudyOutNode(this);
430 }
431
432 } //end namespace ENGINE
433 } //end namespace YACS