Пример #1
0
static SerdStatus
write_statement(SordModel*         sord,
                SerdWriter*        writer,
                SordQuad           tup,
                SerdStatementFlags flags)
{
	const SordNode* s  = tup[SORD_SUBJECT];
	const SordNode* p  = tup[SORD_PREDICATE];
	const SordNode* o  = tup[SORD_OBJECT];
	const SordNode* d  = sord_node_get_datatype(o);
	const SerdNode* ss = sord_node_to_serd_node(s);
	const SerdNode* sp = sord_node_to_serd_node(p);
	const SerdNode* so = sord_node_to_serd_node(o);
	const SerdNode* sd = sord_node_to_serd_node(d);

	const char* lang_str = sord_node_get_language(o);
	size_t      lang_len = lang_str ? strlen(lang_str) : 0;
	SerdNode    language = SERD_NODE_NULL;
	if (lang_str) {
		language.type    = SERD_LITERAL;
		language.n_bytes = lang_len;
		language.n_chars = lang_len;
		language.buf     = (const uint8_t*)lang_str;
	};

	// TODO: Subject abbreviation

	if (sord_node_is_inline_object(s) && !(flags & SERD_ANON_CONT)) {
		return SERD_SUCCESS;
	}

	SerdStatus st = SERD_SUCCESS;
	if (sord_node_is_inline_object(o)) {
		SordQuad  sub_pat  = { o, 0, 0, 0 };
		SordIter* sub_iter = sord_find(sord, sub_pat);

		SerdStatementFlags start_flags = flags
			| ((sub_iter) ? SERD_ANON_O_BEGIN : SERD_EMPTY_O);

		st = serd_writer_write_statement(
			writer, start_flags, NULL, ss, sp, so, sd, &language);

		if (!st && sub_iter) {
			flags |= SERD_ANON_CONT;
			for (; !st && !sord_iter_end(sub_iter); sord_iter_next(sub_iter)) {
				SordQuad sub_tup;
				sord_iter_get(sub_iter, sub_tup);
				st = write_statement(sord, writer, sub_tup, flags);
			}
			sord_iter_free(sub_iter);
			serd_writer_end_anon(writer, so);
		}
	} else {
		st = serd_writer_write_statement(
			writer, flags, NULL, ss, sp, so, sd, &language);
	}

	return st;
}
Пример #2
0
/** Create a new LilvNode from `node`, or return NULL if impossible */
LilvNode*
lilv_node_new_from_node(LilvWorld* world, const SordNode* node)
{
    if (!node) {
        return NULL;
    }

    LilvNode*    result       = NULL;
    SordNode*    datatype_uri = NULL;
    LilvNodeType type         = LILV_VALUE_STRING;
    size_t       len          = 0;

    switch (sord_node_get_type(node)) {
    case SORD_URI:
        result        = (LilvNode*)malloc(sizeof(LilvNode));
        result->world = (LilvWorld*)world;
        result->type  = LILV_VALUE_URI;
        result->node  = sord_node_copy(node);
        break;
    case SORD_BLANK:
        result        = (LilvNode*)malloc(sizeof(LilvNode));
        result->world = (LilvWorld*)world;
        result->type  = LILV_VALUE_BLANK;
        result->node  = sord_node_copy(node);
        break;
    case SORD_LITERAL:
        datatype_uri = sord_node_get_datatype(node);
        if (datatype_uri) {
            if (sord_node_equals(datatype_uri, world->uris.xsd_boolean))
                type = LILV_VALUE_BOOL;
            else if (sord_node_equals(datatype_uri, world->uris.xsd_decimal)
                     || sord_node_equals(datatype_uri, world->uris.xsd_double))
                type = LILV_VALUE_FLOAT;
            else if (sord_node_equals(datatype_uri, world->uris.xsd_integer))
                type = LILV_VALUE_INT;
            else if (sord_node_equals(datatype_uri,
                                      world->uris.xsd_base64Binary))
                type = LILV_VALUE_BLOB;
            else
                LILV_ERRORF("Unknown datatype `%s'\n",
                            sord_node_get_string(datatype_uri));
        }
        result = lilv_node_new(
                     world, type, (const char*)sord_node_get_string_counted(node, &len));
        lilv_node_set_numerics_from_string(result, len);
        break;
    }

    return result;
}
Пример #3
0
static int
check_properties(SordModel* model, URIs* uris)
{
	int       st = 0;
	SordIter* i  = sord_begin(model);
	for (; !sord_iter_end(i); sord_iter_next(i)) {
		SordQuad quad;
		sord_iter_get(i, quad);

		const SordNode* subj = quad[SORD_SUBJECT];
		const SordNode* pred = quad[SORD_PREDICATE];
		const SordNode* obj  = quad[SORD_OBJECT];

		bool is_any_property = false;
		SordIter* t = sord_search(model, pred, uris->rdf_type, NULL, NULL);
		for (; !sord_iter_end(t); sord_iter_next(t)) {
			if (is_descendant_of(model, uris,
			                     sord_iter_get_node(t, SORD_OBJECT),
			                     uris->rdf_Property,
			                     uris->rdfs_subClassOf)) {
				is_any_property = true;
				break;
			}
		}
		sord_iter_free(t);

		const bool is_ObjectProperty = sord_ask(
			model, pred, uris->rdf_type, uris->owl_ObjectProperty, 0);
		const bool is_FunctionalProperty = sord_ask(
			model, pred, uris->rdf_type, uris->owl_FunctionalProperty, 0);
		const bool is_InverseFunctionalProperty = sord_ask(
			model, pred, uris->rdf_type, uris->owl_InverseFunctionalProperty, 0);
		const bool is_DatatypeProperty = sord_ask(
			model, pred, uris->rdf_type, uris->owl_DatatypeProperty, 0);

		if (!is_any_property) {
			st = error("Use of undefined property", quad);
		}

		if (!sord_ask(model, pred, uris->rdfs_label, NULL, NULL)) {
			st = errorf("Property <%s> has no label\n",
			            sord_node_get_string(pred));
		}

		if (is_DatatypeProperty &&
		    sord_node_get_type(obj) != SORD_LITERAL) {
			st = error("Datatype property with non-literal value", quad);
		}

		if (is_ObjectProperty &&
		    sord_node_get_type(obj) == SORD_LITERAL) {
			st = error("Object property with literal value", quad);
		}

		if (is_FunctionalProperty &&
		    sord_count(model, subj, pred, NULL, NULL) > 1) {
			st = error("Functional property with several objects", quad);
		}

		if (is_InverseFunctionalProperty &&
		    sord_count(model, NULL, pred, obj, NULL) > 1) {
			st = error("Inverse functional property with several subjects", quad);
		}

		if (sord_node_equals(pred, uris->rdf_type) &&
		    !sord_ask(model, obj, uris->rdf_type, uris->rdfs_Class, NULL) &&
		    !sord_ask(model, obj, uris->rdf_type, uris->owl_Class, NULL)) {
			st = error("Type is not a rdfs:Class or owl:Class", quad);
		}

		if (sord_node_get_type(obj) == SORD_LITERAL &&
		    !literal_is_valid(model, uris, obj, sord_node_get_datatype(obj))) {
			st = error("Literal does not match datatype", quad);
		}

		SordIter* r = sord_search(model, pred, uris->rdfs_range, NULL, NULL);
		for (; !sord_iter_end(r); sord_iter_next(r)) {
			const SordNode* range = sord_iter_get_node(r, SORD_OBJECT);
			if (!check_type(model, uris, obj, range)) {
				st = error("Object not in property range", quad);
				fprintf(stderr, "note: Range is <%s>\n",
				        sord_node_get_string(range));
			}
		}
		sord_iter_free(r);

		SordIter* d = sord_search(model, pred, uris->rdfs_domain, NULL, NULL);
		if (d) {
			const SordNode* domain = sord_iter_get_node(d, SORD_OBJECT);
			if (!check_type(model, uris, subj, domain)) {
				st = error("Subject not in property domain", quad);
				fprintf(stderr, "note: Domain is <%s>\n",
				        sord_node_get_string(domain));
			}
			sord_iter_free(d);
		}
	}
	sord_iter_free(i);

	return st;
}
Пример #4
0
static bool
literal_is_valid(SordModel*      model,
                 const URIs*     uris,
                 const SordNode* literal,
                 const SordNode* type)
{
	if (!type) {
		return true;
	}

	/* Check that literal data is related to required type.  We don't do a
	   strict subtype check here because e.g. an xsd:decimal might be a valid
	   xsd:unsignedInt, which the pattern checks will verify, but if the
	   literal type is not related to the required type at all
	   (e.g. xsd:decimal and xsd:string) there is a problem. */
	const SordNode* datatype = sord_node_get_datatype(literal);
	if (datatype && datatype != type) {
		if (!is_descendant_of(
			    model, uris,
			    datatype, type, uris->owl_onDatatype) &&
		    !is_descendant_of(
			    model, uris,
			    type, datatype, uris->owl_onDatatype)) {
			errorf("Literal `%s' datatype <%s> is not compatible with <%s>\n",
			       sord_node_get_string(literal),
			       sord_node_get_string(datatype),
			       sord_node_get_string(type));
			return false;
		}
	}

	// Find restrictions list
	SordIter* rs = sord_search(model, type, uris->owl_withRestrictions, 0, 0);
	if (sord_iter_end(rs)) {
		return true;  // No restrictions
	}

	// Walk list, checking each restriction
	const SordNode* head = sord_iter_get_node(rs, SORD_OBJECT);
	while (head) {
		SordIter* f = sord_search(model, head, uris->rdf_first, 0, 0);
		if (!f) {
			break;  // Reached end of restrictions list without failure
		}

		// Check this restriction
		const bool good = check_restriction(
			 model, uris, literal, type, sord_iter_get_node(f, SORD_OBJECT));
		sord_iter_free(f);

		if (!good) {
			sord_iter_free(rs);
			return false;  // Failed, literal is invalid
		}

		// Seek to next list node
		SordIter* n = sord_search(model, head, uris->rdf_rest, 0, 0);
		head = n ? sord_iter_get_node(n, SORD_OBJECT) : NULL;
		sord_iter_free(n);
	}

	sord_iter_free(rs);

	SordIter* s = sord_search(model, type, uris->owl_onDatatype, 0, 0);
	if (s) {
		const SordNode* super = sord_iter_get_node(s, SORD_OBJECT);
		const bool      good  = literal_is_valid(model, uris, literal, super);
		sord_iter_free(s);
		return good;  // Match iff literal also matches supertype
	}

	return true;  // Matches top level type
}