InternalXMLWriter.cc 6.74 KB
/*
 * InternalXMLWriter.cc
 *
 *  Created on: 6 août 2013
 *      Author: CS
 */

#include "InternalXMLData.hh"

#include "InternalXMLWriter.hh"
#include <stdio.h>
#include <string.h>
#include "TimeTableCatalogUtil.hh"
#include <sstream>

#if defined(LIBXML_WRITER_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)

#define MY_ENCODING "UTF-8"

namespace TimeTableCatalog {

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

InternalXMLWriter::InternalXMLWriter(const std::string& pPath, const std::string& pName) :
		XMLWriter(pPath, pName) {
}

InternalXMLWriter::~InternalXMLWriter() {
}

/*
 <?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>
 */

// ---------------------- PUBLIC ----------------------
std::string InternalXMLWriter::write(const TimeTable& pTT) {
	return XMLWriter::write(pTT, MY_ENCODING);
}

/**
 * Creates an instance of this.
 */
std::unique_ptr<AbstractWriter> InternalXMLWriter::createInstance(
		const std::string& pPath, const std::string& pName) {
	return std::unique_ptr < AbstractWriter
			> (new InternalXMLWriter(pPath, pName));
}

/**
 * Gets the tt file expected extension, starting with .
 */
const std::string InternalXMLWriter::getExtension() const {
	return ".xml";
}

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

void InternalXMLWriter::writeContent(const TimeTable& pTT,
		xmlTextWriterPtr& writer) {
	// -- create root element "timetable"
	openTag(pTT, writer, "timetable");

	// -- write metadata as name, creation date, description etc.
	writeMetadata(pTT, writer);

	// -- write intervals
	writeIntervals(pTT, writer);

	// --  close timetable element
	closeTag(pTT, writer, "timetable");
}

void InternalXMLWriter::writeMetadata(const TimeTable& pTT,
		xmlTextWriterPtr& pWriter) {
	// -- write name tag
	writeElement(pTT, pWriter, InternalXMLData::ELEM_NAME, pTT._name);
	// -- write created tag
	std::ostringstream os;
	writeISOTime(pTT._creationDate, pTT._timeFormat, os);
	writeElement(pTT, pWriter, InternalXMLData::ELEM_CREATED, os.str());
	// -- write description tag
	if (!pTT._description.empty()) {
		std::string description = pTT._description.at(0);
		for (size_t i = 1; i < pTT._description.size(); ++i) {
			description += "\n" + pTT._description.at(i);
		}
		writeElement(pTT, pWriter, InternalXMLData::ELEM_DESCRIPTION, description);
	} else {
		writeElement(pTT, pWriter, InternalXMLData::ELEM_DESCRIPTION, std::string());
	}

	// -- write history tag
	writeElement(pTT, pWriter, InternalXMLData::ELEM_HISTORY, pTT._history);

	// Write parameter description if defined (Catalog ONLY)
	ParameterDescriptionList pdl = pTT.getParameterDescritptions();
	if (pdl.empty() == false) {
		// -- open tag ELEM_PARAMETERS
		openTag(pTT, pWriter, InternalXMLData::ELEM_PARAMETERS);

		for (auto parameterDescription : pdl) {
			// -- write parameter tag
			openTag(pTT, pWriter, InternalXMLData::ELEM_PARAMETER);
			addAttribute(pTT, pWriter, InternalXMLData::ATTRIB_ID, parameterDescription.getId());
			addAttribute(pTT, pWriter, InternalXMLData::ATTRIB_NAME, parameterDescription.getName());
			addAttribute(pTT, pWriter, InternalXMLData::ATTRIB_SIZE, parameterDescription.getSize());
			addAttribute(pTT, pWriter, InternalXMLData::ATTRIB_TYPE, getTypeAsString(parameterDescription.getType()));
			addAttribute(pTT, pWriter, InternalXMLData::ATTRIB_UNIT, parameterDescription.getUnit());
			addAttribute(pTT, pWriter, InternalXMLData::ATTRIB_DESCRITION, parameterDescription.getDescription());
			addAttribute(pTT, pWriter, InternalXMLData::ATTRIB_UCD, parameterDescription.getUcd());
			addAttribute(pTT, pWriter, InternalXMLData::ATTRIB_UTYPE, parameterDescription.getUtype());
			closeTag(pTT, pWriter, InternalXMLData::ELEM_PARAMETER);
		}

		// --  close ELEM_PARAMETERS tag
		closeTag(pTT, pWriter, InternalXMLData::ELEM_PARAMETERS);
	}

	// -- write nbIntervals tag
	std::ostringstream osnb;
	osnb << pTT.getIntervalNumber();
	writeElement(pTT, pWriter, InternalXMLData::ELEM_NB_INTERVALS, osnb.str());
}

void InternalXMLWriter::writeIntervals(const TimeTable& pTT, xmlTextWriterPtr& pWriter) {
	ParameterDescriptionList pdl = pTT.getParameterDescritptions();

	for (TimeInterval interval : pTT.getIntervals()) {
		// -- open tag "intervals"
		openTag(pTT, pWriter, "intervals");

		// -- write "start" tag
		std::ostringstream osstart;
		writeISOTime(interval._startTime, pTT._timeFormat, osstart);
		writeElement(pTT, pWriter, InternalXMLData::ELEM_START, osstart.str());

		// -- write "stop" tag
		std::ostringstream osstop;
		writeISOTime(interval._stopTime, pTT._timeFormat, osstop);
		writeElement(pTT, pWriter, InternalXMLData::ELEM_STOP, osstop.str());

		// If the TT has a parameter description list, write parameter data
		if (pdl.empty() == false) {
			for (auto parameterDescription : pdl) {
				std::vector<std::string> dataValues = interval.getParameterData (parameterDescription.getId());

				std::stringstream xmlValue;
				for (auto dataValue : dataValues) {
					if (xmlValue.str().size() == 0)
						xmlValue << dataValue;
					else
						xmlValue << InternalXMLData::SEPARATOR << dataValue;
				}
				writeElement(pTT, pWriter, InternalXMLData::ELEM_PARAM, xmlValue.str());
			}
		}

		// --  close "intervals" tag
		closeTag(pTT, pWriter, "intervals");
	}
}

std::string InternalXMLWriter::getTypeAsString(ParameterDescription::ParameterType type) {
	switch (type) {
		case ParameterDescription::ParameterType::Unknown:
			return "2";
		case ParameterDescription::ParameterType::Double:
			return "0";
		case ParameterDescription::ParameterType::Date:
			return "1";
		case ParameterDescription::ParameterType::String:
			return "2";
		case ParameterDescription::ParameterType::Integer:
			return "3";
	}
	return "2";
}

} /* namespace TimeTableCatalog */

#endif