1 // Copyright (C) 2006-2021 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)
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 << " loopWeight=\"" << node->getWeight()->getSimpleLoopWeight() << "\"";
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::visitForEachLoopDyn(ForEachLoopDyn *node)
153 DEBTRACE("START visitForEachLoopDyn " << _root->getChildName(node));
155 int depth = depthNode(node);
157 _out << indent(depth) << "<foreachdyn name=\"" << node->getName() << "\"";
158 if (node->getState() == YACS::DISABLED)
159 _out << " state=\"disabled\"";
160 _out << " loopWeight=\"" << node->getWeight()->getSimpleLoopWeight() << "\"";
161 if (node->edGetSamplePort())
162 _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
165 writeProperties(node);
166 node->DynParaLoop::accept(this);
167 writeSimpleDataLinks(node);
168 writeSimpleStreamLinks(node);
169 _out << indent(depth) << "</foreachdyn>" << endl;
171 DEBTRACE("END visitForEachLoopDyn " << _root->getChildName(node));
174 void VisitorSaveSchema::visitOptimizerLoop(OptimizerLoop *node)
176 DEBTRACE("START visitOptimizerLoop " << _root->getChildName(node));
178 int depth = depthNode(node);
180 _out << indent(depth) << "<optimizer name=\"" << node->getName() << "\"";
181 AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
182 if (node->getState() == YACS::DISABLED)
183 _out << " state=\"disabled\"";
184 if (!nbranch->isEmpty())
185 _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
186 _out << " loopWeight=\"" << node->getWeight()->getSimpleLoopWeight() << "\"";
187 _out << " lib=\"" << node->getAlgLib() << "\"";
188 _out << " entry=\"" << node->getSymbol() << "\"";
191 writeProperties(node);
192 node->DynParaLoop::accept(this);
193 writeSimpleDataLinks(node);
194 writeSimpleStreamLinks(node);
195 _out << indent(depth) << "</optimizer>" << endl;
197 DEBTRACE("END visitOptimizerLoop " << _root->getChildName(node));
200 void VisitorSaveSchema::visitDynParaLoop(DynParaLoop *node)
202 DEBTRACE("START visitDynParaLoop " << _root->getChildName(node));
203 int depth = depthNode(node);
204 if (node->getInitNode() != NULL)
206 _out << indent(depth+1) << "<initnode>" << endl;
207 node->getInitNode()->accept(this);
208 _out << indent(depth+1) << "</initnode>" << endl;
210 if (node->getExecNode() != NULL)
212 node->getExecNode()->accept(this);
214 if (node->getFinalizeNode() != NULL)
216 _out << indent(depth+1) << "<finalizenode>" << endl;
217 node->getFinalizeNode()->accept(this);
218 _out << indent(depth+1) << "</finalizenode>" << endl;
220 DEBTRACE("END visitDynParaLoop " << _root->getChildName(node));
223 void VisitorSaveSchema::visitForLoop(ForLoop *node)
225 DEBTRACE("START visitForLoop " << _root->getChildName(node));
227 int depth = depthNode(node);
228 AnyInputPort *nsteps = static_cast<AnyInputPort*>(node->edGetNbOfTimesInputPort());
229 _out << indent(depth) << "<forloop name=\"" << node->getName() << "\"";
230 if (node->getState() == YACS::DISABLED)
231 _out << " state=\"disabled\"";
232 if (nsteps->isEmpty())
235 _out << " nsteps=\"" << nsteps->getIntValue() << "\">" << endl;
236 writeProperties(node);
237 node->ComposedNode::accept(this);
238 writeSimpleDataLinks(node);
239 writeSimpleStreamLinks(node);
240 _out << indent(depth) << "</forloop>" << endl;
242 DEBTRACE("END visitForLoop " << _root->getChildName(node));
245 void VisitorSaveSchema::visitInlineNode(InlineNode *node)
247 DEBTRACE("START visitInlineNode " << _root->getChildName(node));
249 int depth = depthNode(node);
250 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
251 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
254 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
255 _out << " elementaryWeight=\"" << node->getWeight()->getElementaryWeight() << "\"";
257 if (node->getState() == YACS::DISABLED)
258 _out << " state=\"disabled\">" << endl;
261 _out << indent(depth+1) << "<script><code><![CDATA[";
262 _out << node->getScript();
263 _out << "]]></code></script>" << endl;
265 //add load container if node is remote
266 Container *cont = node->getContainer();
268 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
270 writeProperties(node);
271 writeInputPorts(node);
272 writeInputDataStreamPorts(node);
273 writeOutputPorts(node);
274 writeOutputDataStreamPorts(node);
276 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
277 _out << indent(depth) << "</inline>" << endl;
279 _out << indent(depth) << "</remote>" << endl;
282 DEBTRACE("END visitInlineNode " << _root->getChildName(node));
285 void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
287 DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
289 int depth = depthNode(node);
290 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
291 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
294 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
295 _out << " elementaryWeight=\"" << node->getWeight()->getElementaryWeight() << "\"";
297 if (node->getState() == YACS::DISABLED)
298 _out << " state=\"disabled\">" << endl;
301 _out << indent(depth+1) << "<function name=\"" << node->getFname() << "\">" << endl;
302 _out << indent(depth+2) << "<code><![CDATA[";
303 _out << node->getScript();
304 _out << "]]></code>" << endl;
305 _out << indent(depth+1) << "</function>" << endl;
307 //add load container if node is remote
308 Container *cont = node->getContainer();
310 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
312 writeProperties(node);
313 writeInputPorts(node);
314 writeInputDataStreamPorts(node);
315 writeOutputPorts(node);
316 writeOutputDataStreamPorts(node);
318 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
319 _out << indent(depth) << "</inline>" << endl;
321 _out << indent(depth) << "</remote>" << endl;
324 DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node));
327 void VisitorSaveSchema::visitLoop(Loop *node)
329 DEBTRACE("START visitLoop " << _root->getChildName(node));
331 int depth = depthNode(node);
332 writeProperties(node);
333 node->ComposedNode::accept(this);
335 writeSimpleDataLinks(node);
336 writeSimpleStreamLinks(node);
338 DEBTRACE("END visitLoop " << _root->getChildName(node));
341 void VisitorSaveSchema::visitProc(Proc *node)
343 DEBTRACE("START visitProc " << node->getName());
344 _out << "<proc name=\""<< node->getName() << "\">" << endl;
346 writeProperties(node);
347 writeTypeCodes(node);
348 writeContainers(node);
349 writeComponentInstances(node);
350 node->ComposedNode::accept(this);
352 writeSimpleDataLinks(node);
353 writeSimpleStreamLinks(node);
354 writeParameters(node);
356 DEBTRACE("END visitProc " << node->getName());
359 void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
361 DEBTRACE("START visitServiceNode " << _root->getChildName(node));
363 int depth = depthNode(node);
364 _out << indent(depth) << "<service name=\"" << node->getName() << "\"";
365 if (node->getState() == YACS::DISABLED)
366 _out << " state=\"disabled\">" << endl;
369 if (node->getKind() == "xmlsh")
371 _out << indent(depth+1) << "<kind>xmlsh</kind>" << endl;
372 _out << indent(depth+1) << "<ref>" << node->getRef() << "</ref>" << endl;
376 ComponentInstance *compo = node->getComponent();
377 if (compo && !compo->isAnonymous())
379 _out << indent(depth+1) << "<componentinstance>" << compo->getInstanceName() << "</componentinstance>" << endl;
381 else if (compo && (_componentInstanceMap.find(compo) == _componentInstanceMap.end()))
383 _out << indent(depth+1) << compo->getFileRepr() << endl;
384 _componentInstanceMap[compo] = _root->getChildName(node);
385 Container *cont = compo->getContainer();
388 map<string, Container*>::const_iterator it;
389 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
391 if (it->second == cont) break;
393 if (it != _containerMap.end())
394 _out << indent(depth+1) << "<load container=\"" << it->first << "\"/>" << endl;
399 _out << indent(depth+1) << "<node>" << _componentInstanceMap[compo] << "</node>" << endl;
403 _out << indent(depth+1) << "<component>" << "UNKNOWN" << "</component>" << endl;
406 _out << indent(depth+1) << "<method>" << node->getMethod() << "</method>" << endl;
408 writeProperties(node);
409 writeInputPorts(node);
410 writeInputDataStreamPorts(node);
411 writeOutputPorts(node);
412 writeOutputDataStreamPorts(node);
413 _out << indent(depth) << "</service>" << endl;
415 DEBTRACE("END visitServiceNode " << _root->getChildName(node));
418 void VisitorSaveSchema::visitServerNode(ServerNode *node)
420 DEBTRACE("START visitServerNode " << _root->getChildName(node));
422 int depth = depthNode(node);
423 _out << indent(depth) << "<server name=\"" << node->getName() << "\"";
424 if (node->getState() == YACS::DISABLED)
425 _out << " state=\"disabled\">" << endl;
428 Container *cont = node->getContainer();
429 map<string, Container*>::const_iterator it;
430 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
432 if (it->second == cont) break;
434 if (it != _containerMap.end())
435 _out << indent(depth+1) << "<loadcontainer>" << it->first << "</loadcontainer>" << endl;
438 _out << indent(depth+1) << "<node>" << _contnentInstanceMap[cont] << "</node>" << endl;
440 _out << indent(depth+1) << "<method>" << node->getFname() << "</method>" << endl;
441 _out << indent(depth+2) << "<script><code><![CDATA[";
442 _out << node->getScript();
443 _out << "]]></code></script>" << endl;
444 //_out << indent(depth+1) << "</function>" << endl;
445 writeProperties(node);
446 writeInputPorts(node);
447 writeInputDataStreamPorts(node);
448 writeOutputPorts(node);
449 writeOutputDataStreamPorts(node);
450 _out << indent(depth) << "</server>" << endl;
452 DEBTRACE("END visitServerNode " << _root->getChildName(node));
455 void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
457 DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node));
459 int depth = depthNode(node);
460 _out << indent(depth) << "<serviceInline name=\"" << node->getName() << "\"";
461 if (node->getState() == YACS::DISABLED)
462 _out << " state=\"disabled\">" << endl;
466 ComponentInstance *compo = node->getComponent();
468 _out << indent(depth+1) << compo->getFileRepr() << endl;
470 _out << indent(depth+1) << "<function name=\"" << node->getMethod() << "\">" << endl;
471 _out << indent(depth+2) << "<code><![CDATA[";
472 _out << node->getScript();
473 _out << "]]></code>" << endl;
474 _out << indent(depth+1) << "</function>" << endl;
475 writeProperties(node);
476 writeInputPorts(node);
477 writeOutputPorts(node);
478 _out << indent(depth) << "</serviceInline>" << endl;
480 DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node));
483 void VisitorSaveSchema::visitPresetNode(DataNode *node)
485 DEBTRACE("START visitPresetNode " << _root->getChildName(node));
486 DEBTRACE("END visitPresetNode " << _root->getChildName(node));
489 void VisitorSaveSchema::visitOutNode(DataNode *node)
491 DEBTRACE("START visitOutNode " << _root->getChildName(node));
492 DEBTRACE("END visitOutNode " << _root->getChildName(node));
495 void VisitorSaveSchema::visitStudyInNode(DataNode *node)
497 DEBTRACE("START visitStudyInNode " << _root->getChildName(node));
498 DEBTRACE("END visitStudyInNode " << _root->getChildName(node));
501 void VisitorSaveSchema::visitStudyOutNode(DataNode *node)
503 DEBTRACE("START visitStudyOutNode " << _root->getChildName(node));
504 DEBTRACE("END visitStudyOutNode " << _root->getChildName(node));
508 void VisitorSaveSchema::visitSwitch(Switch *node)
510 DEBTRACE("START visitSwitch " << _root->getChildName(node));
512 int depth = depthNode(node);
513 AnyInputPort *condition = static_cast<AnyInputPort*>(node->edGetConditionPort());
514 _out << indent(depth) << "<switch name=\"" << node->getName() << "\"";
515 if (node->getState() == YACS::DISABLED)
516 _out << " state=\"disabled\"";
517 if (condition->isEmpty())
520 _out << " select=\"" << condition->getIntValue() << "\">" << endl;
521 writeProperties(node);
522 node->ComposedNode::accept(this);
524 writeSimpleDataLinks(node);
525 writeSimpleStreamLinks(node);
526 _out << indent(depth) << "</switch>" << endl;
528 DEBTRACE("END visitSwitch " << _root->getChildName(node));
531 void VisitorSaveSchema::visitWhileLoop(WhileLoop *node)
533 DEBTRACE("START visitWhileLoop " << _root->getChildName(node));
535 int depth = depthNode(node);
536 _out << indent(depth) << "<while name=\"" << node->getName() << "\"";
537 if (node->getState() == YACS::DISABLED)
538 _out << " state=\"disabled\">" << endl;
541 writeProperties(node);
542 node->ComposedNode::accept(this);
543 writeSimpleDataLinks(node);
544 writeSimpleStreamLinks(node);
545 _out << indent(depth) << "</while>" << endl;
547 DEBTRACE("END visitWhileLoop " << _root->getChildName(node));
551 void VisitorSaveSchema::writeProperties(Node *node)
553 int depth = depthNode(node)+1;
554 map<string,string> properties = getNodeProperties(node);
555 map<string,string>::const_iterator it;
556 for(it = properties.begin(); it != properties.end(); ++it)
558 _out << indent(depth) << "<property name=\"" << it->first
559 << "\" value=\"" << it->second << "\"/>" << endl;
563 void VisitorSaveSchema::dumpTypeCode(TypeCode* type, std::set<std::string>& typeNames,std::map<std::string, TypeCode*>& typeMap,int depth)
565 DynType kind = type->kind();
566 string typeName = type->name();
567 if (typeNames.find(typeName) != typeNames.end())
571 case YACS::ENGINE::Double:
573 typeNames.insert(typeName);
574 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"double\"/>" << endl;
577 case YACS::ENGINE::Int:
579 typeNames.insert(typeName);
580 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"int\"/>" << endl;
583 case YACS::ENGINE::String:
585 typeNames.insert(typeName);
586 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"string\"/>" << endl;
589 case YACS::ENGINE::Bool:
591 typeNames.insert(typeName);
592 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"bool\"/>" << endl;
595 case YACS::ENGINE::Objref:
597 TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(type);
598 std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
599 //try to dump base classes
600 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
602 if (typeNames.find((*il)->name()) == typeNames.end())
603 dumpTypeCode((*il),typeNames,typeMap,depth);
606 typeNames.insert(typeName);
607 _out << indent(depth) << "<objref name=\"" << typeName << "\" id=\""
608 << objref->id() << "\"";
609 if (listOfBases.empty())
610 _out << "/>" << endl;
614 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
616 _out << indent(depth+1) << "<base>";
617 _out << (*il)->name();
618 _out << "</base>" << endl;
620 _out << indent(depth) << "</objref>" << endl;
624 case YACS::ENGINE::Sequence:
626 TypeCode* content = (TypeCode*)type->contentType();
627 if (typeNames.find(content->name()) == typeNames.end())
629 //content type not dumped
630 dumpTypeCode(content,typeNames,typeMap,depth);
632 typeNames.insert(typeName);
633 _out << indent(depth) << "<sequence name=\"" << typeName << "\" content=\""
634 << content->name() << "\"/>" << endl;
637 case YACS::ENGINE::Array:
639 TypeCode* content = (TypeCode*)type->contentType();
640 if (typeNames.find(content->name()) == typeNames.end())
642 //content type not dumped
643 dumpTypeCode(content,typeNames,typeMap,depth);
645 typeNames.insert(typeName);
646 _out << indent(depth) << "<array name=\"" << typeName << "\" content=\""
647 << content->name() << "\"/>" << endl;
650 case YACS::ENGINE::Struct:
652 TypeCodeStruct* tcStruct = dynamic_cast<TypeCodeStruct*>(type);
654 int mbCnt = tcStruct->memberCount();
655 for (int i=0; i<mbCnt; i++)
657 TypeCode* member = tcStruct->memberType(i);
658 if (typeNames.find(member->name()) == typeNames.end())
660 //content type not dumped
661 dumpTypeCode(member,typeNames,typeMap,depth);
664 typeNames.insert(typeName);
665 _out << indent(depth) << "<struct name=\"" << typeName << "\">" << endl;
666 for (int i=0; i<mbCnt; i++)
668 TypeCode* member = tcStruct->memberType(i);
669 _out << indent(depth+1) << "<member name=\"" <<tcStruct->memberName(i) << "\" type=\"" << member->name() << "\"/>" << endl;
671 _out << indent(depth) << "</struct>" << endl;
676 string what = "wrong TypeCode: ";
677 throw Exception(what);
682 void VisitorSaveSchema::writeTypeCodes(Proc *proc)
684 int depth = depthNode(proc)+1;
685 map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
686 map<string, TypeCode*>::const_iterator it;
687 set<string> typeNames;
689 // --- force definition of simple types first
691 for (it = typeMap.begin(); it != typeMap.end(); it++)
693 dumpTypeCode(it->second,typeNames,typeMap,depth);
697 void VisitorSaveSchema::writeComponentInstances(Proc *proc)
699 int depth = depthNode(proc)+1;
700 std::map<std::string, ComponentInstance*>::const_iterator it;
701 for (it = proc->componentInstanceMap.begin(); it != proc->componentInstanceMap.end(); it++)
703 string name = it->first;
704 ComponentInstance* inst=it->second;
705 if(!inst->isAnonymous())
707 _out << indent(depth) << "<componentinstance name=\"" << inst->getInstanceName() << "\">" << endl;
708 _out << indent(depth+1) << "<component>" << inst->getCompoName() << "</component>" << endl;
710 Container *cont = inst->getContainer();
712 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
714 std::map<std::string, std::string> properties = inst->getProperties();
715 std::map<std::string, std::string>::const_iterator itm;
716 for(itm = properties.begin(); itm != properties.end(); ++itm)
717 _out << indent(depth+1) << "<property name=\"" << (*itm).first
718 << "\" value=\"" << (*itm).second << "\"/>" << endl;
720 _out << indent(depth) << "</componentinstance>" << endl;
725 void VisitorSaveSchema::writeContainers(Proc *proc)
727 int depth = depthNode(proc)+1;
728 _containerMap = getContainerMap(proc);
729 map<string, Container*>::const_iterator it;
730 for (it = _containerMap.begin(); it != _containerMap.end(); it++)
732 string name = it->first;
733 _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
734 _out << indent(depth+1) << "<property name=\"" << Container::KIND_ENTRY << "\" value=\"" << it->second->getKind() << "\"/>" << endl;
735 _out << indent(depth+1) << "<property name=\"" << Container::AOC_ENTRY << "\" value=\"" << (int)it->second->isAttachedOnCloning() << "\"/>" << endl;
736 map<string, string> properties = (it->second)->getProperties();
737 map<string, string>::iterator itm;
738 for(itm = properties.begin(); itm != properties.end(); ++itm)
740 if((*itm).first==Container::KIND_ENTRY)
742 if((*itm).first==Container::AOC_ENTRY)
744 if((*itm).first!=HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY)
746 _out << indent(depth+1) << "<property name=\"" << (*itm).first << "\" value=\"" << (*itm).second << "\"/>" << endl;
750 _out << indent(depth+1) << "<initializescriptkey><code><![CDATA[" << (*itm).second << "]]></code></initializescriptkey>" << endl;
753 _out << indent(depth) << "</container>" << endl;
758 void VisitorSaveSchema::writeInputPorts(Node *node)
760 int depth = depthNode(node)+1;
761 list<InputPort*> listOfInputPorts = node->getSetOfInputPort();
762 for (list<InputPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
764 _out << indent(depth) << "<inport name=\"" << (*it)->getName() << "\" type=\""
765 << (*it)->edGetType()->name() << "\"/>" << endl;
769 void VisitorSaveSchema::writeInputDataStreamPorts(Node *node)
771 int depth = depthNode(node)+1;
772 list<InputDataStreamPort*> listOfInputPorts = node->getSetOfInputDataStreamPort();
773 for (list<InputDataStreamPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
775 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
776 if ( aPropMap.empty() )
777 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
778 << (*it)->edGetType()->name() << "\"/>" << endl;
781 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
782 << (*it)->edGetType()->name() << "\">" << endl;
783 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
784 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
785 << (*itP).second << "\"/>" << endl;
786 _out << indent(depth) << "</instream>" << endl;
791 void VisitorSaveSchema::writeOutputPorts(Node *node)
793 int depth = depthNode(node)+1;
794 list<OutputPort*> listOfOutputPorts = node->getSetOfOutputPort();
795 for (list<OutputPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
797 _out << indent(depth) << "<outport name=\"" << (*it)->getName() << "\" type=\""
798 << (*it)->edGetType()->name() << "\"/>" << endl;
802 void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node)
804 int depth = depthNode(node)+1;
805 list<OutputDataStreamPort*> listOfOutputPorts = node->getSetOfOutputDataStreamPort();
806 for (list<OutputDataStreamPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
808 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
809 if ( aPropMap.empty() )
810 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
811 << (*it)->edGetType()->name() << "\"/>" << endl;
814 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
815 << (*it)->edGetType()->name() << "\">" << endl;
816 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
817 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
818 << (*itP).second << "\"/>" << endl;
819 _out << indent(depth) << "</outstream>" << endl;
824 void VisitorSaveSchema::writeControls(ComposedNode *node)
826 int depth = depthNode(node)+1;
827 list<Node*> setOfChildren = node->edGetDirectDescendants();
828 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
830 // --- Control links from direct descendant to nodes inside the bloc
831 list<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
832 for (list<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
834 Node *to = (*ig)->getNode();
835 if (node->isInMyDescendance(to))
838 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
839 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
842 // --- Control links from nodes inside the bloc to direct descendant
843 // avoid links between direct descendants (already done above)
844 list<OutGate*> listOfOutGates = (*ic)->getInGate()->getBackLinks();
845 for (list<OutGate*>::iterator ig = listOfOutGates.begin(); ig != listOfOutGates.end(); ++ig)
847 Node *from = (*ig)->getNode();
848 if ((node->isInMyDescendance(from)) && (from->getFather()->getNumId() != node->getNumId()))
851 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
852 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
859 * Write simple data links from and to direct children of node (grand children already done).
860 * First, for all output ports of direct children, write links where the input port is inside
861 * the node scope. Keep in memory the links where the input port is outside the node scope.
862 * Second, retreive links where the output port is inside the scope, using the links kept in memory
863 * and not yet written.
865 void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
867 int depth = depthNode(node)+1;
868 list<Node*> setOfChildren = node->edGetDirectDescendants();
870 list<Node*> setOfChildrenPlusSplitters = setOfChildren;
872 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
873 // add "splitter" node of ForEachLoop nodes to the set of children
874 if ( dynamic_cast<ForEachLoopGen*>( *ic ) )
876 Node *nodeToInsert=(*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
877 if(find(setOfChildrenPlusSplitters.begin(),setOfChildrenPlusSplitters.end(),nodeToInsert)==setOfChildrenPlusSplitters.end())
878 setOfChildrenPlusSplitters.push_back(nodeToInsert);
881 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
883 for (list<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
886 list<OutputPort*> listOP = from->getLocalOutputPorts();
887 for (list<OutputPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
889 OutputPort* anOP = *io;
890 set<InPort*> setIP = anOP->edSetInPort();
891 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
894 Node* to = anIP->getNode();
895 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
896 << " to " << to->getName() << " inputPort " << anIP->getName() );
897 Node* child = node->isInMyDescendance(to);
898 if (child && (child->getNumId() != node->getNumId())
899 && (from->getNumId() != to->getNumId()))
901 DEBTRACE( "BINGO!" );
904 if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoopGen*>(from->getFather()) )
905 fromName = from->getFather()->getName();
907 fromName = node->getChildName(from);
910 if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoopGen*>(to->getFather()) )
911 childName = node->getChildName(to->getFather());
913 childName = node->getChildName(to);
914 _out << indent(depth) << "<datalink control=\"false\">" << endl;
915 _out << indent(depth+1) << "<fromnode>" << fromName << "</fromnode> ";
916 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
917 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
918 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
919 _out << indent(depth) << "</datalink>" << endl;
922 { // --- store info to create the link later, given the input port
923 DEBTRACE( "For later" );
924 struct DataLinkInfo aLink = { from, to, anOP, anIP, false };
925 _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
931 // --- second pass, retreive links where the output port is inside the scope.
933 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
935 std::multimap<int, DataLinkInfo>::iterator pos;
936 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end(); ++pos)
938 Node* to = (pos->second).to;
939 Node* child = node->isInMyDescendance(to);
940 if (child && (child->getNumId() != node->getNumId()))
942 InPort* anIP = (pos->second).inp;
943 int portId = anIP->getNumId();
944 Node* from = (pos->second).from;
945 child = node->isInMyDescendance(from);
946 if (child && (child->getNumId() != node->getNumId()))
947 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
949 string childName = node->getChildName(from);
950 OutPort *anOP = (pos->second).outp;
951 (pos->second).toDelete = true;
952 _out << indent(depth) << "<datalink control=\"false\">" << endl;
953 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
954 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
955 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
956 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
957 _out << indent(depth) << "</datalink>" << endl;
962 // --- remove the link written from the multimap
964 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end();)
966 if ((pos->second).toDelete)
967 _mapOfDLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
974 void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
976 int depth = depthNode(node)+1;
977 list<Node*> setOfChildren = node->edGetDirectDescendants();
979 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
981 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
984 if ( dynamic_cast<ComposedNode*>(from) ) continue;
985 list<OutputDataStreamPort*> listOP = from->getSetOfOutputDataStreamPort();
986 for (list<OutputDataStreamPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
988 OutputDataStreamPort* anOP = *io;
989 set<InPort*> setIP = anOP->edSetInPort();
990 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
993 Node* to = anIP->getNode();
994 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
995 << " to " << to->getName() << " inputPort " << anIP->getName() );
996 Node* child = node->isInMyDescendance(to);
997 if (child && (child->getNumId() != node->getNumId())
998 && (from->getNumId() != to->getNumId()))
1000 DEBTRACE( "BINGO!" );
1001 string childName = node->getChildName(to);
1002 _out << indent(depth) << "<stream>" << endl;
1003 _out << indent(depth+1) << "<fromnode>" << node->getChildName(from) << "</fromnode> ";
1004 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
1005 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
1006 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
1008 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
1009 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
1011 string notAlinkProperty = "DependencyType";
1012 if (notAlinkProperty != (*itP).first)
1013 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
1014 << (*itP).second << "\"/>" << endl;
1016 _out << indent(depth) << "</stream>" << endl;
1019 { // --- store info to create the link later, given the input port
1020 DEBTRACE("For later" );
1021 struct StreamLinkInfo aLink = { from, to, anOP, anIP, false };
1022 _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
1028 // --- second pass, retreive links where the output port is inside the scope.
1030 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
1032 std::multimap<int, StreamLinkInfo>::iterator pos;
1033 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end(); ++pos)
1035 Node* to = (pos->second).to;
1036 Node* child = node->isInMyDescendance(to);
1037 if (child && (child->getNumId() != node->getNumId()))
1039 InPort* anIP = (pos->second).inp;
1040 int portId = anIP->getNumId();
1041 Node* from = (pos->second).from;
1042 child = node->isInMyDescendance(from);
1043 if (child && (child->getNumId() != node->getNumId()))
1044 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
1046 string childName = node->getChildName(from);
1047 OutputDataStreamPort *anOP = (pos->second).outp;
1048 (pos->second).toDelete = true;
1049 _out << indent(depth) << "<stream>" << endl;
1050 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
1051 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
1052 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
1053 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
1055 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
1056 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
1057 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
1058 << (*itP).second << "\"/>" << endl;
1060 _out << indent(depth) << "</stream>" << endl;
1065 // --- remove the link written from the multimap
1067 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end();)
1069 if ((pos->second).toDelete)
1070 _mapOfSLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
1077 std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
1080 list< Node *> setOfNode = node->edGetDirectDescendants();
1081 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1083 if ( dynamic_cast<ComposedNode*> (*iter) )
1085 set<Node *> myCurrentSet = getAllNodes(dynamic_cast<ComposedNode*> (*iter));
1086 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1091 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1092 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1099 void VisitorSaveSchema::writeParameters(Proc *proc)
1101 // set<Node*> nodeSet = proc->getAllRecursiveConstituents();
1102 set<Node*> nodeSet = getAllNodes(proc);
1103 for (set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter)
1105 // ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
1107 // writeParametersNode(proc,node);
1108 writeParametersNode(proc,(*iter));
1112 void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node)
1115 list<InputPort *> setOfInputPort = node->getLocalInputPorts();
1116 list<InputPort *>::iterator iter;
1117 for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter)
1119 if (!(*iter)->isEmpty())
1121 _out << indent(depth) << "<parameter>" << endl;
1122 _out << indent(depth+1) << "<tonode>" << proc->getChildName(node) << "</tonode>";
1123 _out << "<toport>" << (*iter)->getName() << "</toport>" <<endl;
1126 _out << indent(depth+1) << (*iter)->dump();
1128 catch (YACS::Exception &e)
1130 _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << endl;
1132 _out << indent(depth) << "</parameter>" << endl;
1137 void VisitorSaveSchema::beginCase(Node* node)
1139 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1142 int depth = depthNode(node) -1;
1143 int myCase = myFather->getRankOfNode(node);
1144 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1145 _out << indent(depth) << "<default>" << endl;
1147 _out << indent(depth) << "<case id=\"" << myCase << "\">" << endl;
1151 void VisitorSaveSchema::endCase(Node* node)
1153 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1156 int depth = depthNode(node) -1;
1157 int myCase = myFather->getRankOfNode(node);
1158 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1159 _out << indent(depth) << "</default>" << endl;
1161 _out << indent(depth) << "</case>" << endl;
1165 int VisitorSaveSchema::depthNode(Node* node)
1168 ComposedNode *father = node->getFather();
1172 if (dynamic_cast<Switch*>(father)) depth +=1;
1173 if (father->getNumId() == _root->getNumId()) break;
1174 father = father->getFather();
1179 SchemaSave::SchemaSave(Proc* proc): _p(proc)
1184 void SchemaSave::save(std::string xmlSchemaFile)
1186 VisitorSaveSchema vss(_p);
1187 vss.openFileSchema(xmlSchemaFile);
1189 vss.closeFileSchema();