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