@dasch-swiss/dsp-js
Version:
TypeScript client library for DSP-API
123 lines • 5.86 kB
JavaScript
import { forkJoin, of, map, mergeMap } from 'rxjs';
import { OntologyConversionUtil } from '../../models/v2/ontologies/OntologyConversionUtil';
import { ResourceClassDefinition } from '../../models/v2/ontologies/resource-class-definition';
import { GenericCache } from '../GenericCache';
import { ResourceClassAndPropertyDefinitions } from './resource-class-and-property-definitions';
import { ResourceClassDefinitionWithPropertyDefinition } from './resource-class-definition-with-property-definition';
/**
* Caches ontologies obtained from Knora and handles direct dependencies between ontologies.
*/
export class OntologyCache extends GenericCache {
constructor(knoraApiConfig, v2Endpoint) {
super();
this.knoraApiConfig = knoraApiConfig;
this.v2Endpoint = v2Endpoint;
}
/**
* Gets an ontology from the cache including its direct dependencies.
*
* The ontology Iris are the keys of the resulting Map.
*
* @param ontologyIri the Iri of the ontology.
* @returns the requested ontology and its direct dependencies.
*/
getOntology(ontologyIri) {
return this.getItem(ontologyIri).pipe(mergeMap((ontology) => {
if (ontology.dependsOnOntologies.size > 0) {
// get dependencies
const deps = [];
ontology.dependsOnOntologies.forEach((depKey) => {
deps.push(this.getItem(depKey));
});
// return when all dependencies have been resolved
return forkJoin(deps).pipe(map(ontos => {
const ontoMap = new Map();
// combine ontology and dependencies
[ontology].concat(ontos).forEach((onto) => {
ontoMap.set(onto.id, onto);
});
return ontoMap;
}));
}
else {
// no dependencies
const ontoMap = new Map();
ontoMap.set(ontology.id, ontology);
return of(ontoMap);
}
}));
}
/**
* Gets a resource class definition including the property definitions
* the resource class has cardinalities for.
*
* This method does not return third party ontology entities, e.g., rdfs.
*
* @param resourceClassIri
*/
getResourceClassDefinition(resourceClassIri) {
const ontoIri = OntologyConversionUtil.getOntologyIriFromEntityIri(resourceClassIri, this.knoraApiConfig);
if (ontoIri.length !== 1)
throw Error(`Invalid resource class Iri ${resourceClassIri}`);
const ontology = this.getOntology(ontoIri[0]);
return ontology.pipe(map(ontosMap => {
const mainOnto = ontosMap.get(ontoIri[0]);
if (mainOnto === undefined)
throw new Error('Expected ontology not found');
if (mainOnto.classes.hasOwnProperty(resourceClassIri) &&
mainOnto.classes[resourceClassIri] instanceof ResourceClassDefinition) {
const tmpClasses = {};
const tmpProps = {};
tmpClasses[resourceClassIri] = mainOnto.classes[resourceClassIri];
// filter out non Knora properties
tmpClasses[resourceClassIri].propertiesList = tmpClasses[resourceClassIri].propertiesList.filter((hasProp) => {
return (OntologyConversionUtil.getOntologyIriFromEntityIri(hasProp.propertyIndex, this.knoraApiConfig)
.length === 1);
});
tmpClasses[resourceClassIri].propertiesList.forEach((prop) => {
// prop could refer to entities in the ontology the requested resource class belongs to
// or to other ontologies the resource class has prop cardinalities for, e.g. knora api or another project ontology.
const fromOntoIri = OntologyConversionUtil.getOntologyIriFromEntityIri(prop.propertyIndex, this.knoraApiConfig);
if (fromOntoIri.length === 1) {
const fromOnto = ontosMap.get(fromOntoIri[0]);
if (fromOnto === undefined)
throw new Error('Expected ontology not found');
tmpProps[prop.propertyIndex] = fromOnto.properties[prop.propertyIndex];
}
});
return new ResourceClassAndPropertyDefinitions({
[resourceClassIri]: new ResourceClassDefinitionWithPropertyDefinition(tmpClasses[resourceClassIri], tmpProps),
}, tmpProps);
}
else {
// resource class not found
// TODO: Should an error be thrown?
return new ResourceClassAndPropertyDefinitions({}, {});
}
}));
}
/**
* Public method to access the reloadItem method
*
* @param key the id of the information to be returned.
* @return the item
*/
reloadCachedItem(key) {
return this.reloadItem(key);
}
requestItemFromKnora(key, isDependency) {
// Cache all-language label/comment arrays so consumers can re-render and re-sort
// on UI language change without re-fetching the ontology. Trade-off: cached
// ReadOntology instances are larger (one string per supported language instead
// of a single server-resolved string), and GenericCache has no eviction policy.
const allLanguages = true;
return this.v2Endpoint.onto.getOntology(key, allLanguages).pipe(map((onto) => [onto]));
}
getKeyOfItem(item) {
return item.id;
}
getDependenciesOfItem(item) {
return Array.from(item.dependsOnOntologies);
}
}
//# sourceMappingURL=OntologyCache.js.map