[tracker/wip/sam/resource-jsonld: 5/6] Generate correct JSON-LD contexts



commit eb8873a67090adc57202b4b74c693fe31c9252aa
Author: Sam Thursfield <sam afuera me uk>
Date:   Wed Jul 6 22:10:24 2016 +0100

    Generate correct JSON-LD contexts
    
    also fix docstrings, and be consistent about namespace handling.

 src/libtracker-sparql/tracker-namespace-manager.c |   20 +++++++
 src/libtracker-sparql/tracker-namespace-manager.h |    2 +
 src/libtracker-sparql/tracker-resource.c          |   60 +++++++++++++++++----
 src/libtracker-sparql/tracker-resource.h          |    2 +-
 src/tracker-extract/tracker-extract.c             |    2 +-
 5 files changed, 74 insertions(+), 12 deletions(-)
---
diff --git a/src/libtracker-sparql/tracker-namespace-manager.c 
b/src/libtracker-sparql/tracker-namespace-manager.c
index 91fc449..a1b3e7c 100644
--- a/src/libtracker-sparql/tracker-namespace-manager.c
+++ b/src/libtracker-sparql/tracker-namespace-manager.c
@@ -309,3 +309,23 @@ tracker_namespace_manager_print_turtle (TrackerNamespaceManager *self)
 
        return g_string_free (result, FALSE);
 }
