1 // Copyright (C) 2006-2016 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, or (at your option) any later version.
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
20 #include "VisitorSaveSchema.hxx"
22 #include "ElementaryNode.hxx"
23 #include "InlineNode.hxx"
24 #include "ServiceNode.hxx"
25 #include "ServerNode.hxx"
26 #include "ServiceInlineNode.hxx"
29 #include "ForEachLoop.hxx"
30 #include "OptimizerLoop.hxx"
32 #include "ForLoop.hxx"
33 #include "WhileLoop.hxx"
35 #include "InputPort.hxx"
36 #include "TypeCode.hxx"
37 #include "HomogeneousPoolContainer.hxx"
38 #include "ComponentInstance.hxx"
39 #include "InputDataStreamPort.hxx"
40 #include "OutputDataStreamPort.hxx"
41 #include "Container.hxx"
42 #include "DataNode.hxx"
49 using namespace YACS::ENGINE;
53 #include "YacsTrace.hxx"
55 /*! \class YACS::ENGINE::VisitorSaveSchema
56 * \brief Base class for all visitors that save a schema.
58 * Can be specialized in runtime.
61 VisitorSaveSchema::VisitorSaveSchema(ComposedNode *root): _root(root), Visitor(root)
65 VisitorSaveSchema::~VisitorSaveSchema()
69 _out << "</proc>" << endl;
74 void VisitorSaveSchema::openFileSchema(std::string xmlSchema) throw(YACS::Exception)
76 _out.open(xmlSchema.c_str(), ios::out);
79 string what = "Impossible to open file for writing: " + xmlSchema;
80 throw Exception(what);
82 _out << "<?xml version='1.0' encoding='iso-8859-1' ?>" << endl;
85 void VisitorSaveSchema::closeFileSchema()
87 if (!_out) throw Exception("No file open for save schema");
88 _out << "</proc>" << endl;
92 void VisitorSaveSchema::visitBloc(Bloc *node)
94 DEBTRACE("START visitBloc " << _root->getChildName(node));
96 int depth = depthNode(node);
97 _out << indent(depth) << "<bloc name=\"" << node->getName() << "\"";
98 if (node->getState() == YACS::DISABLED)
99 _out << " state=\"disabled\">" << endl;
102 writeProperties(node);
103 node->ComposedNode::accept(this);
105 writeSimpleDataLinks(node);
106 writeSimpleStreamLinks(node);
107 _out << indent(depth) << "</bloc>" << endl;
109 DEBTRACE("END visitBloc " << _root->getChildName(node));
112 void VisitorSaveSchema::visitElementaryNode(ElementaryNode *node)
114 DEBTRACE("START visitElementaryNode " << _root->getChildName(node));
116 writeProperties(node);
117 writeInputPorts(node);
118 writeInputDataStreamPorts(node);
119 writeOutputPorts(node);
120 writeOutputDataStreamPorts(node);
122 DEBTRACE("END visitElementaryNode " << _root->getChildName(node));
125 void VisitorSaveSchema::visitForEachLoop(ForEachLoop *node)
127 DEBTRACE("START visitForEachLoop " << _root->getChildName(node));
129 int depth = depthNode(node);
131 _out << indent(depth) << "<foreach name=\"" << node->getName() << "\"";
132 AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
133 if (node->getState() == YACS::DISABLED)
134 _out << " state=\"disabled\"";
135 if (!nbranch->isEmpty())
136 _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
137 if (node->edGetSamplePort())
138 _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
141 writeProperties(node);
142 node->DynParaLoop::accept(this);
143 writeSimpleDataLinks(node);
144 writeSimpleStreamLinks(node);
145 _out << indent(depth) << "</foreach>" << endl;
147 DEBTRACE("END visitForEachLoop " << _root->getChildName(node));
150 void VisitorSaveSchema::visitOptimizerLoop(OptimizerLoop *node)
152 DEBTRACE("START visitOptimizerLoop " << _root->getChildName(node));
154 int depth = depthNode(node);
156 _out << indent(depth) << "<optimizer name=\"" << node->getName() << "\"";
157 AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
158 if (node->getState() == YACS::DISABLED)
159 _out << " state=\"disabled\"";
160 if (!nbranch->isEmpty())
161 _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
162 _out << " lib=\"" << node->getAlgLib() << "\"";
163 _out << " entry=\"" << node->getSymbol() << "\"";
166 writeProperties(node);
167 node->DynParaLoop::accept(this);
168 writeSimpleDataLinks(node);
169 writeSimpleStreamLinks(node);
170 _out << indent(depth) << "</optimizer>" << endl;
172 DEBTRACE("END visitOptimizerLoop " << _root->getChildName(node));
175 void VisitorSaveSchema::visitDynParaLoop(DynParaLoop *node)
177 DEBTRACE("START visitDynParaLoop " << _root->getChildName(node));
178 int depth = depthNode(node);
179 if (node->getInitNode() != NULL)
181 _out << indent(depth+1) << "<initnode>" << endl;
182 node->getInitNode()->accept(this);
183 _out << indent(depth+1) << "</initnode>" << endl;
185 if (node->getExecNode() != NULL)
187 node->getExecNode()->accept(this);
189 if (node->getFinalizeNode() != NULL)
191 _out << indent(depth+1) << "<finalizenode>" << endl;
192 node->getFinalizeNode()->accept(this);
193 _out << indent(depth+1) << "</finalizenode>" << endl;
195 DEBTRACE("END visitDynParaLoop " << _root->getChildName(node));
198 void VisitorSaveSchema::visitForLoop(ForLoop *node)
200 DEBTRACE("START visitForLoop " << _root->getChildName(node));
202 int depth = depthNode(node);
203 AnyInputPort *nsteps = static_cast<AnyInputPort*>(node->edGetNbOfTimesInputPort());
204 _out << indent(depth) << "<forloop name=\"" << node->getName() << "\"";
205 if (node->getState() == YACS::DISABLED)
206 _out << " state=\"disabled\"";
207 if (nsteps->isEmpty())
210 _out << " nsteps=\"" << nsteps->getIntValue() << "\">" << endl;
211 writeProperties(node);
212 node->ComposedNode::accept(this);
213 writeSimpleDataLinks(node);
214 writeSimpleStreamLinks(node);
215 _out << indent(depth) << "</forloop>" << endl;
217 DEBTRACE("END visitForLoop " << _root->getChildName(node));
220 void VisitorSaveSchema::visitInlineNode(InlineNode *node)
222 DEBTRACE("START visitInlineNode " << _root->getChildName(node));
224 int depth = depthNode(node);
225 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
226 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
228 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
229 if (node->getState() == YACS::DISABLED)
230 _out << " state=\"disabled\">" << endl;
233 _out << indent(depth+1) << "<script><code><![CDATA[";
234 _out << node->getScript();
235 _out << "]]></code></script>" << endl;
237 //add load container if node is remote
238 Container *cont = node->getContainer();
240 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
242 writeProperties(node);
243 writeInputPorts(node);
244 writeInputDataStreamPorts(node);
245 writeOutputPorts(node);
246 writeOutputDataStreamPorts(node);
248 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
249 _out << indent(depth) << "</inline>" << endl;
251 _out << indent(depth) << "</remote>" << endl;
254 DEBTRACE("END visitInlineNode " << _root->getChildName(node));
257 void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
259 DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
261 int depth = depthNode(node);
262 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
263 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
265 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
266 if (node->getState() == YACS::DISABLED)
267 _out << " state=\"disabled\">" << endl;
270 _out << indent(depth+1) << "<function name=\"" << node->getFname() << "\">" << endl;
271 _out << indent(depth+2) << "<code><![CDATA[";
272 _out << node->getScript();
273 _out << "]]></code>" << endl;
274 _out << indent(depth+1) << "</function>" << endl;
276 //add load container if node is remote
277 Container *cont = node->getContainer();
279 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
281 writeProperties(node);
282 writeInputPorts(node);
283 writeInputDataStreamPorts(node);
284 writeOutputPorts(node);
285 writeOutputDataStreamPorts(node);
287 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
288 _out << indent(depth) << "</inline>" << endl;
290 _out << indent(depth) << "</remote>" << endl;
293 DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node));
296 void VisitorSaveSchema::visitLoop(Loop *node)
298 DEBTRACE("START visitLoop " << _root->getChildName(node));
300 int depth = depthNode(node);
301 writeProperties(node);
302 node->ComposedNode::accept(this);
304 writeSimpleDataLinks(node);
305 writeSimpleStreamLinks(node);
307 DEBTRACE("END visitLoop " << _root->getChildName(node));
310 void VisitorSaveSchema::visitProc(Proc *node)
312 DEBTRACE("START visitProc " << node->getName());
313 _out << "<proc name=\""<< node->getName() << "\">" << endl;
315 writeProperties(node);
316 writeTypeCodes(node);
317 writeContainers(node);
318 writeComponentInstances(node);
319 node->ComposedNode::accept(this);
321 writeSimpleDataLinks(node);
322 writeSimpleStreamLinks(node);
323 writeParameters(node);
325 DEBTRACE("END visitProc " << node->getName());
328 void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
330 DEBTRACE("START visitServiceNode " << _root->getChildName(node));
332 int depth = depthNode(node);
333 _out << indent(depth) << "<service name=\"" << node->getName() << "\"";
334 if (node->getState() == YACS::DISABLED)
335 _out << " state=\"disabled\">" << endl;
338 if (node->getKind() == "xmlsh")
340 _out << indent(depth+1) << "<kind>xmlsh</kind>" << endl;
341 _out << indent(depth+1) << "<ref>" << node->getRef() << "</ref>" << endl;
345 ComponentInstance *compo = node->getComponent();
346 if (compo && !compo->isAnonymous())
348 _out << indent(depth+1) << "<componentinstance>" << compo->getInstanceName() << "</componentinstance>" << endl;
350 else if (compo && (_componentInstanceMap.find(compo) == _componentInstanceMap.end()))
352 _out << indent(depth+1) << compo->getFileRepr() << endl;
353 _componentInstanceMap[compo] = _root->getChildName(node);
354 Container *cont = compo->getContainer();
357 map<string, Container*>::const_iterator it;
358 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
360 if (it->second == cont) break;
362 if (it != _containerMap.end())
363 _out << indent(depth+1) << "<load container=\"" << it->first << "\"/>" << endl;
368 _out << indent(depth+1) << "<node>" << _componentInstanceMap[compo] << "</node>" << endl;
372 _out << indent(depth+1) << "<component>" << "UNKNOWN" << "</component>" << endl;
375 _out << indent(depth+1) << "<method>" << node->getMethod() << "</method>" << endl;
377 writeProperties(node);
378 writeInputPorts(node);
379 writeInputDataStreamPorts(node);
380 writeOutputPorts(node);
381 writeOutputDataStreamPorts(node);
382 _out << indent(depth) << "</service>" << endl;
384 DEBTRACE("END visitServiceNode " << _root->getChildName(node));
387 void VisitorSaveSchema::visitServerNode(ServerNode *node)
389 DEBTRACE("START visitServerNode " << _root->getChildName(node));
391 int depth = depthNode(node);
392 _out << indent(depth) << "<server name=\"" << node->getName() << "\"";
393 if (node->getState() == YACS::DISABLED)
394 _out << " state=\"disabled\">" << endl;
397 Container *cont = node->getContainer();
398 map<string, Container*>::const_iterator it;
399 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
401 if (it->second == cont) break;
403 if (it != _containerMap.end())
404 _out << indent(depth+1) << "<loadcontainer>" << it->first << "</loadcontainer>" << endl;
407 _out << indent(depth+1) << "<node>" << _contnentInstanceMap[cont] << "</node>" << endl;
409 _out << indent(depth+1) << "<method>" << node->getFname() << "</method>" << endl;
410 _out << indent(depth+2) << "<script><code><![CDATA[";
411 _out << node->getScript();
412 _out << "]]></code></script>" << endl;
413 //_out << indent(depth+1) << "</function>" << endl;
414 writeProperties(node);
415 writeInputPorts(node);
416 writeInputDataStreamPorts(node);
417 writeOutputPorts(node);
418 writeOutputDataStreamPorts(node);
419 _out << indent(depth) << "</server>" << endl;
421 DEBTRACE("END visitServerNode " << _root->getChildName(node));
424 void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
426 DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node));
428 int depth = depthNode(node);
429 _out << indent(depth) << "<serviceInline name=\"" << node->getName() << "\"";
430 if (node->getState() == YACS::DISABLED)
431 _out << " state=\"disabled\">" << endl;
435 ComponentInstance *compo = node->getComponent();
437 _out << indent(depth+1) << compo->getFileRepr() << endl;
439 _out << indent(depth+1) << "<function name=\"" << node->getMethod() << "\">" << endl;
440 _out << indent(depth+2) << "<code><![CDATA[";
441 _out << node->getScript();
442 _out << "]]></code>" << endl;
443 _out << indent(depth+1) << "</function>" << endl;
444 writeProperties(node);
445 writeInputPorts(node);
446 writeOutputPorts(node);
447 _out << indent(depth) << "</serviceInline>" << endl;
449 DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node));
452 void VisitorSaveSchema::visitPresetNode(DataNode *node)
454 DEBTRACE("START visitPresetNode " << _root->getChildName(node));
455 DEBTRACE("END visitPresetNode " << _root->getChildName(node));
458 void VisitorSaveSchema::visitOutNode(DataNode *node)
460 DEBTRACE("START visitOutNode " << _root->getChildName(node));
461 DEBTRACE("END visitOutNode " << _root->getChildName(node));
464 void VisitorSaveSchema::visitStudyInNode(DataNode *node)
466 DEBTRACE("START visitStudyInNode " << _root->getChildName(node));
467 DEBTRACE("END visitStudyInNode " << _root->getChildName(node));
470 void VisitorSaveSchema::visitStudyOutNode(DataNode *node)
472 DEBTRACE("START visitStudyOutNode " << _root->getChildName(node));
473 DEBTRACE("END visitStudyOutNode " << _root->getChildName(node));
477 void VisitorSaveSchema::visitSwitch(Switch *node)
479 DEBTRACE("START visitSwitch " << _root->getChildName(node));
481 int depth = depthNode(node);
482 AnyInputPort *condition = static_cast<AnyInputPort*>(node->edGetConditionPort());
483 _out << indent(depth) << "<switch name=\"" << node->getName() << "\"";
484 if (node->getState() == YACS::DISABLED)
485 _out << " state=\"disabled\"";
486 if (condition->isEmpty())
489 _out << " select=\"" << condition->getIntValue() << "\">" << endl;
490 writeProperties(node);
491 node->ComposedNode::accept(this);
493 writeSimpleDataLinks(node);
494 writeSimpleStreamLinks(node);
495 _out << indent(depth) << "</switch>" << endl;
497 DEBTRACE("END visitSwitch " << _root->getChildName(node));
500 void VisitorSaveSchema::visitWhileLoop(WhileLoop *node)
502 DEBTRACE("START visitWhileLoop " << _root->getChildName(node));
504 int depth = depthNode(node);
505 _out << indent(depth) << "<while name=\"" << node->getName() << "\"";
506 if (node->getState() == YACS::DISABLED)
507 _out << " state=\"disabled\">" << endl;
510 writeProperties(node);
511 node->ComposedNode::accept(this);
512 writeSimpleDataLinks(node);
513 writeSimpleStreamLinks(node);
514 _out << indent(depth) << "</while>" << endl;
516 DEBTRACE("END visitWhileLoop " << _root->getChildName(node));
520 void VisitorSaveSchema::writeProperties(Node *node)
522 int depth = depthNode(node)+1;
523 map<string,string> properties = getNodeProperties(node);
524 map<string,string>::const_iterator it;
525 for(it = properties.begin(); it != properties.end(); ++it)
527 _out << indent(depth) << "<property name=\"" << it->first
528 << "\" value=\"" << it->second << "\"/>" << endl;
532 void VisitorSaveSchema::dumpTypeCode(TypeCode* type, std::set<std::string>& typeNames,std::map<std::string, TypeCode*>& typeMap,int depth)
534 DynType kind = type->kind();
535 string typeName = type->name();
536 if (typeNames.find(typeName) != typeNames.end())
540 case YACS::ENGINE::Double:
542 typeNames.insert(typeName);
543 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"double\"/>" << endl;
546 case YACS::ENGINE::Int:
548 typeNames.insert(typeName);
549 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"int\"/>" << endl;
552 case YACS::ENGINE::String:
554 typeNames.insert(typeName);
555 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"string\"/>" << endl;
558 case YACS::ENGINE::Bool:
560 typeNames.insert(typeName);
561 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"bool\"/>" << endl;
564 case YACS::ENGINE::Objref:
566 TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(type);
567 std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
568 //try to dump base classes
569 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
571 if (typeNames.find((*il)->name()) == typeNames.end())
572 dumpTypeCode((*il),typeNames,typeMap,depth);
575 typeNames.insert(typeName);
576 _out << indent(depth) << "<objref name=\"" << typeName << "\" id=\""
577 << objref->id() << "\"";
578 if (listOfBases.empty())
579 _out << "/>" << endl;
583 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
585 _out << indent(depth+1) << "<base>";
586 _out << (*il)->name();
587 _out << "</base>" << endl;
589 _out << indent(depth) << "</objref>" << endl;
593 case YACS::ENGINE::Sequence:
595 TypeCode* content = (TypeCode*)type->contentType();
596 if (typeNames.find(content->name()) == typeNames.end())
598 //content type not dumped
599 dumpTypeCode(content,typeNames,typeMap,depth);
601 typeNames.insert(typeName);
602 _out << indent(depth) << "<sequence name=\"" << typeName << "\" content=\""
603 << content->name() << "\"/>" << endl;
606 case YACS::ENGINE::Array:
608 TypeCode* content = (TypeCode*)type->contentType();
609 if (typeNames.find(content->name()) == typeNames.end())
611 //content type not dumped
612 dumpTypeCode(content,typeNames,typeMap,depth);
614 typeNames.insert(typeName);
615 _out << indent(depth) << "<array name=\"" << typeName << "\" content=\""
616 << content->name() << "\"/>" << endl;
619 case YACS::ENGINE::Struct:
621 TypeCodeStruct* tcStruct = dynamic_cast<TypeCodeStruct*>(type);
623 int mbCnt = tcStruct->memberCount();
624 for (int i=0; i<mbCnt; i++)
626 TypeCode* member = tcStruct->memberType(i);
627 if (typeNames.find(member->name()) == typeNames.end())
629 //content type not dumped
630 dumpTypeCode(member,typeNames,typeMap,depth);
633 typeNames.insert(typeName);
634 _out << indent(depth) << "<struct name=\"" << typeName << "\">" << endl;
635 for (int i=0; i<mbCnt; i++)
637 TypeCode* member = tcStruct->memberType(i);
638 _out << indent(depth+1) << "<member name=\"" <<tcStruct->memberName(i) << "\" type=\"" << member->name() << "\"/>" << endl;
640 _out << indent(depth) << "</struct>" << endl;
645 string what = "wrong TypeCode: ";
646 throw Exception(what);
651 void VisitorSaveSchema::writeTypeCodes(Proc *proc)
653 int depth = depthNode(proc)+1;
654 map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
655 map<string, TypeCode*>::const_iterator it;
656 set<string> typeNames;
658 // --- force definition of simple types first
660 for (it = typeMap.begin(); it != typeMap.end(); it++)
662 dumpTypeCode(it->second,typeNames,typeMap,depth);
666 void VisitorSaveSchema::writeComponentInstances(Proc *proc)
668 int depth = depthNode(proc)+1;
669 std::map<std::string, ComponentInstance*>::const_iterator it;
670 for (it = proc->componentInstanceMap.begin(); it != proc->componentInstanceMap.end(); it++)
672 string name = it->first;
673 ComponentInstance* inst=it->second;
674 if(!inst->isAnonymous())
676 _out << indent(depth) << "<componentinstance name=\"" << inst->getInstanceName() << "\">" << endl;
677 _out << indent(depth+1) << "<component>" << inst->getCompoName() << "</component>" << endl;
679 Container *cont = inst->getContainer();
681 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
683 std::map<std::string, std::string> properties = inst->getProperties();
684 std::map<std::string, std::string>::const_iterator itm;
685 for(itm = properties.begin(); itm != properties.end(); ++itm)
686 _out << indent(depth+1) << "<property name=\"" << (*itm).first
687 << "\" value=\"" << (*itm).second << "\"/>" << endl;
689 _out << indent(depth) << "</componentinstance>" << endl;
694 void VisitorSaveSchema::writeContainers(Proc *proc)
696 int depth = depthNode(proc)+1;
697 _containerMap = getContainerMap(proc);
698 map<string, Container*>::const_iterator it;
699 for (it = _containerMap.begin(); it != _containerMap.end(); it++)
701 string name = it->first;
702 _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
703 _out << indent(depth+1) << "<property name=\"" << Container::KIND_ENTRY << "\" value=\"" << it->second->getKind() << "\"/>" << endl;
704 _out << indent(depth+1) << "<property name=\"" << Container::AOC_ENTRY << "\" value=\"" << (int)it->second->isAttachedOnCloning() << "\"/>" << endl;
705 map<string, string> properties = (it->second)->getProperties();
706 map<string, string>::iterator itm;
707 for(itm = properties.begin(); itm != properties.end(); ++itm)
709 if((*itm).first==Container::KIND_ENTRY)
711 if((*itm).first==Container::AOC_ENTRY)
713 if((*itm).first!=HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY)
715 _out << indent(depth+1) << "<property name=\"" << (*itm).first << "\" value=\"" << (*itm).second << "\"/>" << endl;
719 _out << indent(depth+1) << "<initializescriptkey><code><![CDATA[" << (*itm).second << "]]></code></initializescriptkey>" << endl;
722 _out << indent(depth) << "</container>" << endl;
727 void VisitorSaveSchema::writeInputPorts(Node *node)
729 int depth = depthNode(node)+1;
730 list<InputPort*> listOfInputPorts = node->getSetOfInputPort();
731 for (list<InputPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
733 _out << indent(depth) << "<inport name=\"" << (*it)->getName() << "\" type=\""
734 << (*it)->edGetType()->name() << "\"/>" << endl;
738 void VisitorSaveSchema::writeInputDataStreamPorts(Node *node)
740 int depth = depthNode(node)+1;
741 list<InputDataStreamPort*> listOfInputPorts = node->getSetOfInputDataStreamPort();
742 for (list<InputDataStreamPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
744 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
745 if ( aPropMap.empty() )
746 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
747 << (*it)->edGetType()->name() << "\"/>" << endl;
750 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
751 << (*it)->edGetType()->name() << "\">" << endl;
752 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
753 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
754 << (*itP).second << "\"/>" << endl;
755 _out << indent(depth) << "</instream>" << endl;
760 void VisitorSaveSchema::writeOutputPorts(Node *node)
762 int depth = depthNode(node)+1;
763 list<OutputPort*> listOfOutputPorts = node->getSetOfOutputPort();
764 for (list<OutputPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
766 _out << indent(depth) << "<outport name=\"" << (*it)->getName() << "\" type=\""
767 << (*it)->edGetType()->name() << "\"/>" << endl;
771 void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node)
773 int depth = depthNode(node)+1;
774 list<OutputDataStreamPort*> listOfOutputPorts = node->getSetOfOutputDataStreamPort();
775 for (list<OutputDataStreamPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
777 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
778 if ( aPropMap.empty() )
779 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
780 << (*it)->edGetType()->name() << "\"/>" << endl;
783 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
784 << (*it)->edGetType()->name() << "\">" << endl;
785 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
786 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
787 << (*itP).second << "\"/>" << endl;
788 _out << indent(depth) << "</outstream>" << endl;
793 void VisitorSaveSchema::writeControls(ComposedNode *node)
795 int depth = depthNode(node)+1;
796 list<Node*> setOfChildren = node->edGetDirectDescendants();
797 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
799 // --- Control links from direct descendant to nodes inside the bloc
800 list<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
801 for (list<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
803 Node *to = (*ig)->getNode();
804 if (node->isInMyDescendance(to))
807 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
808 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
811 // --- Control links from nodes inside the bloc to direct descendant
812 // avoid links between direct descendants (already done above)
813 list<OutGate*> listOfOutGates = (*ic)->getInGate()->getBackLinks();
814 for (list<OutGate*>::iterator ig = listOfOutGates.begin(); ig != listOfOutGates.end(); ++ig)
816 Node *from = (*ig)->getNode();
817 if ((node->isInMyDescendance(from)) && (from->getFather()->getNumId() != node->getNumId()))
820 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
821 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
828 * Write simple data links from and to direct children of node (grand children already done).
829 * First, for all output ports of direct children, write links where the input port is inside
830 * the node scope. Keep in memory the links where the input port is outside the node scope.
831 * Second, retreive links where the output port is inside the scope, using the links kept in memory
832 * and not yet written.
834 void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
836 int depth = depthNode(node)+1;
837 list<Node*> setOfChildren = node->edGetDirectDescendants();
839 list<Node*> setOfChildrenPlusSplitters = setOfChildren;
841 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
842 // add "splitter" node of ForEachLoop nodes to the set of children
843 if ( dynamic_cast<ForEachLoop*>( *ic ) )
845 Node *nodeToInsert=(*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
846 if(find(setOfChildrenPlusSplitters.begin(),setOfChildrenPlusSplitters.end(),nodeToInsert)==setOfChildrenPlusSplitters.end())
847 setOfChildrenPlusSplitters.push_back(nodeToInsert);
850 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
852 for (list<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
855 list<OutputPort*> listOP = from->getLocalOutputPorts();
856 for (list<OutputPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
858 OutputPort* anOP = *io;
859 set<InPort*> setIP = anOP->edSetInPort();
860 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
863 Node* to = anIP->getNode();
864 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
865 << " to " << to->getName() << " inputPort " << anIP->getName() );
866 Node* child = node->isInMyDescendance(to);
867 if (child && (child->getNumId() != node->getNumId())
868 && (from->getNumId() != to->getNumId()))
870 DEBTRACE( "BINGO!" );
873 if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoop*>(from->getFather()) )
874 fromName = from->getFather()->getName();
876 fromName = node->getChildName(from);
879 if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoop*>(to->getFather()) )
880 childName = node->getChildName(to->getFather());
882 childName = node->getChildName(to);
883 _out << indent(depth) << "<datalink control=\"false\">" << endl;
884 _out << indent(depth+1) << "<fromnode>" << fromName << "</fromnode> ";
885 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
886 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
887 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
888 _out << indent(depth) << "</datalink>" << endl;
891 { // --- store info to create the link later, given the input port
892 DEBTRACE( "For later" );
893 struct DataLinkInfo aLink = { from, to, anOP, anIP, false };
894 _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
900 // --- second pass, retreive links where the output port is inside the scope.
902 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
904 std::multimap<int, DataLinkInfo>::iterator pos;
905 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end(); ++pos)
907 Node* to = (pos->second).to;
908 Node* child = node->isInMyDescendance(to);
909 if (child && (child->getNumId() != node->getNumId()))
911 InPort* anIP = (pos->second).inp;
912 int portId = anIP->getNumId();
913 Node* from = (pos->second).from;
914 child = node->isInMyDescendance(from);
915 if (child && (child->getNumId() != node->getNumId()))
916 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
918 string childName = node->getChildName(from);
919 OutPort *anOP = (pos->second).outp;
920 (pos->second).toDelete = true;
921 _out << indent(depth) << "<datalink control=\"false\">" << endl;
922 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
923 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
924 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
925 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
926 _out << indent(depth) << "</datalink>" << endl;
931 // --- remove the link written from the multimap
933 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end();)
935 if ((pos->second).toDelete)
936 _mapOfDLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
943 void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
945 int depth = depthNode(node)+1;
946 list<Node*> setOfChildren = node->edGetDirectDescendants();
948 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
950 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
953 if ( dynamic_cast<ComposedNode*>(from) ) continue;
954 list<OutputDataStreamPort*> listOP = from->getSetOfOutputDataStreamPort();
955 for (list<OutputDataStreamPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
957 OutputDataStreamPort* anOP = *io;
958 set<InPort*> setIP = anOP->edSetInPort();
959 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
962 Node* to = anIP->getNode();
963 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
964 << " to " << to->getName() << " inputPort " << anIP->getName() );
965 Node* child = node->isInMyDescendance(to);
966 if (child && (child->getNumId() != node->getNumId())
967 && (from->getNumId() != to->getNumId()))
969 DEBTRACE( "BINGO!" );
970 string childName = node->getChildName(to);
971 _out << indent(depth) << "<stream>" << endl;
972 _out << indent(depth+1) << "<fromnode>" << node->getChildName(from) << "</fromnode> ";
973 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
974 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
975 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
977 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
978 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
980 string notAlinkProperty = "DependencyType";
981 if (notAlinkProperty != (*itP).first)
982 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
983 << (*itP).second << "\"/>" << endl;
985 _out << indent(depth) << "</stream>" << endl;
988 { // --- store info to create the link later, given the input port
989 DEBTRACE("For later" );
990 struct StreamLinkInfo aLink = { from, to, anOP, anIP, false };
991 _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
997 // --- second pass, retreive links where the output port is inside the scope.
999 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
1001 std::multimap<int, StreamLinkInfo>::iterator pos;
1002 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end(); ++pos)
1004 Node* to = (pos->second).to;
1005 Node* child = node->isInMyDescendance(to);
1006 if (child && (child->getNumId() != node->getNumId()))
1008 InPort* anIP = (pos->second).inp;
1009 int portId = anIP->getNumId();
1010 Node* from = (pos->second).from;
1011 child = node->isInMyDescendance(from);
1012 if (child && (child->getNumId() != node->getNumId()))
1013 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
1015 string childName = node->getChildName(from);
1016 OutputDataStreamPort *anOP = (pos->second).outp;
1017 (pos->second).toDelete = true;
1018 _out << indent(depth) << "<stream>" << endl;
1019 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
1020 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
1021 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
1022 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
1024 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
1025 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
1026 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
1027 << (*itP).second << "\"/>" << endl;
1029 _out << indent(depth) << "</stream>" << endl;
1034 // --- remove the link written from the multimap
1036 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end();)
1038 if ((pos->second).toDelete)
1039 _mapOfSLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
1046 std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
1049 list< Node *> setOfNode = node->edGetDirectDescendants();
1050 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1052 if ( dynamic_cast<ComposedNode*> (*iter) )
1054 set<Node *> myCurrentSet = getAllNodes(dynamic_cast<ComposedNode*> (*iter));
1055 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1060 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1061 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1068 void VisitorSaveSchema::writeParameters(Proc *proc)
1070 // set<Node*> nodeSet = proc->getAllRecursiveConstituents();
1071 set<Node*> nodeSet = getAllNodes(proc);
1072 for (set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter)
1074 // ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
1076 // writeParametersNode(proc,node);
1077 writeParametersNode(proc,(*iter));
1081 void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node)
1084 list<InputPort *> setOfInputPort = node->getLocalInputPorts();
1085 list<InputPort *>::iterator iter;
1086 for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter)
1088 if (!(*iter)->isEmpty())
1090 _out << indent(depth) << "<parameter>" << endl;
1091 _out << indent(depth+1) << "<tonode>" << proc->getChildName(node) << "</tonode>";
1092 _out << "<toport>" << (*iter)->getName() << "</toport>" <<endl;
1095 _out << indent(depth+1) << (*iter)->dump();
1097 catch (YACS::Exception &e)
1099 _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << endl;
1101 _out << indent(depth) << "</parameter>" << endl;
1106 void VisitorSaveSchema::beginCase(Node* node)
1108 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1111 int depth = depthNode(node) -1;
1112 int myCase = myFather->getRankOfNode(node);
1113 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1114 _out << indent(depth) << "<default>" << endl;
1116 _out << indent(depth) << "<case id=\"" << myCase << "\">" << endl;
1120 void VisitorSaveSchema::endCase(Node* node)
1122 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1125 int depth = depthNode(node) -1;
1126 int myCase = myFather->getRankOfNode(node);
1127 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1128 _out << indent(depth) << "</default>" << endl;
1130 _out << indent(depth) << "</case>" << endl;
1134 int VisitorSaveSchema::depthNode(Node* node)
1137 ComposedNode *father = node->getFather();
1141 if (dynamic_cast<Switch*>(father)) depth +=1;
1142 if (father->getNumId() == _root->getNumId()) break;
1143 father = father->getFather();
1148 SchemaSave::SchemaSave(Proc* proc): _p(proc)
1153 void SchemaSave::save(std::string xmlSchemaFile)
1155 VisitorSaveSchema vss(_p);
1156 vss.openFileSchema(xmlSchemaFile);
1158 vss.closeFileSchema();