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
Change comment: There is no comment for this version
To version 30.1
edited by Vincent Massol
on 2010/11/14
Change comment: There is no comment for this version

Summary

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't forget that any code that uses the component we wrote needs to have the component interface accessible in its classpath. Even if instantiation and dependency is handled by the engine at runtime, the code still needs to compile. If the two components are not in the same module (the same .jar), don't forget to add the module of the greeter component as a dependency of the module of any component that uses it.
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 AbstractLogEnabled implements Socializer, Initializable
171 +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 AbstractLogEnabled implements Socializer, Initializable
188 +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.

Get Connected