Changes for page Creating XWiki Components
Last modified by Simon Urli on 2023/10/10
From version 29.1
edited by Vincent Massol
on 2010/11/14
on 2010/11/14
Change comment:
There is no comment for this version
To version 30.1
edited by Vincent Massol
on 2010/11/14
on 2010/11/14
Change comment:
There is no comment for this version
Summary
-
Page properties (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -83,7 +83,7 @@ 83 83 84 84 Navigating in the component project folder, you will see the following standard Maven project structure: 85 85 86 -{{code}} 86 +{{code language="none"}} 87 87 pom.xml 88 88 src/main/java/com/acme/HelloWorld.java 89 89 src/main/java/com/acme/internal/DefaultHelloWorld.java ... ... @@ -95,7 +95,7 @@ 95 95 96 96 If you have a look in the ##pom.xml##, you'll notice the following dependencies: 97 97 98 -{{code}} 98 +{{code language="xml"}} 99 99 <dependencies> 100 100 <dependency> 101 101 <groupId>org.xwiki.platform</groupId> ... ... @@ -116,7 +116,7 @@ 116 116 117 117 The interface file (##HelloWorld.java##) contains the definition of a regular Java interface, and looks like this: 118 118 119 -{{code}} 119 +{{code language="java"}} 120 120 @ComponentRole /* annotation used for declaring the service our component provides */ 121 121 public interface HelloWorld 122 122 { ... ... @@ -128,7 +128,7 @@ 128 128 129 129 Then we have the implementation of the interface, the ##DefaltHelloWorld## class. 130 130 131 -{{code}} 131 +{{code language="java"}} 132 132 @Component /* annotation used for declaring a component implementation */ 133 133 public class DefaultHelloWorld implements HelloWorld 134 134 {{/code}} ... ... @@ -135,7 +135,7 @@ 135 135 136 136 Note that optionally, the ##@Component## annotation can specify a //hint//. This is useful especially when we want to distinguish between several implementations for the same type of component. Image we had a special HelloWorld implementation taking the greeting message from a database; it could look lile: 137 137 138 -{{code}} 138 +{{code language="java"}} 139 139 @Component("database") 140 140 public class DatabaseHelloWorld implements HelloWorld 141 141 {{/code}} ... ... @@ -142,7 +142,7 @@ 142 142 143 143 Then the ##sayHello## in ##DefaultHelloWorld## is basic in this example: 144 144 145 -{{code}} 145 +{{code language="java"}} 146 146 /** 147 147 * Says hello by returning a greeting to the caller. 148 148 * ... ... @@ -156,21 +156,19 @@ 156 156 157 157 And now, the ##components.txt## file, in which component implementations present in this jar are specified for the ##ComponentManager## to register them. 158 158 159 -{{code}}com.acme.internal.DefaultHelloWorld{{/code}} 159 +{{code language="none"}}com.acme.internal.DefaultHelloWorld{{/code}} 160 160 161 161 = How to find my component and use it? = 162 162 163 163 == From other components == 164 164 165 -To access your component from another component we use the components engine, and specify the dependencies declarative, leaving instantiation and component injection to the be handled by the component manager.The most straightforward way is the use of the requirements mechanism of plexus, specifying that our component is required by the component that needs to access it.165 +To access your component from another component we use the components engine, and specify the dependencies, leaving instantiation and component injection to the be handled by the component manager. 166 166 167 - Don'tforgetthat any codethatusesthe componentwe wroteneedsto have the componentinterfaceaccessible in its classpath.Evenif instantiationand dependencyisandledby the engine atruntime,thecode still needstocompile. If thetwocomponentsarenot in thesame module(the same .jar),don't forget toaddthe moduleof the greetercomponentasa dependencyofthemodule ofanycomponent that usesit.167 +In order to use the ##HelloWorld## component, you need a reference to it in the the component that uses it. For this, you should use a member variable in the implementation of the using component, for example, a ##Socializer## component will need to be able to say hello to the world: 168 168 169 -Then, to effectively use the ##HelloWorld## component, we need a reference to it in the the component that uses it. For this, we use a member variable in the implementation of the using component, for example, a ##Socializer## component will need to be able to say hello to the world: 170 - 171 171 {{code}} 172 172 @Component 173 -public class DefaultSocializer extends AbstractLogEnabledimplements Socializer,Initializable171 +public class DefaultSocializer implements Socializer 174 174 { 175 175 [...] 176 176 ... ... @@ -184,14 +184,10 @@ 184 184 185 185 Note the ##@Requirement## annotation, which instructs the component manager to inject the required component where needed. 186 186 187 -The content of ##components.txt## should be updated with: 188 - 189 -{{code}}org.xwiki.component.internal.DefaultSocializer{{/code}} 190 - 191 191 And that's it, you can now use the ##helloWorld## member anywhere in the ##DefaultSocializer## class freely, without further concerns, it will be assigned by the component manager provided that the ##HelloWorld## component is on the classpath at runtime when the ##Socializer## is used. Such as: 192 192 193 193 {{code}} 194 -public class DefaultSocializer extends AbstractLogEnabledimplements Socializer,Initializable188 +public class DefaultSocializer implements Socializer 195 195 { 196 196 [...] 197 197 ... ... @@ -208,8 +208,6 @@ 208 208 209 209 More, note that all through the process of defining a communication path between two components, we never referred components implementations, all specifications being done through //roles// and //interfaces//: the implementation of a service is completely hidden from any code external to the component. 210 210 211 -TODO: refer to the other ways of implementing dependencies but requirements mechanism. Details, explanations, links. 212 - 213 213 == From non-components java code (e.g. older plugins) == 214 214 215 215 For this kind of usages, since we cannot use the component-based architecture advantages and the "magic" of the component manager, the XWiki team has created a helper method that acts like a bridge between component code and non-component code, the ##com.xpn.xwiki.web.Utils.getComponent(String role, String hint)## that gets the specified component instance from the component manager and returns it. As seen in the previous sections, the hint is an optional identifier, additional to ##role##, used to differentiate between implementations of the same interface: the //roles// identify services while the hints help differentiate between implementations (see more at [[http://plexus.codehaus.org/guides/developer-guide/building-components/component-identity.html>>http://plexus.codehaus.org/guides/developer-guide/building-components/component-identity.html]]). The ##getComponent## function also has a version without the ##hint## parameter, that uses the default hint.