A XOE package is a container for various types of extensions for the XOE Framework. The package is a file archive in JAR format, containing a description file (package.xml) and other files. The other files will be specific to the package you are creating.
The XOE core contains several "Installer Services". These services are responsible for installing the various parts of a XOE package. The core installers include:
In addition to these core installers, additional Installer Services can themselves be installed from XOE packages.
As a package is installed, it will be processed by all the available Installer Services. In other words, a single package may contain any combination of classes, native libraries, tag-bindings, etc...
The information inside a package description is used for three general purposes:
Every package has a name and a version. If the package is built for a specific architecture, the name must end in "-native". In this case, the package also has an architecture attribute (eg, "i386" or "arm").
The name, version, and architecture of a package make up the Package URI. If two packages have the same URI, they are assumed to be identical.
Inside a package description, a package maintainer may specify dependencies on other packages. A dependency may specify a specific package or a type of package. No package may be installed if any of its dependencies are not met.
Likewise, a package may contain conflicts. No package may be installed if it conflicts with another installed package.
Dependencies and Conflicts are matched by Provisos. A proviso specifies some outward characteristic of a package. All packages have at least one proviso that specifies the name, version, and architecture (for native packages) of the package. Packages that contain services will contain a proviso for each service they install.
This means, for example, that it's possible to depend on a specific package name, a specific version of a specific package, or a range of versions. It's also possible to depend on a certain type of service (eg, a protocol handler for Gopher)
Packages may also contain information meant to be read by users. This should describe, in a human language, what the package provides. Examples of the types of information you can include here:
In addition, a package can have an optional "task" attribute. If set to true, the package will be presented to the user in "basic" searches. If it is unset, or set to false, the package will only be available in advanced searches. This can be used to "hide" packages that the user should never manually install. For example, there's no reason to install libhttps-native or by itself (without libhttps). Several other packages are necessary in order to make these packages useful. The solution is to create a "task-https" package. This package contains dependencies on libhttps, libhttps-native, libssl-native, and default-certificates (which contains the X509 certificates for Verisign, etc..). "task-https" has a task='true' attribute, all the other packages are task='false'. When the user enters the keyword "https", they will only see the task-https package, yet installing it will automatically install all the other packages.
This is an example package description file.
<?xml version="1.0"?> <!-- $tvt: packaging.html,v 1.1 2001/10/16 20:47:06 erik Exp $ --> <!DOCTYPE package PUBLIC "-//TVT//DTD XOEPKG 1.0//EN" "http://www.xoe.org/DTD/xoe-package.dtd"> <package name="libmp3-native" version="0.1"> <info> <name>Native MP3 playback library</name> <description> Native code for MP3 audio playback. Install this package if you want to be able to play MP3s on your device. These libraries are based on libmad which will also be installed if you select this package. </description> <homepage>http://www.xoe.org/packages/libmp3-native</homepage> <maintainer> <name>Sam Clegg</name> <email>samc@transvirtual.com</email> </maintainer> <copyright> <year>2001</year> <holder>Transvirtual Technologies Inc.</holder> <email>info@transvirtual.com</email> </copyright> <licence type="open" common="GPL" /> </info> <requires> <dep name="libmad-native" predepends="true" ns='http://www.xoe.org/installer/base/package' /> </requires> </package> |
Notice that the package description contains four parts: <info />, <provides />, <requires />, and <conflicts />. In addition there are several attributes that go directly on the top-level <package /> element.
The package tag has two mandatory attributes, and one optional attribute.
If task is set to true, the package will be shown in 'basic' queries. The default is false.
The info section contains information meant to be read by the user. Types of information include:
...
This section can contain multiple 'dep' elements. Each element specifies a dependency on another package. The dep element has two mandatory attributes and one optional attribute. Depending on the type of dependency there may be more optional attributes and optional child elements.
The ns specifies the type of dependency. Dependency types include Package Dependencies (a named package, with an optional range of versions) and Service Dependencies (a service supplying some functionality). Custom dependency types may be implemented by custom package installers but your package must depend (directly or indirectly) on the package supplying the custom installer.
The name has a different meaning depending on the type of dependency.
If set to 'true', the dependency is a predependency. If package A predepends on package B, package B must be _completely_ installed before package A is installed. Otherwise, the order of installation is arbitrary (package A might be installed first, but the operation will not complete until package B is installed). The default is 'false'.
At build time, each dependency will be expanded by the appropriate Installer module. This includes creating an XPath representation of the dependency. The XPath will match any package description containing the appropriate proviso.
...
In order to create a XOE package, you must start with source directory. This directory should contain:
The package build process contains several steps:
If a 'rules' file is included in the package source directory, the 'configure' and 'build' targets will be executed.
The first step is to locate all the packages that are required in order to build this package. For every dependency specified in package-in.xml the build system will locate a matching package on the local system. Each of these packages will then be added to the classpath that will be used to compile the java files.
Any files that are to be included in the package (ie *.so files) should be copied to the directory named by the environment variable BUILD.
If the package source directory contains a directory named 'resources', it will be included in the package. All 'CVS' directories will be automatically ignored.
At this point, an intermediate XOE package is created. It includes all the files that will be in the final package, but the package description is incomplete.
At this point, the build system will create several default dependencies, and expand the ones that already exist to include xpaths. If the package is native, an 'architecture' attribute will be added to the <package /> tag to indicate the architecture that the package was built for. In addition, native packages include an architecture dependency that is met only by the appropriate 'architecture-native' package (ie, 'architecture-native_i386_0.1.xoe').
After expansion the complete package is zipped up into a jar file named '<package-name>_<arch>_<version>.xoe'. If the package is not native, the architecture is not included.
When package is installed, every available Installer Service is given an opportunity to process the package. This section describes the operations performed by each of the core installers. In the descriptions, the term "target package" refers to the package that is being installed.
Namespace | http://www.xoe.org/installer/class |
The class installer creates a dedicated classloader for the target package loads all included class files. The target package's dependencies are processed and classloader links created to any package that matches one or more of the dependencies. This allows the target package to refer by name to any class included in a package it depends on.
In addition, the Class Installer will check the currently installed packages to see if they have a dependency that is matched by the target package. If so, it will create a classloader link between that package and the target package.
Namespace | http://xoe.org/installer/resource |
The resource installer copies any resource files (those included in
the 'resources/' subdirectory of the package archive) into the package's
Stash directory (typically stash:/installed-packages/
The resource installer will also process the file 'shortcuts.xml' if it finds it in the package's resources. The shortcuts file has the following structure:
<shortcuts> <lnk file="some-package-resource.file" shortcut="ShortcutName"/> ... </shortcuts> |
Each <lnk /> element requests a shortcut to be made to the specified package resource file. The shortcut will have the specified name plus the extension '.lnk'. It will be created inside the Stash application directory (currently 'stash:/home/default/apps'). The 'shortcut' attribute may specify subdirectories relative to the application directory. If those directories don't exist they will be created.
When the package is uninstalled all resources and shortcuts will be removed.
Namespace | http://www.xoe.org/installer/binding |
Tag bindings map a (namespace qualified) XML tag name to a java class. The class should be a subclass of com.pocketlinux.dom.BaseElement. When XML files are parsed into DOM trees by XOE, the specified class will be instantiated to represent any elements with the matching name and namespace. The installer looks for a file named 'bindings.xml' in the target package's resources. The file has the following structure:
<bindings> <space xmlns="http://www.w3.org/1999/xhtml"> <default class="org.xoe.display.dom.Unknown"/> <bind tag="body" class="org.xoe.display.dom.xhtml.Emphasis"/> <bind tag="head" class="org.xoe.display.dom.Ignore"/> ... </space> </bindings> |
The 'default' tag specifies a class to be used for any tag that is not specifically mentioned in a 'bind' tag. Each 'bind' tag maps a tag to a class. The class must be defined in the same package. The namespace of the 'bind'/'default' tag is the one used to qualify the tag name that is specified. The most convenient way to specify the namespace is on the parent 'space' tag (thus applying it to all children). Tag bindings are automatically unregistered when the package is uninstalled. If multiple packages register bindings for the same fully qualified tag name, the most recent one takes precedence. If that package is uninstalled, the most recent one prior to that takes effect.
Namespace | http://www.xoe.org/installer/mimetype/mappings |
...
Namespace | http://www.xoe.org/installer/native |
...
Namespace | http://www.xoe.org/installer/service |
...
Provisos describe the features provided by a package. They consist of a < proviso /> element with two attributes that specify the type of proviso, and possible child elements (depending on the type of proviso).
Dependencies specify a package that must be installed in order for the package they are found in to be installed. Dependencies need not specify a package by name - they can match any information included in the package description. Usually this information is included inside a proviso.
To create a dependency on another package, you can write a 'friendly' dependency. This dependency contains all the relevant information in a relatively simple XML structure. When you build your package, the 'friendly' dependency will be expanded to include an XPath. This XPath expression is what is actually used to search for matching packages.
In order to expand the dependency, the package build system must have access to the Package Installer Service that knows about that type of dependency. If the installer is not part of the core, you must make sure that your package depends on the package that includes the installer.
In this section, all of the core dependency types that may be explicitly specified in a package are discussed. There are other dependencies that may be added implicitly by the build system, however they are not discussed here.
An explicit dependency on a named package. An optional version (or version range) may be specified.
<!-- Depends on version 1.2 of a package named 'some-pkg' --> <dep name='some-pkg' ns='http://www.xoe.org/installer/base/package'> <version> 1.2 </version> </dep> <!-- Depends on version 1.0 or greater of a package named 'foosball' --> <dep name='foosball' ns='http://www.xoe.org/installer/base/package'> <minimum-version> 1.0 </minimum-version> </dep> <!-- Depends on a package named 'table-tennis'. 1.3 < Version <= 1.7 --> <dep name='table-tennis' ns='http://www.xoe.org/installer/base/package'> <!-- the default for 'inclusive' is true --> <minimum-version inclusive='false'> 1.3 </minimum-version> <maximum-version inclusive='true'> 1.7 </maximum-version> </dep> |
Depend on a package that includes a service. Specify the service using a combination of functionality, interface, and features.
<!-- Depends on having an HTTPS protocol handler --> <dep name='protocolhandler' ns='http://www.xoe.org/installer/service'> <functionality>protocolhandler</functionality> <feature name='protocol' value='https'/> </dep> |