@dasch-swiss/dsp-js
Version:
JavaScript library that handles API requests to Knora
453 lines • 21.5 kB
JavaScript
import { forkJoin, of } from "rxjs";
import { map, mergeMap } from "rxjs";
import { Constants } from "../Constants";
import { ResourcePropertyDefinition } from "../ontologies/resource-property-definition";
import { CountQueryResponse } from "../search/count-query-response";
import { ReadResource } from "./read/read-resource";
import { ReadResourceSequence } from "./read/read-resource-sequence";
import { ReadBooleanValue } from "./values/read/read-boolean-value";
import { ReadColorValue } from "./values/read/read-color-value";
import { ParseReadDateValue, ReadDateValue } from "./values/read/read-date-value";
import { ReadDecimalValue } from "./values/read/read-decimal-value";
import { ReadArchiveFileValue, ReadAudioFileValue, ReadDocumentFileValue, ReadMovingImageFileValue, ReadStillImageExternalFileValue, ReadStillImageFileValue, ReadTextFileValue } from "./values/read/read-file-value";
import { ParseReadGeomValue, ReadGeomValue } from "./values/read/read-geom-value";
import { ReadGeonameValue } from "./values/read/read-geoname-value";
import { ReadIntValue } from "./values/read/read-int-value";
import { ReadIntervalValue } from "./values/read/read-interval-value";
import { ReadLinkValue } from "./values/read/read-link-value";
import { ReadListValue } from "./values/read/read-list-value";
import { ReadTextValueAsHtml, ReadTextValueAsString, ReadTextValueAsXml } from "./values/read/read-text-value";
import { ReadTimeValue } from "./values/read/read-time-value";
import { ReadUriValue } from "./values/read/read-uri-value";
import { ReadValue } from "./values/read/read-value";
/**
* @category Internal
*/
export var ResourcesConversionUtil;
(function (ResourcesConversionUtil) {
/**
* Given a JSON-LD representing zero, one or more resources, converts it to an array of ReadResource.
*
* JSON-LD is expected to have expanded prefixes (processed by jsonld processor).
*
* @param resourcesJsonld a JSON-LD object with expanded prefixes representing zero, one or more resources.
* @param ontologyCache instance of OntologyCache to be used.
* @param listNodeCache instance of ListNodeCache to be used.
* @param jsonConvert instance of JsonConvert to be used.
*/
ResourcesConversionUtil.createReadResourceSequence = function (resourcesJsonld, ontologyCache, listNodeCache, jsonConvert) {
if (resourcesJsonld.hasOwnProperty("@graph")) {
var graphLength = resourcesJsonld["@graph"].length;
if (graphLength > 0) {
// sequence of resources
return forkJoin(resourcesJsonld["@graph"]
.map(function (res) { return createReadResource(res, ontologyCache, listNodeCache, jsonConvert); })).pipe(map(function (resources) {
// check for mayHaveMoreResults
if (resourcesJsonld.hasOwnProperty(Constants.MayHaveMoreResults)) {
// presence of knora-api:mayHaveMoreResults implicitly means true
return new ReadResourceSequence(resources, true);
}
else {
return new ReadResourceSequence(resources);
}
}));
}
else {
if (resourcesJsonld.hasOwnProperty(Constants.MayHaveMoreResults)) {
return of(new ReadResourceSequence([], true));
}
else {
return of(new ReadResourceSequence([]));
}
}
}
else {
// one or no resource
if (Object.keys(resourcesJsonld).length === 0) {
return of(new ReadResourceSequence([]));
}
else {
return forkJoin([createReadResource(resourcesJsonld, ontologyCache, listNodeCache, jsonConvert)]).pipe(map(function (resources) {
return new ReadResourceSequence(resources);
}));
}
}
};
/**
* Creates a single ReadResource.
*
* @param resourceJsonld a JSON-LD object representing a single resource.
* @param ontologyCache instance of OntologyCache to be used.
* @param listNodeCache instance of ListNodeCache to be used.
* @param jsonConvert instance of JsonConvert to be used.
*/
var createReadResource = function (resourceJsonld, ontologyCache, listNodeCache, jsonConvert) {
if (Array.isArray(resourceJsonld))
throw new Error("resource is expected to be a single object");
var resource = jsonConvert.deserialize(resourceJsonld, ReadResource);
return ontologyCache.getResourceClassDefinition(resource.type).pipe(mergeMap(function (entitiyDefs) {
var resourceProps = Object.keys(resourceJsonld)
.filter(function (propIri) {
return entitiyDefs.properties[propIri] instanceof ResourcePropertyDefinition;
});
// add information from ontology (if exists)
if (entitiyDefs.classes[resource.type]) {
resource.resourceClassLabel = entitiyDefs.classes[resource.type].label;
resource.resourceClassComment = entitiyDefs.classes[resource.type].comment;
}
else {
// the label is not defined in this ontology
if (resource.type === Constants.DeletedResource) {
resource.resourceClassLabel = resource.label;
}
else {
console.warn('unsupported type: ', resource.type);
resource.resourceClassLabel = resource.type;
}
}
resource.entityInfo = entitiyDefs;
if (resourceProps.length > 0) {
var values_1 = [];
resourceProps.forEach(function (propIri) {
if (Array.isArray(resourceJsonld[propIri])) {
for (var _i = 0, _a = resourceJsonld[propIri]; _i < _a.length; _i++) {
var value = _a[_i];
values_1.push(createValueValue(propIri, value, entitiyDefs, ontologyCache, listNodeCache, jsonConvert));
}
}
else {
values_1.push(createValueValue(propIri, resourceJsonld[propIri], entitiyDefs, ontologyCache, listNodeCache, jsonConvert));
}
});
return forkJoin(values_1).pipe(map(function (vals) {
// get link values
var linkVals = vals.filter(function (val) {
return val instanceof ReadLinkValue;
});
// incoming references with embedded resource
var incomingRefs = linkVals.filter(function (linkVal) {
return linkVal.incoming && linkVal.linkedResource !== undefined;
});
// outgoing references with embedded resource
var outgoingRefs = linkVals.filter(function (linkVal) {
return !linkVal.incoming && linkVal.linkedResource !== undefined;
});
// create a map structure property Iri -> values
var propMap = {};
vals.forEach(function (val) {
if (!propMap.hasOwnProperty(val.property)) {
propMap[val.property] = [val];
}
else {
propMap[val.property].push(val);
}
});
// assign values
resource.properties = propMap;
resource.incomingReferences = incomingRefs.map(function (linkVal) { return linkVal.linkedResource; });
resource.outgoingReferences = outgoingRefs.map(function (linkVal) { return linkVal.linkedResource; });
return resource;
}));
}
else {
return of(resource);
}
}));
};
/**
* Converts a simple value serialized as JSON-LD to a `ReadValue`.
*
* @param valueJsonld value as JSON-LD to be converted.
* @param dataType the specific value type to convert to.
* @param jsonConvert the converter to be used.
*/
var handleSimpleValue = function (valueJsonld, dataType, jsonConvert) {
return of(jsonConvert.deserialize(valueJsonld, dataType));
};
/**
* Converts a text value serialized as JSON-LD to a `ReadTextValue`.
*
* @param valueJsonld text value as JSON-LD to be converted.
* @param jsonConvert jsonConvert the converter to be used.
*/
var handleTextValue = function (valueJsonld, jsonConvert) {
if (valueJsonld.hasOwnProperty(Constants.ValueAsString)) {
// TODO: query standoff, if any.
var textValue = jsonConvert.deserialize(valueJsonld, ReadTextValueAsString);
return of(textValue);
}
else if (valueJsonld.hasOwnProperty(Constants.TextValueAsHtml)) {
var textValue = jsonConvert.deserialize(valueJsonld, ReadTextValueAsHtml);
return of(textValue);
}
else if (valueJsonld.hasOwnProperty(Constants.TextValueAsXml)) {
var textValue = jsonConvert.deserialize(valueJsonld, ReadTextValueAsXml);
return of(textValue);
}
else {
throw new Error("Invalid Text value");
}
};
/**
* Converts a link value serialized as JSON-LD to a `ReadTextValue`.
*
* @param valueJsonld link value as JSON-LD to be converted.
* @param ontologyCache instance of `OntologyCache` to be used.
* @param listNodeCache instance of ListNodeCache to be used.
* @param jsonConvert jsonConvert the converter to be used.
*/
var handleLinkValue = function (valueJsonld, ontologyCache, listNodeCache, jsonConvert) {
var linkValue = jsonConvert.deserialize(valueJsonld, ReadLinkValue);
var handleLinkedResource = function (linkedResource, incoming) {
var referredRes = createReadResource(linkedResource, ontologyCache, listNodeCache, jsonConvert);
return referredRes.pipe(map(function (refRes) {
linkValue.linkedResource = refRes;
linkValue.linkedResourceIri = refRes.id;
linkValue.incoming = incoming;
return linkValue;
}));
};
var handleLinkedResourceIri = function (linkedResourceIri, incoming) {
if (linkedResourceIri === undefined)
throw new Error("Invalid resource Iri");
linkValue.linkedResourceIri = linkedResourceIri;
linkValue.incoming = incoming;
return of(linkValue);
};
// check if linked resource is nested or if just its IRI is present
if (valueJsonld.hasOwnProperty(Constants.LinkValueHasTarget)) {
return handleLinkedResource(valueJsonld[Constants.LinkValueHasTarget], false);
}
else if (valueJsonld.hasOwnProperty(Constants.LinkValueHasTargetIri)) {
// TODO: check for existence of @id
return handleLinkedResourceIri(valueJsonld[Constants.LinkValueHasTargetIri]["@id"], false);
}
else if (valueJsonld.hasOwnProperty(Constants.LinkValueHasSource)) {
return handleLinkedResource(valueJsonld[Constants.LinkValueHasSource], true);
}
else if (valueJsonld.hasOwnProperty(Constants.LinkValueHasSourceIri)) {
// TODO: check for existence of @id
return handleLinkedResourceIri(valueJsonld[Constants.LinkValueHasSourceIri]["@id"], true);
}
else {
throw new Error("Invalid Link Value");
}
};
/**
* Creates a single ReadValue.
*
* @param propIri Iri of the property pointing to the value.
* @param valueJsonld JSON-LD object representing a single value.
* @param entitiyDefs entity definitions for the given value type.
* @param ontologyCache instance of OntologyCache to be used.
* @param listNodeCache instance of ListNodeCache to be used.
* @param jsonConvert instance of JsonConvert to be used.
*/
var createValueValue = function (propIri, valueJsonld, entitiyDefs, ontologyCache, listNodeCache, jsonConvert) {
if (Array.isArray(valueJsonld))
throw new Error("value is expected to be a single object");
var type = valueJsonld["@type"];
var value;
switch (type) {
case Constants.BooleanValue: {
var boolVal = handleSimpleValue(valueJsonld, ReadBooleanValue, jsonConvert);
value = boolVal.pipe(map(function (val) {
val.strval = val.bool ? "TRUE" : "FALSE";
return val;
}));
break;
}
case Constants.ColorValue: {
var colorVal = handleSimpleValue(valueJsonld, ReadColorValue, jsonConvert);
value = colorVal.pipe(map(function (val) {
val.strval = val.color;
return val;
}));
break;
}
case Constants.DateValue: {
var dateVal = handleSimpleValue(valueJsonld, ParseReadDateValue, jsonConvert);
value = dateVal.pipe(map(function (val) {
return new ReadDateValue(val);
}));
break;
}
case Constants.IntValue: {
var intVal = handleSimpleValue(valueJsonld, ReadIntValue, jsonConvert);
value = intVal.pipe(map(function (val) {
val.strval = val.int.toString();
return val;
}));
break;
}
case Constants.DecimalValue: {
var decimalVal = handleSimpleValue(valueJsonld, ReadDecimalValue, jsonConvert);
value = decimalVal.pipe(map(function (val) {
val.strval = val.decimal.toString();
return val;
}));
break;
}
case Constants.IntervalValue: {
var intervalVal = handleSimpleValue(valueJsonld, ReadIntervalValue, jsonConvert);
value = intervalVal.pipe(map(function (val) {
val.strval = val.start.toString() + " - " + val.end.toString();
return val;
}));
break;
}
case Constants.ListValue: {
var listValue = value = handleSimpleValue(valueJsonld, ReadListValue, jsonConvert);
value = listValue.pipe(mergeMap(function (listVal) {
// get referred list node's label
return listNodeCache.getNode(listVal.listNode).pipe(map(function (listNode) {
listVal.listNodeLabel = listNode.label;
listVal.strval = listNode.label;
return listVal;
}));
}));
break;
}
case Constants.UriValue: {
var uriVal = handleSimpleValue(valueJsonld, ReadUriValue, jsonConvert);
value = uriVal.pipe(map(function (val) {
val.strval = val.uri;
return val;
}));
break;
}
case Constants.TextValue: {
var textVal = handleTextValue(valueJsonld, jsonConvert);
value = textVal.pipe(map(function (val) {
if (val instanceof ReadTextValueAsString) {
val.strval = val.text;
}
else if (val instanceof ReadTextValueAsXml) {
val.strval = val.xml;
}
else if (val instanceof ReadTextValueAsHtml) {
val.strval = val.html;
}
else {
console.error("String representation for a ReadTextValue could not be constructed for: ", type);
}
return val;
}));
break;
}
case Constants.LinkValue: {
var linkVal = handleLinkValue(valueJsonld, ontologyCache, listNodeCache, jsonConvert);
value = linkVal.pipe(map(function (val) {
if (val.linkedResource !== undefined) {
val.strval = val.linkedResource.label;
}
else {
val.strval = val.linkedResourceIri;
}
return val;
}));
break;
}
case Constants.GeomValue: {
var geomVal = handleSimpleValue(valueJsonld, ParseReadGeomValue, jsonConvert);
value = geomVal.pipe(map(function (geom) {
return new ReadGeomValue(geom);
}));
break;
}
case Constants.AudioFileValue: {
var audioVal = handleSimpleValue(valueJsonld, ReadAudioFileValue, jsonConvert);
value = audioVal.pipe(map(function (val) {
val.strval = val.fileUrl;
return val;
}));
break;
}
case Constants.DocumentFileValue: {
var documentVal = handleSimpleValue(valueJsonld, ReadDocumentFileValue, jsonConvert);
value = documentVal.pipe(map(function (val) {
val.strval = val.fileUrl;
return val;
}));
break;
}
case Constants.MovingImageFileValue: {
var movingImageVal = handleSimpleValue(valueJsonld, ReadMovingImageFileValue, jsonConvert);
value = movingImageVal.pipe(map(function (val) {
val.strval = val.fileUrl;
return val;
}));
break;
}
case Constants.StillImageFileValue: {
var stillImageVal = handleSimpleValue(valueJsonld, ReadStillImageFileValue, jsonConvert);
value = stillImageVal.pipe(map(function (val) {
val.strval = val.fileUrl;
return val;
}));
break;
}
case Constants.StillImageExternalFileValue: {
var extStillImageVal = handleSimpleValue(valueJsonld, ReadStillImageExternalFileValue, jsonConvert);
value = extStillImageVal.pipe(map(function (val) {
return val;
}));
break;
}
case Constants.ArchiveFileValue: {
var archiveVal = handleSimpleValue(valueJsonld, ReadArchiveFileValue, jsonConvert);
value = archiveVal.pipe(map(function (val) {
val.strval = val.fileUrl;
return val;
}));
break;
}
case Constants.TextFileValue: {
var textVal = handleSimpleValue(valueJsonld, ReadTextFileValue, jsonConvert);
value = textVal.pipe(map(function (val) {
val.strval = val.fileUrl;
return val;
}));
break;
}
case Constants.TimeValue: {
var timeVal = handleSimpleValue(valueJsonld, ReadTimeValue, jsonConvert);
value = timeVal.pipe(map(function (val) {
val.strval = val.time;
return val;
}));
break;
}
case Constants.GeonameValue: {
var geonameVal = handleSimpleValue(valueJsonld, ReadGeonameValue, jsonConvert);
value = geonameVal.pipe(map(function (val) {
val.strval = val.geoname;
return val;
}));
break;
}
default: {
console.error("Unknown value type: ", type);
value = of(jsonConvert.deserialize(valueJsonld, ReadValue));
}
}
return value.pipe(map(function (val) {
val.property = propIri;
val.propertyLabel = entitiyDefs.properties[propIri].label;
val.propertyComment = entitiyDefs.properties[propIri].comment;
return val;
}));
};
/**
* Creates a response to a count query.
* @param countQueryResult the result of the count query.
* @param jsonConvert the instance of jsonConvert to be used.
*/
ResourcesConversionUtil.createCountQueryResponse = function (countQueryResult, jsonConvert) {
if (Array.isArray(countQueryResult))
throw new Error("countQueryResult is expected to be a single object");
return jsonConvert.deserialize(countQueryResult, CountQueryResponse);
};
})(ResourcesConversionUtil || (ResourcesConversionUtil = {}));
;
//# sourceMappingURL=ResourcesConversionUtil.js.map