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