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