YARP
Yet Another Robot Platform
xmlappsaver.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
7 #include <yarp/manager/utility.h>
8 #include <dirent.h>
9 
10 #include <algorithm>
11 #include <cctype>
12 #include <string>
13 #include <fstream>
14 
15 #include <tinyxml.h>
16 
17 
18 using namespace yarp::manager;
19 
20 
21 XmlAppSaver::XmlAppSaver(const char* szFileName)
22 {
23  if (szFileName) {
24  strFileName = szFileName;
25  }
26 }
27 
28 bool XmlAppSaver::save(Application* application)
29 {
30  if (!strFileName.size()) {
31  return serialXml(application, application->getXmlFile());
32  }
33 
34  return serialXml(application, strFileName.c_str());
35 }
36 
37 XmlAppSaver::~XmlAppSaver() = default;
38 
39 bool XmlAppSaver::serialXml(Application* app, const char* szFile)
40 {
41 
42  // updating application xml file name
43  app->setXmlFile(szFile);
44 
46 
47  TiXmlDocument doc; //(szFile);
48  auto* root = new TiXmlElement("application");
49  doc.LinkEndChild( root );
50  auto* appName = new TiXmlElement("name"); //are all these NEW ok?
51  appName->LinkEndChild(new TiXmlText(app->getName()));
52  root->LinkEndChild(appName);
53 
54 
55  if (strcmp(app->getDescription(), "") != 0)
56  {
57  auto* desc= new TiXmlElement( "description");
58  desc->LinkEndChild(new TiXmlText( app->getDescription()));
59  root->LinkEndChild(desc);
60  }
61 
62  if(strcmp (app->getVersion(), "") != 0)
63  {
64  auto* vers= new TiXmlElement( "version");
65  vers->LinkEndChild(new TiXmlText( app->getVersion()));
66  root->LinkEndChild(vers);
67 
68  }
69 
70  /*
71  * TODO: setting prefix of the main application is inactivated.
72  * Check this should be supported in future or not!
73  */
74  /*
75  if(strcmp (app->getPrefix(), ""))
76  {
77  TiXmlElement * prefix= new TiXmlElement( "prefix");
78  prefix->LinkEndChild(new TiXmlText( app->getPrefix()));
79  root->LinkEndChild(prefix);
80 
81  }
82  */
83 
84  if(app->authorCount()>0)
85  {
86  auto* auths=new TiXmlElement("authors");
87  for (int i=0; i<app->authorCount(); i++)
88  {
89  //app->getAuthorAt(i);
90  auto* auth=new TiXmlElement("author");
91  auth->SetAttribute("email", app->getAuthorAt(i).getEmail());
92  auth->LinkEndChild(new TiXmlText(app->getAuthorAt(i).getName()));
93  auths->LinkEndChild(auth);
94  }
95  root->LinkEndChild(auths);
96  }
97 
98  // iterate over modules
99  {
100  int nModules=app->imoduleCount();
101  for (int modCt=0; modCt<nModules; ++modCt)
102  {
103  auto* newMod = new TiXmlElement("module");
104  root->LinkEndChild(newMod); //add module element
105  ModuleInterface curMod=app->getImoduleAt(modCt);
106 
107  auto* name = new TiXmlElement("name");
108  name->LinkEndChild(new TiXmlText(curMod.getName()));
109  newMod->LinkEndChild(name);
110 
111  auto* parameters=new TiXmlElement("parameters");
112  parameters->LinkEndChild(new TiXmlText(curMod.getParam()));
113  newMod->LinkEndChild(parameters);
114 
115  auto* node = new TiXmlElement("node");
116  node->LinkEndChild(new TiXmlText(curMod.getHost())); //is host the same as node?
117  newMod->LinkEndChild(node);
118 
119  auto* prefix=new TiXmlElement("prefix");
120  prefix->LinkEndChild(new TiXmlText(curMod.getPrefix()));
121  newMod->LinkEndChild(prefix);
122 
123  if(strcmp(curMod.getStdio(), "") != 0)
124  {
125  auto* stdio=new TiXmlElement("stdio");
126  stdio->LinkEndChild(new TiXmlText(curMod.getStdio()));
127  newMod->LinkEndChild(stdio);
128  }
129 
130  if(strcmp(curMod.getWorkDir(), "") != 0)
131  {
132  auto* workdir=new TiXmlElement("workdir");
133  workdir->LinkEndChild(new TiXmlText(curMod.getWorkDir()));
134  newMod->LinkEndChild(workdir);
135  }
136 
137  if(strcmp(curMod.getBroker(), "") != 0)
138  {
139  auto* broker=new TiXmlElement("deployer");
140  broker->LinkEndChild(new TiXmlText(curMod.getBroker()));
141  newMod->LinkEndChild(broker);
142  }
143  /*
144  if(curMod.getRank()>0) //TODO check here how is rank handled
145  {
146  TiXmlElement *rank=new TiXmlElement("rank");
147  char str[256];
148  sprintf(str,"%d", curMod.getRank());
149  rank->LinkEndChild(new TiXmlText(str));
150  newMod->LinkEndChild(rank);
151  }
152  */
153 
154  GraphicModel model = curMod.getModelBase();
155  OSTRINGSTREAM txt;
156  if(model.points.size()>0)
157  {
158  txt<<"(Pos (x "<<model.points[0].x<<") "<<"(y "<<model.points[0].y<<"))";
159  auto* geometry=new TiXmlElement("geometry");
160  geometry->LinkEndChild(new TiXmlText(txt.str().c_str()));
161  newMod->LinkEndChild(geometry);
162  }
163  }
164 
165  }
166 
167  // iterate over embedded applications
168  {
169  int nApps=app->iapplicationCount();
170  for (int appCt=0; appCt<nApps; ++appCt)
171  {
172  auto* newApp = new TiXmlElement("application");
173  root->LinkEndChild(newApp); //add application element
174  ApplicationInterface curApp=app->getIapplicationAt(appCt);
175 
176  auto* name = new TiXmlElement("name");
177  name->LinkEndChild(new TiXmlText(curApp.getName()));
178  newApp->LinkEndChild(name);
179 
180 
181  auto* prefix=new TiXmlElement("prefix");
182  prefix->LinkEndChild(new TiXmlText(curApp.getPrefix()));
183  newApp->LinkEndChild(prefix);
184 
185  GraphicModel model = curApp.getModelBase();
186  OSTRINGSTREAM txt;
187  if(model.points.size()>0)
188  {
189  txt<<"(Pos (x "<<model.points[0].x<<") "<<"(y "<<model.points[0].y<<"))";
190  auto* geometry=new TiXmlElement("geometry");
191  geometry->LinkEndChild(new TiXmlText(txt.str().c_str()));
192  newApp->LinkEndChild(geometry);
193  }
194 
195  }
196  }
197 
198  // iterate over connections
199  {
200  int nConns=app->connectionCount();
201  for (int connCt=0; connCt<nConns; ++connCt)
202  {
203  auto* newConn=new TiXmlElement("connection");
204  Connection curConn=app->getConnectionAt(connCt);
205 
206  if (strlen(curConn.getId())) {
207  newConn->SetAttribute("id", curConn.getId());
208  }
209 
210  if (curConn.isPersistent()) {
211  newConn->SetAttribute("persist", "true");
212  }
213 
214  auto* from = new TiXmlElement("from");
215  if (curConn.isExternalFrom()) {
216  from->SetAttribute("external", "true");
217  }
218  from->LinkEndChild(new TiXmlText(curConn.from()));
219  newConn->LinkEndChild(from);
220 
221  auto* to = new TiXmlElement("to");
222  if (curConn.isExternalTo()) {
223  to->SetAttribute("external", "true");
224  }
225  to->LinkEndChild(new TiXmlText(curConn.to()));
226  newConn->LinkEndChild(to);
227 
228  auto* protocol = new TiXmlElement("protocol");
229  protocol->LinkEndChild(new TiXmlText(curConn.carrier()));
230  newConn->LinkEndChild(protocol);
231 
232  GraphicModel model = curConn.getModelBase();
233  OSTRINGSTREAM txt;
234  if(model.points.size()>0)
235  {
236  txt<<"(Pos ";
237  for (auto& point : model.points) {
238  txt << "((x " << point.x << ") "
239  << "(y " << point.y << ")) ";
240  }
241  txt<<" )";
242  auto* geometry=new TiXmlElement("geometry");
243  geometry->LinkEndChild(new TiXmlText(txt.str().c_str()));
244  newConn->LinkEndChild(geometry);
245  }
246 
247  root->LinkEndChild(newConn);
248  }
249 
250  }
251 
252  // iterate over arbitrators
253  for(int i=0; i<app->arbitratorCount(); i++)
254  {
255  Arbitrator& arb = app->getArbitratorAt(i);
256  auto* newArb = new TiXmlElement("arbitrator");
257 
258  auto* port = new TiXmlElement("port");
259  port->LinkEndChild(new TiXmlText(arb.getPort()));
260  newArb->LinkEndChild(port);
261 
262  std::map<std::string, std::string> &rules = arb.getRuleMap();
263  for(auto& it : rules)
264  {
265  auto* rule = new TiXmlElement("rule");
266  rule->SetAttribute("connection", it.first.c_str());
267  rule->LinkEndChild(new TiXmlText(it.second.c_str()));
268  newArb->LinkEndChild(rule);
269  }
270 
271  GraphicModel model = arb.getModelBase();
272  OSTRINGSTREAM txt;
273  if(model.points.size()>0)
274  {
275  txt<<"(Pos ";
276  for (auto& point : model.points) {
277  txt << "((x " << point.x << ") "
278  << "(y " << point.y << ")) ";
279  }
280  txt<<" )";
281  auto* geometry=new TiXmlElement("geometry");
282  geometry->LinkEndChild(new TiXmlText(txt.str().c_str()));
283  newArb->LinkEndChild(geometry);
284  }
285  root->LinkEndChild(newArb);
286  }
287 
288 
289  bool ok=doc.SaveFile(app->getXmlFile());
290  if (!ok)
291  {
292 
293  OSTRINGSTREAM err;
294  err<<"tinyXml error for file " << app->getXmlFile();
295  if (doc.Error()) {
296  err << " at line " << doc.ErrorRow() << ", column " << doc.ErrorCol() << ": " << doc.ErrorDesc();
297  }
298  logger->addError(err);
299  err <<"\n";
300  return false;
301  } else {
302  return true;
303  }
304 }
Class ApplicationInterface.
Definition: application.h:253
Class Application.
Definition: application.h:289
Connection & getConnectionAt(int index)
Definition: application.h:341
const char * getVersion()
Definition: application.h:305
void setXmlFile(const char *szFilename)
Definition: application.h:337
ApplicationInterface & getIapplicationAt(int index)
Definition: application.h:321
ModuleInterface & getImoduleAt(int index)
Definition: application.h:315
const char * getDescription()
Definition: application.h:306
Arbitrator & getArbitratorAt(int index)
Definition: application.h:347
Author & getAuthorAt(int index)
Definition: application.h:311
const char * getXmlFile()
Definition: application.h:338
Class port Arbitrator.
Definition: arbitrator.h:25
GraphicModel & getModelBase()
Definition: arbitrator.h:52
const char * getPort()
Definition: arbitrator.h:33
std::map< std::string, std::string > & getRuleMap()
Definition: arbitrator.h:43
const char * getName()
Definition: module.h:32
const char * getEmail()
Definition: module.h:33
Class Connection.
Definition: application.h:57
GraphicModel & getModelBase()
Definition: application.h:118
const char * carrier()
Definition: application.h:78
const char * getId()
Definition: application.h:99
Singleton class ErrorLogger.
Definition: utility.h:57
void addError(const char *szError)
Definition: utility.cpp:118
static ErrorLogger * Instance()
Singleton class ErrorLogger.
Definition: utility.cpp:98
std::vector< GyPoint > points
Definition: node.h:30
Class ModuleInterface.
Definition: application.h:161
GraphicModel & getModelBase()
Definition: application.h:218
bool save(Application *application) override
Definition: xmlappsaver.cpp:28
XmlAppSaver(const char *szFileName=NULL)
Definition: xmlappsaver.cpp:21
std::stringstream OSTRINGSTREAM
Definition: utility.h:49