Difference between revisions of "ProtegeOWL API Programmers Guide"

From Protege Wiki
Jump to: navigation, search
(split section out to separate page ProtegeOWL_API_Basics)
 
(39 intermediate revisions by 2 users not shown)
Line 5: Line 5:
 
- Original Author: [http://www.knublauch.com/ Holger Knublauch]<br />
 
- Original Author: [http://www.knublauch.com/ Holger Knublauch]<br />
 
- Currently maintained by: [http://protege.stanford.edu/aboutus/aboutus.html Protege staff members] (contributions from the user community are welcome)<br />
 
- Currently maintained by: [http://protege.stanford.edu/aboutus/aboutus.html Protege staff members] (contributions from the user community are welcome)<br />
- Last update: May 13, 2010
+
- Last update: June 30, 2010
 
</div>
 
</div>
  
Line 60: Line 60:
  
 
Execute this program stand-alone. The output should be "Class URI: <nowiki>http://hello.com#World</nowiki>".
 
Execute this program stand-alone. The output should be "Class URI: <nowiki>http://hello.com#World</nowiki>".
 +
  
 
== Basics ==
 
== Basics ==
  
=== Working with OWL Models ===
+
''For more details on this topic, see [[ProtegeOWL_API_Basics|Protege-OWL API Basics]]''
  
The Protege-OWL API is centered around a collection of Java interfaces from the '''model''' package. These interfaces provide access to the OWL model and its elements like classes, properties, and individuals. Application developers should not access the implementation of these interfaces (such as '''DefaultRDFIndividual''') directly, but only operate on the interfaces. Using these interfaces you don't have to worry about the internal details of how Protege stores ontologies. Everything is abstracted into interfaces and your code should not make any assumptions about the specific implementation.
+
Covered topics include:
  
The most important model interface is '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/OWLModel.html OWLModel]''', which provides access to the top-level container of the resources in the ontology. You can use OWLModel to create, query, and delete resources of various types and then use the objects returned by the OWLModel to do specific operations. For example, the following snippet creates a new '''OWLNamedClass''' (which corresponds to '''owl:Class''' in OWL), and then gets its URI:
+
* Working with OWL Models
 +
* Names, Namespace prefixes, and URIs
 +
* Understanding the Model Interfaces
 +
* Creating Named Classes and Individuals
 +
* Using Datatype Properties and Datatype Values
 +
* Using Object Properties to Build Relationships between Resources
 +
* Working with References to External/Untyped Resources
 +
* Property Domains
  
<pre>
 
    OWLModel owlModel = ProtegeOWL.createJenaOWLModel();
 
    OWLNamedClass worldClass = owlModel.createOWLNamedClass("World");
 
    System.out.println("Class URI: " + worldClass.getURI());
 
</pre>
 
  
Note that the class '''ProtegeOWL''' provides a couple of convenient static methods to create OWLModels, also from existing OWL files. For example, you can load an existing ontology from the web using
+
== Advanced Class Definitions (OWL DL) ==
  
<pre>
+
''For more details on this topic, see [[ProtegeOWL_API_Advanced_Class_Definitions|Protege-OWL API Advanced Class Definitions (OWL DL)]]''
    String uri = "http://www.co-ode.org/ontologies/pizza/2007/02/12/pizza.owl";
 
    OWLModel owlModel = ProtegeOWL.createJenaOWLModelFromURI(uri);
 
</pre>
 
  
=== Names, Namespace prefixes, and URIs ===
+
Covered topics include:
  
OWL and RDF resources are globally identified by their URIs, such as <nowiki>http://www.owl-ontologies.com/travel.owl#Destination</nowiki>. However, since URIs are long and often inconvenient to handle, the primary access and identification mechanism for ontological resources in the Protege-OWL API is their name. A name is a short form consisting of local name and an optional prefix. Prefixes are typically defined in the ontology to abbreviate names of imported resources. For example, instead of writing <nowiki>http://www.w3.org/2002/07/owl#Class</nowiki>, we can write owl:Class because "owl" is a prefix for the namespace "<nowiki>http://www.w3.org/2002/07/owl#</nowiki>". Similarly, if an ontology imports the travel ontology from above, it can define a prefix to access all imported classes and properties with "travel", e.g. travel:Destination. If we are inside the default namespace of the ontology, the prefix is empty, i.e., the name of the resource is only Destination. Application developers can take control of namespace prefixes using the '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/NamespaceManager.html NamespaceManager]''' object. In order to access the current NamespaceManager of an OWLModel, you can use '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/OWLModel.html#getNamespaceManager() OWLModel.getNamespaceManager()]'''.
+
* Restrictions
Assuming we have loaded the travel ontology as a default namespace, we can access the resources contained in the OWLModel using the following example calls:
+
* Logical Class Definitions (Unions, Intersections, Complements)
 +
* Enumerated Classes
 +
* Creating Defined Classes
  
<pre>
 
    OWLNamedClass destinationClass = owlModel.getOWLNamedClass("Destination");
 
    OWLObjectProperty hasContactProperty = owlModel.getOWLObjectProperty("hasContact");
 
    OWLDatatypeProperty hasZipCodeProperty = owlModel.getOWLDatatypeProperty("hasZipCode");
 
    OWLIndividual sydney = owlModel.getOWLIndividual("Sydney");
 
</pre>
 
  
... and use the objects to perform further queries or operations on the corresponding resources. For example, in order to extract the URI for a named object, you can use the '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFResource.html#getURI() RDFResource.getURI()]''' method.
+
== Advanced Topics ==
  
=== Understanding the Model Interfaces ===
+
''For more details on this topic, see [[ProtegeOWL_API_Advanced_Topics|Protege-OWL API Advanced Topics]]''
  
The interfaces of the model package are arranged in an inheritance hierarchy. An overview of the available interfaces can be found in the [http://protege.stanford.edu/plugins/owl/api/ProtegeOWLModel.pdf API diagram], contributed by [http://www.cs.man.ac.uk/~horridgm/ Matthew Horridge]. (You may want to print this diagram and leave it on your desk while you are using the API.) The base interface of all resources is RDFResource, from which subinterfaces for classes, properties, and individuals are derived:
+
Covered topics include:
  
  [http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFResource.html RDFResource]
+
* Querying the OWLModel
      [http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFSClass.html RDFSClass]
+
* RDF(S) and OWL
      [http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFProperty.html RDFProperty]
+
* Reacting to Changes using Listeners
      [http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFIndividual.html RDFIndividual]
+
* Loading and Saving Files
 +
* Working with Multi-File Projects and TripleStores
 +
* Working with Jena Models
  
'''RDFResource''' defines basic operations for all resources, in particular getting and setting property values. '''RDFProperty''' is the base interface for rdf:Properties and its subtypes owl:DatatypeProperty and owl:ObjectProperty. For classes, the hierarchy gets quite complex because of the various types of anonymous classes in OWL. This will be handled later.
 
  
Here is some example code that creates a simple class, an individual of that class, and then assigns a couple of properties.
+
== Protege Programming ==
  
<pre>
+
''For more details on this topic, see [[ProgrammingWithProtege|Programming with Protege-OWL]]''
    OWLModel owlModel = ProtegeOWL.createJenaOWLModel();
 
  
    OWLNamedClass personClass = owlModel.createOWLNamedClass("Person");
+
Covered topics include:
  
    OWLDatatypeProperty ageProperty = owlModel.createOWLDatatypeProperty("age");
+
* Protege-OWL and the Core Protege API
    ageProperty.setRange(owlModel.getXSDint());
+
* Changes from the old Protege-OWL API
    ageProperty.setDomain(personClass);
+
* Protege User Interface Programming
 +
* Protege Plug-in Development
  
    OWLObjectProperty childrenProperty = owlModel.createOWLObjectProperty("children");
 
    childrenProperty.setRange(personClass);
 
    childrenProperty.setDomain(personClass);
 
  
    RDFIndividual darwin = personClass.createRDFIndividual("Darwin");
+
== Building Semantic Web Applications ==
    darwin.setPropertyValue(ageProperty, new Integer(0));
 
  
    RDFIndividual holgi = personClass.createRDFIndividual("Holger");
+
''For more details on this topic, see [[BuildingSemanticWebApplications|Building Semantic Web Applications]]''
    holgi.setPropertyValue(childrenProperty, darwin);
 
    holgi.setPropertyValue(ageProperty, new Integer(33));
 
</pre>
 
 
 
=== Creating Named Classes and Individuals ===
 
 
 
The Protege-OWL API makes a clear distinction between named classes and anonymous classes. Named classes are used to create individuals, while anonymous classes are used to specify logical characteristics (restrictions) of named classes. We will handle anonymous classes later, but let's look at named classes now.
 
 
 
To reflect the OWL specification, there are two types of named classes: '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFSNamedClass.html RDFSNamedClass]''' (rdfs:Class) and '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/OWLNamedClass.html OWLNamedClass]''' (owl:Class). Unless you are explicitly working in RDF, you will most likely create OWL classes. After you have created the classes, you can arrange them in an subclass relationship:
 
 
 
<pre>
 
    OWLNamedClass personClass = owlModel.createOWLNamedClass("Person");
 
 
 
    // Create subclass (complicated version)
 
    OWLNamedClass brotherClass = owlModel.createOWLNamedClass("Brother");
 
    brotherClass.addSuperclass(personClass);
 
    brotherClass.removeSuperclass(owlModel.getOWLThingClass());
 
</pre>
 
 
 
In this example, the class Brother is created first as a top-level class. The method '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/OWLModel.html#createOWLNamedClass(java.lang.String) OWLModel.createOWLNamedClass(String name)]''' makes new classes by default a subclass of owl:Thing only. Then, Person is added to the superclasses, leading to a situation in which both Person and owl:Thing are parents. Therefore, owl:Thing needs to be removed afterwards.
 
 
 
A much more convenient way of creating a subclass of Person is as follows:
 
 
 
    OWLNamedClass sisterClass = owlModel.createOWLNamedSubclass("Sister", personClass);
 
 
 
The resulting inheritance hierarchy of the code above is:
 
 
 
    Person
 
        Brother
 
        Sister
 
 
 
A simple recursive call can then be used to print arbitrary hierarchies with indentation:
 
 
 
<pre>
 
        printClassTree(personClass, "");
 
    }
 
 
 
    private static void printClassTree(RDFSClass cls, String indentation) {
 
        System.out.println(indentation + cls.getName());
 
        for (Iterator it = cls.getSubclasses(false).iterator(); it.hasNext();) {
 
            RDFSClass subclass = (RDFSClass) it.next();
 
            printClassTree(subclass, indentation + "    ");
 
        }
 
    }
 
</pre>
 
 
 
In the recursive routine, '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFSClass.html#getSubclasses(boolean) RDFSClass.getSubclasses()]''' takes a boolean argument. When set to true, this will return not only the direct subclasses of the current class, but also the subclasses of the subclasses, etc.
 
 
 
Named classes can be used to generate individuals. The instances of a class can then be queried using the '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFSClass.html#getInstances(boolean) RDFSClass.getInstances()]''' method:
 
 
 
<pre>
 
    OWLIndividual individual = brotherClass.createOWLIndividual("Hans");
 
    Collection brothers = brotherClass.getInstances(false);
 
    assert (brothers.contains(hans));
 
    assert (brothers.size() == 1);
 
</pre>
 
 
 
There is a crucial distinction between "direct" and "indirect" instances. The individual Hans is a direct instance of Brother, but not a direct instance of Person. However, it is also an indirect instance of Person, because Brother is a subclass of Person, i.e., every Brother is also a Person. Programmers are able to select whether their calls shall address only the direct or also the indirect instances using a boolean parameter:
 
 
 
<pre>
 
    assert (personClass.getInstanceCount(false) == 0);
 
    assert (personClass.getInstanceCount(true) == 0);
 
    assert (personClass.getInstances(true).contains(hans));
 
</pre>
 
 
 
The inverse query to get the type/class of an individual can be made using the '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFResource.html#getRDFType() RDFResource.getRDFType()]''' family of methods. For example, Hans has the rdf:type Brother, and it also has the (indirect) type Person:
 
 
 
    assert (hans.getRDFType().equals(brotherClass));
 
    assert (hans.hasRDFType(brotherClass));
 
    assert !(hans.hasRDFType(personClass, false));
 
    assert (hans.hasRDFType(personClass, true));
 
 
 
If the life cycle of a resource is over, it can be deleted using the '''RDFResource.delete()''' method. The API uses the same convention as other APIs, where "delete" means to completely destroy the object, whereas "remove" only deletes references to the object. This means that when you call delete on a resource, then all its property values are removed but not deleted.
 
 
 
    hans.delete();
 
 
 
=== Using Datatype Properties and Datatype Values ===
 
 
 
To create an owl:DatatypeProperty, you can use '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/OWLModel.html#createOWLDatatypeProperty(java.lang.String) OWLModel.createOWLDatatypeProperty(String name)]'''. By default, datatype properties can take any datatype value such as strings and integers. OWL defines several XML Schema datatypes that can be used to restrict the range of properties. The most popular XML Schema datatypes are '''xsd:string''', '''xsd:int''', '''xsd:float''', and '''xsd:boolean'''. For example, if you want to limit your property to only take string values, you can restrict its range using:
 
 
 
<pre>
 
    OWLDatatypeProperty property = owlModel.createOWLDatatypeProperty("name");
 
    name.setRange(owlModel.getXSDstring());
 
</pre>
 
 
 
... where the call '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/OWLModel.html#getXSDstring() OWLModel.getXSDstring()]''' returns a reference to the '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFSDatatype.html RDFSDatatype]''' xsd:string. Other default datatypes are accessible using similar '''OWLModel.getXSD...''' methods. More complex datatypes can be accessed using their URI:
 
 
 
    RDFSDatatype dateType = owlModel.getRDFSDatatypeByName("xsd:date");
 
 
 
For the default datatypes, property values are conveniently handled using corresponding Java data types. For example, if you assign property values for a string property, you can simply pass a String object to the '''setPropertyValue''' call. Corresponding mappings exist into other data types:
 
 
 
<pre>
 
    individual.setPropertyValue(stringProperty, "MyString");
 
    individual.setPropertyValue(intProperty, new Integer(42));
 
    individual.setPropertyValue(floatProperty, new Float(4.2));
 
    individual.setPropertyValue(booleanProperty, Boolean.TRUE);
 
</pre>
 
 
 
The inverse getter methods will also deliver the objects in their simplest possible forms:
 
 
 
<pre>
 
    String stringValue = (String) individual.getPropertyValue(stringProperty);
 
    Integer intValue = (Integer) individual.getPropertyValue(intProperty);
 
    Float float = (Float) individual.setPropertyValue(floatProperty);
 
    Boolean boolean = (Boolean) individual.setPropertyValue(booleanProperty);
 
</pre>
 
 
 
Values of all other data types are wrapped into objects of the class '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/RDFSLiteral.html RDFSLiteral]'''. A literal combines a value together with its datatype. Values are stored as strings and need to be unwrapped by the user code. The following example is used to assign a value of the XML Schema datatype '''xsd:date'''.
 
 
 
<pre>
 
    RDFSDatatype xsdDate = owlModel.getRDFSDatatypeByName("xsd:date");
 
    OWLDatatypeProperty dateProperty = owlModel.createOWLDatatypeProperty(
 
            "dateProperty", xsdDate);
 
    RDFSLiteral dateLiteral = owlModel.createRDFSLiteral("1971-07-06", xsdDate);
 
    individual.setPropertyValue(dateProperty, dateLiteral);
 
    RDFSLiteral myDate = (RDFSLiteral) individual.getPropertyValue(dateProperty);
 
    System.out.println("Date: " + myDate);
 
</pre>
 
 
 
... will print out "Date: 1971-07-06".
 
 
 
RDFSLiterals are also used to bundle string values together with a language tag:
 
 
 
<pre>
 
    RDFSLiteral langLiteral = owlModel.createRDFSLiteral("Wert", "de");
 
    individual.setPropertyValue(stringProperty, langLiteral);
 
    RDFSLiteral result = (RDFSLiteral) individual.getPropertyValue(stringProperty);
 
    assert (result.getLanguage().equals("de"));
 
    assert (result.getString().equals("Wert"));
 
</pre>
 
  
To summarize, datatype values are handled either as primitive objects ('''String''', '''Integer''', '''Float''', '''Boolean'''), or '''RDFSLiterals'''. If we have a literal of a default data type, then this is automatically simplified. In some cases, it may be more convenient to always have RDFSLiterals, in particular if user's code has to execute on arbitrary data types. For these cases, the Protégé-OWL API provides a number of convenience methods that are guaranteed to return RDFSLiterals, e.g., '''[http://protege.stanford.edu/protege/3.4/docs/api/owl/edu/stanford/smi/protegex/owl/model/OWLModel.html#asRDFSLiteral(java.lang.Object) OWLModel.asRDFSLiteral()]'''.
+
This section provides information on building standalone Semantic Web applications using the Protege-OWL API.

Latest revision as of 12:25, July 8, 2010

Protege-OWL API Programmer's Guide

The Protege-OWL API is an open-source Java library for the Web Ontology Language (OWL) and RDF(S). The API provides classes and methods to load and save OWL files, to query and manipulate OWL data models, and to perform reasoning based on Description Logic engines. Furthermore, the API is optimized for the implementation of graphical user interfaces.

- Original Author: Holger Knublauch
- Currently maintained by: Protege staff members (contributions from the user community are welcome)
- Last update: June 30, 2010



Overview

The Protege-OWL API is an open-source Java library for the Web Ontology Language (OWL) and RDF(S). The API provides classes and methods to load and save OWL files, to query and manipulate OWL data models, and to perform reasoning based on Description Logic engines. Furthermore, the API is optimized for the implementation of graphical user interfaces.

The API is designed to be used in two contexts:

  • For the development of components that are executed inside of the Protege-OWL editor's user interface
  • For the development of stand-alone applications (e.g., Swing applications, Servlets, or Eclipse plug-ins)

Protege is a flexible, configurable platform for the development of arbitrary model-driven applications and components. Protege has an open architecture that allows programmers to integrate plug-ins, which can appear as separate tabs, specific user interface components (widgets), or perform any other task on the current model. The Protege-OWL editor provides many editing and browsing facilities for OWL models, and therefore can serve as an attractive starting point for rapid application development. Developers can initially wrap their components into a Protege tab widget and later extract them to distribute them as part of a stand-alone application.

This guide will introduce you to some basic concepts of the Protege-OWL API, no matter whether you intend to use it for stand-alone applications or Protege plug-ins. The guide tries to illustrate the API by examples, and most examples create parts of OWL ontologies such as properties and restrictions. The complete source code for most of the examples can be found in the edu.stanford.smi.protegex.owlx.examples package in the Protege-OWL source code. If you have trouble getting started, please post questions on the protege-owl mailing list.

Installation & Getting Started

The Protege-OWL editor is provided with the standard installation of Protege. In addition to installing Protege, you should download the source code from the Protege Subversion repository. The source code is the most reliable reference for the system's functionality and browsing the source code with a Java IDE is a great way to learn the API. Detailed instructions on how to download source code from our repository are available on the main Protege website. The URL to download the Protege-OWL source code using a Subversion client is:

http://smi-protege.stanford.edu/repos/protege/owl/trunk/.

You will also find Javadoc for the API useful. In particular, you will need to understand the interfaces from the edu.stanford.smi.protegex.owl.model package.

Following a successful installation, your directory structure should look approximately as follows:

Directory structure of the Protege application after a successful install

Now let us configure our Java project and write a small "Hello World" application. If you are using a Java IDE such as Eclipse or IntelliJ, select the Protege installation folder as your project home. Next, add all the JAR files from the installation to your project classpath. Set your compiler output path to plugins/classes.

Then create a Java class such as the following:

package com.demo.application;

import edu.stanford.smi.protegex.owl.model.OWLModel;
import edu.stanford.smi.protegex.owl.model.OWLNamedClass;
import edu.stanford.smi.protegex.owl.ProtegeOWL;

public class OWLAPIDemoApplication {

    public static void main(String[] args) {
        OWLModel owlModel = ProtegeOWL.createJenaOWLModel();
        owlModel.getNamespaceManager().setDefaultNamespace("http://hello.com#");
        OWLNamedClass worldClass = owlModel.createOWLNamedClass("World");
        System.out.println("Class URI: " + worldClass.getURI());
    }
}

Execute this program stand-alone. The output should be "Class URI: http://hello.com#World".


Basics

For more details on this topic, see Protege-OWL API Basics

Covered topics include:

  • Working with OWL Models
  • Names, Namespace prefixes, and URIs
  • Understanding the Model Interfaces
  • Creating Named Classes and Individuals
  • Using Datatype Properties and Datatype Values
  • Using Object Properties to Build Relationships between Resources
  • Working with References to External/Untyped Resources
  • Property Domains


Advanced Class Definitions (OWL DL)

For more details on this topic, see Protege-OWL API Advanced Class Definitions (OWL DL)

Covered topics include:

  • Restrictions
  • Logical Class Definitions (Unions, Intersections, Complements)
  • Enumerated Classes
  • Creating Defined Classes


Advanced Topics

For more details on this topic, see Protege-OWL API Advanced Topics

Covered topics include:

  • Querying the OWLModel
  • RDF(S) and OWL
  • Reacting to Changes using Listeners
  • Loading and Saving Files
  • Working with Multi-File Projects and TripleStores
  • Working with Jena Models


Protege Programming

For more details on this topic, see Programming with Protege-OWL

Covered topics include:

  • Protege-OWL and the Core Protege API
  • Changes from the old Protege-OWL API
  • Protege User Interface Programming
  • Protege Plug-in Development


Building Semantic Web Applications

For more details on this topic, see Building Semantic Web Applications

This section provides information on building standalone Semantic Web applications using the Protege-OWL API.