YARP
Yet Another Robot Platform
xmltemploader.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/conf/filesystem.h>
8 #include <yarp/manager/utility.h>
9 #include <dirent.h>
10 
11 #include <algorithm>
12 #include <cctype>
13 #include <string>
14 #include <fstream>
15 
16 #include <tinyxml.h>
17 
18 
19 using namespace yarp::manager;
20 
21 
27 XmlTempLoader::XmlTempLoader(const char* szPath, const char* szAppName)
28 {
29  if (szAppName) {
30  strAppName = szAppName;
31  }
32 
33  if(strlen(szPath))
34  {
35  const std::string directorySeparator{yarp::conf::filesystem::preferred_separator};
36  strPath = szPath;
37  if ((strPath.rfind(directorySeparator) == std::string::npos) || (strPath.rfind(directorySeparator) != strPath.size() - 1)) {
38  strPath = strPath + std::string(directorySeparator);
39  }
40  }
41 }
42 
46 XmlTempLoader::XmlTempLoader(const char* szFileName)
47 {
48  if (szFileName) {
49  strFileName = szFileName;
50  }
51 }
52 
53 
55 
56 
58 {
59  fileNames.clear();
61 
65  if(!strFileName.empty())
66  {
67  fileNames.push_back(strFileName);
68  return true;
69  }
70 
71  if(strPath.empty())
72  {
73  logger->addError("No application template path is introduced.");
74  return false;
75  }
76 
77  DIR *dir;
78  struct dirent *entry;
79  if ((dir = opendir(strPath.c_str())) == nullptr)
80  {
81  OSTRINGSTREAM err;
82  err<<"Cannot access "<<strPath;
83  logger->addError(err);
84  return false;
85  }
86 
87  /* we need to load all xml app templates */
88  while((entry = readdir(dir)))
89  {
90  std::string name = entry->d_name;
91  if(name.size() > 12)
92  {
93  std::string ext = name.substr(name.size()-12,12);
94  if (compareString(ext.c_str(), "xml.template")) {
95  fileNames.push_back(strPath + name);
96  }
97  }
98  }
99  closedir(dir);
100  return true;
101 }
102 
104 {
105  fini();
106  init();
107 }
108 
109 
111 {
112  fileNames.clear();
113 }
114 
115 
117 {
118  if(strAppName.empty())
119  {
120  AppTemplate* app = nullptr;
121  while(!app)
122  {
123  if (fileNames.empty()) {
124  return nullptr;
125  }
126  std::string fname = fileNames.back();
127  fileNames.pop_back();
128  app = parsXml(fname.c_str());
129  }
130  return app;
131  }
132  else
133  {
134  std::vector<std::string>::iterator itr;
135  for(itr=fileNames.begin(); itr<fileNames.end(); itr++)
136  {
137  AppTemplate* app = parsXml((*itr).c_str());
138  if (app && (app->name == strAppName)) {
139  return app;
140  }
141  }
142  }
143  return nullptr;
144 }
145 
146 
147 
148 AppTemplate* XmlTempLoader::parsXml(const char* szFile)
149 {
150  app.name.clear();
151  app.tmpFileName.clear();
152 
154 
155  TiXmlDocument doc(szFile);
156  if(!doc.LoadFile())
157  {
158  OSTRINGSTREAM err;
159  err<<"Syntax error while loading "<<szFile<<" at line "\
160  <<doc.ErrorRow()<<": ";
161  err<<doc.ErrorDesc();
162  logger->addError(err);
163  return nullptr;
164  }
165 
166  /* retrieving root element */
167  TiXmlElement *root = doc.RootElement();
168  if(!root)
169  {
170  OSTRINGSTREAM err;
171  err<<"Syntax error while loading "<<szFile<<" . ";
172  err<<"No root element.";
173  logger->addError(err);
174  return nullptr;
175  }
176 
177  if(!compareString(root->Value(), "application"))
178  {
179  return nullptr;
180  }
181 
182  app.tmpFileName = szFile;
183 
184  /* retrieving name */
185  auto* name = (TiXmlElement*) root->FirstChild("name");
186  if(!name || !name->GetText())
187  {
188  OSTRINGSTREAM err;
189  err<<"Application from "<<szFile<<" has no name.";
190  logger->addError(err);
191  //return NULL;
192  }
193  else
194  {
195  std::string strname = name->GetText();
196  for (char& i : strname) {
197  if (i == ' ') {
198  i = '_';
199  }
200  }
201  app.name = strname;
202  }
203 
204  return &app;
205 }
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
XmlTempLoader(const char *szFileName)
load only one application indicated by its xml file name
AppTemplate * getNextAppTemplate() override
static constexpr value_type preferred_separator
Definition: filesystem.h:23
bool compareString(const char *szFirst, const char *szSecond)
Definition: utility.cpp:310
std::stringstream OSTRINGSTREAM
Definition: utility.h:49
Abstract Class TempLoader.