ctkPlugin.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  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 CTKPLUGIN_H
  16. #define CTKPLUGIN_H
  17. #include <QHash>
  18. #include <QWeakPointer>
  19. #include <QMetaType>
  20. #include <QUrl>
  21. #include "ctkVersion.h"
  22. #include "ctkPluginLocalization.h"
  23. #include "ctkPluginConstants.h"
  24. #include "service/log/ctkLogStream.h"
  25. class ctkPluginContext;
  26. class ctkPluginArchive;
  27. class ctkPluginFrameworkContext;
  28. class ctkPluginPrivate;
  29. /**
  30. * \ingroup PluginFramework
  31. *
  32. * An installed plugin in the Framework.
  33. *
  34. * <p>
  35. * A <code>%ctkPlugin</code> object is the access point to define the lifecycle of
  36. * an installed plugin. Each plugin installed in the plugin environment must have
  37. * an associated <code>%ctkPlugin</code> object.
  38. *
  39. * <p>
  40. * A plugin must have a unique identity, a <code>long</code>, chosen by the
  41. * Framework. This identity must not change during the lifecycle of a plugin,
  42. * even when the plugin is updated. Uninstalling and then reinstalling the
  43. * plugin must create a new unique identity.
  44. *
  45. * <p>
  46. * A plugin can be in one of six states:
  47. * <ul>
  48. * <li>{@link #UNINSTALLED}
  49. * <li>{@link #INSTALLED}
  50. * <li>{@link #RESOLVED}
  51. * <li>{@link #STARTING}
  52. * <li>{@link #STOPPING}
  53. * <li>{@link #ACTIVE}
  54. * </ul>
  55. * <p>
  56. * They can be ORed together using the <code>States</code> type to
  57. * determine if a plugin is in one of the valid states.
  58. *
  59. * <p>
  60. * A plugin should only execute code when its state is one of
  61. * <code>STARTING</code>, <code>ACTIVE</code>, or <code>STOPPING</code>.
  62. * An <code>UNINSTALLED</code> plugin can not be set to another state; it is a
  63. * zombie and can only be reached because references are kept somewhere.
  64. *
  65. * <p>
  66. * The Framework is the only entity that is allowed to create
  67. * <code>%ctkPlugin</code> objects, and these objects are only valid within the
  68. * Framework that created them.
  69. *
  70. * @remarks This class is thread safe.
  71. */
  72. class CTK_PLUGINFW_EXPORT ctkPlugin {
  73. public:
  74. enum State {
  75. /**
  76. * The plugin is uninstalled and may not be used.
  77. *
  78. * <p>
  79. * The <code>UNINSTALLED</code> state is only visible after a plugin is
  80. * uninstalled; the plugin is in an unusable state but references to the
  81. * <code>%ctkPlugin</code> object may still be available and used for
  82. * introspection.
  83. */
  84. UNINSTALLED = 0x00000001,
  85. /**
  86. * The plugin is installed but not yet resolved.
  87. *
  88. * <p>
  89. * A plugin is in the <code>INSTALLED</code> state when it has been
  90. * installed in the Framework but is not or cannot be resolved.
  91. * <p>
  92. * This state is visible if the plugin's code dependencies are not resolved.
  93. * The Framework may attempt to resolve an <code>INSTALLED</code> plugin's
  94. * code dependencies and move the plugin to the <code>RESOLVED</code>
  95. * state.
  96. */
  97. INSTALLED = 0x00000002,
  98. /**
  99. * The plugin is resolved and is able to be started.
  100. *
  101. * <p>
  102. * A plugin is in the <code>RESOLVED</code> state when the Framework has
  103. * successfully resolved the plugin's code dependencies. These dependencies
  104. * include:
  105. * <ul>
  106. * <li>The plugin's required plugin dependencies from its
  107. * {@link ctkPluginConstants::REQUIRE_PLUGIN} Manifest header.
  108. * </ul>
  109. * <p>
  110. * Note that the plugin is not active yet. A plugin must be put in the
  111. * <code>RESOLVED</code> state before it can be started. The Framework may
  112. * attempt to resolve a plugin at any time.
  113. */
  114. RESOLVED = 0x00000004,
  115. /**
  116. * The plugin is in the process of starting.
  117. *
  118. * <p>
  119. * A plugin is in the <code>STARTING</code> state when its
  120. * {@link #start(const StartOptions&) start} method is active. A plugin must be in this
  121. * state when the plugin's {@link ctkPluginActivator::start} method is called. If the
  122. * <code>ctkPluginActivator::start</code> method completes without exception,
  123. * then the plugin has successfully started and must move to the
  124. * <code>ACTIVE</code> state.
  125. * <p>
  126. * If the plugin does not have a
  127. * {@link ctkPluginConstants#ACTIVATION_EAGER eager activation policy}, then the
  128. * plugin may remain in this state for some time until the activation is
  129. * triggered.
  130. */
  131. STARTING = 0x00000008,
  132. /**
  133. * The plugin is in the process of stopping.
  134. *
  135. * <p>
  136. * A plugin is in the <code>STOPPING</code> state when its
  137. * {@link #stop(const StopOptions&) stop} method is active. A plugin must be in this state
  138. * when the plugin's {@link ctkPluginActivator::stop} method is called. When the
  139. * <code>ctkPluginActivator::stop</code> method completes the plugin is
  140. * stopped and must move to the <code>RESOLVED</code> state.
  141. */
  142. STOPPING = 0x00000010,
  143. /**
  144. * The plugin is now running.
  145. *
  146. * <p>
  147. * A plugin is in the <code>ACTIVE</code> state when it has been
  148. * successfully started and activated.
  149. */
  150. ACTIVE = 0x00000020
  151. };
  152. /**
  153. * Represents an ORed combination of plugin states.
  154. *
  155. * @see #State
  156. */
  157. Q_DECLARE_FLAGS(States, State)
  158. enum StartOption {
  159. /**
  160. * The plugin start operation is transient and the persistent autostart
  161. * setting of the plugin is not modified.
  162. *
  163. * <p>
  164. * This option may be set when calling {@link #start(const StartOptions&)} to notify the
  165. * framework that the autostart setting of the plugin must not be modified.
  166. * If this option is not set, then the autostart setting of the plugin is
  167. * modified.
  168. *
  169. * @see #start(const StartOptions&)
  170. */
  171. START_TRANSIENT = 0x00000001,
  172. /**
  173. * The plugin start operation must activate the plugin according to the
  174. * plugin's declared
  175. * {@link ctkPluginConstants#PLUGIN_ACTIVATIONPOLICY activation policy}.
  176. *
  177. * <p>
  178. * This bit may be set when calling {@link #start(const StartOptions&)} to notify the
  179. * framework that the plugin must be activated using the plugin's declared
  180. * activation policy.
  181. *
  182. * @see ctkPluginConstants#PLUGIN_ACTIVATIONPOLICY
  183. * @see #start(const StartOptions&)
  184. */
  185. START_ACTIVATION_POLICY = 0x00000002
  186. };
  187. /**
  188. * Represents an ORed combination of start options.
  189. *
  190. * @see #StartOption
  191. */
  192. Q_DECLARE_FLAGS(StartOptions, StartOption)
  193. enum StopOption {
  194. /**
  195. * The plugin stop is transient and the persistent autostart setting of the
  196. * plugin is not modified.
  197. *
  198. * <p>
  199. * This option may be set when calling {@link #stop(const StopOptions&)} to notify the
  200. * framework that the autostart setting of the plugin must not be modified.
  201. * If this option is not set, then the autostart setting of the plugin is
  202. * modified.
  203. *
  204. * @see #stop(const StopOptions&)
  205. */
  206. STOP_TRANSIENT = 0x00000001
  207. };
  208. /**
  209. * Represents an ORed combination of stop options.
  210. *
  211. * @see #StopOption
  212. */
  213. Q_DECLARE_FLAGS(StopOptions, StopOption)
  214. virtual ~ctkPlugin();
  215. /**
  216. * Returns this plugin's current state.
  217. *
  218. * <p>
  219. * A plugin can be in only one state at any time.
  220. *
  221. * @return An element of <code>UNINSTALLED</code>,<code>INSTALLED</code>,
  222. * <code>RESOLVED</code>,<code>STARTING</code>,
  223. * <code>STOPPING</code>,<code>ACTIVE</code>.
  224. */
  225. State getState() const;
  226. /**
  227. * Starts this plugin.
  228. *
  229. * <p>
  230. * If this plugin's state is <code>UNINSTALLED</code> then an
  231. * <code>ctkIllegalStateException</code> is thrown.
  232. * <p>
  233. * The following steps are required to start this bundle:
  234. * <ol>
  235. * <li>If this plugin is in the process of being activated or deactivated
  236. * then this method must wait for activation or deactivation to complete
  237. * before continuing. If this does not occur in a reasonable time, a
  238. * <code>ctkPluginException</code> is thrown to indicate this plugin was unable
  239. * to be started.
  240. *
  241. * <li>If this plugin's state is <code>ACTIVE</code> then this method
  242. * returns immediately.
  243. *
  244. * <li>If the {@link #START_TRANSIENT} option is not set then set this
  245. * plugin's autostart setting to <em>Started with declared activation</em>
  246. * if the {@link #START_ACTIVATION_POLICY} option is set or
  247. * <em>Started with lazy activation</em> if not set. When the Framework is
  248. * restarted and this plugin's autostart setting is not <em>Stopped</em>,
  249. * this plugin must be automatically started.
  250. *
  251. * <li>If this plugin's state is not <code>RESOLVED</code>, an attempt is
  252. * made to resolve this plugin. If the Framework cannot resolve this plugin,
  253. * a <code>ctkPluginException</code> is thrown.
  254. *
  255. * <li>If the {@link #START_ACTIVATION_POLICY} option is not set then:
  256. * <ul>
  257. * <li>If this plugin's state is <code>STARTING</code> then this method
  258. * returns immediately.
  259. * <li>This plugin's state is set to <code>STARTING</code>.
  260. * <li>A plugin event of type {@link ctkPluginEvent::LAZY_ACTIVATION} is fired.
  261. * <li>This method returns immediately and the remaining steps will be
  262. * followed when this plugin's activation is later triggered.
  263. * </ul>
  264. * If the {@link #START_ACTIVATION_POLICY} option is set and this
  265. * plugin's declared activation policy is {@link ctkPluginConstants#ACTIVATION_EAGER
  266. * eager} then:
  267. * <i></i>
  268. * <li>This plugin's state is set to <code>STARTING</code>.
  269. *
  270. * <li>A plugin event of type {@link ctkPluginEvent::STARTING} is fired.
  271. *
  272. * <li>The {@link ctkPluginActivator::start} method of this plugin's
  273. * <code>ctkPluginActivator</code>, is called. If the
  274. * <code>ctkPluginActivator</code> throws an exception then:
  275. * <ul>
  276. * <li>This plugin's state is set to <code>STOPPING</code>.
  277. * <li>A plugin event of type {@link ctkPluginEvent::STOPPING} is fired.
  278. * <li>Any services registered by this plugin must be unregistered.
  279. * <li>Any services used by this plugin must be released.
  280. * <li>Any listeners registered by this plugin must be removed.
  281. * <li>This plugin's state is set to <code>RESOLVED</code>.
  282. * <li>A plugin event of type {@link ctkPluginEvent::STOPPED} is fired.
  283. * <li>A <code>ctkPluginException</code> is then thrown.
  284. * </ul>
  285. * <i></i>
  286. * <li>If this plugin's state is <code>UNINSTALLED</code>, because this
  287. * plugin was uninstalled while the <code>ctkPluginActivator::start</code>
  288. * method was running, a <code>ctkPluginException</code> is thrown.
  289. *
  290. * <li>This plugin's state is set to <code>ACTIVE</code>.
  291. *
  292. * <li>A plugin event of type {@link ctkPluginEvent::STARTED} is fired.
  293. * </ol>
  294. *
  295. * <b>Preconditions </b>
  296. * <ul>
  297. * <li><code>getState()</code> in { <code>INSTALLED</code>,
  298. * <code>RESOLVED</code>, <code>STARTING</code> }
  299. * or { <code>INSTALLED</code>, <code>RESOLVED</code> }
  300. * if this plugin has a eager activation policy.
  301. * </ul>
  302. * <b>Postconditions, no exceptions thrown </b>
  303. * <ul>
  304. * <li>Plugin autostart setting is modified unless the
  305. * {@link #START_TRANSIENT} option was set.
  306. * <li><code>getState()</code> in { <code>ACTIVE</code> }
  307. * if the eager activation policy was used.
  308. * <li><code>ctkPluginActivator::start()</code> has been called and did not
  309. * throw an exception if the eager policy was used.
  310. * </ul>
  311. * <b>Postconditions, when an exception is thrown </b>
  312. * <ul>
  313. * <li>Depending on when the exception occurred, plugin autostart setting is
  314. * modified unless the {@link #START_TRANSIENT} option was set.
  315. * <li><code>getState()</code> not in { <code>STARTING</code>,
  316. * <code>ACTIVE</code> }.
  317. * </ul>
  318. *
  319. * @param options The options for starting this plugin. See
  320. * {@link #START_TRANSIENT} and {@link #START_ACTIVATION_POLICY}. The
  321. * Framework must ignore unrecognized options.
  322. * @throws ctkPluginException If this plugin could not be started. This could
  323. * be because a code dependency could not be resolved or the
  324. * <code>ctkPluginActivator</code> could not be loaded or
  325. * threw an exception.
  326. * @throws ctkIllegalStateException If this plugin has been uninstalled or this
  327. * plugin tries to change its own state.
  328. */
  329. virtual void start(const StartOptions& options = START_ACTIVATION_POLICY);
  330. /**
  331. * Stops this plugin.
  332. *
  333. * <p>
  334. * The following steps are required to stop a plugin:
  335. * <ol>
  336. * <li>If this plugin's state is <code>UNINSTALLED</code> then an
  337. * <code>ctkIllegalStateException</code> is thrown.
  338. *
  339. * <li>If this plugin is in the process of being activated or deactivated
  340. * then this method must wait for activation or deactivation to complete
  341. * before continuing. If this does not occur in a reasonable time, a
  342. * <code>ctkPluginException</code> is thrown to indicate this plugin was unable
  343. * to be stopped.
  344. * <li>If the {@link #STOP_TRANSIENT} option is not set then then set this
  345. * plugin's persistent autostart setting to <em>Stopped</em>. When the
  346. * Framework is restarted and this plugin's autostart setting is
  347. * <em>Stopped</em>, this bundle must not be automatically started.
  348. *
  349. * <li>If this plugin's state is not <code>STARTING</code> or
  350. * <code>ACTIVE</code> then this method returns immediately.
  351. *
  352. * <li>This plugin's state is set to <code>STOPPING</code>.
  353. *
  354. * <li>A plugin event of type {@link ctkPluginEvent::STOPPING} is fired.
  355. *
  356. * <li>If this plugin's state was <code>ACTIVE</code> prior to setting the
  357. * state to <code>STOPPING</code>, the {@link ctkPluginActivator#stop} method
  358. * of this plugin's <code>ctkPluginActivator</code> is
  359. * called. If that method throws an exception, this method must continue to
  360. * stop this plugin and a <code>ctkPluginException</code> must be thrown after
  361. * completion of the remaining steps.
  362. *
  363. * <li>Any services registered by this plugin must be unregistered.
  364. * <li>Any services used by this plugin must be released.
  365. * <li>Any listeners registered by this plugin must be removed.
  366. *
  367. * <li>If this plugin's state is <code>UNINSTALLED</code>, because this
  368. * plugin was uninstalled while the <code>ctkPluginActivator::stop</code> method
  369. * was running, a <code>ctkPluginException</code> must be thrown.
  370. *
  371. * <li>This plugin's state is set to <code>RESOLVED</code>.
  372. *
  373. * <li>A plugin event of type {@link ctkPluginEvent::STOPPED} is fired.
  374. * </ol>
  375. *
  376. * <b>Preconditions </b>
  377. * <ul>
  378. * <li><code>getState()</code> in { <code>ACTIVE</code> }.
  379. * </ul>
  380. * <b>Postconditions, no exceptions thrown </b>
  381. * <ul>
  382. * <li>Plugin autostart setting is modified unless the
  383. * {@link #STOP_TRANSIENT} option was set.
  384. * <li><code>getState()</code> not in &#123; <code>ACTIVE</code>,
  385. * <code>STOPPING</code> &#125;.
  386. * <li><code>ctkPluginActivator::stop</code> has been called and did not throw
  387. * an exception.
  388. * </ul>
  389. * <b>Postconditions, when an exception is thrown </b>
  390. * <ul>
  391. * <li>Plugin autostart setting is modified unless the
  392. * {@link #STOP_TRANSIENT} option was set.
  393. * </ul>
  394. *
  395. * @param options The options for stoping this bundle. See
  396. * {@link #STOP_TRANSIENT}.
  397. * @throws ctkPluginException If this plugin's <code>ctkPluginActivator</code>
  398. * threw an exception.
  399. * @throws ctkIllegalStateException If this plugin has been uninstalled or this
  400. * plugin tries to change its own state.
  401. */
  402. virtual void stop(const StopOptions& options = 0);
  403. /**
  404. * Updates this plugin from a <code>QUrl</code>.
  405. *
  406. * <p>
  407. * If the specified <code>QURl</code> is <code>empty</code>, the
  408. * Framework creates the <code>QUrl</code> from which to read the
  409. * updated plugin by interpreting, in an implementation dependent manner,
  410. * this plugin's {@link ctkPluginConstants#PLUGIN_UPDATELOCATION
  411. * Plugin-UpdateLocation} Manifest header, if present, or this plugin's
  412. * original location.
  413. *
  414. * <p>
  415. * If this plugin's state is <code>ACTIVE</code>, it must be stopped before
  416. * the update and started after the update successfully completes.
  417. *
  418. * <p>
  419. * If this plugin has exported any classes that are used by another
  420. * plugin, these classes remain available until the Framework is relaunched.
  421. *
  422. * <p>
  423. * The following steps are required to update a plugin:
  424. * <ol>
  425. * <li>If this plugin's state is <code>UNINSTALLED</code> then an
  426. * <code>ctkIllegalStateException</code> is thrown.
  427. *
  428. * <li>If this plugin's state is <code>ACTIVE</code>, <code>STARTING</code>
  429. * or <code>STOPPING</code>, this plugin is stopped as described in the
  430. * <code>ctkPlugin::stop()</code> method. If <code>ctkPlugin::stop()</code> throws an
  431. * exception, the exception is rethrown terminating the update.
  432. *
  433. * <li>The updated version of this plugin is read from the URL and
  434. * installed. If the Framework is unable to install the updated version of
  435. * this plugin, the original version of this plugin is restored and a
  436. * <code>ctkPluginException</code> is thrown after completion of the
  437. * remaining steps.
  438. *
  439. * <li>This plugin's state is set to <code>INSTALLED</code>.
  440. *
  441. * <li>If the updated version of this plugin was successfully installed, a
  442. * plugin event of type {@link ctkPluginEvent#UPDATED} is fired.
  443. *
  444. * <li>If this plugin's state was originally <code>ACTIVE</code>, the
  445. * updated plugin is started as described in the <code>ctkPlugin::start()</code>
  446. * method. If <code>ctkPlugin::start()</code> throws an exception, a Framework
  447. * event of type {@link ctkPluginFrameworkEvent#PLUGIN_ERROR} is fired containing the
  448. * exception.
  449. * </ol>
  450. *
  451. * <b>Preconditions </b>
  452. * <ul>
  453. * <li><code>getState()</code> not in &#x007B; <code>UNINSTALLED</code>
  454. * &#x007D;.
  455. * </ul>
  456. * <b>Postconditions, no exceptions thrown </b>
  457. * <ul>
  458. * <li><code>getState()</code> in &#x007B; <code>INSTALLED</code>,
  459. * <code>RESOLVED</code>, <code>ACTIVE</code> &#x007D;.
  460. * <li>This plugin has been updated.
  461. * </ul>
  462. * <b>Postconditions, when an exception is thrown </b>
  463. * <ul>
  464. * <li><code>getState()</code> in &#x007B; <code>INSTALLED</code>,
  465. * <code>RESOLVED</code>, <code>ACTIVE</code> &#x007D;.
  466. * <li>Original plugin is still used; no update occurred.
  467. * </ul>
  468. *
  469. * @param updateLocation The <code>QUrl</code> from which to read the new
  470. * plugin or <code>null</code> to indicate the Framework must create
  471. * the URL from this plugin's
  472. * {@link ctkPluginConstants#PLUGIN_UPDATELOCATION Plugin-UpdateLocation}
  473. * Manifest header, if present, or this plugin's original location.
  474. * @throws ctkPluginException If the update location cannot be read or the update
  475. * fails.
  476. * @throws ctkIllegalStateException If this plugin has been uninstalled or this
  477. * plugin tries to change its own state.
  478. * @see #stop()
  479. * @see #start()
  480. */
  481. void update(const QUrl &updateLocation = QUrl());
  482. /**
  483. * Uninstalls this plugin.
  484. *
  485. * <p>
  486. * This method causes the Plugin Framework to notify other plugins that this
  487. * plugin is being uninstalled, and then puts this plugin into the
  488. * <code>UNINSTALLED</code> state. The Framework must remove any resources
  489. * related to this plugin that it is able to remove.
  490. *
  491. * <p>
  492. * If this plugin is required by other plugins which are already resolved,
  493. * the Framework must keep this plugin loaded until the
  494. * Framework is relaunched.
  495. *
  496. * <p>
  497. * The following steps are required to uninstall a plugin:
  498. * <ol>
  499. * <li>If this plugin's state is <code>UNINSTALLED</code> then an
  500. * <code>ctkIllegalStateException</code> is thrown.
  501. *
  502. * <li>If this plugin's state is <code>ACTIVE</code>, <code>STARTING</code>
  503. * or <code>STOPPING</code>, this plugin is stopped as described in the
  504. * <code>ctkPlugin::stop</code> method. If <code>ctkPlugin::stop</code> throws an
  505. * exception, a Framework event of type ctkPluginFrameworkEvent::PLUGIN_ERROR is
  506. * fired containing the exception.
  507. *
  508. * <li>This plugin's state is set to <code>UNINSTALLED</code>.
  509. *
  510. * <li>A plugin event of type ctkPluginEvent::UNINSTALLED is fired.
  511. *
  512. * <li>This plugin and any persistent storage area provided for this plugin
  513. * by the Framework are removed.
  514. * </ol>
  515. *
  516. * <b>Preconditions </b>
  517. * <ul>
  518. * <li><code>getState()</code> not in &#123; <code>UNINSTALLED</code>
  519. * &#125;.
  520. * </ul>
  521. * <b>Postconditions, no exceptions thrown </b>
  522. * <ul>
  523. * <li><code>getState()</code> in &#123; <code>UNINSTALLED</code>
  524. * &#125;.
  525. * <li>This plugin has been uninstalled.
  526. * </ul>
  527. * <b>Postconditions, when an exception is thrown </b>
  528. * <ul>
  529. * <li><code>getState()</code> not in &#123; <code>UNINSTALLED</code>
  530. * &#125;.
  531. * <li>This plugin has not been uninstalled.
  532. * </ul>
  533. *
  534. * @throws ctkPluginException If the uninstall failed. This can occur if
  535. * another thread is attempting to change this plugin's state and
  536. * does not complete in a timely manner.
  537. * @throws ctkIllegalStateException If this plugin has been uninstalled or this
  538. * plugin tries to change its own state.
  539. * @see #stop()
  540. */
  541. virtual void uninstall();
  542. /**
  543. * Returns this plugin's {@link ctkPluginContext}. The returned
  544. * <code>ctkPluginContext</code> can be used by the caller to act on behalf
  545. * of this plugin.
  546. *
  547. * <p>
  548. * If this plugin is not in the {@link #STARTING}, {@link #ACTIVE}, or
  549. * {@link #STOPPING} states, then this
  550. * plugin has no valid <code>ctkPluginContext</code>. This method will
  551. * return <code>0</code> if this plugin has no valid
  552. * <code>ctkPluginContext</code>.
  553. *
  554. * @return A <code>ctkPluginContext</code> for this plugin or
  555. * <code>0</code> if this plugin has no valid
  556. * <code>ctkPluginContext</code>.
  557. */
  558. ctkPluginContext* getPluginContext() const;
  559. /**
  560. * Returns this plugin's unique identifier. This plugin is assigned a unique
  561. * identifier by the Framework when it was installed in the plugin
  562. * environment.
  563. *
  564. * <p>
  565. * A plugin's unique identifier has the following attributes:
  566. * <ul>
  567. * <li>Is unique and persistent.
  568. * <li>Is a <code>long</code>.
  569. * <li>Its value is not reused for another plugin, even after a plugin is
  570. * uninstalled.
  571. * <li>Does not change while a plugin remains installed.
  572. * <li>Does not change when a plugin is updated.
  573. * </ul>
  574. *
  575. * <p>
  576. * This method must continue to return this plugin's unique identifier while
  577. * this plugin is in the <code>UNINSTALLED</code> state.
  578. *
  579. * @return The unique identifier of this plugin.
  580. */
  581. long getPluginId() const;
  582. /**
  583. * Returns this plugin's location identifier.
  584. *
  585. * <p>
  586. * The location identifier is the location passed to
  587. * <code>ctkPluginContext::installPlugin</code> when a plugin is installed.
  588. * The location identifier does not change while this plugin remains
  589. * installed, even if this plugin is updated.
  590. *
  591. * <p>
  592. * This method must continue to return this plugin's location identifier
  593. * while this plugin is in the <code>UNINSTALLED</code> state.
  594. *
  595. * @return The string representation of this plugin's location identifier.
  596. */
  597. QString getLocation() const;
  598. /**
  599. * Returns this plugin's Manifest headers and values. This method returns
  600. * all the Manifest headers and values from the main section of this
  601. * bundle's Manifest file; that is, all lines prior to the first named section.
  602. *
  603. * TODO: documentation about manifest value internationalization
  604. *
  605. * <p>
  606. * For example, the following Manifest headers and values are included if
  607. * they are present in the Manifest file:
  608. *
  609. * <pre>
  610. * Plugin-Name
  611. * Plugin-Vendor
  612. * Plugin-ctkVersion
  613. * Plugin-Description
  614. * Plugin-DocURL
  615. * Plugin-ContactAddress
  616. * </pre>
  617. *
  618. * <p>
  619. * This method must continue to return Manifest header information while
  620. * this plugin is in the <code>UNINSTALLED</code> state.
  621. *
  622. * @return A <code>QHash<Qstring, QString></code> object containing this plugin's
  623. * Manifest headers and values.
  624. */
  625. virtual QHash<QString, QString> getHeaders();
  626. /**
  627. * Returns the symbolic name of this plugin as specified by its
  628. * <code>Plugin-SymbolicName</code> manifest header. The plugin symbolic
  629. * name together with a version must identify a unique plugin. The plugin
  630. * symbolic name should be based on the reverse domain name naming
  631. * convention like that used for java packages.
  632. *
  633. * <p>
  634. * This method must continue to return this plugin's symbolic name while
  635. * this plugin is in the <code>UNINSTALLED</code> state.
  636. *
  637. * @return The symbolic name of this plugin or a null QString if this
  638. * plugin does not have a symbolic name.
  639. */
  640. QString getSymbolicName() const;
  641. /**
  642. * Returns a list of all the files and directories
  643. * within this plugin whose longest sub-path matches the
  644. * specified path.
  645. * <p>
  646. * The specified path is always relative to the root of this plugin
  647. * (the plugins symbolic name) and may begin with a &quot;/&quot;.
  648. * A path value of &quot;/&quot; indicates the root of this plugin.
  649. * <p>
  650. * Returned paths indicating subdirectory paths end with a &quot;/&quot;.
  651. * The returned paths are all relative to the root of this plugin and must
  652. * not begin with &quot;/&quot;.
  653. * <p>
  654. *
  655. * @param path The path name for which to return resource paths.
  656. * @return A list of the resource paths (<code>QString</code>
  657. * objects) or an empty list if no entry could be found.
  658. * @throws ctkIllegalStateException If this plugin has been
  659. * uninstalled.
  660. */
  661. virtual QStringList getResourceList(const QString& path) const;
  662. /**
  663. * Returns a list of resources in this plugin.
  664. *
  665. * <p>
  666. * This method is intended to be used to obtain configuration, setup,
  667. * localization and other information from this plugin. This method can
  668. * either return only entries in the specified path or recurse into
  669. * subdirectories returning entries in the directory tree beginning at the
  670. * specified path.
  671. *
  672. * <p>
  673. * Examples:
  674. *
  675. * \code
  676. * // List all XML files in the OSGI-INF directory and below
  677. * QStringList r = b->findResources(&quot;OSGI-INF&quot;, &quot;*.xml&quot;, true);
  678. *
  679. * // Find a specific localization file
  680. * QStringList r = b->findResources(&quot;OSGI-INF/l10n&quot;, &quot;plugin_nl_DU.tm&quot;, false);
  681. * \endcode
  682. *
  683. * @param path The path name in which to look. The path is always relative
  684. * to the root of this plugin and may begin with &quot;/&quot;. A
  685. * path value of &quot;/&quot; indicates the root of this plugin.
  686. * @param filePattern The file name pattern for selecting entries in the
  687. * specified path. The pattern is only matched against the last
  688. * element of the entry path. Substring matching is supported, as
  689. * specified in the Filter specification, using the wildcard
  690. * character (&quot;*&quot;). If a null QString is specified, this
  691. * is equivalent to &quot;*&quot; and matches all files.
  692. * @param recurse If <code>true</code>, recurse into subdirectories.
  693. * Otherwise only return entries from the specified path.
  694. * @return A list of QString objects for each matching entry, or
  695. * an empty list if an entry could not be found or if the caller
  696. * does not have the appropriate
  697. * <code>AdminPermission[this,RESOURCE]</code>, and the Plugin
  698. * Framework supports permissions.
  699. * @throws ctkIllegalStateException If this plugin has been uninstalled.
  700. */
  701. virtual QStringList findResources(const QString& path, const QString& filePattern, bool recurse) const;
  702. /**
  703. * Returns a QByteArray containing a Qt resource located at the
  704. * specified path in this plugin.
  705. * <p>
  706. * The specified path is always relative to the root of this plugin
  707. * (the plugins symbolic name) and may
  708. * begin with &quot;/&quot;. A path value of &quot;/&quot; indicates the
  709. * root of this plugin.
  710. * <p>
  711. *
  712. * @param path The path name of the resource.
  713. * @return A QByteArray to the resource, or a null QByteArray if no resource could be
  714. * found.
  715. * @throws ctkIllegalStateException If this plugin has been
  716. * uninstalled.
  717. */
  718. virtual QByteArray getResource(const QString& path) const;
  719. /**
  720. * Returns a <code>ctkPluginLocalization</code> object for the
  721. * specified <code>locale</code>. The translations are loaded from a
  722. * .qm file starting with <code>base</code>.
  723. *
  724. * You can use the returned <code>ctkPluginLocalization</code>
  725. * object to dynamically translate text without changing the current
  726. * locale of the application. This can be used for example to
  727. * provide localized messages to multiple users which use the application
  728. * (maybe some kind of server) simultaneously but require different
  729. * localizations.
  730. *
  731. * @param locale The locale to be used by the returned
  732. * <code>ctkPluginLocalization</code> object.
  733. * @param base The base name of the .qm message file which contains
  734. * translated messages. Defaults to
  735. * <code>ctkPluginConstants::PLUGIN_LOCALIZATION_DEFAULT_BASENAME</code>.
  736. * @return A locale specific <code>ctkPluginLocalization</code> instance.
  737. */
  738. ctkPluginLocalization getPluginLocalization(const QLocale& locale,
  739. const QString& base = ctkPluginConstants::PLUGIN_LOCALIZATION_DEFAULT_BASENAME) const;
  740. /**
  741. * Returns the version of this plugin as specified by its
  742. * <code>Plugin-Version</code> manifest header. If this plugin does not have a
  743. * specified version then {@link ctkVersion#emptyVersion} is returned.
  744. *
  745. * <p>
  746. * This method must continue to return this plugin's version while
  747. * this plugin is in the <code>UNINSTALLED</code> state.
  748. *
  749. * @return The version of this plugin.
  750. */
  751. ctkVersion getVersion() const;
  752. protected:
  753. friend class ctkPluginFramework;
  754. friend class ctkPluginFrameworkLauncherPrivate;
  755. friend class ctkPluginFrameworkPrivate;
  756. friend class ctkPluginFrameworkContext;
  757. friend class ctkPlugins;
  758. friend class ctkServiceReferencePrivate;
  759. // Do NOT change this to QScopedPointer<ctkPluginPrivate>!
  760. // We would need to include ctkPlugin.h (and ctkPluginPrivate_p.h)
  761. // at a lot of places...
  762. ctkPluginPrivate* d_ptr;
  763. ctkPlugin();
  764. void init(ctkPluginPrivate* dd);
  765. void init(const QWeakPointer<ctkPlugin>& self, ctkPluginFrameworkContext* fw, QSharedPointer<ctkPluginArchive> ba);
  766. private:
  767. Q_DECLARE_PRIVATE(ctkPlugin)
  768. Q_DISABLE_COPY(ctkPlugin)
  769. };
  770. /**
  771. * \ingroup PluginFramework
  772. * @{
  773. */
  774. Q_DECLARE_METATYPE(ctkPlugin*)
  775. Q_DECLARE_METATYPE(QSharedPointer<ctkPlugin>)
  776. Q_DECLARE_OPERATORS_FOR_FLAGS(ctkPlugin::States)
  777. Q_DECLARE_OPERATORS_FOR_FLAGS(ctkPlugin::StartOptions)
  778. Q_DECLARE_OPERATORS_FOR_FLAGS(ctkPlugin::StopOptions)
  779. CTK_PLUGINFW_EXPORT QDebug operator<<(QDebug debug, ctkPlugin::State state);
  780. CTK_PLUGINFW_EXPORT QDebug operator<<(QDebug debug, const ctkPlugin& plugin);
  781. CTK_PLUGINFW_EXPORT QDebug operator<<(QDebug debug, ctkPlugin const * plugin);
  782. CTK_PLUGINFW_EXPORT ctkLogStream& operator<<(ctkLogStream& stream, ctkPlugin const * plugin);
  783. CTK_PLUGINFW_EXPORT ctkLogStream& operator<<(ctkLogStream& stream, const QSharedPointer<ctkPlugin>& plugin);
  784. /** @}*/
  785. #endif // CTKPLUGIN_H