Property provider API

Availability

[SINCE Orbeon Forms 2025.1]

Rationale

Orbeon Forms allows configuration through properties, which are typically defined in XML files, including the user-configurable properties-local.xml.

This Java API allows adding custom property providers to supply property values from alternative sources or through custom logic. Use cases include:

  • providing configurations stored in a database

  • providing passwords or keys from a secure vault or Key Management System (KMS)

  • providing preferences linked to a user profile

  • providing properties for a particular tenant in a multi-tenant setup

Architecture

Provider interface

You can provide one or more custom property providers by implementing the org.orbeon.properties.api.PropertyProvider interface. Your implementation is responsible for:

  • checking the passed parameters to handle caching

  • returning a list of properties when needed

At runtime, during a given request, Orbeon Forms queries each registered property providers in order of priority to obtain current properties, and merges the results. In order to make the process efficient, caching is supported.

Caching

The idea of caching is fairly simple, and similar to HTTP caching:

  • a property provider implementation can provide a cache key which identifies the current set of properties

    • in many cases, no cache key is needed if properties are shared amongst users

    • for use cases such as user preferences, a cache key can represent the user identity

    • for multi-tenant setups, a cache key can represent the tenant identity

  • for a given cache key, the provider implementation must return an ETag, which identifies the current version of the properties for that cache key

    • if the properties change, the ETag must also change

    • if the properties do not change, the ETag must remain the same

  • Orbeon Forms calls the provider implementation with the cache key and the last known ETag

    • if the ETag matches the current ETag for that cache key, the provider implementation indicates that properties have not changed

    • if the ETag does not match the current ETag for that cache key, the provider implementation must return the current list of properties

Orbeon Forms creates its own internal data structures to represent properties. However, the provider implementation must return properties using the PropertyDefinition interface.

Context

For providers which depend on the current request context, information is passed to the provider implementation:

  • the current user's credentials (if any)

  • the current session (if any)

  • the current request (if any)

In addition, a provider could use information stored into a ThreadLocal variable by earlier code in the request processing chain, for example to identify the current tenant in a multi-tenant setup. See also the Connection context API.

API

Java interface

The following describes the Java interface you need to implement:

Note that in many cases, only getPropertiesIfNeeded() needs to be implemented, as getCacheKey() has a default implementation which returns an empty Optional. Also, several of the parameters to getPropertiesIfNeeded() might not be needed. However, eTag is a major component of the caching mechanism, so it must be handled properly.

In addition, the following context interfaces are provided to give access to information about the current request:

A provider implementation must not implement these interfaces: instead, they are meant for consumption by your property provider implementation. Orbeon Forms may extend these interfaces with additional methods in the future.

Registering a provider

The connection context API uses the standard Java ServiceLoader API with a provider name of org.orbeon.properties.api.PropertyProvider.

The provider must:

  • be a public class

  • have a public no-arguments constructor

  • implement the PropertyProvider Java interface

To enable a provider with Orbeon Forms:

  • create your provider as per the standard Java ServiceLoader

  • create a JAR file containing the code or your provider

  • place your JAR file under the Orbeon Forms WEB-INF/lib directory

The Orbeon Forms log files will log errors if any when starting if the provider was found but could not be instantiated.

For example, implement an instance of the interface above, and register it with Orbeon Forms by adding a file called:

The file contains a single line with the fully-qualified name of the implementation class, for example:

This file and directory hierarchy are placed within the web application in a JAR file under WEB-INF/lib.

Enabling and priority of providers

Providers must be explicitly enabled to be used by Orbeon Forms to be used. In addition, when multiple providers are registered, their priority must be specified. Both of these functions are achieved using the following property:

Each space-separated token is a regular expression matching the fully-qualified class name of a provider.

NOTE: If you use a fully-qualified class name, such as org.acme.MyPropertyProvider, keep in mind that . in a regular expression matches any character. Use \. or [.] to explicitly match a period. In general, this is not a problem, as it is unlikely that there are two providers in the classpath differing only by these characters.

  • matching

    • providers must be listed in order to be used; providers that are not matched are ignored

    • a regular expression may match no provider, in which case it has no effect

  • order

    • the leftmost providers have the highest priority

    • the rightmost providers have the lowest priority

Orbeon Forms includes a standard provider which has the lowest priority and is always included. This provider reads your properties-local.xml file and other built-in Orbeon Forms property files (which you generally do not directly deal with). Some properties are always checked in the standard Orbeon Forms property provider, including:

  • oxf.properties.providers.classnames

  • oxf.xforms.cache.provider

  • oxf.xforms.store.provider

See also

Last updated