Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
usServiceHooks.cpp
Go to the documentation of this file.
1 /*=============================================================================
2 
3  Library: CppMicroServices
4 
5  Copyright (c) German Cancer Research Center,
6  Division of Medical and Biological Informatics
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 #include "usServiceHooks_p.h"
23 
24 #include "usGetModuleContext.h"
25 #include "usCoreModuleContext_p.h"
27 #include "usServiceFindHook.h"
28 #include "usServiceListenerHook.h"
29 #include "usServiceReferenceBasePrivate.h"
30 
31 US_BEGIN_NAMESPACE
32 
33 ServiceHooks::ServiceHooks(CoreModuleContext* coreCtx)
34  : coreCtx(coreCtx)
35  , listenerHookTracker(NULL)
36  , bOpen(false)
37 {
38 }
39 
40 ServiceHooks::~ServiceHooks()
41 {
42  this->Close();
43 }
44 
45 ServiceHooks::TrackedType ServiceHooks::AddingService(const ServiceReferenceType& reference)
46 {
47  ServiceListenerHook* lh = GetModuleContext()->GetService(reference);
48  try
49  {
50  lh->Added(coreCtx->listeners.GetListenerInfoCollection());
51  }
52  catch (const std::exception& e)
53  {
54  US_WARN << "Failed to call listener hook #" << reference.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
55  << ": " << e.what();
56  }
57  catch (...)
58  {
59  US_WARN << "Failed to call listener hook #" << reference.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
60  << ": unknown exception type";
61  }
62  return lh;
63 }
64 
65 void ServiceHooks::ModifiedService(const ServiceReferenceType& /*reference*/, TrackedType /*service*/)
66 {
67  // noop
68 }
69 
70 void ServiceHooks::RemovedService(const ServiceReferenceType& reference, TrackedType /*service*/)
71 {
72  GetModuleContext()->UngetService(reference);
73 }
74 
75 void ServiceHooks::Open()
76 {
77  US_UNUSED(Lock(this));
78 
79  listenerHookTracker = new ServiceTracker<ServiceListenerHook>(GetModuleContext(), this);
80  listenerHookTracker->Open();
81 
82  bOpen = true;
83 }
84 
85 void ServiceHooks::Close()
86 {
87  US_UNUSED(Lock(this));
88  if (listenerHookTracker)
89  {
90  listenerHookTracker->Close();
91  delete listenerHookTracker;
92  listenerHookTracker = NULL;
93  }
94 
95  bOpen = false;
96 }
97 
98 bool ServiceHooks::IsOpen() const
99 {
100  US_UNUSED(Lock(this));
101  return bOpen;
102 }
103 
104 void ServiceHooks::FilterServiceReferences(ModuleContext* mc, const std::string& service,
105  const std::string& filter, std::vector<ServiceReferenceBase>& refs)
106 {
107  std::vector<ServiceRegistrationBase> srl;
108  coreCtx->services.Get_unlocked(us_service_interface_iid<ServiceFindHook>(), srl);
109  if (!srl.empty())
110  {
111  ShrinkableVector<ServiceReferenceBase> filtered(refs);
112 
113  std::sort(srl.begin(), srl.end());
114  for (std::vector<ServiceRegistrationBase>::reverse_iterator fhrIter = srl.rbegin(), fhrEnd = srl.rend();
115  fhrIter != fhrEnd; ++fhrIter)
116  {
117  ServiceReference<ServiceFindHook> sr = fhrIter->GetReference();
118  ServiceFindHook* const fh = reinterpret_cast<ServiceFindHook*>(sr.d->GetService(GetModuleContext()->GetModule()));
119  if (fh != NULL)
120  {
121  try
122  {
123  fh->Find(mc, service, filter, filtered);
124  }
125  catch (const std::exception& e)
126  {
127  US_WARN << "Failed to call find hook #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
128  << ": " << e.what();
129  }
130  catch (...)
131  {
132  US_WARN << "Failed to call find hook #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
133  << ": unknown exception type";
134  }
135  }
136  }
137  }
138 }
139 
140 void ServiceHooks::FilterServiceEventReceivers(const ServiceEvent& evt,
141  ServiceListeners::ServiceListenerEntries& receivers)
142 {
143  std::vector<ServiceRegistrationBase> eventListenerHooks;
144  coreCtx->services.Get_unlocked(us_service_interface_iid<ServiceEventListenerHook>(), eventListenerHooks);
145  if (!eventListenerHooks.empty())
146  {
147  std::sort(eventListenerHooks.begin(), eventListenerHooks.end());
148  std::map<ModuleContext*, std::vector<ServiceListenerHook::ListenerInfo> > listeners;
149  for (ServiceListeners::ServiceListenerEntries::iterator sleIter = receivers.begin(),
150  sleEnd = receivers.end(); sleIter != sleEnd; ++sleIter)
151  {
152  listeners[sleIter->GetModuleContext()].push_back(*sleIter);
153  }
154 
155  std::map<ModuleContext*, ShrinkableVector<ServiceListenerHook::ListenerInfo> > shrinkableListeners;
156  for (std::map<ModuleContext*, std::vector<ServiceListenerHook::ListenerInfo> >::iterator iter = listeners.begin(),
157  iterEnd = listeners.end(); iter != iterEnd; ++iter)
158  {
159  shrinkableListeners.insert(std::make_pair(iter->first, ShrinkableVector<ServiceListenerHook::ListenerInfo>(iter->second)));
160  }
161 
162  ShrinkableMap<ModuleContext*, ShrinkableVector<ServiceListenerHook::ListenerInfo> > filtered(shrinkableListeners);
163 
164  for(std::vector<ServiceRegistrationBase>::reverse_iterator sriIter = eventListenerHooks.rbegin(),
165  sriEnd = eventListenerHooks.rend(); sriIter != sriEnd; ++sriIter)
166  {
167  ServiceReference<ServiceEventListenerHook> sr = sriIter->GetReference();
168  ServiceEventListenerHook* elh = reinterpret_cast<ServiceEventListenerHook*>(sr.d->GetService(GetModuleContext()->GetModule()));
169  if(elh != NULL)
170  {
171  try
172  {
173  elh->Event(evt, filtered);
174  }
175  catch(const std::exception& e)
176  {
177  US_WARN << "Failed to call event hook #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
178  << ": " << e.what();
179  }
180  catch(...)
181  {
182  US_WARN << "Failed to call event hook #" << sr.GetProperty(ServiceConstants::SERVICE_ID()).ToString()
183  << ": unknown exception type";
184  }
185  }
186  }
187  receivers.clear();
188  for(std::map<ModuleContext*, std::vector<ServiceListenerHook::ListenerInfo> >::iterator iter = listeners.begin(),
189  iterEnd = listeners.end(); iter != iterEnd; ++iter)
190  {
191  receivers.insert(iter->second.begin(), iter->second.end());
192  }
193  }
194 }
195 
196 void ServiceHooks::HandleServiceListenerReg(const ServiceListenerEntry& sle)
197 {
198  if(!IsOpen() || listenerHookTracker->Size() == 0)
199  {
200  return;
201  }
202 
203  std::vector<ServiceReference<ServiceListenerHook> > srl
204  = listenerHookTracker->GetServiceReferences();
205 
206  if (!srl.empty())
207  {
208  std::sort(srl.begin(), srl.end());
209 
210  std::vector<ServiceListenerHook::ListenerInfo> set;
211  set.push_back(sle);
212  for (std::vector<ServiceReference<ServiceListenerHook> >::reverse_iterator srIter = srl.rbegin(),
213  srEnd = srl.rend(); srIter != srEnd; ++srIter)
214  {
215  ServiceListenerHook* lh = listenerHookTracker->GetService(*srIter);
216  try
217  {
218  lh->Added(set);
219  }
220  catch (const std::exception& e)
221  {
222  US_WARN << "Failed to call listener hook #" << srIter->GetProperty(ServiceConstants::SERVICE_ID()).ToString()
223  << ": " << e.what();
224  }
225  catch (...)
226  {
227  US_WARN << "Failed to call listener hook #" << srIter->GetProperty(ServiceConstants::SERVICE_ID()).ToString()
228  << ": unknown exception";
229  }
230  }
231  }
232 }
233 
234 void ServiceHooks::HandleServiceListenerUnreg(const ServiceListenerEntry& sle)
235 {
236  if(IsOpen())
237  {
238  std::vector<ServiceListenerEntry> set;
239  set.push_back(sle);
240  HandleServiceListenerUnreg(set);
241  }
242 }
243 
244 void ServiceHooks::HandleServiceListenerUnreg(const std::vector<ServiceListenerEntry>& set)
245 {
246  if(!IsOpen() || listenerHookTracker->Size() == 0)
247  {
248  return;
249  }
250 
251  std::vector<ServiceReference<ServiceListenerHook> > srl
252  = listenerHookTracker->GetServiceReferences();
253 
254  if (!srl.empty())
255  {
256  std::vector<ServiceListenerHook::ListenerInfo> lis;
257  for (std::vector<ServiceListenerEntry>::const_iterator sleIter = set.begin(),
258  sleEnd = set.end(); sleIter != sleEnd; ++sleIter)
259  {
260  lis.push_back(*sleIter);
261  }
262 
263  std::sort(srl.begin(), srl.end());
264  for (std::vector<ServiceReference<ServiceListenerHook> >::reverse_iterator srIter = srl.rbegin(),
265  srEnd = srl.rend(); srIter != srEnd; ++srIter)
266  {
267  ServiceListenerHook* const lh = listenerHookTracker->GetService(*srIter);
268  try
269  {
270  lh->Removed(lis);
271  }
272  catch (const std::exception& e)
273  {
274  US_WARN << "Failed to call listener hook #" << srIter->GetProperty(ServiceConstants::SERVICE_ID()).ToString()
275  << ": " << e.what();
276  }
277  catch (...)
278  {
279  US_WARN << "Failed to call listener hook #" << srIter->GetProperty(ServiceConstants::SERVICE_ID()).ToString()
280  << ": unknown exception type";
281  }
282  }
283  }
284 }
285 
286 US_END_NAMESPACE
bool UngetService(const ServiceReferenceBase &reference)
void * GetService(const ServiceReferenceBase &reference)
virtual void Event(const ServiceEvent &event, ShrinkableMapType &listeners)=0
MITKMATCHPOINTREGISTRATION_EXPORT ResultImageType::Pointer map(const InputImageType *input, const RegistrationType *registration, bool throwOnOutOfInputAreaError=false, const double &paddingValue=0, const ResultImageGeometryType *resultGeometry=NULL, bool throwOnMappingError=true, const double &errorValue=0, mitk::ImageMappingInterpolator::Type interpolatorType=mitk::ImageMappingInterpolator::Linear)
US_Core_EXPORT const std::string & SERVICE_ID()
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.