PageRenderTime 37ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/content/server/framework/atlassian-sdk/content-for-component-plugin-module.snippet.md

https://bitbucket.org/zchristmas/atlassian-sdk-docs
Markdown | 178 lines | 158 code | 20 blank | 0 comment | 0 complexity | fb22d82fe37f42f1dadab9a04e7ab665 MD5 | raw file
Possible License(s): LGPL-2.0
  1. ---
  2. aliases:
  3. - /server/framework/atlassian-sdk/-content-for-component-plugin-module-852064.html
  4. - /server/framework/atlassian-sdk/-content-for-component-plugin-module-852064.md
  5. category: devguide
  6. confluence_id: 852064
  7. dac_edit_link: https://developer.atlassian.com/pages/editpage.action?cjm=wozere&pageId=852064
  8. dac_view_link: https://developer.atlassian.com/pages/viewpage.action?cjm=wozere&pageId=852064
  9. date: '2017-12-08'
  10. legacy_title: _Content for Component Plugin Module
  11. platform: server
  12. product: atlassian-sdk
  13. subcategory: other
  14. title: _Content for Component Plugin Module
  15. ---
  16. # \_Content for Component Plugin Module
  17. ## Purpose of this Module Type
  18. Component plugin modules enable you to share Java components between other modules in your plugin and optionally with other plugins in the application. You can use it to make any type of class instance available to other plugins or modules. It's in effect a Spring bean declaration (with greatly simplified syntax, since only autowiring is supported) plus an OSGi export.
  19. The typical uses of a component are:
  20. - To define a singleton class that's used internally by your plugin, which the framework instantiates for you and passes to your other classes via autowiring; or
  21. - To expose an API to other plugin modules.
  22. ## Configuration
  23. The root element for the Component plugin module is `component`. It allows the following attributes and child elements for configuration:
  24. #### Attributes
  25. <table>
  26. <colgroup>
  27. <col style="width: 20%" />
  28. <col style="width: 80%" />
  29. </colgroup>
  30. <thead>
  31. <tr class="header">
  32. <th><p>Name*</p></th>
  33. <th><p>Description</p></th>
  34. </tr>
  35. </thead>
  36. <tbody>
  37. <tr class="odd">
  38. <td>alias</td>
  39. <td><p>The alias to use for the component when registering it in the internal bean factory.</p>
  40. <p><strong>Default:</strong> the plugin key.</p></td>
  41. </tr>
  42. <tr class="even">
  43. <td><p>class</p></td>
  44. <td><p>The class which implements this plugin module. The class you need to provide depends on the module type. For example, Confluence theme, layout and colour-scheme modules can use classes already provided in Confluence. So you can write a theme-plugin without any Java code. But for macro and listener modules you need to write your own implementing class and include it in your plugin. See the plugin framework guide to <a href="https://developer.atlassian.com/display/DOCS/Creating+Plugin+Module+Instances">creating plugin module instances</a>. </p>
  45. <p>The Java class of the component. This does not need to extend or implement any class or interface. </p></td>
  46. </tr>
  47. <tr class="odd">
  48. <td>key</td>
  49. <td><p> The unique identifier of the plugin module. You refer to this key to use the resource from other contexts in your plugin, such as from the plugin Java code or JavaScript resources.</p>
  50. <p> </p>
  51. <pre><code>&lt;component-import key=&quot;appProps&quot; interface=&quot;com.atlassian.sal.api.ApplicationProperties&quot;/&gt;</code></pre>
  52. <p> </p>
  53. <p>In the example, <code>appProps</code> is the key for this particular module declaration, for <code>component-import</code>, in this case.</p>
  54.  
  55. <p>I.e. the identifier of the component.</p></td>
  56. </tr>
  57. <tr class="even">
  58. <td><p>state</p>
  59. <p> </p></td>
  60. <td><p>Indicate whether the plugin module should be disabled by default (value='disabled') or enabled by default (value='enabled').</p>
  61. <p><strong>Default:</strong> enabled.</p></td>
  62. </tr>
  63. <tr class="odd">
  64. <td><p>i18n-name-key</p></td>
  65. <td>The localisation key for the human-readable name of the plugin module.</td>
  66. </tr>
  67. <tr class="even">
  68. <td><p>key</p></td>
  69. <td>The unique identifier of the plugin module. You refer to this key to use the resource from other contexts in your plugin, such as from the plugin Java code or JavaScript resources.
  70. <p> </p>
  71. <pre><code>&lt;component-import key=&quot;appProps&quot; interface=&quot;com.atlassian.sal.api.ApplicationProperties&quot;/&gt;</code></pre>
  72. <p> </p>
  73. <p>In the example, <code>appProps</code> is the key for this particular module declaration, for <code>component-import</code>, in this case.</p></td>
  74. </tr>
  75. <tr class="odd">
  76. <td><p>name</p></td>
  77. <td><p>The human-readable name of the plugin module. </p>
  78. <p>I.e. the human-readable name of the component.</p>
  79. <p><strong>Default:</strong> the plugin key.</p></td>
  80. </tr>
  81. <tr class="even">
  82. <td>public</td>
  83. <td><p>Indicates whether this component should be made available to other plugins via the <a href="/server/framework/atlassian-sdk/component-import-plugin-module">Component Import Plugin Module</a> or not.</p>
  84. <p><strong>Default:</strong> false.</p></td>
  85. </tr>
  86. <tr class="odd">
  87. <td><p>system</p></td>
  88. <td><p>Indicates whether this plugin module is a system plugin module (value='true') or not (value='false'). Only available for non-OSGi plugins.</p>
  89. <p><strong>Default:</strong> false.</p></td>
  90. </tr>
  91. </tbody>
  92. </table>
  93. **\*key attribute is required.**
  94. #### Elements
  95. <table>
  96. <colgroup>
  97. <col style="width: 20%" />
  98. <col style="width: 80%" />
  99. </colgroup>
  100. <thead>
  101. <tr class="header">
  102. <th><p>Name*</p></th>
  103. <th><p>Description</p></th>
  104. </tr>
  105. </thead>
  106. <tbody>
  107. <tr class="odd">
  108. <td>interface</td>
  109. <td><p>The Java interface under which this component should be registered.</p>
  110. <p>This element can appear zero or more times.</p></td>
  111. </tr>
  112. <tr class="even">
  113. <td><p>description</p></td>
  114. <td><p> The description of the plugin module. The 'key' attribute can be specified to declare a localisation key for the value instead of text in the element body.</p></td>
  115. </tr>
  116. <tr class="odd">
  117. <td>service-properties</td>
  118. <td><p>Map of simple properties to associate with a public component (Plugin Framework 2.3 and later).</p>
  119. <p>Child elements are named <code>entry</code> and have <code>key</code> and <code>value</code> attributes.</p>
  120. <p>Service properties are intended to serve as filterable values in the component-import declarations that use this component.</p>
  121. <p>This allows you to define various flavors of a public component, and import them based on the value of these flavors.</p>
  122. <p>For example, when importing a component named <code>dictionaryService</code> with a <code>language</code> service property,</p>
  123. <p>the <code>component-import</code> statement can select the component flavor with <code>language</code> property <code>English</code> as follows:</p>
  124. <p><code>&lt;component-import key=&quot;dictionaryService&quot; interface=&quot;com.myapp.DictionaryService&quot; filter=&quot;(language=English)&quot; /&gt;</code></p></td>
  125. </tr>
  126. </tbody>
  127. </table>
  128. ## Example
  129. Here is an example `atlassian-plugin.xml` file containing a single public component:
  130. ``` xml
  131. <atlassian-plugin name="Hello World" key="example.plugin.helloworld" plugins-version="2">
  132. <plugin-info>
  133. <description>A basic component module test</description>
  134. <vendor name="Atlassian Software Systems" url="http://www.atlassian.com"/>
  135. <version>1.0</version>
  136. </plugin-info>
  137. <component key="helloWorldService" class="com.myapp.DefaultHelloWorldService">
  138. <description>Provides hello world services.</description>
  139. <interface>com.myapp.HelloWorldService</interface>
  140. </component>
  141. </atlassian-plugin>
  142. ```
  143. Here is an example public component with several service properties:
  144. ``` xml
  145. <component key="dictionaryService" class="com.myapp.DefaultDictionaryService" interface="com.myapp.DictionaryService">
  146. <description>Provides a dictionary service.</description>
  147. <service-properties>
  148. <entry key="language" value="English" />
  149. </service-properties>
  150. </component>
  151. ```
  152. ## Notes
  153. Some information to be aware of when developing or configuring a Component plugin module:
  154. - Components, at installation time, are used to generate the `atlassian-plugins-spring.xml` Spring Framework configuration file, transforming Component plugin modules into Spring bean definitions. The generated file is stored in a temporary plugin jar and installed into the framework. The plugin author should very rarely need to override this file.
  155. - The injection model for components first looks at the constructor with the largest number of arguments and tries to call it, looking up parameters by type in the plugin's bean factory. If only a no-arg constructor is found, it is called then Spring tries to autowire the bean by looking at the types used by setter methods. If you wish to have more control over how your components are created and configured, you can create your own Spring configuration file, stored in `META-INF/spring` in your plugin jar.
  156. - If the `public` attribute is set to 'true', the component will be turned into an OSGi service under the covers, using Spring Dynamic Modules to manage its lifecycle.
  157. - This module type in non-OSGi (version 1) plugins supported the StateAware interface in some products to allow a component to react to when it is enabled or disabled. To achieve the same effect, you can use the two Spring lifecycle interfaces: <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/InitializingBean.html" class="external-link">InitializingBean</a> and <a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/beans/factory/DisposableBean.html" class="external-link">DisposableBean</a>. The init() and destroy() methods on these interfaces will be called when the module is enabled or disabled, exactly like StateAware. Making this change to a component in an existing plugin will be backwards compatible in all but JIRA. That is, a component module in a legacy plugin which implements InitializingBean will have its init() method called when it is enabled, exactly the same as such a component in an OSGi plugin.
  158. - Components for non-OSGi (version 1) plugins behave very differently to components for OSGi plugins. For version 1 plugins, components are loaded into the application's object container, be it PicoContainer for JIRA or Spring for all other products that support components. For OSGi plugins, components are turned into beans for the Spring bean factory for that specific plugin. This provides more separation for plugins, but means you cannot do things like override JIRA components in OSGi plugins, as you can for static plugins.