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 _out << " weight=\"" << node->getWeight() << "\"";
138 if (node->edGetSamplePort())
139 _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
142 writeProperties(node);
143 node->DynParaLoop::accept(this);
144 writeSimpleDataLinks(node);
145 writeSimpleStreamLinks(node);
146 _out << indent(depth) << "</foreach>" << endl;
148 DEBTRACE("END visitForEachLoop " << _root->getChildName(node));
151 void VisitorSaveSchema::visitOptimizerLoop(OptimizerLoop *node)
153 DEBTRACE("START visitOptimizerLoop " << _root->getChildName(node));
155 int depth = depthNode(node);
157 _out << indent(depth) << "<optimizer name=\"" << node->getName() << "\"";
158 AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
159 if (node->getState() == YACS::DISABLED)
160 _out << " state=\"disabled\"";
161 if (!nbranch->isEmpty())
162 _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
163 _out << " weight=\"" << node->getWeight() << "\"";
164 _out << " lib=\"" << node->getAlgLib() << "\"";
165 _out << " entry=\"" << node->getSymbol() << "\"";
168 writeProperties(node);
169 node->DynParaLoop::accept(this);
170 writeSimpleDataLinks(node);
171 writeSimpleStreamLinks(node);
172 _out << indent(depth) << "</optimizer>" << endl;
174 DEBTRACE("END visitOptimizerLoop " << _root->getChildName(node));
177 void VisitorSaveSchema::visitDynParaLoop(DynParaLoop *node)
179 DEBTRACE("START visitDynParaLoop " << _root->getChildName(node));
180 int depth = depthNode(node);
181 if (node->getInitNode() != NULL)
183 _out << indent(depth+1) << "<initnode>" << endl;
184 node->getInitNode()->accept(this);
185 _out << indent(depth+1) << "</initnode>" << endl;
187 if (node->getExecNode() != NULL)
189 node->getExecNode()->accept(this);
191 if (node->getFinalizeNode() != NULL)
193 _out << indent(depth+1) << "<finalizenode>" << endl;
194 node->getFinalizeNode()->accept(this);
195 _out << indent(depth+1) << "</finalizenode>" << endl;
197 DEBTRACE("END visitDynParaLoop " << _root->getChildName(node));
200 void VisitorSaveSchema::visitForLoop(ForLoop *node)
202 DEBTRACE("START visitForLoop " << _root->getChildName(node));
204 int depth = depthNode(node);
205 AnyInputPort *nsteps = static_cast<AnyInputPort*>(node->edGetNbOfTimesInputPort());
206 _out << indent(depth) << "<forloop name=\"" << node->getName() << "\"";
207 if (node->getState() == YACS::DISABLED)
208 _out << " state=\"disabled\"";
209 if (nsteps->isEmpty())
212 _out << " nsteps=\"" << nsteps->getIntValue() << "\">" << endl;
213 writeProperties(node);
214 node->ComposedNode::accept(this);
215 writeSimpleDataLinks(node);
216 writeSimpleStreamLinks(node);
217 _out << indent(depth) << "</forloop>" << endl;
219 DEBTRACE("END visitForLoop " << _root->getChildName(node));
222 void VisitorSaveSchema::visitInlineNode(InlineNode *node)
224 DEBTRACE("START visitInlineNode " << _root->getChildName(node));
226 int depth = depthNode(node);
227 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
228 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
230 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
231 if (node->getState() == YACS::DISABLED)
232 _out << " state=\"disabled\">" << endl;
235 _out << indent(depth+1) << "<script><code><![CDATA[";
236 _out << node->getScript();
237 _out << "]]></code></script>" << endl;
239 //add load container if node is remote
240 Container *cont = node->getContainer();
242 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
244 writeProperties(node);
245 writeInputPorts(node);
246 writeInputDataStreamPorts(node);
247 writeOutputPorts(node);
248 writeOutputDataStreamPorts(node);
250 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
251 _out << indent(depth) << "</inline>" << endl;
253 _out << indent(depth) << "</remote>" << endl;
256 DEBTRACE("END visitInlineNode " << _root->getChildName(node));
259 void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
261 DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
263 int depth = depthNode(node);
264 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
265 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
267 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
268 if (node->getState() == YACS::DISABLED)
269 _out << " state=\"disabled\">" << endl;
272 _out << indent(depth+1) << "<function name=\"" << node->getFname() << "\">" << endl;
273 _out << indent(depth+2) << "<code><![CDATA[";
274 _out << node->getScript();
275 _out << "]]></code>" << endl;
276 _out << indent(depth+1) << "</function>" << endl;
278 //add load container if node is remote
279 Container *cont = node->getContainer();
281 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
283 writeProperties(node);
284 writeInputPorts(node);
285 writeInputDataStreamPorts(node);
286 writeOutputPorts(node);
287 writeOutputDataStreamPorts(node);
289 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
290 _out << indent(depth) << "</inline>" << endl;
292 _out << indent(depth) << "</remote>" << endl;
295 DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node));
298 void VisitorSaveSchema::visitLoop(Loop *node)
300 DEBTRACE("START visitLoop " << _root->getChildName(node));
302 int depth = depthNode(node);
303 writeProperties(node);
304 node->ComposedNode::accept(this);
306 writeSimpleDataLinks(node);
307 writeSimpleStreamLinks(node);
309 DEBTRACE("END visitLoop " << _root->getChildName(node));
312 void VisitorSaveSchema::visitProc(Proc *node)
314 DEBTRACE("START visitProc " << node->getName());
315 _out << "<proc name=\""<< node->getName() << "\">" << endl;
317 writeProperties(node);
318 writeTypeCodes(node);
319 writeContainers(node);
320 writeComponentInstances(node);
321 node->ComposedNode::accept(this);
323 writeSimpleDataLinks(node);
324 writeSimpleStreamLinks(node);
325 writeParameters(node);
327 DEBTRACE("END visitProc " << node->getName());
330 void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
332 DEBTRACE("START visitServiceNode " << _root->getChildName(node));
334 int depth = depthNode(node);
335 _out << indent(depth) << "<service name=\"" << node->getName() << "\"";
336 if (node->getState() == YACS::DISABLED)
337 _out << " state=\"disabled\">" << endl;
340 if (node->getKind() == "xmlsh")
342 _out << indent(depth+1) << "<kind>xmlsh</kind>" << endl;
343 _out << indent(depth+1) << "<ref>" << node->getRef() << "</ref>" << endl;
347 ComponentInstance *compo = node->getComponent();
348 if (compo && !compo->isAnonymous())
350 _out << indent(depth+1) << "<componentinstance>" << compo->getInstanceName() << "</componentinstance>" << endl;
352 else if (compo && (_componentInstanceMap.find(compo) == _componentInstanceMap.end()))
354 _out << indent(depth+1) << compo->getFileRepr() << endl;
355 _componentInstanceMap[compo] = _root->getChildName(node);
356 Container *cont = compo->getContainer();
359 map<string, Container*>::const_iterator it;
360 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
362 if (it->second == cont) break;
364 if (it != _containerMap.end())
365 _out << indent(depth+1) << "<load container=\"" << it->first << "\"/>" << endl;
370 _out << indent(depth+1) << "<node>" << _componentInstanceMap[compo] << "</node>" << endl;
374 _out << indent(depth+1) << "<component>" << "UNKNOWN" << "</component>" << endl;
377 _out << indent(depth+1) << "<method>" << node->getMethod() << "</method>" << endl;
379 writeProperties(node);
380 writeInputPorts(node);
381 writeInputDataStreamPorts(node);
382 writeOutputPorts(node);
383 writeOutputDataStreamPorts(node);
384 _out << indent(depth) << "</service>" << endl;
386 DEBTRACE("END visitServiceNode " << _root->getChildName(node));
389 void VisitorSaveSchema::visitServerNode(ServerNode *node)
391 DEBTRACE("START visitServerNode " << _root->getChildName(node));
393 int depth = depthNode(node);
394 _out << indent(depth) << "<server name=\"" << node->getName() << "\"";
395 if (node->getState() == YACS::DISABLED)
396 _out << " state=\"disabled\">" << endl;
399 Container *cont = node->getContainer();
400 map<string, Container*>::const_iterator it;
401 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
403 if (it->second == cont) break;
405 if (it != _containerMap.end())
406 _out << indent(depth+1) << "<loadcontainer>" << it->first << "</loadcontainer>" << endl;
409 _out << indent(depth+1) << "<node>" << _contnentInstanceMap[cont] << "</node>" << endl;
411 _out << indent(depth+1) << "<method>" << node->getFname() << "</method>" << endl;
412 _out << indent(depth+2) << "<script><code><![CDATA[";
413 _out << node->getScript();
414 _out << "]]></code></script>" << endl;
415 //_out << indent(depth+1) << "</function>" << endl;
416 writeProperties(node);
417 writeInputPorts(node);
418 writeInputDataStreamPorts(node);
419 writeOutputPorts(node);
420 writeOutputDataStreamPorts(node);
421 _out << indent(depth) << "</server>" << endl;
423 DEBTRACE("END visitServerNode " << _root->getChildName(node));
426 void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
428 DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node));
430 int depth = depthNode(node);
431 _out << indent(depth) << "<serviceInline name=\"" << node->getName() << "\"";
432 if (node->getState() == YACS::DISABLED)
433 _out << " state=\"disabled\">" << endl;
437 ComponentInstance *compo = node->getComponent();
439 _out << indent(depth+1) << compo->getFileRepr() << endl;
441 _out << indent(depth+1) << "<function name=\"" << node->getMethod() << "\">" << endl;
442 _out << indent(depth+2) << "<code><![CDATA[";
443 _out << node->getScript();
444 _out << "]]></code>" << endl;
445 _out << indent(depth+1) << "</function>" << endl;
446 writeProperties(node);
447 writeInputPorts(node);
448 writeOutputPorts(node);
449 _out << indent(depth) << "</serviceInline>" << endl;
451 DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node));
454 void VisitorSaveSchema::visitPresetNode(DataNode *node)
456 DEBTRACE("START visitPresetNode " << _root->getChildName(node));
457 DEBTRACE("END visitPresetNode " << _root->getChildName(node));
460 void VisitorSaveSchema::visitOutNode(DataNode *node)
462 DEBTRACE("START visitOutNode " << _root->getChildName(node));
463 DEBTRACE("END visitOutNode " << _root->getChildName(node));
466 void VisitorSaveSchema::visitStudyInNode(DataNode *node)
468 DEBTRACE("START visitStudyInNode " << _root->getChildName(node));
469 DEBTRACE("END visitStudyInNode " << _root->getChildName(node));
472 void VisitorSaveSchema::visitStudyOutNode(DataNode *node)
474 DEBTRACE("START visitStudyOutNode " << _root->getChildName(node));
475 DEBTRACE("END visitStudyOutNode " << _root->getChildName(node));
479 void VisitorSaveSchema::visitSwitch(Switch *node)
481 DEBTRACE("START visitSwitch " << _root->getChildName(node));
483 int depth = depthNode(node);
484 AnyInputPort *condition = static_cast<AnyInputPort*>(node->edGetConditionPort());
485 _out << indent(depth) << "<switch name=\"" << node->getName() << "\"";
486 if (node->getState() == YACS::DISABLED)
487 _out << " state=\"disabled\"";
488 if (condition->isEmpty())
491 _out << " select=\"" << condition->getIntValue() << "\">" << endl;
492 writeProperties(node);
493 node->ComposedNode::accept(this);
495 writeSimpleDataLinks(node);
496 writeSimpleStreamLinks(node);
497 _out << indent(depth) << "</switch>" << endl;
499 DEBTRACE("END visitSwitch " << _root->getChildName(node));
502 void VisitorSaveSchema::visitWhileLoop(WhileLoop *node)
504 DEBTRACE("START visitWhileLoop " << _root->getChildName(node));
506 int depth = depthNode(node);
507 _out << indent(depth) << "<while name=\"" << node->getName() << "\"";
508 if (node->getState() == YACS::DISABLED)
509 _out << " state=\"disabled\">" << endl;
512 writeProperties(node);
513 node->ComposedNode::accept(this);
514 writeSimpleDataLinks(node);
515 writeSimpleStreamLinks(node);
516 _out << indent(depth) << "</while>" << endl;
518 DEBTRACE("END visitWhileLoop " << _root->getChildName(node));
522 void VisitorSaveSchema::writeProperties(Node *node)
524 int depth = depthNode(node)+1;
525 map<string,string> properties = getNodeProperties(node);
526 map<string,string>::const_iterator it;
527 for(it = properties.begin(); it != properties.end(); ++it)
529 _out << indent(depth) << "<property name=\"" << it->first
530 << "\" value=\"" << it->second << "\"/>" << endl;
534 void VisitorSaveSchema::dumpTypeCode(TypeCode* type, std::set<std::string>& typeNames,std::map<std::string, TypeCode*>& typeMap,int depth)
536 DynType kind = type->kind();
537 string typeName = type->name();
538 if (typeNames.find(typeName) != typeNames.end())
542 case YACS::ENGINE::Double:
544 typeNames.insert(typeName);
545 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"double\"/>" << endl;
548 case YACS::ENGINE::Int:
550 typeNames.insert(typeName);
551 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"int\"/>" << endl;
554 case YACS::ENGINE::String:
556 typeNames.insert(typeName);
557 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"string\"/>" << endl;
560 case YACS::ENGINE::Bool:
562 typeNames.insert(typeName);
563 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"bool\"/>" << endl;
566 case YACS::ENGINE::Objref:
568 TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(type);
569 std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
570 //try to dump base classes
571 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
573 if (typeNames.find((*il)->name()) == typeNames.end())
574 dumpTypeCode((*il),typeNames,typeMap,depth);
577 typeNames.insert(typeName);
578 _out << indent(depth) << "<objref name=\"" << typeName << "\" id=\""
579 << objref->id() << "\"";
580 if (listOfBases.empty())
581 _out << "/>" << endl;
585 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
587 _out << indent(depth+1) << "<base>";
588 _out << (*il)->name();
589 _out << "</base>" << endl;
591 _out << indent(depth) << "</objref>" << endl;
595 case YACS::ENGINE::Sequence:
597 TypeCode* content = (TypeCode*)type->contentType();
598 if (typeNames.find(content->name()) == typeNames.end())
600 //content type not dumped
601 dumpTypeCode(content,typeNames,typeMap,depth);
603 typeNames.insert(typeName);
604 _out << indent(depth) << "<sequence name=\"" << typeName << "\" content=\""
605 << content->name() << "\"/>" << endl;
608 case YACS::ENGINE::Array:
610 TypeCode* content = (TypeCode*)type->contentType();
611 if (typeNames.find(content->name()) == typeNames.end())
613 //content type not dumped
614 dumpTypeCode(content,typeNames,typeMap,depth);
616 typeNames.insert(typeName);
617 _out << indent(depth) << "<array name=\"" << typeName << "\" content=\""
618 << content->name() << "\"/>" << endl;
621 case YACS::ENGINE::Struct:
623 TypeCodeStruct* tcStruct = dynamic_cast<TypeCodeStruct*>(type);
625 int mbCnt = tcStruct->memberCount();
626 for (int i=0; i<mbCnt; i++)
628 TypeCode* member = tcStruct->memberType(i);
629 if (typeNames.find(member->name()) == typeNames.end())
631 //content type not dumped
632 dumpTypeCode(member,typeNames,typeMap,depth);
635 typeNames.insert(typeName);
636 _out << indent(depth) << "<struct name=\"" << typeName << "\">" << endl;
637 for (int i=0; i<mbCnt; i++)
639 TypeCode* member = tcStruct->memberType(i);
640 _out << indent(depth+1) << "<member name=\"" <<tcStruct->memberName(i) << "\" type=\"" << member->name() << "\"/>" << endl;
642 _out << indent(depth) << "</struct>" << endl;
647 string what = "wrong TypeCode: ";
648 throw Exception(what);
653 void VisitorSaveSchema::writeTypeCodes(Proc *proc)
655 int depth = depthNode(proc)+1;
656 map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
657 map<string, TypeCode*>::const_iterator it;
658 set<string> typeNames;
660 // --- force definition of simple types first
662 for (it = typeMap.begin(); it != typeMap.end(); it++)
664 dumpTypeCode(it->second,typeNames,typeMap,depth);
668 void VisitorSaveSchema::writeComponentInstances(Proc *proc)
670 int depth = depthNode(proc)+1;
671 std::map<std::string, ComponentInstance*>::const_iterator it;
672 for (it = proc->componentInstanceMap.begin(); it != proc->componentInstanceMap.end(); it++)
674 string name = it->first;
675 ComponentInstance* inst=it->second;
676 if(!inst->isAnonymous())
678 _out << indent(depth) << "<componentinstance name=\"" << inst->getInstanceName() << "\">" << endl;
679 _out << indent(depth+1) << "<component>" << inst->getCompoName() << "</component>" << endl;
681 Container *cont = inst->getContainer();
683 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
685 std::map<std::string, std::string> properties = inst->getProperties();
686 std::map<std::string, std::string>::const_iterator itm;
687 for(itm = properties.begin(); itm != properties.end(); ++itm)
688 _out << indent(depth+1) << "<property name=\"" << (*itm).first
689 << "\" value=\"" << (*itm).second << "\"/>" << endl;
691 _out << indent(depth) << "</componentinstance>" << endl;
696 void VisitorSaveSchema::writeContainers(Proc *proc)
698 int depth = depthNode(proc)+1;
699 _containerMap = getContainerMap(proc);
700 map<string, Container*>::const_iterator it;
701 for (it = _containerMap.begin(); it != _containerMap.end(); it++)
703 string name = it->first;
704 _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
705 _out << indent(depth+1) << "<property name=\"" << Container::KIND_ENTRY << "\" value=\"" << it->second->getKind() << "\"/>" << endl;
706 _out << indent(depth+1) << "<property name=\"" << Container::AOC_ENTRY << "\" value=\"" << (int)it->second->isAttachedOnCloning() << "\"/>" << endl;
707 map<string, string> properties = (it->second)->getProperties();
708 map<string, string>::iterator itm;
709 for(itm = properties.begin(); itm != properties.end(); ++itm)
711 if((*itm).first==Container::KIND_ENTRY)
713 if((*itm).first==Container::AOC_ENTRY)
715 if((*itm).first!=HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY)
717 _out << indent(depth+1) << "<property name=\"" << (*itm).first << "\" value=\"" << (*itm).second << "\"/>" << endl;
721 _out << indent(depth+1) << "<initializescriptkey><code><![CDATA[" << (*itm).second << "]]></code></initializescriptkey>" << endl;
724 _out << indent(depth) << "</container>" << endl;
729 void VisitorSaveSchema::writeInputPorts(Node *node)
731 int depth = depthNode(node)+1;
732 list<InputPort*> listOfInputPorts = node->getSetOfInputPort();
733 for (list<InputPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
735 _out << indent(depth) << "<inport name=\"" << (*it)->getName() << "\" type=\""
736 << (*it)->edGetType()->name() << "\"/>" << endl;
740 void VisitorSaveSchema::writeInputDataStreamPorts(Node *node)
742 int depth = depthNode(node)+1;
743 list<InputDataStreamPort*> listOfInputPorts = node->getSetOfInputDataStreamPort();
744 for (list<InputDataStreamPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
746 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
747 if ( aPropMap.empty() )
748 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
749 << (*it)->edGetType()->name() << "\"/>" << endl;
752 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
753 << (*it)->edGetType()->name() << "\">" << endl;
754 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
755 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
756 << (*itP).second << "\"/>" << endl;
757 _out << indent(depth) << "</instream>" << endl;
762 void VisitorSaveSchema::writeOutputPorts(Node *node)
764 int depth = depthNode(node)+1;
765 list<OutputPort*> listOfOutputPorts = node->getSetOfOutputPort();
766 for (list<OutputPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
768 _out << indent(depth) << "<outport name=\"" << (*it)->getName() << "\" type=\""
769 << (*it)->edGetType()->name() << "\"/>" << endl;
773 void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node)
775 int depth = depthNode(node)+1;
776 list<OutputDataStreamPort*> listOfOutputPorts = node->getSetOfOutputDataStreamPort();
777 for (list<OutputDataStreamPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
779 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
780 if ( aPropMap.empty() )
781 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
782 << (*it)->edGetType()->name() << "\"/>" << endl;
785 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
786 << (*it)->edGetType()->name() << "\">" << endl;
787 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
788 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
789 << (*itP).second << "\"/>" << endl;
790 _out << indent(depth) << "</outstream>" << endl;
795 void VisitorSaveSchema::writeControls(ComposedNode *node)
797 int depth = depthNode(node)+1;
798 list<Node*> setOfChildren = node->edGetDirectDescendants();
799 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
801 // --- Control links from direct descendant to nodes inside the bloc
802 list<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
803 for (list<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
805 Node *to = (*ig)->getNode();
806 if (node->isInMyDescendance(to))
809 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
810 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
813 // --- Control links from nodes inside the bloc to direct descendant
814 // avoid links between direct descendants (already done above)
815 list<OutGate*> listOfOutGates = (*ic)->getInGate()->getBackLinks();
816 for (list<OutGate*>::iterator ig = listOfOutGates.begin(); ig != listOfOutGates.end(); ++ig)
818 Node *from = (*ig)->getNode();
819 if ((node->isInMyDescendance(from)) && (from->getFather()->getNumId() != node->getNumId()))
822 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
823 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
830 * Write simple data links from and to direct children of node (grand children already done).
831 * First, for all output ports of direct children, write links where the input port is inside
832 * the node scope. Keep in memory the links where the input port is outside the node scope.
833 * Second, retreive links where the output port is inside the scope, using the links kept in memory
834 * and not yet written.
836 void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
838 int depth = depthNode(node)+1;
839 list<Node*> setOfChildren = node->edGetDirectDescendants();
841 list<Node*> setOfChildrenPlusSplitters = setOfChildren;
843 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
844 // add "splitter" node of ForEachLoop nodes to the set of children
845 if ( dynamic_cast<ForEachLoop*>( *ic ) )
847 Node *nodeToInsert=(*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
848 if(find(setOfChildrenPlusSplitters.begin(),setOfChildrenPlusSplitters.end(),nodeToInsert)==setOfChildrenPlusSplitters.end())
849 setOfChildrenPlusSplitters.push_back(nodeToInsert);
852 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
854 for (list<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
857 list<OutputPort*> listOP = from->getLocalOutputPorts();
858 for (list<OutputPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
860 OutputPort* anOP = *io;
861 set<InPort*> setIP = anOP->edSetInPort();
862 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
865 Node* to = anIP->getNode();
866 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
867 << " to " << to->getName() << " inputPort " << anIP->getName() );
868 Node* child = node->isInMyDescendance(to);
869 if (child && (child->getNumId() != node->getNumId())
870 && (from->getNumId() != to->getNumId()))
872 DEBTRACE( "BINGO!" );
875 if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoop*>(from->getFather()) )
876 fromName = from->getFather()->getName();
878 fromName = node->getChildName(from);
881 if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoop*>(to->getFather()) )
882 childName = node->getChildName(to->getFather());
884 childName = node->getChildName(to);
885 _out << indent(depth) << "<datalink control=\"false\">" << endl;
886 _out << indent(depth+1) << "<fromnode>" << fromName << "</fromnode> ";
887 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
888 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
889 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
890 _out << indent(depth) << "</datalink>" << endl;
893 { // --- store info to create the link later, given the input port
894 DEBTRACE( "For later" );
895 struct DataLinkInfo aLink = { from, to, anOP, anIP, false };
896 _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
902 // --- second pass, retreive links where the output port is inside the scope.
904 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
906 std::multimap<int, DataLinkInfo>::iterator pos;
907 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end(); ++pos)
909 Node* to = (pos->second).to;
910 Node* child = node->isInMyDescendance(to);
911 if (child && (child->getNumId() != node->getNumId()))
913 InPort* anIP = (pos->second).inp;
914 int portId = anIP->getNumId();
915 Node* from = (pos->second).from;
916 child = node->isInMyDescendance(from);
917 if (child && (child->getNumId() != node->getNumId()))
918 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
920 string childName = node->getChildName(from);
921 OutPort *anOP = (pos->second).outp;
922 (pos->second).toDelete = true;
923 _out << indent(depth) << "<datalink control=\"false\">" << endl;
924 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
925 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
926 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
927 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
928 _out << indent(depth) << "</datalink>" << endl;
933 // --- remove the link written from the multimap
935 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end();)
937 if ((pos->second).toDelete)
938 _mapOfDLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
945 void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
947 int depth = depthNode(node)+1;
948 list<Node*> setOfChildren = node->edGetDirectDescendants();
950 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
952 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
955 if ( dynamic_cast<ComposedNode*>(from) ) continue;
956 list<OutputDataStreamPort*> listOP = from->getSetOfOutputDataStreamPort();
957 for (list<OutputDataStreamPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
959 OutputDataStreamPort* anOP = *io;
960 set<InPort*> setIP = anOP->edSetInPort();
961 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
964 Node* to = anIP->getNode();
965 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
966 << " to " << to->getName() << " inputPort " << anIP->getName() );
967 Node* child = node->isInMyDescendance(to);
968 if (child && (child->getNumId() != node->getNumId())
969 && (from->getNumId() != to->getNumId()))
971 DEBTRACE( "BINGO!" );
972 string childName = node->getChildName(to);
973 _out << indent(depth) << "<stream>" << endl;
974 _out << indent(depth+1) << "<fromnode>" << node->getChildName(from) << "</fromnode> ";
975 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
976 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
977 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
979 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
980 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
982 string notAlinkProperty = "DependencyType";
983 if (notAlinkProperty != (*itP).first)
984 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
985 << (*itP).second << "\"/>" << endl;
987 _out << indent(depth) << "</stream>" << endl;
990 { // --- store info to create the link later, given the input port
991 DEBTRACE("For later" );
992 struct StreamLinkInfo aLink = { from, to, anOP, anIP, false };
993 _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
999 // --- second pass, retreive links where the output port is inside the scope.
1001 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
1003 std::multimap<int, StreamLinkInfo>::iterator pos;
1004 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end(); ++pos)
1006 Node* to = (pos->second).to;
1007 Node* child = node->isInMyDescendance(to);
1008 if (child && (child->getNumId() != node->getNumId()))
1010 InPort* anIP = (pos->second).inp;
1011 int portId = anIP->getNumId();
1012 Node* from = (pos->second).from;
1013 child = node->isInMyDescendance(from);
1014 if (child && (child->getNumId() != node->getNumId()))
1015 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
1017 string childName = node->getChildName(from);
1018 OutputDataStreamPort *anOP = (pos->second).outp;
1019 (pos->second).toDelete = true;
1020 _out << indent(depth) << "<stream>" << endl;
1021 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
1022 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
1023 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
1024 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
1026 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
1027 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
1028 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
1029 << (*itP).second << "\"/>" << endl;
1031 _out << indent(depth) << "</stream>" << endl;
1036 // --- remove the link written from the multimap
1038 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end();)
1040 if ((pos->second).toDelete)
1041 _mapOfSLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
1048 std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
1051 list< Node *> setOfNode = node->edGetDirectDescendants();
1052 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1054 if ( dynamic_cast<ComposedNode*> (*iter) )
1056 set<Node *> myCurrentSet = getAllNodes(dynamic_cast<ComposedNode*> (*iter));
1057 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1062 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1063 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1070 void VisitorSaveSchema::writeParameters(Proc *proc)
1072 // set<Node*> nodeSet = proc->getAllRecursiveConstituents();
1073 set<Node*> nodeSet = getAllNodes(proc);
1074 for (set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter)
1076 // ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
1078 // writeParametersNode(proc,node);
1079 writeParametersNode(proc,(*iter));
1083 void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node)
1086 list<InputPort *> setOfInputPort = node->getLocalInputPorts();
1087 list<InputPort *>::iterator iter;
1088 for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter)
1090 if (!(*iter)->isEmpty())
1092 _out << indent(depth) << "<parameter>" << endl;
1093 _out << indent(depth+1) << "<tonode>" << proc->getChildName(node) << "</tonode>";
1094 _out << "<toport>" << (*iter)->getName() << "</toport>" <<endl;
1097 _out << indent(depth+1) << (*iter)->dump();
1099 catch (YACS::Exception &e)
1101 _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << endl;
1103 _out << indent(depth) << "</parameter>" << endl;
1108 void VisitorSaveSchema::beginCase(Node* node)
1110 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1113 int depth = depthNode(node) -1;
1114 int myCase = myFather->getRankOfNode(node);
1115 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1116 _out << indent(depth) << "<default>" << endl;
1118 _out << indent(depth) << "<case id=\"" << myCase << "\">" << endl;
1122 void VisitorSaveSchema::endCase(Node* node)
1124 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1127 int depth = depthNode(node) -1;
1128 int myCase = myFather->getRankOfNode(node);
1129 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1130 _out << indent(depth) << "</default>" << endl;
1132 _out << indent(depth) << "</case>" << endl;
1136 int VisitorSaveSchema::depthNode(Node* node)
1139 ComposedNode *father = node->getFather();
1143 if (dynamic_cast<Switch*>(father)) depth +=1;
1144 if (father->getNumId() == _root->getNumId()) break;
1145 father = father->getFather();
1150 SchemaSave::SchemaSave(Proc* proc): _p(proc)
1155 void SchemaSave::save(std::string xmlSchemaFile)
1157 VisitorSaveSchema vss(_p);
1158 vss.openFileSchema(xmlSchemaFile);
1160 vss.closeFileSchema();