InternalXMLReader.cc 8.39 KB
/*
 * InternalXMLReader.cc
 *
 *  Created on: 6 août 2013
 *      Author: CS
 */

#include "InternalXMLData.hh"
#include "InternalXMLReader.hh"
#include <stdio.h>
#include "TimeTableCatalogUtil.hh"
#include <string>
#include "AsciiReader.hh"
#include "Catalog.hh"

#include <boost/algorithm/string.hpp>

#ifdef LIBXML_READER_ENABLED

/*
 <?xml version="1.0" encoding="UTF-8"?>
 <timetable>
 <name>FTE_c3</name>
 <created>2013-07-14T09:09:32</created>
 <description>Uploaded Time Table
 Time Table generated by AMDA @ CDPP;Description: FTE list from Cluster 3 data. From \"A new multivariate time series data analysis technique: Automated detection of flux transfer events using Cluster data\" by Karimabadi et al., JOURNAL OF GEOPHYSICAL RESEARCH, VOL. 114, A06216, doi:10.1029/2009JA014202, 2009 http://www.agu.org/journals/ja/ja0906/2009JA014202/The list is available as Auxiliary material \"Data Set S3\"Transformation into AMDA Time Table by V. Genot, CESR, Toulouse, France 29/06/2009 : - millisec have been omitted - the original event corresponds to the StartTime of the Time Table - if StopTime-StartTime = 1 sec then the event is a magnetosheath FTE - if StopTime-StartTime = 2 sec then the event is a magnetospheric FTE;Source: Upload Time Table;Creation Date :  2009-07-01 17:16:46 shared by Vincent Genot on 2009-11-24 18:52:50;</description>
 <history>created from another TT</history>
 <nbIntervals>738</nbIntervals>
 <intervals>
 <start>2001-02-02T16:27:12</start>
 <stop>2001-02-02T16:27:13</stop>
 </intervals>
 */

