/* * VOTableReader.cc * * Created on: 7 août 2013 * Author: CS */ #include "VOTableData.hh" #include "VOTableReader.hh" #include "TimeTableCatalogUtil.hh" #include "Catalog.hh" #include #include #include namespace TimeTableCatalog { const std::string VOTableReader::FORMAT = "VO"; VOTableReader::VOTableReader(const std::string& pPath) : XMLReader(pPath) { _tmpIntervalstartdate = -1; _readingVOTable = false; _readingResource = false; _readingTable = false; _readingField = false; _readingDescription = false; _readingTr = false; _readingTd = false; _tdCount = 0; _fieldCount = 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::VOTABLE_TAG) { _readingVOTable = (xmlTextReaderNodeType(reader) == 1); } else if (tagName == VOTableData::RESOURCE_TAG) { _readingResource = (xmlTextReaderNodeType(reader) == 1); } else if (tagName == VOTableData::TABLE_TAG) { _readingTable = (xmlTextReaderNodeType(reader) == 1); } else if (tagName == VOTableData::DESCRIPTION_TAG) { _readingDescription = (xmlTextReaderNodeType(reader) == 1); } else if (tagName == VOTableData::FIELD_TAG) { _readingField = (xmlTextReaderNodeType(reader) == 1); if (_readingField) { readField (pTT, reader); ++_fieldCount; } } else if (tagName == VOTableData::TR_TAG) { _readingTr = (xmlTextReaderNodeType(reader) == 1); if (!_readingTr) { _tdCount = 0; } } else if (tagName == VOTableData::TD_TAG) { _readingTd = (xmlTextReaderNodeType(reader) == 1); } else if ((tagName == "#text") && (xmlTextReaderNodeType(reader) == 3)) { if (_readingDescription) { readDescription (pTT, reader); } else 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 (_readingVOTable && !_readingResource) { readMetadata(tagValue, pTT); } else if (_readingResource && !_readingField) { if (value != NULL) split(tagValue, '\n', pTT._description); else pTT._description.clear(); } else if (_readingField && (_fieldCount > 2)) { // Two first fields are used for start time and stop time 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 (_fieldCount >= 2){ 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()); std::string voType = std::string((const char *)attrType); ParameterDescription::ParameterType internalType = getTypeFromString(voType); std::string internalSize("1"); if (((char *) attrSize) != NULL) { internalSize = std::string((const char *)attrSize); } if (internalSize.compare("*") == 0 || internalType == ParameterDescription::ParameterType::String) { internalSize = "1"; } std::string attrIdStr = (attrId != NULL) ? std::string((const char *)attrId) : ""; std::string attrNameStr = (attrName != NULL) ? std::string((const char *)attrName) : ""; std::string attrUnitStr = (attrUnit != NULL) ? std::string((const char *)attrUnit) : ""; std::string attrUcdStr = (attrUcd != NULL) ? std::string((const char *)attrUcd) : ""; std::string attrUtypeStr = (attrUtype != NULL) ? std::string((const char *)attrUtype) : ""; ((Catalog *) &pTT)->addParameterDescription(ParameterDescription( attrIdStr, attrNameStr, internalSize, internalType, attrUnitStr, "", // Read later attrUcdStr, attrUtypeStr)); } } 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) { int size = 0; pTT._timeFormat = getTimeFormat(tagValue, size); } } 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 } } } ParameterDescription::ParameterType VOTableReader::getTypeFromString(std::string type) { boost::algorithm::trim(type); boost::algorithm::to_lower(type); if ((type.compare("boolean") == 0) || (type.compare("short") == 0) || (type.compare("int") == 0) || (type.compare("long") == 0)) { return ParameterDescription::ParameterType::Integer; } else if ((type.compare("float") == 0) || (type.compare("double") == 0)) { return ParameterDescription::ParameterType::Double; } return ParameterDescription::ParameterType::String; } } /* namespace TimeTableCatalog */