diff options
Diffstat (limited to '')
-rw-r--r-- | librdfa/subject.c | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/librdfa/subject.c b/librdfa/subject.c new file mode 100644 index 0000000..f082052 --- /dev/null +++ b/librdfa/subject.c @@ -0,0 +1,535 @@ +/** + * Copyright 2008 Digital Bazaar, Inc. + * + * This file is part of librdfa. + * + * librdfa is Free Software, and can be licensed under any of the + * following three licenses: + * + * 1. GNU Lesser General Public License (LGPL) V2.1 or any + * newer version + * 2. GNU General Public License (GPL) V2 or any newer version + * 3. Apache License, V2.0 or any newer version + * + * You may not use this file except in compliance with at least one of + * the above three licenses. + * + * See LICENSE-* at the top of this software distribution for more + * information regarding the details of each license. + * + * This file is used to process RDFa subjects. + */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "rdfa_utils.h" +#include "rdfa.h" + +/** + * Creates a new bnode given an RDFa context. + * + * @param context the RDFa context. + * + * @return a newly allocated string containing the bnode name. This + * string MUST be memory collected. + */ +char* rdfa_create_bnode(rdfacontext* context) +{ + char* rval = NULL; +#define BNODE_BUFFER_LEN 64 + char buffer[BNODE_BUFFER_LEN]; + + /* print and increment the bnode count */ + snprintf(buffer, BNODE_BUFFER_LEN, "_:bnode%i", (int)context->bnode_count++); + rval = rdfa_replace_string(rval, buffer); + + return rval; +} + +/** + * Establishes a new subject for the given context given the + * attributes on the current element. The given context's new_subject + * value is updated if a new subject is found. + * + * @param context the RDFa context. + * @param name the name of the current element that is being processed. + * @param about the full IRI for about, or NULL if there isn't one. + * @param src the full IRI for src, or NULL if there isn't one. + * @param resource the full IRI for resource, or NULL if there isn't one. + * @param href the full IRI for href, or NULL if there isn't one. + * @param type_of The list of IRIs for type_of, or NULL if there was + * no type_of specified. + */ +void rdfa_establish_new_1_0_subject( + rdfacontext* context, const char* name, const char* about, const char* src, + const char* resource, const char* href, const rdfalist* type_of) +{ + /* 4. If the [current element] contains no valid @rel or @rev + * URI, obtained according to the section on CURIE and URI + * Processing, then the next step is to establish a value for + * [new subject]. Any of the attributes that can carry a + * resource can set [new subject]; */ + + if(about != NULL) + { + /* * by using the URI from @about, if present, obtained according + * to the section on CURIE and URI Processing; */ + context->new_subject = + rdfa_replace_string(context->new_subject, about); + } + else if(src != NULL) + { + /* * otherwise, by using the URI from @src, if present, obtained + * according to the section on CURIE and URI Processing. */ + context->new_subject = + rdfa_replace_string(context->new_subject, src); + } + else if(resource != NULL) + { + /* * otherwise, by using the URI from @resource, if present, + * obtained according to the section on CURIE and URI + * Processing; */ + context->new_subject = + rdfa_replace_string(context->new_subject, resource); + } + else if(href != NULL) + { + /* * otherwise, by using the URI from @href, if present, obtained + * according to the section on CURIE and URI Processing. */ + context->new_subject = + rdfa_replace_string(context->new_subject, href); + } + else if((type_of != NULL) && (type_of->num_items > 0)) + { + /* * if @type_of is present, obtained according to the + * section on CURIE and URI Processing, then [new subject] is + * set to be a newly created [bnode]; */ + char* bnode = rdfa_create_bnode(context); + context->new_subject = rdfa_replace_string(context->new_subject, bnode); + free(bnode); + } + else if(context->parent_object != NULL) + { + /* * otherwise, if [parent object] is present, [new subject] is + * set to that and the [skip element] flag is set to 'true'; */ + context->new_subject = + rdfa_replace_string(context->new_subject, context->parent_object); + + /* TODO: The skip element flag will be set even if there is a + * @property value, which is a bug, isn't it? */ + /*context->skip_element = 1;*/ + } +} + +/** + * Establishes a new subject for the given context given the + * attributes on the current element. The given context's new_subject + * value is updated if a new subject is found. + * + * @param context the RDFa context. + * @param name the name of the current element that is being processed. + * @param about the full IRI for about, or NULL if there isn't one. + * @param src the full IRI for src, or NULL if there isn't one. + * @param resource the full IRI for resource, or NULL if there isn't one. + * @param href the full IRI for href, or NULL if there isn't one. + * @param type_of The list of IRIs for type_of, or NULL if there was + * no type_of specified. + * @param property a list of properties that were detected during processing. + */ +void rdfa_establish_new_1_1_subject( + rdfacontext* context, const char* name, const char* about, const char* src, + const char* resource, const char* href, const rdfalist* type_of, + const rdfalist* property, const char* content, const char* datatype) +{ + /* + * If the current element contains the @property attribute, but does not + * contain either the @content or @datatype attributes, then new subject + * is set to the resource obtained from the first match from the + * following rule: + */ + if(property != NULL && content == NULL && datatype == NULL) + { + /* by using the resource from @about, if present, obtained according to + * the section on CURIE and IRI Processing; + */ + if(about != NULL) + { + /* NOTE: this statement achieves this part of the processing rule + * as well because @about is set if depth == 1 in RDFa 1.1 in + * the calling function: otherwise, if the element is the root + * element of the document, then act as if there is an empty + * @about present, and process it according to the rule for + * @about, above; + */ + context->new_subject = + rdfa_replace_string(context->new_subject, about); + } + else if(context->parent_object != NULL) + { + /* otherwise, if parent object is present, new subject is set + * to the value of parent object. + */ + context->new_subject = + rdfa_replace_string(context->new_subject, context->parent_object); + } + + /* If @typeof is present then typed resource is set to the resource + * obtained from the first match from the following rules: + */ + if(type_of != NULL) + { + if(about != NULL) + { + /* by using the resource from @about, if present, obtained + * according to the section on CURIE and IRI Processing; + * + * NOTE: about is set to the document if this is the root + * element of the document, so the following rule is also applied + * in this case: + * + * otherwise, if the element is the root element of the + * document, then act as if there is an empty @about present + * and process it according to the previous rule; + */ + context->typed_resource = + rdfa_replace_string(context->typed_resource, about); + } + else + { + if(resource != NULL) + { + /* by using the resource from @resource, if present, obtained + * according to the section on CURIE and IRI Processing; + */ + context->typed_resource = + rdfa_replace_string(context->typed_resource, resource); + } + else if(href != NULL) + { + /* otherwise, by using the IRI from @href, if present, obtained + * according to the section on CURIE and IRI Processing; + */ + context->typed_resource = + rdfa_replace_string(context->typed_resource, href); + } + else if(src != NULL) + { + /* otherwise, by using the IRI from @src, if present, obtained + * according to the section on CURIE and IRI Processing; + */ + context->typed_resource = + rdfa_replace_string(context->typed_resource, src); + } + else + { + /* otherwise, the value of typed resource is set to a newly + * created bnode. + */ + char* bnode = rdfa_create_bnode(context); + context->typed_resource = rdfa_replace_string( + context->typed_resource, bnode); + free(bnode); + } + + /* The value of the current object resource is then set to the value + * of typed resource. + */ + context->current_object_resource = rdfa_replace_string( + context->current_object_resource, context->typed_resource); + } + } + } + else + { + /* otherwise: + * If the element contains an @about, @href, @src, or @resource attribute, + * new subject is set to the resource obtained as follows: + */ + if(about != NULL || href != NULL || src != NULL || resource != NULL) + { + if(about != NULL) + { + /* by using the resource from @about, if present, obtained + * according to the section on CURIE and IRI Processing; + */ + context->new_subject = + rdfa_replace_string(context->new_subject, about); + } + else if(resource != NULL) + { + /* otherwise, by using the resource from @resource, if present, + * obtained according to the section on CURIE and IRI Processing; + */ + context->new_subject = + rdfa_replace_string(context->new_subject, resource); + } + else if(href != NULL) + { + /* otherwise, by using the IRI from @href, if present, obtained + * according to the section on CURIE and IRI Processing; + */ + context->new_subject = + rdfa_replace_string(context->new_subject, href); + } + else if(src != NULL) + { + /* otherwise, by using the IRI from @src, if present, obtained + * according to the section on CURIE and IRI Processing. + */ + context->new_subject = + rdfa_replace_string(context->new_subject, src); + } + } + else + { + /* otherwise, if no resource is provided by a resource attribute, + * then the first match from the following rules will apply: + */ + + /* NOTE: this step is achieved via the parent function call as @about + * is set if the current element is the root element. + * + * if the element is the root element of the document, then act + * as if there is an empty @about present, and process it according + * to the rule for @about, above; + */ + if(type_of != NULL) + { + /* otherwise, if @typeof is present, then new subject is set + * to be a newly created bnode; + */ + char* bnode = rdfa_create_bnode(context); + context->new_subject = rdfa_replace_string(context->new_subject, + bnode); + free(bnode); + } + else if(context->parent_object != NULL) + { + /* otherwise, if parent object is present, new subject is set to + * the value of parent object. + */ + context->new_subject = rdfa_replace_string(context->new_subject, + context->parent_object); + + /* Additionally, if @property is not present then the skip + * element flag is set to 'true'. + */ + if(property == NULL) + { + context->skip_element = 1; + } + } + } + + if(type_of != NULL) + { + /* Finally, if @typeof is present, set the typed resource to the value + * of new subject. + */ + context->typed_resource = rdfa_replace_string(context->typed_resource, + context->new_subject); + } + } +} + +/** + * Establishes a new subject for the given context when @rel or @rev + * is present. The given context's new_subject and + * current_object_resource values are updated if a new subject is found. + * + * @param context the RDFa context. + * @param about the full IRI for about, or NULL if there isn't one. + * @param src the full IRI for src, or NULL if there isn't one. + * @param resource the full IRI for resource, or NULL if there isn't one. + * @param href the full IRI for href, or NULL if there isn't one. + * @param type_of the list of IRIs for type_of, or NULL if type_of + * wasn't specified on the current element. + */ +void rdfa_establish_new_1_0_subject_with_relrev( + rdfacontext* context, const char* name, const char* about, const char* src, + const char* resource, const char* href, const rdfalist* type_of) +{ + /* 5. If the [current element] does contain a valid @rel or @rev + * URI, obtained according to the section on CURIE and URI + * Processing, then the next step is to establish both a value + * for [new subject] and a value for [current object resource]: + * + * [new subject] is set to the URI obtained from the first match + * from the following rules: */ + + if(about != NULL) + { + /* * by using the URI from @about, if present, obtained + * according to the section on CURIE and URI Processing; */ + context->new_subject = + rdfa_replace_string(context->new_subject, about); + } + else if(context->rdfa_version == RDFA_VERSION_1_0 && src != NULL) + { + /* * otherwise, by using the URI from @src, if present, obtained + * according to the section on CURIE and URI Processing. */ + context->new_subject = + rdfa_replace_string(context->new_subject, src); + } + else if((type_of != NULL) && (type_of->num_items > 0)) + { + /* * if @type_of is present, obtained according to the + * section on CURIE and URI Processing, then [new subject] is + * set to be a newly created [bnode]; */ + char* bnode = rdfa_create_bnode(context); + context->new_subject = rdfa_replace_string(context->new_subject, bnode); + free(bnode); + } + else if(context->parent_object != NULL) + { + /* * otherwise, if [parent object] is present, [new subject] is + * set to that; */ + context->new_subject = + rdfa_replace_string(context->new_subject, context->parent_object); + } + + /* Then the [current object resource] is set to the URI obtained + * from the first match from the following rules: */ + if(resource != NULL) + { + /* * by using the URI from @resource, if present, obtained + * according to the section on CURIE and URI Processing; */ + context->current_object_resource = + rdfa_replace_string(context->current_object_resource, resource); + } + else if(href != NULL) + { + /* * otherwise, by using the URI from @href, if present, + * obtained according to the section on CURIE and URI Processing. */ + context->current_object_resource = + rdfa_replace_string(context->current_object_resource, href); + } + else + { + /* * otherwise, null. */ + context->current_object_resource = NULL; + } + + /* Note that final value of the [current object resource] will + * either be null, or a full URI. */ +} + +/** + * Establishes a new subject for the given context when @rel or @rev + * is present. The given context's new_subject and + * current_object_resource values are updated if a new subject is found. + * + * @param context the RDFa context. + * @param about the full IRI for about, or NULL if there isn't one. + * @param src the full IRI for src, or NULL if there isn't one. + * @param resource the full IRI for resource, or NULL if there isn't one. + * @param href the full IRI for href, or NULL if there isn't one. + * @param type_of the list of IRIs for type_of, or NULL if type_of + * wasn't specified on the current element. + */ +void rdfa_establish_new_1_1_subject_with_relrev( + rdfacontext* context, const char* name, const char* about, const char* src, + const char* resource, const char* href, const rdfalist* type_of) +{ + /* If the current element does contain a @rel or @rev attribute, then + * the next step is to establish both a value for new subject and a + * value for current object resource: + */ + + /* new subject is set to the resource obtained from the first match from + * the following rules: + */ + + if(about != NULL) + { + /* by using the resource from @about, if present, obtained according + * to the section on CURIE and IRI Processing; + * + * NOTE: This will also catch the following rule due to @about being + * set in the calling function: + * + * if the element is the root element of the document then act as if + * there is an empty @about present, and process it according to the + * rule for @about, above; + */ + context->new_subject = + rdfa_replace_string(context->new_subject, about); + } + + if(type_of != NULL) + { + /* if the @typeof attribute is present, set typed resource to + * new subject. + */ + context->typed_resource = + rdfa_replace_string(context->typed_resource, context->new_subject); + } + + /* If no resource is provided then the first match from the following rules + * will apply: + * + */ + if(context->new_subject == NULL && context->parent_object != NULL) + { + /* otherwise, if parent object is present, new subject is set to that. + */ + context->new_subject = rdfa_replace_string( + context->new_subject, context->parent_object); + } + + /* Then the current object resource is set to the resource obtained from + * the first match from the following rules: + */ + + if(resource != NULL) + { + /* by using the resource from @resource, if present, obtained according + * to the section on CURIE and IRI Processing; + */ + context->current_object_resource = rdfa_replace_string( + context->current_object_resource, resource); + } + else if(href != NULL) + { + /* otherwise, by using the IRI from @href, if present, obtained + * according to the section on CURIE and IRI Processing; + */ + context->current_object_resource = rdfa_replace_string( + context->current_object_resource, href); + } + else if(src != NULL) + { + /* otherwise, by using the IRI from @src, if present, obtained + * according to the section on CURIE and IRI Processing; + */ + context->current_object_resource = rdfa_replace_string( + context->current_object_resource, src); + } + else if(type_of != NULL && about == NULL) + { + /* otherwise, if @typeof is present and @about is not, use a + * newly created bnode. + */ + char* bnode = rdfa_create_bnode(context); + context->current_object_resource = rdfa_replace_string( + context->current_object_resource, bnode); + free(bnode); + } + + if(type_of != NULL && about == NULL) + { + /* If @typeof is present and @about is not, set typed resource to current + * object resource. + */ + context->typed_resource = rdfa_replace_string( + context->typed_resource, context->current_object_resource); + } + + /* Note that final value of the current object resource will either be + * null (from initialization) or a full IRI or bnode. + */ +} |