/* * XMLRequestParser.cc * * Created on: Nov 23, 2012 * Author: f.casimir */ //Common module include #include "DicError.hh" // DD_Client_r_lib module includes #include "TimeUtil.hh" //Parameters module include #include "ServicesServer.hh" //XMLConfigurator module include #include "NodeCfg.hh" #include "Constant.hh" //XMLRequest module include #include "Config.hh" #include "XMLRequestParser.hh" #include "TimeInterval.hh" #include "TimeTableCatalogFactory.hh" #include "TimeTable.hh" #include "Catalog.hh" #include // Using namespace using namespace log4cxx; using namespace AMDA::Parameters; using namespace AMDA::XMLConfigurator; using namespace TimeTableCatalog; namespace AMDA { namespace XMLRequest { class ParamNode : public NodeCfg { public: void proceed(xmlNodePtr pNode,const AMDA::Parameters::CfgContext& pContext) { ParameterManager* lParameterManager = pContext.get(); xmlChar* lParamName = NULL; try { if (!(lParamName = xmlGetProp(pNode, (const xmlChar *) "id"))) { ERROR_EXCEPTION( ERROR_MANDATORY_ATTRIBUTE_MISSING << pNode->name << "@" << PARAMNAME) } lParameterManager->createParameter(std::string((char*)lParamName)); } catch (...) { //This parameter is ignored, continue // if (lParamName) { // xmlFree(lParamName); // } // throw; } if (lParamName) { xmlFree(lParamName); } } }; class IntervalNode : public NodeGrpCfg { public: class StartTimeNode : public NodeCfg { public: void proceed(xmlNodePtr pNode,const AMDA::Parameters::CfgContext& pContext) { IntervalNode* lIntervalNode = pContext.get(); double lStartTime = DD_Time2Double((const char*)pNode->children->content); lIntervalNode->_startTime = lStartTime; } }; class TimeIntervalNode : public NodeCfg { public: void proceed(xmlNodePtr pNode, const AMDA::Parameters::CfgContext& pContext) { IntervalNode* lIntervalNode = pContext.get(); double lTimeInt = DD_Time2Double((const char*)pNode->children->content); lIntervalNode->_timeInt = lTimeInt; } }; IntervalNode () : NodeGrpCfg(), _startTime(0), _timeInt(0) { getChildList()["startTime"] = NodeCfgSPtr(new StartTimeNode); getChildList()["timeInterval"] = NodeCfgSPtr(new TimeIntervalNode); } void proceed(xmlNodePtr pNode, const AMDA::Parameters::CfgContext& pContext) { LOG4CXX_DEBUG(gLogger, "IntervalNode::proceed"); // Create new context CfgContext lContext; lContext.push(this); // Go to next node NodeGrpCfg::proceed(pNode, lContext); // Get manager of the new output parameter for this node ParameterManager* lParameterManager = pContext.get(); lParameterManager->addInputInterval(_startTime, _startTime + _timeInt, 0); } double _startTime; double _timeInt; }; class TimeTableNode : public NodeCfg { public: void proceed(xmlNodePtr pNode, const AMDA::Parameters::CfgContext& pContext) { xmlChar* lTTName = NULL; ParameterManager* lParameterManager = pContext.get(); if (!(lTTName = xmlGetProp(pNode, (const xmlChar *) "id"))) { ERROR_EXCEPTION( AMDA::XMLConfigurator::ERROR_MANDATORY_ATTRIBUTE_MISSING << pNode->name << "@" << AMDA::XMLConfigurator::TIMETABLENAME) } std::string lStrTTName((const char*)lTTName); if(lTTName){ xmlFree(lTTName); } lParameterManager->setTimeTablePath(lStrTTName); // check local file exists // if distant file does not exist an error will be thrown in the next if if((lStrTTName.find("http://")!=std::string::npos && lStrTTName.find("https://")!=std::string::npos) && !boost::filesystem::exists(lStrTTName)){ ERROR_EXCEPTION( AMDA::XMLConfigurator::ERROR_FILE_NOT_EXIST << lStrTTName); } // Read file std::string lReaderType = TimeTableCatalogFactory::getInstance().getReaderType(lStrTTName); if(lReaderType.empty()){ ERROR_EXCEPTION( "Unknown Timetable : " << lStrTTName); } TimeTableCatalog::TimeTable inputTT; inputTT.read(lStrTTName, lReaderType); const std::vector lTimeIntervalList = inputTT.getIntervals(); // Get interval index if exists xmlChar* lTTIndex = xmlGetProp(pNode, (const xmlChar *) "index"); if (lTTIndex) { //Add only interval designate by index size_t index = atoi( (const char*)lTTIndex ); xmlFree(lTTIndex); if (index >= lTimeIntervalList.size()) { ERROR_EXCEPTION( "Cannot find index : " << index << " in TimeTable : " << lStrTTName); } lParameterManager->addInputInterval( lTimeIntervalList[index]._startTime, lTimeIntervalList[index]._stopTime, lTimeIntervalList[index]._index); } else { //Add all intervals for(std::vector::const_iterator it = lTimeIntervalList.begin(); it != lTimeIntervalList.end(); ++it) { lParameterManager->addInputInterval(it->_startTime, it->_stopTime, it->_index); } } } }; class CatalogNode : public NodeCfg { public: void proceed(xmlNodePtr pNode, const AMDA::Parameters::CfgContext& pContext) { xmlChar* lCatalogName = NULL; ParameterManager* lParameterManager = pContext.get(); if (!(lCatalogName = xmlGetProp(pNode, (const xmlChar *) "id"))) { ERROR_EXCEPTION( AMDA::XMLConfigurator::ERROR_MANDATORY_ATTRIBUTE_MISSING << pNode->name << "@" << AMDA::XMLConfigurator::TIMETABLENAME) } std::string lStrCatalogName((const char*)lCatalogName); if(lCatalogName){ xmlFree(lCatalogName); } lParameterManager->setTimeTablePath(lStrCatalogName); // check local file exists // if distant file does not exist an error will be thrown in the next if if((lStrCatalogName.find("http://")!=std::string::npos && lStrCatalogName.find("https://")!=std::string::npos) && !boost::filesystem::exists(lStrCatalogName)){ ERROR_EXCEPTION( AMDA::XMLConfigurator::ERROR_FILE_NOT_EXIST << lStrCatalogName); } // Read file std::string lReaderType = TimeTableCatalogFactory::getInstance().getReaderType(lStrCatalogName); if(lReaderType.empty()){ ERROR_EXCEPTION( "Unknown Catalog : " << lStrCatalogName); } TimeTableCatalog::Catalog inputCatalog; inputCatalog.read(lStrCatalogName, lReaderType); std::vector lTimeIntervalList = inputCatalog.getIntervals(); // Get interval index if exists xmlChar* lCatalogIndex = xmlGetProp(pNode, (const xmlChar *) "index"); if (lCatalogIndex) { //Add only interval designate by index size_t index = atoi( (const char*)lCatalogIndex ); xmlFree(lCatalogIndex); if (index >= lTimeIntervalList.size()) { ERROR_EXCEPTION( "Cannot find index : " << index << " in Catalog : " << lStrCatalogName); } lParameterManager->addInputInterval( lTimeIntervalList[index]._startTime, lTimeIntervalList[index]._stopTime, lTimeIntervalList[index]._index); for (auto &desc : inputCatalog.getParameterDescriptions()) { lParameterManager->addInputIntervalDataList(index, desc.getId(), lTimeIntervalList[index].getParameterData(desc.getId())); } } else { //Add all intervals for(std::vector::const_iterator it = lTimeIntervalList.begin(); it != lTimeIntervalList.end(); ++it) { lParameterManager->addInputInterval(it->_startTime, it->_stopTime, it->_index); for (auto &desc : inputCatalog.getParameterDescriptions()) lParameterManager->addInputIntervalDataList(it->_index, desc.getId(), lTimeIntervalList[it->_index].getParameterData(desc.getId())); } } } }; XMLRequestParser::XMLRequestParser(const char* pXSDFile) : XMLConfigurator(pXSDFile,false) { /* 2008000000000000 0000000100000000 ISO ISO */ // Request root node NodeGrpCfg* lRequestNode = new NodeGrpCfg(); getXmlConfiguratorMap()["request"] = RootNodeCfgSPtr(lRequestNode); { // Params group node NodeGrpCfg* lParamsNode = new NodeGrpCfg(); lRequestNode->getChildList()["params"] = NodeCfgSPtr(lParamsNode); lParamsNode->getChildList()["param"] = NodeCfgSPtr(new ParamNode); } { // Times group node NodeGrpCfg* lTimeNode = new NodeGrpCfg(); lRequestNode->getChildList()["times"] = NodeCfgSPtr(lTimeNode); { // Interval group node NodeGrpCfg* lIntervalNode = new IntervalNode(); lTimeNode->getChildList()["interval"] = NodeCfgSPtr(lIntervalNode); } { // Timetable group node lTimeNode->getChildList()["timetable"] = NodeCfgSPtr( new TimeTableNode); } { // Catalog group node lTimeNode->getChildList()["catalog"] = NodeCfgSPtr( new CatalogNode); } } { // Output group node NodeGrpCfg* lOutputNode = new NodeGrpCfg(); lRequestNode->getChildList()["outputs"] = NodeCfgSPtr(lOutputNode); } } XMLRequestParser::~XMLRequestParser() { } void XMLRequestParser::operator()( AMDA::Parameters::ParameterManager& lParameterManager, const std::string& requestFile) { CfgContext ctx; ctx.push(&lParameterManager); ctx.push(ServicesServer::getInstance()); try { XMLConfigurator::proceed(requestFile.c_str(), ctx); } catch (AMDA::AMDA_exception & e) { e << AMDA::errno_code(AMDA_INFORMATION_REQUEST_ERR); throw; } } } /* namespace XMLRequest */ } /* namespace AMDA */