Skip to content

Commit

Permalink
Resolve imports when querying rather than on load
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanoBilenchi committed Aug 27, 2024
1 parent 045b92b commit 555bcbe
Show file tree
Hide file tree
Showing 18 changed files with 279 additions and 280 deletions.
10 changes: 5 additions & 5 deletions docs/api/crud/read.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ Handling imports
================

Cowl delegates locating and loading imported ontologies to the end user via the
:struct:`CowlImportLoader` interface. Import loaders can be either provided locally
to specific objects (such as via :func:`cowl_manager_set_import_loader()`),
or you can opt to specify a global import loader via :func:`cowl_set_import_loader`.
If you do both, Cowl prioritizes local loaders, as you would expect.
:struct:`CowlImportResolver` interface. Import resolvers can be provided to :struct:`CowlManager`
instances via :func:`cowl_manager_set_import_resolver()`. By default, :struct:`CowlManager` will
attempt to resolve imports based on the IRIs of ontologies it is currently responsible for,
i.e. those that have been loaded or created through it.

.. doxygenstruct:: CowlImportLoader
.. doxygenstruct:: CowlImportResolver

.. _istream:

Expand Down
28 changes: 13 additions & 15 deletions examples/01_errors_imports.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,9 @@
* the imported ontology from the local filesystem. In this example
* we just return a generic local "import.owl" ontology, disregarding its IRI.
*/
static CowlOntology *load_import(cowl_unused void *ctx, cowl_unused CowlIRI *iri) {
CowlOntology *import = NULL;
CowlManager *manager = cowl_manager();

if (manager) {
import = cowl_manager_read_path(manager, ustring_literal(IMPORT));
cowl_release(manager);
}

return import;
static CowlOntology *resolve_import(void *ctx, cowl_unused CowlIRI *iri) {
// In this example, the manager is passed as the resolver's context.
return cowl_manager_read_path(ctx, ustring_literal(IMPORT));
}

/*
Expand All @@ -51,10 +44,7 @@ int main(void) {
return EXIT_FAILURE;
}

// Setup a global error handler and import loader.
CowlImportLoader loader = { NULL, load_import };
cowl_set_import_loader(loader);

// Setup a global error handler.
UOStream stream;
if (uostream_to_path(&stream, LOG)) {
fprintf(stderr, "Failed to open " LOG "\n");
Expand All @@ -64,13 +54,21 @@ int main(void) {
CowlErrorHandler handler = { &stream, handle_error };
cowl_set_error_handler(handler);

// Read the ontology from file.
CowlManager *manager = cowl_manager();

if (!manager) {
return EXIT_FAILURE;
}

// Setup a custom import resolver.
//
// Note that the manager will already attempt to resolve imports based on the
// IRIs of ontologies it is currently responsible for. A custom resolver is only
// needed if you need to override this behavior.
CowlImportResolver resolver = { manager, resolve_import };
cowl_manager_set_import_resolver(manager, resolver);

// Read the ontology from file.
CowlOntology *onto = cowl_manager_read_path(manager, ustring_literal(ONTO));

if (!onto) {
Expand Down
2 changes: 1 addition & 1 deletion include/cowl.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
#include "cowl_facet_restr.h"
#include "cowl_func_data_prop_axiom.h"
#include "cowl_has_key_axiom.h"
#include "cowl_import_loader.h"
#include "cowl_import_resolver.h"
#include "cowl_individual.h"
#include "cowl_inv_obj_prop.h"
#include "cowl_inv_obj_prop_axiom.h"
Expand Down
19 changes: 0 additions & 19 deletions include/cowl_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

#include "cowl_attrs.h"
#include "cowl_error_handler.h"
#include "cowl_import_loader.h"
#include "cowl_reader.h"
#include "cowl_ret.h"
#include "cowl_writer.h"
Expand Down Expand Up @@ -108,24 +107,6 @@ CowlErrorHandler cowl_get_error_handler(void);
COWL_API
void cowl_set_error_handler(CowlErrorHandler handler);

/**
* Gets the global import loader.
*
* @return The global import loader.
*/
COWL_API
CowlImportLoader cowl_get_import_loader(void);

/**
* Sets the global import loader.
*
* @param loader The import loader.
*
* @note This function must be called again if you reinitialize the library after deinitializing it.
*/
COWL_API
void cowl_set_import_loader(CowlImportLoader loader);

/// @}

COWL_END_DECLS
Expand Down
62 changes: 0 additions & 62 deletions include/cowl_import_loader.h

This file was deleted.

90 changes: 90 additions & 0 deletions include/cowl_import_resolver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Defines CowlImportResolver and declares its API.
*
* @author Ivano Bilenchi
*
* @copyright Copyright (c) 2024 SisInf Lab, Polytechnic University of Bari
* @copyright <http://swot.sisinflab.poliba.it>
* @copyright SPDX-License-Identifier: EPL-2.0
*
* @file
*/

#ifndef COWL_IMPORT_RESOLVER_H
#define COWL_IMPORT_RESOLVER_H

#include "cowl_attrs.h"
#include "cowl_macros.h"

COWL_BEGIN_DECLS

/// @cond
cowl_struct_decl(CowlIRI);
cowl_struct_decl(CowlManager);
cowl_struct_decl(CowlOntology);
/// @endcond

/**
* Provides a mechanism for generic handling of [ontology imports].
*
* The `resolve_import` function should return the ontology associated to the specified
* @type{#CowlIRI}. Imports retrieval and loading is deliberately left to the implementor.
*
* [ontology imports]: https://www.w3.org/TR/owl2-syntax/#Imports
*/
typedef struct CowlImportResolver {

/// Resolver context, can be anything.
void *ctx;

/**
* Pointer to a function that returns the ontology associated to the specified IRI.
*
* @param ctx Resolver context.
* @param iri The IRI.
* @return Imported ontology, or NULL on error.
*
* @note The returned ontology must be retained.
*/
CowlOntology *(*resolve_import)(void *ctx, CowlIRI *iri);

/**
* Pointer to a resource deallocator function.
*
* @param ctx Resolver context.
*
* @note Can be NULL if the resolver does not need to release resources.
*/
void (*free)(void *ctx);

} CowlImportResolver;

/**
* Returns the ontology associated to the specified IRI.
*
* @param resolver The resolver.
* @param iri The IRI.
* @return Imported ontology, or NULL on error.
*/
COWL_RETAINED
COWL_INLINE
CowlOntology *
cowl_import_resolver_resolve_import(CowlImportResolver const *resolver, CowlIRI *iri) {
return resolver->resolve_import(resolver->ctx, iri);
}

/**
* Default import resolver, which looks for the ontology with the specified IRI
* in the manager's ontologies.
*
* @param manager The manager.
* @return Default import resolver.
*
* @note The manager is set as the resolver context, but it is not retained.
*/
COWL_API
CowlImportResolver cowl_import_resolver_default(CowlManager *manager);

COWL_END_DECLS

#endif // COWL_IMPORT_RESOLVER_H
14 changes: 7 additions & 7 deletions include/cowl_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#include "cowl_attrs.h"
#include "cowl_error_handler.h"
#include "cowl_import_loader.h"
#include "cowl_import_resolver.h"
#include "cowl_istream_handlers.h"
#include "cowl_iterator.h"
#include "cowl_macros.h"
Expand Down Expand Up @@ -95,22 +95,22 @@ COWL_API
void cowl_manager_set_writer(CowlManager *manager, CowlWriter writer);

/**
* Gets the import loader.
* Gets the import resolver.
*
* @param manager The manager.
* @return The import loader.
* @return The import resolver.
*/
COWL_API
CowlImportLoader cowl_manager_get_import_loader(CowlManager *manager);
CowlImportResolver cowl_manager_get_import_resolver(CowlManager *manager);

/**
* Sets the import loader.
* Sets the import resolver.
*
* @param manager The manager.
* @param loader The import loader.
* @param resolver The import resolver.
*/
COWL_API
void cowl_manager_set_import_loader(CowlManager *manager, CowlImportLoader loader);
void cowl_manager_set_import_resolver(CowlManager *manager, CowlImportResolver resolver);

/**
* Gets the error handler.
Expand Down
20 changes: 5 additions & 15 deletions include/cowl_ontology.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "cowl_attrs.h"
#include "cowl_axiom_flags.h"
#include "cowl_axiom_type.h"
#include "cowl_import_resolver.h"
#include "cowl_iterator.h"
#include "cowl_macros.h"
#include "cowl_position.h"
Expand Down Expand Up @@ -140,26 +141,15 @@ COWL_API
bool cowl_ontology_remove_annot(CowlOntology *onto, CowlAnnotation *annot);

/**
* Gets an imported ontology given its import IRI.
* Checks if the given ontology has an import with the specified IRI.
*
* @param onto The ontology.
* @param iri Import IRI.
* @return Imported ontology.
*/
COWL_API
COWL_PURE
CowlOntology *cowl_ontology_get_import(CowlOntology *onto, CowlIRI *iri);

/**
* Gets the import IRI of an imported ontology.
*
* @param onto The ontology.
* @param import The imported ontology.
* @return Import IRI.
* @param import IRI of the imported ontology.
* @return True if the ontology has the specified import, false otherwise.
*/
COWL_API
COWL_PURE
CowlIRI *cowl_ontology_get_import_iri(CowlOntology *onto, CowlOntology *import);
bool cowl_ontology_has_import(CowlOntology *onto, CowlIRI *import);

/**
* Adds an import to the ontology.
Expand Down
15 changes: 0 additions & 15 deletions src/cowl_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "cowl_anon_ind_private.h"
#include "cowl_entity_private.h"
#include "cowl_error_handler.h"
#include "cowl_import_loader.h"
#include "cowl_iri_private.h"
#include "cowl_reader.h"
#include "cowl_ret.h"
Expand All @@ -23,7 +22,6 @@

static bool cowl_initialized = false;
static CowlErrorHandler global_error_handler;
static CowlImportLoader global_import_loader;
static CowlReader global_reader;
static CowlWriter global_writer;

Expand All @@ -41,7 +39,6 @@ static CowlWriter global_writer;

static void cowl_config_init(void) {
global_error_handler = (CowlErrorHandler){ 0 };
global_import_loader = (CowlImportLoader){ 0 };
global_reader = cowl_default_reader();
global_writer = cowl_default_writer();

Expand All @@ -51,7 +48,6 @@ static void cowl_config_init(void) {

static void cowl_config_deinit(void) {
if (global_error_handler.free) global_error_handler.free(global_error_handler.ctx);
if (global_import_loader.free) global_import_loader.free(global_import_loader.ctx);
}

cowl_ret cowl_init(void) {
Expand Down Expand Up @@ -89,17 +85,6 @@ void cowl_set_error_handler(CowlErrorHandler handler) {
global_error_handler = handler;
}

CowlImportLoader cowl_get_import_loader(void) {
return (CowlImportLoader){
.ctx = global_import_loader.ctx,
.load_ontology = global_import_loader.load_ontology,
};
}

void cowl_set_import_loader(CowlImportLoader loader) {
global_import_loader = loader;
}

CowlReader cowl_get_reader(void) {
return global_reader;
}
Expand Down
Loading

0 comments on commit 555bcbe

Please sign in to comment.