Changes

Jump to navigation Jump to search
7,618 bytes added ,  17:39, 1 December 2023
m
Text replacement - "syntaxhighlight" to "pre"
This article is part of the [[XQuery|XQuery Portal]].
It shows describes how to add external packages to BaseX, usingXQuery modules and Java code can be installedin the [http://expath.org/modules/pkg/ EXPath Packaging API]XQuery module repository, and how new packages are built and deployed.
==Introduction==
The functionality One of an XQuery processor can be extended with a variety the things that makes languages successful is the availability of external libraries. ThisAs XQuery comes with only 150 pre-defined functions, howeverwhich cannot meet all requirements, becomes often a difficult task additional library modules exist – such as there is no common defined installation process and different libraries comply with different rules[http://www.functx. EXPath addresses this problem by creating a generic mechanism for extending an XQuery processor com/ FunctX] – which extend the language with packagesnew features.
BaseX offers an implementation of this mechanism based on the [http://expath.org/following mechanisms to make external modules/pkg/ specification] created by [httpaccessible to the XQuery processor://expath.org/ EXPath]. A package is a .xar archive encapsulating one or more extension libraries. The implementation of BaseX currently supports extensions with XQuery libraries and java libraries packed as .jar files.
==Package Repository==# The internal [[#Packaging|Packaging]] mechanism will install single XQuery and JAR modules in the repository.# The [[#EXPath Packaging|EXPath Packaging]] system provides a generic mechanism for adding XQuery modules to query processors. A package is defined as a {{Code|.xar}} archive, which encapsulates one or more extension libraries.
Unzipped packages are stored in the package repository. This is a directory named <code>BaseXRepo</code>, which is located in your home folder. Depending on your [[Configuration]], the name and location of your repository might vary.==Accessing Modules==
BaseX provides three commands for interaction Library modules can be imported with the package repository – {{MonoCode|REPO INSTALLimport module}}statement, {{Mono|REPO DELETE}} followed by a freely choosable prefix and {{Mono|REPO LIST}}the namespace of the target module. The syntax of these commands specified location may be absolute or relative; in the latter case, it is described in [[Commands]]resolved against the location (i. Since {{Mark|Version 7e.1}}, ''static base URI'') of the calling module. Import module statements must be placed at the beginning of a [[Repository Module]] exists, which can be used to install new packages via XQuery.module:
Here we give simple examples of their usage and the usage of a package after it is installed'''Main Module''' <code>hello-universe.xq</code>:
<pre lang='xquery'>import module namespace m ='http://basex.org/modules/hello' at 'hello-world.xqm';m:hello("Universe")</pre> '''Library Module''' <code>hello-world.xqm</code> (in the same directory): <pre lang=Installing 'xquery'>module namespace m = 'http://basex.org/modules/Hello';declare function m:hello($world) { 'Hello ' || $world};</pre> If no location is supplied, modules will be looked up in the repository. Repository modules are stored in the {{Code|repo}} directory, which resides in your [[Configuration#Home Directory|home directory]]. XQuery modules can be manually copied to the repository directory or installed and deleted via [[#Commands|commands]]. The following example calls a function from the FunctX module in the repository: <pre lang='xquery'>import module namespace functx = 'http://www.functx.com';functx:capitalize-first('test')</pre> =Commands= There are various ways to organize your packages: * Execute BaseX REPO commands (listed below)* Call XQuery functions of the [[Repository Module]]* Use the GUI (''Options'' → ''Packages'') You can even manually add and remove packages in the repository directory; all changes will automatically be detected by BaseX. ==Installation== A module or package can be installed with {{Command|REPO INSTALL}}. The path to the file has to be given as a parameter:  REPO INSTALL https://files.basex.org/modules/expath/functx-1.0.xar REPO INSTALL hello-world.xqm The installation will only succeed if the specified file conforms to the constraints described below. If you know that your input is valid, you may as well copy the files directly to the repository directory, or edit its contents in the repository without deleting and reinstalling them. ==Listing== All currently installed packages can be listed with {{Command|REPO LIST}}. The names of all packages are listed, along with their version, their package type, and the repository path:  Name Version Type Path ----------------------------------------------------------------- <nowiki>http://www.functx.com</nowiki> 1.0 EXPath http-www.functx.com-1.0 ==Removal== A package can be deleted with {{Command|REPO DELETE}} and an additional argument, containing its name or the name suffixed with a hyphen and the package version:  REPO DELETE <nowiki>http://www.functx.com</nowiki> REPO DELETE <nowiki>http://www.functx.com-1.0</nowiki> =Packaging= ==XQuery== If an XQuery file is specified as input for the install command, it will be parsed as XQuery library module. If the file can successfully be parsed, the module URI will be [[Java Bindings#URI Rewriting|rewritten]] to a Packagefile path and attached with the {{Code|.xqm}} file suffix, and the original file will possibly be renamed and copied to that path into the repository. '''Example:''' Installation (the original file will be copied to the {{Code|org/basex/modules/Hello}} subdirectory of the repository):  REPO INSTALL https://files.basex.org/modules/org/basex/modules/Hello/HelloWorld.xqm Importing the repository module: <pre lang='xquery'>import module namespace m = 'http://basex.org/modules/Hello';m:hello("Universe")</pre> ==Java== For general notes on importing Java classes, please read the Java Bindings article on [[Java Bindings#Module_Imports|Module Imports]]. Java archives (JARs) may contain one or more class files. One of them will be chosen as main class, which must be specified in a {{Code|Main-Class}} entry in the manifest file ({{Code|META-INF/MANIFEST.MF}}). This fully qualified Java class name will be rewritten to a file path by replacing the dots with slashes and attaching the {{Code|.jar}} file suffix, and the original file will be renamed and copied to that path into the repository. If the class will be imported in the prolog of the XQuery module, an instance of it will be created, and its public functions can then be addressed from XQuery. A class may extend the {{Code|QueryModule}} class to get access to the current query context and to be enriched by some helpful annotations (see [[Java_Bindings#Annotations|Annotations]]). '''Example:''' Structure of the <code>[https://files.basex.org/modules/org/basex/modules/Hello/HelloWorld.jar HelloWorld.jar]</code> archive:  META-INF/ MANIFEST.MF org/basex/modules/ Hello.class Contents of the file {{Code|MANIFEST.mf}} (the whitespaces are obligatory):  Manifest-Version: 1.0 Main-Class: org.basex.modules.Hello Contents of the file {{Code|Hello.java}} (comments removed): <pre lang="java">package org.basex.modules;public class Hello { public String hello(final String world) { return "Hello " + world; }}</pre>
A package can Installation (the file will be installed using the copied to {{MonoCode|REPO INSTALLorg/basex/modules/Hello.jar}} command. The path to the package has to be given as a parameter. An example):
{{Mono| REPO INSTALL http://filesHelloWorld.basex.org/xar/functx-1.0.xar}}jar
===Using a Package===XQuery file <code>[https://files.basex.org/modules/org/basex/modules/Hello/HelloUniverse.xq HelloUniverse.xq]</code> (same as above):
The functionality offered by an already installed package can be used by a module <pre lang='xquery'>import. Since we have the package repository where all packages reside, it is not needed to indicate the exact place of the module you want to usenamespace m = 'http://basex. It is enough to just import its namespaceorg/modules/Hello';m:hello("Universe")</pre>
<pre class="brush:xquery">After having installed the module, all of the following URIs can be used in XQuery to import this module namespace functx="httpor call its functions (see [[Java Bindings#URI Rewriting|URI Rewriting]] for more information)://www.functx.com";</pre>
At "seeing" this statement BaseX will check if the namespace " <nowiki>http://wwwbasex.functxorg/modules/Hello</nowiki> org/basex/modules/Hello org.basex.com" is used in some of the installed packages and if yes, it will load their modules. After that you can call the functions from a module in the standard way, e.g:Hello
<pre class="brush:xquery">functx:capitalize-first("test")</pre>==Additional Libraries===
If you want to use A Java class may depend on additional libraries. The dependencies can be resolved by creating a package which encapsulates jar fat JAR file, i.e., extracting all files, you will have to import in the same way the namespace of the module which wraps the java methods library archives and call the XQuery wrapper functions for these methodsproducing a single, flat JAR package.
===Deleting Another solution is to copy the libraries into a Package==={{Code|lib}} directory of the JAR package. When the package is installed, the additional library archives will be extracted and copied to a hidden subdirectory in the repository. If the package is deleted, the hidden subdirectory will be removed as well.
A package can be deleted either by its name or by the name ; Examplary contents of its directory. This can be done with the command REPO DELETE. e.g{{Code|Image.jar}}
{{Mono|REPO DELETE http: lib/ Images.jar META-INF/www MANIFEST.functxMF org/basex/modules/ Image.com}}class
or; Directory structure of the repository directory after installing the package
{{Mono|REPO DELETE functx-1 org/basex/modules/ Image.0}}class .Images/ Images.jar
===Listing installed packages=Combined==
All currently installed packages can be listed using the <code>REPO LIST</code> command. It will list makes sense to combine the names advantages of all XQuery and Java packages which currently reside in the repository along with their versions:
* Instead of directly calling Java code, a wrapper module can be provided. This module contains functions that invoke the Java functions.* These functions can be strictly typed. This reduces the danger of erroneous or unexpected conversions between XQuery and Java code.* In addition, the entry functions can have properly maintained XQuery comments. XQuery and Java can be combined as follows: * First, a JAR package is created (as described above).* A new XQuery wrapper module is created, which is named identically to the Java main class.* The URL of the {{Code|import module}} statement in the wrapper module must start with the {{Code|java:}} prefix.* The finalized XQuery module must be copied into the JAR file, and placed in the same directory as the Java main class. If the resulting JAR file is installed, the embedded XQuery module will be extracted, and will be called first if the module will be imported. ; Main Module {{Code|hello-universe.xq}}: <pre lang='xquery'>import module namespace m = 'http://basex.org/modules/Hello';m:hello("Universe")</pre>URI Version Directory-------------------------------------------------------; Wrapper Module {{Code|Hello.xqm}}: <pre lang='xquery'>module namespace hello = 'http://wwwbasex.functxorg/modules/Hello'; (: Import JAR file :)import module namespace java = 'java:org.com 1basex.0 http-www.functx.com-1modules.0Hello';
1 package(s:~ : Say hello to someone. : @param $world the one to be greeted : @return welcome string :)declare function hello:hello( $world as xs:string) as xs:string { java:hello($world).};
</pre>
==Structure==; Java class {{Code|Hello.java}}:
<pre lang="java">package org.basex.modules; public class Hello { public String hello(final String world) { return "Hello " + world; }}</pre> If the JAR file is installed, {{Code|Combined}} will be displayed as type:  REPO INSTALL https://files.basex.org/modules/org/basex/modules/Hello.jar REPO LIST Name Version Type Path ----------------------------------------------------------------------- org.basex.modules.Hello - Combined org/basex/modules/Hello.xqm =EXPath Packaging= The [http://expath.org/spec/pkg EXPath specification] defines how the structure of a .xar archive shall look like. The package contains at its root a package descriptor named <code>expath-pkg.xml</code>. This descriptor presents some meta data metadata about the package as well as the libraries which it contains and their dependencies on other libraries or processors.  ==XQuery== Apart from the package descriptor , a {{Code|.xar }} archive contains a directory which includes the actual XQuery librariesmodules. For example , the [httphttps://wwwfiles.basex.org/modules/expath/functx-1.0.com/ xar FunctX XQuery LibraryXAR archive] is packaged as follows:
<pre>
</pre>
In case you want to extend BaseX with a ==Java archive, some additional requirements have to be fulfilled:==
* Apart from the If you want to package descriptor <an EXPath archive with Java code>expath-pkg.xml</code> the package has to contain at its root a descriptor defining the included jars and the binary names of the public classes from them. It has , some additional requirements have to be named <code>basex.xml</code> and has to have the following structurefulfilled:
* Apart from the package descriptor <code>expath-pkg.xml</code>, the package has to contain a descriptor file at its root, defining the included jars and the binary names of their public classes. It must be named <code>basex.xml</code> and must conform to the following structure: <pre classlang="brush:xml">
<package xmlns="http://expath.org/ns/pkg">
<jar>...</jar>
* The jar file itself along with an XQuery file defining wrapper functions around the java methods has to reside in the module directory. The following example illustrates how java methods are wrapped with XQuery functions:
'''Example:'''<br>Suppose we have a simple class <code>Printer</code> having just one public method <code>print()</code>:
Suppose we have a simple class <code>Printer</code> having just one public method <code>print()</code>: <pre classlang="brush:java">
package test;
We want to extend BaseX with this class and use its method. In order to make this possible we have to define an XQuery function which wraps the <code>print</code> method of our class. This can be done in the following way:
<pre classlang="brush:'xquery"'>
import module namespace j="http://basex.org/lib/testJar";
</pre>
As it can be seen, the class {{MonoCode|Printer}} is declared with its binary name as a namespace prefixed with "java" and the XQuery function is implemented using the [http://docs.basex.org/wiki/Java_Bindings Java Bindings] offered by BaseX. On our [https://files.basex.org/modules/ file server], you can find some example libraries packaged as XML archives (xar files). You can use them to try our packaging API or just as a reference for creating your own packages. =Performance= Importing XQuery modules that are located in the repository is just as fast as importing any other modules. Modules that are imported several times in a project will only be compiled once. Imported Java archives will be dynamically added to the classpath and unregistered after query execution. This requires some constant overhead and may lead to unexpected effects in scenarios with highly concurrent read operations. If you want to get optimal performance, it is recommendable to move your JAR files into the {{Code|lib/custom}} directory of BaseX. This way, the archive will be added to the classpath if BaseX is started. If you have installed a [[#Combined|Combined Package]], you can simply keep your XQuery module in the repository, and the Java classes will be automatically detected. =Changelog= ;Version 9.0 * Added: [[#Combined|Combined]] XQuery and Java packages* Added: [[#Additional Libraries|Additional Libraries]] ;Version 7.2.1 * Updated: [[#Installation|Installation]]: existing packages will be replaced without raising an error* Updated: [[#Removal|Removal]]: remove specific version of a package ;Version 7.1 * Added: [[Repository Module]] ;Version 7.0
* Added: [[http://files.basex.org/xar/ Here#EXPath Packaging|EXPath Packaging]] you can find the FunctX library packaged as a .xar and a sample package containing a .jar file. You can use them to try our packaging API or just as a reference if you want to create your own packages.
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu