/* * 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 #include #include "log4cxx/logger.h" #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 &, const int&) > StatisticProcessFactory; typedef std::map StatisticProcessFactories; // map to link process with pluging typedef std::map> AMDA_ProcessPluginMaps; 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){ if (_PLUGINS_DYNAMIC_LOADING) loadPlugin(pImplName); 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) { if (_PLUGINS_DYNAMIC_LOADING) loadPlugin(paramOutputId, "paramOutputs"); return _paramOutputFactory[paramOutputId](); } void addParamOutputFactory(std::string paramOutputId, ParamOutputFactory paramOutputFactory) { _paramOutputFactory[paramOutputId] = paramOutputFactory; } StatisticProcess* getStatisticProcess(std::string processId, Parameter ¶meter, int index) { if (_PLUGINS_DYNAMIC_LOADING) loadPlugin(processId, "statisticProcess"); 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) { if (_PLUGINS_DYNAMIC_LOADING) loadPlugin(processId, "process"); 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; } // link Process with the corresponding Plugin void linkProcessWithPlugin(std::string process, std::string pluginPath) { if (pluginPath != "") _processPluginMaps["process"].insert(std::pair(process, pluginPath)); } void linkStatisticProcessWithPlugin(std::string process, std::string pluginPath) { if (pluginPath != "") _processPluginMaps["statisticProcess"].insert(std::pair(process, pluginPath)); } void linkParamOutputsWithPlugin(std::string process, std::string pluginPath) { if (pluginPath != "") _processPluginMaps["paramOutputs"].insert(std::pair(process, pluginPath)); } void linkParamGetWithPlugin(std::string process, std::string pluginPath) { _processPluginMaps["paramGet"].insert(std::pair(process, pluginPath)); } bool generatePluginsXml(const char* filePath); bool fillPluginsMap(std::string xmlFile, std::string xsdFile); void setPluginsDynamicLoading(bool isPluginsDynamicLoading) { _PLUGINS_DYNAMIC_LOADING = isPluginsDynamicLoading; } bool getPluginsDynamicLoading() { return _PLUGINS_DYNAMIC_LOADING; } bool loadPlugin(const std::string& process, const std::string& type = ""); bool loadPluginByType(const std::string& type); bool loadPluginsFromRequest(const char* requestXML); std::list getPluginsToLoad() { return _pluginsToLoad; } 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; /** * Map of processes and corresponding plugins */ AMDA_ProcessPluginMaps _processPluginMaps; /** * List of services. */ ServiceList _serviceList; static bool _PLUGINS_DYNAMIC_LOADING; std::list _pluginsToLoad; std::list _outputs{"