Apache Ant/Creating a .xar file
Motivation
editThis example is under development!
You want to create an XML archive file (.xar file) directly from your source code that can be used to load library modules or applications into a native XML database. This makes it much easier for users to install your module or application. The packaging process does all the work of uploading your files into the correct location on a running eXist server and also sets all the permissions of the XQuery files (.xq) for you automatically.
Method
editWe need to create a "zip" file with all the right components in it.
The format of the package is here:
The eXist-specific package documentation is here:
GUI Package vs. On-Disk Library vs. In DB Library
editThere are three types of installation packages:
- A external library that is not in the database
- A library that is loaded into the database
- A full application with a GUI
For all library apps without GUI but deployed into db you must use two attributes, one for the target the type="library" use the following structure:
target="some /db path" + type="library"
For a simple XQuery library package, which only needs to be registered with eXist but not deployed within the exist database the target attribute should not be used.
no target + type="library"
Sample Package Structure
editThe archive must contain two XML descriptor files in the root directory: expath-pkg.xml and repo.xml
Sample expath-pkg.xml file
<package xmlns="http://expath.org/ns/pkg" name="http://example.com/apps/myapp"
abbrev="myapp" version="0.1" spec="1.0">
<title>My Cool Application</title>
<dependency package="http://exist-db.org/apps/xsltforms"/>
</package>
Note that the file name and the string in the namespace are "pkg" but the element name and the attribute in the dependency are "package". Make sure to keep these clear.
The format of this XML file is describe in the EXPath documentation.
Sample repo.xml file that contains instructions for the eXist-specific packaging
<meta xmlns="http://exist-db.org/xquery/repo">
<description>My eXist application</description>
<author>Dan McCreary</author>
<website>http://danmccreary.com</website>
<status>alpha</status>
<license>GNU-LGPL</license>
<copyright>true</copyright>
<!-- set this to "application" (without quotes) for system that have a GUI -->
<type>application</type>
<target>myapp</target>
<prepare>pre-install.xql</prepare>
<finish>post-install.xql</finish>
<permissions user="admin" password="" group="dba" mode="rw-rw-r--"/>
<!-- this element is automatically added by the deployment tool -->
<deployed>2012-11-28T23:15:39.646+01:00</deployed>
</meta>
Sample Apache Ant Target to Generate an Application .xar file
editThis ant target needs the following inputs:
source-dir - the place you keep your source code package-dir - a temp dir such as /tmp/my-package to store temporary files app-name - the name of your application app-version - the version of your application
- verify that repo.xml and expath-package.xml exist in the source dir and copy them into temp.dir
- copy all application files temp.dir
- create zip file from contents of temp.dir in the packages area and upload it to repositories if needed
<target name="generate-app-xar" description="Generate Application xar archive file">
<echo>Making Package for ${app-name} use source from ${source-dir}</echo>
<zip destfile="${package-dir}/${app-name}-${app-version}.xar">
<fileset dir="${source-dir}">
<include name="**/*.*" />
<exclude name="**/.svn" />
</fileset>
</zip>
<echo>Package is stored at ${package-dir}/${app-name}-${app-version}.xar</echo>
</target>
Sample Apache Ant Target to Generate a Library .xar file
editThis script depends on the following Ant properties:
ant.project.name - the name of the project xslt.dir - the directory that the XSLT script are stored temp.dir - a temp dir such as /tmp to store temporary files web.specs.dir - the place to put the results
<target name="generate-xar" description="Generate xar archive">
<echo>Making ${ant.project.name}.xar...</echo>
<!-- run a transform in the input specification file to create the a.xml file -->
<xslt force="true" style="${xslt.dir}/generate-xar-descriptors.xsl"
in="${web.specs.dir}/${ant.project.name}/${ant.project.name}.xml"
out="${temp.dir}/files/a.xml">
<param name="module-version" expression="${module-version}" />
<param name="eXist-main-class-name" expression="${eXist-main-class-name}" />
</xslt>
<delete file="${temp.dir}/files/a.xml" />
<!-- now create the .xar file with all our files in the right place -->
<zip destfile="${temp.dir}/archives/${ant.project.name}-${module-version}.xar">
<fileset dir="${temp.dir}/files">
<include name="**/*.*" />
<exclude name="*-tests.jar" />
</fileset>
</zip>
</target>
Sample XSLT Script
edit<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" />
<xsl:param name="module-version" />
<xsl:param name="eXist-main-class-name" />
<xsl:template match="/">
<xsl:variable name="module-namespace">
<xsl:copy-of select="//element()[@id = 'module-namespace']" />
</xsl:variable>
<xsl:variable name="module-prefix">
<xsl:copy-of select="//element()[@id = 'module-prefix']" />
</xsl:variable>
<xsl:variable name="spec-title">
<xsl:copy-of select="concat('EXPath ', //element()[local-name() = 'title'])" />
</xsl:variable>
<xsl:variable name="author">
<xsl:copy-of select="//element()[local-name() = 'author'][1]/element()[1]" />
</xsl:variable>
<xsl:result-document href="target/files/expath-pkg.xml">
<package xmlns="http://expath.org/ns/pkg" name="http://expath.org/lib/{$module-prefix}" abbrev="{concat('expath-', $module-prefix)}"
version="{$module-version}" spec="1.0">
<title>
<xsl:value-of select="$spec-title" />
</title>
<dependency processor="http://exist-db.org/" />
</package>
</xsl:result-document>
<xsl:result-document href="target/files/repo.xml">
<meta xmlns="http://exist-db.org/xquery/repo">
<description>
<xsl:value-of select="$spec-title" />
</description>
<author>
<xsl:value-of select="$author" />
</author>
<website />
<status>stable</status>
<license>GNU-LGPL</license>
<copyright>true</copyright>
<type>library</type>
</meta>
</xsl:result-document>
<xsl:result-document href="target/files/exist.xml">
<package xmlns="http://exist-db.org/ns/expath-pkg">
<jar>
<xsl:value-of select="concat('expath-', $module-prefix, '.jar')" />
</jar>
<java>
<namespace>
<xsl:value-of select="$module-namespace" />
</namespace>
<class>
<xsl:value-of select="concat('org.expath.exist.', $eXist-main-class-name)" />
</class>
</java>
</package>
</xsl:result-document>
<xsl:result-document href="target/files/cxan.xml">
<package xmlns="http://cxan.org/ns/package" id="{concat('expath-', $module-prefix, '-exist')}" name="http://expath.org/lib/{$module-prefix}"
version="{$module-version}">
<author id="{$author/element()/@id}">
<xsl:value-of select="$author" />
</author>
<category id="libs">Libraries</category>
<category id="exist">eXist extensions</category>
<tag>
<xsl:value-of select="$module-prefix" />
</tag>
<tag>expath</tag>
<tag>library</tag>
<tag>exist</tag>
</package>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
Sample XQuery Script
editAcknowledgements
editThe Apache Ant target and the XSLT script were provided by Claudius Teodorescu.