]> SALOME platform Git repositories - modules/yacs.git/blob - src/engine/Proc.cxx
Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / engine / Proc.cxx
1 //  Copyright (C) 2006-2008  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 #include "Proc.hxx"
20 #include "ElementaryNode.hxx"
21 #include "Runtime.hxx"
22 #include "Container.hxx"
23 #include "InputPort.hxx"
24 #include "OutputPort.hxx"
25 #include "TypeCode.hxx"
26 #include "Logger.hxx"
27 #include "Visitor.hxx"
28 #include "VisitorSaveSchema.hxx"
29 #include "VisitorSaveState.hxx"
30 #include <sstream>
31 #include <set>
32
33 //#define _DEVDEBUG_
34 #include "YacsTrace.hxx"
35
36 using namespace std;
37 using namespace YACS::ENGINE;
38
39 Proc::Proc(const std::string& name):Bloc(name),_edition(false)
40 {
41   Runtime *theRuntime=getRuntime();
42   DEBTRACE("theRuntime->_tc_double->ref: " << theRuntime->_tc_double->getRefCnt());
43   DEBTRACE("theRuntime->_tc_int->ref: " << theRuntime->_tc_int->getRefCnt());
44   DEBTRACE("theRuntime->_tc_string->ref: " << theRuntime->_tc_string->getRefCnt());
45   DEBTRACE("theRuntime->_tc_bool->ref: " << theRuntime->_tc_bool->getRefCnt());
46   DEBTRACE("theRuntime->_tc_file->ref: " << theRuntime->_tc_file->getRefCnt());
47   theRuntime->_tc_double->incrRef();
48   theRuntime->_tc_string->incrRef();
49   theRuntime->_tc_int->incrRef();
50   theRuntime->_tc_bool->incrRef();
51   theRuntime->_tc_file->incrRef();
52   typeMap["double"]=theRuntime->_tc_double;
53   typeMap["string"]=theRuntime->_tc_string;
54   typeMap["int"]=theRuntime->_tc_int;
55   typeMap["bool"]=theRuntime->_tc_bool;
56   typeMap["file"]=theRuntime->_tc_file;
57 }
58
59 Proc::~Proc()
60 {
61   DEBTRACE("Proc::~Proc");
62   //for the moment all nodes are owned, so no need to manage their destruction
63   //nodeMap, inlineMap, serviceMap will be cleared automatically
64   //but we need to destroy TypeCodes
65   std::map<std::string, TypeCode *>::iterator pt;
66   for(pt=typeMap.begin();pt!=typeMap.end();pt++)
67     ((*pt).second)->decrRef();
68
69   //get rid of containers in container map
70   std::map<std::string, Container*>::const_iterator it;
71   for(it=containerMap.begin();it!=containerMap.end();it++)
72     ((*it).second)->decrRef();
73
74   //get rid of loggers in logger map
75   std::map<std::string, Logger*>::const_iterator lt;
76   for(lt=_loggers.begin();lt!=_loggers.end();lt++)
77     delete (*lt).second;
78 }
79
80 void Proc::writeDot(std::ostream &os) const
81 {
82   os << "digraph " << getQualifiedName() << " {\n" ;
83   os << "node [ style=\"filled\" ];\n" ;
84   os << "compound=true;";
85   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";
86
87   Bloc::writeDot(os);
88   os << "}\n" ;
89 }
90
91 std::ostream& operator<< (std::ostream& os, const Proc& p)
92 {
93   os << "Proc" ;
94   return os;
95 }
96
97 TypeCode *Proc::createType(const std::string& name, const std::string& kind)
98 {
99   TypeCode* t;
100   if(kind=="double")
101     t=getRuntime()->_tc_double;
102   else if(kind=="string")
103     t=getRuntime()->_tc_string;
104   else if(kind=="int")
105     t=getRuntime()->_tc_int;
106   else if(kind=="bool")
107     t=getRuntime()->_tc_bool;
108   else
109     throw Exception("Unknown kind");
110
111   if(typeMap.count(name)!=0)
112     typeMap[name]->decrRef();
113   t->incrRef();
114   typeMap[name]=t;
115   t->incrRef();
116   return t;
117 }
118
119 //! Create an object reference TypeCode 
120 /*!
121  * \param id: the TypeCode repository id
122  * \param name: the TypeCode name
123  * \param ltc: a liste of object reference TypeCode to use as base types for this type
124  * \return the created TypeCode
125  */
126 TypeCode *Proc::createInterfaceTc(const std::string& id, const std::string& name,
127                                   std::list<TypeCodeObjref *> ltc)
128 {
129   TypeCode* t = TypeCode::interfaceTc(id.c_str(),name.c_str(),ltc);
130   if(typeMap.count(name)!=0)
131     typeMap[name]->decrRef();
132   typeMap[name]=t;
133   t->incrRef();
134   return t;
135 }
136
137 //! Create a sequence TypeCode 
138 /*!
139  * \param id: the TypeCode repository id ("" for normal use)
140  * \param name: the TypeCode name
141  * \param content: the element TypeCode 
142  * \return the created TypeCode
143  */
144 TypeCode * Proc::createSequenceTc (const std::string& id, const std::string& name,
145                                    TypeCode *content)
146 {
147   TypeCode* t = TypeCode::sequenceTc(id.c_str(),name.c_str(),content);
148   if(typeMap.count(name)!=0)
149     typeMap[name]->decrRef();
150   typeMap[name]=t;
151   t->incrRef();
152   return t;
153 }
154
155 TypeCode * Proc::createStructTc (const std::string& id, const std::string& name)
156 {
157   TypeCode* t = TypeCode::structTc(id.c_str(),name.c_str());
158   if(typeMap.count(name)!=0)
159     typeMap[name]->decrRef();
160   typeMap[name]=t;
161   t->incrRef();
162   return t;
163 }
164
165 TypeCode * Proc::getTypeCode (const std::string& name)
166 {
167   TypeCode* aTC=0;
168   if(typeMap.count(name)==0)
169     aTC=getRuntime()->getTypeCode(name);
170   else
171     aTC=typeMap[name];
172
173   if(!aTC)
174     {
175       std::stringstream msg;
176       msg << "Type " << name << " does not exist" ;
177       msg << " (" <<__FILE__ << ":" << __LINE__ << ")";
178       throw Exception(msg.str());
179     }
180
181   return aTC;
182 }
183
184 void Proc::setTypeCode (const std::string& name,TypeCode *t)
185 {
186   if(typeMap.count(name)!=0)
187     typeMap[name]->decrRef();
188   typeMap[name]=t;
189   t->incrRef();
190 }
191
192
193 void Proc::accept(Visitor *visitor)
194 {
195   visitor->visitProc(this);
196 }
197
198 void Proc::setName(const std::string& name)
199 {
200   _name = name;
201 }
202
203 YACS::StatesForNode Proc::getNodeState(int numId)
204 {
205   if(YACS::ENGINE::Node::idMap.count(numId) == 0)
206     {
207       cerr << "Unknown node id " << numId << endl;
208       return YACS::UNDEFINED;
209     }
210   YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[numId];
211   YACS::StatesForNode state = node->getEffectiveState();
212   return state;
213 }
214
215 std::string Proc::getXMLState(int numId)
216 {
217   if(YACS::ENGINE::Node::idMap.count(numId) == 0)
218     {
219       cerr << "Unknown node id " << numId << endl;
220       return "<state>unknown</state>";
221     }
222   YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[numId];
223   stringstream msg;
224   msg << "<state>" << node->getEffectiveState() << "</state>";
225   msg << "<name>" << node->getQualifiedName() << "</name>";
226   msg << "<id>" << numId << "</id>";
227   return msg.str();
228 }
229
230 std::string Proc::getInPortValue(int nodeNumId, std::string portName)
231 {
232   DEBTRACE("Proc::getInPortValue " << nodeNumId << " " << portName);
233   stringstream msg;
234   if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
235     {
236       msg << "<value><error>unknown node id: " << nodeNumId << "</error></value>";
237       return msg.str();
238     }
239   try
240     {
241       YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
242       InputPort * inputPort = node->getInputPort(portName);
243       return inputPort->getAsString();
244     }
245   catch(YACS::Exception& ex)
246     {
247       DEBTRACE("Proc::getInPortValue " << ex.what());
248       msg << "<value><error>" << ex.what() << "</error></value>";
249       return msg.str();
250     }
251 }
252
253 std::string Proc::getOutPortValue(int nodeNumId, std::string portName)
254 {
255   DEBTRACE("Proc::getOutPortValue " << nodeNumId << " " << portName);
256   stringstream msg;
257   if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
258     {
259       msg << "<value><error>unknown node id: " << nodeNumId << "</error></value>";
260       return msg.str();
261     }
262   try
263     {
264       YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
265       OutputPort * outputPort = node->getOutputPort(portName);
266       return outputPort->getAsString();
267     }
268   catch(YACS::Exception& ex)
269     {
270       DEBTRACE("Proc::getOutPortValue " << ex.what());
271       msg << "<value><error>" << ex.what() << "</error></value>";
272       return msg.str();
273     }
274 }
275
276 std::string Proc::getNodeErrorDetails(int nodeNumId)
277 {
278   DEBTRACE("Proc::getNodeErrorDetails " << nodeNumId);
279   stringstream msg;
280   if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
281     {
282       msg << "Unknown node id " << nodeNumId;
283       return msg.str();
284     }
285   YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
286   return node->getErrorDetails();
287 }
288
289 std::string Proc::getNodeErrorReport(int nodeNumId)
290 {
291   DEBTRACE("Proc::getNodeErrorReport " << nodeNumId);
292   stringstream msg;
293   if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
294     {
295       msg << "Unknown node id " << nodeNumId;
296       return msg.str();
297     }
298   YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
299   return node->getErrorReport();
300 }
301
302 std::string Proc::getNodeContainerLog(int nodeNumId)
303 {
304   DEBTRACE("Proc::getNodeContainerLog " << nodeNumId);
305   stringstream msg;
306   if(YACS::ENGINE::Node::idMap.count(nodeNumId) == 0)
307     {
308       msg << "Unknown node id " << nodeNumId;
309       return msg.str();
310     }
311   YACS::ENGINE::Node* node = YACS::ENGINE::Node::idMap[nodeNumId];
312   return node->getContainerLog();
313 }
314
315 std::list<int> Proc::getNumIds()
316 {
317   list<YACS::ENGINE::Node *> nodes = getAllRecursiveConstituents();
318   int len = nodes.size();
319   list<int> numids;
320   for( list<YACS::ENGINE::Node *>::const_iterator iter = nodes.begin();
321        iter != nodes.end(); iter++)
322     {
323       numids.push_back((*iter)->getNumId());
324     }
325   numids.push_back(this->getNumId());
326   return numids;
327 }
328
329 std::list<std::string> Proc::getIds()
330 {
331   list<YACS::ENGINE::Node *> nodes = getAllRecursiveConstituents();
332   int len = nodes.size();
333   list<string> ids;
334   for( list<YACS::ENGINE::Node *>::const_iterator iter = nodes.begin();
335        iter != nodes.end(); iter++)
336     {
337       ids.push_back(getChildName(*iter));
338     }
339   ids.push_back("_root_");
340   return ids;
341 }
342
343 Logger *Proc::getLogger(const std::string& name)
344 {
345   Logger* logger;
346   LoggerMap::const_iterator it = _loggers.find(name);
347
348   if (it != _loggers.end())
349   {
350     logger = it->second;
351   }
352   else
353   {
354     logger = new Logger(name);
355     _loggers[name]=logger;
356   }
357   return logger;
358 }
359
360 void Proc::setEdition(bool edition)
361 {
362   DEBTRACE("Proc::setEdition: " << edition);
363   _edition=edition;
364   if(_edition)
365     edUpdateState();
366 }
367 //! Sets Proc in modified state and update state if in edition mode
368 /*!
369  *
370  */
371 void Proc::modified()
372 {
373   DEBTRACE("Proc::modified() " << _edition);
374   _modified=1;
375   if(_edition)
376     edUpdateState();
377 }
378
379 //! Save Proc in XML schema file
380 /*!
381  * \param xmlSchemaFile: the file name
382  */
383 void Proc::saveSchema(std::string xmlSchemaFile)
384 {
385   VisitorSaveSchema vss(this);
386   vss.openFileSchema(xmlSchemaFile);
387   accept(&vss);
388   vss.closeFileSchema();
389 }
390
391 //! Save Proc state in XML state file
392 /*!
393  * \param xmlStateFile: the file name
394  */
395 void Proc::saveState(std::string xmlStateFile)
396 {
397   VisitorSaveState vst(this);
398   vst.openFileDump(xmlStateFile);
399   accept(&vst);
400   vst.closeFileDump();
401 }
402
403 //! Create a new Container and store it in containerMap
404 /*!
405  * \param name: the container name and key in containerMap
406  * \param kind: the container kind (depends on runtime)
407  * \return the created Container
408  */
409 Container* Proc::createContainer(const std::string& name,const std::string& kind)
410 {
411   Container* co=  getRuntime()->createContainer(kind);
412   co->setName(name);
413   if(containerMap.count(name)!=0)
414     containerMap[name]->decrRef();
415   containerMap[name]=co;
416   co->incrRef();
417   return co;
418 }