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