stdr_parser_validator.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  STDR Simulator - Simple Two DImensional Robot Simulator
3  Copyright (C) 2013 STDR Simulator
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 3 of the License, or
7  (at your option) any later version.
8  This program 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
11  GNU General Public License for more details.
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 
16  Authors :
17  * Manos Tsardoulias, etsardou@gmail.com
18  * Aris Thallas, aris.thallas@gmail.com
19  * Chris Zalidis, zalidis@gmail.com
20 ******************************************************************************/
21 
23 
24 namespace stdr_parser
25 {
31  {
32 
33  }
34 
41  void Validator::validityAllowedCheck(std::string file_name, Node* n)
42  {
44  if(n->value != "")
45  {
46  return;
47  }
48  std::string tag = n->tag;
49  if(Specs::specs.find(tag) == Specs::specs.end() &&
50  tag != "STDR_Parser_Root_Node")
51  {
52  std::string error =
53  std::string("STDR parser : ") + n->tag +
54  std::string(" is not a valid tag") +
55  std::string("\nTrail: ");
56  throw ParserException(error);
57  }
58  for(unsigned int i = 0 ; i < n->elements.size() ; i++)
59  {
60  std::string child_tag = n->elements[i]->tag;
61  std::string child_value = n->elements[i]->value;
62  if(tag != "STDR_Parser_Root_Node" && child_value == "")
63  {
64  if(Specs::specs[tag].allowed.find(child_tag) ==
65  Specs::specs[tag].allowed.end())
66  {
67  int decreaser = (extractFilename(n->elements[i]->file_origin) ==
68  extractFilename(file_name) ? 1 : 0);
69  std::string error =
70  std::string("STDR parser : ") + child_tag +
71  std::string(" is not allowed in a ") + tag + std::string(" tag") +
72  std::string("\nTrail: ");
73  error += std::string("\n [") + child_tag + std::string("] Line ") +
74  SSTR( n->elements[i]->file_row - decreaser ) +
75  std::string(" of file '") +
76  extractFilename(n->elements[i]->file_origin) +
77  std::string("'");
78  throw ParserException(error);
79  }
80  }
81  try
82  {
83  validityAllowedCheck(file_name, n->elements[i]);
84  }
85  catch(ParserException ex)
86  {
87  if(n->tag == "STDR_Parser_Root_Node")
88  {
89  throw ex;
90  }
91  int decreaser = (extractFilename(n->file_origin) ==
92  extractFilename(file_name) ? 1 : 0);
93  std::string trail(ex.what());
94  trail += std::string("\n [") + n->tag + std::string("] Line ") +
95  SSTR( n->file_row - decreaser) +
96  std::string(" of file '") +
97  extractFilename(n->file_origin) + std::string("'");
98  ParserException ex_new(trail);
99  throw ex_new;
100  }
101  }
102  }
103 
110  void Validator::validityRequiredCheck(std::string file_name, Node* n)
111  {
113  if(n->value != "")
114  {
115  return;
116  }
117  std::string tag = n->tag;
118  if(Specs::specs.find(tag) == Specs::specs.end() &&
119  tag != "STDR_Parser_Root_Node")
120  {
121  std::string error =
122  std::string("STDR parser : ") + n->tag +
123  std::string(" is not a valid tag") +
124  std::string("\nTrail: ");
125  throw ParserException(error);
126  }
127  for(std::set<std::string>::iterator it = Specs::specs[tag].required.begin()
128  ; it != Specs::specs[tag].required.end() ; it++)
129  {
130  std::vector<int> num = n->getTag(*it);
131  if(num.size() == 0)
132  {
133  std::string error =
134  std::string("STDR parser : ") + tag +
135  std::string(" requires ") + (*it) +
136  std::string("\nTrail: ");
137  throw ParserException(error);
138  }
139  }
140  for(unsigned int i = 0 ; i < n->elements.size() ; i++)
141  {
142  try
143  {
144  validityRequiredCheck(file_name, n->elements[i]);
145  }
146  catch(ParserException ex)
147  {
148  if(n->tag == "STDR_Parser_Root_Node")
149  {
150  throw ex;
151  }
152 
153  int decreaser = (extractFilename(n->elements[i]->file_origin) ==
154  extractFilename(file_name) ? 1 : 0);
155 
156  std::string trail(ex.what());
157  trail += std::string("\n [") + n->tag + std::string("] Line ") +
158  SSTR( n->file_row - decreaser ) +
159  std::string(" of file '") + extractFilename(n->file_origin)
160  + std::string("'");
161  ParserException ex_new(trail);
162  throw ex_new;
163  }
164  }
165  }
166 
172  {
173  std::string base_path_ = ros::package::getPath("stdr_resources");
174  std::string path=base_path_ +
175  std::string("/resources/specifications/stdr_multiple_allowed.xml");
176  TiXmlDocument doc;
177  bool loadOkay = doc.LoadFile(path.c_str());
178  if (!loadOkay)
179  {
180  std::string error =
181  std::string("STDR parser : Failed to load file ") +
182  path + std::string("'") +
183  std::string("\nError was \n\t") + std::string(doc.ErrorDesc());
184  throw ParserException(error);
185  }
187  doc.FirstChild()->FirstChild()->Value(), ',');
188  }
189 
195  void Validator::parseSpecifications(TiXmlNode* node)
196  {
197  TiXmlNode* pChild;
198  int type = node->Type();
199  std::string node_text(node->Value());
200  switch (type)
201  {
202  case 0 :
203  {
204  break;
205  }
206  case 1 :
207  {
208  if(node_text == "specifications")
209  {
210  break;
211  }
212  else if(node_text!="allowed" && node_text!="required"
213  && node_text!="default")
214  {
215  if(Specs::specs.find(node_text) == Specs::specs.end())
216  {
217  Specs::specs.insert(std::pair<std::string,ElSpecs>(
218  node_text,ElSpecs()));
219  }
220  else
221  {
222  std::string error =
223  std::string("STDR parser : Multiple instance of '") + node_text +
224  std::string("' in specifications.");
225  throw ParserException(error);
226  }
227  }
228  else
229  {
230  break;
231  }
232  break;
233  }
234  case 4 :
235  {
236  std::string base_tag (node->Parent()->Parent()->Value());
237  std::string base_type(node->Parent()->Value());
238  if(base_type == "allowed")
239  {
240  Specs::specs[base_tag].allowed = explodeString(node_text,',');
241  }
242  else if(base_type == "required")
243  {
244  Specs::specs[base_tag].required = explodeString(node_text,',');
245  }
246  else if(base_type == "default")
247  {
248  Specs::specs[base_tag].default_value = node_text;
249  }
250  else
251  {
252  std::string error =
253  std::string("STDR parser : Specification '") + base_tag +
254  std::string("' not in 'allowed', 'required' or 'default' : '") +
255  base_type + std::string("' / '") + node_text + std::string("'");
256  throw ParserException(error);
257  }
258  break;
259  }
260  }
261 
262  for (
263  pChild = node->FirstChild();
264  pChild != 0;
265  pChild = pChild->NextSibling())
266  {
267  try
268  {
269  parseSpecifications( pChild );
270  }
271  catch(ParserException ex)
272  {
273  throw ex;
274  }
275  }
276  }
277 
284  void Validator::validate(std::string file_name, Node* n)
285  {
286 
287  Specs::specs.clear();
288  Specs::non_mergable_tags.clear();
289 
290  std::string base_path_ = ros::package::getPath("stdr_resources");
291 
292  std::string path = base_path_ +
293  std::string("/resources/specifications/stdr_specifications.xml");
294 
295  TiXmlDocument doc;
296  bool loadOkay = doc.LoadFile(path.c_str());
297  if (!loadOkay)
298  {
299  std::string error =
300  std::string("Failed to load specifications file.\nShould be at '") +
301  path + std::string("'\nError was") + std::string(doc.ErrorDesc());
302  throw ParserException(error);
303  }
304 
305  try
306  {
307  parseSpecifications(&doc);
308  }
309  catch(ParserException ex)
310  {
311  throw ex;
312  }
313 
314  try
315  {
316  validityAllowedCheck(file_name, n);
317  validityRequiredCheck(file_name, n);
318  }
319  catch(ParserException ex)
320  {
321  throw ex;
322  }
323  }
324 }
325 
std::string tag
The node value (if it not a tag node)
std::vector< int > getTag(std::string tag)
Searches for a tag in the specific node.
The main namespace for STDR GUI XML parser.
static std::set< std::string > non_mergable_tags
#define SSTR(x)
< Transforms a float number to string
std::string extractFilename(std::string s)
Extracts the filename from an absolute path.
std::string value
The node children.
An element of Specs - represents a valid tag.
static void parseMergableSpecifications(void)
Parses the mergable specifications file.
static void parseSpecifications(TiXmlNode *node)
Low-level recursive function for parsing the xml specifications file.
static void validate(std::string file_name, Node *n)
Performs a required / allowed - validity check on the xml tree.
static std::map< std::string, ElSpecs > specs
List of non-mergable tags. Read from stdr_multiple_allowed.xml.
static void validityRequiredCheck(std::string file_name, Node *n)
Performs a required - validity check on the xml tree.
ROSLIB_DECL std::string getPath(const std::string &package_name)
static void validityAllowedCheck(std::string file_name, Node *n)
Performs a allowed - validity check on the xml tree.
std::set< std::string > explodeString(std::string s, char delimiter)
Explodes a string based on a delimiter.
Implements the main functionalities of the stdr parser tree.
std::string file_origin
Row in the original file.
Validator(void)
Default constructor.
std::vector< Node * > elements
File it was into.
Provides a parser exception. Publicly inherits from std::runtime_error. Used in robot handler...


stdr_parser
Author(s): Manos Tsardoulias, Chris Zalidis, Aris Thallas
autogenerated on Mon Jun 10 2019 15:14:54