sparnatural
Version:
Visual client-side SPARQL query builder and knowledge graph exploration tool
239 lines • 10.8 kB
JavaScript
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