Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdr_parser/stdr_parser_validator.h"
00023
00024 namespace stdr_parser
00025 {
00030 Validator::Validator(void)
00031 {
00032
00033 }
00034
00041 void Validator::validityAllowedCheck(std::string file_name, Node* n)
00042 {
00044 if(n->value != "")
00045 {
00046 return;
00047 }
00048 std::string tag = n->tag;
00049 if(Specs::specs.find(tag) == Specs::specs.end() &&
00050 tag != "STDR_Parser_Root_Node")
00051 {
00052 std::string error =
00053 std::string("STDR parser : ") + n->tag +
00054 std::string(" is not a valid tag") +
00055 std::string("\nTrail: ");
00056 throw ParserException(error);
00057 }
00058 for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00059 {
00060 std::string child_tag = n->elements[i]->tag;
00061 std::string child_value = n->elements[i]->value;
00062 if(tag != "STDR_Parser_Root_Node" && child_value == "")
00063 {
00064 if(Specs::specs[tag].allowed.find(child_tag) ==
00065 Specs::specs[tag].allowed.end())
00066 {
00067 int decreaser = (extractFilename(n->elements[i]->file_origin) ==
00068 extractFilename(file_name) ? 1 : 0);
00069 std::string error =
00070 std::string("STDR parser : ") + child_tag +
00071 std::string(" is not allowed in a ") + tag + std::string(" tag") +
00072 std::string("\nTrail: ");
00073 error += std::string("\n [") + child_tag + std::string("] Line ") +
00074 SSTR( n->elements[i]->file_row - decreaser ) +
00075 std::string(" of file '") +
00076 extractFilename(n->elements[i]->file_origin) +
00077 std::string("'");
00078 throw ParserException(error);
00079 }
00080 }
00081 try
00082 {
00083 validityAllowedCheck(file_name, n->elements[i]);
00084 }
00085 catch(ParserException ex)
00086 {
00087 if(n->tag == "STDR_Parser_Root_Node")
00088 {
00089 throw ex;
00090 }
00091 int decreaser = (extractFilename(n->file_origin) ==
00092 extractFilename(file_name) ? 1 : 0);
00093 std::string trail(ex.what());
00094 trail += std::string("\n [") + n->tag + std::string("] Line ") +
00095 SSTR( n->file_row - decreaser) +
00096 std::string(" of file '") +
00097 extractFilename(n->file_origin) + std::string("'");
00098 ParserException ex_new(trail);
00099 throw ex_new;
00100 }
00101 }
00102 }
00103
00110 void Validator::validityRequiredCheck(std::string file_name, Node* n)
00111 {
00113 if(n->value != "")
00114 {
00115 return;
00116 }
00117 std::string tag = n->tag;
00118 if(Specs::specs.find(tag) == Specs::specs.end() &&
00119 tag != "STDR_Parser_Root_Node")
00120 {
00121 std::string error =
00122 std::string("STDR parser : ") + n->tag +
00123 std::string(" is not a valid tag") +
00124 std::string("\nTrail: ");
00125 throw ParserException(error);
00126 }
00127 for(std::set<std::string>::iterator it = Specs::specs[tag].required.begin()
00128 ; it != Specs::specs[tag].required.end() ; it++)
00129 {
00130 std::vector<int> num = n->getTag(*it);
00131 if(num.size() == 0)
00132 {
00133 std::string error =
00134 std::string("STDR parser : ") + tag +
00135 std::string(" requires ") + (*it) +
00136 std::string("\nTrail: ");
00137 throw ParserException(error);
00138 }
00139 }
00140 for(unsigned int i = 0 ; i < n->elements.size() ; i++)
00141 {
00142 try
00143 {
00144 validityRequiredCheck(file_name, n->elements[i]);
00145 }
00146 catch(ParserException ex)
00147 {
00148 if(n->tag == "STDR_Parser_Root_Node")
00149 {
00150 throw ex;
00151 }
00152
00153 int decreaser = (extractFilename(n->elements[i]->file_origin) ==
00154 extractFilename(file_name) ? 1 : 0);
00155
00156 std::string trail(ex.what());
00157 trail += std::string("\n [") + n->tag + std::string("] Line ") +
00158 SSTR( n->file_row - decreaser ) +
00159 std::string(" of file '") + extractFilename(n->file_origin)
00160 + std::string("'");
00161 ParserException ex_new(trail);
00162 throw ex_new;
00163 }
00164 }
00165 }
00166
00171 void Validator::parseMergableSpecifications(void)
00172 {
00173 std::string base_path_ = ros::package::getPath("stdr_resources");
00174 std::string path=base_path_ +
00175 std::string("/resources/specifications/stdr_multiple_allowed.xml");
00176 TiXmlDocument doc;
00177 bool loadOkay = doc.LoadFile(path.c_str());
00178 if (!loadOkay)
00179 {
00180 std::string error =
00181 std::string("STDR parser : Failed to load file ") +
00182 path + std::string("'") +
00183 std::string("\nError was \n\t") + std::string(doc.ErrorDesc());
00184 throw ParserException(error);
00185 }
00186 Specs::non_mergable_tags = explodeString(
00187 doc.FirstChild()->FirstChild()->Value(), ',');
00188 }
00189
00195 void Validator::parseSpecifications(TiXmlNode* node)
00196 {
00197 TiXmlNode* pChild;
00198 int type = node->Type();
00199 std::string node_text(node->Value());
00200 switch (type)
00201 {
00202 case 0 :
00203 {
00204 break;
00205 }
00206 case 1 :
00207 {
00208 if(node_text == "specifications")
00209 {
00210 break;
00211 }
00212 else if(node_text!="allowed" && node_text!="required"
00213 && node_text!="default")
00214 {
00215 if(Specs::specs.find(node_text) == Specs::specs.end())
00216 {
00217 Specs::specs.insert(std::pair<std::string,ElSpecs>(
00218 node_text,ElSpecs()));
00219 }
00220 else
00221 {
00222 std::string error =
00223 std::string("STDR parser : Multiple instance of '") + node_text +
00224 std::string("' in specifications.");
00225 throw ParserException(error);
00226 }
00227 }
00228 else
00229 {
00230 break;
00231 }
00232 break;
00233 }
00234 case 4 :
00235 {
00236 std::string base_tag (node->Parent()->Parent()->Value());
00237 std::string base_type(node->Parent()->Value());
00238 if(base_type == "allowed")
00239 {
00240 Specs::specs[base_tag].allowed = explodeString(node_text,',');
00241 }
00242 else if(base_type == "required")
00243 {
00244 Specs::specs[base_tag].required = explodeString(node_text,',');
00245 }
00246 else if(base_type == "default")
00247 {
00248 Specs::specs[base_tag].default_value = node_text;
00249 }
00250 else
00251 {
00252 std::string error =
00253 std::string("STDR parser : Specification '") + base_tag +
00254 std::string("' not in 'allowed', 'required' or 'default' : '") +
00255 base_type + std::string("' / '") + node_text + std::string("'");
00256 throw ParserException(error);
00257 }
00258 break;
00259 }
00260 }
00261
00262 for (
00263 pChild = node->FirstChild();
00264 pChild != 0;
00265 pChild = pChild->NextSibling())
00266 {
00267 try
00268 {
00269 parseSpecifications( pChild );
00270 }
00271 catch(ParserException ex)
00272 {
00273 throw ex;
00274 }
00275 }
00276 }
00277
00284 void Validator::validate(std::string file_name, Node* n)
00285 {
00286
00287 Specs::specs.clear();
00288 Specs::non_mergable_tags.clear();
00289
00290 std::string base_path_ = ros::package::getPath("stdr_resources");
00291
00292 std::string path = base_path_ +
00293 std::string("/resources/specifications/stdr_specifications.xml");
00294
00295 TiXmlDocument doc;
00296 bool loadOkay = doc.LoadFile(path.c_str());
00297 if (!loadOkay)
00298 {
00299 std::string error =
00300 std::string("Failed to load specifications file.\nShould be at '") +
00301 path + std::string("'\nError was") + std::string(doc.ErrorDesc());
00302 throw ParserException(error);
00303 }
00304
00305 try
00306 {
00307 parseSpecifications(&doc);
00308 }
00309 catch(ParserException ex)
00310 {
00311 throw ex;
00312 }
00313
00314 try
00315 {
00316 validityAllowedCheck(file_name, n);
00317 validityRequiredCheck(file_name, n);
00318 }
00319 catch(ParserException ex)
00320 {
00321 throw ex;
00322 }
00323 }
00324 }
00325