#include <config.h>
#include <utils/common/MsgHandler.h>
#include <utils/common/StringUtils.h>
#include <utils/xml/XMLSubSys.h>
#include "DataHandler.h"
DataHandler::DataHandler(const std::string& filename) :
CommonHandler(filename),
SUMOSAXHandler(filename) {
}
DataHandler::~DataHandler() {}
bool
DataHandler::parse() {
return XMLSubSys::runParser(*this, getFileName());
}
void
DataHandler::parseSumoBaseObject(CommonXMLStructure::SumoBaseObject* obj) {
if (!myAbortLoading) {
switch (obj->getTag()) {
case SUMO_TAG_INTERVAL:
if (buildDataInterval(obj,
obj->getStringAttribute(SUMO_ATTR_ID),
obj->getDoubleAttribute(SUMO_ATTR_BEGIN),
obj->getDoubleAttribute(SUMO_ATTR_END))) {
obj->markAsCreated();
}
break;
case SUMO_TAG_EDGE:
if (buildEdgeData(obj,
obj->getStringAttribute(SUMO_ATTR_ID),
obj->getParameters())) {
obj->markAsCreated();
}
break;
case SUMO_TAG_EDGEREL:
if (buildEdgeRelationData(obj,
obj->getStringAttribute(SUMO_ATTR_FROM),
obj->getStringAttribute(SUMO_ATTR_TO),
obj->getParameters())) {
obj->markAsCreated();
}
break;
case SUMO_TAG_TAZREL:
if (buildTAZRelationData(obj,
obj->getStringAttribute(SUMO_ATTR_FROM),
obj->getStringAttribute(SUMO_ATTR_TO),
obj->getParameters())) {
obj->markAsCreated();
}
break;
default:
break;
}
for (const auto& child : obj->getSumoBaseObjectChildren()) {
parseSumoBaseObject(child);
}
}
}
void
DataHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) {
const SumoXMLTag tag = (element == 0) ? SUMO_TAG_ROOTFILE : static_cast<SumoXMLTag>(element);
myCommonXMLStructure.openSUMOBaseOBject();
try {
switch (tag) {
case SUMO_TAG_INTERVAL:
parseInterval(attrs);
break;
case SUMO_TAG_EDGE:
parseEdgeData(attrs);
break;
case SUMO_TAG_EDGEREL:
parseEdgeRelationData(attrs);
break;
case SUMO_TAG_TAZREL:
parseTAZRelationData(attrs);
break;
case SUMO_TAG_PARAM:
WRITE_WARNING(TL("Data elements cannot load attributes as params"));
myCommonXMLStructure.abortSUMOBaseOBject();
break;
default:
myCommonXMLStructure.abortSUMOBaseOBject();
break;
}
} catch (InvalidArgument& e) {
writeError(e.what());
}
}
void
DataHandler::myEndElement(int element) {
const SumoXMLTag tag = static_cast<SumoXMLTag>(element);
CommonXMLStructure::SumoBaseObject* obj = myCommonXMLStructure.getCurrentSumoBaseObject();
myCommonXMLStructure.closeSUMOBaseOBject();
if (obj) {
switch (tag) {
case SUMO_TAG_INTERVAL:
parseSumoBaseObject(obj);
delete obj;
break;
default:
break;
}
}
}
void
DataHandler::parseInterval(const SUMOSAXAttributes& attrs) {
bool parsedOk = true;
const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
const double begin = attrs.get<double>(SUMO_ATTR_BEGIN, "", parsedOk);
const double end = attrs.get<double>(SUMO_ATTR_END, "", parsedOk);
if (parsedOk) {
myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_INTERVAL);
myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_BEGIN, begin);
myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_END, end);
} else {
myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
}
}
void
DataHandler::parseEdgeData(const SUMOSAXAttributes& attrs) {
bool parsedOk = true;
const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
getAttributes(attrs, {SUMO_ATTR_ID});
if (parsedOk) {
myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_EDGE);
myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
} else {
myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
}
}
void
DataHandler::parseEdgeRelationData(const SUMOSAXAttributes& attrs) {
bool parsedOk = true;
const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, "", parsedOk);
const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, "", parsedOk);
getAttributes(attrs, {SUMO_ATTR_FROM, SUMO_ATTR_TO});
if (parsedOk) {
myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_EDGEREL);
myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
} else {
myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
}
}
void
DataHandler::parseTAZRelationData(const SUMOSAXAttributes& attrs) {
bool parsedOk = true;
const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, "", parsedOk);
const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, "", parsedOk);
getAttributes(attrs, {SUMO_ATTR_FROM, SUMO_ATTR_TO});
if (parsedOk) {
myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TAZREL);
myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
} else {
myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
}
}
void
DataHandler::getAttributes(const SUMOSAXAttributes& attrs, const std::vector<SumoXMLAttr> avoidAttributes) const {
std::vector<std::string> avoidAttributesStr;
for (const SumoXMLAttr& avoidAttribute : avoidAttributes) {
avoidAttributesStr.push_back(toString(avoidAttribute));
}
for (const std::string& attribute : attrs.getAttributeNames()) {
if (std::find(avoidAttributesStr.begin(), avoidAttributesStr.end(), attribute) == avoidAttributesStr.end()) {
myCommonXMLStructure.getCurrentSumoBaseObject()->addParameter(attribute, attrs.getStringSecure(attribute, ""));
}
}
}
void
DataHandler::checkParent(const SumoXMLTag currentTag, const SumoXMLTag parentTag, bool& ok) {
if ((myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject() &&
(myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject()->getTag() == parentTag)) == false) {
writeError(toString(currentTag) + " must be defined within the definition of a " + toString(parentTag));
ok = false;
}
}