Medical Imaging Interaction Toolkit  2018.4.99-12ad79a3
Medical Imaging Interaction Toolkit
berryExtensionTracker.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "berryExtensionTracker.h"
14 
15 #include <berryIExtension.h>
16 #include <berryIExtensionPoint.h>
21 #include <berryListenerList.h>
22 #include <berryLog.h>
23 #include "internal/berrySimpleExtensionPointFilter.h"
24 #include <berryPlatform.h>
25 
26 #include <QSet>
27 #include <QHash>
28 #include <QMutex>
29 
30 namespace berry {
31 
32 struct ExtensionTracker::Impl
33 {
34  struct HandlerWrapper;
35 
36  ExtensionTracker* const q;
37  QHash<IExtension::Pointer, QSet<Object::Pointer> > extensionToStrongObjects;
38  QHash<IExtension::Pointer, QSet<Object::WeakPtr> > extensionToWeakObjects;
39  //ListenerList<HandlerWrapper> handlers;
40  QHash<IExtensionChangeHandler*, HandlerWrapper*> handlerToWrapper;
41  QMutex mutex;
42  bool closed;
43  IExtensionRegistry* registry; // the registry that this tacker works with
44 
45  Impl(ExtensionTracker* q, IExtensionRegistry* theRegistry)
46  : q(q)
47  , closed(false)
48  , registry(theRegistry)
49  {}
50 
51 };
52 
53 struct ExtensionTracker::Impl::HandlerWrapper : public IRegistryEventListener
54 {
55  ExtensionTracker* const q;
56  IExtensionChangeHandler* const handler;
57 
58  HandlerWrapper(ExtensionTracker* q, IExtensionChangeHandler* handler)
59  : q(q)
60  , handler(handler)
61  {}
62 
63  bool operator==(const HandlerWrapper& target) const
64  {
65  return handler == target.handler;
66  }
67 
68  void Added(const QList<IExtension::Pointer>& extensions) override
69  {
70  for (int i = 0; i < extensions.size(); ++i)
71  {
72  q->ApplyAdd(handler, extensions[i]);
73  }
74  }
75 
76  void Removed(const QList<IExtension::Pointer>& extensions) override
77  {
78  QList<QList<Object::Pointer> > removedObjects;
79  {
80  QMutexLocker lock(&q->d->mutex);
81  for (int i = 0; i < extensions.size(); ++i)
82  {
83  QSet<Object::Pointer> associatedObjects = q->d->extensionToStrongObjects.take(extensions[i]);
84  foreach(const Object::WeakPtr& ptr, q->d->extensionToWeakObjects.take(extensions[i]))
85  {
86  if (!ptr.Expired())
87  {
88  associatedObjects.insert(ptr.Lock());
89  }
90  }
91  removedObjects.push_back(associatedObjects.toList());
92  }
93  }
94  for (int i = 0; i < extensions.size(); ++i)
95  {
96  q->ApplyRemove(handler, extensions[i], removedObjects[i]);
97  }
98  }
99 
100  void Added(const QList<IExtensionPoint::Pointer>& /*extensionPoints*/) override
101  {
102  // do nothing
103  }
104 
105  void Removed(const QList<IExtensionPoint::Pointer>& /*extensionPoints*/) override
106  {
107  // do nothing
108  }
109 };
110 
112 {
113  this->Init(Platform::GetExtensionRegistry());
114 }
115 
117 {
118 }
119 
121  : d()
122 {
123  this->Init(theRegistry);
124 }
125 
126 void ExtensionTracker::Init(IExtensionRegistry* registry)
127 {
128  d.reset(new Impl(this, registry));
129  if (registry == nullptr)
130  {
131  //RuntimeLog.log(new Status(IStatus.ERROR, RegistryMessages.OWNER_NAME, 0, RegistryMessages.registry_no_default, null));
132  BERRY_ERROR << "Extension tracker was unable to obtain BlueBerry extension registry.";
133  d->closed = true;
134  }
135 }
136 
138 {
139  QMutexLocker lock(&d->mutex);
140  if (d->closed) return;
141  auto iter = d->handlerToWrapper.insert(handler, new Impl::HandlerWrapper(this, handler));
142  d->registry->AddListener(iter.value(), filter);
143 }
144 
145 void ExtensionTracker::RegisterHandler(IExtensionChangeHandler* handler, const QString& extensionPointId)
146 {
147  this->RegisterHandler(handler, extensionPointId.isEmpty() ? IExtensionPointFilter(nullptr)
148  : IExtensionPointFilter(new SimpleExtensionPointFilter(extensionPointId)));
149 }
150 
152 {
153  QMutexLocker lock(&d->mutex);
154  if (d->closed) return;
155  IRegistryEventListener* listener = d->handlerToWrapper.take(handler);
156  d->registry->RemoveListener(listener);
157  delete listener;
158 }
159 
161 {
162  if (element.IsNull() || object.IsNull()) return;
163 
164  QMutexLocker lock(&d->mutex);
165  if (d->closed) return;
166 
167  if (referenceType == REF_STRONG)
168  {
169  d->extensionToStrongObjects[element].insert(object);
170  }
171  else if (referenceType == REF_WEAK)
172  {
173  d->extensionToWeakObjects[element].insert(Object::WeakPtr(object));
174  }
175 }
176 
177 QList<SmartPointer<Object> > ExtensionTracker::GetObjects(const IExtension::Pointer& element) const
178 {
179  QSet<Object::Pointer> objectSet;
180 
181  QMutexLocker lock(&d->mutex);
182  if (d->closed) return objectSet.toList();
183 
184  auto iter = d->extensionToStrongObjects.find(element);
185  if (iter != d->extensionToStrongObjects.end())
186  {
187  objectSet.unite(iter.value());
188  }
189  auto iter2 = d->extensionToWeakObjects.find(element);
190  if (iter2 != d->extensionToWeakObjects.end())
191  {
192  foreach(const Object::WeakPtr& ptr, iter2.value())
193  {
194  if (!ptr.Expired()) objectSet.insert(ptr.Lock());
195  }
196  }
197  return objectSet.toList();
198 }
199 
201 {
202  QMutexLocker lock(&d->mutex);
203  if (d->closed) return;
204  foreach(Impl::HandlerWrapper* wrapper, d->handlerToWrapper.values())
205  {
206  d->registry->RemoveListener(wrapper);
207  delete wrapper;
208  }
209  d->extensionToStrongObjects.clear();
210  d->extensionToWeakObjects.clear();
211  d->handlerToWrapper.clear();
212 
213  d->closed = true;
214 }
215 
217 {
218  QMutexLocker lock(&d->mutex);
219  if (d->closed) return;
220 
221  auto iter = d->extensionToStrongObjects.find(extension);
222  if (iter != d->extensionToStrongObjects.end())
223  {
224  iter.value().remove(object);
225  }
226  auto iter2 = d->extensionToWeakObjects.find(extension);
227  if (iter2 != d->extensionToWeakObjects.end())
228  {
229  iter2.value().remove(Object::WeakPtr(object));
230  }
231 }
232 
233 QList<SmartPointer<Object> > ExtensionTracker::UnregisterObject(const SmartPointer<IExtension>& extension)
234 {
235  QSet<Object::Pointer> objectSet;
236 
237  QMutexLocker lock(&d->mutex);
238  if (d->closed) return objectSet.toList();
239 
240  auto iter = d->extensionToStrongObjects.find(extension);
241  if (iter != d->extensionToStrongObjects.end())
242  {
243  objectSet.unite(iter.value());
244  d->extensionToStrongObjects.erase(iter);
245  }
246  auto iter2 = d->extensionToWeakObjects.find(extension);
247  if (iter2 != d->extensionToWeakObjects.end())
248  {
249  foreach(const Object::WeakPtr& ptr, iter2.value())
250  {
251  if (!ptr.Expired()) objectSet.insert(ptr.Lock());
252  }
253  d->extensionToWeakObjects.erase(iter2);
254  }
255 
256  return objectSet.toList();
257 }
258 
260 {
261  struct F : IExtensionPointFilter::Concept {
262  const IExtensionPoint::Pointer m_Xpt;
263 
264  F(const IExtensionPoint::Pointer& xp)
265  : m_Xpt(xp)
266  {}
267 
268  bool Matches(const IExtensionPoint* target) const override
269  {
270  return m_Xpt == target;
271  }
272  };
273 
274  return IExtensionPointFilter(new F(xpt));
275 }
276 
278 {
279  struct F : IExtensionPointFilter::Concept {
280  const QList<IExtensionPoint::Pointer> m_Xpts;
281 
282  F(const QList<IExtensionPoint::Pointer>& xps)
283  : m_Xpts(xps)
284  {}
285 
286  bool Matches(const IExtensionPoint* target) const override
287  {
288  for (int i = 0; i < m_Xpts.size(); i++)
289  {
290  if (m_Xpts[i] == target)
291  {
292  return true;
293  }
294  }
295  return false;
296  }
297  };
298 
299  return IExtensionPointFilter(new F(xpts));
300 }
301 
303 {
304  struct F : IExtensionPointFilter::Concept {
305  const QString m_Id;
306 
307  F(const QString& id)
308  : m_Id(id)
309  {}
310 
311  bool Matches(const IExtensionPoint* target) const override
312  {
313  return m_Id == target->GetNamespaceIdentifier();
314  }
315  };
316 
317  return IExtensionPointFilter(new F(id));
318 }
319 
321 {
322  handler->AddExtension(this, extension);
323 }
324 
325 void ExtensionTracker::ApplyRemove(IExtensionChangeHandler* handler, const SmartPointer<IExtension>& removedExtension, const QList<Object::Pointer>& removedObjects)
326 {
327  handler->RemoveExtension(removedExtension, removedObjects);
328 }
329 
330 }
static MsgHandler handler
Definition: usUtils.cpp:261
QList< SmartPointer< Object > > GetObjects(const SmartPointer< IExtension > &element) const override
Implements transparent reference counting.
virtual void ApplyRemove(IExtensionChangeHandler *handler, const SmartPointer< IExtension > &removedExtension, const QList< SmartPointer< Object > > &removedObjects)
MITKCORE_EXPORT bool operator==(const InteractionEvent &a, const InteractionEvent &b)
#define BERRY_ERROR
Definition: berryLog.h:22
SmartPointer< ObjectType > Lock() const
static IExtensionPointFilter CreateExtensionPointFilter(const SmartPointer< IExtensionPoint > &xpt)
void RegisterHandler(IExtensionChangeHandler *handler, const IExtensionPointFilter &filter) override
void UnregisterObject(const SmartPointer< IExtension > &extension, const SmartPointer< Object > &object) override
virtual QString GetNamespaceIdentifier() const =0
static IExtensionRegistry * GetExtensionRegistry()
void UnregisterHandler(IExtensionChangeHandler *handler) override
static IExtensionPointFilter CreateNamespaceFilter(const QString &id)
berry::WeakPointer< Self > WeakPtr
Definition: berryObject.h:84
virtual void RemoveExtension(const SmartPointer< IExtension > &extension, const QList< SmartPointer< Object > > &objects)=0
virtual void AddExtension(IExtensionTracker *tracker, const SmartPointer< IExtension > &extension)=0
virtual void ApplyAdd(IExtensionChangeHandler *handler, const SmartPointer< IExtension > &extension)
void RegisterObject(const SmartPointer< IExtension > &element, const SmartPointer< Object > &object, ReferenceType referenceType) override