ctkServiceTracker.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. /*=============================================================================
  2. Library: CTK
  3. Copyright (c) German Cancer Research Center,
  4. Division of Medical and Biological Informatics
  5. Licensed under the Apache License, Version 2.0 (the "License");
  6. you may not use this file except in compliance with the License.
  7. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. =============================================================================*/
  15. #ifndef CTKSERVICETRACKER_H
  16. #define CTKSERVICETRACKER_H
  17. #include <QScopedPointer>
  18. #include "CTKPluginFrameworkExport.h"
  19. #include "ctkServiceReference.h"
  20. #include "ctkServiceTrackerCustomizer.h"
  21. #include "ctkLDAPSearchFilter.h"
  22. class ctkPluginContext;
  23. class ctkServiceTrackerPrivate;
  24. /**
  25. * The <code>ctkServiceTracker</code> class simplifies using services from the
  26. * Framework's service registry.
  27. * <p>
  28. * A <code>ctkServiceTracker</code> object is constructed with search criteria and
  29. * a <code>ctkServiceTrackerCustomizer</code> object. A <code>ctkServiceTracker</code>
  30. * can use a <code>ctkServiceTrackerCustomizer</code> to customize the service
  31. * objects to be tracked. The <code>ctkServiceTracker</code> can then be opened to
  32. * begin tracking all services in the Framework's service registry that match
  33. * the specified search criteria. The <code>ctkServiceTracker</code> correctly
  34. * handles all of the details of listening to <code>ctkServiceEvent</code>s and
  35. * getting and ungetting services.
  36. * <p>
  37. * The <code>getServiceReferences</code> method can be called to get references
  38. * to the services being tracked. The <code>getService</code> and
  39. * <code>getServices</code> methods can be called to get the service objects for
  40. * the tracked service.
  41. * <p>
  42. * The <code>ctkServiceTracker</code> class is thread-safe. It does not call a
  43. * <code>ctkServiceTrackerCustomizer</code> while holding any locks.
  44. * <code>ctkServiceTrackerCustomizer</code> implementations must also be
  45. * thread-safe.
  46. *
  47. * @ThreadSafe
  48. */
  49. class CTK_PLUGINFW_EXPORT ctkServiceTracker : protected ctkServiceTrackerCustomizer
  50. {
  51. public:
  52. ~ctkServiceTracker();
  53. /**
  54. * Create a <code>ctkServiceTracker</code> on the specified
  55. * <code>ctkServiceReference</code>.
  56. *
  57. * <p>
  58. * The service referenced by the specified <code>ctkServiceReference</code>
  59. * will be tracked by this <code>ctkServiceTracker</code>.
  60. *
  61. * @param context The <code>ctkPluginContext</code> against which the tracking
  62. * is done.
  63. * @param reference The <code>ctkServiceReference</code> for the service to be
  64. * tracked.
  65. * @param customizer The customizer object to call when services are added,
  66. * modified, or removed in this <code>ctkServiceTracker</code>. If
  67. * customizer is <code>null</code>, then this
  68. * <code>ctkServiceTracker</code> will be used as the
  69. * <code>ctkServiceTrackerCustomizer</code> and this
  70. * <code>ctkServiceTracker</code> will call the
  71. * <code>ctkServiceTrackerCustomizer</code> methods on itself. If the
  72. * customizer is not <code>null</code>, this <code>ctkServiceTracker</code>
  73. * takes ownership of the customizer.
  74. */
  75. ctkServiceTracker(ctkPluginContext* context,
  76. const ctkServiceReference& reference,
  77. ctkServiceTrackerCustomizer* customizer = 0);
  78. /**
  79. * Create a <code>ctkServiceTracker</code> on the specified class name.
  80. *
  81. * <p>
  82. * Services registered under the specified class name will be tracked by
  83. * this <code>ctkServiceTracker</code>.
  84. *
  85. * @param context The <code>ctkPluginContext</code> against which the tracking
  86. * is done.
  87. * @param clazz The class name of the services to be tracked.
  88. * @param customizer The customizer object to call when services are added,
  89. * modified, or removed in this <code>ctkServiceTracker</code>. If
  90. * customizer is <code>null</code>, then this
  91. * <code>ctkServiceTracker</code> will be used as the
  92. * <code>ctkServiceTrackerCustomizer</code> and this
  93. * <code>ctkServiceTracker</code> will call the
  94. * <code>ctkServiceTrackerCustomizer</code> methods on itself. If the
  95. * customizer is not <code>null</code>, this <code>ctkServiceTracker</code>
  96. * takes ownership of the customizer.
  97. */
  98. ctkServiceTracker(ctkPluginContext* context, const QString& clazz,
  99. ctkServiceTrackerCustomizer* customizer = 0);
  100. /**
  101. * Create a <code>ctkServiceTracker</code> on the specified
  102. * <code>ctkLDAPSearchFilter</code> object.
  103. *
  104. * <p>
  105. * Services which match the specified <code>ctkLDAPSearchFilter</code> object will be
  106. * tracked by this <code>ctkServiceTracker</code>.
  107. *
  108. * @param context The <code>ctkPluginContext</code> against which the tracking
  109. * is done.
  110. * @param filter The <code>ctkLDAPSearchFilter</code> to select the services to be
  111. * tracked.
  112. * @param customizer The customizer object to call when services are added,
  113. * modified, or removed in this <code>ctkServiceTracker</code>. If
  114. * customizer is null, then this <code>ctkServiceTracker</code> will be
  115. * used as the <code>ctkServiceTrackerCustomizer</code> and this
  116. * <code>ctkServiceTracker</code> will call the
  117. * <code>ctkServiceTrackerCustomizer</code> methods on itself. If the
  118. * customizer is not <code>null</code>, this <code>ctkServiceTracker</code>
  119. * takes ownership of the customizer.
  120. */
  121. ctkServiceTracker(ctkPluginContext* context, const ctkLDAPSearchFilter& filter,
  122. ctkServiceTrackerCustomizer* customizer = 0);
  123. /**
  124. * Open this <code>ctkServiceTracker</code> and begin tracking services.
  125. *
  126. * <p>
  127. * Services which match the search criteria specified when this
  128. * <code>ctkServiceTracker</code> was created are now tracked by this
  129. * <code>ctkServiceTracker</code>.
  130. *
  131. * @throws std::logic_error If the <code>ctkPluginContext</code>
  132. * with which this <code>ctkServiceTracker</code> was created is no
  133. * longer valid.
  134. */
  135. void open();
  136. /**
  137. * Close this <code>ctkServiceTracker</code>.
  138. *
  139. * <p>
  140. * This method should be called when this <code>ctkServiceTracker</code> should
  141. * end the tracking of services.
  142. *
  143. * <p>
  144. * This implementation calls getServiceReferences() to get the list
  145. * of tracked services to remove.
  146. */
  147. void close();
  148. /**
  149. * Wait for at least one service to be tracked by this
  150. * <code>ctkServiceTracker</code>. This method will also return when this
  151. * <code>ctkServiceTracker</code> is closed.
  152. *
  153. * <p>
  154. * It is strongly recommended that <code>waitForService</code> is not used
  155. * during the calling of the <code>ctkPluginActivator</code> methods.
  156. * <code>ctkPluginActivator</code> methods are expected to complete in a short
  157. * period of time.
  158. *
  159. * <p>
  160. * This implementation calls getService() to determine if a service
  161. * is being tracked.
  162. *
  163. * @param timeout The time interval in milliseconds to wait. If zero, the
  164. * method will wait indefinitely.
  165. * @return Returns the result of getService().
  166. */
  167. QObject* waitForService(unsigned long timeout);
  168. /**
  169. * Return a list of <code>ctkServiceReference</code>s for all services being
  170. * tracked by this <code>ctkServiceTracker</code>.
  171. *
  172. * @return List of <code>ctkServiceReference</code>s.
  173. */
  174. QList<ctkServiceReference> getServiceReferences() const;
  175. /**
  176. * Returns a <code>ctkServiceReference</code> for one of the services being
  177. * tracked by this <code>ctkServiceTracker</code>.
  178. *
  179. * <p>
  180. * If multiple services are being tracked, the service with the highest
  181. * ranking (as specified in its <code>service.ranking</code> property) is
  182. * returned. If there is a tie in ranking, the service with the lowest
  183. * service ID (as specified in its <code>service.id</code> property); that
  184. * is, the service that was registered first is returned. This is the same
  185. * algorithm used by <code>ctkPluginContext::getServiceReference()</code>.
  186. *
  187. * <p>
  188. * This implementation calls getServiceReferences() to get the list
  189. * of references for the tracked services.
  190. *
  191. * @return A <code>ctkServiceReference</code> for a tracked service.
  192. * @throws ctkServiceException if no services are being tracked.
  193. */
  194. ctkServiceReference getServiceReference() const;
  195. /**
  196. * Returns the service object for the specified
  197. * <code>ctkServiceReference</code> if the specified referenced service is
  198. * being tracked by this <code>ctkServiceTracker</code>.
  199. *
  200. * @param reference The reference to the desired service.
  201. * @return A service object or <code>null</code> if the service referenced
  202. * by the specified <code>ctkServiceReference</code> is not being
  203. * tracked.
  204. */
  205. QObject* getService(const ctkServiceReference& reference) const;
  206. /**
  207. * Return a list of service objects for all services being tracked by this
  208. * <code>ctkServiceTracker</code>.
  209. *
  210. * <p>
  211. * This implementation calls getServiceReferences() to get the list
  212. * of references for the tracked services and then calls
  213. * getService(const ctkServiceReference&) for each reference to get the
  214. * tracked service object.
  215. *
  216. * @return A list of service objects or an empty list if no services
  217. * are being tracked.
  218. */
  219. QList<QObject*> getServices() const;
  220. /**
  221. * Returns a service object for one of the services being tracked by this
  222. * <code>ctkServiceTracker</code>.
  223. *
  224. * <p>
  225. * If any services are being tracked, this implementation returns the result
  226. * of calling <code>getService(getServiceReference())</code>.
  227. *
  228. * @return A service object or <code>null</code> if no services are being
  229. * tracked.
  230. */
  231. QObject* getService() const;
  232. /**
  233. * Remove a service from this <code>ctkServiceTracker</code>.
  234. *
  235. * The specified service will be removed from this
  236. * <code>ctkServiceTracker</code>. If the specified service was being tracked
  237. * then the <code>ctkServiceTrackerCustomizer::removedService</code> method will
  238. * be called for that service.
  239. *
  240. * @param reference The reference to the service to be removed.
  241. */
  242. void remove(const ctkServiceReference& reference);
  243. /**
  244. * Return the number of services being tracked by this
  245. * <code>ctkServiceTracker</code>.
  246. *
  247. * @return The number of services being tracked.
  248. */
  249. int size() const;
  250. /**
  251. * Returns the tracking count for this <code>ctkServiceTracker</code>.
  252. *
  253. * The tracking count is initialized to 0 when this
  254. * <code>ctkServiceTracker</code> is opened. Every time a service is added,
  255. * modified or removed from this <code>ctkServiceTracker</code>, the tracking
  256. * count is incremented.
  257. *
  258. * <p>
  259. * The tracking count can be used to determine if this
  260. * <code>ctkServiceTracker</code> has added, modified or removed a service by
  261. * comparing a tracking count value previously collected with the current
  262. * tracking count value. If the value has not changed, then no service has
  263. * been added, modified or removed from this <code>ctkServiceTracker</code>
  264. * since the previous tracking count was collected.
  265. *
  266. * @return The tracking count for this <code>ctkServiceTracker</code> or -1 if
  267. * this <code>ctkServiceTracker</code> is not open.
  268. */
  269. int getTrackingCount() const;
  270. protected:
  271. /**
  272. * Default implementation of the
  273. * <code>ctkServiceTrackerCustomizer::addingService</code> method.
  274. *
  275. * <p>
  276. * This method is only called when this <code>ctkServiceTracker</code> has been
  277. * constructed with a <code>null</code> ctkServiceTrackerCustomizer argument.
  278. *
  279. * <p>
  280. * This implementation returns the result of calling <code>getService</code>
  281. * on the <code>ctkPluginContext</code> with which this
  282. * <code>ctkServiceTracker</code> was created passing the specified
  283. * <code>ctkServiceReference</code>.
  284. * <p>
  285. * This method can be overridden in a subclass to customize the service
  286. * object to be tracked for the service being added. In that case, take care
  287. * not to rely on the default implementation of
  288. * \link removedService(const ctkServiceReference&, QObject*) removedService\endlink
  289. * to unget the service.
  290. *
  291. * @param reference The reference to the service being added to this
  292. * <code>ctkServiceTracker</code>.
  293. * @return The service object to be tracked for the service added to this
  294. * <code>ctlServiceTracker</code>.
  295. * @see ctkServiceTrackerCustomizer::addingService(const ctkServiceReference&)
  296. */
  297. QObject* addingService(const ctkServiceReference& reference);
  298. /**
  299. * Default implementation of the
  300. * <code>ctkServiceTrackerCustomizer::modifiedService</code> method.
  301. *
  302. * <p>
  303. * This method is only called when this <code>ctkServiceTracker</code> has been
  304. * constructed with a <code>null</code> ctkServiceTrackerCustomizer argument.
  305. *
  306. * <p>
  307. * This implementation does nothing.
  308. *
  309. * @param reference The reference to modified service.
  310. * @param service The service object for the modified service.
  311. * @see ctkServiceTrackerCustomizer::modifiedService(const ctkServiceReference&, QObject*)
  312. */
  313. void modifiedService(const ctkServiceReference& reference, QObject* service);
  314. /**
  315. * Default implementation of the
  316. * <code>ctkServiceTrackerCustomizer::removedService</code> method.
  317. *
  318. * <p>
  319. * This method is only called when this <code>ctkServiceTracker</code> has been
  320. * constructed with a <code>null</code> ctkServiceTrackerCustomizer argument.
  321. *
  322. * <p>
  323. * This implementation calls <code>ungetService</code>, on the
  324. * <code>ctkPluginContext</code> with which this <code>ctkServiceTracker</code>
  325. * was created, passing the specified <code>ctkServiceReference</code>.
  326. * <p>
  327. * This method can be overridden in a subclass. If the default
  328. * implementation of \link addingService(const ctkServiceReference&) addingService\endlink
  329. * method was used, this method must unget the service.
  330. *
  331. * @param reference The reference to removed service.
  332. * @param service The service object for the removed service.
  333. * @see ctkServiceTrackerCustomizer::removedService(const ServiceReference&, QObject*)
  334. */
  335. void removedService(const ctkServiceReference& reference, QObject* service);
  336. private:
  337. friend class ctkTrackedService;
  338. Q_DECLARE_PRIVATE(ctkServiceTracker)
  339. const QScopedPointer<ctkServiceTrackerPrivate> d_ptr;
  340. };
  341. #endif // CTKSERVICETRACKER_H