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