Extension Modules - eXist: A NoSQL Document Database and Application Platform (2015)

eXist: A NoSQL Document Database and Application Platform (2015)

Chapter 7. Extension Modules

eXist has a large number of extension modules built in that allow you to do lots of wonderful things that you can’t do with straight XQuery, such as manipulating the database’s content, inspecting an HTTP request, encrypting/decrypting data, and performing XSLT transformations. This chapter will provide you with an overview of the module mechanism in general. An overview of the available modules can be found in Appendix A.

Types of Extension Modules

Extension modules come in two flavors, which you need to be aware of because they behave differently in eXist. The module descriptions in Extension Module Descriptions will tell you the module type. We will also explain how to find out the module type yourself in “Enabling Extension Modules”.

Extension Modules Written in Java

Extension modules written in Java are fully integrated into eXist. You don’t even have to put an import module statement in your XQuery code to be able to use them. Most of the eXist core functionality you use regularly is Java-backed (e.g., xmldb, request, transform,response, and util).

For instance, when you want to find out the eXist home directory by calling system:get-exist-home, you can simply do this in your code without an import module statement for the system module. However, it is generally considered good practice to have this explicitly set out, so you may choose to add, for example:

import module namespace system="http://exist-db.org/xquery/system";

Not all of the available Java modules are enabled by default. Even worse, some of them are not even built in (compiled and linked) to the default eXist configuration! How to find out which are built in and/or enabled, and what to do about it is covered in “Enabling Java Extension Modules”. Writing your own extension modules in Java is covered in “Internal XQuery Library Modules”.

NOTE

If you use eXide, oXygen, or another eXist-aware IDE, there is a very easy way to find out whether a Java-based extension module is enabled. While editing an XQuery script, type the prefix of the module and press the shortcut keys that pop up autocompletion suggestions (usually Ctrl-space bar). If a list of functions appears, the module is enabled.

Extension Modules Written in XQuery

Some extension modules are written in XQuery. To use them, you need to explicitly import the module by placing an import module statement in your XQuery code. You need not specify the at clause because eXist already knows where to find them.

For instance, to use the KWIC (see “Using Keywords in Context”) extension module, you would add the following to your XQuery prolog:

import module namespace kwic="http://exist-db.org/xquery/kwic";

XQuery-based modules can be disabled too. However, in contrast to Java-based modules, this only means eXist doesn’t know their location and you have to add an at clause to your import module statement if you still want to use them. Read more about this in “Enabling XQuery Extension Modules”.

Enabling Extension Modules

This section will tell you how to enable an extension module. There are two files/locations that are important here:

$EXIST_HOME/conf.xml

Search this file for the builtin-modules element. Within you’ll find module elements, some of which are commented out. As you might have guessed, enabling a module here means removing the comment from the appropriate module element (and restarting eXist).

The module elements also show you the type of the module (Java or XQuery). Java modules have a class attribute. For instance:

<module uri="http://exist-db.org/xquery/xmldb"

class="org.exist.xquery.functions.xmldb.XMLDBModule" />

But XQuery modules have a src attribute:

<module uri="http://exist-db.org/xquery/kwic"

src="resource:org/exist/xquery/lib/kwic.xql" />

If there is a resource: prefix it indicates that the module is located within a package inside one of eXist’s JAR files.

$EXIST_HOME/extensions/build.properties

For some Java modules (and some additional features), you have a choice of whether to include them in the eXist build. The default settings for this are in $EXIST_HOME/extensions/build.properties. More information can be found in the next section.

Enabling Java Extension Modules

To use a Java extension module, two conditions must be met:

§ It must be part of the eXist build. You can determine this as follows:

§ Open $EXIST_HOME/extensions/build.properties (this is a text file, not an XML document), and see if the module or feature you want to use is mentioned there. For instance, the memcached extension module has this line:

include.module.memcached = false

§ If your module is not mentioned in build.properties, you don’t have to worry about it being part of the build; that will always be the case.

§ If your module is mentioned in build.properties and its include.module entry is set to true, it will be part of the build.

§ If your module is mentioned in build.properties and its include.module is set to false, it will not be part of the build. To enable it, you will have to change this and rebuild eXist. The following subsection explains how to do this.

§ If you (or somebody else working on the same eXist installation) has already changed some of the settings in build.properties, there will be a local.build.properties file also. Settings in this file override the settings in build.properties, so you have to check this too.

§ It must be enabled in the built-in modules list in $EXIST_HOME/conf.xml. To determine this, do the following:

§ Open $EXIST_HOME/conf.xml and search for the modules list in the builtin-modules element.

§ If the child module element for the module you’re looking for is commented out, the module is disabled. Remove the comment and restart eXist to enable it.

Rebuilding eXist

If you’ve found out that the module you needed was not part of the eXist build because its include.module entry was set to false in $EXIST_HOME/extensions/build.properties, here is how to change it:

1. Install (if it’s not on your system already) the Java SE JDK—that is, the development kit, not the runtime environment. For instructions and downloads, refer to http://www.oracle.com/technetwork/java/javase/overview/index.html.

2. Make sure you have an environment variable called JAVA_HOME pointing to the root directory of your Java installation. If it does not exist, create it.

3. If you haven’t done so before, copy $EXIST_HOME/extensions/build.properties to local.build.properties (in the same directory).

4. Edit local.build.properties and set the include.module entry for the module you want to enable to true (for instance, include.module.xslfo = true).

5. Stop eXist.

6. Open a command window, navigate to $EXIST_HOME, and issue the appropriate build command:

o On Unix-based systems: ./build.sh extension-modules

o On Windows-based systems: build.bat extension-modules

The build will run. If you examine the output you should see some messages scroll by regarding your module.

7. Since eXist is still stopped at this point, enable the corresponding module element in the built-in modules list in $EXIST_HOME/conf.xml now.

8. Restart eXist.

Now the module is enabled. This not only means that you can use its functions from within your XQuery code, but also that it should show up in the eXist function documentation browser (after a regeneration).

Enabling XQuery Extension Modules

An XQuery extension module is not so different from an XQuery module that you could write yourself. The real difference is that the extension modules are a part of the main eXist distribution and are included in one of eXist’s JAR files that is present on the classpath. Paths to a resource on the classpath in $EXIST_HOME/conf.xml are prefixed with resource:, like so:

<module uri="http://exist-db.org/xquery/kwic"

src="resource:org/exist/xquery/lib/kwic.xql" />

The manifest difference between an XQuery extension module provided on the classpath and your own extension modules is that eXist already knows where to find them, so you don’t have to add an at clause to the import module statement when using a provided module. So, to use the kwic module, you can write:

import module namespace kwic="http://exist-db.org/xquery/kwic";

However, if you want to, you can also specify it in full, in which case the built-in modules list in $EXIST_HOME/conf.xml is not even used:

import module namespace kwic="http://exist-db.org/xquery/kwic"

at "resource:org/exist/xquery/lib/kwic.xql";

Specifying an XQuery-based module in the built-in modules list only tells eXist where to find it, nothing more. It actually has nothing to do with enabling or disabling a module, since you can always reference it using an explicit at clause.

By the way, this also means that you can add your own modules to the built-in modules list by specifying their full paths; for example:

<module uri="http://www.mycompany.org/modules/helper"

src="xmldb:exist:///db/myapp/lib/helper.xq" />

However, the advice is not to do this. Keep the built-in modules list for, well, the built-in modules, and don’t litter it with your own stuff, as it will make upgrading in the future more tedious. In any case, changes to the built-in modules list only take effect after a restart.