[tracker] ttl2graphviz: attempt to draw ontologies automatically.



commit 9995f4a204db454bfd8f6030d15b4355ee7ba971
Author: Ivan Frade <ivan frade nokia com>
Date:   Fri Sep 25 01:47:31 2009 +0300

    ttl2graphviz: attempt to draw ontologies automatically.

 utils/services/Makefile.am    |   21 ++++++++-
 utils/services/qname.c        |  109 +++++++++++++++++++++++++++++++++++++++++
 utils/services/qname.h        |   19 +++++++
 utils/services/ttl2graphviz.c |   87 ++++++++++++++++++++++++++++++++
 utils/services/ttl_graphviz.c |   82 +++++++++++++++++++++++++++++++
 utils/services/ttl_graphviz.h |   18 +++++++
 utils/services/ttl_html.c     |   80 +-----------------------------
 7 files changed, 337 insertions(+), 79 deletions(-)
---
diff --git a/utils/services/Makefile.am b/utils/services/Makefile.am
index 98cd070..fdf72d3 100644
--- a/utils/services/Makefile.am
+++ b/utils/services/Makefile.am
@@ -1,6 +1,6 @@
 include $(top_srcdir)/Makefile.decl
 
-noinst_PROGRAMS = ontology-validator ttl2html data-validator
+noinst_PROGRAMS = ontology-validator ttl2html data-validator ttl2graphviz
 
 INCLUDES = 				\
 	-DG_LOG_DOMAIN=\"Tracker\"	\
@@ -34,6 +34,8 @@ ttl2html_SOURCES =			\
 	ttl_loader.c			\
 	ttl_model.h 			\
 	ttl_model.c			\
+	qname.h				\
+	qname.c				\
 	ttl_html.h			\
 	ttl_html.c
 
@@ -42,3 +44,20 @@ ttl2html_LDADD = 			\
 	$(top_builddir)/src/libtracker-common/libtracker-common.la	\
 	$(GLIB2_LIBS)			\
 	$(GIO_LIBS)	
