ProcessNode.cc 6 KB
/*
 * ProcessNode.cc
 *
 *  Created on: Oct 31, 2012
 *      Author: f.casimir
 */

#include <sstream>
#include <algorithm>
#include <regex>

#include "ProcessNode.hh"


#include <boost/shared_ptr.hpp>


#include <Parameter.hh>
#include <Process.hh>
#include <Parameter.hh>
#include <FileConfigurator.hh>
#include <ServicesServer.hh>

#include "Config.hh"

using namespace AMDA::Parameters;
using namespace boost;

namespace AMDA {
namespace XMLParameterConfigurator {

ProcessNode::ProcessNode() : NodeCfg() {
}

ProcessNode::~ProcessNode() {
}

std::string injectResamplingIntoProcess(const std::string& pProcessName, const std::string& pProcessParams, const std::string& pExpression) {
	std::stringstream lBuffer;
	bool isAParam = false;

	unsigned int length = pExpression.size();
	std::string part;

    bool isSpecialCase = false;
    std::string pattern;
    std::string proc;
    std::size_t found;

    for ( unsigned int i = 0; i < length; ++i) {
        
		switch(pExpression[i]) {
		case '#':
            
            part = pExpression.substr(i);
            found = part.find("(");
            if (found != std::string::npos) {
                // Test if special case
                proc = part.substr(1, found-1);
                isSpecialCase = !ServicesServer::getInstance()->getInjectResamplingBeforeProcess(proc);
                pattern = "#";
                pattern += proc;
                pattern += "(";
            }
            if (isSpecialCase) {
                int patternSize = pattern.size();
                i += patternSize;
                //special case with sum_into_table_range
                lBuffer << "#" << pProcessName << "(" << pattern;
                part = part.substr(patternSize);

                int openBracket = 0;
                int pos = 0;
                for (unsigned int j = 0; j < part.size(); ++j) {
                    if (part[j] == '(') {
                        openBracket++;
                    }
                    else if (part[j] == ')') {
                        if (openBracket == 0) {
                            pos = j;
                            break;
                        }
                        openBracket--;
                    }
                }
                lBuffer << part.substr(0, pos);
                i += pos;
                lBuffer << ");" << pProcessParams << ")";
            }
			else {
				lBuffer << pExpression[i];
			}
			break;
		case '$':
			isAParam = true;
			lBuffer << "#" << pProcessName << "($";
			break;
		default:
			if( isAParam && ! (isalnum(pExpression[i]) || (pExpression[i]=='_'))) {
				lBuffer << ";" << pProcessParams << ")";
				isAParam=false;
			}
			lBuffer << pExpression[i];
			break;
		}
	}
	if (isAParam) {
		lBuffer << ";" << pProcessParams << ")";
	}

	return std::string(lBuffer.str());
}

void ProcessNode::proceed(xmlNodePtr pNode, const AMDA::Parameters::CfgContext& pContext) {
	LOG4CXX_DEBUG(gLogger, "ProcessNode::proceed");
	Parameter* lParameter = pContext.get<Parameter*>();

	double lTimeResolution = lParameter->getTimeResolution();
	double lGapThreshold = lParameter->getGapThreshold();
	std::string lReferenceParam = lParameter->getReferenceParameter();
	Process *lProcess = ServicesServer::getInstance()->getProcess("standard", *lParameter);

	//process description
	xmlChar *lProcessDesc = xmlGetProp(pNode, (const xmlChar *) "description");
	if (lProcessDesc != NULL)
	{
		lProcess->setDescription(std::string((const char *)lProcessDesc));
		xmlFree(lProcessDesc);
	}

	//user process
	xmlChar *lUserProcess = xmlGetProp(pNode, (const xmlChar *) "userProcess");
	if (lUserProcess != NULL)
	{
		lProcess->setIsUserProcess(strcasecmp ((const char*)lUserProcess, "true") == 0);
		xmlFree(lUserProcess);
	}

	DataWriterSPtr lDataWriter( lProcess);
	std::string* xmlFileName = pContext.get<std::string*>();
	lDataWriter->setSignatureTrigger(*xmlFileName);

	lParameter->setDataWriter(lDataWriter);
	if (pNode->children && pNode->children->content && pNode->children->content[0] != '\0') {
		std::string expression = std::string((char*)pNode->children->content);
		// Remove all aspaces
		expression.erase(std::remove(expression.begin(), expression.end(), ' '), expression.end());
		if (!lReferenceParam.empty()) {
			// Inject Resampling with reference param
			expression = injectResamplingIntoProcess("sampling_under_refparam", lReferenceParam, expression.c_str());
		}
		else if ( lTimeResolution != 0 ) {
			// Inject Resampling
			std::stringstream lProcessParams;
			lProcessParams << lTimeResolution << ";" << lGapThreshold;
			expression = injectResamplingIntoProcess("sampling_classic", lProcessParams.str(), expression.c_str());
		}
		lProcess->setExpression(expression);
	} else {
		if ( lParameter->getParameterList().size() == 1 ) {
			// Inject Resampling
			if (!lReferenceParam.empty()) {
				lProcess = ServicesServer::getInstance()->getProcess("sampling_under_refparam",*lParameter);
				std::stringstream lBuffer;
				lProcess->getAttributList().push_back(lReferenceParam);
				lBuffer.str(""); lBuffer << "$" << (*lParameter->getParameterList().begin())->getId();
				lProcess->setExpression(lBuffer.str());
				lDataWriter.reset( lProcess);
				lParameter->setDataWriter(lDataWriter);
			}
			else if ( lTimeResolution != 0 ) {
				lProcess = ServicesServer::getInstance()->getProcess("sampling_classic",*lParameter);
				std::stringstream lBuffer;
				lBuffer.str(""); lBuffer << lTimeResolution;
				lProcess->getAttributList().push_back(lBuffer.str());
				lBuffer.str(""); lBuffer << lGapThreshold;
				lProcess->getAttributList().push_back(lBuffer.str());
				lBuffer.str(""); lBuffer << "$" << (*lParameter->getParameterList().begin())->getId();
				lProcess->setExpression(lBuffer.str());
				lDataWriter.reset( lProcess);
				lParameter->setDataWriter(lDataWriter);
			}
			else
				//only one parameter + no process => use the same info
				(*lParameter->getParameterList().begin())->setInfoId(lParameter->getInfoId());
		} else {
			ERROR_EXCEPTION( "Too many ParamGet with no process");
		}
	}
}

} /* namespace XMLParameterConfigurator */
} /* namespace AMDA */