/* * VOTableReader.cc * * Created on: 7 août 2013 * Author: CS */ #include "VOTableData.hh" #include "VOTableReader.hh" #include "TimeTableCatalogUtil.hh" #include "Catalog.hh" #include #include namespace TimeTableCatalog { const std::string VOTableReader::FORMAT = "VO"; VOTableReader::VOTableReader(const std::string& pPath) : XMLReader(pPath) { _tmpIntervalstartdate = -1; _mainDescriptionRead = false; _ttDescriptionRead = false; _readingDescription = false; _readingField = false; _readingTr = false; _readingTd = false; _tdCount = 0; } VOTableReader::~VOTableReader() { } // ---------------- PUBLIC ------------------- std::unique_ptr VOTableReader::createInstance( const std::string& pPath) { return std::unique_ptr < AbstractReader > (new VOTableReader(pPath)); } std::string VOTableReader::getFirstNode() { return VOTableData::VOTABLE_TAG; } // ----------------- PRIVATE -------------------------- /** * * @pTT : the timetable to load * @reader: the xmlReader * * Fills the given TimeTable with the xml file content */ void VOTableReader::processNode(TimeTable& pTT, xmlTextReaderPtr reader, int &crtIndex) { const xmlChar *name; // -- read tag name = xmlTextReaderConstName(reader); if (name == NULL) name = BAD_CAST "--"; // get tag name to easily handle it std::string tagName = reinterpret_cast(name); if (tagName == VOTableData::DESCRIPTION_TAG) { _readingDescription = !_readingDescription; } else if (tagName == VOTableData::FIELD_TAG) { _readingField = !_readingField; if (_readingField) { readField (pTT, reader); } } else if (tagName == VOTableData::TR_TAG) { _readingTr = !_readingTr; // Reset td count for each tr end if (_readingTr == false) _tdCount = 0; } else if (tagName == VOTableData::TD_TAG) { _readingTd = !_readingTd; } else if (tagName == "#text") { if (_readingDescription == true) { readDescription (pTT, reader); } if (_readingTr == true) { readInterval (pTT, reader, crtIndex); ++crtIndex; _tdCount++; } } } void VOTableReader::readDescription(TimeTable& pTT, xmlTextReaderPtr reader) { // -- read tag text (may be NULL) const xmlChar *value = xmlTextReaderConstValue(reader); std::string tagValue = reinterpret_cast(value); if (_mainDescriptionRead == false) { readMetadata(tagValue, pTT); _mainDescriptionRead = true; } else if (_ttDescriptionRead == false) { if (value != NULL) split(tagValue, '\n', pTT._description); else pTT._description.clear(); _ttDescriptionRead = true; } else { ParameterDescription *pd = pTT.getLastParameterDescritption(); pd->setDescription(tagValue); } } void VOTableReader::readField(TimeTable& pTT, xmlTextReaderPtr reader) { const xmlChar *attrName; attrName = xmlTextReaderGetAttribute (reader, (const xmlChar*)VOTableData::FIELD_NAME_ATTRIB.c_str()); // Jump startTime & stopTime tag if ((strcmp ((char *) attrName, "startTime") != 0) && (strcmp ((char *) attrName, "stopTime") != 0)){ const xmlChar *attrId, *attrSize, *attrType, *attrUnit, *attrUcd, *attrUtype; attrId = xmlTextReaderGetAttribute (reader, (const xmlChar*)VOTableData::FIELD_ID_ATTRIB.c_str()); attrSize = xmlTextReaderGetAttribute (reader, (const xmlChar*)VOTableData::FIELD_ARRAYSIZE_ATTRIB.c_str()); attrType = xmlTextReaderGetAttribute (reader, (const xmlChar*)VOTableData::FIELD_DATATYPE_ATTRIB.c_str()); attrUnit = xmlTextReaderGetAttribute (reader, (const xmlChar*)VOTableData::FIELD_UNIT_ATTRIB.c_str()); attrUcd = xmlTextReaderGetAttribute (reader, (const xmlChar*)VOTableData::FIELD_UCD_ATTRIB.c_str()); attrUtype = xmlTextReaderGetAttribute (reader, (const xmlChar*)VOTableData::FIELD_UTYPE_ATTRIB.c_str()); ParameterDescription::ParameterType internalType; std::string voType = std::string((const char *)attrType); if (voType == "char") { internalType = ParameterDescription::ParameterType::String; } else if (voType == "int") { internalType = ParameterDescription::ParameterType::Integer; } else if (voType == "double") { internalType = ParameterDescription::ParameterType::Double; } else { internalType = ParameterDescription::ParameterType::Unknown; } std::string internalSize("1"); if (((char *) attrSize) != NULL) { internalSize = std::string((const char *)attrSize); } ((Catalog *) &pTT)->addParameterDescription(ParameterDescription( std::string((const char *)attrId), std::string((const char *)attrName), internalSize, internalType, std::string((const char *)attrUnit), "", // Read later std::string((const char *)attrUcd), std::string((const char *)attrUtype))); } } void VOTableReader::readInterval (TimeTable& pTT, xmlTextReaderPtr reader, int pcrtIndex) { // -- read tag text (may be NULL) const xmlChar *value = xmlTextReaderConstValue(reader); std::string tagValue = reinterpret_cast(value); // first TD is startdate if (_tdCount == 0) { // read start date of interval _tmpIntervalstartdate = readISOTime(tagValue); // read time format, the first date of the first interval if (pTT._timeFormat == TimeTable::TIME_FORMAT::UNKNOWN) { pTT._timeFormat = getTimeFormat(tagValue); } } else if (_tdCount == 1) { // start date is set, that means we are waiting for stop date pTT.addInterval( TimeInterval(_tmpIntervalstartdate, readISOTime(tagValue), pcrtIndex)); } else { TimeInterval * pLastInterval = pTT.getLastInterval(); // If interval list is not empty, add parameter data to the last interval if (pLastInterval != NULL) { ParameterDescriptionList pdl = pTT.getParameterDescritptions(); std::vector paramList; split (tagValue, VOTableData::SEPARATOR.c_str()[0], paramList); int nbParamDataInterval = pLastInterval->getParameterDataCount(); std::string paramKey = pdl [nbParamDataInterval].getId(); pLastInterval->addParameterData(paramKey, paramList); } } } void VOTableReader::readMetadata(const std::string& pDescription, TimeTable& pTimeTable) { // try to find string like "Prop:xxxx" and set _prop attribute to "xxxx" std::vector lines; split(pDescription, ';', lines); for (std::string line : lines) { // -- here try to find "Name:" if (contains(line, VOTableData::NAME_TAG)) { extractvalue(line, pTimeTable._name); } // -- here try to find "Historic:" else if (contains(line, VOTableData::HISTORIC_TAG)) { extractvalue(line, pTimeTable._history); } // -- here try to find "CreationDate:" // and try to set it as unix time // if impossible, add the line to the description else if (contains(line, VOTableData::CREATION_DATE_TAG)) { // convert creation date string to char* std::string creationDate; extractvalue(line, creationDate); // try to read date try { pTimeTable._creationDate = TimeTableCatalog::readISOTime(creationDate); } catch (...) { LOG4CXX_WARN(_logger, "Unable to parse creation date in " + getPath()); } } else { // ignore lines } } } } /* namespace TimeTableCatalog */