namespace TimeTableCatalog {

const std::string InternalXMLReader::FORMAT = "Internal";

InternalXMLReader::InternalXMLReader(const std::string& pPath) :
		XMLReader(pPath) {

}

InternalXMLReader::~InternalXMLReader() {

}

// ---------------- PUBLIC -----------------

std::unique_ptr<AbstractReader> InternalXMLReader::createInstance(
		const std::string& pPath) {
	return std::unique_ptr < AbstractReader
			> (new InternalXMLReader(pPath));
}

std::string InternalXMLReader::getFirstNode() {
	return "timetable";
}

// ----------------- PRIVATE --------------------------

/**
 *
 * @pTT : the timetable to load
 * @reader: the xmlReader
 *
 * Fills the given TimeTable with the xml file content
 */
void InternalXMLReader::processNode(TimeTable& pTT,	xmlTextReaderPtr reader, int &crtIndex) {
	const xmlChar *name, *value;

	// -- read tag
	name = xmlTextReaderConstName(reader);
	if (name == NULL)
		name = BAD_CAST "--";
	// -- read tag text (may be NULL)
	value = xmlTextReaderConstValue(reader);

	// -- is tag interested ?
	std::string tagName = reinterpret_cast<const char*>(name);
	if (_step == READ_STEP::NO_TAG
			&& (tagName == InternalXMLData::ELEM_NAME
					|| tagName == InternalXMLData::ELEM_CREATED
					|| tagName == InternalXMLData::ELEM_DESCRIPTION
					|| tagName == InternalXMLData::ELEM_HISTORY
					|| tagName == InternalXMLData::ELEM_START
					|| tagName == InternalXMLData::ELEM_STOP
					|| tagName == InternalXMLData::ELEM_PARAMETER
					|| tagName == InternalXMLData::ELEM_PARAM
					|| tagName == InternalXMLData::ELEM_NB_INTERVALS)) {
		// yes, it is !
		// save current tag to get its text value next process
		_tmpCurrentTag = reinterpret_cast<const char*>(name);
		_step = READ_STEP::START_TAG;
	}
	// are we waiting for a tag value of an interested tag ?
	if (_step == READ_STEP::TEXT) {
		// now the tag is read, do not care anymore of it
		_step = READ_STEP::END_TAG;
		// process tag value according to current tag
		if (value != NULL) {
			std::string tagValue = reinterpret_cast<const char*>(value);

			if (_tmpCurrentTag == InternalXMLData::ELEM_NAME) {
				pTT._name = tagValue;
			} else if (_tmpCurrentTag == InternalXMLData::ELEM_DESCRIPTION) {
				split(tagValue, '\n', pTT._description);
			} else if (_tmpCurrentTag == InternalXMLData::ELEM_HISTORY) {
				pTT._history = tagValue;
			} else if (_tmpCurrentTag == InternalXMLData::ELEM_CREATED) {
				pTT._creationDate = readISOTime(tagValue);
			} else if (_tmpCurrentTag == InternalXMLData::ELEM_NB_INTERVALS) {
				// NOP, dont care about interval number
			} else {
				// read intervals
				if (_tmpCurrentTag == InternalXMLData::ELEM_START) {
					_tmpIntervalstartdate = readISOTime(tagValue);
					if (pTT._timeFormat == TimeTable::TIME_FORMAT::UNKNOWN) {
						int size = 0;
						pTT._timeFormat = getTimeFormat(tagValue, size);
					}
				} else if (_tmpCurrentTag == InternalXMLData::ELEM_STOP) {
					pTT.addInterval(TimeInterval(_tmpIntervalstartdate, readISOTime(tagValue), crtIndex));
					++crtIndex;
				}
				// Read parameters data
				else if (_tmpCurrentTag == InternalXMLData::ELEM_PARAM) {
					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<std::string> paramList;
						split (tagValue, InternalXMLData::SEPARATOR.c_str()[0], paramList);

						int nbParamDataInterval = pLastInterval->getParameterDataCount();
						std::string paramKey = pdl [nbParamDataInterval].getId();
						pLastInterval->addParameterData(paramKey, paramList);
					}
				}
			}
		}
		else {
			_step = READ_STEP::NO_TAG;
		}
	} else if (_step == READ_STEP::START_TAG) {

		// Read XML_PARAMETER_TAG attributes (if found)
		if (tagName == InternalXMLData::ELEM_PARAMETER) {
			const xmlChar *attrId, *attrName, *attrSize, *attrType, *attrUnit, *attrDescription, *attrUcd, *attrUtype;
			attrId	 		= xmlTextReaderGetAttribute (reader, (const xmlChar*)InternalXMLData::ATTRIB_ID);
			if (attrId == NULL)
				//Compatibility mode with older catalogs
				attrId          = xmlTextReaderGetAttribute (reader, (const xmlChar*)InternalXMLData::ATTRIB_ID_UPPER_CASE);
			attrName 		= xmlTextReaderGetAttribute (reader, (const xmlChar*)InternalXMLData::ATTRIB_NAME);
			attrSize 		= xmlTextReaderGetAttribute (reader, (const xmlChar*)InternalXMLData::ATTRIB_SIZE);
			attrType 		= xmlTextReaderGetAttribute (reader, (const xmlChar*)InternalXMLData::ATTRIB_TYPE);
			attrUnit		= xmlTextReaderGetAttribute (reader, (const xmlChar*)InternalXMLData::ATTRIB_UNIT);
			attrDescription = xmlTextReaderGetAttribute (reader, (const xmlChar*)InternalXMLData::ATTRIB_DESCRITION);
			attrUcd			= xmlTextReaderGetAttribute (reader, (const xmlChar*)InternalXMLData::ATTRIB_UCD);
			attrUtype		= xmlTextReaderGetAttribute (reader, (const xmlChar*)InternalXMLData::ATTRIB_UTYPE);

			std::string attrIdStr = (attrId != NULL) ? std::string((const char *)attrId) : "";
			std::string attrNameStr = (attrName != NULL) ? std::string((const char *)attrName) : "";
			std::string attrSizeStr = (attrSize != NULL) ? std::string((const char *)attrSize) : "";
			ParameterDescription::ParameterType type = (attrType != NULL) ? getTypeFromString(std::string((const char *)attrType)) : ParameterDescription::ParameterType::String;
			std::string attrUnitStr = (attrUnit != NULL) ? std::string((const char *)attrUnit) : "";
			std::string attrDescriptionStr = (attrDescription != NULL) ? std::string((const char *)attrDescription) : "";
			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,
					attrSizeStr,
					type,
					attrUnitStr,
					attrDescriptionStr,
					attrUcdStr,
					attrUtypeStr));

			// Jump to next XML_PARAMETER_TAG
			_step = READ_STEP::NO_TAG;
		}
		else {
			_step = READ_STEP::TEXT;
		}
	} else if (_step == READ_STEP::END_TAG) {
		_step = READ_STEP::NO_TAG;
	}
}

ParameterDescription::ParameterType InternalXMLReader::getTypeFromString(std::string type) {
	boost::algorithm::trim(type);
	boost::algorithm::to_lower(type);

	if ((type.compare("2") == 0) || (type.compare("string") == 0) || (type.compare("char") == 0)) {
		return ParameterDescription::ParameterType::String;
	}
	else if ((type.compare("3") == 0) || (type.compare("integer") == 0) || (type.compare("int") == 0)) {
		return ParameterDescription::ParameterType::Integer;
	}
	else if ((type.compare("0") == 0) || (type.compare("float") == 0) || (type.compare("double") == 0)) {
		return ParameterDescription::ParameterType::Double;
	}
	else if ((type.compare("1") == 0) || (type.compare("date") == 0)) {
		return ParameterDescription::ParameterType::Date;
	}
	return ParameterDescription::ParameterType::String;
}

} /* namespace TimeTableCatalog */

#endif