Wiki source code of Maven XAR Plugin

Last modified by Thomas Mortagne on 2025/04/23 10:46

Hide last authors
Vincent Massol 2.2 1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
4
Vincent Massol 9.1 5 This build tool allows creating XAR files, expanding XAR files, reformatting them and verifying some best practices.
Vincent Massol 1.1 6
7 = XAR Mojo =
8
9 To configure it:
Thomas Mortagne 17.1 10
Vincent Massol 1.1 11 * Register a new Maven Lifecycle in your POM:(((
12 {{code language="xml"}}
13 ...
14 <build>
15 <extensions>
16 <extension>
17 <groupId>org.xwiki.commons</groupId>
18 <artifactId>xwiki-commons-tool-xar-handlers</artifactId>
19 <version>...version here...</version>
20 </extension>
21 </extensions>
22 ...
23 {{/code}}
24 )))
25 * Create a Maven POM file with the ##xar## packaging: {{code language="xml"}}<packaging>xar</packaging>{{/code}}
Thomas Mortagne 17.1 26 * Put the wiki pages as XML files in ##src/main/resources## by having directories matching space names. For example:(((
Vincent Massol 1.1 27 {{image reference="structure.png"/}}
28 )))
29
30 To use it:
Thomas Mortagne 17.1 31
Vincent Massol 1.1 32 * ##mvn xar:xar## will generate the XAR file
33
Vincent Massol 16.3 34 == Transformations ==
Vincent Massol 3.1 35
Vincent Massol 16.3 36 It is also possible to perform transformations on the XML files. For example:
37
Paul Libbrecht 26.1 38 === Insert a text value ===
39
40 This can work well, for example, to change skin definitions. E.g.:
41
Vincent Massol 3.1 42 {{code language="xml"}}
43 <plugin>
44 <groupId>org.xwiki.commons</groupId>
45 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
46 <configuration>
47 <transformations>
48 <transformation>
49 <file>Blog/WebHome.xml</file>
50 <xpath>/xwikidoc/object/property/itemsPerPage</xpath>
51 <value>100</value>
52 </transformation>
53 <transformation>
54 <artifact>org.xwiki.platform:xwiki-platform-administration-ui</artifact>
55 <file>XWiki/XWikiPreferences.xml</file>
56 <xpath>/xwikidoc/object/property/colorTheme</xpath>
57 <value>ColorThemes.Mint</value>
58 </transformation>
59 </transformations>
60 </configuration>
61 </plugin>
62 {{/code}}
63
Paul Libbrecht 26.1 64 === Manipulate XML elements ===
Thomas Mortagne 17.1 65
Vincent Massol 35.2 66 It is possible to remove/replace/insert a complete XML element. Here is an example:
Paul Libbrecht 26.1 67
Thomas Mortagne 17.1 68 {{code language="xml"}}
69 <plugin>
70 <groupId>org.xwiki.commons</groupId>
71 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
72 <configuration>
73 <transformations>
Paul Libbrecht 26.1 74 <!-- Insert the content of file src/xar/transformations/ckeditor.xml
75 as child of xwikidoc element in XWiki/XWikiPreferences.xml -->
Thomas Mortagne 17.1 76 <transformation>
77 <artifact>org.xwiki.platform:xwiki-platform-distribution-ui-base</artifact>
78 <file>XWiki/XWikiPreferences.xml</file>
79 <xpath>xwikidoc</xpath>
80 <action>INSERT_CHILD</action>
81 <xml>src/xar/transformations/ckeditor.xml</xml>
82 </transformation>
Vincent Massol 17.3 83 <!-- Remove first attachments from XWiki/XWikiPreferences.xml -->
Thomas Mortagne 17.1 84 <transformation>
85 <artifact>org.xwiki.platform:xwiki-platform-distribution-ui-base</artifact>
86 <xpath>xwikidoc/attachment</xpath>
87 <action>REMOVE</action>
88 </transformation>
89 </transformations>
90 </configuration>
91 </plugin>
92 {{/code}}
93
Paul Libbrecht 26.1 94 === Insert Text Content of a File ===
95
Vincent Massol 35.2 96 It is possible to insert the text of another project file. This works well to insert complex JavaScript, Velocity or CSS files. These files, if they are not named ##.xml## stay within the same directory and will be ignored unless they are inserted and can thus be edited with an integrated development environment (which brings syntax coloring, auto-completion, reformatting, or validation). Here is an example:
Paul Libbrecht 26.1 97
98 {{code language="xml"}}
99 <plugin>
100 <groupId>org.xwiki.commons</groupId>
101 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
102 <configuration>
103 <transformations>
104 <transformation>
105 <!-- Insert the content of file src/main/resources/MyApp/config.js
106 as the value of the property code in the first object of class
107 XWiki.JavaScriptExtension of the XML file MyApp/Config.xml -->
108 <action>INSERT_TEXT</action>
109 <file>MyApp/Config.xml</file>
110 <xpath>/xwikidoc/object[className[text()='XWiki.JavaScriptExtension']]/property/code</xpath>
111 <content>src/main/resources/MyApp/config.js</content>
112 </transformation>
113 </transformations>
114 </configuration>
115 </plugin>
116 {{/code}}
117
118
119 === Insert an Attachment ===
120
Vincent Massol 35.2 121 It is possible to insert the content of another project file as an attachment in Base64 encoding just as XWiki would do it in an XML file of a XAR. You can use this to insert files with the same name edited somewhere else. Doing so, it also updates the filesize attribute. Here is an example:
Paul Libbrecht 26.1 122
123 {{code language="xml"}}
124 <plugin>
125 <groupId>org.xwiki.commons</groupId>
126 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
127 <configuration>
128 <transformations>
129 <transformation>
130 <!-- Insert the content of file src/main/resources/MyApp/testcolors.xls
131 as the attachment of the page TestDocumentList of the space MyApp -->
132 <action>INSERT_ATTACHMENT_CONTENT</action>
133 <file>MyApp/TestDocumentList.xml</file>
Paul Libbrecht 31.7 134 <xpath>/xwikidoc/attachment[/filename[text()='testcolors.xls']]</xpath>
Paul Libbrecht 26.1 135 <content>src/main/resources/MyApp/testcolors.xls</content>
136 </transformation>
137 </transformations>
138 </configuration>
139 </plugin>
140 {{/code}}
141
Thomas Mortagne 22.1 142 == Documents types ==
143
Thomas Mortagne 34.1 144 It's possible to indicate in the pom.xml the [[type>>extensions:Extension.Extension Module.Extensions.XAR||anchor="HStandardtypes"]] of a each document. That way the [[##package.xml##>>extensions:Extension.XAR Module Specifications||anchor="Hpackage.xml"]] will be generated automatically but will take into account information it cannot really deduce from the documents XML files.
Thomas Mortagne 22.1 145
146 {{code}}
147 <plugin>
148 <groupId>org.xwiki.commons</groupId>
149 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
150 <configuration>
151 <entries>
152 <entry>
153 <document>Main.WebHome</document>
154 <type>home</type>
155 </entry>
156 <entry>
157 <document>Some.Demo.Page</document>
158 <type>demo</type>
159 </entry>
160 <entry>
161 <document>MyApplication.MyConfiguration</document>
162 <type>configuration</type>
163 </entry>
164 </entries>
165 </configuration>
166 </plugin>
167 {{/code}}
168
Alexandru Brassat 37.2 169 You can provide the option {{code}}<defaultEntryType>myEntryType</defaultEntryType>{{/code}} in the configuration of the plugin. When defined, the default entry type will be applied to every entry not being overridden through the {{code}}<entries>...</entries>{{/code}} list in the plugin configuration.
Clément Aubin 31.5 170
Clément Aubin 27.1 171 {{warning}}
172 You should only provide one {{code}}<document>{{/code}} per {{code}}<entry>{{/code}}. For example, the following configuration will not work :
173
Clément Aubin 31.4 174 {{code}}
175 <entries>
176 <entry>
177 <document>MySpace.MyPage1</document>
178 <document>MySpace.MyPage1</document>
179 <type>demo</type>
180 </entry>
181 </entries>
182 {{/code}}
183
184 Instead, you should write :
185
186 {{code}}
187 <entries>
188 <entry>
189 <document>MySpace.MyPage1</document>
190 <type>demo</type>
191 </entry>
192 <entry>
193 <document>MySpace.MyPage2</document>
194 <type>demo</type>
195 </entry>
196 </entries>
197 {{/code}}
Clément Aubin 27.1 198 {{/warning}}
199
Vincent Massol 31.1 200 = Format & Verify Mojo =
201
Vincent Massol 35.2 202 There are 4 types of pages that can be defined using regexes:
Paul Libbrecht 31.6 203
Vincent Massol 31.1 204 * Technical Pages: This is the default. It means pages must be hidden and not have any default language set.
205 * Content Pages: These are pages having content and that can have translations. These pages must not be hidden and must have a non-empty default language (so that the XWiki search return results for them when the English language is selected in language facet for example). Example:(((
206 {{code language="xml"}}
207 <plugin>
208 <groupId>org.xwiki.commons</groupId>
209 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
210 <configuration>
211 <contentPages>
212 <contentPage>.*/Space[1-9]*/WebHome\.xml</contentPage>
213 </contentPages>
214 </configuration>
215 </plugin>
216 {{/code}}
217 )))
218 * Translatable Pages: These are technical pages but that can have translations. It means pages must be hidden and have a non-empty default language. When not specified it defaults to ##.*/.*Translations\.xml##, which corresponds to XWiki platform's best practice for naming wiki translation pages. Override example:(((
219 {{code language="xml"}}
220 <plugin>
221 <groupId>org.xwiki.commons</groupId>
222 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
223 <configuration>
224 <translatablePages>
225 <translatablePage>.*/Translations\.xml</translatablePage>
226 </translatablePages>
227 </configuration>
228 </plugin>
229 {{/code}}
230 )))
231 * Visible Technical Pages: These are technical pages but that must be visible but that shouldn't return results in Search. For example, home pages of applications. They must not be hidden but they must have their default language set to empty. Example:(((
232 {{code language="xml"}}
233 <plugin>
234 <groupId>org.xwiki.commons</groupId>
235 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
236 <configuration>
237 <visibleTechnicalPages>
Vincent Massol 31.8 238 <visibleTechnicalPage>.*/Space/WebHome\.xml</visibleTechnicalPage>
Vincent Massol 31.1 239 </visibleTechnicalPages>
240 </configuration>
241 </plugin>
242 {{/code}}
243 )))
244
Vincent Massol 1.1 245 = Format Mojo =
246
Vincent Massol 31.1 247 To use the mojo:
248
Vincent Massol 1.1 249 * ##mvn xar:format## will perform some cleaning of your XML files, namely:
Vincent Massol 3.3 250 ** Indent lines (using 2 space characters)
Vincent Massol 10.1 251 ** Set ##author##, ##contentAuthor##, ##creator## and attachment ##author##s to be ##xwiki:XWiki.Admin##
Vincent Massol 1.1 252 ** Set ##version## to be 1.1
253 ** Set ##minorEdit## to be false
Vincent Massol 31.1 254 ** Remove any content of the ##defaultLanguage## element unless the document has translations, or it's marked as a ##translatablePage## or it's marked as a ##contentPage## (see above).
Vincent Massol 1.1 255 ** Remove any content of the ##comment## element
Vincent Massol 31.1 256 ** Add any missing license header by using the license defined in ##xwiki-commons-tool-verification-resources## JAR. License headers will be checked if the ##formatLicense## configuration parameter is set to true:(((
Vincent Massol 4.1 257 {{code language="xml"}}
258 <plugin>
259 <groupId>org.xwiki.commons</groupId>
260 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
261 <version>${commons.version}</version>
262 <configuration>
263 <!-- Add missing license headers by default -->
264 <formatLicense>true</formatLicense>
265 </configuration>
266 </plugin>
267 {{/code}}
268 )))
Vincent Massol 31.1 269 ** Technical pages are marked hidden. Same for translatable pages.
Vincent Massol 35.2 270 ** Remove any ##date##, ##creationDate##, ##contentUpdateDate## or attachment ##date## fields, regardless if they have empty values or not. This is done because it's causing confusion for users to install pages that are created in 2005/2009/etc. so we should avoid committing dates on git that users might end up installing.
Eduard Moraru 25.1 271 *** Can be disabled for individual pages with either ##-Dxar.dates.skip.documentList=Space1.Subspace2.Page1,Space2.Subspace2.Page2,etc.## (system property) or ##<skipDatesDocumentList>Space1.Subspace2.Page1,Space2.Subspace2.Page2,etc.</skipDatesDocumentList>## (plugin configuration parameter).
272 *** Can be disabled for all pages in the xar with either ##-Dxar.dates.skip=true## (system property) or ##<skipDates>true</skipDates>## (plugin configuration parameter).
Vincent Massol 35.2 273 ** Forces the XML version to be 1.1
Thomas Mortagne 36.1 274 ** {{version since="16.6.0"}}Fix locale with wrong format (pt-BR instead of pt_BR){{/version}}
Vincent Massol 1.1 275
276 = Verify Mojo =
277
278 This is used to fail the build if the XML pages don't conform to the following rules:
Thomas Mortagne 17.1 279
Vincent Massol 1.1 280 * Verify that the encoding is UTF-8
Vincent Massol 10.1 281 * Verify that ##author##, ##contentAuthor##, ##creator## and attachment ##author##s are set to ##xwiki:XWiki.Admin##
Vincent Massol 30.1 282 * Verify that the ##parent## field is not empty (except for ##Main.WebHome##). This check became optional (and turned off by default) in XWiki 11.10.3 & 12.0RC1.
283 ** To turn if on, set ##<emptyParentSkip>false</emptyParentSkip>## in the POM or pass ##-Dxar.verify.translationVisibility.skip=false## on the Maven command line
Vincent Massol 1.1 284 * Verify that ##version## is set to 1.1
285 * Verify that ##comment## is empty
286 * Verify that ##minorEdit## is set to false
Vincent Massol 31.1 287 * Verify that the ##defaultLanguage## is empty for technical documents and ##visibleTechnicalPage##s (see above).
288 * Verify that the ##defaultLanguage## is not empty for ##contentPage##s and ##translatablePage##s (see above) and it matches the configured language in the mojo (by default ##en##, it's configurable in the ##<configuration>##, for example ##<defaultLanguage>fr</defaultLanguage>##).
Thomas Mortagne 38.1 289 * Verify that the locale matches the name of the XML file
Vincent Massol 8.1 290 * (optional) Verify that the XML files contain license headers (if the ##formatLicense## configuration property is set to ##true##).
Vincent Massol 31.1 291 * Verify that technical pages, and ##translatablePage##s are set as hidden, and that ##contentPage##s and ##translatablePage##s are set as npot hidden.
292 * Verify that defined pages have a specific matching title. For example:(((
Thomas Mortagne 33.1 293 {{code language="xml"}}
294 <plugin>
Vincent Massol 14.1 295 <groupId>org.xwiki.commons</groupId>
296 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
297 ...
298 <configuration>
299 ...
Vincent Massol 15.1 300 <titles>
301 <!-- Verify that all WebPreferences pages have the same title for consistency -->
302 <property>
303 <name>.*WebPreferences</name>
304 <value>\$services\.localization\.render\('admin.preferences.title'\)</value>
305 </property>
306 </titles>
Vincent Massol 14.1 307 </configuration>
Thomas Mortagne 33.1 308 </plugin>
309 {{/code}}
Vincent Massol 14.1 310 )))
Vincent Massol 31.1 311 * Verify that Translations pages (i.e. documents with a ##XWiki.TranslationDocumentClass## xobject) are using the ##plain/1.0## syntax.
Vincent Massol 35.2 312 * Verify that Translations pages don't have a GLOBAL or USER visibility (USER makes no sense and GLOBAL would require Programming Rights, which is an issue in farm-based use cases). This check can be ignore by using the ##translationVisibilitySkip## configuration option (or ##xar.verify.translationVisibility.skip## on the command line).
313 * Verify that attachments have a mimetype set. If the mimetype is missing then the attachment won't be filterable in the attachment view in Page Index.
314 * Verify that any ##date##, ##creationDate##, ##contentUpdateDate## or attachment ##date## fields are not specified, thus risking to import pages with stale dates.
Eduard Moraru 25.1 315 ** Can be disabled for individual pages with either ##-Dxar.dates.skip.documentList=Space1.Subspace2.Page1,Space2.Subspace2.Page2,etc.## (system property) or ##<skipDatesDocumentList>Space1.Subspace2.Page1,Space2.Subspace2.Page2,etc.</skipDatesDocumentList>## (plugin configuration parameter).
316 ** Can be disabled for all pages in the xar with either ##-Dxar.dates.skip=true## (system property) or ##<skipDates>true</skipDates>## (plugin configuration parameter).
Vincent Massol 35.2 317 * Verify that translated pages don't contain any attachment.
318 * Verify that translated pages don't contain any object.
Thomas Mortagne 37.1 319 * {{version since="16.6.0"}}Verify there is no locale with the wrong format (pt-BR instead of pt_BR){{/version}}
Vincent Massol 1.1 320
321 Example usage:
322
323 {{code language="xml"}}
324 <plugin>
325 <groupId>org.xwiki.commons</groupId>
326 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
327 <executions>
328 <execution>
329 <goals>
330 <goal>verify</goal>
331 </goals>
332 </execution>
333 </executions>
334 </plugin>
335 {{/code}}
336
Eduard Moraru 19.1 337 To skip the execution of the verify mojo, you can use the property ##xar.verify.skip## with the value ##true##.
338
Vincent Massol 1.1 339 = UnXAR Mojo =
340
341 To configure it:
342
343 {{code language="xml"}}
344 <plugin>
345 <groupId>org.xwiki.commons</groupId>
346 <artifactId>xwiki-commons-tool-xar-plugin</artifactId>
347 <configuration>
348 <groupId>...group id of XAR artifact to expand...</groupId>
349 <artifactId>...artifact id of XAR artifact to expand...</artifactId>
350 <outputDirectory>${project.build.outputDirectory}</outputDirectory>
351 <includes>
352 <include>Space/Page.xml</include>
353 ...
354 </includes>
355 <excludes>
356 <exclude>Space/Page.xml</exclude>
357 ...
358 </excludes>
359 </configuration>
360 </plugin>
361 {{/code}}
362
363 To use it:
Thomas Mortagne 17.1 364
Vincent Massol 1.1 365 * ##mvn unxar## will expand the XAR file

Get Connected