1 /***************************************************************************
3 * Copyright 2012 BMW Car IT GmbH
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 ****************************************************************************/
20 #include "PluginManager.h"
21 #include "Configuration.h"
31 StaticPluginCreateFuncList PluginManager::mStaticPluginCreateFuncList;
33 //===========================================================================
34 // register statically linked plugins (configured by build system)
35 //===========================================================================
36 STATIC_PLUGIN_REGISTRATION
38 //===========================================================================
39 // class implementation
40 //===========================================================================
41 PluginManager::PluginManager(ICommandExecutor& executor, Configuration& config)
43 , mConfiguration(config)
45 LOG_DEBUG("PluginManager", "loading plugins from " << mConfiguration.getPluginPath());
47 // create static plugins
48 createStaticallyLinkedPlugins();
50 #ifndef WITH_STATIC_LIBRARIES
51 // create dynamic plugins
52 getAllFilesInPluginPath(mConfiguration.getPluginPath());
53 createDynamicallyLinkedPlugins();
56 LOG_INFO("PluginManager", "created " << mPluginList.size() << " plugins");
59 PluginManager::~PluginManager()
61 PluginList::iterator iter = mPluginList.begin();
62 PluginList::iterator iterEnd = mPluginList.end();
64 for (; iter != iterEnd; ++iter)
66 IPlugin* plugin = *iter;
69 LOG_INFO("PluginManager", "plugin " << plugin->pluginGetName() << " destroyed");
76 void PluginManager::getRendererList(RendererList& list)
78 PluginList::const_iterator iter = mPluginList.begin();
79 PluginList::const_iterator iterEnd = mPluginList.end();
81 for (; iter != iterEnd; ++iter)
83 IPlugin* plugin = *iter;
84 ilmPluginApi api = plugin->pluginGetApi();
85 if (PLUGIN_IS_RENDERER(api))
87 IRenderer* renderer = dynamic_cast<IRenderer*>(plugin);
88 list.push_back(renderer);
93 void PluginManager::getHealthMonitorList(HealthMonitorList& list)
95 PluginList::const_iterator iter = mPluginList.begin();
96 PluginList::const_iterator iterEnd = mPluginList.end();
98 for (; iter != iterEnd; ++iter)
100 IPlugin* plugin = *iter;
101 ilmPluginApi api = plugin->pluginGetApi();
102 if (PLUGIN_IS_HEALTHMONITOR(api))
104 IHealthMonitor* monitor = dynamic_cast<IHealthMonitor*>(plugin);
107 list.push_back(monitor);
113 void PluginManager::getSceneProviderList(SceneProviderList& list)
115 PluginList::const_iterator iter = mPluginList.begin();
116 PluginList::const_iterator iterEnd = mPluginList.end();
118 for (; iter != iterEnd; ++iter)
120 IPlugin* plugin = *iter;
121 ilmPluginApi api = plugin->pluginGetApi();
122 if (PLUGIN_IS_SCENEPROVIDER(api))
124 ISceneProvider* sceneprovider = dynamic_cast<ISceneProvider*>(plugin);
125 list.push_back(sceneprovider);
130 void PluginManager::getCommunicatorList(CommunicatorList& list)
132 PluginList::const_iterator iter = mPluginList.begin();
133 PluginList::const_iterator iterEnd = mPluginList.end();
135 for (; iter != iterEnd; ++iter)
137 IPlugin* plugin = *iter;
138 ilmPluginApi api = plugin->pluginGetApi();
139 if (PLUGIN_IS_COMMUNICATOR(api))
141 ICommunicator* comm = dynamic_cast<ICommunicator*>(plugin);
142 list.push_back(comm);
148 bool PluginManager::registerStaticPluginCreateFunction(StaticPluginCreateFunc func)
153 mStaticPluginCreateFuncList.push_back(func);
159 void PluginManager::createStaticallyLinkedPlugins()
161 StaticPluginCreateFuncList::iterator iter = mStaticPluginCreateFuncList.begin();
162 StaticPluginCreateFuncList::iterator iterEnd = mStaticPluginCreateFuncList.end();
164 for (; iter != iterEnd; ++iter)
166 StaticPluginCreateFunc func = *iter;
167 IPlugin* plugin = (*func)(mExecutor, mConfiguration);
168 LOG_INFO("PluginManager", "creating plugin " << plugin->pluginGetName() << " (static linking)");
169 mPluginList.push_back(plugin);
173 void PluginManager::getAllFilesInPluginPath(std::string path)
175 DIR *directory = opendir(path.c_str());
176 struct dirent *itemInDirectory = 0;
178 while (directory && (itemInDirectory = readdir(directory)))
180 unsigned char entryType = itemInDirectory->d_type;
181 std::string entryName = itemInDirectory->d_name;
182 std::string fullPath = path + "/" + entryName;
184 if (entryName.at(0) == '.')
194 mFileList.push_back(fullPath);
195 LOG_DEBUG("PluginManager", "considering File " << fullPath);
199 getAllFilesInPluginPath(fullPath);
203 LOG_DEBUG("PluginManager", "ignored file " << fullPath);
211 void PluginManager::createDynamicallyLinkedPlugins()
213 FileList::const_iterator iter = mFileList.begin();
214 FileList::const_iterator iterEnd = mFileList.end();
216 for (; iter != iterEnd; ++iter)
218 IPlugin* plugin = createDynamicallyLinkedPlugin(*iter);
221 mPluginList.push_back(plugin);
226 IPlugin* PluginManager::createDynamicallyLinkedPlugin(std::string path)
228 IPlugin* returnValue = NULL;
232 dlerror(); // Clear any existing error
233 libraryHandle = dlopen(path.c_str(), RTLD_NOW | RTLD_GLOBAL);
234 const char* dlopen_error = dlerror();
237 LOG_DEBUG("PluginManager", "not a shared library: " << dlopen_error);
245 IPlugin* (*createFunc)(ICommandExecutor&, Configuration&);
248 int cutBegin = path.find_last_of('/') + 4; // remove '*/lib' from name
249 int cutEnd = path.find_first_of('.', cutBegin); // remove '.extension' from name
251 std::string createFunctionName = "create";
252 createFunctionName += path.substr(cutBegin, cutEnd - cutBegin);
254 convertUnion.data = dlsym(libraryHandle, createFunctionName.c_str());
256 // create plugin instance from entry point
257 const char* dlsym_error = dlerror();
258 if (convertUnion.data && !dlsym_error)
260 returnValue = convertUnion.createFunc(mExecutor, mConfiguration);
261 LOG_INFO("PluginManager", "creating plugin " << returnValue->pluginGetName() << " (dynamic linking)");
265 LOG_DEBUG("PluginManager", "not a valid Plugin: " << path << ": " << dlsym_error);
266 dlclose(libraryHandle);