Medical Imaging Interaction Toolkit  2018.4.99-12ad79a3
Medical Imaging Interaction Toolkit
usModule.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3  Library: CppMicroServices
4 
5  Copyright (c) German Cancer Research Center (DKFZ)
6  All rights reserved.
7 
8  Licensed under the Apache License, Version 2.0 (the "License");
9  you may not use this file except in compliance with the License.
10  You may obtain a copy of the License at
11 
12  http://www.apache.org/licenses/LICENSE-2.0
13 
14  Unless required by applicable law or agreed to in writing, software
15  distributed under the License is distributed on an "AS IS" BASIS,
16  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  See the License for the specific language governing permissions and
18  limitations under the License.
19 
20 ============================================================================*/
21 
22 
23 #include "usModule.h"
24 
25 #include "usModuleContext.h"
26 #include "usModuleActivator.h"
27 #include "usModulePrivate.h"
28 #include "usModuleResource.h"
29 #include "usModuleSettings.h"
30 #include "usCoreModuleContext_p.h"
31 
32 #include "usCoreConfig.h"
33 
34 US_BEGIN_NAMESPACE
35 
36 const std::string& Module::PROP_ID()
37 {
38  static const std::string s("module.id");
39  return s;
40 }
41 const std::string& Module::PROP_NAME()
42 {
43  static const std::string s("module.name");
44  return s;
45 }
46 const std::string& Module::PROP_LOCATION()
47 {
48  static const std::string s("module.location");
49  return s;
50 }
51 const std::string& Module::PROP_VERSION()
52 {
53  static const std::string s("module.version");
54  return s;
55 }
56 
57 const std::string&Module::PROP_VENDOR()
58 {
59  static const std::string s("module.vendor");
60  return s;
61 }
62 
63 const std::string&Module::PROP_DESCRIPTION()
64 {
65  static const std::string s("module.description");
66  return s;
67 }
68 
69 const std::string&Module::PROP_AUTOLOAD_DIR()
70 {
71  static const std::string s("module.autoload_dir");
72  return s;
73 }
74 
75 const std::string&Module::PROP_AUTOLOADED_MODULES()
76 {
77  static const std::string s("module.autoloaded_modules");
78  return s;
79 }
80 
81 Module::Module()
82 : d(nullptr)
83 {
84 
85 }
86 
87 Module::~Module()
88 {
89  delete d;
90 }
91 
92 void Module::Init(CoreModuleContext* coreCtx,
94 {
95  ModulePrivate* mp = new ModulePrivate(this, coreCtx, info);
96  std::swap(mp, d);
97  delete mp;
98 }
99 
100 void Module::Uninit()
101 {
102  if (d->moduleContext != nullptr)
103  {
104  //d->coreCtx->listeners.HooksModuleStopped(d->moduleContext);
105  d->RemoveModuleResources();
106  delete d->moduleContext;
107  d->moduleContext = nullptr;
108  d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::UNLOADED, this));
109 
110  d->moduleActivator = nullptr;
111  }
112 }
113 
114 bool Module::IsLoaded() const
115 {
116  return d->moduleContext != nullptr;
117 }
118 
119 void Module::Start()
120 {
121 
122  if (d->moduleContext)
123  {
124  US_WARN << "Module " << d->info.name << " already started.";
125  return;
126  }
127 
128  d->moduleContext = new ModuleContext(this->d);
129 
130  typedef ModuleActivator*(*ModuleActivatorHook)(void);
131  ModuleActivatorHook activatorHook = nullptr;
132 
133  std::string activator_func = "_us_module_activator_instance_" + d->info.name;
134  void* activatorHookSym = ModuleUtils::GetSymbol(d->info, activator_func.c_str());
135  std::memcpy(&activatorHook, &activatorHookSym, sizeof(void*));
136 
137  d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::LOADING, this));
138  // try to get a ModuleActivator instance
139 
140  if (activatorHook)
141  {
142  try
143  {
144  d->moduleActivator = activatorHook();
145  }
146  catch (...)
147  {
148  US_ERROR << "Creating the module activator of " << d->info.name << " failed";
149  throw;
150  }
151 
152  // This method should be "noexcept" and by not catching exceptions
153  // here we semantically treat it that way since any exception during
154  // static initialization will either terminate the program or cause
155  // the dynamic loader to report an error.
156  d->moduleActivator->Load(d->moduleContext);
157  }
158 
159 #ifdef US_ENABLE_AUTOLOADING_SUPPORT
160  if (ModuleSettings::IsAutoLoadingEnabled())
161  {
162  const std::vector<std::string> loadedPaths = AutoLoadModules(d->info);
163  if (!loadedPaths.empty())
164  {
165  d->moduleManifest.SetValue(PROP_AUTOLOADED_MODULES(), Any(loadedPaths));
166  }
167  }
168 #endif
169 
170  d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::LOADED, this));
171 }
172 
173 void Module::Stop()
174 {
175  if (d->moduleContext == nullptr)
176  {
177  US_WARN << "Module " << d->info.name << " already stopped.";
178  return;
179  }
180 
181  try
182  {
183  d->coreCtx->listeners.ModuleChanged(ModuleEvent(ModuleEvent::UNLOADING, this));
184 
185  if (d->moduleActivator)
186  {
187  d->moduleActivator->Unload(d->moduleContext);
188  }
189  }
190  catch (...)
191  {
192  US_WARN << "Calling the module activator Unload() method of " << d->info.name << " failed!";
193 
194  try
195  {
196  this->Uninit();
197  }
198  catch (...) {}
199 
200  throw;
201  }
202 
203  this->Uninit();
204 }
205 
207 {
208  return d->moduleContext;
209 }
210 
211 long Module::GetModuleId() const
212 {
213  return d->info.id;
214 }
215 
216 std::string Module::GetLocation() const
217 {
218  return d->info.location;
219 }
220 
221 std::string Module::GetName() const
222 {
223  return d->info.name;
224 }
225 
226 ModuleVersion Module::GetVersion() const
227 {
228  return d->version;
229 }
230 
231 Any Module::GetProperty(const std::string& key) const
232 {
233  return d->moduleManifest.GetValue(key);
234 }
235 
236 std::vector<std::string> Module::GetPropertyKeys() const
237 {
238  return d->moduleManifest.GetKeys();
239 }
240 
241 std::vector<ServiceReferenceU> Module::GetRegisteredServices() const
242 {
243  std::vector<ServiceRegistrationBase> sr;
244  std::vector<ServiceReferenceU> res;
245  d->coreCtx->services.GetRegisteredByModule(d, sr);
246  for (std::vector<ServiceRegistrationBase>::const_iterator i = sr.begin();
247  i != sr.end(); ++i)
248  {
249  res.push_back(i->GetReference());
250  }
251  return res;
252 }
253 
254 std::vector<ServiceReferenceU> Module::GetServicesInUse() const
255 {
256  std::vector<ServiceRegistrationBase> sr;
257  std::vector<ServiceReferenceU> res;
258  d->coreCtx->services.GetUsedByModule(const_cast<Module*>(this), sr);
259  for (std::vector<ServiceRegistrationBase>::const_iterator i = sr.begin();
260  i != sr.end(); ++i)
261  {
262  res.push_back(i->GetReference());
263  }
264  return res;
265 }
266 
267 ModuleResource Module::GetResource(const std::string& path) const
268 {
269  if (!d->resourceContainer.IsValid())
270  {
271  return ModuleResource();
272  }
273  ModuleResource result(path, d->resourceContainer);
274  if (result) return result;
275  return ModuleResource();
276 }
277 
278 std::vector<ModuleResource> Module::FindResources(const std::string& path, const std::string& filePattern,
279  bool recurse) const
280 {
281  std::vector<ModuleResource> result;
282  if (!d->resourceContainer.IsValid())
283  {
284  return result;
285  }
286 
287  std::string normalizedPath = path;
288  // add a leading and trailing slash
289  if (normalizedPath.empty()) normalizedPath.push_back('/');
290  if (*normalizedPath.begin() != '/') normalizedPath = '/' + normalizedPath;
291  if (*normalizedPath.rbegin() != '/') normalizedPath.push_back('/');
292  d->resourceContainer.FindNodes(d->info.name + normalizedPath,
293  filePattern.empty() ? "*" : filePattern,
294  recurse, result);
295  return result;
296 }
297 
298 US_END_NAMESPACE
299 
300 US_USE_NAMESPACE
301 
302 std::ostream& operator<<(std::ostream& os, const Module& module)
303 {
304  os << "Module[" << "id=" << module.GetModuleId() <<
305  ", loc=" << module.GetLocation() <<
306  ", name=" << module.GetName() << "]";
307  return os;
308 }
309 
310 std::ostream& operator<<(std::ostream& os, Module const * module)
311 {
312  return operator<<(os, *module);
313 }
static void info(const char *fmt,...)
Definition: svm.cpp:86
Definition: usAny.h:163
std::vector< std::string > AutoLoadModules(const ModuleInfo &moduleInfo)
Definition: usUtils.cpp:188
static void swap(T &x, T &y)
Definition: svm.cpp:58
static std::string GetName(std::string fileName, std::string suffix)
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
US_USE_NAMESPACE std::ostream & operator<<(std::ostream &os, const Module &module)
Definition: usModule.cpp:302