]> SALOME platform Git repositories - modules/yacs.git/blob - src/runtime/XMLNode.cxx
Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / runtime / XMLNode.cxx
1 #include "XMLNode.hxx"
2 #include "XMLPorts.hxx"
3 #include "Mutex.hxx"
4
5 #include <libxml/parser.h>
6 #include <libxml/tree.h>
7
8 #include <stdlib.h>
9 #include <iostream>
10 #include <fstream>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13
14 //#define _DEVDEBUG_
15 #include "YacsTrace.hxx"
16
17 using namespace YACS::ENGINE;
18 using namespace std;
19
20 const char XmlNode::IMPL_NAME[]="XML";
21 const char XmlNode::KIND[]="xmlsh";
22 static YACS::BASES::Mutex MUTEX;
23
24 XmlNode::XmlNode(const XmlNode& other, ComposedNode *father)
25   : _script(other._script), ServiceNode(other, father)
26 {
27   _implementation=IMPL_NAME;
28   _ref = other._ref;
29 }
30
31 XmlNode::XmlNode(const std::string& name)
32   : ServiceNode(name)
33 {
34   _implementation=IMPL_NAME;
35 }
36
37 Node *XmlNode::simpleClone(ComposedNode *father, bool editionOnly) const
38 {
39   return new XmlNode(*this,father);
40 }
41
42 void XmlNode::setRef(const std::string& ref)
43 {
44   //No component instance here
45   _ref=ref;
46 }
47
48 void XmlNode::setScript(const std::string& script)
49 {
50   _script=script;
51 }
52
53 std::string XmlNode::getKind() const
54 {
55   return KIND;
56 }
57
58 void XmlNode::execute()
59 {
60   DEBTRACE("execute");
61   char dir[]="yacsXXXXXX";
62   // add a lock around mkdtemp (seems not thread safe)
63   MUTEX.lock();
64   char* mdir=mkdtemp(dir);
65   MUTEX.unlock();
66   if(mdir==NULL)
67     {
68       perror("mkdtemp failed");
69       std::cerr << "Problem in mkdtemp " << dir << " " << mdir << std::endl;
70       throw Exception("Execution problem in mkdtemp");
71     }
72   std::string sdir(dir);
73   std::string input=sdir+"/input";
74   std::ofstream f(input.c_str());
75   f<<"<methodCall> <methodName>" << _method << "</methodName> <params>"<<std::endl;
76   DEBTRACE("---------------XmlNode::inputs---------------");
77   list<InputPort *>::iterator iter;
78   for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
79     {
80       InputXmlPort *p=(InputXmlPort *)*iter;
81       DEBTRACE("port name: " << p->getName());
82       DEBTRACE("port kind: " << p->edGetType()->kind());
83       const char* ob=p->getXml();
84       DEBTRACE("Xml: " << ob );
85       f<<"<param>" << ob << "</param>"<<std::endl;
86     }
87   f<<"</params>"<<std::endl;
88   f<<"</methodCall>"<<std::endl;
89   f.close();
90   DEBTRACE("--------------XmlNode::calculation---------------" << _ref );
91   std::string call=sdir+"/run.sh";
92   std::ofstream run(call.c_str());
93   run << "#!/bin/sh" << std::endl;
94   run << "cd " << sdir << std::endl;
95   if(_ref[0]=='/' || _ref[0]=='~')
96     run << _ref << "> stdout 2>&1 " << std::endl;
97   else
98     run << "../"<<_ref << "> stdout 2>&1 " << std::endl;
99   run << "cat stdout" << std::endl;
100   run.close();
101   chmod(call.c_str(),00777);
102
103   int ret=system(call.c_str());
104   if(ret)
105     {
106       std::cerr << "Problem: " << ret << std::endl;
107       DEBTRACE("Problem: " << ret);
108       throw Exception("Execution problem");
109     }
110   std::string output=sdir+"/output";
111   xmlDocPtr doc; 
112   doc = xmlReadFile(output.c_str(), NULL, 0);
113   if (doc == NULL) 
114     {
115       DEBTRACE("Failed to parse " << output);
116       throw Exception("Execution problem");
117     }
118   xmlNodePtr cur;
119   cur = xmlDocGetRootElement(doc);
120   if (cur == NULL) 
121     {
122       DEBTRACE("empty document " );
123       xmlFreeDoc(doc);
124       throw Exception("Execution problem");
125     }
126   if (xmlStrcmp(cur->name, (const xmlChar *) "methodResponse")) 
127     {
128       DEBTRACE("document of the wrong type, root node != methodResponse");
129       xmlFreeDoc(doc);
130       throw Exception("Execution problem");
131     }
132   cur = cur->xmlChildrenNode;
133   xmlBufferPtr buf=xmlBufferCreate();
134   list<OutputPort *>::iterator iter2;
135   iter2 = _setOfOutputPort.begin(); 
136   OutputXmlPort *p;
137   p=(OutputXmlPort *)*iter2;
138   int nres=0;
139
140   while (cur != NULL) 
141     {
142       if ((!xmlStrcmp(cur->name, (const xmlChar *)"fault")))
143         {
144           DEBTRACE("exception in shell" );
145           xmlFreeDoc(doc);
146           throw Exception("Execution problem");
147         }
148       if ((!xmlStrcmp(cur->name, (const xmlChar *)"params")))
149         {
150           xmlNodePtr cur0 = cur->xmlChildrenNode;
151           while (cur0 != NULL)
152             {
153               if ((!xmlStrcmp(cur0->name, (const xmlChar *)"param")))
154                 {
155                   xmlNodePtr cur1 = cur0->xmlChildrenNode;
156                   while (cur1 != NULL)
157                     {
158                       if ((!xmlStrcmp(cur1->name, (const xmlChar *)"value")))
159                         {
160                           xmlNodePtr cur2=cur1->xmlChildrenNode;
161                           while (cur2 != NULL)
162                             {
163                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"int")))
164                                 {
165                                   //got an int
166                                   if(getNumberOfOutputPorts()!=1)
167                                     {
168                                       //mismatch
169                                       xmlBufferFree(buf);
170                                       xmlFreeDoc(doc);
171                                       throw Exception("Execution problem:mismatch in output numbers");
172                                     }
173                                   xmlBufferEmpty(buf);
174                                   xmlNodeDump(buf,doc,cur1,0,0);
175                                   DEBTRACE(xmlBufferContent(buf));
176                                   p->put(xmlBufferContent(buf));
177                                 }
178                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"double")))
179                                 {
180                                   //got an double
181                                   if(getNumberOfOutputPorts()!=1)
182                                     {
183                                       //mismatch
184                                       xmlBufferFree(buf);
185                                       xmlFreeDoc(doc);
186                                       throw Exception("Execution problem:mismatch in output numbers");
187                                     }
188                                   xmlBufferEmpty(buf);
189                                   xmlNodeDump(buf,doc,cur1,0,0);
190                                   DEBTRACE(xmlBufferContent(buf));
191                                   p->put(xmlBufferContent(buf));
192                                 }
193                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"string")))
194                                 {
195                                   //got an string
196                                   if(getNumberOfOutputPorts()!=1)
197                                     {
198                                       //mismatch
199                                       xmlBufferFree(buf);
200                                       xmlFreeDoc(doc);
201                                       throw Exception("Execution problem:mismatch in output port numbers");
202                                     }
203                                   xmlBufferEmpty(buf);
204                                   xmlNodeDump(buf,doc,cur1,0,0);
205                                   DEBTRACE(xmlBufferContent(buf));
206                                   p->put(xmlBufferContent(buf));
207                                 }
208                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"boolean")))
209                                 {
210                                   //got an boolean
211                                   if(getNumberOfOutputPorts()!=1)
212                                     {
213                                       //mismatch
214                                       xmlBufferFree(buf);
215                                       xmlFreeDoc(doc);
216                                       throw Exception("Execution problem:mismatch in output port numbers");
217                                     }
218                                   xmlBufferEmpty(buf);
219                                   xmlNodeDump(buf,doc,cur1,0,0);
220                                   DEBTRACE(xmlBufferContent(buf));
221                                   p->put(xmlBufferContent(buf));
222                                 }
223                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"objref")))
224                                 {
225                                   //got an objref
226                                   if(getNumberOfOutputPorts()!=1)
227                                     {
228                                       //mismatch
229                                       xmlBufferFree(buf);
230                                       xmlFreeDoc(doc);
231                                       throw Exception("Execution problem:mismatch in output port numbers");
232                                     }
233                                   xmlBufferEmpty(buf);
234                                   xmlNodeDump(buf,doc,cur1,0,0);
235                                   DEBTRACE(xmlBufferContent(buf));
236                                   p->put(xmlBufferContent(buf));
237                                 }
238                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"struct")))
239                                 {
240                                   //got an struct
241                                   if(getNumberOfOutputPorts()!=1)
242                                     {
243                                       //mismatch
244                                       xmlBufferFree(buf);
245                                       xmlFreeDoc(doc);
246                                       throw Exception("Execution problem:mismatch in output port numbers");
247                                     }
248                                   xmlBufferEmpty(buf);
249                                   xmlNodeDump(buf,doc,cur1,0,0);
250                                   DEBTRACE(xmlBufferContent(buf));
251                                   p->put(xmlBufferContent(buf));
252                                 }
253                               if ((!xmlStrcmp(cur2->name, (const xmlChar *)"array")))
254                                 {
255                                   //got a tuple of results or only one result (but a list)
256                                   if(getNumberOfOutputPorts()==1)
257                                     {
258                                       //It's a one result list
259                                       xmlBufferEmpty(buf);
260                                       xmlNodeDump(buf,doc,cur1,0,0);
261                                       DEBTRACE(xmlBufferContent(buf));
262                                       p->put(xmlBufferContent(buf));
263                                     }
264                                   else
265                                     {
266                                       //It's a list of results
267                                       xmlNodePtr cur3=cur2->xmlChildrenNode;
268                                       while (cur3 != NULL)
269                                         {
270                                           if ((!xmlStrcmp(cur3->name, (const xmlChar *)"data")))
271                                             {
272                                               xmlNodePtr cur4=cur3->xmlChildrenNode;
273                                               while (cur4 != NULL)
274                                                 {
275                                                   if ((!xmlStrcmp(cur4->name, (const xmlChar *)"value")))
276                                                     {
277                                                       nres++;
278                                                       if(nres > getNumberOfOutputPorts())
279                                                         {
280                                                           //mismatch
281                                                           xmlBufferFree(buf);
282                                                           xmlFreeDoc(doc);
283                                                           throw Exception("Execution problem:mismatch in output port numbers");
284                                                         }
285                                                       xmlBufferEmpty(buf);
286                                                       xmlNodeDump(buf,doc,cur4,0,0);
287                                                       DEBTRACE(xmlBufferContent(buf));
288                                                       p=(OutputXmlPort *)*iter2;
289                                                       p->put(xmlBufferContent(buf));
290                                                       iter2++;
291                                                     }
292                                                   cur4 = cur4->next;
293                                                 } // end while value
294                                               break;
295                                             }
296                                           cur3 = cur3->next;
297                                         } // end while data
298                                     }
299                                   break;
300                                 }
301                               cur2 = cur2->next;
302                             } // end while array
303                           break;
304                         }
305                       cur1 = cur1->next;
306                     } // end while value
307                 }
308               cur0 = cur0->next;
309             }// end while param
310         }
311       cur = cur->next;
312     }
313   xmlBufferFree(buf);
314   xmlFreeDoc(doc);
315 }
316
317