1 // Copyright (C) 2006-2016 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #ifndef _SERVICEPARSERS_HXX_
21 #define _SERVICEPARSERS_HXX_
23 #include "parserBase.hxx"
24 #include "containerParsers.hxx"
25 #include "dataParsers.hxx"
26 #include "portParsers.hxx"
27 #include "codeParsers.hxx"
28 #include "propertyParsers.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"
43 extern YACS::ENGINE::Proc* currentProc;
44 extern YACS::ENGINE::Runtime* theRuntime;
49 static std::string t2[]={"ref","node","component","componentinstance",""};
51 template <class T=YACS::ENGINE::ServiceNode*>
52 struct servicetypeParser:public inlinetypeParser<T>
54 static servicetypeParser<T> serviceParser;
56 virtual void onStart(const XML_Char* el, const XML_Char** attr);
57 virtual void onEnd(const char *el,parser* child)
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());
74 virtual void ref (const std::string& name)
76 DEBTRACE( "service_ref: " << name )
77 this->_node=theRuntime->createRefNode(this->_kind,this->_name);
78 this->_node->setRef(name);
81 virtual void componentinstance (const std::string& name)
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);
91 virtual void component (const std::string& name)
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);
99 virtual void node (const std::string& name)
101 DEBTRACE( "service_node: " << name )
102 std::string fullname = currentProc->names.back()+name;
103 if(currentProc->serviceMap.count(name) != 0)
105 //ServiceNode with absolute name found
106 YACS::ENGINE::ServiceNode* n=currentProc->serviceMap[name];
107 this->_node =n->createNode(this->_name);
109 else if(currentProc->serviceMap.count(fullname) != 0)
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);
118 throw YACS::Exception("Unknown ServiceNode");
122 virtual void method (const std::string& name)
124 DEBTRACE( "service_method: " << name )
126 throw YACS::Exception("ServiceNode must be completely defined before defining its method");
129 this->logError("a service name must be a non empty string");
132 this->_node->setMethod(name);
135 virtual void load (const loadon& l)
137 DEBTRACE( "service_load: " << l._container);
138 this->_container=l._container;
141 virtual void instream (const myinport& p)
143 DEBTRACE( "service_instream" )
147 throw YACS::Exception("ServiceNode must be completely defined before defining its ports");
149 if(currentProc->typeMap.count(p._type)==0)
151 YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(p._type);
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);
160 currentProc->typeMap[p._type]=t;
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);
171 virtual void outstream (const myoutport& p)
173 DEBTRACE( "service_outstream" )
177 throw YACS::Exception("ServiceNode must be completely defined before defining its ports");
179 if(currentProc->typeMap.count(p._type)==0)
181 YACS::ENGINE::TypeCode* t=theRuntime->getTypeCode(p._type);
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);
190 currentProc->typeMap[p._type]=t;
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);
203 DEBTRACE( "service_post " << this->_node->getName() )
204 this->mincount("method",1);
205 if(this->_state == "disabled")this->_node->exDisabledState();
207 // If the service node has no component instance don't go further return the node
208 if(!this->_node->getComponent())
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())
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())
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)
225 //a default container is defined : use it if supported
228 currentProc->containerMap["DefaultContainer"]->checkCapabilityToDealWith(this->_node->getComponent());
229 this->_node->getComponent()->setContainer(currentProc->containerMap["DefaultContainer"]);
231 catch(YACS::Exception)
235 std::cerr << "WARNING: Unknown container " << this->_container << " ignored" << std::endl;
241 template <class T> servicetypeParser<T> servicetypeParser<T>::serviceParser;
244 void servicetypeParser<T>::onStart(const XML_Char* el, const XML_Char** attr)
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);
275 } // end of namespace YACS