VOTableWriter.cc 7.64 KB
/*
 * VOTableWriter.cc
 *
 *  Created on: 7 août 2013
 *      Author: CS
 */

#include "VOTableData.hh"
#include "VOTableWriter.hh"
#include "TimeTableCatalogUtil.hh"

namespace TimeTableCatalog {

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

#define MY_ENCODING "UTF-8"

const std::string VOTableWriter::FORMAT = "VO";

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

}

VOTableWriter::~VOTableWriter() {
}

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

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

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

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

void VOTableWriter::writeContent(const TimeTable& pTT,
		xmlTextWriterPtr& pWriter) {
	// -- create root element
	openTag(pTT, pWriter, VOTableData::VOTABLE_TAG);
	// add version attribute
	addAttribute(pTT, pWriter, VOTableData::VOTABLE_VERSION_ATTRIB, VOTableData::VOTABLE_VERSION_VALUE);
	// add xmlns:xsi attribute
	addAttribute(pTT, pWriter, VOTableData::VOTABLE_XMLNS_XSI_ATTRIB, VOTableData::VOTABLE_XMLNS_XSI_VALUE);
	// add xmlns attribute
	addAttribute(pTT, pWriter, VOTableData::VOTABLE_XMLNS_ATTRIB, VOTableData::VOTABLE_XMLNS_VALUE);
	// add xmlns:stc attribute
	addAttribute(pTT, pWriter, VOTableData::VOTABLE_XMLNS_STC_ATTRIB, VOTableData::VOTABLE_XMLNS_STC_VALUE);

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

	// -- write intervals
	writeVOTable(pTT, pWriter);

	// --  close root element
	closeTag(pTT, pWriter, VOTableData::VOTABLE_TAG);
}

void VOTableWriter::writeMetadata(const TimeTable& pTT,
		xmlTextWriterPtr& pWriter) {
	// -- write name tag
	std::ostringstream allMetadata;
	allMetadata << VOTableData::NAME_TAG << pTT._name << ";" << std::endl;
	allMetadata << VOTableData::HISTORIC_TAG << pTT._history << ";"
			<< std::endl;
	allMetadata << VOTableData::CREATION_DATE_TAG;
	writeISOTime(pTT._creationDate, pTT._timeFormat, allMetadata);
	allMetadata << ";" << std::endl;
	writeElement(pTT, pWriter, VOTableData::DESCRIPTION_TAG, allMetadata.str());
}

void VOTableWriter::writeField(const TimeTable& pTT,
		xmlTextWriterPtr& pWriter,
		const std::string &name,
		const std::string &ID,
		const std::string &ucd,
		const std::string &datatype,
		const std::string &xtype,
		const std::string &utype,
		const std::string &unit,
		const std::string &description,
		int arraysize
		) {

	// -- create FIELD element
	openTag(pTT, pWriter, VOTableData::FIELD_TAG);

	// add Fields attributes
	addAttribute(pTT, pWriter, VOTableData::FIELD_NAME_ATTRIB, name);
	addAttribute(pTT, pWriter, VOTableData::FIELD_ID_ATTRIB, ID);
	addAttribute(pTT, pWriter, VOTableData::FIELD_UCD_ATTRIB, ucd);
	addAttribute(pTT, pWriter, VOTableData::FIELD_DATATYPE_ATTRIB, datatype);
	if (xtype.size() != 0)
		addAttribute(pTT, pWriter, VOTableData::FIELD_XTYPE_ATTRIB, xtype);
	addAttribute(pTT, pWriter, VOTableData::FIELD_UTYPE_ATTRIB, utype);
	if (unit.size() != 0)
		addAttribute(pTT, pWriter, VOTableData::FIELD_UNIT_ATTRIB, unit);
	if (arraysize != 1) {
		std::string arraySizeString;
		if (arraysize == -1) {
			arraySizeString = "*";
		}
		else {
			arraySizeString = std::to_string(arraysize);
		}
		addAttribute(pTT, pWriter, VOTableData::FIELD_ARRAYSIZE_ATTRIB, arraySizeString);
	}

	if (description.empty() == false) {
		writeElement(pTT, pWriter, VOTableData::DESCRIPTION_TAG, description);
	}

	// --  close FIELD element
	closeTag(pTT, pWriter, VOTableData::FIELD_TAG);
}

