]> SALOME platform Git repositories - modules/yacs.git/blob - src/yacsloader/nodeParsers.hxx
Salome HOME
merge from branch DEV tag mergeto_trunk_04apr08
[modules/yacs.git] / src / yacsloader / nodeParsers.hxx
1
2 #ifndef _NODEPARSERS_HXX_
3 #define _NODEPARSERS_HXX_
4
5 #include "parserBase.hxx"
6 #include "containerParsers.hxx"
7 #include "dataParsers.hxx"
8 #include "portParsers.hxx"
9 #include "codeParsers.hxx"
10 #include "propertyParsers.hxx"
11
12 #include "Proc.hxx"
13 #include "TypeCode.hxx"
14 #include "InlineNode.hxx"
15 #include "ServiceNode.hxx"
16 #include "ServiceInlineNode.hxx"
17 #include "Exception.hxx"
18 #include "Runtime.hxx"
19 #include "OutputDataStreamPort.hxx"
20 #include "InputDataStreamPort.hxx"
21 #include "ComponentInstance.hxx"
22 #include "factory.hxx"
23
24 extern YACS::ENGINE::Proc* currentProc;
25 extern YACS::ENGINE::Runtime* theRuntime;
26
27 namespace YACS
28 {
29
30 /*! \brief Class for node parser.
31  *
32  *  This class is a base class for other parsers
33  */
34 template <class T=YACS::ENGINE::InlineNode*>
35 struct nodetypeParser: parser
36 {
37   static nodetypeParser<T> nodeParser;
38
39   virtual void onStart(const XML_Char* el, const XML_Char** attr)
40     {
41       DEBTRACE( "nodetypeParser::onStart: " << el )             
42       std::string element(el);
43       parser* pp=&parser::main_parser;
44       this->SetUserDataAndPush(pp);
45       pp->init();
46       pp->pre();
47       pp->buildAttr(attr);
48     }
49   virtual void onEnd(const char *el,parser* child)
50     {
51       DEBTRACE( "nodetypeParser::onEnd: " << el )             
52       std::string element(el);
53     }
54   virtual void buildAttr(const XML_Char** attr)
55     {
56       required("name",attr);
57       required("type",attr);
58       for (int i = 0; attr[i]; i += 2) 
59       {
60         if(std::string(attr[i]) == "name")name(attr[i+1]);
61         if(std::string(attr[i]) == "state")state(attr[i+1]);
62         if(std::string(attr[i]) == "type")type(attr[i+1]);
63       }
64     }
65   virtual void pre()
66     {
67       _node=0;
68       _container="";
69     }
70   virtual void name (const std::string& name)
71     {
72       DEBTRACE( "inline_name: " << name )             
73       _name=name;
74     }
75   virtual void state (const std::string& name)
76     {
77       _state=name;
78     }
79   virtual void type (const std::string& name)
80     {
81       DEBTRACE( "node_type " << name )             
82       _type=name;
83     }
84   virtual void property (const myprop& prop);
85   virtual T post();
86   std::string _type;
87   std::string _name;
88   std::string _state;
89   std::string _container;
90   T _node;
91 };
92
93 template <class T> nodetypeParser<T> nodetypeParser<T>::nodeParser;
94
95 template <class T>
96 void nodetypeParser<T>::property (const myprop& prop)
97 {
98   _node->setProperty(prop._name,prop._value);
99 }
100
101 template <class T>
102 T nodetypeParser<T>::post()
103 {
104   return _node;
105 }
106
107 template <>
108 YACS::ENGINE::InlineNode* nodetypeParser<YACS::ENGINE::InlineNode*>::post ()
109 {
110   std::string fullname = currentProc->names.back()+_type;
111   if(currentProc->inlineMap.count(_type) != 0)
112     {
113       //InlineNode type with absolute name found
114       YACS::ENGINE::InlineNode* n=currentProc->inlineMap[_type];
115       _node=n->cloneNode(_name);
116     }
117   else if(currentProc->inlineMap.count(fullname) != 0)
118     {
119       //InlineNode type with relative name found
120       YACS::ENGINE::InlineNode* n=currentProc->inlineMap[fullname];
121       _node=n->cloneNode(_name);
122     }
123   else
124     {
125       throw YACS::Exception("Unknown InlineNode type");
126     }
127   if(_state == "disabled")_node->exDisabledState();
128   DEBTRACE( "node_post " << _node->getName() )             
129   return _node;
130 }
131
132 static std::string t1[]={"script","function",""};
133
134 template <class T=YACS::ENGINE::InlineNode*>
135 struct inlinetypeParser:public nodetypeParser<T>
136 {
137   static inlinetypeParser<T> inlineParser;
138
139   virtual void onStart(const XML_Char* el, const XML_Char** attr);
140   virtual void onEnd(const char *el,parser* child)
141     {
142       DEBTRACE( "inlinetypeParser::onEnd: " << el )             
143       std::string element(el);
144       if(element == "kind")kind(((stringtypeParser*)child)->post());
145       else if(element == "script")script(((codetypeParser*)child)->post());
146       else if(element == "function")function(((functypeParser*)child)->post());
147       else if(element == "property")this->property(((propertytypeParser*)child)->post());
148       else if(element == "inport") inport(((inporttypeParser<myinport>*)child)->post());
149       else if(element == "outport") outport(((outporttypeParser<myoutport>*)child)->post());
150     }
151   virtual void buildAttr(const XML_Char** attr)
152     {
153       this->required("name",attr);
154       for (int i = 0; attr[i]; i += 2) 
155       {
156         if(std::string(attr[i]) == "name")this->name(attr[i+1]);
157         if(std::string(attr[i]) == "state")this->state(attr[i+1]);
158       }
159     }
160   virtual void pre ()
161     {
162       this->_node=0;
163       _kind="";
164       this->_state="";
165       this->_container="";
166     }
167   virtual void kind (const std::string& name)
168     {
169       DEBTRACE( "inline_kind " << name )             
170       _kind=name;
171     }
172
173   virtual void script (const myfunc& f){}
174   virtual void function (const myfunc& f) {}
175
176   virtual void inport (const myinport& p)
177     {
178       DEBTRACE( "inline_inport: " << p._name <<":"<<p._type)             
179       if(this->_node==0)
180         throw YACS::Exception("Node must be completely defined before defining its ports");
181
182       if(currentProc->typeMap.count(p._type)==0)
183       {
184         //Check if the typecode is defined in the runtime
185         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(p._type);
186         if(t==0)
187         {
188           std::string msg="Unknown InPort Type: ";
189           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
190           throw YACS::Exception(msg);
191         }
192         else
193         {
194           currentProc->typeMap[p._type]=t;
195           t->incrRef();
196         }
197       }
198       this->_node->edAddInputPort(p._name,currentProc->typeMap[p._type]);
199     }
200   virtual void outport (const myoutport& p)
201     {
202       DEBTRACE( "inline_outport: " << p._name <<":"<<p._type)             
203       if(this->_node==0)
204         throw YACS::Exception("Node must be completely defined before defining its ports");
205
206       if(currentProc->typeMap.count(p._type)==0)
207       {
208         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(p._type);
209         if(t==0)
210         {
211           std::string msg="Unknown OutPort Type: ";
212           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
213           throw YACS::Exception(msg);
214         }
215         else
216         {
217           currentProc->typeMap[p._type]=t;
218           t->incrRef();
219         }
220       }
221       this->_node->edAddOutputPort(p._name,currentProc->typeMap[p._type]);
222     }
223   virtual T post()
224     {
225       DEBTRACE( "inline_post " << this->_node->getName() )             
226       if(this->_state == "disabled")this->_node->exDisabledState();
227       /*
228       std::list<OutputPort *>::iterator iter;
229       std::list<OutputPort *> s=_node->getSetOfOutputPort();
230       for(iter=s.begin();iter!=s.end();iter++)
231         {
232           std::cerr << "port name: " << (*iter)->getName() << std::endl;
233           std::cerr << "port kind: " << (*iter)->edGetType()->kind() << std::endl;
234         }
235         */
236       return this->_node;
237     }
238   std::string _kind;
239 };
240
241 template <class T> inlinetypeParser<T> inlinetypeParser<T>::inlineParser;
242
243 template <>
244 void inlinetypeParser<YACS::ENGINE::InlineNode*>::script (const myfunc& f)
245 {
246   DEBTRACE( "inline_script: " << f._code )             
247   _node=theRuntime->createScriptNode(_kind,_name);
248   _node->setScript(f._code);
249 }
250
251 template <>
252 void inlinetypeParser<YACS::ENGINE::InlineNode*>::function (const myfunc& f)
253 {
254   DEBTRACE( "inline_function: " << f._code )             
255   YACS::ENGINE::InlineFuncNode *fnode;
256   fnode=theRuntime->createFuncNode(_kind,_name);
257   fnode->setScript(f._code);
258   fnode->setFname(f._name);
259   _node=fnode;
260 }
261
262 /*! \brief Class for parsing ServiceInlineNode description
263  *
264  *  
265  */
266 template <class T=YACS::ENGINE::ServiceInlineNode*>
267 struct sinlinetypeParser:public inlinetypeParser<T>
268 {
269   static sinlinetypeParser<T> sinlineParser;
270
271   virtual void onStart(const XML_Char* el, const XML_Char** attr);
272   virtual void onEnd(const char *el,parser* child)
273     {
274       DEBTRACE( "sinlinetypeParser::onEnd: " << el )             
275       std::string element(el);
276       if(element == "kind")this->kind(((stringtypeParser*)child)->post());
277       else if(element == "function")this->function(((functypeParser*)child)->post());
278       else if(element == "load") load(((loadtypeParser*)child)->post());
279       else if(element == "property")this->property(((propertytypeParser*)child)->post());
280       else if(element == "inport") this->inport(((inporttypeParser<myinport>*)child)->post());
281       else if(element == "outport") this->outport(((outporttypeParser<myoutport>*)child)->post());
282     }
283   //virtual void service (const myfunc& f) {}
284   virtual void load (const loadon& l)
285     {
286       DEBTRACE( "sinline_load: " )             
287       this->_container=l._container;
288     }
289   virtual T post()
290     {
291       DEBTRACE( "sinline_post " << this->_node->getName() );
292       if(this->_state == "disabled")this->_node->exDisabledState();
293
294       if(currentProc->containerMap.count(this->_container) != 0)
295         {
296           this->_node->getComponent()->setContainer(currentProc->containerMap[this->_container]);
297         }
298       else if(this->_container == "")
299         {
300           if(currentProc->containerMap.count("DefaultContainer") != 0)
301           {
302             //a default container is defined : use it
303             this->_node->getComponent()->setContainer(currentProc->containerMap["DefaultContainer"]);
304           }
305         }
306       else
307         {
308           std::cerr << "WARNING: Unknown container " << this->_container << " ignored" << std::endl;
309         }
310
311       return this->_node;
312     }
313 };
314 template <class T> sinlinetypeParser<T> sinlinetypeParser<T>::sinlineParser;
315
316 // sinline ????
317 template <>
318 void inlinetypeParser<YACS::ENGINE::ServiceInlineNode*>::function (const myfunc& f)
319 {
320   DEBTRACE( "sinline_function: " << f._code )             
321   YACS::ENGINE::ServiceInlineNode *fnode;
322   fnode=theRuntime->createSInlineNode(_kind,_name);
323   fnode->setScript(f._code);
324   fnode->setMethod(f._name);
325   fnode->setComponent(theRuntime->createComponentInstance("PyCompo","SalomePy"));
326   //fnode->setRef("PyCompo");
327   _node=fnode;
328 }
329
330 static std::string t2[]={"ref","node","component",""};
331
332 template <class T=YACS::ENGINE::ServiceNode*>
333 struct servicetypeParser:public inlinetypeParser<T>
334 {
335   static servicetypeParser<T> serviceParser;
336
337   virtual void onStart(const XML_Char* el, const XML_Char** attr);
338   virtual void onEnd(const char *el,parser* child)
339     {
340       DEBTRACE( "servicetypeParser::onEnd: " << el )             
341       std::string element(el);
342       if(element == "kind")this->kind(((stringtypeParser*)child)->post());
343       else if(element == "ref") ref(((stringtypeParser*)child)->post());
344       else if(element == "component") component(((stringtypeParser*)child)->post());
345       else if(element == "node") node(((stringtypeParser*)child)->post());
346       else if(element == "method") method(((stringtypeParser*)child)->post());
347       else if(element == "load") load(((loadtypeParser*)child)->post());
348       else if(element == "property")this->property(((propertytypeParser*)child)->post());
349       else if(element == "inport") this->inport(((inporttypeParser<myinport>*)child)->post());
350       else if(element == "outport") this->outport(((outporttypeParser<myoutport>*)child)->post());
351       else if(element == "instream") instream(((inporttypeParser<myinport>*)child)->post());
352       else if(element == "outstream") outstream(((outporttypeParser<myoutport>*)child)->post());
353     }
354   virtual void ref (const std::string& name)
355     {
356       DEBTRACE( "service_ref: " << name )             
357       this->_node=theRuntime->createRefNode(this->_kind,this->_name);
358       this->_node->setRef(name);
359     }
360   virtual void component (const std::string& name)
361     {
362       DEBTRACE( "service_component: " << name )             
363       this->_node=theRuntime->createCompoNode(this->_kind,this->_name);
364       this->_node->setRef(name);
365     }
366   virtual void node (const std::string& name)
367     {
368       DEBTRACE( "service_node: " << name )             
369       std::string fullname = currentProc->names.back()+name;
370       if(currentProc->serviceMap.count(name) != 0)
371         {
372           //ServiceNode with absolute name found
373           YACS::ENGINE::ServiceNode* n=currentProc->serviceMap[name];
374           this->_node =n->createNode(this->_name);
375         }
376       else if(currentProc->serviceMap.count(fullname) != 0)
377         {
378           //ServiceNode with relative name found
379           //TODO: must be a short name (possible only in the same context)
380           YACS::ENGINE::ServiceNode* n=currentProc->serviceMap[fullname];
381           this->_node =n->createNode(this->_name);
382         }
383       else
384         {
385           throw YACS::Exception("Unknown ServiceNode");
386         }
387     }
388
389   virtual void method (const std::string& name)
390     {
391       DEBTRACE( "service_method: " << name )             
392       if(this->_node==0)
393         throw YACS::Exception("ServiceNode must be completely defined before defining its method");
394       if(name == "")
395       {
396         this->logError("a service name must be a non empty string");
397         return;
398       }
399       this->_node->setMethod(name);
400     }
401
402   virtual void load (const loadon& l)
403     {
404       DEBTRACE( "service_load: " );
405       this->_container=l._container;
406     }
407
408   virtual void instream (const myinport& p)
409     {
410       DEBTRACE( "service_instream" )             
411       DEBTRACE( p._type )             
412       DEBTRACE( p._name )             
413       if(this->_node==0)
414         throw YACS::Exception("ServiceNode must be completely defined before defining its ports");
415
416       if(currentProc->typeMap.count(p._type)==0)
417       {
418         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(p._type);
419         if(t==0)
420         {
421           std::string msg="Unknown InStreamPort Type: ";
422           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
423           throw YACS::Exception(msg);
424         }
425         else
426         {
427           currentProc->typeMap[p._type]=t;
428           t->incrRef();
429         }
430       }
431       YACS::ENGINE::InputDataStreamPort* port;
432       port=this->_node->edAddInputDataStreamPort(p._name,currentProc->typeMap[p._type]);
433       // Set all properties for this port
434       std::map<std::string, std::string>::const_iterator pt;
435       for(pt=p._props.begin();pt!=p._props.end();pt++)
436         port->setProperty((*pt).first,(*pt).second);
437     }
438   virtual void outstream (const myoutport& p)
439     {
440       DEBTRACE( "service_outstream" )             
441       DEBTRACE( p._type )             
442       DEBTRACE( p._name )             
443       if(this->_node==0)
444         throw YACS::Exception("ServiceNode must be completely defined before defining its ports");
445
446       if(currentProc->typeMap.count(p._type)==0)
447       {
448         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(p._type);
449         if(t==0)
450         {
451           std::string msg="Unknown OutStreamPort Type: ";
452           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
453           throw YACS::Exception(msg);
454         }
455         else
456         {
457           currentProc->typeMap[p._type]=t;
458           t->incrRef();
459         }
460       }
461       YACS::ENGINE::OutputDataStreamPort* port;
462       port=this->_node->edAddOutputDataStreamPort(p._name,currentProc->typeMap[p._type]);
463       // Set all properties for this port
464       std::map<std::string, std::string>::const_iterator pt;
465       for(pt=p._props.begin();pt!=p._props.end();pt++)
466         port->setProperty((*pt).first,(*pt).second);
467     }
468   virtual T post()
469     {
470       DEBTRACE( "service_post " << this->_node->getName() )             
471       this->mincount("method",1);
472       if(this->_state == "disabled")this->_node->exDisabledState();
473
474       if(currentProc->containerMap.count(this->_container) != 0)
475         {
476           this->_node->getComponent()->setContainer(currentProc->containerMap[this->_container]);
477         }
478       else if(this->_container == "")
479         {
480           if(currentProc->containerMap.count("DefaultContainer") != 0)
481           {
482             //a default container is defined : use it
483             this->_node->getComponent()->setContainer(currentProc->containerMap["DefaultContainer"]);
484           }
485         }
486       else
487         {
488           std::cerr << "WARNING: Unknown container " << this->_container << " ignored" << std::endl;
489         }
490       return this->_node;
491     }
492 };
493
494 template <class T> servicetypeParser<T> servicetypeParser<T>::serviceParser;
495
496 }
497
498
499 namespace YACS
500 {
501 template <class T>
502 void inlinetypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
503
504     {
505       DEBTRACE( "inlinetypeParser::onStart: " << el )
506       std::string element(el);
507       parser* pp=&parser::main_parser;
508       this->maxcount("kind",1,element);
509       this->maxcount("script",1,element);
510       this->maxcount("function",1,element);
511       this->maxchoice(t1,1,element);
512       if(element == "kind")pp=&stringtypeParser::stringParser;
513       else if(element == "script")pp=&codetypeParser::codeParser;
514       else if(element == "function")pp=&functypeParser::funcParser;
515       else if(element == "property")pp=&propertytypeParser::propertyParser;
516       else if(element == "inport")pp=&inporttypeParser<>::inportParser;
517       else if(element == "outport")pp=&outporttypeParser<>::outportParser;
518       this->SetUserDataAndPush(pp);
519       pp->init();
520       pp->pre();
521       pp->buildAttr(attr);
522     }
523
524 template <class T>
525 void sinlinetypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
526     {
527       DEBTRACE( "sinlinetypeParser::onStart: " << el )
528       std::string element(el);
529       parser* pp=&parser::main_parser;
530       this->maxcount("kind",1,element);
531       this->maxcount("function",1,element);
532       this->maxcount("load",1,element);
533       if(element == "kind")pp=&stringtypeParser::stringParser;
534       else if(element == "function")pp=&functypeParser::funcParser;
535       else if(element == "load")pp=&loadtypeParser::loadParser;
536       else if(element == "property")pp=&propertytypeParser::propertyParser;
537       else if(element == "inport")pp=&inporttypeParser<>::inportParser;
538       else if(element == "outport")pp=&outporttypeParser<>::outportParser;
539       this->SetUserDataAndPush(pp);
540       pp->init();
541       pp->pre();
542       pp->buildAttr(attr);
543     }
544
545 template <class T>
546 void servicetypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
547     {
548       DEBTRACE( "servicetypeParser::onStart: " << el )
549       std::string element(el);
550       parser* pp=&parser::main_parser;
551       this->maxcount("kind",1,element);
552       this->maxcount("ref",1,element);
553       this->maxcount("node",1,element);
554       this->maxcount("component",1,element);
555       this->maxcount("method",1,element);
556       this->maxcount("load",1,element);
557       this->maxchoice(t2,1,element);
558       if(element == "kind")pp=&stringtypeParser::stringParser;
559       else if(element == "ref")pp=&stringtypeParser::stringParser;
560       else if(element == "component")pp=&stringtypeParser::stringParser;
561       else if(element == "node")pp=&stringtypeParser::stringParser;
562       else if(element == "method")pp=&stringtypeParser::stringParser;
563       else if(element == "load")pp=&loadtypeParser::loadParser;
564       else if(element == "property")pp=&propertytypeParser::propertyParser;
565       else if(element == "inport")pp=&inporttypeParser<>::inportParser;
566       else if(element == "outport")pp=&outporttypeParser<>::outportParser;
567       else if(element == "instream")pp=&inporttypeParser<>::inportParser;
568       else if(element == "outstream")pp=&outporttypeParser<>::outportParser;
569       this->SetUserDataAndPush(pp);
570       pp->init();
571       pp->pre();
572       pp->buildAttr(attr);
573     }
574
575
576
577
578 }
579
580 #endif