In this tutorial we create a SPARQL to SPIN converter using the Topraid SPIN API. Furthermore we use Apache Jena and Maven to setup a simple FileChooser UI to convert a selected SPARQL Query.
SPIN is a de-facto industry standard to represent SPARQL, rules and constraints on Semantic Web models. Among others, SPIN is used to:
- Calculate the value of a property based on other properties:
- Caluclate the area of a geometric figure as a product of its height and width
- Caluclate the age of a person as a difference between today’s date and person’s birthday date
- Isolate a set of rules to be executed under certain conditions:
- Support incremental reasoning, to initialize certain values when a resource is first created
- Constraint checking
- Definition of new SPARQL functions
1. Prerequisites
- SPIN API: Download SPIN 1.4
- Apache Jena: Download Jena
- Optional: Install Maven
2. Project Setup
- Without Maven:
- Create a standard Java project
- Include the SPIN and Jena JAR files in your classpath
- Create a Maven project and adapt the POM file with the following code
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tutorialacademy.rdf</groupId> <artifactId>spin</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spin</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.topbraid</groupId> <artifactId>spin</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.apache.jena</groupId> <artifactId>apache-jena-libs</artifactId> <type>pom</type> <version>2.11.0</version> </dependency> </dependencies> <repositories> <repository> <id>org.topbraid</id> <url>http://topquadrant.com/repository/spin</url> </repository> </repositories> </project>
Update or rebuild your project to download the required libraries. Afterwards create a package and create a Java class called SPARQL2SPINConverter. The necessary code is provided in the next chapter.
3. Code Example
The following example will open a FileChooser UI to select a SPARQL rule that should be converted to the SPIN syntax. We use the following SPARQL query stored in sparqlQuery.txt:
PREFIX ta: <https://tutorial-academy.com/2015/spin#> PREFIX sp: <http://spinrdf.org/sp#> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> SELECT ( ( AVG ( ?value ) ) AS ?average ) ?sensor WHERE { ?measurement rdf:type ta:Measurement . ?measurement ta:timestamp ?timestamp . ?measurement ta:value ?value . ?measurement ta:sensor ?sensor . } GROUP BY ( ?sensor ) ORDER BY DESC ( ?average )
The necessary Java code is shown below:
package com.tutorialacademy.rdf.spin; import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import javax.swing.JFileChooser; import javax.swing.JFrame; import org.topbraid.spin.arq.ARQ2SPIN; import org.topbraid.spin.arq.ARQFactory; import org.topbraid.spin.model.Select; import org.topbraid.spin.system.SPINModuleRegistry; import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.util.FileUtils; /** * Converts between textual SPARQL representation and SPIN RDF model. */ public class SPARQL2SPINConverter { public static String readFile( String path, Charset encoding ) { byte[] encoded = null; try { encoded = Files.readAllBytes( Paths.get( path ) ); } catch (IOException e) { e.printStackTrace(); } return new String( encoded, encoding ); } public static void main(String[] args) { // Register system functions SPINModuleRegistry.get().init(); // Create an empty OntModel final Model model = ModelFactory.createDefaultModel(); // FileChooser UI JFrame frame = new JFrame( "SPARQL2SPIN Converter" ); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); Container contentPane = frame.getContentPane(); JFileChooser fileChooser = new JFileChooser("."); fileChooser.setControlButtonsAreShown( false ); contentPane.add( fileChooser, BorderLayout.CENTER ); ActionListener actionListener = new ActionListener() { public void actionPerformed( ActionEvent actionEvent ) { model.removeAll(); JFileChooser theFileChooser = (JFileChooser) actionEvent.getSource(); String command = actionEvent.getActionCommand(); if ( command.equals( JFileChooser.APPROVE_SELECTION ) ) { File selectedFile = theFileChooser.getSelectedFile(); // read rule String query = readFile( selectedFile.getAbsolutePath(), Charset.defaultCharset() ); Query arqQuery = ARQFactory.get().createQuery( model, query ); ARQ2SPIN arq2SPIN = new ARQ2SPIN( model ); Select sparqlQuery = (Select) arq2SPIN.createQuery( arqQuery, null ); System.out.println( "SPARQL Query:\n" + sparqlQuery ); System.out.println( "\nSPIN Representation:" ); model.write( System.out, FileUtils.langTurtle ); } } }; fileChooser.addActionListener( actionListener ); frame.pack(); frame.setVisible(true); } }
Now you can execute the Java code and select the sparqlQuery.txt file.
![SPARQL2SPIN Converter](https://tutorial-academy.com/wp-content/uploads/2015/07/SPARQL2SPIN_Converter_FileChooser-300x211.jpg)
Doubleclick the specified SPARQL query and check the console output of your Java programm. You should see something like:
SPARQL Query: SELECT ((AVG(?value)) AS ?average) ?sensor WHERE { ?measurement a <https://tutorial-academy.com/2015/spin#Measurement> . ?measurement <https://tutorial-academy.com/2015/spin#timestamp> ?timestamp . ?measurement <https://tutorial-academy.com/2015/spin#value> ?value . ?measurement <https://tutorial-academy.com/2015/spin#sensor> ?sensor . } GROUP BY ?sensor ORDER BY DESC (?average) SPIN Representation: [ a <http://spinrdf.org/sp#Select> ; <http://spinrdf.org/sp#groupBy> ( [ <http://spinrdf.org/sp#varName> "sensor"^^<http://www.w3.org/2001/XMLSchema#string> ] ) ; <http://spinrdf.org/sp#orderBy> ( [ a <http://spinrdf.org/sp#Desc> ; <http://spinrdf.org/sp#expression> [ <http://spinrdf.org/sp#varName> "average"^^<http://www.w3.org/2001/XMLSchema#string> ] ] ) ; <http://spinrdf.org/sp#resultVariables> ( [ <http://spinrdf.org/sp#expression> [ a <http://spinrdf.org/sp#Avg> ; <http://spinrdf.org/sp#expression> [ <http://spinrdf.org/sp#varName> "value"^^<http://www.w3.org/2001/XMLSchema#string> ] ] ; <http://spinrdf.org/sp#varName> "average"^^<http://www.w3.org/2001/XMLSchema#string> ] [ <http://spinrdf.org/sp#varName> "sensor"^^<http://www.w3.org/2001/XMLSchema#string> ] ) ; <http://spinrdf.org/sp#where> ( [ <http://spinrdf.org/sp#object> <https://tutorial-academy.com/2015/spin#Measurement> ; <http://spinrdf.org/sp#predicate> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ; <http://spinrdf.org/sp#subject> [ <http://spinrdf.org/sp#varName> "measurement"^^<http://www.w3.org/2001/XMLSchema#string> ] ] [ <http://spinrdf.org/sp#object> [ <http://spinrdf.org/sp#varName> "timestamp"^^<http://www.w3.org/2001/XMLSchema#string> ] ; <http://spinrdf.org/sp#predicate> <https://tutorial-academy.com/2015/spin#timestamp> ; <http://spinrdf.org/sp#subject> [ <http://spinrdf.org/sp#varName> "measurement"^^<http://www.w3.org/2001/XMLSchema#string> ] ] [ <http://spinrdf.org/sp#object> [ <http://spinrdf.org/sp#varName> "value"^^<http://www.w3.org/2001/XMLSchema#string> ] ; <http://spinrdf.org/sp#predicate> <https://tutorial-academy.com/2015/spin#value> ; <http://spinrdf.org/sp#subject> [ <http://spinrdf.org/sp#varName> "measurement"^^<http://www.w3.org/2001/XMLSchema#string> ] ] [ <http://spinrdf.org/sp#object> [ <http://spinrdf.org/sp#varName> "sensor"^^<http://www.w3.org/2001/XMLSchema#string> ] ; <http://spinrdf.org/sp#predicate> <https://tutorial-academy.com/2015/spin#sensor> ; <http://spinrdf.org/sp#subject> [ <http://spinrdf.org/sp#varName> "measurement"^^<http://www.w3.org/2001/XMLSchema#string> ] ] ) ] .
Now you converted an existing SPARQL query into the SPIN syntax representation.
If you have problems or questions, feel free to comment.
![Share on Facebook Facebook](http://tutorial-academy.com/wp-content/plugins/social-media-feather/synved-social/image/social/regular/96x96/facebook.png)
![Share on Twitter twitter](http://tutorial-academy.com/wp-content/plugins/social-media-feather/synved-social/image/social/regular/96x96/twitter.png)
![Share on Reddit reddit](http://tutorial-academy.com/wp-content/plugins/social-media-feather/synved-social/image/social/regular/96x96/reddit.png)
![Pin it with Pinterest pinterest](http://tutorial-academy.com/wp-content/plugins/social-media-feather/synved-social/image/social/regular/96x96/pinterest.png)
![Share on Linkedin linkedin](http://tutorial-academy.com/wp-content/plugins/social-media-feather/synved-social/image/social/regular/96x96/linkedin.png)
![Share by email mail](http://tutorial-academy.com/wp-content/plugins/social-media-feather/synved-social/image/social/regular/96x96/mail.png)