Skip to content

Commit 58683ad

Browse files
committed
webanno: if the predicate is an iri and the value looks like an IRI where the base url corresponds to one of the extra contexts, then strip this prefix and reduce the IRI value to an alias
1 parent 3db50a2 commit 58683ad

File tree

1 file changed

+50
-14
lines changed

1 file changed

+50
-14
lines changed

src/api/webanno.rs

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -332,15 +332,15 @@ impl<'store> ResultItem<'store, Annotation> {
332332
}
333333
body_out.add(
334334
Cow::Borrowed(key_id),
335-
output_datavalue(key_id, data.value()),
335+
output_datavalue(key_id, data.value(), config),
336336
);
337337
}
338338
},
339339
Some(NS_RDF) if key_id == "type" => {
340340
suppress_default_body_type = true; //no need for the default because we provided one explicitly
341341
body_out.add(
342342
Cow::Borrowed(key_id),
343-
output_datavalue(key_id, data.value()),
343+
output_datavalue(key_id, data.value(), config),
344344
);
345345
}
346346
Some(set_id) => {
@@ -355,7 +355,7 @@ impl<'store> ResultItem<'store, Annotation> {
355355
key.iri(&config.default_set_iri).expect("set must have ID")
356356
},
357357
),
358-
output_datavalue(key_id, data.value()),
358+
output_datavalue(key_id, data.value(), config),
359359
);
360360
}
361361
None => unreachable!("all sets should have a public identifier"),
@@ -454,13 +454,18 @@ fn output_predicate_datavalue(
454454
false
455455
};
456456
if is_iri(predicate) && value_is_iri {
457-
// If the predicate is an IRI and the value *(looks like* an IRI, then the latter will be interpreted as an IRI rather than a string literal
458-
// (This is not formally defined in the spec! the predicate check is needed because we don't want this behaviour if the predicate is an alias defined in the JSON-LD context)
459-
format!(
460-
"\"{}\": {{ \"id\": \"{}\" }}",
461-
config.uri_to_namespace(predicate.into()),
462-
datavalue
463-
)
457+
if let Some(s) = value_to_alias(predicate, datavalue, config) {
458+
// if the predicate is an iri and the value looks like an IRI where the base url correspondonds to one of the added contexts, then strip this prefix and reduce the IRI value to an alias
459+
s
460+
} else {
461+
// Else: If the predicate is an IRI and the value *(looks like* an IRI, then the latter will be interpreted as an IRI rather than a string literal
462+
// (This is not formally defined in the spec! the predicate check is needed because we don't want this behaviour if the predicate is an alias defined in the JSON-LD context)
463+
format!(
464+
"\"{}\": {{ \"id\": \"{}\" }}",
465+
config.uri_to_namespace(predicate.into()),
466+
datavalue
467+
)
468+
}
464469
} else {
465470
format!(
466471
"\"{}\": {}",
@@ -470,16 +475,47 @@ fn output_predicate_datavalue(
470475
}
471476
}
472477

473-
fn output_datavalue(predicate: &str, datavalue: &DataValue) -> String {
478+
#[inline]
479+
/// if the predicate is an iri and the value looks like an IRI where the base url correspondonds to one of the added contexts, then strip this prefix and reduce the IRI value to an alias
480+
/// Returns None if this is not the case
481+
fn value_to_alias(
482+
predicate: &str,
483+
datavalue: &DataValue,
484+
config: &WebAnnoConfig,
485+
) -> Option<String> {
486+
if !config.extra_context.is_empty() {
487+
if let DataValue::String(datavalue) = datavalue {
488+
for prefix in config.extra_context.iter() {
489+
if datavalue.starts_with(&format!("{}/", prefix.as_str()))
490+
|| datavalue.starts_with(&format!("{}#", prefix.as_str()))
491+
{
492+
return Some(format!(
493+
"\"{}\": \"{}\"",
494+
config.uri_to_namespace(predicate.into()),
495+
&datavalue[prefix.len() + 1..]
496+
));
497+
}
498+
}
499+
}
500+
}
501+
None
502+
}
503+
504+
fn output_datavalue(predicate: &str, datavalue: &DataValue, config: &WebAnnoConfig) -> String {
474505
let value_is_iri = if let DataValue::String(s) = datavalue {
475506
is_iri(s)
476507
} else {
477508
false
478509
};
479510
if is_iri(predicate) && value_is_iri {
480-
// If the predicate is an IRI and the value *(looks like* an IRI, then the latter will be interpreted as an IRI rather than a string literal
481-
// (This is not formally defined in the spec! the predicate check is needed because we don't want this behaviour if the predicate is an alias defined in the JSON-LD context)
482-
format!("{{ \"id\": \"{}\" }}", datavalue)
511+
if let Some(s) = value_to_alias(predicate, datavalue, config) {
512+
// if the predicate is an iri and the value looks like an IRI where the base url correspondonds to one of the added contexts, then strip this prefix and reduce the IRI value to an alias
513+
s
514+
} else {
515+
// If the predicate is an IRI and the value *(looks like* an IRI, then the latter will be interpreted as an IRI rather than a string literal
516+
// (This is not formally defined in the spec! the predicate check is needed because we don't want this behaviour if the predicate is an alias defined in the JSON-LD context)
517+
format!("{{ \"id\": \"{}\" }}", datavalue)
518+
}
483519
} else {
484520
value_to_json(datavalue)
485521
}

0 commit comments

Comments
 (0)