# 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 major ontology APIs (OWL API and Jena, soon SKOS API).

## 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`
  simply describes an ontology. No assumption is made about the fact that the ontology has been loaded. Its entities may be identified by simple URIs.
`LoadedOntology`
  describes an ontology that has been loaded in main memory. Thus, an implementation of this class is bound to an ontology API. However, the connection with the API is very limited: it is possible to know the type of entity (class, property, etc.) and its names and comments. This does not put burden on developers when connecting an API and this applies to "lightweight" ontologies such as unstructured thesauri.
`HeavyLoadedOntology`
  is supposed to offer broad access to the ontology by obtaining the relations between entities (super-classes, properties, etc.).

These three interfaces extend each others so that the `Ontology` interface is the minimal one.

Switching implementations of the API is obtained through:

OntologyFactory.setDefaultFactory("fr.inrialpes.exmo.ontowrap.owlapi30.OWLAPI3OntologyFactory");
and then ontologies can be loaded through:
Ontology o = OntologyFactory.getFactory().loadOntology(new URI(...));
There is a built-in caching mechanism which attempts at avoiding loading twice the same ontology under the same implementation.

## `Ontology`

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

`public URI getURI();
public void setURI( URI uri );`
  Provide the URI identifying the ontology.
`public URI getFile();
public void setFile( URI file );`
  Provide the URL from where the ontology can be loaded.
`public URI getFormURI(); public void setFormURI( URI u );`
  Provide the URI identifying the knowledge representation formalism (may be null).
`public String getFormalism();
public void setFormalism( String name );`
  Provide a String indicating the knowledge representation formalism ("OWL", "SKOS", etc.; may be null).
`public O getOntology();
public void setOntology( O o );`
  Provides the ontology object itself when it has been loaded.

## `LoadedOntology`

`LoadedOntology` extends `Ontology` and provides a minimal interface to the content of the ontologies. This interface is made of two main parts:

- One part dealing with the various types of objects in the ontology (classes, properties, instances, etc.). It only deals with locally defined and named entities.
- One part dealing with their names and the annotations they are assigned.

`public int nbEntities();
public int nbClasses();
public int nbProperties();
public int nbDataProperties();
public int nbObjectProperties();
public int nbIndividuals();
`
  Provide the number of corresponding entities defined in the ontology.
`public Set<? extends Object> getEntities();
public Set<? extends Object> getClasses();
public Set<? extends Object> getProperties();
public Set<? extends Object> getObjectProperties();
public Set<? extends Object> getDataProperties();
public Set<? extends Object> getIndividuals();
`
  Provide the sets of corresponding entities defined in the ontology.
`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 );
`
  Tell if a particular object is of the corresponding type in the ontology.
`public String getEntityName( Object o, String lang ) throws OntowrapException;
public String getEntityName( Object o ) throws OntowrapException;`
  Provide the name of an object in this ontology or its name depending on a particular language. This primitive is not very precise and must be used with caution: some entities may have no names (identified by `rdfs:label` property) and some entities may have several names. In the former case, the interface should try to extract a fragment from the URI of the entity, but it may reveal impossible. Hence the answer would null. In the latter case, which name is returned is unspecified. This primitive is more robust in SKOS terminologies where it is possible to specify a `skos:preferedLabel`.
`public Set<String> getEntityNames( Object o , String lang ) throws OntowrapException;
public Set<String> getEntityNames( Object o ) throws OntowrapException;`
  Provide the names (identified by `rdfs:label` property) of an object in this ontology or its name depending on a particular language.
`public Set<String> getEntityComments( Object o , String lang ) throws OntowrapException;
public Set<String> getEntityComments( Object o ) throws OntowrapException;`
  Provide the comments (identified by `rdfs:comment` property) of an object in this ontology or its comments depending on a particular language.
`public Set<String> getEntityAnnotations( Object o, String lang ) throws OntowrapException;
public Set<String> getEntityAnnotations( Object o ) throws OntowrapException;`
  Provide the annotations (found under `owl:AnnotationProperty`s) of an object in this ontology or its annotations depending on a particular language (when these are available).
`public void unload();`
  Free the memory occupied by this ontology.

## `HeavyLoadedOntology`

`HeavyLoadedOntology` extends `LoadedOntology` and provides an interface to the entities in the ontologies. In particular, it provides informations about relations between these entities.

Unfortunately, various APIs would return different kind of answers to such queries depending on:

- if they consider only entities defined in the ontologies or any entity referenced (`local`);
- if they consider only asserted statements or statements entailed in some way (`asserted`);
- if they consider only named entities or any entities, including anonymous ones (`named`).

In order to unify the behaviour of the APIs, Ontowrap uses the following solution:

- 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:

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 by the implementation.

#### General methods

`public boolean getCapabilities( int Direct, int Asserted, int Named );`
  Tests the capabilities of the ontology implementation.

#### Class methods

`public Set<Object> getSubClasses( Object c, int local, int asserted, int named );`
  Returns the set of subclasses of the specified class.
`public Set<Object> getSuperClasses( Object c, int local, int asserted, int named );`
  Returns the set of superclasses of the specified class.
`public Set<Object> getProperties( Object c, int local, int asserted, int named );`
  Returns the set of properties defined on the specified class.
`public Set<Object> getDataProperties( Object c, int local, int asserted, int named );`
  Returns the set of data properties defined on the specified class.
`public Set<Object> getObjectProperties( Object c, int local, int asserted, int named );`
  Returns the set of object properties defined on the specified class.
`public Set<Object> getInstances( Object c, int local, int asserted, int named );`
  Returns the set of objects belonging to the specified class.

#### Property methods

`public Set<Object> getSubProperties( Object p, int local, int asserted, int named );`
  Returns the set of subproperties of the specified property.
`public Set<Object> getSuperProperties( Object p, int local, int asserted, int named );`
  Returns the set of superproperties of the specified property.
`public Set<Object> getRange( Object p, int asserted );`
  Returns the set of range constraints defined on the specified property.
`public Set<Object> getDomain( Object p, int asserted );`
  Returns the set of domain constraints defined on the specified property.

#### Individual methods

`public Set<Object> getClasses( Object i, int local, int asserted, int named );`
  Returns the set of classes to which the specified individual belongs.

## Implementations

Here are the available implementations:

API | Version | Implementation | Availability | classname
Jena | 2.5 | LoadedOntology | Since 3.5 | `ow.jena25.JENAOntologyFactory`
Jena | 2.6 | LoadedOntology | Since 4.0 | `ow.jena25.JENAOntologyFactory`
OWL API | 1.0 | HeavyLoadedOntology | Since /3.5 | `ow.owlapi10.OWLAPIOntologyFactory`
OWL API | 2.0 | HeavyLoadedOntology | Discontinued (3.4-3.6) | `ow.owlapi20.OWLAPIOntologyFactory`
OWL API | 3.0 | HeavyLoadedOntology | Since 4.0 | `ow.owlapi30.OWLAPI3OntologyFactory`
SKOS API |  | LoadedOntology | In progress (4.x) | ``

`ow` stands for `fr.inrialpes.exmo.ontowrap`.

## Miscellaneous

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).