1 // Copyright (C) 2006-2008 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "VisitorSaveSchema.hxx"
21 #include "ElementaryNode.hxx"
22 #include "InlineNode.hxx"
23 #include "ServiceNode.hxx"
24 #include "ServiceInlineNode.hxx"
27 #include "ForEachLoop.hxx"
29 #include "ForLoop.hxx"
30 #include "WhileLoop.hxx"
32 #include "InputPort.hxx"
33 #include "TypeCode.hxx"
34 #include "ComponentInstance.hxx"
35 #include "InputDataStreamPort.hxx"
36 #include "OutputDataStreamPort.hxx"
37 #include "Container.hxx"
38 #include "DataNode.hxx"
45 using namespace YACS::ENGINE;
49 #include "YacsTrace.hxx"
51 VisitorSaveSchema::VisitorSaveSchema(ComposedNode *root): _root(root), Visitor(root)
55 VisitorSaveSchema::~VisitorSaveSchema()
59 _out << "</proc>" << endl;
64 void VisitorSaveSchema::openFileSchema(std::string xmlSchema) throw(Exception)
66 _out.open(xmlSchema.c_str(), ios::out);
69 string what = "Impossible to open file for writing: " + xmlSchema;
70 throw Exception(what);
72 _out << "<?xml version='1.0'?>" << endl;
73 _out << "<proc>" << endl;
76 void VisitorSaveSchema::closeFileSchema()
78 if (!_out) throw Exception("No file open for save schema");
79 _out << "</proc>" << endl;
83 void VisitorSaveSchema::visitBloc(Bloc *node)
85 DEBTRACE("START visitBloc " << _root->getChildName(node));
87 int depth = depthNode(node);
88 _out << indent(depth) << "<bloc name=\"" << node->getName() << "\"";
89 if (node->getState() == YACS::DISABLED)
90 _out << " state=\"disabled\">" << endl;
93 writeProperties(node);
94 node->ComposedNode::accept(this);
96 writeSimpleDataLinks(node);
97 writeSimpleStreamLinks(node);
98 _out << indent(depth) << "</bloc>" << endl;
100 DEBTRACE("END visitBloc " << _root->getChildName(node));
103 void VisitorSaveSchema::visitElementaryNode(ElementaryNode *node)
105 DEBTRACE("START visitElementaryNode " << _root->getChildName(node));
107 writeProperties(node);
108 writeInputPorts(node);
109 writeInputDataStreamPorts(node);
110 writeOutputPorts(node);
111 writeOutputDataStreamPorts(node);
113 DEBTRACE("END visitElementaryNode " << _root->getChildName(node));
116 void VisitorSaveSchema::visitForEachLoop(ForEachLoop *node)
118 DEBTRACE("START visitForEachLoop " << _root->getChildName(node));
120 int depth = depthNode(node);
122 _out << indent(depth) << "<foreach name=\"" << node->getName() << "\"";
123 AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
124 if (node->getState() == YACS::DISABLED)
125 _out << " state=\"disabled\"";
126 if (!nbranch->isEmpty())
127 _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
128 if (node->edGetSamplePort())
129 _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
132 writeProperties(node);
133 node->ComposedNode::accept(this);
134 writeSimpleDataLinks(node);
135 writeSimpleStreamLinks(node);
136 _out << indent(depth) << "</foreach>" << endl;
138 DEBTRACE("END visitForEachLoop " << _root->getChildName(node));
141 void VisitorSaveSchema::visitForLoop(ForLoop *node)
143 DEBTRACE("START visitForLoop " << _root->getChildName(node));
145 int depth = depthNode(node);
146 AnyInputPort *nsteps = static_cast<AnyInputPort*>(node->edGetNbOfTimesInputPort());
147 _out << indent(depth) << "<forloop name=\"" << node->getName() << "\"";
148 if (node->getState() == YACS::DISABLED)
149 _out << " state=\"disabled\"";
150 if (nsteps->isEmpty())
153 _out << " nsteps=\"" << nsteps->getIntValue() << "\">" << endl;
154 writeProperties(node);
155 node->ComposedNode::accept(this);
156 writeSimpleDataLinks(node);
157 writeSimpleStreamLinks(node);
158 _out << indent(depth) << "</forloop>" << endl;
160 DEBTRACE("END visitForLoop " << _root->getChildName(node));
163 void VisitorSaveSchema::visitInlineNode(InlineNode *node)
165 DEBTRACE("START visitInlineNode " << _root->getChildName(node));
167 int depth = depthNode(node);
168 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
169 if (node->getState() == YACS::DISABLED)
170 _out << " state=\"disabled\">" << endl;
173 _out << indent(depth+1) << "<script><code><![CDATA[";
174 _out << node->getScript();
175 _out << "]]></code></script>" << endl;
176 writeProperties(node);
177 writeInputPorts(node);
178 writeInputDataStreamPorts(node);
179 writeOutputPorts(node);
180 writeOutputDataStreamPorts(node);
181 _out << indent(depth) << "</inline>" << endl;
183 DEBTRACE("END visitInlineNode " << _root->getChildName(node));
186 void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
188 DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
190 int depth = depthNode(node);
191 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
192 if (node->getState() == YACS::DISABLED)
193 _out << " state=\"disabled\">" << endl;
196 _out << indent(depth+1) << "<function name=\"" << node->getFname() << "\">" << endl;
197 _out << indent(depth+2) << "<code><![CDATA[";
198 _out << node->getScript();
199 _out << "]]></code>" << endl;
200 _out << indent(depth+1) << "</function>" << endl;
201 writeProperties(node);
202 writeInputPorts(node);
203 writeInputDataStreamPorts(node);
204 writeOutputPorts(node);
205 writeOutputDataStreamPorts(node);
206 _out << indent(depth) << "</inline>" << endl;
208 DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node));
211 void VisitorSaveSchema::visitLoop(Loop *node)
213 DEBTRACE("START visitLoop " << _root->getChildName(node));
215 int depth = depthNode(node);
216 writeProperties(node);
217 node->ComposedNode::accept(this);
219 writeSimpleDataLinks(node);
220 writeSimpleStreamLinks(node);
222 DEBTRACE("END visitLoop " << _root->getChildName(node));
225 void VisitorSaveSchema::visitProc(Proc *node)
227 DEBTRACE("START visitProc " << node->getName());
229 writeProperties(node);
230 writeTypeCodes(node);
231 writeContainers(node);
232 node->ComposedNode::accept(this);
234 writeSimpleDataLinks(node);
235 writeSimpleStreamLinks(node);
236 writeParameters(node);
238 DEBTRACE("END visitProc " << node->getName());
241 void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
243 DEBTRACE("START visitServiceNode " << _root->getChildName(node));
245 int depth = depthNode(node);
246 _out << indent(depth) << "<service name=\"" << node->getName() << "\"";
247 if (node->getState() == YACS::DISABLED)
248 _out << " state=\"disabled\">" << endl;
251 if (node->getKind() == "xmlsh")
253 _out << indent(depth+1) << "<kind>xmlsh</kind>" << endl;
254 _out << indent(depth+1) << "<ref>" << node->getRef() << "</ref>" << endl;
258 ComponentInstance *compo = node->getComponent();
259 if (compo && (_componentInstanceMap.find(compo) == _componentInstanceMap.end()))
261 _out << indent(depth+1) << compo->getFileRepr() << endl;
262 _componentInstanceMap[compo] = _root->getChildName(node);
263 Container *cont = compo->getContainer();
266 map<string, Container*>::const_iterator it;
267 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
269 if (it->second == cont) break;
271 if (it != _containerMap.end())
272 _out << indent(depth+1) << "<load container=\"" << it->first << "\"/>" << endl;
277 _out << indent(depth+1) << "<node>" << _componentInstanceMap[compo] << "</node>" << endl;
280 _out << indent(depth+1) << "<method>" << node->getMethod() << "</method>" << endl;
282 writeProperties(node);
283 writeInputPorts(node);
284 writeInputDataStreamPorts(node);
285 writeOutputPorts(node);
286 writeOutputDataStreamPorts(node);
287 _out << indent(depth) << "</service>" << endl;
289 DEBTRACE("END visitServiceNode " << _root->getChildName(node));
292 void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
294 DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node));
296 int depth = depthNode(node);
297 _out << indent(depth) << "<serviceInline name=\"" << node->getName() << "\"";
298 if (node->getState() == YACS::DISABLED)
299 _out << " state=\"disabled\">" << endl;
303 ComponentInstance *compo = node->getComponent();
305 _out << indent(depth+1) << compo->getFileRepr() << endl;
307 _out << indent(depth+1) << "<function name=\"" << node->getMethod() << "\">" << endl;
308 _out << indent(depth+2) << "<code><![CDATA[";
309 _out << node->getScript();
310 _out << "]]></code>" << endl;
311 _out << indent(depth+1) << "</function>" << endl;
312 writeProperties(node);
313 writeInputPorts(node);
314 writeOutputPorts(node);
315 _out << indent(depth) << "</serviceInline>" << endl;
317 DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node));
320 void VisitorSaveSchema::visitPresetNode(DataNode *node)
322 DEBTRACE("START visitPresetNode " << _root->getChildName(node));
323 DEBTRACE("END visitPresetNode " << _root->getChildName(node));
326 void VisitorSaveSchema::visitOutNode(DataNode *node)
328 DEBTRACE("START visitOutNode " << _root->getChildName(node));
329 DEBTRACE("END visitOutNode " << _root->getChildName(node));
332 void VisitorSaveSchema::visitStudyInNode(DataNode *node)
334 DEBTRACE("START visitStudyInNode " << _root->getChildName(node));
335 DEBTRACE("END visitStudyInNode " << _root->getChildName(node));
338 void VisitorSaveSchema::visitStudyOutNode(DataNode *node)
340 DEBTRACE("START visitStudyOutNode " << _root->getChildName(node));
341 DEBTRACE("END visitStudyOutNode " << _root->getChildName(node));
345 void VisitorSaveSchema::visitSwitch(Switch *node)
347 DEBTRACE("START visitSwitch " << _root->getChildName(node));
349 int depth = depthNode(node);
350 AnyInputPort *condition = static_cast<AnyInputPort*>(node->edGetConditionPort());
351 _out << indent(depth) << "<switch name=\"" << node->getName() << "\"";
352 if (node->getState() == YACS::DISABLED)
353 _out << " state=\"disabled\"";
354 if (condition->isEmpty())
357 _out << " select=\"" << condition->getIntValue() << "\">" << endl;
358 writeProperties(node);
359 node->ComposedNode::accept(this);
361 writeSimpleDataLinks(node);
362 writeSimpleStreamLinks(node);
363 _out << indent(depth) << "</switch>" << endl;
365 DEBTRACE("END visitSwitch " << _root->getChildName(node));
368 void VisitorSaveSchema::visitWhileLoop(WhileLoop *node)
370 DEBTRACE("START visitWhileLoop " << _root->getChildName(node));
372 int depth = depthNode(node);
373 _out << indent(depth) << "<while name=\"" << node->getName() << "\"";
374 if (node->getState() == YACS::DISABLED)
375 _out << " state=\"disabled\">" << endl;
378 writeProperties(node);
379 node->ComposedNode::accept(this);
380 writeSimpleDataLinks(node);
381 writeSimpleStreamLinks(node);
382 _out << indent(depth) << "</while>" << endl;
384 DEBTRACE("END visitWhileLoop " << _root->getChildName(node));
388 void VisitorSaveSchema::writeProperties(Node *node)
390 int depth = depthNode(node)+1;
391 map<string,string> properties = getNodeProperties(node);
392 map<string,string>::const_iterator it;
393 for(it = properties.begin(); it != properties.end(); ++it)
395 _out << indent(depth) << "<property name=\"" << it->first
396 << "\" value=\"" << it->second << "\"/>" << endl;
400 void VisitorSaveSchema::dumpTypeCode(TypeCode* type, set<string>& typeNames,map<string, TypeCode*>& typeMap,int depth)
402 DynType kind = type->kind();
403 string typeName = type->name();
404 if (typeNames.find(typeName) != typeNames.end())
408 case YACS::ENGINE::Double:
410 typeNames.insert(typeName);
411 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"double\"/>" << endl;
414 case YACS::ENGINE::Int:
416 typeNames.insert(typeName);
417 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"int\"/>" << endl;
420 case YACS::ENGINE::String:
422 typeNames.insert(typeName);
423 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"string\"/>" << endl;
426 case YACS::ENGINE::Bool:
428 typeNames.insert(typeName);
429 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"bool\"/>" << endl;
432 case YACS::ENGINE::Objref:
434 TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(type);
435 std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
436 //try to dump base classes
437 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
439 if (typeNames.find((*il)->name()) == typeNames.end())
440 dumpTypeCode((*il),typeNames,typeMap,depth);
443 typeNames.insert(typeName);
444 _out << indent(depth) << "<objref name=\"" << typeName << "\" id=\""
445 << objref->id() << "\"";
446 if (listOfBases.empty())
447 _out << "/>" << endl;
451 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
453 _out << indent(depth+1) << "<base>";
454 _out << (*il)->name();
455 _out << "</base>" << endl;
457 _out << indent(depth) << "</objref>" << endl;
461 case YACS::ENGINE::Sequence:
463 TypeCode* content = (TypeCode*)type->contentType();
464 if (typeNames.find(content->name()) == typeNames.end())
466 //content type not dumped
467 dumpTypeCode(content,typeNames,typeMap,depth);
469 typeNames.insert(typeName);
470 _out << indent(depth) << "<sequence name=\"" << typeName << "\" content=\""
471 << content->name() << "\"/>" << endl;
474 case YACS::ENGINE::Array:
476 TypeCode* content = (TypeCode*)type->contentType();
477 if (typeNames.find(content->name()) == typeNames.end())
479 //content type not dumped
480 dumpTypeCode(content,typeNames,typeMap,depth);
482 typeNames.insert(typeName);
483 _out << indent(depth) << "<array name=\"" << typeName << "\" content=\""
484 << content->name() << "\"/>" << endl;
487 case YACS::ENGINE::Struct:
489 TypeCodeStruct* tcStruct = dynamic_cast<TypeCodeStruct*>(type);
491 int mbCnt = tcStruct->memberCount();
492 for (int i=0; i<mbCnt; i++)
494 TypeCode* member = tcStruct->memberType(i);
495 if (typeNames.find(member->name()) == typeNames.end())
497 //content type not dumped
498 dumpTypeCode(member,typeNames,typeMap,depth);
501 typeNames.insert(typeName);
502 _out << indent(depth) << "<struct name=\"" << typeName << "\">" << endl;
503 for (int i=0; i<mbCnt; i++)
505 TypeCode* member = tcStruct->memberType(i);
506 _out << indent(depth+1) << "<member name=\"" <<tcStruct->memberName(i) << "\" type=\"" << member->name() << "\"/>" << endl;
508 _out << indent(depth) << "</struct>" << endl;
513 string what = "wrong TypeCode: ";
514 throw Exception(what);
519 void VisitorSaveSchema::writeTypeCodes(Proc *proc)
521 int depth = depthNode(proc)+1;
522 map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
523 map<string, TypeCode*>::const_iterator it;
524 set<string> typeNames;
526 // --- force definition of simple types first
528 for (it = typeMap.begin(); it != typeMap.end(); it++)
530 dumpTypeCode(it->second,typeNames,typeMap,depth);
534 void VisitorSaveSchema::writeContainers(Proc *proc)
536 int depth = depthNode(proc)+1;
537 _containerMap = getContainerMap(proc);
538 map<string, Container*>::const_iterator it;
539 for (it = _containerMap.begin(); it != _containerMap.end(); it++)
541 string name = it->first;
542 _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
543 map<string, string> properties = (it->second)->getProperties();
544 map<string, string>::iterator itm;
545 for(itm = properties.begin(); itm != properties.end(); ++itm)
546 _out << indent(depth+1) << "<property name=\"" << (*itm).first
547 << "\" value=\"" << (*itm).second << "\"/>" << endl;
548 _out << indent(depth) << "</container>" << endl;
553 void VisitorSaveSchema::writeInputPorts(Node *node)
555 int depth = depthNode(node)+1;
556 list<InputPort*> listOfInputPorts = node->getSetOfInputPort();
557 for (list<InputPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
559 _out << indent(depth) << "<inport name=\"" << (*it)->getName() << "\" type=\""
560 << (*it)->edGetType()->name() << "\"/>" << endl;
564 void VisitorSaveSchema::writeInputDataStreamPorts(Node *node)
566 int depth = depthNode(node)+1;
567 list<InputDataStreamPort*> listOfInputPorts = node->getSetOfInputDataStreamPort();
568 for (list<InputDataStreamPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
570 std::map<std::string,std::string> aPropMap = (*it)->getPropertyMap();
571 if ( aPropMap.empty() )
572 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
573 << (*it)->edGetType()->name() << "\"/>" << endl;
576 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
577 << (*it)->edGetType()->name() << "\">" << endl;
578 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
579 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
580 << (*itP).second << "\"/>" << endl;
581 _out << indent(depth) << "</instream>" << endl;
586 void VisitorSaveSchema::writeOutputPorts(Node *node)
588 int depth = depthNode(node)+1;
589 list<OutputPort*> listOfOutputPorts = node->getSetOfOutputPort();
590 for (list<OutputPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
592 _out << indent(depth) << "<outport name=\"" << (*it)->getName() << "\" type=\""
593 << (*it)->edGetType()->name() << "\"/>" << endl;
597 void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node)
599 int depth = depthNode(node)+1;
600 list<OutputDataStreamPort*> listOfOutputPorts = node->getSetOfOutputDataStreamPort();
601 for (list<OutputDataStreamPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
603 std::map<std::string,std::string> aPropMap = (*it)->getPropertyMap();
604 if ( aPropMap.empty() )
605 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
606 << (*it)->edGetType()->name() << "\"/>" << endl;
609 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
610 << (*it)->edGetType()->name() << "\">" << endl;
611 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
612 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
613 << (*itP).second << "\"/>" << endl;
614 _out << indent(depth) << "</outstream>" << endl;
619 void VisitorSaveSchema::writeControls(ComposedNode *node)
621 int depth = depthNode(node)+1;
622 list<Node*> setOfChildren = node->edGetDirectDescendants();
623 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
625 // --- Control links from direct descendant to nodes inside the bloc
626 set<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
627 for (set<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
629 Node *to = (*ig)->getNode();
630 if (node->isInMyDescendance(to))
633 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
634 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
637 // --- Control links from nodes inside the bloc to direct descendant
638 // avoid links between direct descendants (already done above)
639 list<OutGate*> listOfOutGates = (*ic)->getInGate()->getBackLinks();
640 for (list<OutGate*>::iterator ig = listOfOutGates.begin(); ig != listOfOutGates.end(); ++ig)
642 Node *from = (*ig)->getNode();
643 if ((node->isInMyDescendance(from)) && (from->getFather()->getNumId() != node->getNumId()))
646 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
647 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
654 * Write simple data links from and to direct children of node (grand children already done).
655 * First, for all output ports of direct children, write links where the input port is inside
656 * the node scope. Keep in memory the links where the input port is outside the node scope.
657 * Second, retreive links where the output port is inside the scope, using the links kept in memory
658 * and not yet written.
660 void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
662 int depth = depthNode(node)+1;
663 list<Node*> setOfChildren = node->edGetDirectDescendants();
665 list<Node*> setOfChildrenPlusSplitters = setOfChildren;
667 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
668 // add "splitter" node of ForEachLoop nodes to the set of children
669 if ( dynamic_cast<ForEachLoop*>( *ic ) )
671 Node *nodeToInsert=(*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
672 if(find(setOfChildrenPlusSplitters.begin(),setOfChildrenPlusSplitters.end(),nodeToInsert)==setOfChildrenPlusSplitters.end())
673 setOfChildrenPlusSplitters.push_back(nodeToInsert);
676 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
678 for (list<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
681 list<OutputPort*> listOP = from->getLocalOutputPorts();
682 for (list<OutputPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
684 OutputPort* anOP = *io;
685 set<InPort*> setIP = anOP->edSetInPort();
686 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
689 Node* to = anIP->getNode();
690 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
691 << " to " << to->getName() << " inputPort " << anIP->getName() );
692 Node* child = node->isInMyDescendance(to);
693 if (child && (child->getNumId() != node->getNumId())
694 && (from->getNumId() != to->getNumId()))
696 DEBTRACE( "BINGO!" );
699 if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoop*>(from->getFather()) )
700 fromName = from->getFather()->getName();
702 fromName = node->getChildName(from);
705 if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoop*>(to->getFather()) )
706 childName = node->getChildName(to->getFather());
708 childName = node->getChildName(to);
709 _out << indent(depth) << "<datalink control=\"false\">" << endl;
710 _out << indent(depth+1) << "<fromnode>" << fromName << "</fromnode> ";
711 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
712 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
713 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
714 _out << indent(depth) << "</datalink>" << endl;
717 { // --- store info to create the link later, given the input port
718 DEBTRACE( "For later" );
719 struct DataLinkInfo aLink = { from, to, anOP, anIP, false };
720 _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
726 // --- second pass, retreive links where the output port is inside the scope.
728 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
730 std::multimap<int, DataLinkInfo>::iterator pos;
731 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end(); ++pos)
733 Node* to = (pos->second).to;
734 Node* child = node->isInMyDescendance(to);
735 if (child && (child->getNumId() != node->getNumId()))
737 InPort* anIP = (pos->second).inp;
738 int portId = anIP->getNumId();
739 Node* from = (pos->second).from;
740 child = node->isInMyDescendance(from);
741 if (child && (child->getNumId() != node->getNumId()))
742 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
744 string childName = node->getChildName(from);
745 OutPort *anOP = (pos->second).outp;
746 (pos->second).toDelete = true;
747 _out << indent(depth) << "<datalink control=\"false\">" << endl;
748 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
749 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
750 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
751 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
752 _out << indent(depth) << "</datalink>" << endl;
757 // --- remove the link written from the multimap
759 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end();)
761 if ((pos->second).toDelete)
762 _mapOfDLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
769 void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
771 int depth = depthNode(node)+1;
772 list<Node*> setOfChildren = node->edGetDirectDescendants();
774 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
776 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
779 if ( dynamic_cast<ComposedNode*>(from) ) continue;
780 list<OutputDataStreamPort*> listOP = from->getSetOfOutputDataStreamPort();
781 for (list<OutputDataStreamPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
783 OutputDataStreamPort* anOP = *io;
784 set<InPort*> setIP = anOP->edSetInPort();
785 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
788 Node* to = anIP->getNode();
789 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
790 << " to " << to->getName() << " inputPort " << anIP->getName() );
791 Node* child = node->isInMyDescendance(to);
792 if (child && (child->getNumId() != node->getNumId())
793 && (from->getNumId() != to->getNumId()))
795 DEBTRACE( "BINGO!" );
796 string childName = node->getChildName(to);
797 _out << indent(depth) << "<stream>" << endl;
798 _out << indent(depth+1) << "<fromnode>" << node->getChildName(from) << "</fromnode> ";
799 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
800 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
801 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
803 std::map<std::string,std::string> aPropMap = anOP->getPropertyMap();
804 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
806 string notAlinkProperty = "DependencyType";
807 if (notAlinkProperty != (*itP).first)
808 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
809 << (*itP).second << "\"/>" << endl;
811 _out << indent(depth) << "</stream>" << endl;
814 { // --- store info to create the link later, given the input port
815 DEBTRACE("For later" );
816 struct StreamLinkInfo aLink = { from, to, anOP, anIP, false };
817 _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
823 // --- second pass, retreive links where the output port is inside the scope.
825 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
827 std::multimap<int, StreamLinkInfo>::iterator pos;
828 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end(); ++pos)
830 Node* to = (pos->second).to;
831 Node* child = node->isInMyDescendance(to);
832 if (child && (child->getNumId() != node->getNumId()))
834 InPort* anIP = (pos->second).inp;
835 int portId = anIP->getNumId();
836 Node* from = (pos->second).from;
837 child = node->isInMyDescendance(from);
838 if (child && (child->getNumId() != node->getNumId()))
839 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
841 string childName = node->getChildName(from);
842 OutputDataStreamPort *anOP = (pos->second).outp;
843 (pos->second).toDelete = true;
844 _out << indent(depth) << "<stream>" << endl;
845 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
846 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
847 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
848 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
850 std::map<std::string,std::string> aPropMap = anOP->getPropertyMap();
851 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
852 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
853 << (*itP).second << "\"/>" << endl;
855 _out << indent(depth) << "</stream>" << endl;
860 // --- remove the link written from the multimap
862 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end();)
864 if ((pos->second).toDelete)
865 _mapOfSLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
872 std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
875 list< Node *> setOfNode = node->edGetDirectDescendants();
876 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
878 if ( dynamic_cast<ComposedNode*> (*iter) )
880 set<Node *> myCurrentSet = getAllNodes(dynamic_cast<ComposedNode*> (*iter));
881 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
886 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
887 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
894 void VisitorSaveSchema::writeParameters(Proc *proc)
896 // set<Node*> nodeSet = proc->getAllRecursiveConstituents();
897 set<Node*> nodeSet = getAllNodes(proc);
898 for (set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter)
900 // ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
902 // writeParametersNode(proc,node);
903 writeParametersNode(proc,(*iter));
907 void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node)
910 list<InputPort *> setOfInputPort = node->getLocalInputPorts();
911 if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
913 DEBTRACE("writeParametersNode foreach");
914 setOfInputPort.push_back( foreach->edGetSeqOfSamplesPort());
916 list<InputPort *>::iterator iter;
917 for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter)
919 if (!(*iter)->isEmpty())
921 _out << indent(depth) << "<parameter>" << endl;
922 _out << indent(depth+1) << "<tonode>" << proc->getChildName(node) << "</tonode>";
923 _out << "<toport>" << (*iter)->getName() << "</toport>" <<endl;
926 _out << indent(depth+1) << (*iter)->dump();
928 catch (YACS::Exception &e)
930 _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << endl;
932 _out << indent(depth) << "</parameter>" << endl;
937 void VisitorSaveSchema::beginCase(Node* node)
939 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
942 int depth = depthNode(node) -1;
943 int myCase = myFather->getRankOfNode(node);
944 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
945 _out << indent(depth) << "<default>" << endl;
947 _out << indent(depth) << "<case id=\"" << myCase << "\">" << endl;
951 void VisitorSaveSchema::endCase(Node* node)
953 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
956 int depth = depthNode(node) -1;
957 int myCase = myFather->getRankOfNode(node);
958 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
959 _out << indent(depth) << "</default>" << endl;
961 _out << indent(depth) << "</case>" << endl;
965 int VisitorSaveSchema::depthNode(Node* node)
968 ComposedNode *father = node->getFather();
972 if (dynamic_cast<Switch*>(father)) depth +=1;
973 if (father->getNumId() == _root->getNumId()) break;
974 father = father->getFather();
979 SchemaSave::SchemaSave(Proc* proc): _p(proc)
984 void SchemaSave::save(std::string xmlSchemaFile)
986 VisitorSaveSchema vss(_p);
987 vss.openFileSchema(xmlSchemaFile);
989 vss.closeFileSchema();