void VOTableWriter::writeVOTable(const TimeTable& pTT,
		xmlTextWriterPtr& pWriter) {
	// -- open tag RESOURCE
	openTag(pTT, pWriter, VOTableData::RESOURCE_TAG);
	// write tt description
	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, VOTableData::DESCRIPTION_TAG, description);
	} else {
		writeElement(pTT, pWriter, VOTableData::DESCRIPTION_TAG, std::string());
	}
	// -- open tag TABLE
	openTag(pTT, pWriter, VOTableData::TABLE_TAG);

	// --------------- FIELD(S) -----------------------------
	writeField (pTT, pWriter, "startTime", "startTime", "time.epoch", "char", "dateTime", "", "", "", -1);
	writeField (pTT, pWriter, "stopTime", "stopTime", "time.epoch", "char", "dateTime", "", "", "", -1);

	// Write parameter description if defined (Catalog ONLY)
	ParameterDescriptionList pdl = pTT.getParameterDescritptions();

	for (auto parameterDescription : pdl) {
		ParameterDescription::ParameterType internalType = parameterDescription.getType();
		std::string type = getTypeAsString(internalType);
		std::string ucd  = parameterDescription.getUcd();
		std::string xtype = "";
		int size = parameterDescription.getSizeAsInt();
		if (type.compare("char") == 0) {
			switch (internalType) {
				case ParameterDescription::ParameterType::Date:
					ucd = "time.epoch";
					xtype = "dateTime";
					size = -1;
					break;
				case ParameterDescription::ParameterType::Unknown:
				case ParameterDescription::ParameterType::String:
					size = -1;
					break;
			}
		}

		writeField (pTT, pWriter,
				parameterDescription.getName(),
				parameterDescription.getId(),
				ucd,
				type,
				xtype,	// XTYPE
				parameterDescription.getUtype(),
				parameterDescription.getUnit(),
				parameterDescription.getDescription(),
				size);
	}

	// --------------- INTERVALS (+ DATA) -------------------

	// -- open tag DATA
	openTag(pTT, pWriter, VOTableData::DATA_TAG);
	// -- open tag TABLE_DATA
	openTag(pTT, pWriter, VOTableData::TABLEDATA_TAG);

	for (TimeInterval interval : pTT.getIntervals()) {
		openTag(pTT, pWriter, VOTableData::TR_TAG);

		// -- write "TD" tag for start date
		std::ostringstream osstart;
		writeTimeData(interval._startTime, pTT._extTimeFormat, osstart);
		writeElement(pTT, pWriter, VOTableData::TD_TAG, osstart.str());

		// -- write "TD" tag for stop date
		std::ostringstream osstop;
		writeTimeData(interval._stopTime, pTT._extTimeFormat, osstop);
		writeElement(pTT, pWriter, VOTableData::TD_TAG, osstop.str());

		// Write parameter values if defined (Catalog ONLY)
		for (auto parameterDescription : pdl) {
			std::vector<std::string> dataValues = interval.getParameterData (parameterDescription.getId());
			std::string paramData;

			for (auto dataValue : dataValues) {
				if (paramData.empty()) {
					paramData += dataValue;
				} else {
					paramData +=  VOTableData::SEPARATOR + dataValue;
				}
			}
			writeElement(pTT, pWriter, VOTableData::TD_TAG, paramData);
		}

		closeTag(pTT, pWriter, VOTableData::TR_TAG);
	}

	closeTag(pTT, pWriter, VOTableData::TABLEDATA_TAG);
	closeTag(pTT, pWriter, VOTableData::DATA_TAG);
	closeTag(pTT, pWriter, VOTableData::TABLE_TAG);
	closeTag(pTT, pWriter, VOTableData::RESOURCE_TAG);
}

std::string VOTableWriter::getTypeAsString(ParameterDescription::ParameterType type) {
	switch (type) {
		case ParameterDescription::ParameterType::Unknown:
			return "char";
		case ParameterDescription::ParameterType::Double:
			return "double";
		case ParameterDescription::ParameterType::Date:
			return "char";
		case ParameterDescription::ParameterType::String:
			return "char";
		case ParameterDescription::ParameterType::Integer:
			return "int";
	}
	return "string";
}

#endif

} /* namespace TimeTableCatalog */