/* * ModuleManager.cpp * * Created on: 2011-8-29 * Author: dev */ #include #include "ModuleManager.h" #include "Module.h" #include "ParameterItem.h" #include "ModuleMetaData.h" #include "ModuleParameter.h" // #include "json/json.h" // #include "Configure.h" #include #include #include #include #include #include #include "Turtle.h" #include #include #include // #include #include #include #include // #include "Log.h" using namespace std; using namespace pai::turtle; namespace pai { namespace module { static const char * MODULE_PATH = "module"; //需要使用的字符串常量 const std::string DERECTORY_SPLIT = "/"; //文件夹分割符 const std::string JSON_METADATA_FILE_SUFFIX = "MetaData.json"; //JSON文件后缀名 const std::string KEY_JSON_MODULE_NAME = "ModuleName"; //JSON文件里 文件名字段 KEY ModuleName const std::string KEY_JSON_META_DATA = "MetaData"; //JSON文件里 MetaData字段 KEY MetaData const std::string KEY_JSON_CLASS_NAME = "ClassName"; //JSON文件里 ClassName字段 KEY ClassName const std::string KEY_JSON_LIB_NAME = "LibName"; //JSON文件里 LibName字段 KEY LibName #if defined(_WINDOWS) const std::string LIB_NAME_PREFIX = ""; //动态库前缀名 const std::string LIB_NAME_SUFFIX = ".dll"; //动态库后缀名 #else const std::string LIB_NAME_PREFIX = "lib"; //动态库前缀名 const std::string LIB_NAME_SUFFIX = ".so"; //动态库后缀名 #endif CModuleManager::CModuleManager() : m_moduleContainer(), m_modulePaths(), m_moduleHandles(), m_isLoadAllModules(false) { // pai::conf::CConfigure config; // string loadLazy = config.GetValueByKey("MODULE_LOAD_LAZY"); // if(loadLazy == "false") { // pai::log::Info("using load all module mode"); LoadAllModules(); } } CModuleManager::~CModuleManager() { for (std::map::iterator it = m_moduleContainer.begin(); it != m_moduleContainer.end(); it++) { if(it->second != NULL) { delete it->second; it->second = NULL; } } for (std::vector::iterator it = m_moduleHandles.begin(); it != m_moduleHandles.end(); it++) { if(*it) GetTurtleAPI()->CloseLibrary(*it); } } CModule* CModuleManager::CreateModuleByClassNameInternal(const std::string& strModuleClassName) { CModule* pModule = CModuleFactory::Instance()->CreateModule(strModuleClassName); if (pModule == NULL) { std::map::const_iterator it = m_modulePaths.find(strModuleClassName); if (it != m_modulePaths.end()) { void* handle = GetTurtleAPI()->OpenLibrary(it->second); if (handle == 0) { std::stringstream errorMsg; errorMsg << std::string(GetTurtleAPI()->ErrorLibrary()) << std::endl; errorMsg <<"Please check " << it->second << " first." << std::endl; // pai::log::Error(errorMsg.str()); return NULL;; } m_moduleHandles.push_back(handle); pModule = CModuleFactory::Instance()->CreateModule(strModuleClassName); } else { std::stringstream errorMsg; errorMsg << strModuleClassName << " not registered." << std::endl; // pai::log::Error(errorMsg.str()); return NULL; } } if (NULL == pModule) { std::stringstream errorMsg; errorMsg << strModuleClassName << " Cannot load " << std::endl; // pai::log::Error(errorMsg.str()); } return pModule; } CModule* CModuleManager::CreateModuleByClassName(const std::string& strModuleClassName) { //如果是特殊的PELibraryModule模块,则从注册的模块中clone一份 std::string PELibraryModule_="PELibraryModule_"; int x=strModuleClassName.find(PELibraryModule_); if(x>=0) { CModule* templateModule=GetModuleManager()->FindModule(strModuleClassName.substr(x+PELibraryModule_.length(),100)); if(templateModule) return templateModule->Clone(); } //////////////////////////////////////////// if(!LoadModuleByClassName(strModuleClassName)) { // pai::log::Error("Load "+strModuleClassName + "失败,可能原因如下:1.JSON文件格式错误,2.部署的模块版本与当前系统不兼容,请联系模块的开发人员或管理员"); return NULL; } CModule* pModule = CreateModuleByClassNameInternal(strModuleClassName); if(pModule==NULL){ // pai::log::Error("Create "+strModuleClassName + "失败,可能原因如下:1.JSON文件格式错误,2.部署的模块版本与当前系统不兼容,请联系模块的开发人员或管理员"); return pModule; } std::map::const_iterator it = m_moduleContainer.begin(); for (; it != m_moduleContainer.end(); ++it) { if (std::string(it->second->GetClassName()) == strModuleClassName) { //拷贝元数据和参数部分 CModuleParameter* pModuleParameter = pModule->GetModuleParameter(); *pModuleParameter = *(it->second->GetModuleParameter()); *(pModule->GetMetaData()) = *(it->second->GetMetaData()); //调用模块需要元数据的初始 pModule->Initialize(); break; } } return pModule; } void CModuleManager::Initialize(string jsonPath) { //得到jsonPath目录下所有json文件名 // DIR* dp; // struct dirent* ep; // dp = opendir(jsonPath.c_str()); // if(dp != NULL) // { // while((ep = readdir(dp))) // { // string tmpPath = jsonPath +DERECTORY_SPLIT+ ep->d_name; // size_t pos = tmpPath.rfind(JSON_METADATA_FILE_SUFFIX, tmpPath.length()-1); //失败返回第二个参数 // pai::log::Debug("Begin parse "+tmpPath); // if(pos == (tmpPath.length() - JSON_METADATA_FILE_SUFFIX.length()))//是.json文件的时候注册模块 // { // Json::Value root; // ParseMetaData(tmpPath,root); // LoadModule(root); // } // }//end of while // closedir(dp); // } // else // { // std::stringstream errorMsg; // errorMsg << "打开目录:"<(pModel->GetMetaData()); // pMetaData->LoadFromJsonObject(rMeta); // pMetaData->LoadIOFromJsonObject(PORT_INPUT, root); // pMetaData->LoadIOFromJsonObject(PORT_OUTPUT, root); // CModuleParameter* pModuleParam = pModel->GetModuleParameter(); // try // { // pModuleParam->LoadFromJson(root,true); // } // catch (pai::error::generic_error & e) // { // std::stringstream errorMsg; // errorMsg << "\nAn error occurred when create module " << pMetaData->GetName() // << ": Load parameter from json failed!" << e.what(); // pai::log::Error(errorMsg.str()); // } // m_moduleContainer.insert(make_pair(pMetaData->GetID(), pModel)); // return true; // } // else // { // std::string errorMsg = " 创建Module失败,该模块部署错误,可能被误删除或者部署了错误的版本,请联系该模块开发人员!cannot create class "+rMeta["ClassName"].asString()+" from "+"lib"+rMeta["LibName"].asString()+".so"; // pai::log::Error(errorMsg); // return false; // } // } void CModuleManager::ListAllModules(std::vector& vecModules) const { std::map::const_iterator it = m_moduleContainer.begin(); while(it != m_moduleContainer.end()) { vecModules.push_back(it->second); it++; } } CModule* CModuleManager::FindModule(const std::string& id) const { std::map::const_iterator it = m_moduleContainer.find(id); if (it != m_moduleContainer.end()) { return it->second; } return NULL; } CModuleMetaData* CModuleManager::FindModuleMetaData(const std::string& id) const { CModule* module = FindModule(id); if(module==NULL) return NULL; else return module->GetMetaData(); } void CModuleManager::GetModulesByCategory(const std::string& strCategory, std::vector& vecModules) { std::map::const_iterator it = m_moduleContainer.begin(); for (; it != m_moduleContainer.end(); ++it) { if (it->second->GetMetaData()->GetCategory() == strCategory) { vecModules.push_back(it->second); } } } void CModuleManager::GetCategoryNames(std::vector& vecCategoryNames) { vecCategoryNames.clear(); std::map::const_iterator it = m_moduleContainer.begin(); for (; it != m_moduleContainer.end(); ++it) { vecCategoryNames.push_back(it->second->GetMetaData()->GetCategory()); } sort(vecCategoryNames.begin(), vecCategoryNames.end()); vecCategoryNames.erase(unique(vecCategoryNames.begin(), vecCategoryNames.end()), vecCategoryNames.end()); } string CModuleManager::GetLibDeployPath() const { return MODULE_PATH; } void CModuleManager::ReLoadAllModules() { char * pVal = (char*)PAI_HOME.c_str(); //getenv(PAI_HOME.c_str())获取环境变量PAI_HOME string str = pVal; string path = DERECTORY_SPLIT; path.append(MODULE_PATH); str += path; Initialize(str); } void CModuleManager::LoadAllModules() { if(!m_isLoadAllModules){ ReLoadAllModules(); m_isLoadAllModules = true; } } void CModuleManager::AddModule(std::string modulefileFullPathName,CModule* aModule,void* modulehandle) { m_moduleContainer.insert(make_pair(aModule->GetMetaData()->GetID(), aModule)); m_modulePaths.insert(make_pair(aModule->GetMetaData()->GetID(), modulefileFullPathName)); m_moduleHandles.push_back(modulehandle); } CModuleManager* GetModuleManager() { static CModuleManager g_moduleManager; return &g_moduleManager; } } }