/* * ServicesServer.h * * Created on: Nov 12, 2012 * Author: g.schneller */ #ifndef SERVICESSERVER_H_ #define SERVICESSERVER_H_ #include #include #include #include #include #include #include #include #include #include "dsgpatt_Singleton.hh" #include "Demangle.hh" #include "AMDA_exception.hh" namespace AMDA { namespace Parameters { //use class class ServicesServer; class ParamGet; class Process; class ParamOutput; class Parameter; class StatisticProcess; typedef boost::shared_ptr ServicesServerSPtr; // ParamGet factory definition typedef boost::function < ParamGet*(Parameter &) > ParamGetFactory; typedef std::map ParamGetFactories; // Process factory definition typedef boost::function < Process*(Parameter &) > ProcessFactory; typedef std::map ProcessFactories; // ParamOutput factory definition typedef boost::function < ParamOutput*() > ParamOutputFactory; typedef std::map ParamOutputFactories; // StatisticProcess factory definition typedef boost::function < StatisticProcess*(Parameter &, int) > StatisticProcessFactory; typedef std::map StatisticProcessFactories; class FileConfigurator; typedef boost::shared_ptr ParameterConfiguratorSPtr; /** * @class ServicesServer * @brief To call to register needed Services or to notify implemented Services * @details This Singleton class is frequently called into the registerPlugin method to notify one or more Services implementation as Process, ParamGet and ParamOutput. */ class ServicesServer : public ::Singleton{ public: // Design pattern friend class Singleton; typedef std::list ServiceList; struct exception: virtual AMDA_exception { }; /** * @brief Add a Service implementation */ template void addService(T v) { _serviceList.push_back(v); } /** * @brief Add a Service implementation */ template void declareService() { typedef typename std::map TServiceImpList; for ( ServiceList::const_reverse_iterator rit = _serviceList.rbegin(); rit != _serviceList.rend(); ++rit ) { if ( (*rit).type() == typeid(TServiceImpList)) { std::stringstream oss; oss << "Service already declared: " << Helpers::Demangle(typeid(T).name()); BOOST_THROW_EXCEPTION(exception() << AMDA::ex_msg(oss.str())); } } _serviceList.push_back(TServiceImpList()); } /** * @brief Add a Service implementation */ template void addServiceImpl(std::string name, T t) { typedef typename std::map TServiceImpList; ServiceList::iterator it = _serviceList.begin(); for ( ; it != _serviceList.end(); ++it ) { if ( (*it).type() == typeid(TServiceImpList)) { TServiceImpList& list = boost::any_cast(*it); list.insert(make_pair(name,t)); break; } } if( it == _serviceList.end()) { _serviceList.push_back(TServiceImpList()); ServiceList::iterator it =_serviceList.end(); TServiceImpList& list = boost::any_cast(*(--it)); list.insert(make_pair(name,t)); } } /** * @brief Search a Service implementation by this type. * @return Service or NULL if not found. */ template T getService() const { for ( ServiceList::const_reverse_iterator rit = _serviceList.rbegin(); rit != _serviceList.rend(); ++rit ) { if ( (*rit).type() == typeid(T)) { return boost::any_cast(*rit); } } return NULL; } /** * @brief Search a Service implementation by this type. * @return Service or NULL if not found. */ template T getService(const std::string& pImplName) const { typedef typename std::map TServiceImpList; for ( ServiceList::const_reverse_iterator rit = _serviceList.rbegin(); rit != _serviceList.rend(); ++rit ) { if ( (*rit).type() == typeid(TServiceImpList)) { TServiceImpList list = boost::any_cast(*rit); typename TServiceImpList::iterator it = list.find(pImplName); if ( it != list.end()) { return it->second; } else { return NULL; } } } return NULL; } ParamOutput* getParamOutput(std::string paramOutputId) { return _paramOutputFactory[paramOutputId](); } void addParamOutputFactory(std::string paramOutputId, ParamOutputFactory paramOutputFactory) { _paramOutputFactory[paramOutputId] = paramOutputFactory; } StatisticProcess* getStatisticProcess(std::string processId, Parameter ¶meter, int index) { return _statisticProcessFactory[processId](parameter,index); } void addStatisticProcessFactory(std::string processId, StatisticProcessFactory statisticProcessFactory) { _statisticProcessFactory[processId] = statisticProcessFactory; } ParamGet* getParamGet(std::string paramGetId, Parameter ¶meter) { return _paramGetFactory[paramGetId](parameter); } void addParamGetFactory(std::string paramGetId, ParamGetFactory paramGetFactory) { _paramGetFactory[paramGetId] = paramGetFactory; } Process* getProcess(std::string processId, Parameter ¶meter) { auto lIt = _processFactory.find(processId); return (lIt==_processFactory.end())?nullptr:lIt->second(parameter); } void addProcessFactory(std::string processId, ProcessFactory processFactory) { _processFactory[processId] = processFactory; } // Get methods ParameterConfiguratorSPtr& getConfigurator() { return _configurator; } // Set methods void setConfigurator(ParameterConfiguratorSPtr &configurator){ _configurator = configurator; } private: ServicesServer(); virtual ~ServicesServer(); /** * Factory of ParamGet * for a string are a sourceParmGet, use * @code ParamGet p = _paramGetFactory[souceParamGet]() */ ParamGetFactories _paramGetFactory; /** * Factory of Process * for a string are a sourceProcess, use * @code Process p = _processFactory[souceProcess]() */ ProcessFactories _processFactory; /** * Factory of ParamOutput * for a string are a sourceParmOutput, use * @code ParamOutput p = _paramOutputFactory[souceParamGet]() */ ParamOutputFactories _paramOutputFactory; /** * Factory of StatisticProcess */ StatisticProcessFactories _statisticProcessFactory; ParameterConfiguratorSPtr _configurator; /** * List of services. */ ServiceList _serviceList; }; } /* namespace Parameters */ } /* namespace AMDA */ #endif /* SERVICESSERVER_H_ */