TTOperationsLauncher.cc 4.3 KB
/*
 * OperationsLauncher.cc
 *
 *  Created on: 14 août 2013
 *      Author: CS
 */

#include <iostream>
#include <cstring>
#include "TimeTable.hh"
#include <vector>
#include "TimeTableCatalogFactory.hh"
#include "InternalXMLReader.hh"
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include "Application.hh"
#include <log4cxx/logger.h>

/**
 * Logger
 */
log4cxx::LoggerPtr _logger(
		log4cxx::Logger::getLogger("AMDA-Kernel.TTOperations"));

/**
 * Shows help on std::cout.
 */
void help() {
	std::cout << "Use : ttOperation OPERATION [OPTIONS] TT...  " << std::endl;
	std::cout << "    with OPERATION in (intersect, union, antiintersect)  "
			<< std::endl;
	std::cout << "         OPTIONS as " << std::endl;
	std::cout << "           --with_msk " << std::endl;
	std::cout << "           --out_dir=<path> default is ." << std::endl;
	std::cout
			<< "           --out_type=<type> with type in (ASCII, VO, Internal) default is Internal"
			<< std::endl;
	std::cout << "         TT a list of time table files  " << std::endl;
}

/**
 * Extracts a value from a pattern key=value.
 * Used for options.
 */
std::string extractValue(std::string& pKeyAndValue) {
	return pKeyAndValue.substr(pKeyAndValue.find("=") + 1);
}

/**
 * Main for ttOperation binary.
 */
int ttOperation(int argc, char *argv[], AMDA::helpers::Properties& /*properties*/) {

	// executable options
	if (argc < 3 || (argc > 1 && strcmp(argv[1], "--help") == 0)) {
		help();
		return -1;
	}

	int curIndex = 2;
	// init options with default values
	std::string outdirectory = ".";
	std::string outformat = TimeTableCatalog::InternalXMLReader::FORMAT;
	TimeTableCatalog::TimeTable::TIME_FORMAT timeformat =
			TimeTableCatalog::TimeTable::TIME_FORMAT::YYYYMMDDThhmmss;

	// search for specified options
	// and fill option values
	while (boost::starts_with(argv[curIndex], "--")) {
		std::string option(argv[curIndex]);
		if (strcmp("--with_msk", argv[curIndex]) == 0) {
			timeformat = TimeTableCatalog::TimeTable::TIME_FORMAT::YYYYMMDDThhmmssmsk;
		} else if (boost::starts_with(argv[curIndex], "--out_dir=")) {
			outdirectory = extractValue(option);
			boost::filesystem::path path(outdirectory);
			if (!boost::filesystem::exists(path)) {
				LOG4CXX_ERROR(_logger, "The path " + outdirectory << " does not exist.");
				return -1;
			}
		} else if (boost::starts_with(argv[curIndex], "--out_type=")) {
			outformat = extractValue(option);
			if (!TimeTableCatalog::TimeTableCatalogFactory::getInstance().canRead(
					outformat)) {
				LOG4CXX_ERROR(_logger, "Unknown type " + outformat << ".");
				return -1;
			}
		} else {
			LOG4CXX_ERROR(_logger, "Unknown option " << argv[curIndex] << ".");
		}
		++curIndex;
	}

	// read tt list
	std::vector<TimeTableCatalog::TimeTable> tts;
	for (int i = curIndex; i < argc; i++) {
		TimeTableCatalog::TimeTable tt;
		std::string path(argv[i]);
		boost::filesystem::path boostpath(path);
		if (!(boost::starts_with(path, "http:")
				|| boost::starts_with(path, "https:"))
				&& !boost::filesystem::exists(boostpath)) {
			LOG4CXX_ERROR(_logger, "The time table " + path << " does not exist.");
			return -1;
		}
		// read tt with auto-detected type
		std::string type = TimeTableCatalog::TimeTableCatalogFactory::getInstance().getReaderType(
								path);
		if(type.empty()){
			LOG4CXX_ERROR(_logger, "Unknown Timetable : " << path);
			return -1;
		}
		tt.read(path,type);
		tts.push_back(tt);
	}

	// do action according to OPERATION
	std::unique_ptr<TimeTableCatalog::TimeTable> tt;
	if (strcmp("intersect", argv[1]) == 0) {
		tt = TimeTableCatalog::TimeTable::intersect(tts);
	} else if (strcmp("union", argv[1]) == 0) {
		tt = TimeTableCatalog::TimeTable::merge(tts);
	} else if (strcmp("antiintersect", argv[1]) == 0) {
		tt = TimeTableCatalog::TimeTable::antiintersect(tts);
	} else {
		LOG4CXX_ERROR(_logger, "Wrong OPERATION...");
		help();
		return -1;
	}

	LOG4CXX_DEBUG(_logger, "Number of resulting Intervals : " << tt->getIntervalNumber());
	// write output with resulting tt
	tt->_timeFormat = timeformat;
	LOG4CXX_INFO(_logger, "Writing output in " << outdirectory << " with format :" << outformat);
	tt->write(outdirectory, outformat);

	return 0;
}

/**
 * Main function
 */
int main(int argc, char *argv[]) {

	AMDA::Common::Application lMain;
	return lMain.main(argc, argv, ttOperation, true);
}