1 // Copyright (C) 2006-2008 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.
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
19 #include "XMLNode.hxx"
20 #include "XMLPorts.hxx"
23 #include <libxml/parser.h>
24 #include <libxml/tree.h>
29 #include <sys/types.h>
33 #include "YacsTrace.hxx"
35 using namespace YACS::ENGINE;
38 const char XmlNode::IMPL_NAME[]="XML";
39 const char XmlNode::KIND[]="xmlsh";
40 static YACS::BASES::Mutex MUTEX;
42 XmlNode::XmlNode(const XmlNode& other, ComposedNode *father)
43 : _script(other._script), ServiceNode(other, father)
45 _implementation=IMPL_NAME;
49 XmlNode::XmlNode(const std::string& name)
52 _implementation=IMPL_NAME;
55 Node *XmlNode::simpleClone(ComposedNode *father, bool editionOnly) const
57 return new XmlNode(*this,father);
60 void XmlNode::setRef(const std::string& ref)
62 //No component instance here
66 void XmlNode::setScript(const std::string& script)
71 std::string XmlNode::getScript() const
76 std::string XmlNode::getKind() const
81 void XmlNode::execute()
84 char dir[]="yacsXXXXXX";
85 // add a lock around mkdtemp (seems not thread safe)
87 char* mdir=mkdtemp(dir);
91 perror("mkdtemp failed");
92 std::cerr << "Problem in mkdtemp " << dir << " " << mdir << std::endl;
93 throw Exception("Execution problem in mkdtemp");
95 std::string sdir(dir);
96 std::string input=sdir+"/input";
97 std::ofstream f(input.c_str());
98 f<<"<methodCall> <methodName>" << _method << "</methodName> <params>"<<std::endl;
99 DEBTRACE("---------------XmlNode::inputs---------------");
100 list<InputPort *>::iterator iter;
101 for(iter = _setOfInputPort.begin(); iter != _setOfInputPort.end(); iter++)
103 InputXmlPort *p=(InputXmlPort *)*iter;
104 DEBTRACE("port name: " << p->getName());
105 DEBTRACE("port kind: " << p->edGetType()->kind());
106 const char* ob=p->getXml();
107 DEBTRACE("Xml: " << ob );
108 f<<"<param>" << ob << "</param>"<<std::endl;
110 f<<"</params>"<<std::endl;
111 f<<"</methodCall>"<<std::endl;
113 DEBTRACE("--------------XmlNode::calculation---------------" << _ref );
114 std::string call=sdir+"/run.sh";
115 std::ofstream run(call.c_str());
116 run << "#!/bin/sh" << std::endl;
117 run << "cd " << sdir << std::endl;
118 if(_ref[0]=='/' || _ref[0]=='~')
119 run << _ref << "> stdout 2>&1 " << std::endl;
121 run << "../"<<_ref << "> stdout 2>&1 " << std::endl;
122 //run << "cat stdout" << std::endl;
124 chmod(call.c_str(),00777);
126 std::string call2="/bin/sh "+call;
127 int ret=system(call2.c_str());
130 std::cerr << "Problem: " << ret << std::endl;
131 DEBTRACE("Problem: " << ret);
132 throw Exception("Execution problem");
134 std::string output=sdir+"/output";
136 doc = xmlReadFile(output.c_str(), NULL, 0);
139 DEBTRACE("Failed to parse " << output);
140 throw Exception("Execution problem");
143 cur = xmlDocGetRootElement(doc);
146 DEBTRACE("empty document " );
148 throw Exception("Execution problem");
150 if (xmlStrcmp(cur->name, (const xmlChar *) "methodResponse"))
152 DEBTRACE("document of the wrong type, root node != methodResponse");
154 throw Exception("Execution problem");
156 cur = cur->xmlChildrenNode;
157 xmlBufferPtr buf=xmlBufferCreate();
158 list<OutputPort *>::iterator iter2;
159 iter2 = _setOfOutputPort.begin();
161 p=(OutputXmlPort *)*iter2;
166 if ((!xmlStrcmp(cur->name, (const xmlChar *)"fault")))
168 DEBTRACE("exception in shell" );
170 throw Exception("Execution problem");
172 if ((!xmlStrcmp(cur->name, (const xmlChar *)"params")))
174 xmlNodePtr cur0 = cur->xmlChildrenNode;
177 if ((!xmlStrcmp(cur0->name, (const xmlChar *)"param")))
179 xmlNodePtr cur1 = cur0->xmlChildrenNode;
182 if ((!xmlStrcmp(cur1->name, (const xmlChar *)"value")))
184 xmlNodePtr cur2=cur1->xmlChildrenNode;
187 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"int")))
190 if(getNumberOfOutputPorts()!=1)
195 throw Exception("Execution problem:mismatch in output numbers");
198 xmlNodeDump(buf,doc,cur1,0,0);
199 DEBTRACE(xmlBufferContent(buf));
200 p->put(xmlBufferContent(buf));
202 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"double")))
205 if(getNumberOfOutputPorts()!=1)
210 throw Exception("Execution problem:mismatch in output numbers");
213 xmlNodeDump(buf,doc,cur1,0,0);
214 DEBTRACE(xmlBufferContent(buf));
215 p->put(xmlBufferContent(buf));
217 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"string")))
220 if(getNumberOfOutputPorts()!=1)
225 throw Exception("Execution problem:mismatch in output port numbers");
228 xmlNodeDump(buf,doc,cur1,0,0);
229 DEBTRACE(xmlBufferContent(buf));
230 p->put(xmlBufferContent(buf));
232 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"boolean")))
235 if(getNumberOfOutputPorts()!=1)
240 throw Exception("Execution problem:mismatch in output port numbers");
243 xmlNodeDump(buf,doc,cur1,0,0);
244 DEBTRACE(xmlBufferContent(buf));
245 p->put(xmlBufferContent(buf));
247 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"objref")))
250 if(getNumberOfOutputPorts()!=1)
255 throw Exception("Execution problem:mismatch in output port numbers");
258 xmlNodeDump(buf,doc,cur1,0,0);
259 DEBTRACE(xmlBufferContent(buf));
260 p->put(xmlBufferContent(buf));
262 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"struct")))
265 if(getNumberOfOutputPorts()!=1)
270 throw Exception("Execution problem:mismatch in output port numbers");
273 xmlNodeDump(buf,doc,cur1,0,0);
274 DEBTRACE(xmlBufferContent(buf));
275 p->put(xmlBufferContent(buf));
277 if ((!xmlStrcmp(cur2->name, (const xmlChar *)"array")))
279 //got a tuple of results or only one result (but a list)
280 if(getNumberOfOutputPorts()==1)
282 //It's a one result list
284 xmlNodeDump(buf,doc,cur1,0,0);
285 DEBTRACE(xmlBufferContent(buf));
286 p->put(xmlBufferContent(buf));
290 //It's a list of results
291 xmlNodePtr cur3=cur2->xmlChildrenNode;
294 if ((!xmlStrcmp(cur3->name, (const xmlChar *)"data")))
296 xmlNodePtr cur4=cur3->xmlChildrenNode;
299 if ((!xmlStrcmp(cur4->name, (const xmlChar *)"value")))
302 if(nres > getNumberOfOutputPorts())
307 throw Exception("Execution problem:mismatch in output port numbers");
310 xmlNodeDump(buf,doc,cur4,0,0);
311 DEBTRACE(xmlBufferContent(buf));
312 p=(OutputXmlPort *)*iter2;
313 p->put(xmlBufferContent(buf));