UNPKG

sparnatural

Version:

Visual client-side SPARQL query builder and knowledge graph exploration tool

239 lines 10.8 kB
import { DataFactory } from "rdf-data-factory"; import { Config } from "../../ontologies/SparnaturalConfig"; import { SHACLSpecificationEntry } from "./SHACLSpecificationEntry"; import { SpecialSHACLSpecificationEntityRegistry, } from "./SHACLSpecificationEntity"; import { Datasources } from "../../ontologies/SparnaturalConfigDatasources"; import { DatasourceReading } from "../DatasourceReading"; import { Model, RDF, SH, ShaclModel, ShapeFactory, StatisticsReader, XSD, } from "rdf-shacl-commons"; const factory = new DataFactory(); export class SHACLSpecificationProperty extends SHACLSpecificationEntry { constructor(uri, provider, n3store, lang) { super(uri, provider, n3store, lang); } /** * Tests whether the provided property shape URI will be turned into a Sparnatural property * @param propertyShapeUri * @param n3store * @returns false if the property is deactivated, or it has an sh:hasValue */ static isSparnaturalSHACLSpecificationProperty(propertyShapeUri, n3store) { let graph = new Model(n3store); let statReader = new StatisticsReader(graph); let shapeIri = factory.namedNode(propertyShapeUri); return (!graph.hasTriple(shapeIri, SH.DEACTIVATED, factory.literal("true", XSD.BOOLEAN)) && !graph.hasTriple(shapeIri, SH.HAS_VALUE, null) && // if there is a qualified value shape with a sh:hasValue, exclude too as this represents a fixed value that we don't want to query !(graph.hasTriple(shapeIri, SH.QUALIFIED_VALUE_SHAPE, null) && graph.hasTriple(graph.readSingleProperty(shapeIri, SH.QUALIFIED_VALUE_SHAPE), SH.HAS_VALUE, null)) && (!statReader.hasStatistics(shapeIri) || statReader.getTriplesCountForShape(shapeIri) > 0)); } getLabel() { return this.shape.getLabel(this.lang); } getTooltip() { return this.shape.getTooltip(this.lang); } getPropertyType(range) { return this.shape .getSearchWidgetForRange(factory.namedNode(range)) .getResource().value; } /** * A property is multilingual if its datatype points to rdf:langString */ isMultilingual() { return this.graph.hasTriple(factory.namedNode(this.uri), SH.DATATYPE, RDF.LANG_STRING); } isDeactivated() { return this.shape.isDeactivated(); } getShPath() { return this.shape.getShPath(); } getParents() { return this.shape .getParentProperties() .map((r) => r.resource.value); } /** * @returns */ getRange() { // first read on property shape itself var classes = this.shape .resolveShNodeOrShClass() .map((r) => r.value); // nothing, see if some default can apply on the property shape itself if (classes.length == 0) { SpecialSHACLSpecificationEntityRegistry.getInstance() .getRegistry() .forEach((value, key) => { if (key != SpecialSHACLSpecificationEntityRegistry.SPECIAL_SHACL_ENTITY_OTHER) { if (value.isRangeOf(this.store, this.uri)) { classes.push(key); } } }); } // still nothing, look on the sh:or members if (classes.length == 0) { var orMembers = this.shape .getShOr() .map((m) => ShapeFactory.buildShape(m, new ShaclModel(this.store))); orMembers?.forEach((m) => { // read sh:class / sh:node var orClasses = m .resolveShNodeOrShClass() .map((r) => r.value); // nothing, see if default applies on this sh:or member if (orClasses.length == 0) { SpecialSHACLSpecificationEntityRegistry.getInstance() .getRegistry() .forEach((value, key) => { if (key != SpecialSHACLSpecificationEntityRegistry.SPECIAL_SHACL_ENTITY_OTHER) { if (value.isRangeOf(this.store, m.resource.value)) { orClasses.push(key); } } }); } // still nothing, recurse one level more if (orClasses.length == 0) { var orOrMembers = m .getShOr() .map((m) => ShapeFactory.buildShape(m, new ShaclModel(this.store))); orOrMembers?.forEach((orOrMember) => { // read sh:class / sh:node var orOrClasses = orOrMember .resolveShNodeOrShClass() .map((r) => r.value); // nothing, see if default applies on this sh:or member if (orOrClasses.length == 0) { SpecialSHACLSpecificationEntityRegistry.getInstance() .getRegistry() .forEach((value, key) => { if (key != SpecialSHACLSpecificationEntityRegistry.SPECIAL_SHACL_ENTITY_OTHER) { if (value.isRangeOf(this.store, m.resource.value)) { orClasses.push(key); } } }); } }); } // still nothing, add default, only if not added previously if (orClasses.length == 0) { if (orClasses.indexOf(SpecialSHACLSpecificationEntityRegistry.SPECIAL_SHACL_ENTITY_OTHER) == -1) { orClasses.push(SpecialSHACLSpecificationEntityRegistry.SPECIAL_SHACL_ENTITY_OTHER); } } // add sh:or range to final list of ranges classes.push(...orClasses); }); // end iterate sh:or members } // still nothing, look for sh:class or sh:node on an sh:qualifiedValueShape if (classes.length == 0) { var qvs = this.shape.getShQualifiedValueShape(); if (qvs) { var qvsClasses = qvs .resolveShNodeOrShClass() .map((r) => r.value); // nothing, see if default applies on this sh:qualifiedValueShape if (qvsClasses.length == 0) { SpecialSHACLSpecificationEntityRegistry.getInstance() .getRegistry() .forEach((value, key) => { if (key != SpecialSHACLSpecificationEntityRegistry.SPECIAL_SHACL_ENTITY_OTHER) { if (value.isRangeOf(this.store, qvs.resource.value)) { qvsClasses.push(key); } } }); } // still nothing, add default, only if not added previously if (qvsClasses.length == 0) { if (qvsClasses.indexOf(SpecialSHACLSpecificationEntityRegistry.SPECIAL_SHACL_ENTITY_OTHER) == -1) { qvsClasses.push(SpecialSHACLSpecificationEntityRegistry.SPECIAL_SHACL_ENTITY_OTHER); } } // add sh:qualifiedValueShape range to final list of ranges classes.push(...qvsClasses); } } // still nothing, add the default if (classes.length == 0) { classes.push(SpecialSHACLSpecificationEntityRegistry.SPECIAL_SHACL_ENTITY_OTHER); } // return a dedup array return [...new Set(classes)]; } getDatasource() { return DatasourceReading.readDatasourceAnnotationProperty(this.uri, Datasources.DATASOURCE, this.graph); } getTreeChildrenDatasource() { return DatasourceReading.readDatasourceAnnotationProperty(this.uri, Datasources.TREE_CHILDREN_DATASOURCE, this.graph); } getTreeRootsDatasource() { return DatasourceReading.readDatasourceAnnotationProperty(this.uri, Datasources.TREE_ROOTS_DATASOURCE, this.graph); } getMinValue() { let datatype = this.shape.getShDatatype(); if (datatype && datatype.length > 0) { return datatype[0]?.minInclusive?.toString(); } } getMaxValue() { let datatype = this.shape.getShDatatype(); if (datatype && datatype.length > 0) { return datatype[0]?.maxInclusive?.toString(); } } getValues() { return this.shape.getShIn(); } getBeginDateProperty() { return this.graph.readSingleProperty(factory.namedNode(this.uri), factory.namedNode(Config.BEGIN_DATE_PROPERTY))?.value; } getEndDateProperty() { return this.graph.readSingleProperty(factory.namedNode(this.uri), factory.namedNode(Config.END_DATE_PROPERTY))?.value; } getExactDateProperty() { return this.graph.readSingleProperty(factory.namedNode(this.uri), factory.namedNode(Config.EXACT_DATE_PROPERTY))?.value; } isEnablingNegation() { return !(this.graph.readSingleProperty(factory.namedNode(this.uri), factory.namedNode(Config.ENABLE_NEGATION))?.value == "false"); } isEnablingOptional() { return !(this.graph.readSingleProperty(factory.namedNode(this.uri), factory.namedNode(Config.ENABLE_OPTIONAL))?.value == "false"); } getServiceEndpoint() { const service = this.graph.readSingleProperty(factory.namedNode(this.uri), factory.namedNode(Config.SPARQL_SERVICE)); if (service) { return this.graph.readSingleProperty(service, factory.namedNode(Config.ENDPOINT))?.value; } } isLogicallyExecutedAfter() { return this.graph.hasTriple(factory.namedNode(this.uri), factory.namedNode(Config.SPARNATURAL_CONFIG_CORE + "executedAfter"), null); } hasQualifiedValueShapeRange() { var qvs = this.shape.getShQualifiedValueShape(); if (qvs) { var qvsClasses = qvs .resolveShNodeOrShClass() .map((r) => r.value); if (qvsClasses.length > 0) { return true; } } return false; } static compare(item1, item2) { return SHACLSpecificationEntry.compare(item1, item2); } } //# sourceMappingURL=SHACLSpecificationProperty.js.map