diff options
Diffstat (limited to 'src/world.c')
-rw-r--r-- | src/world.c | 446 |
1 files changed, 189 insertions, 257 deletions
diff --git a/src/world.c b/src/world.c index f32dfaa..9657805 100644 --- a/src/world.c +++ b/src/world.c @@ -24,7 +24,6 @@ #ifdef SLV2_DYN_MANIFEST #include <dlfcn.h> #endif -#include <redland.h> #include "slv2/types.h" #include "slv2/world.h" #include "slv2/slv2.h" @@ -32,32 +31,36 @@ #include "slv2-config.h" #include "slv2_internal.h" +static void +slv2_world_set_prefix(SLV2World world, const char* name, const char* uri) +{ + const SerdNode name_node = serd_node_from_string(SERD_LITERAL, + (const uint8_t*)name); + const SerdNode uri_node = serd_node_from_string(SERD_URI, + (const uint8_t*)uri); + serd_env_add(world->namespaces, &name_node, &uri_node); +} + /* private */ static SLV2World slv2_world_new_internal(SLV2World world) { assert(world); - assert(world->world); - - world->storage = slv2_world_new_storage(world); - if (!world->storage) - goto fail; - world->model = librdf_new_model(world->world, world->storage, NULL); + world->model = sord_new(); if (!world->model) goto fail; - world->parser = librdf_new_parser(world->world, "turtle", NULL, NULL); - if (!world->parser) + if (!sord_open(world->model)) goto fail; - + world->plugin_classes = slv2_plugin_classes_new(); world->plugins = slv2_plugins_new(); #define NS_DYNMAN (const uint8_t*)"http://lv2plug.in/ns/ext/dynmanifest#" -#define NEW_URI(uri) librdf_new_node_from_uri_string(world->world, uri); +#define NEW_URI(uri) sord_get_uri(world->model, true, (const char*)uri) world->dyn_manifest_node = NEW_URI(NS_DYNMAN "DynManifest"); world->lv2_specification_node = NEW_URI(SLV2_NS_LV2 "Specification"); @@ -84,15 +87,17 @@ slv2_world_new_internal(SLV2World world) world->lv2_plugin_class = slv2_plugin_class_new( world, NULL, world->lv2_plugin_node, "Plugin"); + assert(world->lv2_plugin_class); + + world->namespaces = serd_env_new(); + slv2_world_set_prefix(world, "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); + slv2_world_set_prefix(world, "rdfs", "http://www.w3.org/2000/01/rdf-schema#"); + slv2_world_set_prefix(world, "doap", "http://usefulinc.com/ns/doap#"); + slv2_world_set_prefix(world, "foaf", "http://xmlns.com/foaf/0.1/"); + slv2_world_set_prefix(world, "lv2", "http://lv2plug.in/ns/lv2core#"); + slv2_world_set_prefix(world, "lv2ev", "http://lv2plug.in/ns/ext/event#"); - world->namespaces = librdf_new_hash_from_string( - world->world, NULL, - "rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'," - "rdfs='http://www.w3.org/2000/01/rdf-schema#'," - "doap='http://usefulinc.com/ns/doap#'," - "foaf='http://xmlns.com/foaf/0.1/'," - "lv2='http://lv2plug.in/ns/lv2core#'," - "lv2ev='http://lv2plug.in/ns/ext/event#'"); + world->n_read_files = 0; return world; @@ -102,57 +107,10 @@ fail: } -/* private */ -librdf_storage* -slv2_world_new_storage(SLV2World world) -{ - static bool warned = false; - librdf_hash* options = librdf_new_hash_from_string(world->world, NULL, - "index-spo='yes',index-ops='yes'"); - librdf_storage* ret = librdf_new_storage_with_options( - world->world, "trees", NULL, options); - if (!ret) { - warned = true; - SLV2_WARN("Unable to create \"trees\" RDF storage, you should upgrade librdf.\n"); - ret = librdf_new_storage(world->world, "hashes", NULL, - "hash-type='memory'"); - } - - librdf_free_hash(options); - return ret; -} - - SLV2World slv2_world_new() { SLV2World world = (SLV2World)malloc(sizeof(struct _SLV2World)); - - world->world = librdf_new_world(); - if (!world->world) { - free(world); - return NULL; - } - - world->local_world = true; - - librdf_world_open(world->world); - - return slv2_world_new_internal(world); -} - - -SLV2World -slv2_world_new_using_rdf_world(librdf_world* rdf_world) -{ - if (rdf_world == NULL) - return slv2_world_new(); - - SLV2World world = (SLV2World)malloc(sizeof(struct _SLV2World)); - - world->world = rdf_world; - world->local_world = false; - return slv2_world_new_internal(world); } @@ -194,51 +152,82 @@ slv2_world_free(SLV2World world) raptor_free_sequence(world->plugin_classes); world->plugin_classes = NULL; - librdf_free_parser(world->parser); - world->parser = NULL; - - librdf_free_model(world->model); + sord_free(world->model); world->model = NULL; - librdf_free_storage(world->storage); - world->storage = NULL; + serd_env_free(world->namespaces); - librdf_free_hash(world->namespaces); + free(world); +} - if (world->local_world) - librdf_free_world(world->world); - world->world = NULL; +static SLV2Matches +slv2_world_find_statements(SLV2World world, + Sord model, + SLV2Node subject, + SLV2Node predicate, + SLV2Node object, + SLV2Node graph) +{ + SordTuple pat = { subject, predicate, object, graph }; + return sord_find(model, pat); +} - free(world); +static SerdNode +slv2_new_uri_relative_to_base(const uint8_t* uri_str, const uint8_t* base_uri_str) +{ + SerdURI uri; + if (!serd_uri_parse(uri_str, &uri)) { + return SERD_NODE_NULL; + } + + SerdURI base_uri; + if (!serd_uri_parse(base_uri_str, &base_uri)) { + return SERD_NODE_NULL; + } + + SerdURI abs_uri; + if (!serd_uri_resolve(&uri, &base_uri, &abs_uri)) { + return SERD_NODE_NULL; + } + + SerdURI ignored; + return serd_node_new_uri(&abs_uri, &ignored); +} + +const uint8_t* +slv2_world_blank_node_prefix(SLV2World world) +{ + static char str[32]; + snprintf(str, sizeof(str), "%d", world->n_read_files++); + return (const uint8_t*)str; } -/** Load the entire contents of a file into the world model. - */ -void -slv2_world_load_file(SLV2World world, librdf_uri* file_uri) +/** Comparator for sorting SLV2Plugins */ +int +slv2_plugin_compare_by_uri(const void* a, const void* b) { - librdf_parser_parse_into_model(world->parser, file_uri, file_uri, world->model); + SLV2Plugin plugin_a = *(SLV2Plugin*)a; + SLV2Plugin plugin_b = *(SLV2Plugin*)b; + + return strcmp(slv2_value_as_uri(plugin_a->plugin_uri), + slv2_value_as_uri(plugin_b->plugin_uri)); } -static SLV2Matches -slv2_world_find_statements(SLV2World world, - librdf_model* model, - SLV2Node subject, - SLV2Node predicate, - SLV2Node object) + +/** Comparator for sorting SLV2PluginClasses */ +int +slv2_plugin_class_compare_by_uri(const void* a, const void* b) { - librdf_statement* q = librdf_new_statement_from_nodes( - world->world, - subject ? slv2_node_copy(subject) : NULL, - predicate ? slv2_node_copy(predicate) : NULL, - object ? slv2_node_copy(object) : NULL); - SLV2Matches results = librdf_model_find_statements(model, q); - librdf_free_statement(q); - return results; + SLV2PluginClass class_a = *(SLV2PluginClass*)a; + SLV2PluginClass class_b = *(SLV2PluginClass*)b; + + return strcmp(slv2_value_as_uri(class_a->uri), + slv2_value_as_uri(class_b->uri)); } + void slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri) { @@ -247,17 +236,14 @@ slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri) return; } - librdf_uri* manifest_uri = librdf_new_uri_relative_to_base( - librdf_node_get_uri(bundle_uri->val.uri_val), - (const uint8_t*)"manifest.ttl"); + const SordNode bundle_node = bundle_uri->val.uri_val; - /* Parse the manifest into a temporary model */ - librdf_storage* manifest_storage = slv2_world_new_storage(world); + SerdNode manifest_uri = slv2_new_uri_relative_to_base( + (const uint8_t*)"manifest.ttl", + (const uint8_t*)sord_node_get_string(bundle_node)); - librdf_model* manifest_model = librdf_new_model(world->world, - manifest_storage, NULL); - librdf_parser_parse_into_model(world->parser, manifest_uri, - manifest_uri, manifest_model); + sord_read_file(world->model, manifest_uri.buf, bundle_node, + slv2_world_blank_node_prefix(world)); #ifdef SLV2_DYN_MANIFEST typedef void* LV2_Dyn_Manifest_Handle; @@ -267,14 +253,15 @@ slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri) world, world->model, NULL, world->rdf_a_node, - world->dyn_manifest_node); + world->dyn_manifest_node, + bundle_node); FOREACH_MATCH(dmanifests) { SLV2Node dmanifest = slv2_match_subject(dmanifests); SLV2Matches binaries = slv2_world_find_statements( world, world->model, dmanifest, world->lv2_binary_node, - NULL); + bundle_node); if (slv2_matches_end(binaries)) { slv2_match_end(binaries); SLV2_ERRORF("Dynamic manifest in <%s> has no binaries, ignored\n", @@ -283,7 +270,7 @@ slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri) } SLV2Node binary = slv2_node_copy(slv2_match_object(binaries)); - const uint8_t* lib_uri = librdf_uri_as_string(librdf_node_get_uri(binary)); + const uint8_t* lib_uri = sord_node_get_string(binary); const char* lib_path = slv2_uri_to_path((const char*)lib_uri); if (!lib_path) continue; @@ -323,14 +310,15 @@ slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri) world, dyn_manifest_model, NULL, world->rdf_a_node, - world->lv2_plugin_node); + world->lv2_plugin_node, + bundle_node); FOREACH_MATCH(dyn_plugins) { SLV2Node plugin = slv2_match_subject(dyn_plugins); // Add ?plugin slv2:dynamic-manifest ?binary to dynamic model librdf_model_add( manifest_model, plugin, - librdf_new_node_from_uri_string(world->world, SLV2_NS_RDFS "seeAlso"), + world->slv2_dmanifest_node, slv2_node_copy(binary)); } slv2_match_end(dyn_plugins); @@ -346,63 +334,85 @@ slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri) #endif // SLV2_DYN_MANIFEST // ?plugin a lv2:Plugin - SLV2Matches results = slv2_world_find_statements( - world, manifest_model, + SLV2Matches plug_results = slv2_world_find_statements( + world, world->model, NULL, world->rdf_a_node, - world->lv2_plugin_node); - FOREACH_MATCH(results) { - SLV2Node plugin = slv2_match_subject(results); - - // Add ?plugin rdfs:seeAlso <manifest.ttl> - librdf_model_add( - world->model, - slv2_node_copy(plugin), - librdf_new_node_from_uri_string(world->world, SLV2_NS_RDFS "seeAlso"), - librdf_new_node_from_uri(world->world, manifest_uri)); - - // Add ?plugin slv2:bundleURI <file://some/path> - librdf_model_add( - world->model, - slv2_node_copy(plugin), - librdf_new_node_from_uri_string(world->world, SLV2_NS_SLV2 "bundleURI"), - slv2_node_copy(bundle_uri->val.uri_val)); + world->lv2_plugin_node, + bundle_node); + FOREACH_MATCH(plug_results) { + SLV2Node plugin_node = slv2_match_subject(plug_results); + SLV2Value plugin_uri = slv2_value_new_from_node(world, plugin_node); + + //fprintf(stderr, "Add <%s> in %s\n", sord_node_get_string(plugin_node), + // sord_node_get_string(bundle_uri->val.uri_val)); + + SLV2Plugin existing = slv2_plugins_get_by_uri(world->plugins, plugin_uri); + if (existing) { + SLV2_ERRORF("Duplicate plugin <%s>\n", slv2_value_as_uri(plugin_uri)); + SLV2_ERRORF("... found in %s\n", slv2_value_as_string( + slv2_plugin_get_bundle_uri(existing))); + SLV2_ERRORF("... and %s\n", sord_node_get_string(bundle_node)); + slv2_value_free(plugin_uri); + continue; + } + + // Create SLV2Plugin + SLV2Value bundle_uri = slv2_value_new_from_node(world, bundle_node); + SLV2Plugin plugin = slv2_plugin_new(world, plugin_uri, bundle_uri); + + // Add manifest as plugin data file (as if it were rdfs:seeAlso) + raptor_sequence_push(plugin->data_uris, + slv2_value_new_uri(world, (const char*)manifest_uri.buf)); + + // Add all plugin data files (rdfs:seeAlso) + SLV2Matches files = slv2_world_find_statements( + world, world->model, + plugin_node, + world->rdfs_seealso_node, + NULL, + NULL); + FOREACH_MATCH(files) { + SLV2Node file_node = slv2_match_object(files); + raptor_sequence_push(plugin->data_uris, + slv2_value_new_from_node(world, file_node)); + } + + // Add plugin to world plugin list + raptor_sequence_push(world->plugins, plugin); + raptor_sequence_sort(world->plugins, slv2_plugin_compare_by_uri); } - slv2_match_end(results); + slv2_match_end(plug_results); // ?specification a lv2:Specification - results = slv2_world_find_statements( - world, manifest_model, + SLV2Matches spec_results = slv2_world_find_statements( + world, world->model, NULL, world->rdf_a_node, - world->lv2_specification_node); - FOREACH_MATCH(results) { - SLV2Node spec = slv2_match_subject(results); + world->lv2_specification_node, + bundle_node); + FOREACH_MATCH(spec_results) { + SLV2Node spec = slv2_match_subject(spec_results); // Add ?specification rdfs:seeAlso <manifest.ttl> - librdf_model_add( - world->model, + SordTuple see_also_tup = { slv2_node_copy(spec), - librdf_new_node_from_uri_string(world->world, SLV2_NS_RDFS "seeAlso"), - librdf_new_node_from_uri(world->world, manifest_uri)); + world->rdfs_seealso_node, + sord_get_uri(world->model, true, (const char*)manifest_uri.buf), + NULL + }; + sord_add(world->model, see_also_tup); // Add ?specification slv2:bundleURI <file://some/path> - librdf_model_add( - world->model, + SordTuple bundle_uri_tup = { slv2_node_copy(spec), - librdf_new_node_from_uri_string(world->world, SLV2_NS_SLV2 "bundleURI"), - slv2_node_copy(bundle_uri->val.uri_val)); + slv2_node_copy(world->slv2_bundleuri_node), + slv2_node_copy(bundle_uri->val.uri_val), + NULL + }; + sord_add(world->model, bundle_uri_tup); } - slv2_match_end(results); - - // Join the temporary model to the main model - librdf_stream* manifest_stream = librdf_model_as_stream(manifest_model); - librdf_model_add_statements(world->model, manifest_stream); - librdf_free_stream(manifest_stream); - - librdf_free_model(manifest_model); - librdf_free_storage(manifest_storage); - librdf_free_uri(manifest_uri); + slv2_match_end(spec_results); } @@ -463,30 +473,6 @@ slv2_world_load_path(SLV2World world, } -/** Comparator for sorting SLV2Plugins */ -int -slv2_plugin_compare_by_uri(const void* a, const void* b) -{ - SLV2Plugin plugin_a = *(SLV2Plugin*)a; - SLV2Plugin plugin_b = *(SLV2Plugin*)b; - - return strcmp(slv2_value_as_uri(plugin_a->plugin_uri), - slv2_value_as_uri(plugin_b->plugin_uri)); -} - - -/** Comparator for sorting SLV2PluginClasses */ -int -slv2_plugin_class_compare_by_uri(const void* a, const void* b) -{ - SLV2PluginClass class_a = *(SLV2PluginClass*)a; - SLV2PluginClass class_b = *(SLV2PluginClass*)b; - - return strcmp(slv2_value_as_uri(class_a->uri), - slv2_value_as_uri(class_b->uri)); -} - - void slv2_world_load_specifications(SLV2World world) { @@ -494,17 +480,22 @@ slv2_world_load_specifications(SLV2World world) world, world->model, NULL, world->rdf_a_node, - world->lv2_specification_node); + world->lv2_specification_node, + NULL); FOREACH_MATCH(specs) { SLV2Node spec_node = slv2_match_subject(specs); SLV2Matches files = slv2_world_find_statements( world, world->model, spec_node, world->rdfs_seealso_node, + NULL, NULL); FOREACH_MATCH(files) { SLV2Node file_node = slv2_match_object(files); - slv2_world_load_file(world, librdf_node_get_uri(file_node)); + sord_read_file(world->model, + (const uint8_t*)sord_node_get_string(file_node), + NULL, + slv2_world_blank_node_prefix(world)); } slv2_match_end(files); } @@ -525,7 +516,8 @@ slv2_world_load_plugin_classes(SLV2World world) world, world->model, NULL, world->rdf_a_node, - world->rdfs_class_node); + world->rdfs_class_node, + NULL); FOREACH_MATCH(classes) { SLV2Node class_node = slv2_match_subject(classes); @@ -534,6 +526,7 @@ slv2_world_load_plugin_classes(SLV2World world) world, world->model, class_node, world->rdfs_subclassof_node, + NULL, NULL); if (slv2_matches_end(parents)) { @@ -544,7 +537,7 @@ slv2_world_load_plugin_classes(SLV2World world) SLV2Node parent_node = slv2_node_copy(slv2_match_object(parents)); slv2_match_end(parents); - if (!librdf_node_is_resource(parent_node)) { + if (!sord_node_get_type(parent_node) == SORD_URI) { // Class parent is not a resource, ignore (e.g. owl restriction) continue; } @@ -554,6 +547,7 @@ slv2_world_load_plugin_classes(SLV2World world) world, world->model, class_node, world->rdfs_label_node, + NULL, NULL); if (slv2_matches_end(labels)) { @@ -562,7 +556,7 @@ slv2_world_load_plugin_classes(SLV2World world) } SLV2Node label_node = slv2_node_copy(slv2_match_object(labels)); - const uint8_t* label = librdf_node_get_literal_value(label_node); + const uint8_t* label = (const uint8_t*)sord_node_get_string(label_node); slv2_match_end(labels); SLV2PluginClasses classes = world->plugin_classes; @@ -573,15 +567,17 @@ slv2_world_load_plugin_classes(SLV2World world) SLV2PluginClass prev = raptor_sequence_get_at(classes, n_classes - 1); assert(strcmp( slv2_value_as_string(slv2_plugin_class_get_uri(prev)), - (const char*)librdf_uri_as_string( - librdf_node_get_uri(class_node))) < 0); + (const char*)sord_node_get_string(class_node)) < 0); } #endif - raptor_sequence_push(classes, - slv2_plugin_class_new(world, - parent_node, - class_node, - (const char*)label)); + SLV2PluginClass pclass = slv2_plugin_class_new(world, + parent_node, + class_node, + (const char*)label); + + if (pclass) { + raptor_sequence_push(classes, pclass); + } slv2_node_free(parent_node); slv2_node_free(label_node); @@ -641,68 +637,18 @@ slv2_world_load_all(SLV2World world) slv2_world_load_plugin_classes(world); - SLV2Matches plugins = slv2_world_find_statements( - world, world->model, - NULL, - world->rdf_a_node, - world->lv2_plugin_node); - FOREACH_MATCH(plugins) { - SLV2Node plugin_node = slv2_match_subject(plugins); - const char* plugin_uri = (const char*)librdf_uri_as_string( - librdf_node_get_uri(plugin_node)); - - SLV2Matches bundles = slv2_world_find_statements( - world, world->model, - plugin_node, - world->slv2_bundleuri_node, - NULL); - - if (slv2_matches_end(bundles)) { - slv2_match_end(bundles); - SLV2_ERRORF("Plugin <%s> has no bundle, ignored\n", plugin_uri); - continue; - } - - SLV2Node bundle_node = slv2_node_copy(slv2_match_object(bundles)); - - slv2_matches_next(bundles); - if (!slv2_matches_end(bundles)) { - slv2_match_end(bundles); - SLV2_ERRORF("Plugin <%s> found in several bundles, ignored\n", - plugin_uri); - continue; - } - - slv2_match_end(bundles); - - // Add a new plugin to the world - SLV2Value uri = slv2_value_new_from_node(world, plugin_node); - const unsigned n_plugins = raptor_sequence_size(world->plugins); -#ifndef NDEBUG - if (n_plugins > 0) { - // Plugin results are in increasing sorted order - SLV2Plugin prev = raptor_sequence_get_at(world->plugins, n_plugins - 1); - assert(strcmp(slv2_value_as_string(slv2_plugin_get_uri(prev)), - plugin_uri) < 0); - } -#endif - - SLV2Plugin plugin = slv2_plugin_new( - world, uri, slv2_value_new_from_node(world, bundle_node)); - - raptor_sequence_push(world->plugins, plugin); - +/* FIXME: move this to slv2_world_load_bundle #ifdef SLV2_DYN_MANIFEST { SLV2Matches dmanifests = slv2_world_find_statements( world, world->model, plugin_node, world->slv2_dmanifest_node, + NULL, NULL); FOREACH_MATCH(dmanifests) { SLV2Node lib_node = slv2_match_object(dmanifests); - const char* lib_uri = (const char*)librdf_uri_as_string( - librdf_node_get_uri(lib_node)); + const char* lib_uri = (const char*)sord_node_get_string(lib_node); if (dlopen(slv2_uri_to_path(lib_uri, RTLD_LAZY))) { plugin->dynman_uri = slv2_value_new_from_node(world, lib_node); @@ -711,21 +657,7 @@ slv2_world_load_all(SLV2World world) slv2_match_end(dmanifests); } #endif - SLV2Matches files = slv2_world_find_statements( - world, world->model, - plugin_node, - world->rdfs_seealso_node, - NULL); - FOREACH_MATCH(files) { - SLV2Node file_node = slv2_match_object(files); - raptor_sequence_push(plugin->data_uris, - slv2_value_new_from_node(world, file_node)); - } - slv2_match_end(files); - - slv2_node_free(bundle_node); - } - slv2_match_end(plugins); +*/ } |