+
+ttl2graphviz_SOURCES =			\
+	ttl2graphviz.c			\
+	ttl_loader.h			\
+	ttl_loader.c			\
+	ttl_model.h 			\
+	ttl_model.c			\
+	qname.h				\
+	qname.c				\
+	ttl_graphviz.h			\
+	ttl_graphviz.c
+
+ttl2graphviz_LDADD = 			\
+	$(top_builddir)/src/libtracker-data/libtracker-data.la		\
+	$(top_builddir)/src/libtracker-common/libtracker-common.la	\
+	$(GLIB2_LIBS)			\
+	$(GIO_LIBS)	
diff --git a/utils/services/qname.c b/utils/services/qname.c
new file mode 100644
index 0000000..401a429
--- /dev/null
+++ b/utils/services/qname.c
@@ -0,0 +1,109 @@
+#include "qname.h"
+
+static gchar *local_uri = NULL;
+
+typedef struct {
+        const gchar *namespace;
+        const gchar *uri;
+} Namespace;
+
+Namespace NAMESPACES [] = {
+        {"dc", "http://purl.org/dc/elements/1.1/"},
+        {"xsd", "http://www.w3.org/2001/XMLSchema#"},
+        {"fts", "http://www.tracker-project.org/ontologies/fts#"},
+        {"mto", "http://www.tracker-project.org/temp/mto#"},
+        {"mlo", "http://www.tracker-project.org/temp/mlo#"},
+        {"nao", "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#"},
+        {"ncal", "http://www.semanticdesktop.org/ontologies/2007/04/02/ncal#"},
+        {"nco", "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#"},
+        {"nfo", "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#"},
+        {"nid3", "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#"},
+        {"nie", "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#"},
+        {"nmm", "http://www.tracker-project.org/temp/nmm#"},
+        {"nmo", "http://www.semanticdesktop.org/ontologies/2007/03/22/nmo#"},
+        {"nrl", "http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#"},
+        {"rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"},
+        {"rdfs", "http://www.w3.org/2000/01/rdf-schema#"},
+        {"tracker", "http://www.tracker-project.org/ontologies/tracker#"},
+        {NULL, NULL}
+};
+
+
+void   
+qname_init (const gchar *luri)
+{
+        if (local_uri) {
+                g_warning ("Reinitializing qname_module");
+                g_free (local_uri);
+        }
+        local_uri = g_strdup (local_uri);
+}
+
+void   
+qname_shutdown (void)
+{
+        g_free (local_uri);
+}
+
+gchar *
+qname_to_link (const gchar *qname)
+{
+        gchar **pieces;
+        gchar *name;
+
+        if (local_uri) {
+                /* There is a local URI! */
+                if (g_str_has_prefix (qname, local_uri)) {
+                        pieces = g_strsplit (qname, "#", 2);
+                        g_assert (g_strv_length (pieces) == 2);
+                        name = g_strdup_printf ("#%s", pieces[1]);
+                        g_strfreev (pieces);
+                        return name;
+                }
+        }
+        
+        return g_strdup (qname);
+}
+
+gchar *
+qname_to_shortname (const gchar *qname)
+{
+        gchar **pieces;
+        gchar  *name = NULL;
+        gint    i;
+
+        for (i = 0; NAMESPACES[i].namespace != NULL; i++) {
+                if (g_str_has_prefix (qname, NAMESPACES[i].uri)) {
+                        pieces = g_strsplit (qname, "#", 2);
+                        if (g_strv_length (pieces) != 2) {
+                                g_warning ("Unable to get the shortname for %s", qname);
+                                break;
+                        }
+
+                        name = g_strdup_printf ("%s:%s", 
+                                                NAMESPACES[i].namespace, 
+                                                pieces[1]);
+                        g_strfreev (pieces);
+                        break;
+                }
+        }
+
+        if (!name) {
+                return g_strdup (qname);
+        } else {
+                return name;
+        }
+}
+
+gboolean 
+qname_is_basic_type (const gchar *qname)
+{
+        gint i; 
+        /* dc: or xsd: are basic types */
+        for (i = 0; NAMESPACES[i].namespace != NULL && i < 3; i++) {
+                if (g_str_has_prefix (qname, NAMESPACES[i].uri)) {
+                        return TRUE;
+                }
+        }
+        return FALSE;
+}
diff --git a/utils/services/qname.h b/utils/services/qname.h
new file mode 100644
index 0000000..1518402
--- /dev/null
+++ b/utils/services/qname.h
@@ -0,0 +1,19 @@
+#ifndef __TTL_QNAME_H__
+#define __TTL_QNAME_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+void     qname_init          (const gchar *local_uri);
+void     qname_shutdown      (void);
+
+gchar *  qname_to_link       (const gchar *qname);
+gchar *  qname_to_shortname  (const gchar *qname);
+
+gboolean qname_is_basic_type (const gchar *qname);
+
+
+G_END_DECLS
+
+#endif
diff --git a/utils/services/ttl2graphviz.c b/utils/services/ttl2graphviz.c
new file mode 100644
index 0000000..0270f94
--- /dev/null
+++ b/utils/services/ttl2graphviz.c
@@ -0,0 +1,87 @@
+#include <glib.h>
+#include <gio/gio.h>
+#include <string.h>
+#include <stdio.h>
+#include "ttl_loader.h"
+#include "ttl_model.h"
+#include "ttl_graphviz.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 graphviz 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);
+
+        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_graphviz_print (description, ontology, f);
+
+        ttl_loader_free_ontology (ontology);
+        ttl_loader_free_description (description);
+
+        g_option_context_free (context);
+        
+        fclose (f);
+
+        return 0;
+}
diff --git a/utils/services/ttl_graphviz.c b/utils/services/ttl_graphviz.c
new file mode 100644
index 0000000..c0dd182
--- /dev/null
+++ b/utils/services/ttl_graphviz.c
@@ -0,0 +1,82 @@
+#include "ttl_graphviz.h"
+#include <glib.h>
+#include <glib/gprintf.h>
+#include "qname.h"
+
+static void
+generate_class_nodes (gpointer key, gpointer value, gpointer user_data)
+{
+        FILE *output = (FILE *)user_data;
+        OntologyClass *klass = (OntologyClass *)value;
+        GList *it = NULL;
+
+        g_fprintf (output, "\t \"%s\" [fillcolor=\"greenyellow\"];\n",
+                   qname_to_shortname (klass->classname));
+
+        for (it = klass->superclasses; it != NULL; it = it->next) {
+                g_fprintf (output, 
+                           "\t \"%s\" -> \"%s\" [arrowhead=\"empty\"];\n",
+                           qname_to_shortname (klass->classname),
+                           qname_to_shortname (it->data));
+                
+        }
+}
+
+static void
+generate_property_edges (gpointer key, gpointer value, gpointer user_data)
+{
+        FILE *output = (FILE *)user_data;
+        OntologyProperty *prop = (OntologyProperty *)value;
+        static gint counter = 0;
+
+        g_assert (g_list_length (prop->domain) == 1);
+        g_assert (g_list_length (prop->range) == 1);
+
+        if (qname_is_basic_type (prop->range->data)) {
+/*
+ "_str_1" [label="_str_", shape="box"];
+ "nfo:Video" ->  "_str_1" [label="name"];
+*/
+                g_fprintf (output, 
+                           "\t \"_str_%d\" [label=\"%s\", shape=\"box\", fontsize=\"8\", height=\"0.2\"];\n",
+                           counter,
+                           qname_to_shortname (prop->range->data));
+                g_fprintf (output, 
+                           "\t \"%s\" -> \"_str_%d\" [label=\"%s\"];\n",
+                           qname_to_shortname (prop->domain->data),
+                           counter,
+                           qname_to_shortname (prop->propertyname));
+                counter += 1;
+                
+        } else {
+                g_fprintf (output, 
+                           "\t \"%s\" -> \"%s\" [label=\"%s\"];\n",
+                           qname_to_shortname (prop->domain->data),
+                           qname_to_shortname (prop->range->data),
+                           qname_to_shortname (prop->propertyname));
+        }
+}
+
+
+void 
+ttl_graphviz_print (OntologyDescription *description,
+                    Ontology *ontology,
+                    FILE *output)
+{
+
+        g_fprintf (output, "digraph \"%s\" {\n",  description->title);
+        g_fprintf (output, "    label=\"%s\";\n", description->title);
+        g_fprintf (output, "    rankdir=BT;\n");
+        g_fprintf (output, "    node [style=filled];\n");
+
+        g_hash_table_foreach (ontology->classes,
+                              generate_class_nodes,
+                              output);
+
+        g_hash_table_foreach (ontology->properties,
+                              generate_property_edges,
+                              output);
+
+        g_fprintf (output, "}\n");
+
+}
diff --git a/utils/services/ttl_graphviz.h b/utils/services/ttl_graphviz.h
new file mode 100644
index 0000000..8d77d03
--- /dev/null
+++ b/utils/services/ttl_graphviz.h
@@ -0,0 +1,18 @@
+#ifndef __TTL_GRAPHVIZ_H__
+#define __TTL_GRAPHVIZ_H__
+
+#include <gio/gio.h>
+#include "ttl_model.h"
+#include <stdio.h>
+
+G_BEGIN_DECLS
+
+void ttl_graphviz_print (OntologyDescription *description,
+                         Ontology *ontology,
+                         FILE *output);
+
+
+
+G_END_DECLS
+
+#endif
diff --git a/utils/services/ttl_html.c b/utils/services/ttl_html.c
index f7fe08c..1d8d604 100644
--- a/utils/services/ttl_html.c
+++ b/utils/services/ttl_html.c
@@ -1,33 +1,6 @@
 #include "ttl_html.h"
 #include <glib/gprintf.h>
