1 // Copyright (C) 2006-2015 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
21 #include "ElementaryNode.hxx"
22 #include "Runtime.hxx"
23 #include "Container.hxx"
24 #include "ComponentInstance.hxx"
25 #include "InputPort.hxx"
26 #include "OutputPort.hxx"
27 #include "TypeCode.hxx"
29 #include "Visitor.hxx"
30 #include "VisitorSaveSchema.hxx"
31 #include "VisitorSaveState.hxx"
36 #include "YacsTrace.hxx"
39 using namespace YACS::ENGINE;
41 /*! \class YACS::ENGINE::Proc
42 * \brief Base class for all schema objects.
44 * This is an abstract class that must be specialized in runtime.
48 Proc::Proc(const std::string& name):Bloc(name),_edition(false),_compoinstctr(0)
50 Runtime *theRuntime=getRuntime();
51 DEBTRACE("theRuntime->_tc_double->ref: " << theRuntime->_tc_double->getRefCnt());
52 DEBTRACE("theRuntime->_tc_int->ref: " << theRuntime->_tc_int->getRefCnt());
53 DEBTRACE("theRuntime->_tc_string->ref: " << theRuntime->_tc_string->getRefCnt());
54 DEBTRACE("theRuntime->_tc_bool->ref: " << theRuntime->_tc_bool->getRefCnt());
55 DEBTRACE("theRuntime->_tc_file->ref: " << theRuntime->_tc_file->getRefCnt());
56 theRuntime->_tc_double->incrRef();
57 theRuntime->_tc_string->incrRef();
58 theRuntime->_tc_int->incrRef();
59 theRuntime->_tc_bool->incrRef();
60 theRuntime->_tc_file->incrRef();
61 typeMap["double"]=theRuntime->_tc_double;
62 typeMap["string"]=theRuntime->_tc_string;
63 typeMap["int"]=theRuntime->_tc_int;
64 typeMap["bool"]=theRuntime->_tc_bool;
65 typeMap["file"]=theRuntime->_tc_file;
70 DEBTRACE("Proc::~Proc");
71 //for the moment all nodes are owned, so no need to manage their destruction
72 //nodeMap, inlineMap, serviceMap will be cleared automatically
73 //but we need to destroy TypeCodes
74 std::map<std::string, TypeCode *>::iterator pt;
75 for(pt=typeMap.begin();pt!=typeMap.end();pt++)
76 ((*pt).second)->decrRef();
80 //get rid of loggers in logger map
81 std::map<std::string, Logger*>::const_iterator lt;
82 for(lt=_loggers.begin();lt!=_loggers.end();lt++)
86 void Proc::writeDot(std::ostream &os) const
88 os << "digraph " << getQualifiedName() << " {\n" ;
89 os << "node [ style=\"filled\" ];\n" ;
90 os << "compound=true;";
91 os << "states [label=< <TABLE> <TR> <TD BGCOLOR=\"pink\" > Ready</TD> <TD BGCOLOR=\"magenta\" > Toload</TD> </TR> <TR> <TD BGCOLOR=\"magenta\" > Loaded</TD> <TD BGCOLOR=\"purple\" > Toactivate</TD> </TR> <TR> <TD BGCOLOR=\"blue\" > Activated</TD> <TD BGCOLOR=\"green\" > Done</TD> </TR> <TR> <TD BGCOLOR=\"red\" > Error</TD> <TD BGCOLOR=\"orange\" > Failed</TD> </TR> <TR> <TD BGCOLOR=\"grey\" > Disabled</TD> <TD BGCOLOR=\"white\" > Pause</TD> </TR> </TABLE>> \n shape = plaintext \n style = invis \n ];\n";
97 std::ostream& operator<< (std::ostream& os, const Proc& p)
103 TypeCode *Proc::createType(const std::string& name, const std::string& kind)
107 t=getRuntime()->_tc_double;
108 else if(kind=="string")
109 t=getRuntime()->_tc_string;
111 t=getRuntime()->_tc_int;
112 else if(kind=="bool")
113 t=getRuntime()->_tc_bool;
115 throw Exception("Unknown kind");
117 if(typeMap.count(name)!=0)
118 typeMap[name]->decrRef();
125 //! Create an object reference TypeCode
127 * \param id: the TypeCode repository id
128 * \param name: the TypeCode name
129 * \param ltc: a liste of object reference TypeCode to use as base types for this type
130 * \return the created TypeCode
132 TypeCode *Proc::createInterfaceTc(const std::string& id, const std::string& name,
133 std::list<TypeCodeObjref *> ltc)
135 TypeCode* t = TypeCode::interfaceTc(id.c_str(),name.c_str(),ltc);
136 if(typeMap.count(name)!=0)
137 typeMap[name]->decrRef();
143 //! Create a sequence TypeCode
145 * \param id: the TypeCode repository id ("" for normal use)
146 * \param name: the TypeCode name
147 * \param content: the element TypeCode
148 * \return the created TypeCode
150 TypeCode * Proc::createSequenceTc (const std::string& id, const std::string& name,
153 TypeCode* t = TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
154 if(typeMap.count(name)!=0)
155 typeMap[name]->decrRef();
161 TypeCode * Proc::createStructTc (const std::string& id, const std::string& name)
163 TypeCode* t = TypeCode::structTc(id.c_str(),name.c_str());
164 if(typeMap.count(name)!=0)
165 typeMap[name]->decrRef();
171 TypeCode * Proc::getTypeCode (const std::string& name)
174 if(typeMap.count(name)==0)
175 aTC=getRuntime()->getTypeCode(name);
181 std::stringstream msg;
182 msg << "Type " << name << " does not exist" ;
183 msg << " (" <<__FILE__ << ":" << __LINE__ << ")";
184 throw Exception(msg.str());
190 void Proc::setTypeCode (const std::string& name,TypeCode *t)
192 if(typeMap.count(name)!=0)
193 typeMap[name]->decrRef();
199 void Proc::accept(Visitor *visitor)
201 visitor->visitProc(this);
204 void Proc::setName(const std::string& name)
209 YACS::StatesForNode Proc::getNodeState(int numId)
211 if(YACS::ENGINE::Node::idMap.count(numId) == 0)
213 cerr << "Unknown node id " << numId << endl;
214 return YACS::UNDEFINED;
216 YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[numId];
217 YACS::StatesForNode state = node->getEffectiveState();
221 std::string Proc::getNodeProgress(int numId)
223 std::string progress = "0";
224 if(YACS::ENGINE::Node::idMap.count(numId) == 0)
226 cerr << "Unknown node id " << numId << endl;
228 else if (YACS::ENGINE::ComposedNode* node = dynamic_cast<YACS::ENGINE::ComposedNode*>(YACS::ENGINE::Node::idMap[numId]))
229 progress = node->getProgress();
233 int Proc::getGlobalProgressPercent()
235 list<ProgressWeight> weightList = getProgressWeight();
238 int progressPercent = 0;
239 for(list<ProgressWeight>::const_iterator iter=weightList.begin();iter!=weightList.end();iter++)
241 weightDone += (*iter).weightDone;
242 weightTotal += (*iter).weightTotal;
245 progressPercent = int(float(weightDone) / float(weightTotal) * 100);
246 return progressPercent;
249 std::string Proc::getXMLState(int numId)
251 if(YACS::ENGINE::Node::idMap.count(numId) == 0)
253 cerr << "Unknown node id " << numId << endl;
254 return "<state>unknown</state>";
256 YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[numId];
258 msg << "<state>" << node->getEffectiveState() << "</state>";
259 msg << "<name>" << node->getQualifiedName() << "</name>";
260 msg << "<id>" << numId << "</id>";
264 std::string Proc::getInPortValue(int nodeNumId, std::string portName)
266 DEBTRACE("Proc::getInPortValue " << nodeNumId << " " << portName);
268 if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
270 msg << "<value><error>unknown node id: " << nodeNumId << "</error></value>";
275 YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
276 InputPort * inputPort = node->getInputPort(portName);
277 return inputPort->getAsString();
279 catch(YACS::Exception& ex)
281 DEBTRACE("Proc::getInPortValue " << ex.what());
282 msg << "<value><error>" << ex.what() << "</error></value>";
287 std::string Proc::setInPortValue(std::string nodeName, std::string portName, std::string value)
289 DEBTRACE("Proc::setInPortValue " << nodeName << " " << portName << " " << value);
293 YACS::ENGINE::Node* node = YACS::ENGINE::Proc::nodeMap[nodeName];
294 YACS::ENGINE::InputPort* inputPort = node->getInputPort(portName);
296 switch (inputPort->edGetType()->kind())
300 double val = atof(value.c_str());
301 inputPort->edInit(val);
305 int val = atoi(value.c_str());
306 inputPort->edInit(val);
309 inputPort->edInit(value.c_str());
312 bool val = (! value.compare("False") ) && (! value.compare("0") );
313 inputPort->edInit(val);
316 DEBTRACE("Proc::setInPortValue: filtered type: " << inputPort->edGetType()->kind());
320 catch(YACS::Exception& ex)
322 DEBTRACE("Proc::setInPortValue " << ex.what());
324 msg << "<value><error>" << ex.what() << "</error></value>";
329 std::string Proc::getOutPortValue(int nodeNumId, std::string portName)
331 DEBTRACE("Proc::getOutPortValue " << nodeNumId << " " << portName);
333 if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
335 msg << "<value><error>unknown node id: " << nodeNumId << "</error></value>";
340 YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
341 OutputPort * outputPort = node->getOutputPort(portName);
342 return outputPort->getAsString();
344 catch(YACS::Exception& ex)
346 DEBTRACE("Proc::getOutPortValue " << ex.what());
347 msg << "<value><error>" << ex.what() << "</error></value>";
352 std::string Proc::getNodeErrorDetails(int nodeNumId)
354 DEBTRACE("Proc::getNodeErrorDetails " << nodeNumId);
356 if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
358 msg << "Unknown node id " << nodeNumId;
361 YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
362 return node->getErrorDetails();
365 std::string Proc::getNodeErrorReport(int nodeNumId)
367 DEBTRACE("Proc::getNodeErrorReport " << nodeNumId);
369 if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
371 msg << "Unknown node id " << nodeNumId;
374 YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
375 return node->getErrorReport();
378 std::string Proc::getNodeContainerLog(int nodeNumId)
380 DEBTRACE("Proc::getNodeContainerLog " << nodeNumId);
382 if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
384 msg << "Unknown node id " << nodeNumId;
387 YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
388 return node->getContainerLog();
391 std::list<int> Proc::getNumIds()
393 list<YACS::ENGINE::Node *> nodes = getAllRecursiveConstituents();
394 int len = nodes.size();
396 for( list<YACS::ENGINE::Node *>::const_iterator iter = nodes.begin();
397 iter != nodes.end(); iter++)
399 numids.push_back((*iter)->getNumId());
401 numids.push_back(this->getNumId());
405 std::list<std::string> Proc::getIds()
407 list<YACS::ENGINE::Node *> nodes = getAllRecursiveConstituents();
408 int len = nodes.size();
410 for( list<YACS::ENGINE::Node *>::const_iterator iter = nodes.begin();
411 iter != nodes.end(); iter++)
413 ids.push_back(getChildName(*iter));
415 ids.push_back("_root_");
419 Logger *Proc::getLogger(const std::string& name)
422 LoggerMap::const_iterator it = _loggers.find(name);
424 if (it != _loggers.end())
430 logger = new Logger(name);
431 _loggers[name]=logger;
436 void Proc::setEdition(bool edition)
438 DEBTRACE("Proc::setEdition: " << edition);
443 //! Sets Proc in modified state and update state if in edition mode
447 void Proc::modified()
449 DEBTRACE("Proc::modified() " << _edition);
455 //! Save Proc in XML schema file
457 * \param xmlSchemaFile: the file name
459 void Proc::saveSchema(const std::string& xmlSchemaFile)
461 VisitorSaveSchema vss(this);
462 vss.openFileSchema(xmlSchemaFile);
464 vss.closeFileSchema();
467 //! Save Proc state in XML state file
469 * \param xmlStateFile: the file name
471 void Proc::saveState(const std::string& xmlStateFile)
473 VisitorSaveState vst(this);
474 vst.openFileDump(xmlStateFile);
479 void Proc::removeContainers()
481 //get rid of containers in container map
482 std::map<std::string, Container*>::const_iterator it;
483 for(it=containerMap.begin();it!=containerMap.end();it++)
484 ((*it).second)->decrRef();
485 containerMap.clear();
488 //! Create a new Container and store it in containerMap
490 * \param name: the container name and key in containerMap
491 * \param kind: the container kind (depends on runtime)
492 * \return the created Container
494 Container *Proc::createContainer(const std::string& name, const std::string& kind)
496 Container *co(getRuntime()->createContainer(kind));
498 if(containerMap.count(name)!=0)
499 containerMap[name]->decrRef();
500 containerMap[name]=co;
506 //! Add a ComponentInstance into componentInstanceMap
508 * If the name == "", the component instance is automatically named with a unique (in the Proc) name
510 * \param inst: the component instance
511 * \param name: the component instance name
512 * \param resetCtr: try to reuse instance number previously released, false by default
514 void Proc::addComponentInstance(ComponentInstance* inst, const std::string& name, bool resetCtr)
519 inst->setAnonymous(false);
520 if(componentInstanceMap.count(name)!=0)
521 componentInstanceMap[name]->decrRef();
522 componentInstanceMap[name]=inst;
527 //automatic naming : componame_<_compoinstctr>
528 std::string instname;
529 std::string componame=inst->getCompoName();
534 std::ostringstream buffer;
535 buffer << ++_compoinstctr;
536 instname=componame+"_"+buffer.str();
537 if(componentInstanceMap.count(instname)==0)
539 inst->setName(instname);
540 componentInstanceMap[instname]=inst;
548 //! Remove a componentInstance from the componentInstanceMap
550 * To be used for a componentInstance with no service nodes referenced.
552 * \param inst: the component instance
554 void Proc::removeComponentInstance(ComponentInstance* inst)
556 if (componentInstanceMap.count(inst->getInstanceName()))
558 componentInstanceMap.erase(inst->getInstanceName());
563 //! Remove a container from the containerMap
565 * To be used for a container with no componentInstance referenced.
567 * \param cont: the container
569 void Proc::removeContainer(Container* cont)
571 if (containerMap.count(cont->getName()))
573 containerMap.erase(cont->getName());
578 //! Create a new ComponentInstance and add it into componentInstanceMap
580 * If the name == "", the component instance is automatically named with a unique (in the Proc) name
582 * \param componame: the component name
583 * \param name: the component instance name
584 * \param kind: the component instance kind (depends on runtime)
585 * \return the created ComponentInstance
587 ComponentInstance* Proc::createComponentInstance(const std::string& componame, const std::string& name,const std::string& kind)
589 ComponentInstance* inst= getRuntime()->createComponentInstance(componame,kind);
590 addComponentInstance(inst,name);
594 //! Return the proc (this)
595 Proc* Proc::getProc()
600 //! Return the proc (this)
601 const Proc * Proc::getProc() const
607 * This method is useful if this has been modified recursively and an update is needed between all the
608 * containers and components refered by children and little children and maps.
610 void Proc::updateContainersAndComponents()
612 std::map<std::string, Container*> myContainerMap;
613 std::map<std::string, ComponentInstance*> myComponentInstanceMap;
614 DeploymentTree treeToDup(getDeploymentTree());
615 vector<Container *> conts(treeToDup.getAllContainers());
616 for(vector<Container *>::const_iterator iterCt=conts.begin();iterCt!=conts.end();iterCt++)
618 Container *tmp(*iterCt);
621 if(myContainerMap.find(tmp->getName())!=myContainerMap.end())
623 std::ostringstream oss; oss << "Proc::updateContainersAndComponents : more than one container instance with name \"" << tmp->getName() << "\" !";
624 throw YACS::Exception(oss.str());
626 myContainerMap[tmp->getName()]=tmp;
629 vector<ComponentInstance *> comps=treeToDup.getComponentsLinkedToContainer(*iterCt);
630 for(vector<ComponentInstance *>::iterator iterCp=comps.begin();iterCp!=comps.end();iterCp++)
632 ComponentInstance *tmp2(*iterCp);
635 if(myComponentInstanceMap.find(tmp2->getCompoName())!=myComponentInstanceMap.end())
637 std::ostringstream oss; oss << "Proc::updateContainersAndComponents : more than one component instance with name \"" << tmp2->getCompoName() << "\" !";
638 throw YACS::Exception(oss.str());
641 myComponentInstanceMap[tmp2->getCompoName()]=tmp2;
646 containerMap=myContainerMap;
647 componentInstanceMap=myComponentInstanceMap;