00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00042
00043
00044 #include <stdlib.h>
00045 #include "../tool/FixWinCE.h"
00046 #include <ace/Log_Msg.h>
00047 #include <ace/Env_Value_T.h>
00048 #include "../tool/OT_ACE_Log.h"
00049
00050 #include "ConfigurationParser.h"
00051
00052 #ifdef USE_XERCES
00053 #include <xercesc/dom/DOM.hpp>
00054 #include <xercesc/util/XMLString.hpp>
00055 #include <xercesc/util/XMLUniDefs.hpp>
00056 #include <xercesc/parsers/XercesDOMParser.hpp>
00057 #include <xercesc/util/PlatformUtils.hpp>
00058 #include <xercesc/util/XMLEntityResolver.hpp>
00059 #include <xercesc/framework/LocalFileInputSource.hpp>
00060 #endif //USE_XERCES
00061
00062 #include "DOMTreeErrorReporter.h"
00063 #include "RefNode.h"
00064
00065 #include <iostream>
00066
00067
00068
00069 #ifdef USE_XERCES
00070 XERCES_CPP_NAMESPACE_USE
00071 #endif //USE_XERCES
00072
00073
00074 namespace ot {
00075
00076 #ifdef USE_XERCES
00077 const XMLCh ud_node[] = { chLatin_n, chLatin_o, chLatin_d, chLatin_e, chNull };
00078
00079 class OpenTrackerResolver : public XMLEntityResolver {
00080 protected:
00081 Context * context;
00082
00083 public:
00084 OpenTrackerResolver ( Context * context_ ) : context(context_)
00085 {};
00086
00087 virtual InputSource * resolveEntity( XMLResourceIdentifier * resourceIdentifier );
00088 };
00089
00090 InputSource * OpenTrackerResolver::resolveEntity( XMLResourceIdentifier * resourceIdentifier )
00091 {
00092 if (resourceIdentifier->getResourceIdentifierType() == XMLResourceIdentifier::ExternalEntity)
00093 {
00094 XMLCh * test = XMLString::transcode("opentracker.dtd");
00095 if(XMLString::endsWith(resourceIdentifier->getSystemId(), test))
00096 {
00097 ACE_Env_Value<std::string> otroot(ACE_TEXT("OTROOT"), "");
00098 std::string otrootvalue = (std::string)otroot;
00099 std::string otdatadir;
00100 if( otrootvalue.compare("") != 0 )
00101 {
00102 otdatadir = otrootvalue + "/data";
00103 context->addDirectoryLast(otdatadir);
00104 }
00105 char * file = XMLString::transcode(resourceIdentifier->getSystemId());
00106 std::string filename( file ), fullname;
00107 XMLString::release( &file );
00108 bool result = context->findFile( filename, fullname );
00109 if( otrootvalue.compare("") != 0 )
00110 {
00111 context->removeDirectory(otdatadir);
00112 }
00113 if( result == true )
00114 {
00115 XMLCh * file = XMLString::transcode( fullname.c_str());
00116 LocalFileInputSource * input = new LocalFileInputSource( file );
00117 XMLString::release( &file );
00118 XMLString::release( &test );
00119 return input;
00120 }
00121 }
00122 XMLString::release( &test );
00123 }
00124 return NULL;
00125 }
00126
00127 #endif //USE_XERCES
00128
00129
00130
00131 ConfigurationParser::ConfigurationParser( Context & context_)
00132 : context( context_ )
00133 {
00134 #ifdef USE_XERCES
00135
00136 try {
00137 XMLPlatformUtils::Initialize();
00138 }
00139 catch (const XMLException& toCatch) {
00140 char * message = XMLString::transcode( toCatch.getMessage());
00141 LOG_ACE_ERROR( "ot: ConfigurationParser Error during initialization: %s\n", message );
00142 XMLString::release( &message );
00143 exit(1);
00144 }
00145 #endif //USE_XERCES
00146 }
00147
00148
00149
00150 ConfigurationParser::~ConfigurationParser()
00151 {
00152 references.clear();
00153 }
00154
00155
00156
00157 ConfigNode * ConfigurationParser::buildConfigTree( OT_DOMELEMENT * element )
00158 {
00159 #ifdef USE_XERCES
00160 std::auto_ptr<StringTable> map ( parseElement( element ));
00161 char * tempName = XMLString::transcode( element->getLocalName());
00162 std::string tagName = tempName;
00163 XMLString::release( &tempName );
00164 ConfigNode * config = new ConfigNode( *map );
00165 config->setParent( element );
00166
00167 DOMNodeList * list = element->getChildNodes();
00168 for( unsigned int i = 0; i < list->getLength(); i ++ )
00169 {
00170 if( list->item(i)->getNodeType() == DOMNode::ELEMENT_NODE )
00171 {
00172 OT_DOMELEMENT * childElement = (OT_DOMELEMENT *)list->item(i);
00173 ConfigNode * child = buildConfigTree( childElement );
00174 }
00175 }
00176 return config;
00177 #endif //USE_XERCES
00178
00179 #ifdef USE_TINYXML
00180 std::auto_ptr<StringTable> map ( parseElement( element ));
00181 std::string tagName = element->Value();
00182 ConfigNode * config = new ConfigNode( *map );
00183 config->setParent( element );
00184
00185 TiXmlElement * el = element->FirstChildElement();
00186 while( el != NULL )
00187 {
00188 ConfigNode * child = buildConfigTree( el);
00189 el = el->NextSiblingElement();
00190 }
00191 return config;
00192 #endif //USE_TINYXML
00193 }
00194
00195
00196
00197 Node * ConfigurationParser::buildTree( OT_DOMELEMENT * element)
00198 {
00199 #ifdef USE_XERCES
00200 char * tempName = XMLString::transcode( element->getLocalName());
00201 std::string tagName = tempName;
00202 XMLString::release( &tempName );
00203 std::auto_ptr<StringTable> map ( parseElement( element ));
00204
00205 if( tagName.compare("Ref") == 0 )
00206 {
00207 NodeMap::iterator find = references.find(map->get("USE"));
00208 if( find != references.end()){
00209 RefNode * ref = new RefNode( (*find).second );
00210 ref->type = tagName;
00211 ref->setParent( element );
00212 LOG_ACE_INFO("ot:Build Reference node -> %s\n", map->get("USE").c_str());
00213 return ref;
00214 } else
00215 {
00216 LOG_ACE_ERROR("ot:Undefined reference %s\n", map->get("USE").c_str());
00217 return NULL;
00218 }
00219 }
00220
00221 Node * value = context.factory.createNode( tagName , *map );
00222 if( value != NULL )
00223 {
00224 value->setParent( element );
00225
00226 if( map->containsKey("DEF"))
00227 {
00228 references[map->get("DEF")] = value;
00229 value->name = map->get("DEF");
00230 LOG_ACE_INFO("ot:Storing Reference %s\n", map->get("USE").c_str());
00231 }
00232
00233 DOMNodeList * list = element->getChildNodes();
00234 for( unsigned int i = 0; i < list->getLength(); i ++ )
00235 {
00236 if( list->item(i)->getNodeType() == DOMNode::ELEMENT_NODE )
00237 {
00238 OT_DOMELEMENT * childElement = (OT_DOMELEMENT *)list->item(i);
00239 Node * childNode = buildTree( childElement );
00240 }
00241 }
00242 }
00243 else
00244 {
00245 LOG_ACE_INFO("ot:Warning : Could not parse element %s\n", tagName.c_str());
00246 }
00247 return value;
00248 #endif //USE_XERCES
00249
00250 #ifdef USE_TINYXML
00251 std::string tagName = element->Value();
00252 std::auto_ptr<StringTable> map ( parseElement( element ));
00253
00254 if( tagName.compare("Ref") == 0 )
00255 {
00256 NodeMap::iterator find = references.find(map->get("USE"));
00257 if( find != references.end()){
00258 RefNode * ref = new RefNode( (*find).second );
00259 ref->type = tagName;
00260 ref->setParent( element );
00261 LOG_ACE_INFO("ot:Build Reference node -> %s\n", map->get("USE").c_str());
00262 return ref;
00263 } else
00264 {
00265 LOG_ACE_ERROR("ot:Undefined reference %s\n", map->get("USE").c_str());
00266 return NULL;
00267 }
00268 }
00269
00270 Node * value = context.factory.createNode( tagName , *map );
00271 if( value != NULL )
00272 {
00273 value->setParent( element );
00274
00275 if( map->containsKey("DEF"))
00276 {
00277 references[map->get("DEF")] = value;
00278 value->name = map->get("DEF");
00279 LOG_ACE_INFO("ot:Storing Reference %s\n", map->get("USE").c_str());
00280 }
00281
00282 TiXmlElement * el = element->FirstChildElement();
00283 while( el != NULL )
00284 {
00285 Node * childNode = buildTree( el );
00286 el = el->NextSiblingElement();
00287 }
00288 }
00289 else
00290 {
00291 LOG_ACE_INFO("ot:Warning : Could not parse element %s\n", tagName.c_str());
00292 }
00293 return value;
00294 #endif //USE_TINYXML
00295 }
00296
00297
00298
00299
00300 Node * ConfigurationParser::parseConfigurationFile(const std::string& filename)
00301 {
00302 #ifdef USE_XERCES
00303
00304 XercesDOMParser * parser = new XercesDOMParser();
00305 parser->setValidationScheme( XercesDOMParser::Val_Auto );
00306 parser->setIncludeIgnorableWhitespace( false );
00307 parser->setDoNamespaces(true);
00308 parser->setDoSchema(true);
00309
00310 OpenTrackerResolver resolver( &context);
00311 parser->setXMLEntityResolver( &resolver );
00312
00313 DOMTreeErrorReporter errReporter;
00314 parser->setErrorHandler( &errReporter );
00315
00316 try
00317 {
00318 parser->parse( filename.c_str() );
00319 }
00320 catch (const XMLException& e)
00321 {
00322 char * message = XMLString::transcode( e.getMessage());
00323 LOG_ACE_ERROR("ot:An error occured during parsing\n Message: %s\n", message);
00324 XMLString::release( & message );
00325 exit(1);
00326 }
00327 catch (const DOMException& e)
00328 {
00329 char * message = XMLString::transcode( e.msg );
00330 LOG_ACE_ERROR("ot:An error occured during parsing\n Message: %s\n", message);
00331 XMLString::release( & message );
00332 exit(1);
00333 }
00334 if( errReporter.errorsEncountered() > 0 )
00335 {
00336 LOG_ACE_ERROR("ot:There were non fatal errors in the configuration file !\n");
00337 LOG_ACE_ERROR("ot:Please check the file and start again.\n");
00338 exit(1);
00339 }
00340
00341 DOMDocument * doc = parser->getDocument();
00342 DOMElement * root = doc->getDocumentElement();
00343 Node * node = new Node();
00344 node->setParent( root );
00345 char * tempName = XMLString::transcode( root->getLocalName());
00346 LOG_ACE_INFO("ot:Root node is %s\n", tempName);
00347 XMLString::release( & tempName );
00348
00349 const XMLCh* xmlspace = root->getNamespaceURI();
00350 if (xmlspace != NULL) {
00351 char * tempSpace = XMLString::transcode( xmlspace );
00352 LOG_ACE_INFO("ot:Namespace is %s\n", tempSpace);
00353 XMLString::release( & tempSpace );
00354 }
00355 else {
00356 ACE_DEBUG((LM_INFO, ACE_TEXT("ot:Not using namespaces!\n")));
00357 }
00358
00359
00360 XMLCh * configurationCh = XMLString::transcode( "configuration" );
00361
00362 DOMNodeList * list = root->getElementsByTagNameNS(xmlspace, configurationCh);
00363 XMLString::release( & configurationCh );
00364 if( list->getLength() != 1 )
00365 {
00366 ACE_DEBUG((LM_ERROR, ACE_TEXT("ot:not valid config file, not exactly one configuration tag\n")));
00367 LOG_ACE_INFO("ot:%d configurations.\n", list->getLength());
00368 exit(1);
00369 }
00370
00371 ACE_DEBUG((LM_INFO, ACE_TEXT("ot:parsing configuration section\n")));
00372
00373
00374 DOMElement * config = (DOMElement *)list->item(0);
00375
00376 DOMNodeList * configlist = config->getChildNodes();
00377 unsigned int i;
00378 for( i = 0; i < configlist->getLength(); i ++ )
00379 {
00380 if( configlist->item(i)->getNodeType() == DOMNode::ELEMENT_NODE )
00381 {
00382 DOMElement * configElement = (DOMElement *)configlist->item(i);
00383 std::auto_ptr<StringTable> attributes( parseElement( configElement ));
00384 char * tempName = XMLString::transcode( configElement->getLocalName());
00385 std::string tagName = tempName;
00386 XMLString::release( &tempName );
00387 ConfigNode * base = new ConfigNode( *attributes );
00388 base->setParent( configElement );
00389 LOG_ACE_INFO("ot:config for %s\n", tagName.c_str());
00390
00391
00392 DOMNodeList * nodelist = configElement->getChildNodes();
00393
00394 unsigned int j;
00395 for( j = 0; j < nodelist->getLength(); j++ )
00396 {
00397 if( nodelist->item(j)->getNodeType() == DOMNode::ELEMENT_NODE )
00398 {
00399 DOMElement * element = (DOMElement *)nodelist->item(j);
00400 ConfigNode * child = buildConfigTree( element );
00401 }
00402 }
00403 Module * module = context.getModule( tagName );
00404 if( module != NULL )
00405 {
00406 module->init( *attributes, base );
00407 }
00408 }
00409 }
00410
00411 ACE_DEBUG((LM_INFO, ACE_TEXT("ot:parsing tracker tree section\n")));
00412
00413
00414
00415 DOMNodeList * rootlist = root->getChildNodes();
00416 for( i = 0; i < rootlist->getLength(); i++ )
00417 {
00418 if( rootlist->item(i)->getNodeType() != DOMNode::ELEMENT_NODE )
00419 {
00420 continue;
00421 }
00422 DOMElement * element = (DOMElement *)rootlist->item(i);
00423 char * tempTagName = XMLString::transcode(element->getLocalName());
00424 if( 0 == XMLString::compareString( tempTagName, "configuration" ))
00425 {
00426 XMLString::release( &tempTagName );
00427 continue;
00428 }
00429 XMLString::release( &tempTagName );
00430 buildTree( element );
00431 }
00432 return node;
00433 #endif //USE_XERCES
00434
00435
00436 #ifdef USE_TINYXML
00437 TiXmlDocument* document = new TiXmlDocument();
00438
00439 if(!document->LoadFile(filename.c_str()))
00440 {
00441 LOG_ACE_ERROR("ot:An error occured during parsing\n Message: %s\n", document->ErrorDesc());
00442 exit(1);
00443 }
00444
00445 TiXmlElement* root = document->RootElement();
00446 Node * node = new Node();
00447 node->setParent( root );
00448 const char* tempName = root->Value();
00449
00450 LOG_ACE_INFO("ot:Root node is %s\n", tempName);
00451
00452 const char* xmlspace = NULL;
00453 if (xmlspace != NULL) {
00454 LOG_ACE_INFO("ot:Namespace is %s\n", xmlspace);
00455 }
00456 else {
00457 ACE_DEBUG((LM_INFO, ACE_TEXT("ot:Not using namespaces!\n")));
00458 }
00459
00460
00461 const char* configurationCh = "configuration";
00462
00463 TiXmlElement * config = root->FirstChildElement(configurationCh);
00464 if(config->NextSiblingElement(configurationCh))
00465 {
00466 ACE_DEBUG((LM_INFO, ACE_TEXT("ot:not valid config file, not exactly one configuration tag\n")));
00467 exit(1);
00468 }
00469
00470 ACE_DEBUG((LM_INFO, ACE_TEXT("ot:parsing configuration section\n")));
00471
00472 TiXmlElement * configElement = config->FirstChildElement();
00473 while(configElement)
00474 {
00475 std::auto_ptr<StringTable> attributes( parseElement( configElement ));
00476 std::string tagName = configElement->Value();
00477 ConfigNode * base = new ConfigNode( *attributes );
00478 base->setParent( configElement );
00479 LOG_ACE_INFO("ot:config for %s\n", tagName.c_str());
00480
00481 TiXmlElement * element = configElement->FirstChildElement();
00482 while(element)
00483 {
00484 ConfigNode * child = buildConfigTree( element );
00485 element = element->NextSiblingElement();
00486 }
00487
00488 Module * module = context.getModule( tagName );
00489 if( module != NULL )
00490 {
00491 module->init( *attributes, base );
00492 }
00493
00494 configElement = configElement->NextSiblingElement();
00495 }
00496
00497 ACE_DEBUG((LM_INFO, ACE_TEXT("ot:parsing tracker tree section\n")));
00498
00499
00500
00501 TiXmlElement * element = root->FirstChildElement();
00502 while(element)
00503 {
00504 if(strcmp(element->Value(), "configuration")!=0)
00505 buildTree( element );
00506
00507 element = element->NextSiblingElement();
00508 }
00509
00510 return node;
00511 #endif //USE_TINYXML
00512 }
00513
00514
00515
00516 StringTable * ConfigurationParser::parseElement( OT_DOMELEMENT * element)
00517 {
00518 #ifdef USE_XERCES
00519 StringTable * value = new StringTable;
00520
00521 DOMNamedNodeMap * map = element->getAttributes();
00522 for( unsigned int i = 0; i < map->getLength(); i++ )
00523 {
00524 DOMAttr * attribute = (DOMAttr *)map->item( i );
00525 char * nameTemp = XMLString::transcode( attribute->getName());
00526 char * valueTemp = XMLString::transcode( attribute->getValue());
00527 value->put(nameTemp, valueTemp );
00528 XMLString::release( &valueTemp );
00529 XMLString::release( &nameTemp );
00530 }
00531 return value;
00532 #endif //USE_XERCES
00533
00534
00535 #ifdef USE_TINYXML
00536 StringTable * value = new StringTable;
00537
00538 TiXmlAttribute* attribute = element->FirstAttribute();
00539 while(attribute)
00540 {
00541 value->put(attribute->Name(), attribute->Value());
00542 attribute = attribute->Next();
00543 }
00544 return value;
00545 #endif //USE_TINYXML
00546 }
00547
00548
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565