1 // Copyright (C) 2006-2014 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 "ComponentInstance.hxx"
38 #include "InputDataStreamPort.hxx"
39 #include "OutputDataStreamPort.hxx"
40 #include "Container.hxx"
41 #include "DataNode.hxx"
48 using namespace YACS::ENGINE;
52 #include "YacsTrace.hxx"
54 /*! \class YACS::ENGINE::VisitorSaveSchema
55 * \brief Base class for all visitors that save a schema.
57 * Can be specialized in runtime.
60 VisitorSaveSchema::VisitorSaveSchema(ComposedNode *root): _root(root), Visitor(root)
64 VisitorSaveSchema::~VisitorSaveSchema()
68 _out << "</proc>" << endl;
73 void VisitorSaveSchema::openFileSchema(std::string xmlSchema) throw(YACS::Exception)
75 _out.open(xmlSchema.c_str(), ios::out);
78 string what = "Impossible to open file for writing: " + xmlSchema;
79 throw Exception(what);
81 _out << "<?xml version='1.0' encoding='iso-8859-1' ?>" << endl;
84 void VisitorSaveSchema::closeFileSchema()
86 if (!_out) throw Exception("No file open for save schema");
87 _out << "</proc>" << endl;
91 void VisitorSaveSchema::visitBloc(Bloc *node)
93 DEBTRACE("START visitBloc " << _root->getChildName(node));
95 int depth = depthNode(node);
96 _out << indent(depth) << "<bloc name=\"" << node->getName() << "\"";
97 if (node->getState() == YACS::DISABLED)
98 _out << " state=\"disabled\">" << endl;
101 writeProperties(node);
102 node->ComposedNode::accept(this);
104 writeSimpleDataLinks(node);
105 writeSimpleStreamLinks(node);
106 _out << indent(depth) << "</bloc>" << endl;
108 DEBTRACE("END visitBloc " << _root->getChildName(node));
111 void VisitorSaveSchema::visitElementaryNode(ElementaryNode *node)
113 DEBTRACE("START visitElementaryNode " << _root->getChildName(node));
115 writeProperties(node);
116 writeInputPorts(node);
117 writeInputDataStreamPorts(node);
118 writeOutputPorts(node);
119 writeOutputDataStreamPorts(node);
121 DEBTRACE("END visitElementaryNode " << _root->getChildName(node));
124 void VisitorSaveSchema::visitForEachLoop(ForEachLoop *node)
126 DEBTRACE("START visitForEachLoop " << _root->getChildName(node));
128 int depth = depthNode(node);
130 _out << indent(depth) << "<foreach name=\"" << node->getName() << "\"";
131 AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
132 if (node->getState() == YACS::DISABLED)
133 _out << " state=\"disabled\"";
134 if (!nbranch->isEmpty())
135 _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
136 if (node->edGetSamplePort())
137 _out << " type=\"" << node->edGetSamplePort()->edGetType()->name() << "\"";
140 writeProperties(node);
141 node->DynParaLoop::accept(this);
142 writeSimpleDataLinks(node);
143 writeSimpleStreamLinks(node);
144 _out << indent(depth) << "</foreach>" << endl;
146 DEBTRACE("END visitForEachLoop " << _root->getChildName(node));
149 void VisitorSaveSchema::visitOptimizerLoop(OptimizerLoop *node)
151 DEBTRACE("START visitOptimizerLoop " << _root->getChildName(node));
153 int depth = depthNode(node);
155 _out << indent(depth) << "<optimizer name=\"" << node->getName() << "\"";
156 AnyInputPort *nbranch = static_cast<AnyInputPort*>(node->edGetNbOfBranchesPort());
157 if (node->getState() == YACS::DISABLED)
158 _out << " state=\"disabled\"";
159 if (!nbranch->isEmpty())
160 _out << " nbranch=\"" << nbranch->getIntValue() << "\"";
161 _out << " lib=\"" << node->getAlgLib() << "\"";
162 _out << " entry=\"" << node->getSymbol() << "\"";
165 writeProperties(node);
166 node->DynParaLoop::accept(this);
167 writeSimpleDataLinks(node);
168 writeSimpleStreamLinks(node);
169 _out << indent(depth) << "</optimizer>" << endl;
171 DEBTRACE("END visitOptimizerLoop " << _root->getChildName(node));
174 void VisitorSaveSchema::visitDynParaLoop(DynParaLoop *node)
176 DEBTRACE("START visitDynParaLoop " << _root->getChildName(node));
177 int depth = depthNode(node);
178 if (node->getInitNode() != NULL)
180 _out << indent(depth+1) << "<initnode>" << endl;
181 node->getInitNode()->accept(this);
182 _out << indent(depth+1) << "</initnode>" << endl;
184 if (node->getExecNode() != NULL)
186 node->getExecNode()->accept(this);
188 if (node->getFinalizeNode() != NULL)
190 _out << indent(depth+1) << "<finalizenode>" << endl;
191 node->getFinalizeNode()->accept(this);
192 _out << indent(depth+1) << "</finalizenode>" << endl;
194 DEBTRACE("END visitDynParaLoop " << _root->getChildName(node));
197 void VisitorSaveSchema::visitForLoop(ForLoop *node)
199 DEBTRACE("START visitForLoop " << _root->getChildName(node));
201 int depth = depthNode(node);
202 AnyInputPort *nsteps = static_cast<AnyInputPort*>(node->edGetNbOfTimesInputPort());
203 _out << indent(depth) << "<forloop name=\"" << node->getName() << "\"";
204 if (node->getState() == YACS::DISABLED)
205 _out << " state=\"disabled\"";
206 if (nsteps->isEmpty())
209 _out << " nsteps=\"" << nsteps->getIntValue() << "\">" << endl;
210 writeProperties(node);
211 node->ComposedNode::accept(this);
212 writeSimpleDataLinks(node);
213 writeSimpleStreamLinks(node);
214 _out << indent(depth) << "</forloop>" << endl;
216 DEBTRACE("END visitForLoop " << _root->getChildName(node));
219 void VisitorSaveSchema::visitInlineNode(InlineNode *node)
221 DEBTRACE("START visitInlineNode " << _root->getChildName(node));
223 int depth = depthNode(node);
224 if(node->getExecutionMode()=="local")
225 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
227 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
228 if (node->getState() == YACS::DISABLED)
229 _out << " state=\"disabled\">" << endl;
232 _out << indent(depth+1) << "<script><code><![CDATA[";
233 _out << node->getScript();
234 _out << "]]></code></script>" << endl;
236 //add load container if node is remote
237 Container *cont = node->getContainer();
239 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
241 writeProperties(node);
242 writeInputPorts(node);
243 writeInputDataStreamPorts(node);
244 writeOutputPorts(node);
245 writeOutputDataStreamPorts(node);
247 if(node->getExecutionMode()=="local")
248 _out << indent(depth) << "</inline>" << endl;
250 _out << indent(depth) << "</remote>" << endl;
253 DEBTRACE("END visitInlineNode " << _root->getChildName(node));
256 void VisitorSaveSchema::visitInlineFuncNode(InlineFuncNode *node)
258 DEBTRACE("START visitInlineFuncNode " << _root->getChildName(node));
260 int depth = depthNode(node);
261 if(node->getExecutionMode()=="local")
262 _out << indent(depth) << "<inline name=\"" << node->getName() << "\"";
264 _out << indent(depth) << "<remote name=\"" << node->getName() << "\"";
265 if (node->getState() == YACS::DISABLED)
266 _out << " state=\"disabled\">" << endl;
269 _out << indent(depth+1) << "<function name=\"" << node->getFname() << "\">" << endl;
270 _out << indent(depth+2) << "<code><![CDATA[";
271 _out << node->getScript();
272 _out << "]]></code>" << endl;
273 _out << indent(depth+1) << "</function>" << endl;
275 //add load container if node is remote
276 Container *cont = node->getContainer();
278 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
280 writeProperties(node);
281 writeInputPorts(node);
282 writeInputDataStreamPorts(node);
283 writeOutputPorts(node);
284 writeOutputDataStreamPorts(node);
286 if(node->getExecutionMode()=="local")
287 _out << indent(depth) << "</inline>" << endl;
289 _out << indent(depth) << "</remote>" << endl;
292 DEBTRACE("END visitInlineFuncNode " << _root->getChildName(node));
295 void VisitorSaveSchema::visitLoop(Loop *node)
297 DEBTRACE("START visitLoop " << _root->getChildName(node));
299 int depth = depthNode(node);
300 writeProperties(node);
301 node->ComposedNode::accept(this);
303 writeSimpleDataLinks(node);
304 writeSimpleStreamLinks(node);
306 DEBTRACE("END visitLoop " << _root->getChildName(node));
309 void VisitorSaveSchema::visitProc(Proc *node)
311 DEBTRACE("START visitProc " << node->getName());
312 _out << "<proc name=\""<< node->getName() << "\">" << endl;
314 writeProperties(node);
315 writeTypeCodes(node);
316 writeContainers(node);
317 writeComponentInstances(node);
318 node->ComposedNode::accept(this);
320 writeSimpleDataLinks(node);
321 writeSimpleStreamLinks(node);
322 writeParameters(node);
324 DEBTRACE("END visitProc " << node->getName());
327 void VisitorSaveSchema::visitServiceNode(ServiceNode *node)
329 DEBTRACE("START visitServiceNode " << _root->getChildName(node));
331 int depth = depthNode(node);
332 _out << indent(depth) << "<service name=\"" << node->getName() << "\"";
333 if (node->getState() == YACS::DISABLED)
334 _out << " state=\"disabled\">" << endl;
337 if (node->getKind() == "xmlsh")
339 _out << indent(depth+1) << "<kind>xmlsh</kind>" << endl;
340 _out << indent(depth+1) << "<ref>" << node->getRef() << "</ref>" << endl;
344 ComponentInstance *compo = node->getComponent();
345 if (compo && !compo->isAnonymous())
347 _out << indent(depth+1) << "<componentinstance>" << compo->getInstanceName() << "</componentinstance>" << endl;
349 else if (compo && (_componentInstanceMap.find(compo) == _componentInstanceMap.end()))
351 _out << indent(depth+1) << compo->getFileRepr() << endl;
352 _componentInstanceMap[compo] = _root->getChildName(node);
353 Container *cont = compo->getContainer();
356 map<string, Container*>::const_iterator it;
357 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
359 if (it->second == cont) break;
361 if (it != _containerMap.end())
362 _out << indent(depth+1) << "<load container=\"" << it->first << "\"/>" << endl;
367 _out << indent(depth+1) << "<node>" << _componentInstanceMap[compo] << "</node>" << endl;
371 _out << indent(depth+1) << "<component>" << "UNKNOWN" << "</component>" << endl;
374 _out << indent(depth+1) << "<method>" << node->getMethod() << "</method>" << endl;
376 writeProperties(node);
377 writeInputPorts(node);
378 writeInputDataStreamPorts(node);
379 writeOutputPorts(node);
380 writeOutputDataStreamPorts(node);
381 _out << indent(depth) << "</service>" << endl;
383 DEBTRACE("END visitServiceNode " << _root->getChildName(node));
386 void VisitorSaveSchema::visitServerNode(ServerNode *node)
388 DEBTRACE("START visitServerNode " << _root->getChildName(node));
390 int depth = depthNode(node);
391 _out << indent(depth) << "<server name=\"" << node->getName() << "\"";
392 if (node->getState() == YACS::DISABLED)
393 _out << " state=\"disabled\">" << endl;
396 Container *cont = node->getContainer();
397 map<string, Container*>::const_iterator it;
398 for (it = _containerMap.begin(); it != _containerMap.end(); ++it)
400 if (it->second == cont) break;
402 if (it != _containerMap.end())
403 _out << indent(depth+1) << "<loadcontainer>" << it->first << "</loadcontainer>" << endl;
406 _out << indent(depth+1) << "<node>" << _contnentInstanceMap[cont] << "</node>" << endl;
408 _out << indent(depth+1) << "<method>" << node->getFname() << "</method>" << endl;
409 _out << indent(depth+2) << "<script><code><![CDATA[";
410 _out << node->getScript();
411 _out << "]]></code></script>" << endl;
412 //_out << indent(depth+1) << "</function>" << endl;
413 writeProperties(node);
414 writeInputPorts(node);
415 writeInputDataStreamPorts(node);
416 writeOutputPorts(node);
417 writeOutputDataStreamPorts(node);
418 _out << indent(depth) << "</server>" << endl;
420 DEBTRACE("END visitServerNode " << _root->getChildName(node));
423 void VisitorSaveSchema::visitServiceInlineNode(ServiceInlineNode *node)
425 DEBTRACE("START visitServiceInlineNode " << _root->getChildName(node));
427 int depth = depthNode(node);
428 _out << indent(depth) << "<serviceInline name=\"" << node->getName() << "\"";
429 if (node->getState() == YACS::DISABLED)
430 _out << " state=\"disabled\">" << endl;
434 ComponentInstance *compo = node->getComponent();
436 _out << indent(depth+1) << compo->getFileRepr() << endl;
438 _out << indent(depth+1) << "<function name=\"" << node->getMethod() << "\">" << endl;
439 _out << indent(depth+2) << "<code><![CDATA[";
440 _out << node->getScript();
441 _out << "]]></code>" << endl;
442 _out << indent(depth+1) << "</function>" << endl;
443 writeProperties(node);
444 writeInputPorts(node);
445 writeOutputPorts(node);
446 _out << indent(depth) << "</serviceInline>" << endl;
448 DEBTRACE("END visitServiceInlineNode " << _root->getChildName(node));
451 void VisitorSaveSchema::visitPresetNode(DataNode *node)
453 DEBTRACE("START visitPresetNode " << _root->getChildName(node));
454 DEBTRACE("END visitPresetNode " << _root->getChildName(node));
457 void VisitorSaveSchema::visitOutNode(DataNode *node)
459 DEBTRACE("START visitOutNode " << _root->getChildName(node));
460 DEBTRACE("END visitOutNode " << _root->getChildName(node));
463 void VisitorSaveSchema::visitStudyInNode(DataNode *node)
465 DEBTRACE("START visitStudyInNode " << _root->getChildName(node));
466 DEBTRACE("END visitStudyInNode " << _root->getChildName(node));
469 void VisitorSaveSchema::visitStudyOutNode(DataNode *node)
471 DEBTRACE("START visitStudyOutNode " << _root->getChildName(node));
472 DEBTRACE("END visitStudyOutNode " << _root->getChildName(node));
476 void VisitorSaveSchema::visitSwitch(Switch *node)
478 DEBTRACE("START visitSwitch " << _root->getChildName(node));
480 int depth = depthNode(node);
481 AnyInputPort *condition = static_cast<AnyInputPort*>(node->edGetConditionPort());
482 _out << indent(depth) << "<switch name=\"" << node->getName() << "\"";
483 if (node->getState() == YACS::DISABLED)
484 _out << " state=\"disabled\"";
485 if (condition->isEmpty())
488 _out << " select=\"" << condition->getIntValue() << "\">" << endl;
489 writeProperties(node);
490 node->ComposedNode::accept(this);
492 writeSimpleDataLinks(node);
493 writeSimpleStreamLinks(node);
494 _out << indent(depth) << "</switch>" << endl;
496 DEBTRACE("END visitSwitch " << _root->getChildName(node));
499 void VisitorSaveSchema::visitWhileLoop(WhileLoop *node)
501 DEBTRACE("START visitWhileLoop " << _root->getChildName(node));
503 int depth = depthNode(node);
504 _out << indent(depth) << "<while name=\"" << node->getName() << "\"";
505 if (node->getState() == YACS::DISABLED)
506 _out << " state=\"disabled\">" << endl;
509 writeProperties(node);
510 node->ComposedNode::accept(this);
511 writeSimpleDataLinks(node);
512 writeSimpleStreamLinks(node);
513 _out << indent(depth) << "</while>" << endl;
515 DEBTRACE("END visitWhileLoop " << _root->getChildName(node));
519 void VisitorSaveSchema::writeProperties(Node *node)
521 int depth = depthNode(node)+1;
522 map<string,string> properties = getNodeProperties(node);
523 map<string,string>::const_iterator it;
524 for(it = properties.begin(); it != properties.end(); ++it)
526 _out << indent(depth) << "<property name=\"" << it->first
527 << "\" value=\"" << it->second << "\"/>" << endl;
531 void VisitorSaveSchema::dumpTypeCode(TypeCode* type, std::set<std::string>& typeNames,std::map<std::string, TypeCode*>& typeMap,int depth)
533 DynType kind = type->kind();
534 string typeName = type->name();
535 if (typeNames.find(typeName) != typeNames.end())
539 case YACS::ENGINE::Double:
541 typeNames.insert(typeName);
542 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"double\"/>" << endl;
545 case YACS::ENGINE::Int:
547 typeNames.insert(typeName);
548 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"int\"/>" << endl;
551 case YACS::ENGINE::String:
553 typeNames.insert(typeName);
554 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"string\"/>" << endl;
557 case YACS::ENGINE::Bool:
559 typeNames.insert(typeName);
560 _out << indent(depth) << "<type name=\"" << typeName << "\" kind=\"bool\"/>" << endl;
563 case YACS::ENGINE::Objref:
565 TypeCodeObjref *objref = dynamic_cast<TypeCodeObjref*>(type);
566 std::list<TypeCodeObjref*> listOfBases = getListOfBases(objref);
567 //try to dump base classes
568 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
570 if (typeNames.find((*il)->name()) == typeNames.end())
571 dumpTypeCode((*il),typeNames,typeMap,depth);
574 typeNames.insert(typeName);
575 _out << indent(depth) << "<objref name=\"" << typeName << "\" id=\""
576 << objref->id() << "\"";
577 if (listOfBases.empty())
578 _out << "/>" << endl;
582 for(std::list<TypeCodeObjref*>::iterator il=listOfBases.begin(); il != listOfBases.end(); ++il)
584 _out << indent(depth+1) << "<base>";
585 _out << (*il)->name();
586 _out << "</base>" << endl;
588 _out << indent(depth) << "</objref>" << endl;
592 case YACS::ENGINE::Sequence:
594 TypeCode* content = (TypeCode*)type->contentType();
595 if (typeNames.find(content->name()) == typeNames.end())
597 //content type not dumped
598 dumpTypeCode(content,typeNames,typeMap,depth);
600 typeNames.insert(typeName);
601 _out << indent(depth) << "<sequence name=\"" << typeName << "\" content=\""
602 << content->name() << "\"/>" << endl;
605 case YACS::ENGINE::Array:
607 TypeCode* content = (TypeCode*)type->contentType();
608 if (typeNames.find(content->name()) == typeNames.end())
610 //content type not dumped
611 dumpTypeCode(content,typeNames,typeMap,depth);
613 typeNames.insert(typeName);
614 _out << indent(depth) << "<array name=\"" << typeName << "\" content=\""
615 << content->name() << "\"/>" << endl;
618 case YACS::ENGINE::Struct:
620 TypeCodeStruct* tcStruct = dynamic_cast<TypeCodeStruct*>(type);
622 int mbCnt = tcStruct->memberCount();
623 for (int i=0; i<mbCnt; i++)
625 TypeCode* member = tcStruct->memberType(i);
626 if (typeNames.find(member->name()) == typeNames.end())
628 //content type not dumped
629 dumpTypeCode(member,typeNames,typeMap,depth);
632 typeNames.insert(typeName);
633 _out << indent(depth) << "<struct name=\"" << typeName << "\">" << endl;
634 for (int i=0; i<mbCnt; i++)
636 TypeCode* member = tcStruct->memberType(i);
637 _out << indent(depth+1) << "<member name=\"" <<tcStruct->memberName(i) << "\" type=\"" << member->name() << "\"/>" << endl;
639 _out << indent(depth) << "</struct>" << endl;
644 string what = "wrong TypeCode: ";
645 throw Exception(what);
650 void VisitorSaveSchema::writeTypeCodes(Proc *proc)
652 int depth = depthNode(proc)+1;
653 map<string, TypeCode*> typeMap = getTypeCodeMap(proc);
654 map<string, TypeCode*>::const_iterator it;
655 set<string> typeNames;
657 // --- force definition of simple types first
659 for (it = typeMap.begin(); it != typeMap.end(); it++)
661 dumpTypeCode(it->second,typeNames,typeMap,depth);
665 void VisitorSaveSchema::writeComponentInstances(Proc *proc)
667 int depth = depthNode(proc)+1;
668 std::map<std::string, ComponentInstance*>::const_iterator it;
669 for (it = proc->componentInstanceMap.begin(); it != proc->componentInstanceMap.end(); it++)
671 string name = it->first;
672 ComponentInstance* inst=it->second;
673 if(!inst->isAnonymous())
675 _out << indent(depth) << "<componentinstance name=\"" << inst->getInstanceName() << "\">" << endl;
676 _out << indent(depth+1) << "<component>" << inst->getCompoName() << "</component>" << endl;
678 Container *cont = inst->getContainer();
680 _out << indent(depth+1) << "<load container=\"" << cont->getName() << "\"/>" << endl;
682 std::map<std::string, std::string> properties = inst->getProperties();
683 std::map<std::string, std::string>::const_iterator itm;
684 for(itm = properties.begin(); itm != properties.end(); ++itm)
685 _out << indent(depth+1) << "<property name=\"" << (*itm).first
686 << "\" value=\"" << (*itm).second << "\"/>" << endl;
688 _out << indent(depth) << "</componentinstance>" << endl;
693 void VisitorSaveSchema::writeContainers(Proc *proc)
695 int depth = depthNode(proc)+1;
696 _containerMap = getContainerMap(proc);
697 map<string, Container*>::const_iterator it;
698 for (it = _containerMap.begin(); it != _containerMap.end(); it++)
700 string name = it->first;
701 _out << indent(depth) << "<container name=\"" << name << "\">" << endl;
702 map<string, string> properties = (it->second)->getProperties();
703 map<string, string>::iterator itm;
704 for(itm = properties.begin(); itm != properties.end(); ++itm)
705 _out << indent(depth+1) << "<property name=\"" << (*itm).first
706 << "\" value=\"" << (*itm).second << "\"/>" << endl;
707 _out << indent(depth) << "</container>" << endl;
712 void VisitorSaveSchema::writeInputPorts(Node *node)
714 int depth = depthNode(node)+1;
715 list<InputPort*> listOfInputPorts = node->getSetOfInputPort();
716 for (list<InputPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
718 _out << indent(depth) << "<inport name=\"" << (*it)->getName() << "\" type=\""
719 << (*it)->edGetType()->name() << "\"/>" << endl;
723 void VisitorSaveSchema::writeInputDataStreamPorts(Node *node)
725 int depth = depthNode(node)+1;
726 list<InputDataStreamPort*> listOfInputPorts = node->getSetOfInputDataStreamPort();
727 for (list<InputDataStreamPort*>::iterator it = listOfInputPorts.begin(); it != listOfInputPorts.end(); ++it)
729 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
730 if ( aPropMap.empty() )
731 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
732 << (*it)->edGetType()->name() << "\"/>" << endl;
735 _out << indent(depth) << "<instream name=\"" << (*it)->getName() << "\" type=\""
736 << (*it)->edGetType()->name() << "\">" << endl;
737 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
738 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
739 << (*itP).second << "\"/>" << endl;
740 _out << indent(depth) << "</instream>" << endl;
745 void VisitorSaveSchema::writeOutputPorts(Node *node)
747 int depth = depthNode(node)+1;
748 list<OutputPort*> listOfOutputPorts = node->getSetOfOutputPort();
749 for (list<OutputPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
751 _out << indent(depth) << "<outport name=\"" << (*it)->getName() << "\" type=\""
752 << (*it)->edGetType()->name() << "\"/>" << endl;
756 void VisitorSaveSchema::writeOutputDataStreamPorts(Node *node)
758 int depth = depthNode(node)+1;
759 list<OutputDataStreamPort*> listOfOutputPorts = node->getSetOfOutputDataStreamPort();
760 for (list<OutputDataStreamPort*>::iterator it = listOfOutputPorts.begin(); it != listOfOutputPorts.end(); ++it)
762 std::map<std::string,std::string> aPropMap = (*it)->getProperties();
763 if ( aPropMap.empty() )
764 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
765 << (*it)->edGetType()->name() << "\"/>" << endl;
768 _out << indent(depth) << "<outstream name=\"" << (*it)->getName() << "\" type=\""
769 << (*it)->edGetType()->name() << "\">" << endl;
770 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
771 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
772 << (*itP).second << "\"/>" << endl;
773 _out << indent(depth) << "</outstream>" << endl;
778 void VisitorSaveSchema::writeControls(ComposedNode *node)
780 int depth = depthNode(node)+1;
781 list<Node*> setOfChildren = node->edGetDirectDescendants();
782 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
784 // --- Control links from direct descendant to nodes inside the bloc
785 set<InGate*> setOfInGates = (*ic)->getOutGate()->edSetInGate();
786 for (set<InGate*>::iterator ig = setOfInGates.begin(); ig != setOfInGates.end(); ++ig)
788 Node *to = (*ig)->getNode();
789 if (node->isInMyDescendance(to))
792 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
793 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
796 // --- Control links from nodes inside the bloc to direct descendant
797 // avoid links between direct descendants (already done above)
798 list<OutGate*> listOfOutGates = (*ic)->getInGate()->getBackLinks();
799 for (list<OutGate*>::iterator ig = listOfOutGates.begin(); ig != listOfOutGates.end(); ++ig)
801 Node *from = (*ig)->getNode();
802 if ((node->isInMyDescendance(from)) && (from->getFather()->getNumId() != node->getNumId()))
805 _out << indent(depth) << "<control> <fromnode>" << node->getChildName(from) << "</fromnode> ";
806 _out << "<tonode>" << node->getChildName(to) << "</tonode> </control>" << endl;
813 * Write simple data links from and to direct children of node (grand children already done).
814 * First, for all output ports of direct children, write links where the input port is inside
815 * the node scope. Keep in memory the links where the input port is outside the node scope.
816 * Second, retreive links where the output port is inside the scope, using the links kept in memory
817 * and not yet written.
819 void VisitorSaveSchema::writeSimpleDataLinks(ComposedNode *node)
821 int depth = depthNode(node)+1;
822 list<Node*> setOfChildren = node->edGetDirectDescendants();
824 list<Node*> setOfChildrenPlusSplitters = setOfChildren;
826 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
827 // add "splitter" node of ForEachLoop nodes to the set of children
828 if ( dynamic_cast<ForEachLoop*>( *ic ) )
830 Node *nodeToInsert=(*ic)->getChildByName(ForEachLoop::NAME_OF_SPLITTERNODE);
831 if(find(setOfChildrenPlusSplitters.begin(),setOfChildrenPlusSplitters.end(),nodeToInsert)==setOfChildrenPlusSplitters.end())
832 setOfChildrenPlusSplitters.push_back(nodeToInsert);
835 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
837 for (list<Node*>::iterator ic = setOfChildrenPlusSplitters.begin(); ic != setOfChildrenPlusSplitters.end(); ++ic)
840 list<OutputPort*> listOP = from->getLocalOutputPorts();
841 for (list<OutputPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
843 OutputPort* anOP = *io;
844 set<InPort*> setIP = anOP->edSetInPort();
845 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
848 Node* to = anIP->getNode();
849 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
850 << " to " << to->getName() << " inputPort " << anIP->getName() );
851 Node* child = node->isInMyDescendance(to);
852 if (child && (child->getNumId() != node->getNumId())
853 && (from->getNumId() != to->getNumId()))
855 DEBTRACE( "BINGO!" );
858 if ( dynamic_cast<SplitterNode*>(from) && dynamic_cast<ForEachLoop*>(from->getFather()) )
859 fromName = from->getFather()->getName();
861 fromName = node->getChildName(from);
864 if ( dynamic_cast<SplitterNode*>(to) && dynamic_cast<ForEachLoop*>(to->getFather()) )
865 childName = node->getChildName(to->getFather());
867 childName = node->getChildName(to);
868 _out << indent(depth) << "<datalink control=\"false\">" << endl;
869 _out << indent(depth+1) << "<fromnode>" << fromName << "</fromnode> ";
870 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
871 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
872 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
873 _out << indent(depth) << "</datalink>" << endl;
876 { // --- store info to create the link later, given the input port
877 DEBTRACE( "For later" );
878 struct DataLinkInfo aLink = { from, to, anOP, anIP, false };
879 _mapOfDLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
885 // --- second pass, retreive links where the output port is inside the scope.
887 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
889 std::multimap<int, DataLinkInfo>::iterator pos;
890 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end(); ++pos)
892 Node* to = (pos->second).to;
893 Node* child = node->isInMyDescendance(to);
894 if (child && (child->getNumId() != node->getNumId()))
896 InPort* anIP = (pos->second).inp;
897 int portId = anIP->getNumId();
898 Node* from = (pos->second).from;
899 child = node->isInMyDescendance(from);
900 if (child && (child->getNumId() != node->getNumId()))
901 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
903 string childName = node->getChildName(from);
904 OutPort *anOP = (pos->second).outp;
905 (pos->second).toDelete = true;
906 _out << indent(depth) << "<datalink control=\"false\">" << endl;
907 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
908 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
909 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
910 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
911 _out << indent(depth) << "</datalink>" << endl;
916 // --- remove the link written from the multimap
918 for (pos = _mapOfDLtoCreate.begin(); pos != _mapOfDLtoCreate.end();)
920 if ((pos->second).toDelete)
921 _mapOfDLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
928 void VisitorSaveSchema::writeSimpleStreamLinks(ComposedNode *node)
930 int depth = depthNode(node)+1;
931 list<Node*> setOfChildren = node->edGetDirectDescendants();
933 // --- first pass, write links where the input port is inside the node scope. Keep in memory others.
935 for (list<Node*>::iterator ic = setOfChildren.begin(); ic != setOfChildren.end(); ++ic)
938 if ( dynamic_cast<ComposedNode*>(from) ) continue;
939 list<OutputDataStreamPort*> listOP = from->getSetOfOutputDataStreamPort();
940 for (list<OutputDataStreamPort*>::iterator io = listOP.begin(); io != listOP.end(); ++io)
942 OutputDataStreamPort* anOP = *io;
943 set<InPort*> setIP = anOP->edSetInPort();
944 for (set<InPort*>::iterator iip = setIP.begin(); iip != setIP.end(); ++iip)
947 Node* to = anIP->getNode();
948 DEBTRACE("from " << from->getName() << " outputPort " << anOP->getName()
949 << " to " << to->getName() << " inputPort " << anIP->getName() );
950 Node* child = node->isInMyDescendance(to);
951 if (child && (child->getNumId() != node->getNumId())
952 && (from->getNumId() != to->getNumId()))
954 DEBTRACE( "BINGO!" );
955 string childName = node->getChildName(to);
956 _out << indent(depth) << "<stream>" << endl;
957 _out << indent(depth+1) << "<fromnode>" << node->getChildName(from) << "</fromnode> ";
958 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
959 _out << indent(depth+1) << "<tonode>" << childName << "</tonode> ";
960 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
962 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
963 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
965 string notAlinkProperty = "DependencyType";
966 if (notAlinkProperty != (*itP).first)
967 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
968 << (*itP).second << "\"/>" << endl;
970 _out << indent(depth) << "</stream>" << endl;
973 { // --- store info to create the link later, given the input port
974 DEBTRACE("For later" );
975 struct StreamLinkInfo aLink = { from, to, anOP, anIP, false };
976 _mapOfSLtoCreate.insert(make_pair(anIP->getNumId(), aLink));
982 // --- second pass, retreive links where the output port is inside the scope.
984 if (!dynamic_cast<Switch*>(node)) // xml parser does not take into account datalinks in a switch context
986 std::multimap<int, StreamLinkInfo>::iterator pos;
987 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end(); ++pos)
989 Node* to = (pos->second).to;
990 Node* child = node->isInMyDescendance(to);
991 if (child && (child->getNumId() != node->getNumId()))
993 InPort* anIP = (pos->second).inp;
994 int portId = anIP->getNumId();
995 Node* from = (pos->second).from;
996 child = node->isInMyDescendance(from);
997 if (child && (child->getNumId() != node->getNumId()))
998 if((from->getNumId() != to->getNumId()) || dynamic_cast<Loop*>(node))
1000 string childName = node->getChildName(from);
1001 OutputDataStreamPort *anOP = (pos->second).outp;
1002 (pos->second).toDelete = true;
1003 _out << indent(depth) << "<stream>" << endl;
1004 _out << indent(depth+1) << "<fromnode>" << childName << "</fromnode> ";
1005 _out << "<fromport>" << anOP->getName() << "</fromport>" << endl;
1006 _out << indent(depth+1) << "<tonode>" << node->getChildName(to) << "</tonode> ";
1007 _out << "<toport>" << anIP->getName() << "</toport>" << endl;
1009 std::map<std::string,std::string> aPropMap = dynamic_cast<InputDataStreamPort*>(anIP)->getProperties();
1010 for (std::map<std::string,std::string>::iterator itP = aPropMap.begin(); itP != aPropMap.end(); itP++)
1011 _out << indent(depth+1) << "<property name=\"" << (*itP).first << "\" value=\""
1012 << (*itP).second << "\"/>" << endl;
1014 _out << indent(depth) << "</stream>" << endl;
1019 // --- remove the link written from the multimap
1021 for (pos = _mapOfSLtoCreate.begin(); pos != _mapOfSLtoCreate.end();)
1023 if ((pos->second).toDelete)
1024 _mapOfSLtoCreate.erase(pos++); // be careful not to saw off the branch on which you are sitting!
1031 std::set<Node*> VisitorSaveSchema::getAllNodes(ComposedNode *node)
1034 list< Node *> setOfNode = node->edGetDirectDescendants();
1035 for(list<Node *>::iterator iter=setOfNode.begin();iter!=setOfNode.end();iter++)
1037 if ( dynamic_cast<ComposedNode*> (*iter) )
1039 set<Node *> myCurrentSet = getAllNodes(dynamic_cast<ComposedNode*> (*iter));
1040 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1045 list<ElementaryNode *> myCurrentSet=(*iter)->getRecursiveConstituents();
1046 ret.insert(myCurrentSet.begin(),myCurrentSet.end());
1053 void VisitorSaveSchema::writeParameters(Proc *proc)
1055 // set<Node*> nodeSet = proc->getAllRecursiveConstituents();
1056 set<Node*> nodeSet = getAllNodes(proc);
1057 for (set<Node*>::iterator iter = nodeSet.begin(); iter != nodeSet.end(); ++iter)
1059 // ElementaryNode *node = dynamic_cast<ElementaryNode*>(*iter);
1061 // writeParametersNode(proc,node);
1062 writeParametersNode(proc,(*iter));
1066 void VisitorSaveSchema::writeParametersNode(ComposedNode *proc, Node *node)
1069 list<InputPort *> setOfInputPort = node->getLocalInputPorts();
1070 if (ForEachLoop* foreach = dynamic_cast<ForEachLoop*>(node))
1072 DEBTRACE("writeParametersNode foreach");
1073 setOfInputPort.push_back( foreach->edGetSeqOfSamplesPort());
1075 list<InputPort *>::iterator iter;
1076 for(iter = setOfInputPort.begin(); iter != setOfInputPort.end(); ++iter)
1078 if (!(*iter)->isEmpty())
1080 _out << indent(depth) << "<parameter>" << endl;
1081 _out << indent(depth+1) << "<tonode>" << proc->getChildName(node) << "</tonode>";
1082 _out << "<toport>" << (*iter)->getName() << "</toport>" <<endl;
1085 _out << indent(depth+1) << (*iter)->dump();
1087 catch (YACS::Exception &e)
1089 _out << "<value><error><![CDATA[" << e.what() << "]]></error></value>" << endl;
1091 _out << indent(depth) << "</parameter>" << endl;
1096 void VisitorSaveSchema::beginCase(Node* node)
1098 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1101 int depth = depthNode(node) -1;
1102 int myCase = myFather->getRankOfNode(node);
1103 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1104 _out << indent(depth) << "<default>" << endl;
1106 _out << indent(depth) << "<case id=\"" << myCase << "\">" << endl;
1110 void VisitorSaveSchema::endCase(Node* node)
1112 Switch *myFather =dynamic_cast<Switch*>(node->getFather());
1115 int depth = depthNode(node) -1;
1116 int myCase = myFather->getRankOfNode(node);
1117 if (myCase == Switch::ID_FOR_DEFAULT_NODE)
1118 _out << indent(depth) << "</default>" << endl;
1120 _out << indent(depth) << "</case>" << endl;
1124 int VisitorSaveSchema::depthNode(Node* node)
1127 ComposedNode *father = node->getFather();
1131 if (dynamic_cast<Switch*>(father)) depth +=1;
1132 if (father->getNumId() == _root->getNumId()) break;
1133 father = father->getFather();
1138 SchemaSave::SchemaSave(Proc* proc): _p(proc)
1143 void SchemaSave::save(std::string xmlSchemaFile)
1145 VisitorSaveSchema vss(_p);
1146 vss.openFileSchema(xmlSchemaFile);
1148 vss.closeFileSchema();