-
-static gchar *local_uri = NULL;
-
-typedef struct {
-        const gchar *namespace;
-        const gchar *uri;
-} Namespace;
-
-Namespace NAMESPACES [] = {
-        {"dc", "http://purl.org/dc/elements/1.1/"},
-        {"fts", "http://www.tracker-project.org/ontologies/fts#"},
-        {"mto", "http://www.tracker-project.org/temp/mto#"},
-        {"mlo", "http://www.tracker-project.org/temp/mlo#"},
-        {"nao", "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#"},
-        {"ncal", "http://www.semanticdesktop.org/ontologies/2007/04/02/ncal#"},
-        {"nco", "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#"},
-        {"nfo", "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#"},
-        {"nid3", "http://www.semanticdesktop.org/ontologies/2007/05/10/nid3#"},
-        {"nie", "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#"},
-        {"nmm", "http://www.tracker-project.org/temp/nmm#"},
-        {"nmo", "http://www.semanticdesktop.org/ontologies/2007/03/22/nmo#"},
-        {"nrl", "http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#"},
-        {"rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"},
-        {"rdfs", "http://www.w3.org/2000/01/rdf-schema#"},
-        {"tracker", "http://www.tracker-project.org/ontologies/tracker#"},
-        {"xsd", "http://www.w3.org/2001/XMLSchema#"},
-        {NULL, NULL}
-};
+#include "qname.h"
 
 typedef struct {
         Ontology *ontology;
@@ -35,55 +8,6 @@ typedef struct {
         FILE *output;
 } CallbackInfo;
 
-static gchar *
-qname_to_link (const gchar *qname)
-{
-        gchar **pieces;
-        gchar *name;
-
-        if (local_uri) {
-                /* There is a local URI! */
-                if (g_str_has_prefix (qname, local_uri)) {
-                        pieces = g_strsplit (qname, "#", 2);
-                        g_assert (g_strv_length (pieces) == 2);
-                        name = g_strdup_printf ("#%s", pieces[1]);
-                        g_strfreev (pieces);
-                        return name;
-                }
-        }
-        
-        return g_strdup (qname);
-}
-
-static gchar *
-qname_to_shortname (const gchar *qname)
-{
-        gchar **pieces;
-        gchar  *name = NULL;
-        gint    i;
-
-        for (i = 0; NAMESPACES[i].namespace != NULL; i++) {
-                if (g_str_has_prefix (qname, NAMESPACES[i].uri)) {
-                        pieces = g_strsplit (qname, "#", 2);
-                        if (g_strv_length (pieces) != 2) {
-                                g_warning ("Unable to get the shortname for %s", qname);
-                                break;
-                        }
-
-                        name = g_strdup_printf ("%s:%s", 
-                                                NAMESPACES[i].namespace, 
-                                                pieces[1]);
-                        g_strfreev (pieces);
-                        break;
-                }
-        }
-
-        if (!name) {
-                return g_strdup (qname);
-        } else {
-                return name;
-        }
-}
 
 static void
 print_author (gpointer item, gpointer user_data) {
@@ -286,7 +210,7 @@ ttl_html_print (OntologyDescription *description,
                 FILE *f)
 {
 
-        local_uri = description->baseUrl;
+        qname_init (description->baseUrl);
         print_html_header (f, description);
         g_fprintf (f,"<h2>Ontology Classes Descriptions</h2>");
         g_hash_table_foreach (ontology->classes, print_ontology_class, f);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]