Commit 28fba517 authored by Ivan Frade's avatar Ivan Frade Committed by Jürg Billeter

Add ontology utilities

parent bbce4638
......@@ -1441,6 +1441,7 @@ AC_CONFIG_FILES([
utils/Makefile
utils/qdbm/Makefile
utils/tracker-fts/Makefile
utils/services/Makefile
])
AC_OUTPUT
......
......@@ -5,5 +5,6 @@ build_sqlite_fts = tracker-fts
endif
SUBDIRS = \
services \
$(build_sqlite_fts) \
qdbm
include $(top_srcdir)/Makefile.decl
noinst_PROGRAMS = ontology-validator ttl2html
INCLUDES = \
-DG_LOG_DOMAIN=\"Tracker\" \
$(WARN_CFLAGS) \
$(GLIB2_CFLAGS) \
$(RAPTOR_CFLAGS) \
$(GIO_CFLAGS)
ontology_validator_SOURCES = \
ontology-validator.c
ontology_validator_LDADD = \
$(RAPTOR_LIBS) \
$(GLIB2_LIBS) \
$(GIO_LIBS)
ttl2html_SOURCES = \
ttl2html.c \
ttl_loader.h \
ttl_loader.c \
ttl_model.h \
ttl_model.c \
ttl_html.h \
ttl_html.c
ttl2html_LDADD = \
$(RAPTOR_LIBS) \
$(GLIB2_LIBS) \
$(GIO_LIBS)
== ttl2html ==
This programs outputs in stdout a HTML representation of the TTL ontology file.
It receives as parameter an ontology TTL file, and
optionally the base URI for the classes in that ontology. This base
URI is used to turn the internal references in the ontology into
HTML anchors.
E.g.
./ttl2html -f ../../data/ontologies/39-mto.ontology -u http://www.tracker-project.org/temp/mto#
== ontology-validator ==
This program check that all files in the ontology are TTL
syntactically correct, and all referenced classes are defined
somewhere in the ontology.
It receives as parameter the ontology files directory. Usually:
./ontology-validator -o ../../data/ontologies
== Deprecated ==
python ./service2xml.py < ../../data/services/email.metadata > t.xml ; xsltproc sample.xsl t.xml
#!/bin/bash
#
# This script generates the HTML documentation from TTL description
# for the tracker specific ontologies
#
BUILD_DIR="./build/ontologies"
if [ -e $BUILD_DIR ]; then
echo "Removing old " $BUILD_DIR "directory"
rm -rf $BUILD_DIR
fi
echo "Creating new directory"
mkdir -p $BUILD_DIR
echo "Compiling the tools"
make
for f in `find ../../data/ontologies -name "*.description"` ; do
# ../../data/ontologies/XX-aaa.description -> PREFIX=aaa
TMPNAME=${f%.description}
PREFIX=${TMPNAME#*-}
echo "Generating $PREFIX"
mkdir -p $BUILD_DIR/$PREFIX
./ttl2html -d $f -o $BUILD_DIR/$PREFIX/index.html
done
echo "Copying resources"
cp -R resources/ $BUILD_DIR
\ No newline at end of file
#include <raptor.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <string.h>
static gchar *ontology_dir = NULL;
static GOptionEntry entries[] = {
{ "ontology-dir", 'o', 0, G_OPTION_ARG_FILENAME, &ontology_dir,
"Directory containing the ontology description files (TTL FORMAT)",
NULL
},
{ NULL }
};
typedef void (* TurtleTripleCallback) (void *user_data, const raptor_statement *triple);
#define RDFS_CLASS "http://www.w3.org/2000/01/rdf-schema#Class"
#define RDF_PROPERTY "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"
#define RDFS_SUBCLASSOF "http://www.w3.org/2000/01/rdf-schema#subClassOf"
#define RDFS_TYPE "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
#define TRACKER_NAMESPACE "http://www.tracker-project.org/ontologies/tracker#Namespace"
#define RDFS_RANGE "http://www.w3.org/2000/01/rdf-schema#range"
#define RDFS_DOMAIN "http://www.w3.org/2000/01/rdf-schema#domain"
static void
raptor_error (void *user_data, raptor_locator* locator, const char *message)
{
g_message ("RAPTOR parse error: %s:%d:%d: %s\n",
(gchar *) user_data,
locator->line,
locator->column,
message);
}
static GList *unknown_items = NULL;
static GList *known_items = NULL;
static gboolean
exists_or_already_reported (const gchar *item)
{
if (!g_list_find_custom (known_items,
item,
(GCompareFunc) g_strcmp0)){
if (!g_list_find_custom (unknown_items,
item,
(GCompareFunc) g_strcmp0)) {
return FALSE;
}
}
return TRUE;
}
static void
turtle_load_ontology (void *user_data,
const raptor_statement *triple)
{
gchar *turtle_subject;
gchar *turtle_predicate;
char *turtle_object;
/* set new statement */
turtle_subject = g_strdup ((const gchar *) raptor_uri_as_string ((raptor_uri *) triple->subject));
turtle_predicate = g_strdup ((const gchar *) raptor_uri_as_string ((raptor_uri *) triple->predicate));
turtle_object = g_strdup ((const gchar *) triple->object);
/* nmo:Email a rdfs:Class
* If rdfs:Class exists, add nmo:Email to the known_items
**/
if (!g_strcmp0 (turtle_predicate, RDFS_TYPE)) {
if (!g_strcmp0 (turtle_object, TRACKER_NAMESPACE)) {
/* Ignore the internal tracker namespace definitions */
return;
}
/* Check the class is already defined */
if (!exists_or_already_reported (turtle_object)) {
g_error ("Class %s is subclass of %s but %s is not defined",
turtle_subject, turtle_object, turtle_object);
} else {
known_items = g_list_prepend (known_items, turtle_subject);
}
}
/*
* nmo:Message rdfs:subClassOf nie:InformationElement
* Check nie:InformationElement is defined
*/
if (!g_strcmp0 (turtle_predicate, RDFS_SUBCLASSOF)
|| !g_strcmp0 (turtle_predicate, RDFS_RANGE)
|| !g_strcmp0 (turtle_predicate, RDFS_DOMAIN)) {
/* Check the class is already defined */
if (!exists_or_already_reported (turtle_object)) {
g_error ("Class %s refears to %s but it is not defined",
turtle_subject, turtle_object);
}
}
}
static void
process_file (const gchar *ttl_file, TurtleTripleCallback handler)
{
FILE *file;
raptor_parser *parser;
raptor_uri *uri, *buri, *base_uri;
unsigned char *uri_string;
g_print ("Processing %s\n", ttl_file);
file = g_fopen (ttl_file, "r");
parser = raptor_new_parser ("turtle");
base_uri = raptor_new_uri ((unsigned char *) "/");
raptor_set_statement_handler (parser, NULL,
handler);
raptor_set_fatal_error_handler (parser, (void *)file, raptor_error);
raptor_set_error_handler (parser, (void *)file, raptor_error);
raptor_set_warning_handler (parser, (void *)file, raptor_error);
uri_string = raptor_uri_filename_to_uri_string (ttl_file);
uri = raptor_new_uri (uri_string);
buri = raptor_new_uri ((unsigned char *) base_uri);
raptor_parse_file (parser, uri, buri);
raptor_free_uri (uri);
raptor_free_parser (parser);
fclose (file);
}
static void
load_ontology_files (const gchar *services_dir)
{
GList *files = NULL;
GDir *services;
const gchar *conf_file;
GFile *f;
gchar *dir_uri, *fullpath;
f = g_file_new_for_path (services_dir);
dir_uri = g_file_get_path (f);
g_print ("dir_uri %s\n", dir_uri);
services = g_dir_open (dir_uri, 0, NULL);
conf_file = g_dir_read_name (services);
while (conf_file) {
if (!g_str_has_suffix (conf_file, "ontology")) {
conf_file = g_dir_read_name (services);
continue;
}
fullpath = g_build_filename (dir_uri, conf_file, NULL);
files = g_list_insert_sorted (files, fullpath, (GCompareFunc) g_strcmp0);
conf_file = g_dir_read_name (services);
}
g_dir_close (services);
//process_file (fullpath, turtle_load_ontology, NULL);
g_list_foreach (files, (GFunc) process_file, turtle_load_ontology);
g_list_foreach (files, (GFunc) g_free, NULL);
g_object_unref (f);
g_free (dir_uri);
}
static void
load_basic_classes ()
{
known_items = g_list_prepend (known_items, RDFS_CLASS);
known_items = g_list_prepend (known_items, RDF_PROPERTY);
}
gint
main (gint argc, gchar **argv)
{
GOptionContext *context;
g_type_init ();
raptor_init ();
/* Translators: this messagge will apper immediately after the */
/* usage string - Usage: COMMAND [OPTION]... <THIS_MESSAGE> */
context = g_option_context_new ("- Validate the ontology consistency");
/* Translators: this message will appear after the usage string */
/* and before the list of options. */
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_parse (context, &argc, &argv, NULL);
if (!ontology_dir) {
gchar *help;
g_printerr ("%s\n\n",
"Ontology directory is mandatory");
help = g_option_context_get_help (context, TRUE, NULL);
g_option_context_free (context);
g_printerr ("%s", help);
g_free (help);
return -1;
}
load_basic_classes ();
//"/home/ivan/devel/codethink/tracker-ssh/data/services"
load_ontology_files (ontology_dir);
raptor_finish ();
return 0;
}
......@@ -35,19 +35,29 @@
<xsl:when test="substring-after($about, '#')">
<xsl:if test="substring-before($about, '#') != 'XMLSchema'"><xsl:value-of select="substring-before($about, '#')"/>:</xsl:if><xsl:value-of select="substring-after($about, '#')"/>
</xsl:when>
<xsl:otherwise>DC:<xsl:value-of select="$about"/></xsl:otherwise>
<xsl:otherwise>dc:<xsl:value-of select="$about"/></xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="convert-datatype-of">
<xsl:param name="datatype"/>
<xsl:choose>
<xsl:when test="substring-after($datatype, ':')">resource</xsl:when>
<xsl:when test="$datatype = 'float'">double</xsl:when>
<xsl:when test="$datatype = 'dateTime'">date</xsl:when>
<xsl:otherwise><xsl:value-of select="$datatype"/></xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="rdf:RDF">
<xsl:for-each select="rdf:Property">
[<xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="@rdf:about"/></xsl:with-param></xsl:call-template>]
<xsl:choose>
[<xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="@rdf:about"/></xsl:with-param></xsl:call-template>]<xsl:choose>
<xsl:when test="rdfs:range">
DataType=<xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="rdfs:range/@rdf:resource"/></xsl:with-param></xsl:call-template>
DataType=<xsl:call-template name="convert-datatype-of"><xsl:with-param name="datatype">
<xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="rdfs:range/@rdf:resource"/></xsl:with-param></xsl:call-template></xsl:with-param></xsl:call-template>
</xsl:when>
<xsl:otherwise>Abstract=true
DataType=string</xsl:otherwise>
......@@ -60,8 +70,8 @@ DisplayName=<xsl:value-of select="rdfs:label"/>
Domain=<xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="rdfs:domain/@rdf:resource"/></xsl:with-param></xsl:call-template></xsl:if>
<xsl:if test="rdfs:subPropertyOf">
SuperProperties=<xsl:for-each select="rdfs:subPropertyOf"><xsl:if test="@rdf:resource"><xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="@rdf:resource"/></xsl:with-param></xsl:call-template>;</xsl:if><xsl:for-each select="rdfs:subPropertyOf/rdf:Property"><xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="@rdf:about"/></xsl:with-param></xsl:call-template>;</xsl:for-each></xsl:for-each></xsl:if>
SuperProperties=<xsl:for-each select="rdfs:subPropertyOf">
<xsl:if test="@rdf:resource"><xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="@rdf:resource"/></xsl:with-param></xsl:call-template>;</xsl:if><xsl:for-each select="rdf:Property"><xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="@rdf:about"/></xsl:with-param></xsl:call-template>;</xsl:for-each></xsl:for-each></xsl:if>
<xsl:if test="rdfs:comment">
Description=<xsl:value-of select="rdfs:comment"/></xsl:if>
</xsl:for-each>
......
<xsl:stylesheet version = '1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:nid3="http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#"
xmlns:nfo="http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#"
xmlns:nmo="http://www.semanticdesktop.org/ontologies/2007/03/22/nmo#"
xmlns:nie="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#"
xmlns:exif="http://www.kanzaki.com/ns/exif#"
xmlns:nao="http://www.semanticdesktop.org/ontologies/2007/08/15/nao#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:protege="http://protege.stanford.edu/system#"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ncal="http://www.semanticdesktop.org/ontologies/2007/04/02/ncal#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:nrl="http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#"
xmlns:pimo="http://www.semanticdesktop.org/ontologies/2007/11/01/pimo#"
xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
xmlns:tmo="http://www.semanticdesktop.org/ontologies/2008/05/20/tmo#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:nco="http://www.semanticdesktop.org/ontologies/2007/03/22/nco#"
xmlns:nexif="http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#">
<xsl:output method="text" />
<xsl:template name="predicate-of">
<xsl:param name="about"/>
<xsl:choose>
<xsl:when test="substring-after($about, '/')">
<xsl:call-template name="predicate-of">
<xsl:with-param name="about" select="substring-after($about, '/')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="substring-after($about, '#')">
<xsl:if test="substring-before($about, '#') != 'XMLSchema'"><xsl:value-of select="substring-before($about, '#')"/>:</xsl:if><xsl:value-of select="substring-after($about, '#')"/>
</xsl:when>
<xsl:otherwise>dc:<xsl:value-of select="$about"/></xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="rdf:RDF">
<xsl:for-each select="rdfs:Class">
[<xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="@rdf:about"/></xsl:with-param></xsl:call-template>]<xsl:if test="rdfs:label">
DisplayName=<xsl:value-of select="rdfs:label"/>
</xsl:if>
<xsl:if test="rdfs:subClassOf">
SuperClasses=<xsl:for-each select="rdfs:subClassOf">
<xsl:if test="@rdf:resource">
<!-- xsl:if test="substring-after(@rdf:resource, '#') != 'Resource'" //-->
<xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="@rdf:resource"/></xsl:with-param></xsl:call-template>;</xsl:if><!-- /xsl:if //-->
<xsl:for-each select="rdfs:Class"><xsl:call-template name="predicate-of"><xsl:with-param name="about"><xsl:value-of select="@rdf:about"/></xsl:with-param></xsl:call-template>;</xsl:for-each></xsl:for-each></xsl:if>
<xsl:if test="rdfs:comment">
Description=<xsl:value-of select="rdfs:comment"/></xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
/* Adapted from a "Style for an "Interest Group Note" */ /*
Copyright 1997-2003 W3C (MIT, ERCIM, Keio). All Rights Reserved.
The following software licensing rules apply:
http://www.w3.org/Consortium/Legal/copyright-software */
body {
padding: 2em 1em 2em 70px;
margin: 0;
font-family: sans-serif;
color: black;
background: white;
background-position: top left;
background-attachment: fixed;
background-repeat: no-repeat;
}
blockquote { margin-top: 0pt; margin-bottom: 0pt; text-align: justify }
pre { border: 1.00pt solid #000000; padding: 0.02in; width:85%; }
blockquote pre { border: none; width: 100% }
p {text-indent: 15pt}
.footnotes { font-size: smaller; background-color:#fef; width: 70% }
address {text-align: right; text-indent: 15pt}
:link {
color: #856347;
background: transparent
}
table {
border: solid;
width: 100%;
border-collapse: collapse;
}
td {
border: 1px solid black;
}
TD.rowheader {
width: 20%;
}
:visited {
color: #609;
background: transparent
}
a:active {
color: #C00;
background: transparent
}
a:link img,a:visited img {
border-style: none
}
/* no border on img links */
a img {
color: white;
}
/* trick to hide the border in Netscape 4 */
@media all {
/* hide the next rule from Netscape 4 */
a img {
color: inherit;
}
/* undo the color change above */
}
th,td {
/* ns 4 */
font-family: sans-serif;
}
h1,h2,h3,h4,h5,h6 {
text-align: left
}
/* background should be transparent, but WebTV has a bug */
h1,h2,h3 {
color: #CE5C00;
background: white
}
h1 {
font: 170% sans-serif
}
h2 {
font: 140% sans-serif
}
h3 {
font: 120% sans-serif
}
h4 {
font: bold 100% sans-serif
}
h5 {
font: italic 100% sans-serif
}
h6 {
font: small-caps 100% sans-serif
}
.hide {
display: none
}
div.head {
margin-bottom: 1em
}
div.head h1 {
margin-top: 2em;
clear: both
}
div.head table {
margin-left: 2em;
margin-top: 2em
}
p.copyright {
font-size: small
}
p.copyright small {
font-size: small
}
@media screen { /* hide from IE3 */
a [href]:hover {
background: #ffa
}
}
pre {
margin-left: 2em
}
/*
p {
margin-top: 0.6em;
margin-bottom: 0.6em;
}
*/
dt,dd {
margin-top: 0;
margin-bottom: 0
} /* opera 3.50 */
dt {
font-weight: bold
}
pre,code {
font-family: monospace
} /* navigator 4 requires this */
ul.toc,ol.toc {
list-style: disc; /* Mac NS has problem with 'none' */
list-style: none;
}
@media aural {
h1,h2,h3 {
stress: 20;
richness: 90
}
.hide {
speak: none
}
p.copyright {
volume: x-soft;
speech-rate: x-fast
}
dt {
pause-before: 20%
}
pre {
speak-punctuation: code
}
}
/* Copyright 1997-2003 W3C (MIT, ERCIM, Keio). All Rights Reserved.
The following software licensing rules apply:
http://www.w3.org/Consortium/Legal/copyright-software */
body {
background-image: url(logo-maemo-ontology.png);
}
\ No newline at end of file
......@@ -94,7 +94,7 @@ def main():
if name == "weight":
print "\t\t<rdfs:comment>Weight is " + value + "</rdfs:comment>"
print "\t</rdfs:Property>"
print "\t</rdf:Property>"
print "</rdf:RDF>"
except getopt.GetoptError, err:
......
#include <glib.h>
#include <gio/gio.h>
#include <string.h>
#include <stdio.h>
#include "ttl_loader.h"
#include "ttl_model.h"
#include "ttl_html.h"
static gchar *desc_file = NULL;
static gchar *output_file = NULL;
static GOptionEntry entries[] = {
{ "desc", 'd', 0, G_OPTION_ARG_FILENAME, &desc_file,
"TTL file with the ontology description and documentation",
NULL
},
{ "output", 'o', 0, G_OPTION_ARG_FILENAME, &output_file,
"File to write the output (default stdout)",
NULL
},
{ NULL }
};
gint
main (gint argc, gchar **argv)
{
GOptionContext *context;
Ontology *ontology = NULL;
OntologyDescription *description = NULL;
gchar *ttl_file = NULL;
gchar *dirname = NULL;
FILE *f = NULL;
g_type_init ();
/* Translators: this messagge will apper immediately after the */
/* usage string - Usage: COMMAND [OPTION]... <THIS_MESSAGE> */
context = g_option_context_new ("- Generates HTML doc for a TTL file");
/* Translators: this message will appear after the usage string */
/* and before the list of options. */
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_parse (context, &argc, &argv, NULL);
if (!desc_file) {
gchar *help;
g_printerr ("%s\n\n",
"Description file is mandatory");
help = g_option_context_get_help (context, TRUE, NULL);
g_option_context_free (context);
g_printerr ("%s", help);
g_free (help);
return -1;
}
if (output_file) {
f = fopen (output_file, "w");
} else {
f = stdout;
}
g_assert (f != NULL);
ttl_loader_init ();
description = ttl_loader_load_description (desc_file);
dirname = g_path_get_dirname (desc_file);
ttl_file = g_build_filename (dirname,
description->relativePath,
NULL);
ontology = ttl_loader_load_ontology (ttl_file);
g_free (ttl_file);
g_free (dirname);
ttl_html_print (description, ontology, f);
ttl_loader_free_ontology (ontology);
ttl_loader_free_description (description);
ttl_loader_shutdown ();
g_option_context_free (context);