ProvToolbox Tutorial 1: Creating and Saving a PROV Document

1. Introduction

The aim of this tutorial is to show how to create a simple PROV Document in Java using ProvToolbox, and export it to some format.  The post also explains how to configure Maven to use the required ProvToolbox artifacts.

The tutorial is based on “A Little Provenance Goes a Long Way“, a quote that Paul and I asserted in our book  “An introduction to PROV” (see www.provbook.org).

2. Download and Execution

The tutorial is standalone and a zip archive can be downloaded from the following URL: http://search.maven.org/remotecontent?filepath=org/openprovenance/prov/ProvToolbox-Tutorial1/0.7.0/ProvToolbox-Tutorial1-0.7.0-src.zip.The tutorial can also be found on the ProvToolbox project on GitHub.

After unziping the archive, we obtain the following directory structure:

tutorial1

The directory contains a README file, a license file, and a  Maven pom.xml configuration file, and a source directory containing a single Java file.

To execute the tutorial, you need to have two pieces of software installed:

  1. the software project management tool Apache Maven  (see http://maven.apache.org/download.html),  and
  2. the graph visualization software GraphViz (see http://www.graphviz.org/).

You are then ready to execute the tutorial by calling

mvn clean install

Beside the verbose logging by the Maven build process, the tutorial itself displays the following text, including some PROV expressed according to the Provenance Notation.

*************************
* Converting document  
*************************
document
prefix xsd <http://www.w3.org/2001/XMLSchema>
prefix provbook <http://www.provbook.org>
prefix jim <http://www.cs.rpi.edu/~hendler/>
entity(provbook:a-little-provenance-goes-a-long-way,[prov:value = "A little provenance goes a long way" %% xsd:string])
agent(provbook:Paul,[prov:label = "Paul Groth"])
agent(provbook:Luc,[prov:label = "Luc Moreau"])
wasAttributedTo(provbook:a-little-provenance-goes-a-long-way, provbook:Paul)
wasAttributedTo(provbook:a-little-provenance-goes-a-long-way, provbook:Luc)
entity(jim:LittleSemanticsWeb.html)
wasDerivedFrom(provbook:a-little-provenance-goes-a-long-way, jim:LittleSemanticsWeb.html)
endDocument
*************************

Furthermore, a file target/little.svg appears in the target/ directory. It displays as follows.
little

3. Java Source Code

We now examine the Java class Little. The main method creates an instance of the Little class, constructs a PROV document, and writes it to a file, and also displays it on the System.out stream, in the Provenance notation (here "target/little.svg" was passed as argument when invoking the main method).

    public void doConversions(Document document, String file) {
        InteropFramework intF=new InteropFramework();
        intF.writeDocument(file, document);     
        intF.writeDocument(System.out, ProvFormat.PROVN, document);
    }

    public static void main(String [] args) {
        if (args.length!=1) throw new UnsupportedOperationException("main to be called with filename");
        String file=args[0];
        
        Little little=new Little(InteropFramework.newXMLProvFactory());
        little.openingBanner();
        Document document = little.makeDocument();
        little.doConversions(document,file);
        little.closingBanner();
    }

The InteropFramework class deals with conversion of Java representations to PROV serializations and vice-versa. It uses the writeDocument method to save a Document to a file or to an Outputstream.

The code snippet below displays the method  makeDocument which constructs a Document. It proceeds by creating two entities quote and original, and two agents paul and luc. It then creates three associations (two attributions from quote to the agents) and one derivation from the quote to the original.  A new Document is created, and all the assertions are added. The Document namespace is also set appropriately.

    public Document makeDocument() {     
        Entity quote = pFactory.newEntity(qn("a-little-provenance-goes-a-long-way"));
        quote.setValue(pFactory.newValue("A little provenance goes a long way",
                                         pFactory.getName().XSD_STRING));

        Entity original = pFactory.newEntity(ns.qualifiedName(JIM_PREFIX,"LittleSemanticsWeb.html",pFactory));

        Agent paul = pFactory.newAgent(qn("Paul"), "Paul Groth");
        Agent luc = pFactory.newAgent(qn("Luc"), "Luc Moreau");

        WasAttributedTo attr1 = pFactory.newWasAttributedTo(null,
                                                            quote.getId(),
                                                            paul.getId());
        WasAttributedTo attr2 = pFactory.newWasAttributedTo(null,
                                                            quote.getId(),
                                                            luc.getId());
        WasDerivedFrom wdf = pFactory.newWasDerivedFrom(quote.getId(),
                                                        original.getId());

        Document document = pFactory.newDocument();
        document.getStatementOrBundle()
                .addAll(Arrays.asList(new StatementOrBundle[] { quote, 
                                                                paul,
                                                                luc, 
                                                                attr1,
                                                                attr2, 
                                                                original,
                                                                wdf }));
        document.setNamespace(ns);
        return document;
    }
    public QualifiedName qn(String n) {
        return ns.qualifiedName(PROVBOOK_PREFIX, n, pFactory);
    }

As one can see from the code, the ProvFactory is used to create all statements. The constructor receives a ProvFactory from the main method. The constructor also creates a namespace object ns to manage all namespace/prefix declarations.

    public Little(ProvFactory pFactory) {
        this.pFactory = pFactory;
        ns=new Namespace();
        ns.addKnownNamespaces();
        ns.register(PROVBOOK_PREFIX, PROVBOOK_NS);
        ns.register(JIM_PREFIX, JIM_NS);
    }

4. Maven Configuration

The Maven configuration file is straightforward to define. First, one needs to specify the artifacts this code depends on. There are two of them. The prov-model artifact provides the classes necessary to manipulate the PROV Data Model in Java, irrespectively of the serialization chosen for it. The prov-interop artifact provides the classes necessary to convert the PROV Data Model in Java to any PROV-compatible serialization and back.

  <dependencies>
    <dependency>
      <groupId>org.openprovenance.prov</groupId>
      <artifactId>prov-model</artifactId>
      <version>0.7.0</version>
    </dependency>
    <dependency>
      <groupId>org.openprovenance.prov</groupId>
      <artifactId>prov-interop</artifactId>
      <version>0.7.0</version>
    </dependency>
  </dependencies>

Since version 0.6.1, ProvToolbox is deployed on Maven central. Hence, it is not required to specify any repository for artifacts.

For completeness, we show how the tutorial is started by Maven during the test phase. The main method of class Little is invoked by the exec-maven-plugin passing an explicit argument target/little.svg.

<plugin>
	<groupId>org.codehaus.mojo</groupId>
	<artifactId>exec-maven-plugin</artifactId>
	<version>1.3.2</version>
	<executions>
	  <execution>
	    <phase>test</phase>
	    <goals>
	      <goal>java</goal>
	    </goals>
	    <configuration>
	      <mainClass>org.openprovenance.prov.tutorial.tutorial1.Little</mainClass>
	      <arguments>
		<argument>target/little.svg</argument>
	      </arguments>
	    </configuration>
	  </execution>
	</executions>
</plugin>

5. Conclusion

For further documentation on the classes and methods used, Javadoc for ProvToolbox can be found from http://openprovenance.org/java/site/latest/apidocs/.  The Javadoc documentation also refers to PROV specifications where appropriate.

This is the first tutorial for ProvToolbox. Others will follow. We also welcome suggestions for tutorial topics, and also for ways of improving the programming experience offered by ProvToolbox. Post comments on this site or use GitHub issues.

 

6. Appendix. Log Change

  1. Original version submitted on 2014/08/01
  2. Updated with maven central configuration on 2014/08/08
  3. Updated to 0.6.2 on 2015/07/01
  4. Updated to 0.7.0 on 2015/07/27

 

Advertisements

4 thoughts on “ProvToolbox Tutorial 1: Creating and Saving a PROV Document

  1. Pingback: ProvToolbox Tutorial 2: Reading, Converting and Saving PROV Documents | Luc's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s