+
+/**
+ * tracker_namespace_manager_foreach:
+ * @self: a #TrackerNamespaceManager
+ * @func: the function to call for each prefix / URI pair
+ * @user_data: user data to pass to the function
+ *
+ * Calls @func for each known prefix / URI pair.
+ *
+ * Since: 1.10
+ */
+void
+tracker_namespace_manager_foreach (TrackerNamespaceManager *self,
+                                   GHFunc                   func,
+                                   gpointer                 user_data)
+{
+       TrackerNamespaceManagerPrivate *priv = GET_PRIVATE (self);
+
+       g_hash_table_foreach (priv->prefix_to_namespace, func, user_data);
+};
diff --git a/src/libtracker-sparql/tracker-namespace-manager.h 
b/src/libtracker-sparql/tracker-namespace-manager.h
index 2a6e45e..0f539d4 100644
--- a/src/libtracker-sparql/tracker-namespace-manager.h
+++ b/src/libtracker-sparql/tracker-namespace-manager.h
@@ -43,6 +43,8 @@ void tracker_namespace_manager_add_prefix (TrackerNamespaceManager *self, const
 
 char *tracker_namespace_manager_print_turtle (TrackerNamespaceManager *self);
 
+void tracker_namespace_manager_foreach (TrackerNamespaceManager *self, GHFunc func, gpointer user_data);
+
 G_END_DECLS
 
 #endif /* __LIBTRACKER_SPARQL_NAMESPACE_MANAGER_H__ */
diff --git a/src/libtracker-sparql/tracker-resource.c b/src/libtracker-sparql/tracker-resource.c
index 33e6fcd..17d42a0 100644
--- a/src/libtracker-sparql/tracker-resource.c
+++ b/src/libtracker-sparql/tracker-resource.c
@@ -1138,6 +1138,7 @@ tracker_resource_print_sparql_update (TrackerResource         *resource,
 }
 
 typedef struct {
+       TrackerNamespaceManager *all_namespaces, *our_namespaces;
        JsonBuilder *builder;
        GList *done_list;
 } GenerateJsonldData;
@@ -1148,14 +1149,10 @@ static void
 tracker_resource_generate_jsonld (TrackerResource    *self,
                                   GenerateJsonldData *data)
 {
-       /* FIXME: generate a JSON-LD context ! */
-
        TrackerResourcePrivate *priv = GET_PRIVATE (self);
        JsonBuilder *builder = data->builder;
        JsonNode *result;
 
-       json_builder_begin_object (builder);
-
        /* The JSON-LD spec says it is "important that nodes have an identifier", but
         * doesn't mandate one. I think it's better to omit the ID for blank nodes
         * (where the caller passed NULL as an identifier) than to emit something
@@ -1167,8 +1164,6 @@ tracker_resource_generate_jsonld (TrackerResource    *self,
        }
 
        g_hash_table_foreach (priv->properties, generate_jsonld_foreach, data);
-
-       json_builder_end_object (builder);
 };
 
 static void
@@ -1183,8 +1178,12 @@ generate_jsonld_value (const GValue       *value,
                resource = TRACKER_RESOURCE (g_value_get_object (value));
 
                if (g_list_find_custom (data->done_list, resource, (GCompareFunc) tracker_resource_compare) 
== NULL) {
+                       json_builder_begin_object (data->builder);
+
                        tracker_resource_generate_jsonld (resource, data);
 
+                       json_builder_end_object (data->builder);
+
                        data->done_list = g_list_prepend (data->done_list, resource);
                } else {
                        json_builder_add_string_value (data->builder, 
tracker_resource_get_identifier(resource));
@@ -1196,6 +1195,7 @@ generate_jsonld_value (const GValue       *value,
                 * string manually here.
                 */
                const char *uri = g_value_get_string (value);
+               maybe_intern_prefix_of_compact_uri (data->all_namespaces, data->our_namespaces, uri);
                node = json_node_new (JSON_NODE_VALUE);
                json_node_set_string (node, uri);
                json_builder_add_value (data->builder, node);
@@ -1218,9 +1218,12 @@ generate_jsonld_foreach (gpointer key,
 
        if (strcmp (property, "rdf:type") == 0) {
                property = "@type";
+       } else {
+               maybe_intern_prefix_of_compact_uri (data->all_namespaces, data->our_namespaces, property);
        }
 
        json_builder_set_member_name (builder, property);
+
        if (G_VALUE_HOLDS (value, G_TYPE_PTR_ARRAY)) {
                json_builder_begin_array (builder);
                g_ptr_array_foreach (g_value_get_boxed (value), (GFunc) generate_jsonld_value, data);
@@ -1230,32 +1233,69 @@ generate_jsonld_foreach (gpointer key,
        }
 }
 
+static void
+generate_jsonld_namespace_mapping_foreach (gpointer key,
+                                           gpointer value,
+                                           gpointer user_data)
+{
+       GenerateJsonldData *data = user_data;
+
+       json_builder_set_member_name (data->builder, key);
+       json_builder_add_string_value (data->builder, value);
+}
+
+
 /**
  * tracker_resource_print_jsonld:
  * @resource: a #TrackerResource
- * @error: address where an error can be returned
+ * @namespaces: (allow-none): a set of prefixed URLs, or %NULL to use the
+ *     default set
  *
  * Serialize all the information in @resource as a JSON-LD document.
  *
  * See <http://www.jsonld.org/> for more information on the JSON-LD
  * serialization format.
  *
- * Returns: a newly-allocated string
+ * The @namespaces object is used to expand any compact URI values. In most
+ * cases you should pass %NULL, which means the set of namespaces returned by
+ * tracker_namespace_manager_get_default() will be used. This defines the
+ * usual prefixes for all of the ontologies that Tracker ships with by default.
+ *
+ * Returns: a newly-allocated string containing JSON-LD data.
  *
  * Since: 1.10
  */
 char *
-tracker_resource_print_jsonld (TrackerResource *resource)
+tracker_resource_print_jsonld (TrackerResource         *resource,
+                               TrackerNamespaceManager *namespaces)
 {
        GenerateJsonldData context;
        JsonNode *json_root_node;
        JsonGenerator *generator;
        char *result;
 
-       context.done_list = NULL;
+       if (namespaces == NULL) {
+               namespaces = tracker_namespace_manager_get_default ();
+       }
+
+       context.all_namespaces = namespaces;
+       context.our_namespaces = tracker_namespace_manager_new ();
        context.builder = json_builder_new ();
+       context.done_list = NULL;
+
+       maybe_intern_prefix_of_compact_uri (context.all_namespaces, context.our_namespaces, 
tracker_resource_get_identifier (resource));
+
+       json_builder_begin_object (context.builder);
 
        tracker_resource_generate_jsonld (resource, &context);
+
+       json_builder_set_member_name (context.builder, "@context");
+       json_builder_begin_object (context.builder);
+       tracker_namespace_manager_foreach (context.our_namespaces, generate_jsonld_namespace_mapping_foreach, 
&context);
+       json_builder_end_object (context.builder);
+
+       json_builder_end_object (context.builder);
+
        json_root_node = json_builder_get_root (context.builder);
 
        generator = json_generator_new ();
diff --git a/src/libtracker-sparql/tracker-resource.h b/src/libtracker-sparql/tracker-resource.h
index c3a7221..e7c0a07 100644
--- a/src/libtracker-sparql/tracker-resource.h
+++ b/src/libtracker-sparql/tracker-resource.h
@@ -77,7 +77,7 @@ char *tracker_resource_print_turtle(TrackerResource *self, TrackerNamespaceManag
 
 char *tracker_resource_print_sparql_update (TrackerResource *self, TrackerNamespaceManager *namespaces, 
const char *graph_id);
 
-char *tracker_resource_print_jsonld (TrackerResource *self);
+char *tracker_resource_print_jsonld (TrackerResource *self, TrackerNamespaceManager *namespaces);
 
 G_END_DECLS
 
diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c
index 65d3141..7e1bf7b 100644
--- a/src/tracker-extract/tracker-extract.c
+++ b/src/tracker-extract/tracker-extract.c
@@ -819,7 +819,7 @@ tracker_extract_get_metadata_by_cmdline (TrackerExtract             *object,
                                 */
                                tracker_resource_set_identifier (resource, uri);
 
-                               json = tracker_resource_print_jsonld (resource);
+                               json = tracker_resource_print_jsonld (resource, NULL);
                                if (json) {
                                        g_print ("%s\n", json);
                                        g_free (json);


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