Salome HOME
[EDF30062] and [EDF30014] : addition of --activate-custom-overrides parameter in...
[modules/yacs.git] / src / yacsloader / serverParsers.hxx
1 // Copyright (C) 2006-2024  CEA, EDF
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 _SERVERPARSERS_HXX_
21 #define _SERVERPARSERS_HXX_
22
23 #include "ServerNode.hxx"
24
25 extern YACS::ENGINE::Proc* currentProc;
26 extern YACS::ENGINE::Runtime* theRuntime;
27
28 namespace YACS
29 {
30
31 static std::string t22[]={"ref","node","component","componentinstance",""};
32
33 template <class T=YACS::ENGINE::ServerNode*>
34 struct servertypeParser:public inlinetypeParser<T>
35 {
36   static servertypeParser<T> serverParser;
37
38   virtual void onStart(const XML_Char* el, const XML_Char** attr);
39   virtual void onEnd(const char *el,parser* child)
40     {
41       DEBTRACE( "servertypeParser::onEnd: " << el )             
42       std::string element(el);
43       if(element == "kind")this->kind(((stringtypeParser*)child)->post());
44       else if(element == "loadcontainer") loadcontainer(((stringtypeParser*)child)->post());
45       //else if(element == "loadcontainerinstance") containerinstance(((stringtypeParser*)child)->post());
46       else if(element == "script") script(((codetypeParser*)child)->post());
47       else if(element == "node") node(((stringtypeParser*)child)->post());
48       else if(element == "method") method(((stringtypeParser*)child)->post());
49       else if(element == "load") load(((loadtypeParser*)child)->post());
50       else if(element == "property")this->property(((propertytypeParser*)child)->post());
51       else if(element == "inport") this->inport(((inporttypeParser<myinport>*)child)->post());
52       else if(element == "outport") this->outport(((outporttypeParser<myoutport>*)child)->post());
53       else if(element == "instream") instream(((inporttypeParser<myinport>*)child)->post());
54       else if(element == "outstream") outstream(((outporttypeParser<myoutport>*)child)->post());
55     }
56
57   /*virtual void containerinstance (const std::string& name)
58     {
59       DEBTRACE( "componentinstance: " << name )             
60       if(currentProc->componentInstanceMap.count(name) == 0)
61         throw YACS::Exception("Unknown ComponentInstance: "+name);
62       this->_node=theRuntime->createCompoNode(this->_kind,this->_name);
63       YACS::ENGINE::ComponentInstance* inst=currentProc->componentInstanceMap[name];
64       this->_node->setComponent(inst);
65       }*/
66
67   virtual void loadcontainer (const std::string& name)
68     {
69       DEBTRACE( "server_loadcontainer: " << name )             
70       this->_node=(YACS::ENGINE::ServerNode*)theRuntime->createFuncNode("DistPython",this->_name);
71       std::map<std::string,YACS::ENGINE::Container *>::const_iterator it(currentProc->containerMap.find(name));
72       if(it!=currentProc->containerMap.end())
73         {
74           this->_node->setContainer((*it).second);
75         }
76       else
77         {
78           YACS::ENGINE::Container *cont=currentProc->createContainer(this->_node->getEffectiveKindOfServer());
79           cont->setName(name);
80           this->_node->setContainer(cont);
81           cont->decrRef();
82         }
83     }
84   virtual void script (const myfunc& f)
85   {
86     DEBTRACE( "server_script: " << f._code )
87     this->_node->setScript(f._code);
88   }
89   virtual void node (const std::string& name)
90     {
91       DEBTRACE( "server_node: " << name )             
92       std::string fullname = currentProc->names.back()+name;
93       if(currentProc->inlineMap.count(name) != 0)
94         {
95           //ServerNode with absolute name found
96           YACS::ENGINE::ServerNode* n=(YACS::ENGINE::ServerNode*)currentProc->inlineMap[name];
97           this->_node =n->createNode(this->_name);
98         }
99       else if(currentProc->inlineMap.count(fullname) != 0)
100         {
101           //ServerNode with relative name found
102           //TODO: must be a short name (possible only in the same context)
103           YACS::ENGINE::ServerNode* n=(YACS::ENGINE::ServerNode*)currentProc->inlineMap[fullname];
104           this->_node =n->createNode(this->_name);
105         }
106       else
107         {
108           throw YACS::Exception("Unknown ServerNode");
109         }
110     }
111
112   virtual void method (const std::string& name)
113     {
114       DEBTRACE( "server_method: " << name )             
115       if(this->_node==0)
116         throw YACS::Exception("ServerNode must be completely defined before defining its method");
117       if(name == "")
118       {
119         this->logError("a server name must be a non empty string");
120         return;
121       }
122       this->_node->setFname(name);
123     }
124
125   virtual void load (const loadon& l)
126     {
127       DEBTRACE( "server_load: " << l._container);
128       this->_container=l._container;
129     }
130
131   virtual void instream (const myinport& p)
132     {
133       DEBTRACE( "server_instream" )             
134       DEBTRACE( p._type )             
135       DEBTRACE( p._name )             
136       if(this->_node==0)
137         throw YACS::Exception("ServerNode must be completely defined before defining its ports");
138
139       if(currentProc->typeMap.count(p._type)==0)
140       {
141         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(p._type);
142         if(t==0)
143         {
144           std::string msg="Unknown InStreamPort Type: ";
145           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
146           throw YACS::Exception(msg);
147         }
148         else
149         {
150           currentProc->typeMap[p._type]=t;
151           t->incrRef();
152         }
153       }
154       YACS::ENGINE::InputDataStreamPort* port;
155       port=this->_node->edAddInputDataStreamPort(p._name,currentProc->typeMap[p._type]);
156       // Set all properties for this port
157       std::map<std::string, std::string>::const_iterator pt;
158       for(pt=p._props.begin();pt!=p._props.end();pt++)
159         port->setProperty((*pt).first,(*pt).second);
160     }
161   virtual void outstream (const myoutport& p)
162     {
163       DEBTRACE( "server_outstream" )             
164       DEBTRACE( p._type )             
165       DEBTRACE( p._name )             
166       if(this->_node==0)
167         throw YACS::Exception("ServerNode must be completely defined before defining its ports");
168
169       if(currentProc->typeMap.count(p._type)==0)
170       {
171         YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(p._type);
172         if(t==0)
173         {
174           std::string msg="Unknown OutStreamPort Type: ";
175           msg=msg+p._type+" for node: "+this->_node->getName()+" port name: "+p._name;
176           throw YACS::Exception(msg);
177         }
178         else
179         {
180           currentProc->typeMap[p._type]=t;
181           t->incrRef();
182         }
183       }
184       YACS::ENGINE::OutputDataStreamPort* port;
185       port=this->_node->edAddOutputDataStreamPort(p._name,currentProc->typeMap[p._type]);
186       // Set all properties for this port
187       std::map<std::string, std::string>::const_iterator pt;
188       for(pt=p._props.begin();pt!=p._props.end();pt++)
189         port->setProperty((*pt).first,(*pt).second);
190     }
191   virtual T post()
192     {
193       DEBTRACE( "server_post " << this->_node->getName() )             
194       this->mincount("method",1);
195       if(this->_state == "disabled")this->_node->exDisabledState();
196
197       // If the server node has no component instance don't go further return the node
198       if(!this->_node->getComponent())
199         return this->_node;
200       
201       // when container is not defined by <load container="xxx"/> but indirectly by <node>xxx</node>
202       // this->_container is not set, and there is no need to setContainer 
203       // so stop here and return the node
204       if(this->_node->getComponent()->getContainer())
205         return this->_node;
206
207       //If the component instance is anonymous set the container
208       // with the load directive or with the DefaultContainer
209       if(this->_node->getComponent()->isAnonymous())
210         {
211           if(currentProc->containerMap.count(this->_container) != 0)
212             this->_node->getComponent()->setContainer(currentProc->containerMap[this->_container]);
213           else if(this->_container == "" && currentProc->containerMap.count("DefaultContainer") != 0)
214             {
215               //a default container is defined : use it if supported
216               try
217                 {
218                   currentProc->containerMap["DefaultContainer"]->checkCapabilityToDealWith(this->_node->getComponent());
219                   this->_node->getComponent()->setContainer(currentProc->containerMap["DefaultContainer"]);
220                 }
221               catch(YACS::Exception)
222                 {}
223             }
224           else
225             std::cerr << "WARNING: Unknown container " << this->_container << " ignored" << std::endl;
226         }
227       return this->_node;
228     }
229 };
230
231 template <class T> servertypeParser<T> servertypeParser<T>::serverParser;
232
233
234 template <class T>
235 void servertypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
236     {
237       DEBTRACE( "servertypeParser::onStart: " << el )
238       std::string element(el);
239       parser* pp=&parser::main_parser;
240       this->maxcount("kind",1,element);
241       this->maxcount("ref",1,element);
242       this->maxcount("node",1,element);
243       this->maxcount("component",1,element);
244       this->maxcount("componentinstance",1,element);
245       this->maxcount("loadcontainer",1,element);
246       this->maxcount("script",1,element);
247       this->maxcount("method",1,element);
248       this->maxcount("load",1,element);
249       this->maxchoice(t22,1,element);
250       if(element == "kind")pp=&stringtypeParser::stringParser;
251       else if(element == "ref")pp=&stringtypeParser::stringParser;
252       else if(element == "component")pp=&stringtypeParser::stringParser;
253       else if(element == "componentinstance")pp=&stringtypeParser::stringParser;
254       else if(element == "loadcontainer")pp=&stringtypeParser::stringParser;
255       else if(element == "script")pp=&codetypeParser::codeParser;
256       else if(element == "node")pp=&stringtypeParser::stringParser;
257       else if(element == "method")pp=&stringtypeParser::stringParser;
258       else if(element == "load")pp=&loadtypeParser::loadParser;
259       else if(element == "property")pp=&propertytypeParser::propertyParser;
260       else if(element == "inport")pp=&inporttypeParser<>::inportParser;
261       else if(element == "outport")pp=&outporttypeParser<>::outportParser;
262       else if(element == "instream")pp=&inporttypeParser<>::inportParser;
263       else if(element == "outstream")pp=&outporttypeParser<>::outportParser;
264       this->SetUserDataAndPush(pp);
265       pp->init();
266       pp->pre();
267       pp->buildAttr(attr);
268     }
269
270 } // end of namespace YACS
271
272 #endif