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