Contracts and Converters Development
Introduction
The syntax and semantics of PEARL should be as concise and application/domain independent as possible. At the same time, the generation of RDF terms out of UIMA metadata might require complex and, possibly, domain dependent procedures.
PEARL reconciles these seemingly conflicting requirements by delegating to externally defined converters the conversion task associated with each placeholder in the nodes
section. In fact, a PEARL rule should mention converters indirectly by means of the URI denoting the contracts they implement.
Converters are published as OSGi bundles, which can be deployed in the execution enviroment at any time. Indeed, a contract URI should resolve to an RDF document providing information about a contract, including the address of an OBR repository that contains bundles providing concrete implementations. Locally installed bundles advertise the provided converters in the OSGi service registry.
Contract Development
A contract defines a set of assumptions about the behavior of a conforming converter. Concrete converters can implement a contract in any manner, as long as they are consistent with the general behavior prescribed by the contract.
Contract RDF Description
A contract is identified by a URI, which should return (when dereferenced) an RDF description of the contract. The simplest approach to accomplish that goal is to publish an RDF document as a static file, which contains the description of a contract.
The description of a contract should include its name in one or more natural languages (e.g. through the property rdfs:label
), its description (e.g. through the property rdfs:comment
), and a reference to a known OBR repository of implementations. Only the latter is really prescribed by CODA, which designates for this purpose the property http://art.uniroma2.it/coda/ns/authoritativeOBR
.
As an example, let us consider the identity contract, which prescribes that a conforming converter should produce a node that reflects the provided input as is. The first step is to mint a URI for this contract. The easiest approch is mint a hash-URI based on the URI of a Web document. Concretely, we could decide to publish an RDF document at the address http://example.org/coda/contracts.ttl
, and then decide to mint the URI http://example.org/coda/contracts.ttl#identity
for the contract. The semantics is that the description of the resource is found in the document located at the address that is obtained by ignoring everything that follows the hash (#), including the hash. A possible description of the contract expressed in the Turtle syntax looks like the following:
@prefix coda: <http://art.uniroma2.it/coda/ns/> .
@prefix : <http://example.org/coda/contracts.ttl#> .
:identity a coda:Contract ;
rdfs:label "Identity contract" ;
rdfs:comment "A conforming converter should construct an RDF term out of the input value as is"@en ;
coda:authoritativeOBR <http://example.org/coda/repository.xml> .
The URI http://example.org/coda/repository.xml
is the address of the OBR repository file, which references known implementations of the contract. We will se how to create this file at the end of this guide.
Contract Java Implementation
Currently, CODA does not enforce that each contract has a counterpart in the Java runtime (e.g. an interface). However, it is a good practice (an a future-proof decision with respect to the evolution of CODA) to clealry define a Java interface for a contract.
The following is a possible interface for the identity contract:
package org.example.coda.contracts;
import it.uniroma2.art.coda.interfaces.CODAContext;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.model.ARTLiteral;
/**
* A conforming converter should construct
* an RDF term out of the input value as is.
*/
public interface IdentityContract {
ARTURIResource produceURI(CODAContext ctx, String value);
ARTLiteral produceLiteral(CODAContext ctx, String datatype, String lang, String value);
}
In general:
YYY produceURI(CODAContext ctx, String XXX)
is invoked during the conversion a value to a URI. The typeXXX
could be anything: in the example a simplejava.lang.String
. The typeYYY
should beit.uniroma2.art.owlart.model.ARTURIResource
, if the contract is meant to be used at the end of a conversion chain. Otherwise, it could be anything else.YYY produceLiteral(CODAContext ctx, String datatype, String lang, XXX value)
is invoked during the conversion a value to a Literal. The typeXXX
could be anything: in the example a simplejava.lang.String
. The typeYYY
should beit.uniroma2.art.owlart.model.ARTLiteral
, if the contract is meant to be used at the end of a conversion chain. Otherwise, it could be anything else. The parameterlang
anddatatype
represents the language tag and the datatype, respectively. Either can benull
ctx
provides contextual information, such as a reference to the target semantic repository. The interface is provided by the coda framework artifact.
The interface associated with a contract should be deployed as a separate bundle. The only required configuration is that the bundle must export the package containing the interface. The identity contract in fact does not foresee multiple implementations, therefore the interface could be shipped directly with the converter.
Converter development
A converter is a specific implementation of a contract, and it is realized as a Java class. Converters are shipped as OSGi bundles, which must meet the following conditions:
- they must contain the converter class (e.g.
org.example.coda.converters.IdentityConverter
) (the containing package is not required to be exported) - they must eventually publish an instance of the converter in the OSGi service registry
- there must be a file named
obr.xml
in the root of the bundle classpath, providing additional OBR metadata about the bundle
Converter Java Implementation
Continuing our example on the identity contract, we should define the associated converter as a Java class:
package org.example.coda.converters;
import it.uniroma2.art.coda.interfaces.CODAContext;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.model.ARTLiteral;
import org.example.coda.contracts.IdentityContract;
/**
* An implementation of the IdentityContract.
*/
public class IdentityConverter implements IdentityContract {
public ARTURIResource produceURI(CODAContext ctx, String value) {
...
...
}
public ARTLiteral produceLiteral(CODAContext ctx, String datatype, String lang, String value) {
...
...
}
}
The details of the implementation are out of the scope of this guide, which focuses instead on how to make converters available to CODA.
Converter Publication on the Service Registry
The publication of the converter in the service registry may be perfomed in many different ways. If the converter is relatively simple (e.g. it does not depend on other services), then it is possible to publish it using the bundle context, as in the following example.
Properties properties = new Properties();
properties.setProperty("it.uniroma2.art.coda.contract", "http://example.org/coda/contracts.ttl#identity");
context.registerService(IdentityContract.class.getName(), new IdentityConverter(), properties);
Where:
- context is the bundle context
- http://example.org/coda/contracts.ttl#identity is the contract URI
- IdentityContract is the contract interface
- IdentityConverter is the converter class
obr.xml
The file obr.xml
contains additional metadata to be added to the bundle description in the OBR repository. In particular, a bundle providing a converter should declare that it will publish the converter as a service:
<obr>
<capability name='service'>
<p v='org.example.coda.contracts.IdentityContract' n='service' />
<p v='http://example.org/coda/contracts.ttl#identity' n='it.uniroma2.art.coda.contract' />
</capability>
</obr>
Obviously, it is necessary indicate the correct contract interface and URI.
Support Autmatic Provisioning of Converters
The PEARL Execution Engine is able to use any converter published on the OSGi Service Regsitry by a locally active bundle. In other words, CODA can operate completely on locally available bundles, without relying on any metadata on the Web.
However, the Component Discovery may exploit the information provided by the RDF description of a contract URI to support the dynamic provision of converters. In particular, it uses the value of coda:authoritativeOBR
to locate its associated OBR repository.
Publish the Artifacts on the Web
The bundles providing the converters, the contracts and their dependencies (excluded those already provided by CODA) should be made available on the Web.
Construct the OBR Repository
In the simplest deployment, an OBR repository is completely represented as an XML document, which contains the metadata about the resources in the repository. Actually, the connection between a repository and a resource lies in the fact that among other metadata there is also the Web address of the resource. In this context, a resource is more general concept that also includes OSGi bundles.
Provided that Maven is available on the PATH as mvn
, the following steps are sufficient for adding a bundle to an OBR repository.
- unpack the bundle in a folder
- add the metadata of the bundle to the OBR repository
mvn org.apache.felix:maven-bundle-plugin:2.3.7:install-file -Dfile={artifact-file} -DpomFile={unpacked-folder}/META-INF/maven/*/*/pom.xml -DobrXml={unpacked-folder}/obr.xml -DobrRepository={obr-repository}
{artifact-file}
is the path to the bundle{unpacked-folder}
is the path to a folder where the bundle has already been unpacked{obr-repository}
is the path to the (local copy of) the OBR repository
obr.xml
, omit the parameterobrXml
. -
In the
repository.xml
, there should be aresource
element for the newly added bundle. However, it is necessary to change theuri
attribute, with the value of the Web address of the bundle.
Further Material
- Apache Karaf - http://karaf.apache.org/
- OSGi Alliance | Release 4 / Version 4.3 API Javadoc - http://www.osgi.org/Release4/Javadoc43
- Bundle Plugin for Maven - http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
- Apache Felix OSGi Bundle Repository (OBR) - http://karaf.apache.org/
- Sources of the CODA standard converter library - https://bitbucket.org/art-uniroma2/coda/src/7ea7e0c77e5888ac6bd9965d98f46f1038ab3817/coda-converters/?at=master