Salome HOME
Still a problem with forward
[modules/yacs.git] / src / runtime / StudyPorts.cxx
1 // Copyright (C) 2006-2016  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, or (at your option) any later version.
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
20 #include "StudyPorts.hxx"
21 #include "TypeCode.hxx"
22 #include "Node.hxx"
23 #include "Proc.hxx"
24 #include "ComponentInstance.hxx"
25 #include "SalomeComponent.hxx"
26 #include "RuntimeSALOME.hxx"
27
28 #include "SALOMEDS_Attributes.hh"
29
30 #include <iostream>
31 #include <iomanip>
32 #include <cstdlib>
33
34 //#define _DEVDEBUG_
35 #include "YacsTrace.hxx"
36
37
38 namespace YACS
39 {
40 namespace ENGINE
41 {
42
43 /*! \class YACS::ENGINE::OutputStudyPort
44  *  \brief Class for Study output Ports
45  *
46  * \ingroup Ports
47  *
48  * \see StudyInNode
49  */
50
51 OutputStudyPort::OutputStudyPort(const std::string& name,  Node* node, TypeCode* type)
52   : OutputXmlPort(name, node, type),
53     DataPort(name, node, type),
54     Port(node)
55 {
56 }
57
58 OutputStudyPort::OutputStudyPort(const OutputStudyPort& other, Node *newHelder)
59   : OutputXmlPort(other,newHelder),
60     DataPort(other,newHelder),
61     Port(other,newHelder),_storeData(other._storeData)
62 {
63 }
64
65 OutputPort* OutputStudyPort::clone(Node *newHelder) const
66 {
67   return new OutputStudyPort(*this,newHelder);
68 }
69
70 void OutputStudyPort::setData(const std::string& data)
71 {
72   _storeData = data;
73   DEBTRACE( "OutputStudyPort::setData " << _storeData );
74   modified();
75 }
76
77 std::string OutputStudyPort::getData()
78 {
79   DEBTRACE("OutputStudyPort::getData " << _storeData);
80   return _storeData;
81 }
82
83 void OutputStudyPort::putIOR(const std::string& ior)
84 {
85   DEBTRACE("OutputStudyPort::putIOR " << ior);
86   if(ior.substr(0,7) == "<value>")
87     {
88       put(ior.c_str());
89     }
90   else
91     {
92       int tk=edGetType()->kind();
93       std::string value;
94       switch(tk)
95         {
96         case Double:
97           value="<value><double>"+ior+"</double></value>";
98           break;
99         case Int:
100           value="<value><int>"+ior+"</int></value>";
101           break;
102         case String:
103           value="<value><string>"+ior+"</string></value>";
104           break;
105         case Bool:
106           value="<value><boolean>"+ior+"</boolean></value>";
107           break;
108         case Objref:
109           value="<value><objref>"+ior+"</objref></value>";
110           break;
111         case Sequence:
112         case Array:
113         case Struct:
114         default:
115           break;
116         }
117       put(value.c_str());
118     }
119 }
120
121 std::string OutputStudyPort::dump()
122 {
123   DEBTRACE( "OutputStudyPort::dump " << _storeData );
124   DEBTRACE( "OutputStudyPort::dump " << _data );
125   //return "<value><string>"+_storeData+"</string></value>";
126   return _data;
127 }
128
129 std::string OutputStudyPort::getPyObj()
130 {
131   return getData();
132 }
133 std::string OutputStudyPort::getAsString()
134 {
135   return getData();
136 }
137
138 void OutputStudyPort::getDataFromStudy(SALOMEDS::Study_var myStudy)
139 {
140       std::string data = getData();
141       DEBTRACE("data: " << data );
142       //try an id
143       SALOMEDS::SObject_var aSO = myStudy->FindObjectID(data.c_str());
144       if(CORBA::is_nil(aSO))
145         {
146           //try a path
147           aSO=myStudy->FindObjectByPath(data.c_str());
148           if(CORBA::is_nil(aSO))
149             {
150               std::stringstream msg;
151               msg << "Execution problem: no id or path: " << data << " in study " << myStudy->StudyId();
152               throw Exception(msg.str());
153             }
154         }
155
156       CORBA::String_var path=myStudy->GetObjectPath(aSO);
157       DEBTRACE(path);
158       CORBA::String_var id=aSO->GetID();
159       DEBTRACE(id);
160       //CORBA::Object_var sobj=aSO->GetObject();
161
162       SALOMEDS::GenericAttribute_var aGAttr;
163       CORBA::String_var value;
164
165       if(edGetType()->kind()==Objref)
166         {
167           if ( aSO->FindAttribute( aGAttr, "AttributeIOR" ) )
168             {
169               SALOMEDS::AttributeIOR_var anAttr = SALOMEDS::AttributeIOR::_narrow( aGAttr );
170               value=anAttr->Value();
171               putIOR((const char*)value);
172             }
173           else
174             {
175               //Problem !!!
176               std::string error="Execution problem: no AttributeIOR in study object: ";
177               error=error+data;
178               throw Exception(error);
179             }
180         }
181       else if(edGetType()->kind()==Double )
182         {
183           if ( aSO->FindAttribute( aGAttr, "AttributeReal" ) )
184             {
185               SALOMEDS::AttributeReal_var anAttr = SALOMEDS::AttributeReal::_narrow( aGAttr );
186               CORBA::Double d=anAttr->Value();
187               std::stringstream msg;
188               msg << "<value><double>" << std::setprecision(16) << d << "</double></value>";
189               put(msg.str().c_str());
190             }
191           else
192             {
193               std::string error="Execution problem: no AttributeReal in study object: ";
194               throw Exception(error+data);
195             }
196         }
197       else if(edGetType()->kind()== Int)
198         {
199           if ( aSO->FindAttribute( aGAttr, "AttributeInteger" ) )
200             {
201               SALOMEDS::AttributeInteger_var anAttr = SALOMEDS::AttributeInteger::_narrow( aGAttr );
202               CORBA::Long l=anAttr->Value();
203               std::stringstream msg;
204               msg << "<value><int>" << l << "</int></value>";
205               put(msg.str().c_str());
206             }
207           else
208             {
209               std::string error="Execution problem: no AttributeInteger in study object: ";
210               throw Exception(error+data);
211             }
212         }
213       else
214         {
215           if ( aSO->FindAttribute( aGAttr, "AttributeComment" ) )
216             {
217               SALOMEDS::AttributeComment_var anAttr = SALOMEDS::AttributeComment::_narrow( aGAttr );
218               value=anAttr->Value();
219               DEBTRACE(value);
220               putIOR((const char*)value);
221             }
222           else
223             {
224               std::string error="Execution problem: no AttributeComment in study object: ";
225               throw Exception(error+data);
226             }
227         }
228 }
229
230
231
232
233 SALOMEDS::SObject_ptr findOrCreateSoWithName(SALOMEDS::Study_ptr study, SALOMEDS::StudyBuilder_ptr builder,
234                                              SALOMEDS::SObject_ptr sobj, const std::string& name)
235 {
236   SALOMEDS::ChildIterator_var anIterator= study->NewChildIterator(sobj);
237   SALOMEDS::GenericAttribute_var anAttr;
238   SALOMEDS::AttributeName_var namAttr ;
239   SALOMEDS::SObject_var result=SALOMEDS::SObject::_nil();
240
241   for (; anIterator->More(); anIterator->Next())
242     {
243       SALOMEDS::SObject_var anObj=anIterator->Value();
244       if(anObj->FindAttribute(anAttr, "AttributeName"))
245         {
246           namAttr = SALOMEDS::AttributeName::_narrow( anAttr );
247           CORBA::String_var value=namAttr->Value();
248           if(name == (const char*)value)
249             {
250               result=anObj;
251               break;
252             }
253         }
254     }
255   if(CORBA::is_nil(result))
256     {
257       //create it
258       result = builder->NewObject( sobj );
259       anAttr=builder->FindOrCreateAttribute(result,"AttributeName");
260       namAttr = SALOMEDS::AttributeName::_narrow( anAttr );
261       namAttr->SetValue(name.c_str());
262     }
263   return result._retn();
264 }
265
266 /*! \class YACS::ENGINE::InputStudyPort
267  *  \brief Class for Study input Ports
268  *
269  * \ingroup Ports
270  *
271  * \see StudyOutNode
272  */
273
274 InputStudyPort::InputStudyPort(const std::string& name,  Node* node, TypeCode* type)
275   : InputXmlPort(name, node, type),
276     DataPort(name, node, type),
277     Port(node)
278 {
279 }
280
281 InputStudyPort::InputStudyPort(const InputStudyPort& other, Node *newHelder)
282   : InputXmlPort(other,newHelder),
283     DataPort(other,newHelder),
284     Port(other,newHelder),_storeData(other._storeData)
285 {
286 }
287
288 InputPort* InputStudyPort::clone(Node *newHelder) const
289 {
290   return new InputStudyPort(*this,newHelder);
291 }
292
293 void InputStudyPort::setData(const std::string& data)
294 {
295   _storeData = data;
296   DEBTRACE( "InputStudyPort::setData " << _storeData );
297   modified();
298 }
299
300 std::string InputStudyPort::getData()
301 {
302   DEBTRACE("InputStudyPort::getData " << _storeData);
303   return _storeData;
304 }
305
306 std::string InputStudyPort::getIOR()
307 {
308   switch(edGetType()->kind())
309    {
310    case Objref:
311      return splitXML(_data);
312    default:
313      return _data;
314    }
315 }
316
317 std::string InputStudyPort::splitXML(const std::string& s)
318 {
319   // <value><tag>content</tag></value>
320   std::string::size_type begin = s.find_first_of("<"); // <value>
321   begin = s.find_first_of(">",begin); // end of <value>
322   begin = s.find_first_of("<",begin); // beginning of <tag>
323   begin = s.find_first_of(">",begin); // end of <tag>
324   begin = s.find_first_not_of("> ",begin); // beginning of content
325   std::string::size_type last = s.find_first_of("<",begin); // beginning of </tag>
326   return s.substr(begin,last-begin);
327 }
328
329 std::string InputStudyPort::dump()
330 {
331   DEBTRACE( "InputStudyPort::dump " << _storeData );
332   DEBTRACE( "InputStudyPort::dump " << _data );
333   //return "<value><string>"+_storeData+"</string></value>";
334   return _data;
335 }
336 std::string InputStudyPort::getPyObj()
337 {
338   return getData();
339 }
340 std::string InputStudyPort::getAsString()
341 {
342   return getData();
343 }
344
345 void InputStudyPort::putDataInStudy(SALOMEDS::Study_var myStudy,SALOMEDS::StudyBuilder_var aBuilder)
346 {
347   SALOMEDS::GenericAttribute_var aGAttr;
348   SALOMEDS::SObject_var aSO ;
349   SALOMEDS::AttributeName_var anAttr ;
350   SALOMEDS::AttributeIOR_var iorAttr ;
351   SALOMEDS::SComponent_var       aFather;
352
353   std::string data = getData();
354   DEBTRACE("data: " << data );
355   //try to find an existing id (i:j:k...)
356   aSO = myStudy->FindObjectID(data.c_str());
357   if(CORBA::is_nil(aSO))
358     {
359       // the id does not exist. Try to create it by id
360       aSO=myStudy->CreateObjectID(data.c_str());
361       if(!CORBA::is_nil(aSO))
362         {
363           aGAttr=aBuilder->FindOrCreateAttribute(aSO,"AttributeName");
364           anAttr = SALOMEDS::AttributeName::_narrow( aGAttr );
365           anAttr->SetValue(getName().c_str());
366         }
367     }
368
369   if(CORBA::is_nil(aSO))
370     {
371       //try to publish the object with a given path
372       std::string name; // the component instance name
373       std::string objname; // the object name (eventually with "/")
374       std::string::size_type begin = data.find_first_not_of("/");
375       std::string::size_type pos=data.find_first_of("/", begin);
376       if (pos != std::string::npos)
377         {
378           name=data.substr(begin,pos-begin);
379           objname=data.substr(pos+1);
380         }
381       else
382         {
383           name=data.substr(begin);
384           objname="";
385         }
386       std::string pname="/"+name;
387       DEBTRACE(pname);
388       DEBTRACE(objname);
389
390       Proc* proc=getNode()->getProc();
391       if(proc->componentInstanceMap.count(name)!=0)
392         {
393           // There is a component instance with this name. Is it a Salome component or not ?
394           ComponentInstance* compo=proc->componentInstanceMap[name];
395           if(SalomeComponent* scompo=dynamic_cast<SalomeComponent*>(compo))
396             {
397                   //It's a Salome component, make it the right way : component name, component instance reference, ...
398               CORBA::Object_var compovar= scompo->getCompoPtr();
399               SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(compovar);
400               if ( !CORBA::is_nil( aDriver ) )
401                 {
402                   //It's a Salome component that implements the Driver interface. Use it to publish in study
403                   CORBA::ORB_ptr orb;
404                   CORBA::Object_var anObject;
405                   try
406                     {
407                           orb = getSALOMERuntime()->getOrb();
408                           anObject=orb->string_to_object(getIOR().c_str());
409                     }
410                   catch ( ... ) 
411                     {
412                       std::cerr << "Execution problem: can not get the object to publish" << std::endl;
413                       return;
414                     }
415                   if ( aDriver->CanPublishInStudy( anObject ) ) 
416                     {
417                           //It's fine use the driver to publish
418                           SALOMEDS::SObject_var aTmpSO; // initialized to nil
419                           try 
420                             {
421                               aTmpSO = aDriver->PublishInStudy(myStudy, aTmpSO, anObject,objname.c_str() );
422                               return;
423                             }
424                           catch ( ... ) 
425                             {
426                               std::cerr << "Execution problem: error in PublishInStudy" << std::endl;
427                               return;
428                             }
429                     }
430                 }
431             }
432         }
433
434       // Does component entry exist ?
435       aSO=myStudy->FindObjectByPath(pname.c_str());
436       if(CORBA::is_nil(aSO))
437         {
438           // We have not been able to publish the object with Salome Driver, make it the light way
439           aFather=aBuilder->NewComponent(name.c_str());
440           if(CORBA::is_nil(aFather))
441             {
442               std::cerr << "Execution problem: can not create component: " + name << std::endl;
443               return;
444             }
445           aGAttr=aBuilder->FindOrCreateAttribute(aFather,"AttributeName");
446           anAttr = SALOMEDS::AttributeName::_narrow( aGAttr );
447           anAttr->SetValue(name.c_str());
448           aSO=myStudy->FindObjectByPath(pname.c_str());
449         }
450
451       begin=data.find_first_not_of("/",pos);
452       while (begin != std::string::npos)
453         {
454           pos = data.find_first_of("/", begin);
455           if (pos != std::string::npos)
456             name=data.substr(begin,pos-begin);
457           else
458             name=data.substr(begin);
459           aSO=findOrCreateSoWithName(myStudy,aBuilder,aSO,name);
460           begin=data.find_first_not_of("/",pos);
461         }
462     }
463
464   if(CORBA::is_nil(aSO))
465     {
466       std::cerr << "Execution problem: can not create id or path: " + data + " in study" << std::endl;
467       return;
468     }
469
470   std::string value;
471   SALOMEDS::AttributeComment_var commentAttr ;
472   SALOMEDS::AttributeReal_var realAttr ;
473   SALOMEDS::AttributeInteger_var intAttr ;
474   SALOMEDS::AttributeString_var stringAttr ;
475   double d;
476   long v;
477   switch(edGetType()->kind())
478     {
479       case Objref:
480              value=getIOR();
481              DEBTRACE(value);
482              aGAttr=aBuilder->FindOrCreateAttribute(aSO,"AttributeIOR");
483              iorAttr = SALOMEDS::AttributeIOR::_narrow( aGAttr );
484              iorAttr->SetValue(value.c_str());
485              break;
486       case Double:
487              value=splitXML(dump());
488              DEBTRACE(value);
489              aGAttr=aBuilder->FindOrCreateAttribute(aSO,"AttributeReal");
490              realAttr = SALOMEDS::AttributeReal::_narrow( aGAttr );
491              d=atof(value.c_str());
492              realAttr->SetValue(d);
493              break;
494       case Int:
495              value=splitXML(dump());
496              DEBTRACE(value);
497              aGAttr=aBuilder->FindOrCreateAttribute(aSO,"AttributeInteger");
498              intAttr = SALOMEDS::AttributeInteger::_narrow( aGAttr );
499              v=atol(value.c_str());
500              intAttr->SetValue(v);
501              break;
502       case String:
503       case Bool:
504              value=splitXML(dump());
505              DEBTRACE(value);
506              aGAttr=aBuilder->FindOrCreateAttribute(aSO,"AttributeComment");
507              commentAttr = SALOMEDS::AttributeComment::_narrow( aGAttr );
508              commentAttr->SetValue(value.c_str());
509              break;
510       default:
511              value=dump();
512              DEBTRACE(value);
513              aGAttr=aBuilder->FindOrCreateAttribute(aSO,"AttributeComment");
514              commentAttr = SALOMEDS::AttributeComment::_narrow( aGAttr );
515              commentAttr->SetValue(value.c_str());
516     }
517 }
518
519 } //end namespace ENGINE
520 } //end namespace YACS