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