ctkPluginContext.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  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 CTKPLUGINCONTEXT_H_
  16. #define CTKPLUGINCONTEXT_H_
  17. #include <QHash>
  18. #include <QString>
  19. #include <QVariant>
  20. #include <QUrl>
  21. #include <QSharedPointer>
  22. #include <QFileInfo>
  23. #include "ctkPluginFramework_global.h"
  24. #include "ctkPluginEvent.h"
  25. #include "ctkServiceException.h"
  26. #include "ctkServiceReference.h"
  27. #include "ctkServiceRegistration.h"
  28. #include "ctkPluginFrameworkExport.h"
  29. // CTK class forward declarations
  30. class ctkPlugin;
  31. class ctkPluginPrivate;
  32. class ctkPluginContextPrivate;
  33. /**
  34. * A plugin's execution context within the Framework. The context is used to
  35. * grant access to other methods so that this plugin can interact with the
  36. * Framework.
  37. *
  38. * <p>
  39. * <code>ctkPluginContext</code> methods allow a plugin to:
  40. * <ul>
  41. * <li>Subscribe to events published by the Framework.
  42. * <li>Register service objects with the Framework service registry.
  43. * <li>Retrieve <code>ServiceReferences</code> from the Framework service
  44. * registry.
  45. * <li>Get and release service objects for a referenced service.
  46. * <li>Install new plugins in the Framework.
  47. * <li>Get the list of plugins installed in the Framework.
  48. * <li>Get the {@link ctkPlugin} object for a plugin.
  49. * <li>Create <code>QFile</code> objects for files in a persistent storage
  50. * area provided for the plugin by the Framework.
  51. * </ul>
  52. *
  53. * <p>
  54. * A <code>ctkPluginContext</code> object will be created and provided to the
  55. * plugin associated with this context when it is started using the
  56. * {@link ctkPluginActivator::start} method. The same <code>ctkPluginContext</code>
  57. * object will be passed to the plugin associated with this context when it is
  58. * stopped using the {@link ctkPluginActivator::stop} method. A
  59. * <code>ctkPluginContext</code> object is generally for the private use of its
  60. * associated plugin and is not meant to be shared with other plugins in the
  61. * plugin environment.
  62. *
  63. * <p>
  64. * The <code>ctkPlugin</code> object associated with a <code>ctkPluginContext</code>
  65. * object is called the <em>context plugin</em>.
  66. *
  67. * <p>
  68. * The <code>ctkPluginContext</code> object is only valid during the execution of
  69. * its context plugin; that is, during the period from when the context plugin
  70. * is in the <code>STARTING</code>, <code>STOPPING</code>, and
  71. * <code>ACTIVE</code> plugin states. If the <code>ctkPluginContext</code>
  72. * object is used subsequently, a <code>std::logic_error</code> must be
  73. * thrown. The <code>ctkPluginContext</code> object must never be reused after
  74. * its context plugin is stopped.
  75. *
  76. * <p>
  77. * The Framework is the only entity that can create <code>ctkPluginContext</code>
  78. * objects and they are only valid within the Framework that created them.
  79. *
  80. * @threadsafe
  81. */
  82. class CTK_PLUGINFW_EXPORT ctkPluginContext
  83. {
  84. Q_DECLARE_PRIVATE(ctkPluginContext)
  85. public:
  86. ~ctkPluginContext();
  87. /**
  88. * Returns the value of the specified property. If the key is not found in
  89. * the Framework properties, the system properties are then searched. The
  90. * method returns an invalid QVariant if the property is not found.
  91. *
  92. * @param key The name of the requested property.
  93. * @return The value of the requested property, or an invalid QVariant if
  94. * the property is undefined.
  95. */
  96. QVariant getProperty(const QString& key) const;
  97. /**
  98. * Returns the <code>ctkPlugin</code> object associated with this
  99. * <code>ctkPluginContext</code>. This plugin is called the context plugin.
  100. *
  101. * @return The <code>ctkPlugin</code> object associated with this
  102. * <code>ctkPluginContext</code>.
  103. * @throws std::logic_error If this ctkPluginContext is no
  104. * longer valid.
  105. */
  106. QSharedPointer<ctkPlugin> getPlugin() const;
  107. /**
  108. * Returns the plugin with the specified identifier.
  109. *
  110. * @param id The identifier of the plugin to retrieve.
  111. * @return A <code>ctkPlugin</code> object or <code>0</code> if the
  112. * identifier does not match any installed plugin.
  113. */
  114. QSharedPointer<ctkPlugin> getPlugin(long id) const;
  115. /**
  116. * Returns a list of all installed plugins.
  117. * <p>
  118. * This method returns a list of all plugins installed in the plugin
  119. * environment at the time of the call to this method. However, since the
  120. * Framework is a very dynamic environment, plugins can be installed or
  121. * uninstalled at anytime.
  122. *
  123. * @return A QList of <code>ctkPlugin</code> objects, one object per
  124. * installed plugin.
  125. */
  126. QList<QSharedPointer<ctkPlugin> > getPlugins() const;
  127. /**
  128. * Registers the specified service object with the specified properties
  129. * under the specified class names into the Framework. A
  130. * <code>ctkServiceRegistration</code> object is returned. The
  131. * <code>ctkServiceRegistration</code> object is for the private use of the
  132. * plugin registering the service and should not be shared with other
  133. * plugins. The registering plugin is defined to be the context plugin.
  134. * Other plugins can locate the service by using either the
  135. * {@link #getServiceReferences} or {@link #getServiceReference} method.
  136. *
  137. * <p>
  138. * A plugin can register a service object that implements the
  139. * {@link ctkServiceFactory} interface to have more flexibility in providing
  140. * service objects to other plugins.
  141. *
  142. * <p>
  143. * The following steps are required to register a service:
  144. * <ol>
  145. * <li>If <code>service</code> is not a <code>ctkServiceFactory</code>, an
  146. * <code>std::invalid_argument</code> is thrown if <code>service</code>
  147. * is not an instance of all the specified class names.
  148. * <li>The Framework adds the following service properties to the service
  149. * properties from the specified <code>ServiceProperties</code> (which may be
  150. * omitted): <br/>
  151. * A property named {@link ctkPluginConstants#SERVICE_ID} identifying the
  152. * registration number of the service <br/>
  153. * A property named {@link ctkPluginConstants#OBJECTCLASS} containing all the
  154. * specified classes. <br/>
  155. * Properties with these names in the specified <code>ServiceProperties</code> will
  156. * be ignored.
  157. * <li>The service is added to the Framework service registry and may now be
  158. * used by other plugins.
  159. * <li>A service event of type {@link ServiceEvent#REGISTERED} is fired.
  160. * <li>A <code>ctkServiceRegistration</code> object for this registration is
  161. * returned.
  162. * </ol>
  163. *
  164. * @param clazzes The class names under which the service can be located.
  165. * The class names will be stored in the service's
  166. * properties under the key {@link ctkPluginConstants#OBJECTCLASS}.
  167. * @param service The service object or a <code>ctkServiceFactory</code>
  168. * object.
  169. * @param properties The properties for this service. The keys in the
  170. * properties object must all be <code>QString</code> objects. See
  171. * {@link ctkPluginConstants} for a list of standard service property keys.
  172. * Changes should not be made to this object after calling this
  173. * method. To update the service's properties the
  174. * {@link ctkServiceRegistration::setProperties} method must be called.
  175. * The set of properties may be omitted if the service has
  176. * no properties.
  177. * @return A <code>ctkServiceRegistration</code> object for use by the plugin
  178. * registering the service to update the service's properties or to
  179. * unregister the service.
  180. * @throws std::invalid_argument If one of the following is true:
  181. * <ul>
  182. * <li><code>service</code> is <code>0</code>. <li><code>service
  183. * </code> is not a <code>ctkServiceFactory</code> object and is not an
  184. * instance of all the named classes in <code>clazzes</code>. <li>
  185. * <code>properties</code> contains case variants of the same key
  186. * name.
  187. * </ul>
  188. * @throws std::logic_error If this ctkPluginContext is no longer valid.
  189. * @see ctkServiceRegistration
  190. * @see ctkServiceFactory
  191. */
  192. ctkServiceRegistration registerService(const QStringList& clazzes, QObject* service, const ServiceProperties& properties = ServiceProperties());
  193. /**
  194. * Registers the specified service object with the specified properties
  195. * under the specified class name with the Framework.
  196. *
  197. * <p>
  198. * This method is otherwise identical to
  199. * registerService(const QStringList&, QObject*, const ServiceProperties&) and is provided as
  200. * a convenience when <code>service</code> will only be registered under a single
  201. * class name. Note that even in this case the value of the service's
  202. * ctkPluginConstants::OBJECTCLASS property will be a QStringList, rather
  203. * than just a single string.
  204. *
  205. * @param clazz The class name under which the service can be located.
  206. * @param service The service object or a ctkServiceFactory object.
  207. * @param properties The properties for this service.
  208. * @return A ctkServiceRegistration object for use by the plugin
  209. * registering the service to update the service's properties or to
  210. * unregister the service.
  211. * @throws std::logic_error If this ctkPluginContext is no longer valid.
  212. * @see registerService(const QStringList&, QObject*, const ServiceProperties&)
  213. */
  214. ctkServiceRegistration registerService(const char* clazz, QObject* service, const ServiceProperties& properties = ServiceProperties());
  215. template<class S>
  216. ctkServiceRegistration registerService(QObject* service, const ServiceProperties& properties = ServiceProperties())
  217. {
  218. const char* clazz = qobject_interface_iid<S*>();
  219. if (clazz == 0)
  220. {
  221. throw ctkServiceException(QString("The interface class you are registering your service %1 against has no Q_DECLARE_INTERFACE macro")
  222. .arg(service->metaObject()->className()));
  223. }
  224. return registerService(clazz, service, properties);
  225. }
  226. /**
  227. * Returns a list of <code>ctkServiceReference</code> objects. The returned
  228. * list contains services that
  229. * were registered under the specified class and match the specified filter
  230. * expression.
  231. *
  232. * <p>
  233. * The list is valid at the time of the call to this method. However since
  234. * the Framework is a very dynamic environment, services can be modified or
  235. * unregistered at any time.
  236. *
  237. * <p>
  238. * The specified <code>filter</code> expression is used to select the
  239. * registered services whose service properties contain keys and values
  240. * which satisfy the filter expression. See {@link Filter} for a description
  241. * of the filter syntax. If the specified <code>filter</code> is
  242. * empty, all registered services are considered to match the
  243. * filter. If the specified <code>filter</code> expression cannot be parsed,
  244. * an {@link std::invalid_argument} will be thrown with a human readable
  245. * message where the filter became unparsable.
  246. *
  247. * <p>
  248. * The result is a list of <code>ctkServiceReference</code> objects for all
  249. * services that meet all of the following conditions:
  250. * <ul>
  251. * <li>If the specified class name, <code>clazz</code>, is not
  252. * empty, the service must have been registered with the
  253. * specified class name. The complete list of class names with which a
  254. * service was registered is available from the service's
  255. * {@link PlugincConstants::OBJECTCLASS objectClass} property.
  256. * <li>If the specified <code>filter</code> is not empty, the
  257. * filter expression must match the service.
  258. * </ul>
  259. *
  260. * @param clazz The class name with which the service was registered or
  261. * an empty string for all services.
  262. * @param filter The filter expression or empty for all
  263. * services.
  264. * @return A list of <code>ctkServiceReference</code> objects or
  265. * an empty list if no services are registered which satisfy the
  266. * search.
  267. * @throws std::invalid_argument If the specified <code>filter</code>
  268. * contains an invalid filter expression that cannot be parsed.
  269. * @throws std::logic_error If this ctkPluginContext is no longer valid.
  270. */
  271. QList<ctkServiceReference> getServiceReferences(const QString& clazz, const QString& filter = QString());
  272. /**
  273. * Returns a list of <code>ctkServiceReference</code> objects. The returned
  274. * list contains services that
  275. * were registered under the Qt interface id of the template argument <code>S</code>
  276. * and match the specified filter expression.
  277. *
  278. * <p>
  279. * This method is identical to getServiceReferences(const QString&, const QString&) except that
  280. * the class name for the service object is automatically deduced from the template argument.
  281. *
  282. * @param filter The filter expression or empty for all
  283. * services.
  284. * @return A list of <code>ctkServiceReference</code> objects or
  285. * an empty list if no services are registered which satisfy the
  286. * search.
  287. * @throws std::invalid_argument If the specified <code>filter</code>
  288. * contains an invalid filter expression that cannot be parsed.
  289. * @throws std::logic_error If this ctkPluginContext is no longer valid.
  290. * @see getServiceReferences(const QString&, const QString&)
  291. */
  292. template<class S>
  293. QList<ctkServiceReference> getServiceReferences(const QString& filter = QString())
  294. {
  295. const char* clazz = qobject_interface_iid<S*>();
  296. if (clazz == 0) throw ctkServiceException("The service interface class has no Q_DECLARE_INTERFACE macro");
  297. return getServiceReferences(QString(clazz), filter);
  298. }
  299. /**
  300. * Returns a <code>ctkServiceReference</code> object for a service that
  301. * implements and was registered under the specified class.
  302. *
  303. * <p>
  304. * The returned <code>ctkServiceReference</code> object is valid at the time of
  305. * the call to this method. However as the Framework is a very dynamic
  306. * environment, services can be modified or unregistered at any time.
  307. *
  308. * <p>
  309. * This method is the same as calling
  310. * {@link ctkPluginContext::getServiceReferences(const QString&, const QString&)} with an
  311. * empty filter expression. It is provided as a convenience for
  312. * when the caller is interested in any service that implements the
  313. * specified class.
  314. * <p>
  315. * If multiple such services exist, the service with the highest ranking (as
  316. * specified in its {@link ctkPluginConstants::SERVICE_RANKING} property) is returned.
  317. * <p>
  318. * If there is a tie in ranking, the service with the lowest service ID (as
  319. * specified in its {@link ctkPluginConstants::SERVICE_ID} property); that is, the
  320. * service that was registered first is returned.
  321. *
  322. * @param clazz The class name with which the service was registered.
  323. * @return A <code>ctkServiceReference</code> object, or <code>0</code> if
  324. * no services are registered which implement the named class.
  325. * @throws std::logic_error If this ctkPluginContext is no longer valid.
  326. * @throws ctkServiceException It no service was registered under the given class name.
  327. * @see #getServiceReferences(const QString&, const QString&)
  328. */
  329. ctkServiceReference getServiceReference(const QString& clazz);
  330. /**
  331. * Returns a <code>ctkServiceReference</code> object for a service that
  332. * implements and was registered under the specified template class argument.
  333. *
  334. * <p>
  335. * This method is identical to getServiceReference(const QString&) except that
  336. * the class name for the service object is automatically deduced from the template argument.
  337. *
  338. * @return A <code>ctkServiceReference</code> object, or <code>0</code> if
  339. * no services are registered which implement the named class.
  340. * @throws std::logic_error If this ctkPluginContext is no longer valid.
  341. * @throws ctkServiceException It no service was registered under the given class name.
  342. * @see #getServiceReference(const QString&)
  343. * @see #getServiceReferences(const QString&)
  344. */
  345. template<class S>
  346. ctkServiceReference getServiceReference()
  347. {
  348. const char* clazz = qobject_interface_iid<S*>();
  349. if (clazz == 0) throw ctkServiceException("The service interface class has no Q_DECLARE_INTERFACE macro");
  350. return getServiceReference(QString(clazz));
  351. }
  352. /**
  353. * Returns the service object referenced by the specified
  354. * <code>ctkServiceReference</code> object.
  355. * <p>
  356. * A plugin's use of a service is tracked by the plugin's use count of that
  357. * service. Each time a service's service object is returned by
  358. * {@link #getService(ctkServiceReference*)} the context plugin's use count for
  359. * that service is incremented by one. Each time the service is released by
  360. * {@link #ungetService(ctkServiceReference*)} the context plugin's use count
  361. * for that service is decremented by one.
  362. * <p>
  363. * When a plugin's use count for a service drops to zero, the plugin should
  364. * no longer use that service.
  365. *
  366. * <p>
  367. * This method will always return <code>0</code> when the service
  368. * associated with this <code>reference</code> has been unregistered.
  369. *
  370. * <p>
  371. * The following steps are required to get the service object:
  372. * <ol>
  373. * <li>If the service has been unregistered, <code>0</code> is returned.
  374. * <li>The context plugin's use count for this service is incremented by
  375. * one.
  376. * <li>If the context plugin's use count for the service is currently one
  377. * and the service was registered with an object implementing the
  378. * <code>ctkServiceFactory</code> interface, the
  379. * {@link ctkServiceFactory::getService(ctkPlugin*, ctkServiceRegistration*)} method is
  380. * called to create a service object for the context plugin. This service
  381. * object is cached by the Framework. While the context plugin's use count
  382. * for the service is greater than zero, subsequent calls to get the
  383. * services's service object for the context plugin will return the cached
  384. * service object. <br>
  385. * If the service object returned by the <code>ctkServiceFactory</code> object
  386. * is not an instance of all the classes named when the service
  387. * was registered or the <code>ctkServiceFactory</code> object throws an
  388. * exception, <code>0</code> is returned and a Framework event of type
  389. * {@link ctkPluginFrameworkEvent::ERROR} containing a {@link ctkServiceException}
  390. * describing the error is fired.
  391. * <li>The service object for the service is returned.
  392. * </ol>
  393. *
  394. * @param reference A reference to the service.
  395. * @return A service object for the service associated with
  396. * <code>reference</code> or <code>0</code> if the service is not
  397. * registered, the service object returned by a
  398. * <code>ctkServiceFactory</code> does not implement the classes under
  399. * which it was registered or the <code>ctkServiceFactory</code> threw
  400. * an exception.
  401. * @throws std::logic_error If this ctkPluginContext is no
  402. * longer valid.
  403. * @throws std::invalid_argument If the specified
  404. * <code>ctkServiceReference</code> was not created by the same
  405. * framework instance as this <code>ctkPluginContext</code>.
  406. * @see #ungetService(const ctkServiceReference&)
  407. * @see ctkServiceFactory
  408. */
  409. QObject* getService(ctkServiceReference reference);
  410. /**
  411. * Returns the service object referenced by the specified
  412. * <code>ctkServiceReference</code> object.
  413. * <p>
  414. * This is a convenience method which is identical to QObject* getService(ctkServiceReference)
  415. * except that it casts the service object to the supplied template argument type
  416. *
  417. * @return A service object for the service associated with
  418. * <code>reference</code> or <code>0</code> if the service is not
  419. * registered, the service object returned by a
  420. * <code>ctkServiceFactory</code> does not implement the classes under
  421. * which it was registered, the <code>ctkServiceFactory</code> threw
  422. * an exception or the service could not be casted to the desired type.
  423. * @throws std::logic_error If this ctkPluginContext is no
  424. * longer valid.
  425. * @throws std::invalid_argument If the specified
  426. * <code>ctkServiceReference</code> was not created by the same
  427. * framework instance as this <code>ctkPluginContext</code>.
  428. * @see #getService(ctkServiceReference)
  429. * @see #ungetService(const ctkServiceReference&)
  430. * @see ctkServiceFactory
  431. */
  432. template<class S>
  433. S* getService(ctkServiceReference reference)
  434. {
  435. return qobject_cast<S*>(getService(reference));
  436. }
  437. /**
  438. * Releases the service object referenced by the specified
  439. * <code>ctkServiceReference</code> object. If the context plugin's use count
  440. * for the service is zero, this method returns <code>false</code>.
  441. * Otherwise, the context plugins's use count for the service is decremented
  442. * by one.
  443. *
  444. * <p>
  445. * The service's service object should no longer be used and all references
  446. * to it should be destroyed when a bundle's use count for the service drops
  447. * to zero.
  448. *
  449. * <p>
  450. * The following steps are required to unget the service object:
  451. * <ol>
  452. * <li>If the context plugin's use count for the service is zero or the
  453. * service has been unregistered, <code>false</code> is returned.
  454. * <li>The context plugin's use count for this service is decremented by
  455. * one.
  456. * <li>If the context plugin's use count for the service is currently zero
  457. * and the service was registered with a <code>ctkServiceFactory</code> object,
  458. * the
  459. * {@link ctkServiceFactory#ungetService(ctkPlugin*, ctkServiceRegistration*, QObject*)}
  460. * method is called to release the service object for the context plugin.
  461. * <li><code>true</code> is returned.
  462. * </ol>
  463. *
  464. * @param reference A reference to the service to be released.
  465. * @return <code>false</code> if the context plugin's use count for the
  466. * service is zero or if the service has been unregistered;
  467. * <code>true</code> otherwise.
  468. * @throws std::logic_error If this ctkPluginContext is no
  469. * longer valid.
  470. * @throws std::invalid_argument If the specified
  471. * <code>ctkServiceReference</code> was not created by the same
  472. * framework instance as this <code>ctkPluginContext</code>.
  473. * @see #getService
  474. * @see ctkServiceFactory
  475. */
  476. bool ungetService(const ctkServiceReference& reference);
  477. /**
  478. * Creates a <code>QFileInfo</code> object for a file or directoryin the
  479. * persistent storage area provided for the plugin by the Framework.
  480. *
  481. * <p>
  482. * A <code>QFileInfo</code> object for the base directory of the persistent
  483. * storage area provided for the context plugin by the Framework can be
  484. * obtained by calling this method with an empty string as
  485. * <code>filename</code>.
  486. *
  487. * <p>
  488. * If the permissions are enabled, the Framework will
  489. * ensure that the plugin has the <code>ctkFilePermission</code> with
  490. * actions <code>read</code>,<code>write</code>,<code>delete</code>
  491. * for all files (recursively) in the persistent storage area provided for
  492. * the context plugin.
  493. *
  494. * @param filename A relative name to the file or directory to be accessed.
  495. * @return A <code>QFileInfo</code> object that represents the requested file
  496. * or directory.
  497. * @throws std::logic_error If this ctkPluginContext is no longer valid.
  498. */
  499. QFileInfo getDataFile(const QString& filename);
  500. /**
  501. * Installs a plugin from the specified <code>QIODevice</code> object.
  502. *
  503. * <p>
  504. * If the specified <code>QIODevice</code> is <code>null</code>, the
  505. * Framework must create the <code>QIODevice</code> from which to read the
  506. * plugin by interpreting, in an implementation dependent manner, the
  507. * specified <code>location</code>.
  508. *
  509. * <p>
  510. * The specified <code>location</code> identifier will be used as the
  511. * identity of the plugin. Every installed plugin is uniquely identified by
  512. * its location identifier which is typically in the form of a URL.
  513. *
  514. * <p>
  515. * The following steps are required to install a plugin:
  516. * <ol>
  517. * <li>If a plugin containing the same location identifier is already
  518. * installed, the <code>ctkPlugin</code> object for that plugin is returned.
  519. *
  520. * <li>The plugin's content is read from the input stream. If this fails, a
  521. * {@link ctkPluginException} is thrown.
  522. *
  523. * <li>The plugin's associated resources are allocated. The associated
  524. * resources minimally consist of a unique identifier and a persistent
  525. * storage area. If this step fails, a <code>ctkPluginException</code>
  526. * is thrown.
  527. *
  528. * <li>The plugin's state is set to <code>INSTALLED</code>.
  529. *
  530. * <li>A plugin event of type {@link ctkPluginEvent#INSTALLED} is fired.
  531. *
  532. * <li>The <code>ctkPlugin</code> object for the newly or previously installed
  533. * plugin is returned.
  534. * </ol>
  535. *
  536. * <b>Postconditions, no exceptions thrown </b>
  537. * <ul>
  538. * <li><code>getState()</code> in &#x007B; <code>INSTALLED</code>,
  539. * <code>RESOLVED</code> &#x007D;.
  540. * <li>Plugin has a unique ID.
  541. * </ul>
  542. * <b>Postconditions, when an exception is thrown </b>
  543. * <ul>
  544. * <li>Plugin is not installed and no trace of the plugin exists.
  545. * </ul>
  546. *
  547. * @param location The location identifier of the plugin to install.
  548. * @param input The <code>QIODevice</code> object from which this plugin
  549. * will be read or <code>null</code> to indicate the Framework must
  550. * create the I/O device from the specified location identifier.
  551. * The I/O device must always be closed when this method completes,
  552. * even if an exception is thrown.
  553. * @return The <code>ctkPlugin</code> object of the installed plugin.
  554. * @throws ctkPluginException If the I/O device cannot be read or the
  555. * installation failed.
  556. * @throws std::logic_error If this ctkPluginContext is no longer valid.
  557. */
  558. QSharedPointer<ctkPlugin> installPlugin(const QUrl& location, QIODevice* in = 0);
  559. /**
  560. * Connects the specified <code>slot</code> to the context
  561. * plugins's signal which is emitted when a plugin has
  562. * a lifecycle state change. The signature of the slot
  563. * must be "slotName(ctkPluginEvent)".
  564. *
  565. * @param receiver The object to connect to.
  566. * @param slot The slot to be connected.
  567. * @param type The Qt connection type. Only Qt::DirectConnection,
  568. * Qt::QueuedConnection, or Qt::BlockingQueuedConnection is allowed.
  569. * @throws std::logic_error If this ctkPluginContext is no
  570. * longer valid.
  571. * @see ctkPluginEvent
  572. * @see ctkEventBus
  573. */
  574. bool connectPluginListener(const QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::QueuedConnection);
  575. /**
  576. * Connects the specified <code>slot</code> to the context
  577. * plugin's signal which emits general Framework events. The signature
  578. * of the slot must be "slotName(ctkPluginFrameworkEvent)".
  579. *
  580. * @param receiver The object to connect to.
  581. * @param slot The slot to be connected.
  582. * @param type The Qt connection type.
  583. * @throws std::logic_error If this ctkPluginContext is no
  584. * longer valid.
  585. * @see ctkPluginFrameworkEvent
  586. * @see ctkEventBus
  587. */
  588. bool connectFrameworkListener(const QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::QueuedConnection);
  589. /**
  590. * Connects the specified <code>slot</code> with the
  591. * specified <code>filter</code> to the context plugins's signal emitting
  592. * service events when a service has a lifecycle state change. The signature
  593. * of the slot must be "slotName(const ctkServiceEvent&)", but only the name
  594. * of the slot must be provided as the argument.
  595. * See {@link ctkLDAPSearchFilter} for a description of
  596. * the filter syntax.
  597. *
  598. * <p>
  599. * If the object to connect to is destroyed, the slot is automatically
  600. * disconnected. To explicitly disconnect the slot, use
  601. * disconnectServiceListener().
  602. *
  603. * <p>
  604. * If the context plugin's list of listeners already contains the same
  605. * slot for the given receiver, then this
  606. * method replaces that slot's filter (which may be <code>null</code>)
  607. * with the specified one (which may be <code>null</code>).
  608. *
  609. * <p>
  610. * The slot is called if the filter criteria is met. To filter based
  611. * upon the class of the service, the filter should reference the
  612. * {@link ctkPluginConstants#OBJECTCLASS} property. If <code>filter</code> is
  613. * <code>null</code>, all services are considered to match the filter.
  614. *
  615. * <p>
  616. * When using a <code>filter</code>, it is possible that the
  617. * <code>ctkServiceEvent</code>s for the complete lifecycle of a service
  618. * will not be delivered to the slot. For example, if the
  619. * <code>filter</code> only matches when the property <code>x</code> has
  620. * the value <code>1</code>, the listener will not be called if the
  621. * service is registered with the property <code>x</code> not set to the
  622. * value <code>1</code>. Subsequently, when the service is modified
  623. * setting property <code>x</code> to the value <code>1</code>, the
  624. * filter will match and the slot will be called with a
  625. * <code>ServiceEvent</code> of type <code>MODIFIED</code>. Thus, the
  626. * slot will not be called with a <code>ServiceEvent</code> of type
  627. * <code>REGISTERED</code>.
  628. *
  629. * @param receiver The object to connect to.
  630. * @param slot The name of the slot to be connected.
  631. * @param filter The filter criteria.
  632. * @throws std::invalid_argument If <code>filter</code> contains an
  633. * invalid filter string that cannot be parsed.
  634. * @throws std::logic_error If this ctkPluginContext is no
  635. * longer valid.
  636. * @see ctkServiceEvent
  637. * @see disconnectServiceListener()
  638. * @see ctkEventBus
  639. */
  640. void connectServiceListener(QObject* receiver, const char* slot,
  641. const QString& filter = QString());
  642. /**
  643. * Disconnects a slot which has been previously connected
  644. * with a call to connectServiceListener().
  645. *
  646. * @param receiver The object containing the slot.
  647. * @param slot The slot to be disconnected.
  648. * @see connectServiceListener()
  649. */
  650. void disconnectServiceListener(QObject* receiver, const char* slot);
  651. protected:
  652. friend class ctkPluginFrameworkPrivate;
  653. friend class ctkPlugin;
  654. friend class ctkPluginPrivate;
  655. ctkPluginContext(ctkPluginPrivate* plugin);
  656. ctkPluginContextPrivate * const d_ptr;
  657. };
  658. #endif /* CTKPLUGINCONTEXT_H_ */