]> SALOME platform Git repositories - modules/yacs.git/blob - src/yacsloader/blocParsers.hxx
Salome HOME
05b46940db1d18dc042f3e2ec0f0bd1546f791bd
[modules/yacs.git] / src / yacsloader / blocParsers.hxx
1 #ifndef _BLOCPARSER_HXX_
2 #define _BLOCPARSER_HXX_
3
4 #include "parserBase.hxx"
5 #include "linkParsers.hxx"
6 #include "xmlrpcParsers.hxx"
7 #include "nodeParsers.hxx"
8
9
10 #include "Proc.hxx"
11 #include "Logger.hxx"
12 #include "Runtime.hxx"
13 #include "ForLoop.hxx"
14 #include "ForEachLoop.hxx"
15 #include "WhileLoop.hxx"
16 #include "Switch.hxx"
17 #include "Bloc.hxx"
18 #include "Exception.hxx"
19 #include "InlineNode.hxx"
20 #include "DataNode.hxx"
21 #include "ServiceNode.hxx"
22 #include "ServiceInlineNode.hxx"
23 #include "OutputDataStreamPort.hxx"
24 #include "InputDataStreamPort.hxx"
25
26 #include <vector>
27
28 extern YACS::ENGINE::Proc* currentProc;
29 extern YACS::ENGINE::Runtime* theRuntime;
30
31 namespace YACS
32 {
33
34 template <class T=YACS::ENGINE::Bloc*>
35 struct bloctypeParser:parser
36 {
37   static bloctypeParser<T> blocParser;
38
39   bloctypeParser():parser()
40   {
41     _orders["property"]=0;
42     _orders["inline"]=2;
43     _orders["service"]=2;
44     _orders["sinline"]=2;
45     _orders["node"]=2;
46     _orders["datanode"]=2;
47     _orders["outnode"]=2;
48     _orders["forloop"]=2;
49     _orders["foreach"]=2;
50     _orders["while"]=2;
51     _orders["switch"]=2;
52     _orders["bloc"]=2;
53     _orders["control"]=3;
54     _orders["datalink"]=3;
55     _orders["stream"]=3;
56     _orders["parameter"]=3;
57   }
58   virtual void onStart(const XML_Char* el, const XML_Char** attr);
59   virtual void onEnd(const char *el,parser* child);
60   virtual void buildAttr(const XML_Char** attr)
61     {
62       this->required("name",attr);
63       for (int i = 0; attr[i]; i += 2) 
64         {
65           if(std::string(attr[i]) == "name")name(attr[i+1]);
66           if(std::string(attr[i]) == "state")state(attr[i+1]);
67         }
68     }
69   void name (const std::string& name)
70     {
71     }
72   virtual void state (const std::string& name){
73       DEBTRACE( "bloc_state: " << name )             
74       _state=name;
75       if(_state == "disabled")
76         {
77           DEBTRACE( "Bloc disabled: " << _bloc->getName())             
78           _bloc->exDisabledState();
79         }
80     }
81   virtual void property (const myprop& prop)
82     {
83       DEBTRACE( "property_set: " << prop._name << prop._value )             
84       _bloc->setProperty(prop._name,prop._value);
85     }
86   virtual void inline_ (YACS::ENGINE::InlineNode* const& n)
87     {
88       DEBTRACE( "bloc_pynode_set: " << n->getName() )             
89       _bloc->edAddChild(n);
90       std::string fullname = currentProc->names.back()+n->getName();
91       currentProc->nodeMap[fullname]=n;
92       currentProc->inlineMap[fullname]=n;
93     }
94   virtual void sinline (YACS::ENGINE::ServiceInlineNode* const& n)
95     {
96       DEBTRACE( "bloc_sinline: " << n->getName() )             
97       _bloc->edAddChild(n);
98       std::string fullname = currentProc->names.back()+n->getName();
99       currentProc->nodeMap[fullname]=n;
100       currentProc->serviceMap[fullname]=n;
101     }
102   virtual void service (YACS::ENGINE::ServiceNode* const& n)
103     {
104       DEBTRACE( "bloc_service_set: " << n->getName() )             
105       _bloc->edAddChild(n);
106       std::string fullname = currentProc->names.back()+n->getName();
107       currentProc->nodeMap[fullname]=n;
108       currentProc->serviceMap[fullname]=n;
109     }
110   virtual void node (YACS::ENGINE::InlineNode* const& n)
111     {
112       DEBTRACE( "bloc_node_set: " << n->getName() )             
113       _bloc->edAddChild(n);
114       std::string fullname = currentProc->names.back()+n->getName();
115       DEBTRACE( "bloc_node_set fullname = "  << fullname )             
116       currentProc->nodeMap[fullname]=n;
117       currentProc->inlineMap[fullname]=n;
118     }
119   virtual void forloop (YACS::ENGINE::ForLoop* const& b)
120     {
121       DEBTRACE( "bloc_forloop_set: " << b->getName() )             
122       _bloc->edAddChild(b);
123       std::string fullname = currentProc->names.back()+b->getName();
124       currentProc->nodeMap[fullname]=b;
125     }
126   virtual void foreach (YACS::ENGINE::ForEachLoop* const& b)
127     {
128       DEBTRACE( "bloc_foreach_set: " << b->getName() )             
129       _bloc->edAddChild(b);
130       std::string fullname = currentProc->names.back()+b->getName();
131       currentProc->nodeMap[fullname]=b;
132       fullname += ".splitter";
133       currentProc->nodeMap[fullname]=b->getChildByShortName("splitter");
134     }
135   virtual void while_ (YACS::ENGINE::WhileLoop* const& b)
136     {
137       DEBTRACE( "bloc_while_set: " << b->getName() )             
138       _bloc->edAddChild(b);
139       std::string fullname = currentProc->names.back()+b->getName();
140       currentProc->nodeMap[fullname]=b;
141     }
142   virtual void switch_ (YACS::ENGINE::Switch* const& b)
143     {
144       DEBTRACE( "bloc_switch_set: " << b->getName() )             
145       _bloc->edAddChild(b);
146       std::string fullname = currentProc->names.back()+b->getName();
147       currentProc->nodeMap[fullname]=b;
148     }
149   virtual void bloc (YACS::ENGINE::Bloc* const& b)
150     {
151       DEBTRACE( "bloc_bloc_set: " << b->getName() )             
152       _bloc->edAddChild(b);
153       std::string fullname=currentProc->names.back()+ b->getName();
154       currentProc->nodeMap[fullname]=b;
155     }
156   virtual void control (const mycontrol& l)
157     {
158       DEBTRACE( "bloc_control_set: " << l.fromnode() << " "<< l.tonode() )             
159       std::string msg;
160
161       if(currentProc->nodeMap.count(currentProc->names.back()+l.fromnode()) == 0)
162         {
163           msg="from node " + l.fromnode() + " does not exist in control link: ";
164           msg=msg+l.fromnode()+"->"+l.tonode();
165           msg=msg+ " context: "+currentProc->names.back();
166           this->logError(msg);
167           return;
168         }
169       if(currentProc->nodeMap.count(currentProc->names.back()+l.tonode()) == 0)
170         {
171           msg="to node " + l.tonode() + " does not exist in control link: ";
172           msg=msg+l.fromnode()+"->"+l.tonode();
173           msg=msg+ " context: "+currentProc->names.back();
174           this->logError(msg);
175           return;
176         }
177       // We only link local nodes
178       try
179         {
180           _bloc->edAddCFLink(currentProc->nodeMap[currentProc->names.back()+l.fromnode()],
181                              currentProc->nodeMap[currentProc->names.back()+l.tonode()]);
182         }
183       catch(YACS::Exception& e)
184         {
185           this->logError(e.what());
186         }
187     }
188   virtual void datalink (const mylink& l)
189     {
190       DEBTRACE( "bloc_datalink_set: "<<l.fromnode()<<"("<<l.fromport()<<")->"<<l.tonode()<<"("<<l.toport()<<")")
191       std::string msg;
192
193       //Try only relative name for from node
194       std::string fromname = currentProc->names.back()+l.fromnode();
195       if(currentProc->nodeMap.count(fromname) == 0)
196         {
197           msg="from node " + l.fromnode() + " does not exist in data link: ";
198           msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
199           this->logError(msg);
200           return;
201         }
202       //Try relative name for to node and then absolute one
203       std::string toname = currentProc->names.back()+l.tonode();
204       if(currentProc->nodeMap.count(toname) == 0)
205         {
206           //It's not a relative name. Try an absolute one (I think it's not possible)
207           toname=l.tonode();
208           if(currentProc->nodeMap.count(toname) == 0)
209             {
210               // The TO node does not exist -> error
211               msg="to node " + l.tonode() + " does not exist in data link: ";
212               msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
213               this->logError(msg);
214               return;
215             }
216         }
217       // We only link local node and other nodes (relative or absolute name in this order)
218       DEBTRACE(fromname <<":"<<l.fromport()<<toname<<":"<<l.toport());
219       try
220         {
221           if (l.withControl())
222             _bloc->edAddDFLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
223                                currentProc->nodeMap[toname]->getInputPort(l.toport()));
224           else
225             _bloc->edAddLink(currentProc->nodeMap[fromname]->getOutputPort(l.fromport()),
226                              currentProc->nodeMap[toname]->getInputPort(l.toport()));
227         }
228       catch(YACS::Exception& e)
229         {
230           this->logError(e.what());
231         }
232     }
233   virtual void stream (const mystream& l)
234     {
235       DEBTRACE( "bloc_stream_set: " << l.fromnode() << l.fromport() << l.tonode() << l.toport() )
236       std::string msg;
237       std::string fromname = currentProc->names.back()+l.fromnode();
238       std::string toname = currentProc->names.back()+l.tonode();
239       //only relative names
240       if(currentProc->nodeMap.count(fromname) == 0)
241         {
242             msg="from node " + l.fromnode() + " does not exist in stream link: ";
243             msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
244             this->logError(msg);
245             return;
246         }
247       if(currentProc->nodeMap.count(toname) == 0)
248         {
249             msg="to node " + l.tonode() + " does not exist in stream link: ";
250             msg=msg+l.fromnode()+"("+l.fromport()+")->"+l.tonode()+"("+l.toport()+")";
251             this->logError(msg);
252             return;
253         }
254       YACS::ENGINE::OutputDataStreamPort* pout=currentProc->nodeMap[fromname]->getOutputDataStreamPort(l.fromport());
255       YACS::ENGINE::InputDataStreamPort* pin=currentProc->nodeMap[toname]->getInputDataStreamPort(l.toport());
256       _bloc->edAddLink(pout,pin);
257       // Set all properties for this link
258       std::map<std::string, std::string>::const_iterator pt;
259       for(pt=l._props.begin();pt!=l._props.end();pt++)
260         {
261           pin->setProperty((*pt).first,(*pt).second);
262           pout->setProperty((*pt).first,(*pt).second);
263         }
264     }
265   virtual void parameter (const myparam& param)
266     {
267       DEBTRACE( "++++++++++++++++++++Parameter+++++++++++++++++++++" );
268       std::string msg;
269       std::string toname = currentProc->names.back()+param._tonode;
270       if(currentProc->nodeMap.count(toname) == 0)
271         {
272           msg="to node " + param._tonode + " does not exist in parameter: ";
273           msg=msg+"->"+param._tonode+"("+param._toport+")";
274           this->logError(msg);
275           return;
276         }
277       YACS::ENGINE::InputPort* inport=currentProc->nodeMap[toname]->getInputPort(param._toport);
278       //We don't know the parameter type. So we try to initialize the port
279       //with the value. If it's not the right type, edInit throws an exception
280       try
281         {
282           inport->edInit("XML",param._value.c_str());
283         }
284       catch(YACS::Exception& e)
285         {
286           this->logError(e.what());
287         }
288       DEBTRACE( "++++++++++++++++++++End parameter+++++++++++++++++++++" );
289     }
290
291   virtual void preset (ENGINE::DataNode* const& n);
292   virtual void outnode (ENGINE::DataNode* const& n);
293
294   T post()
295     {
296       DEBTRACE( "bloc_post" )             
297       currentProc->names.pop_back();
298       T b=_bloc;
299       _blocs.pop_back();
300       if(_blocs.empty())
301         _bloc=NULL;
302       else
303         _bloc=_blocs.back();
304       return b;
305     }
306
307   T _bloc;
308   std::string _state;
309   std::vector<YACS::ENGINE::Bloc *> _blocs;
310 };
311
312 template <class T> bloctypeParser<T> bloctypeParser<T>::blocParser;
313
314 template <class T>
315 void bloctypeParser<T>::preset (ENGINE::DataNode* const& n)
316 {
317   DEBTRACE("bloc_preset_set: " << n->getName() );
318   _bloc->edAddChild(n);
319   std::string fullname = currentProc->names.back()+n->getName();
320   currentProc->nodeMap[fullname]=n;
321 }
322
323 template <class T>
324 void bloctypeParser<T>::outnode (ENGINE::DataNode* const& n)
325 {
326   DEBTRACE("bloc_outnode: " << n->getName() );
327   _bloc->edAddChild(n);
328   std::string fullname = currentProc->names.back()+n->getName();
329   currentProc->nodeMap[fullname]=n;
330 }
331
332 template <>
333 void bloctypeParser<YACS::ENGINE::Bloc*>::name (const std::string& name)
334 {
335   DEBTRACE( "bloc_name: " << name )             
336   std::string fullname=currentProc->names.back()+name;
337   _bloc=theRuntime->createBloc(name);
338   _blocs.push_back(_bloc);
339   currentProc->names.push_back(fullname+'.');
340 }
341
342 }
343
344 #include "loopParsers.hxx"
345 #include "switchParsers.hxx"
346 #include "presetParsers.hxx"
347 #include "outputParsers.hxx"
348
349 namespace YACS
350 {
351
352 template <class T>
353 void bloctypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
354 {
355   DEBTRACE( "bloctypeParser::onStart: " << el )             
356   std::string element(el);
357   checkOrder(element);
358   parser* pp=&parser::main_parser;
359   if(element == "property")pp=&propertytypeParser::propertyParser;
360
361   else if(element == "inline")pp=&inlinetypeParser<>::inlineParser;
362   else if(element == "sinline")pp=&sinlinetypeParser<>::sinlineParser;
363   else if(element == "service")pp=&servicetypeParser<>::serviceParser;
364   else if(element == "node")pp=&nodetypeParser<>::nodeParser;
365   else if(element == "datanode")pp=&presettypeParser<>::presetParser;
366   else if(element == "outnode")pp=&outnodetypeParser<>::outnodeParser;
367
368   else if(element == "bloc")pp=&bloctypeParser<>::blocParser;
369   else if(element == "forloop")pp=&forlooptypeParser<>::forloopParser;
370   else if(element == "foreach")pp=&foreachlooptypeParser<>::foreachloopParser;
371   else if(element == "while")pp=&whilelooptypeParser<>::whileloopParser;
372   else if(element == "switch")pp=&switchtypeParser::switchParser;
373
374   else if(element == "control")pp=&controltypeParser<>::controlParser;
375   else if(element == "datalink")pp=&linktypeParser<>::linkParser;
376   else if(element == "stream")pp=&streamtypeParser<>::streamParser;
377   else if(element == "parameter")pp=&parametertypeParser::parameterParser;
378
379   this->SetUserDataAndPush(pp);
380   pp->init();
381   pp->pre();
382   pp->buildAttr(attr);
383 }
384
385 template <class T>
386 void bloctypeParser<T>::onEnd(const char *el,parser* child)
387 {
388   DEBTRACE( "bloctypeParser::onEnd: " << el )             
389   std::string element(el);
390   if(element == "property")property(((propertytypeParser*)child)->post());
391   else if(element == "inline")inline_(((inlinetypeParser<>*)child)->post());
392   else if(element == "sinline")sinline(((sinlinetypeParser<>*)child)->post());
393   else if(element == "service")service(((servicetypeParser<>*)child)->post());
394   else if(element == "node")node(((nodetypeParser<>*)child)->post());
395   else if(element == "datanode")preset(((presettypeParser<>*)child)->post());
396   else if(element == "outnode")outnode(((outnodetypeParser<>*)child)->post());
397
398   else if(element == "bloc")bloc(((bloctypeParser<>*)child)->post());
399   else if(element == "forloop")forloop(((forlooptypeParser<>*)child)->post());
400   else if(element == "foreach")foreach(((foreachlooptypeParser<>*)child)->post());
401   else if(element == "while")while_(((whilelooptypeParser<>*)child)->post());
402   else if(element == "switch")switch_(((switchtypeParser*)child)->post());
403
404   else if(element == "control") control(((controltypeParser<>*)child)->post());
405   else if(element == "datalink") datalink(((linktypeParser<>*)child)->post());
406   else if(element == "stream") stream(((streamtypeParser<>*)child)->post());
407   else if(element == "parameter") parameter(((parametertypeParser*)child)->post());
408 }
409
410 }
411
412 #endif