1 // Copyright (C) 2006-2019 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 << " 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::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 << " loopWeight=\"" << node->getWeight()->getSimpleLoopWeight() << "\"";
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() << "\"";
231 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
232 _out << " elementaryWeight=\"" << node->getWeight()->getElementaryWeight() << "\"";
234 if (node->getState() == YACS::DISABLED)
235 _out << " state=\"disabled\">" << endl;
238 _out << indent(depth+1) << "<script><code><![CDATA[";
239 _out << node->getScript();
240 _out << "]]></code></script>" << endl;
242 //add load container if node is remote
243 Container *cont = node->getContainer();
245 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
247 writeProperties(node);
248 writeInputPorts(node);
249 writeInputDataStreamPorts(node);
250 writeOutputPorts(node);
251 writeOutputDataStreamPorts(node);
253 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
254 _out << indent(depth) << "</inline>" << endl;
256 _out << indent(depth) << "</remote>" << endl;
259 DEBTRACE("END visitInlineNode " << _root->getChildName(node));
262 void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
264 DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
266 int depth = depthNode(node);
267 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
268 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
271 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
272 _out << " elementaryWeight=\"" << node->getWeight()->getElementaryWeight() << "\"";
274 if (node->getState() == YACS::DISABLED)
275 _out << " state=\"disabled\">" << endl;
278 _out << indent(depth+1) << "<function name=\"" << node->getFname() << "\">" << endl;
279 _out << indent(depth+2) << "<code><![CDATA[";
280 _out << node->getScript();
281 _out << "]]></code>" << endl;
282 _out << indent(depth+1) << "</function>" << endl;
284 //add load container if node is remote
285 Container *cont = node->getContainer();
287 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
289 writeProperties(node);
290 writeInputPorts(node);
291 writeInputDataStreamPorts(node);
292 writeOutputPorts(node);
293 writeOutputDataStreamPorts(node);
295 if(node->getExecutionMode()==InlineNode::LOCAL_STR)
296 _out << indent(depth) << "</inline>" << endl;
298 _out << indent(depth) << "</remote>" << endl;
301 DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node));
304 void VisitorSaveSchema::visitLoop(Loop *node)
306 DEBTRACE("START visitLoop " << _root->getChildName(node));
308 int depth = depthNode(node);
309 writeProperties(node);
310 node->ComposedNode::accept(this);
312 writeSimpleDataLinks(node);
313 writeSimpleStreamLinks(node);
315 DEBTRACE("END visitLoop " << _root->getChildName(node));
318 void VisitorSaveSchema::visitProc(Proc *node)
320 DEBTRACE("START visitProc " << node->getName());
321 _out << "<proc name=\""<< node->getName() << "\">" << endl;
323 writeProperties(node);
324 writeTypeCodes(node);
325 writeContainers(node);
326 writeComponentInstances(node);
327 node->ComposedNode::accept(this);
329 writeSimpleDataLinks(node);
330 writeSimpleStreamLinks(node);
331 writeParameters(node);
333 DEBTRACE("END visitProc " << node->getName());
336 void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
338 DEBTRACE("START visitServiceNode " << _root->getChildName(node));
340 int depth = depthNode(node);
341 _out << indent(depth) << "<service name=\"" << node->getName() << "\"";
342 if (node->getState() == YACS::DISABLED)
343 _out << " state=\"disabled\">" << endl;
346 if (node->getKind() == "xmlsh")
348 _out << indent(depth+1) << "<kind>xmlsh</kind>" << endl;
349 _out << indent(depth+1) << "<ref>" << node->getRef() << "</ref>" << endl;
353 ComponentInstance *compo = node->getComponent();
354 if (compo && !compo->isAnonymous())
356 _out << indent(depth+1) << "<componentinstance>" << compo->getInstanceName() << "</componentinstance>" << endl;
358 else if (compo && (_componentInstanceMap.find(compo) == _componentInstanceMap.end()))
360 _out << indent(depth+1) << compo->getFileRepr() << endl;
361 _componentInstanceMap[compo] = _root->getChildName(node);
362 Container *cont = compo->getContainer();
365 map<string, Container*>::const_iterator it;
366 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
368 if (it->second == cont) break;
370 if (it != _containerMap.end())
371 _out << indent(depth+1) << "<load container=\"" << it->first << "\"/>" << endl;
376 _out << indent(depth+1) << "<node>" << _componentInstanceMap[compo] << "</node>" << endl;
380 _out << indent(depth+1) << "<component>" << "UNKNOWN" << "</component>" << endl;
383 _out << indent(depth+1) << "<method>" << node->getMethod() << "</method>" << endl;
385 writeProperties(node);
386 writeInputPorts(node);
387 writeInputDataStreamPorts(node);
388 writeOutputPorts(node);
389 writeOutputDataStreamPorts(node);
390 _out << indent(depth) << "</service>" << endl;
392 DEBTRACE("END visitServiceNode " << _root->getChildName(node));
395 void VisitorSaveSchema::visitServerNode(ServerNode *node)
397 DEBTRACE("START visitServerNode " << _root->getChildName(node));
399 int depth = depthNode(node);
400 _out << indent(depth) << "<server name=\"" << node->getName() << "\"";
401 if (node->getState() == YACS::DISABLED)
402 _out << " state=\"disabled\">" << endl;
405 Container *cont = node->getContainer();
406 map<string, Container*>::const_iterator it;
407 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
409 if (it->second == cont) break;
411 if (it != _containerMap.end())
412 _out << indent(depth+1) << "<loadcontainer>" << it->first << "</loadcontainer>" << endl;
415 _out << indent(depth+1) << "<node>" << _contnentInstanceMap[cont] << "</node>" << endl;
417 _out << indent(depth+1) << "<method>" << node->getFname() << "</method>" << endl;
418 _out << indent(depth+2) << "<script><code><![CDATA[";
419 _out << node->getScript();
420 _out << "]]></code></script>" << endl;
421 //_out << indent(depth+1) << "</function>" << endl;
422 writeProperties(node);
423 writeInputPorts(node);
424 writeInputDataStreamPorts(node);
425 writeOutputPorts(node);
426 writeOutputDataStreamPorts(node);
427 _out << indent(depth) << "</server>" << endl;
429 DEBTRACE("END visitServerNode " << _root->getChildName(node));
432 void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
434 DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node));
436 int depth = depthNode(node);
437 _out << indent(depth) << "<serviceInline name=\"" << node->getName() << "\"";
438 if (node->getState() == YACS::DISABLED)
439 _out << " state=\"disabled\">" << endl;
443 ComponentInstance *compo = node->getComponent();
445 _out << indent(depth+1) << compo->getFileRepr() << endl;
447 _out << indent(depth+1) << "<function name=\"" << node->getMethod() << "\">" << endl;
448 _out << indent(depth+2) << "<code><![CDATA[";
449 _out << node->getScript();
450 _out << "]]></code>" << endl;
451 _out << indent(depth+1) << "</function>" << endl;
452 writeProperties(node);
453 writeInputPorts(node);
454 writeOutputPorts(node);
455 _out << indent(depth) << "</serviceInline>" << endl;
457 DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node));
460 void VisitorSaveSchema::visitPresetNode(DataNode *node)
462 DEBTRACE("START visitPresetNode " << _root->getChildName(node));
463 DEBTRACE("END visitPresetNode " << _root->getChildName(node));
466 void VisitorSaveSchema::visitOutNode(DataNode *node)
468 DEBTRACE("START visitOutNode " << _root->getChildName(node));
469 DEBTRACE("END visitOutNode " << _root->getChildName(node));
472 void VisitorSaveSchema::visitStudyInNode(DataNode *node)
474 DEBTRACE("START visitStudyInNode " << _root->getChildName(node));
475 DEBTRACE("END visitStudyInNode " << _root->getChildName(node));
478 void VisitorSaveSchema::visitStudyOutNode(DataNode *node)
480 DEBTRACE("START visitStudyOutNode " << _root->getChildName(node));
481 DEBTRACE("END visitStudyOutNode " << _root->getChildName(node));
485 void VisitorSaveSchema::visitSwitch(Switch *node)
487 DEBTRACE("START visitSwitch " << _root->getChildName(node));
489 int depth = depthNode(node);
490 AnyInputPort *condition = static_cast<AnyInputPort*>(node->edGetConditionPort());
491 _out << indent(depth) << "<switch name=\"" << node->getName() << "\"";
492 if (node->getState() == YACS::DISABLED)
493 _out << " state=\"disabled\"";
494 if (condition->isEmpty())
497 _out << " select=\"" << condition->getIntValue() << "\">" << endl;
498 writeProperties(node);
499 node->ComposedNode::accept(this);
501 writeSimpleDataLinks(node);
502 writeSimpleStreamLinks(node);
503 _out << indent(depth) << "</switch>" << endl;
505 DEBTRACE("END visitSwitch " << _root->getChildName(node));
508 void VisitorSaveSchema::visitWhileLoop(WhileLoop *node)
510 DEBTRACE("START visitWhileLoop " << _root->getChildName(node));
512 int depth = depthNode(node);
513 _out << indent(depth) << "<while name=\"" << node->getName() << "\"";
514 if (node->getState() == YACS::DISABLED)
515 _out << " state=\"disabled\">" << endl;
518 writeProperties(node);
519 node->ComposedNode::accept(this);
520 writeSimpleDataLinks(node);
521 writeSimpleStreamLinks(node);
522 _out << indent(depth) << "</while>" << endl;
524 DEBTRACE("END visitWhileLoop " << _root->getChildName(node));
528 void VisitorSaveSchema::writeProperties(Node *node)
530 int depth = depthNode(node)+1;
531 map<string,string> properties = getNodeProperties(node);
532 map<string,string>::const_iterator it;
533 for(it = properties.begin(); it != properties.end(); ++it)
535 _out << indent(depth) << "<property name=\"" << it->first
536 << "\" value=\"" << it->second << "\"/>" << endl;
540 void VisitorSaveSchema::dumpTypeCode(TypeCode* type, std::set<std::string>& typeNames,std::map<std::string, TypeCode*>& typeMap,int depth)
542 DynType kind = type->kind();
543 string typeName = type->name();
544 if (typeNames.find(typeName) != typeNames.end())
548 case YACS::ENGINE::Double:
550 typeNames.insert(typeName);
551 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"double\"/>" << endl;
554 case YACS::ENGINE::Int:
556 typeNames.insert(typeName);
557 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"int\"/>" << endl;
560 case YACS::ENGINE::String:
562 typeNames.insert(typeName);
563 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"string\"/>" << endl;
566 case YACS::ENGINE::Bool:
568 typeNames.insert(typeName);
569 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"bool\"/>" << endl;
572 case YACS::ENGINE::Objref:
574 TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(type);
575 std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
576 //try to dump base classes
577 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
579 if (typeNames.find((*il)->name()) == typeNames.end())
580 dumpTypeCode((*il),typeNames,typeMap,depth);
583 typeNames.insert(typeName);
584 _out << indent(depth) << "<objref name=\"" << typeName << "\" id=\""
585 << objref->id() << "\"";
586 if (listOfBases.empty())
587 _out << "/>" << endl;
591 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
593 _out << indent(depth+1) << "<base>";
594 _out << (*il)->name();
595 _out << "</base>" << endl;
597 _out << indent(depth) << "</objref>" << endl;
601 case YACS::ENGINE::Sequence:
603 TypeCode* content = (TypeCode*)type->contentType();
604 if (typeNames.find(content->name()) == typeNames.end())
606 //content type not dumped
607 dumpTypeCode(content,typeNames,typeMap,depth);
609 typeNames.insert(typeName);
610 _out << indent(depth) << "<sequence name=\"" << typeName << "\" content=\""
611 << content->name() << "\"/>" << endl;
614 case YACS::ENGINE::Array:
616 TypeCode* content = (TypeCode*)type->contentType();
617 if (typeNames.find(content->name()) == typeNames.end())
619 //content type not dumped
620 dumpTypeCode(content,typeNames,typeMap,depth);
622 typeNames.insert(typeName);
623 _out << indent(depth) << "<array name=\"" << typeName << "\" content=\""
624 << content->name() << "\"/>" << endl;
627 case YACS::ENGINE::Struct:
629 TypeCodeStruct* tcStruct = dynamic_cast<TypeCodeStruct*>(type);
631 int mbCnt = tcStruct->memberCount();
632 for (int i=0; i<mbCnt; i++)
634 TypeCode* member = tcStruct->memberType(i);
635 if (typeNames.find(member->name()) == typeNames.end())
637 //content type not dumped
638 dumpTypeCode(member,typeNames,typeMap,depth);
641 typeNames.insert(typeName);
642 _out << indent(depth) << "<struct name=\"" << typeName << "\">" << endl;
643 for (int i=0; i<mbCnt; i++)
645 TypeCode* member = tcStruct->memberType(i);
646 _out << indent(depth+1) << "<member name=\"" <<tcStruct->memberName(i) << "\" type=\"" << member->name() << "\"/>" << endl;
648 _out << indent(depth) << "</struct>" << endl;
653 string what = "wrong TypeCode: ";
654 throw Exception(what);
659 void VisitorSaveSchema::writeTypeCodes(Proc *proc)
661 int depth = depthNode(proc)+1;
662 map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
663 map<string, TypeCode*>::const_iterator it;
664 set<string> typeNames;
666 // --- force definition of simple types first
668 for (it = typeMap.begin(); it != typeMap.end(); it++)
670 dumpTypeCode(it->second,typeNames,typeMap,depth);
674 void VisitorSaveSchema::writeComponentInstances(Proc *proc)
676 int depth = depthNode(proc)+1;
677 std::map<std::string, ComponentInstance*>::const_iterator it;
678 for (it = proc->componentInstanceMap.begin(); it != proc->componentInstanceMap.end(); it++)
680 string name = it->first;
681 ComponentInstance* inst=it->second;
682 if(!inst->isAnonymous())
684 _out << indent(depth) << "<componentinstance name=\"" << inst->getInstanceName() << "\">" << endl;
685 _out << indent(depth+1) << "<component>" << inst->getCompoName() << "</component>" << endl;
687 Container *cont = inst->getContainer();
689 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
691 std::map<std::string, std::string> properties = inst->getProperties();
692 std::map<std::string, std::string>::const_iterator itm;
693 for(itm = properties.begin(); itm != properties.end(); ++itm)
694 _out << indent(depth+1) << "<property name=\"" << (*itm).first
695 << "\" value=\"" << (*itm).second << "\"/>" << endl;
697 _out << indent(depth) << "</componentinstance>" << endl;
702 void VisitorSaveSchema::writeContainers(Proc *proc)
704 int depth = depthNode(proc)+1;
705 _containerMap = getContainerMap(proc);
706 map<string, Container*>::const_iterator it;
707 for (it = _containerMap.begin(); it != _containerMap.end(); it++)
709 string name = it->first;
710 _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
711 _out << indent(depth+1) << "<property name=\"" << Container::KIND_ENTRY << "\" value=\"" << it->second->getKind() << "\"/>" << endl;
712 _out << indent(depth+1) << "<property name=\"" << Container::AOC_ENTRY << "\" value=\"" << (int)it->second->isAttachedOnCloning() << "\"/>" << endl;
713 map<string, string> properties = (it->second)->getProperties();
714 map<string, string>::iterator itm;
715 for(itm = properties.begin(); itm != properties.end(); ++itm)
717 if((*itm).first==Container::KIND_ENTRY)
719 if((*itm).first==Container::AOC_ENTRY)
721 if((*itm).first!=HomogeneousPoolContainer::INITIALIZE_SCRIPT_KEY)
723 _out << indent(depth+1) << "<property name=\"" << (*itm).first << "\" value=\"" << (*itm).second << "\"/>" << endl;
727 _out << indent(depth+1) << "<initializescriptkey><code><![CDATA[" << (*itm).second << "]]></code></initializescriptkey>" << endl;
730 _out << indent(depth) << "</container>" << endl;
735 void VisitorSaveSchema::writeInputPorts(Node *node)
737 int depth = depthNode(node)+1;
738 list<InputPort*> listOfInputPorts = node->getSetOfInputPort();
739 for (list<InputPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
741 _out << indent(depth) << "<inport name=\"" << (*it)->getName() << "\" type=\""
742 << (*it)->edGetType()->name() << "\"/>" << endl;
746 void VisitorSaveSchema::writeInputDataStreamPorts(Node *node)
748 int depth = depthNode(node)+1;
749 list<InputDataStreamPort*> listOfInputPorts = node->getSetOfInputDataStreamPort();
750 for (list<InputDataStreamPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
752 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
753 if ( aPropMap.empty() )
754 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
755 << (*it)->edGetType()->name() << "\"/>" << endl;
758 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
759 << (*it)->edGetType()->name() << "\">" << endl;
760 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
761 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
762 << (*itP).second << "\"/>" << endl;
763 _out << indent(depth) << "</instream>" << endl;
768 void VisitorSaveSchema::writeOutputPorts(Node *node)
770 int depth = depthNode(node)+1;
771 list<OutputPort*> listOfOutputPorts = node->getSetOfOutputPort();
772 for (list<OutputPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
774 _out << indent(depth) << "<outport name=\"" << (*it)->getName() << "\" type=\""
775 << (*it)->edGetType()->name() << "\"/>" << endl;
779 void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node)
781 int depth = depthNode(node)+1;
782 list<OutputDataStreamPort*> listOfOutputPorts = node->getSetOfOutputDataStreamPort();
783 for (list<OutputDataStreamPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
785 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
786 if ( aPropMap.empty() )
787 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
788 << (*it)->edGetType()->name() << "\"/>" << endl;
791 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
792 << (*it)->edGetType()->name() << "\">" << endl;
793 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
794 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
795 << (*itP).second << "\"/>" << endl;
796 _out << indent(depth) << "</outstream>" << endl;
801 void VisitorSaveSchema::writeControls(ComposedNode *node)
803 int depth = depthNode(node)+1;
804 list<Node*> setOfChildren = node->edGetDirectDescendants();
805 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
807 // --- Control links from direct descendant to nodes inside the bloc
808 list<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
809 for (list<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
811 Node *to = (*ig)->getNode();
812 if (node->isInMyDescendance(to))
815 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
816 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
819 // --- Control links from nodes inside the bloc to direct descendant
820 // avoid links between direct descendants (already done above)
821 list<OutGate*> listOfOutGates = (*ic)->getInGate()->getBackLinks();
822 for (list<OutGate*>::iterator ig = listOfOutGates.begin(); ig != listOfOutGates.end(); ++ig)
824 Node *from = (*ig)->getNode();
825 if ((node->isInMyDescendance(from)) && (from->getFather()->getNumId() != node->getNumId()))
828 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
829 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
836 * Write simple data links from and to direct children of node (grand children already done).
837 * First, for all output ports of direct children, write links where the input port is inside
838 * the node scope. Keep in memory the links where the input port is outside the node scope.
839 * Second, retreive links where the output port is inside the scope, using the links kept in memory
840 * and not yet written.
842 void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
844 int depth = depthNode(node)+1;
845 list<Node*> setOfChildren = node->edGetDirectDescendants();
847 list<Node*> setOfChildrenPlusSplitters = setOfChildren;
849 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
850 // add "splitter" node of ForEachLoop nodes to the set of children
851 if ( dynamic_cast<ForEachLoop*>( *ic ) )
853 Node *nodeToInsert=(*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
854 if(find(setOfChildrenPlusSplitters.begin(),setOfChildrenPlusSplitters.end(),nodeToInsert)==setOfChildrenPlusSplitters.end())
855 setOfChildrenPlusSplitters.push_back(nodeToInsert);
858 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
860 for (list<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
863 list<OutputPort*> listOP = from->getLocalOutputPorts();
864 for (list<OutputPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
866 OutputPort* anOP = *io;
867 set<InPort*> setIP = anOP->edSetInPort();
868 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
871 Node* to = anIP->getNode();
872 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
873 << " to " << to->getName() << " inputPort " << anIP->getName() );
874 Node* child = node->isInMyDescendance(to);
875 if (child && (child->getNumId() != node->getNumId())
876 && (from->getNumId() != to->getNumId()))
878 DEBTRACE( "BINGO!" );
881 if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoop*>(from->getFather()) )
882 fromName = from->getFather()->getName();
884 fromName = node->getChildName(from);
887 if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoop*>(to->getFather()) )
888 childName = node->getChildName(to->getFather());
890 childName = node->getChildName(to);
891 _out << indent(depth) << "<datalink control=\"false\">" << endl;
892 _out << indent(depth+1) << "<fromnode>" << fromName << "</fromnode> ";
893 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
894 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
895 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
896 _out << indent(depth) << "</datalink>" << endl;
899 { // --- store info to create the link later, given the input port
900 DEBTRACE( "For later" );
901 struct DataLinkInfo aLink = { from, to, anOP, anIP, false };
902 _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
908 // --- second pass, retreive links where the output port is inside the scope.
910 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
912 std::multimap<int, DataLinkInfo>::iterator pos;
913 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end(); ++pos)
915 Node* to = (pos->second).to;
916 Node* child = node->isInMyDescendance(to);
917 if (child && (child->getNumId() != node->getNumId()))
919 InPort* anIP = (pos->second).inp;
920 int portId = anIP->getNumId();
921 Node* from = (pos->second).from;
922 child = node->isInMyDescendance(from);
923 if (child && (child->getNumId() != node->getNumId()))
924 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
926 string childName = node->getChildName(from);
927 OutPort *anOP = (pos->second).outp;
928 (pos->second).toDelete = true;
929 _out << indent(depth) << "<datalink control=\"false\">" << endl;
930 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
931 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
932 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
933 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
934 _out << indent(depth) << "</datalink>" << endl;
939 // --- remove the link written from the multimap
941 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end();)
943 if ((pos->second).toDelete)
944 _mapOfDLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
951 void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
953 int depth = depthNode(node)+1;
954 list<Node*> setOfChildren = node->edGetDirectDescendants();
956 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
958 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
961 if ( dynamic_cast<ComposedNode*>(from) ) continue;
962 list<OutputDataStreamPort*> listOP = from->getSetOfOutputDataStreamPort();
963 for (list<OutputDataStreamPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
965 OutputDataStreamPort* anOP = *io;
966 set<InPort*> setIP = anOP->edSetInPort();
967 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
970 Node* to = anIP->getNode();
971 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
972 << " to " << to->getName() << " inputPort " << anIP->getName() );
973 Node* child = node->isInMyDescendance(to);
974 if (child && (child->getNumId() != node->getNumId())
975 && (from->getNumId() != to->getNumId()))
977 DEBTRACE( "BINGO!" );
978 string childName = node->getChildName(to);
979 _out << indent(depth) << "<stream>" << endl;
980 _out << indent(depth+1) << "<fromnode>" << node->getChildName(from) << "</fromnode> ";
981 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
982 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
983 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
985 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
986 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
988 string notAlinkProperty = "DependencyType";
989 if (notAlinkProperty != (*itP).first)
990 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
991 << (*itP).second << "\"/>" << endl;
993 _out << indent(depth) << "</stream>" << endl;
996 { // --- store info to create the link later, given the input port
997 DEBTRACE("For later" );
998 struct StreamLinkInfo aLink = { from, to, anOP, anIP, false };
999 _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
1005 // --- second pass, retreive links where the output port is inside the scope.
1007 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
1009 std::multimap<int, StreamLinkInfo>::iterator pos;
1010 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end(); ++pos)
1012 Node* to = (pos->second).to;
1013 Node* child = node->isInMyDescendance(to);
1014 if (child && (child->getNumId() != node->getNumId()))
1016 InPort* anIP = (pos->second).inp;
1017 int portId = anIP->getNumId();
1018 Node* from = (pos->second).from;
1019 child = node->isInMyDescendance(from);
1020 if (child && (child->getNumId() != node->getNumId()))
1021 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
1023 string childName = node->getChildName(from);
1024 OutputDataStreamPort *anOP = (pos->second).outp;
1025 (pos->second).toDelete = true;
1026 _out << indent(depth) << "<stream>" << endl;
1027 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
1028 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
1029 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
1030 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
1032 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
1033 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
1034 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
1035 << (*itP).second << "\"/>" << endl;
1037 _out << indent(depth) << "</stream>" << endl;
1042 // --- remove the link written from the multimap
1044 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end();)
1046 if ((pos->second).toDelete)
1047 _mapOfSLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
1054 std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
1057 list< Node *> setOfNode = node->edGetDirectDescendants();
1058 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1060 if ( dynamic_cast<ComposedNode*> (*iter) )
1062 set<Node *> myCurrentSet = getAllNodes(dynamic_cast<ComposedNode*> (*iter));
1063 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1068 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1069 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1076 void VisitorSaveSchema::writeParameters(Proc *proc)
1078 // set<Node*> nodeSet = proc->getAllRecursiveConstituents();
1079 set<Node*> nodeSet = getAllNodes(proc);
1080 for (set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter)
1082 // ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
1084 // writeParametersNode(proc,node);
1085 writeParametersNode(proc,(*iter));
1089 void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node)
1092 list<InputPort *> setOfInputPort = node->getLocalInputPorts();
1093 list<InputPort *>::iterator iter;
1094 for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter)
1096 if (!(*iter)->isEmpty())
1098 _out << indent(depth) << "<parameter>" << endl;
1099 _out << indent(depth+1) << "<tonode>" << proc->getChildName(node) << "</tonode>";
1100 _out << "<toport>" << (*iter)->getName() << "</toport>" <<endl;
1103 _out << indent(depth+1) << (*iter)->dump();
1105 catch (YACS::Exception &e)
1107 _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << endl;
1109 _out << indent(depth) << "</parameter>" << endl;
1114 void VisitorSaveSchema::beginCase(Node* node)
1116 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1119 int depth = depthNode(node) -1;
1120 int myCase = myFather->getRankOfNode(node);
1121 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1122 _out << indent(depth) << "<default>" << endl;
1124 _out << indent(depth) << "<case id=\"" << myCase << "\">" << endl;
1128 void VisitorSaveSchema::endCase(Node* node)
1130 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1133 int depth = depthNode(node) -1;
1134 int myCase = myFather->getRankOfNode(node);
1135 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1136 _out << indent(depth) << "</default>" << endl;
1138 _out << indent(depth) << "</case>" << endl;
1142 int VisitorSaveSchema::depthNode(Node* node)
1145 ComposedNode *father = node->getFather();
1149 if (dynamic_cast<Switch*>(father)) depth +=1;
1150 if (father->getNumId() == _root->getNumId()) break;
1151 father = father->getFather();
1156 SchemaSave::SchemaSave(Proc* proc): _p(proc)
1161 void SchemaSave::save(std::string xmlSchemaFile)
1163 VisitorSaveSchema vss(_p);
1164 vss.openFileSchema(xmlSchemaFile);
1166 vss.closeFileSchema();