Ontowrap: wrapping ontology APIs

There are many different APIs for ontologies. Even if the Alignment API is independent from these APIs, it is often convenient to interact with them. For that purpose, we have designed the ontowrap API which provides a minimal interaction with

The ontowrap architecture

An implementation of ontowrap is a OntologyFactory and an Ontology class. The ontology factory is used for creating a new Ontology object.

The new ontowrap package defines an OntologyFactory class that is used for loading ontologies under a particular API. Depending on the used factory, the API will be different and the kind of ontology will be different. The default factory to use is provided to the abstract OntologyFactory class which is always used for loading ontologies.

There are three interfaces for ontologies:

Ontology

Ontology provides a minimal interface to ontologies. It only describes the ontology but nothing from its content.

    public URI getURI();
    public URI getFile();
    public URI getFormURI(); // Can be null
    public String getFormalism(); // Can be null
    public O getOntology();

    public void setURI( URI uri );
    public void setFile( URI file );
    public void setFormURI( URI u );
    public void setFormalism( String name );
    public void setOntology( O o );

LoadedOntology

LoadedOntology

    public boolean isEntity( Object o );
    public boolean isClass( Object o );
    public boolean isProperty( Object o );
    public boolean isDataProperty( Object o );
    public boolean isObjectProperty( Object o );
    public boolean isIndividual( Object o );

    public Set getEntities();
    public Set getClasses();
    public Set getProperties();
    public Set getObjectProperties();
    public Set getDataProperties();
    public Set getIndividuals();

    public int nbEntities();
    public int nbClasses();
    public int nbProperties();
    public int nbDataProperties();
    public int nbObjectProperties();
    public int nbIndividuals();

    public void unload();

HeavyLoadedOntology

    /* Capability methods */
    public boolean getCapabilities( int Direct, int Asserted, int Named );

    /* Class methods */
    public Set getSubClasses( Object c, int local, int asserted, int named );
    public Set getSuperClasses( Object c, int local, int asserted, int named );
    public Set getProperties( Object c, int local, int asserted, int named );
    public Set getDataProperties( Object c, int local, int asserted, int named );
    public Set getObjectProperties( Object c, int local, int asserted, int named );
    public Set getInstances( Object c, int local, int asserted, int named  );

    /* Property methods */
    public Set getSubProperties( Object p, int local, int asserted, int named );
    public Set getSuperProperties( Object p, int local, int asserted, int named );
    public Set getRange( Object p, int asserted );
    public Set getDomain( Object p, int asserted );

    /* Individual methods */
    public Set getClasses( Object i, int local, int asserted, int named );


Additional services



Unified interface

The proposed solution goes in two ways:

  • Having only one getSuperClasses( Class ) primitive but appending to it a number of boolean arguments defining if the results should be restricted to named, asserted, local, etc.
  • Having primitives at the factory level expressing the capabilities of the implementation, i.e., if it can deliver inherited super classes.
The idea is that it is possible to invoke the method with particular arguments and the API will try to satisfy it as best as possible. However, it is possible to check beforehand if the API meets the requirements of the application and to raise an exception (or change API) if this is not the case.

Hence, for instance (dummy):

if ( !onto.getCapabilities( OntologyFactory.GLOBAL, OntologyFactory.INHERITED, 0 ) ) {
    throw new AlignementException( onto+" : cannot provide both global and inherited answers");
} else {
    Set<Object> sups = onto.getSuperClasses( class, OntologyFactory.GLOBAL,
                                     OntologyFactory.INHERITED, OntologyFactory.DIRECT );
}
These primitives always answer, but the answers are only correct if the modalities asked in argument are supported.

Of course, similar reasoning must be applied to the other primitives.

Implementations

APIVersionImplementationAvailability
Jena2.5HeavyLoadedOntologySince 3.5
OWL API1.0HeavyLoadedOntologySince /3.5
OWL API2.0HeavyLoadedOntologyDiscontinued (3.4-3.6)
OWL API3.0HeavyLoadedOntologySince 4.0
SKOS APILoadedOntologyIn progress (4.x)

Miscellaneous

The Alignment API was first designed on top of what was the first published OWL API1 (the Manchester/Karlsruhe OWL API). Since it was an API for OWL, I assumed that anybody else would implement it. Too bad, we soon had the Jena API2 and plenty of others3. Instead of implementing a common API (a common set of interfaces like the OWL API), each new player designed its own.

Here are the historical howto notes for starting quickly with OWL-API (Outdated notes about the OWL API and its integration in the Alignment API).

$Id$