UNPKG

sparnatural

Version:

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

144 lines 6.72 kB
import { DataFactory } from 'rdf-data-factory'; import { SHACLSpecificationEntry } from "./SHACLSpecificationEntry"; import { SHACLSpecificationEntity, SpecialSHACLSpecificationEntityRegistry } from "./SHACLSpecificationEntity"; import { SHACLSpecificationProperty } from "./SHACLSpecificationProperty"; import { Model, RDF, SH, ShaclModel, ShaclSparqlPostProcessor, StatisticsReader, XSD } from 'rdf-shacl-commons'; import { BaseRdfStore } from '../BaseRdfStore'; import { Dag } from '../../dag/Dag'; const factory = new DataFactory(); export class SHACLSpecificationProvider extends BaseRdfStore { constructor(n3store, lang) { super(n3store, lang); // skolemize blank nodes ShaclModel.skolemizeAnonymousPropertyShapes(this.store); } getAllSparnaturalEntities() { const quadsArray = this.store.getQuads(null, RDF.TYPE, SH.NODE_SHAPE, null); const itemsSet = new Set(); for (const quad of quadsArray) { var nodeShapeId = quad.subject.value; itemsSet.add(this.getEntity(nodeShapeId)); } let items = SHACLSpecificationEntry.sort(Array.from(itemsSet)); return items.map(e => e.getId()); } getEntitiesInDomainOfAnyProperty() { // map to extract just the uri return this.getInitialEntityList().map(e => e.getId()); } getEntitiesTreeInDomainOfAnyProperty() { // 1. get the entities that are in a domain of a property let entities = this.getInitialEntityList(); // 2. add the children of these entities - recursively // while the children of every entity is not found in our flat list of entity, continue adding children while (!entities.every(entity => { return entity.getChildren().every(child => { // avoid testing deactivated shapes return (this.isDeactivated(factory.namedNode(child))) || (entities.find(anotherEntity => anotherEntity.getId() === child) != undefined); }); })) { let childrenToAdd = []; // for each entity in the initial list... entities.forEach(entity => { // foreach child of this entity... entity.getChildren().forEach(child => { // if this child is not in the list, add it if ( // don't put deactivated shapes in the list !this.isDeactivated(factory.namedNode(child)) && !entities.find(anotherEntity => anotherEntity.getId() === child)) { childrenToAdd.push(this.getEntity(child)); } }); }); childrenToAdd.forEach(p => entities.push(p)); } // 3. complement the initial list with their parents let disabledList = new Array(); while (!entities.every(entity => { return entity.getParents().every(parent => { return (entities.find(anotherEntity => anotherEntity.getId() === parent) != undefined); }); })) { let parentsToAdd = []; entities.forEach(entity => { entity.getParents().forEach(parent => { if (!entities.find(anotherEntity => anotherEntity.getId() === parent)) { parentsToAdd.push(this.getEntity(parent)); } }); }); parentsToAdd.forEach(p => entities.push(p)); // also keep that as a disabled node parentsToAdd.forEach(p => disabledList.push(p.getId())); } let dag = new Dag(); dag.initFromParentableAndIdAbleEntity(entities, disabledList); let statisticsReader = new StatisticsReader(new Model(this.store)); // add count dag.traverseBreadthFirst((node) => { if (node.parents.length == 0) { // if this is a root // add a count to it node.count = statisticsReader.getEntitiesCountForShape(factory.namedNode(node.payload.getId())); } else { // otherwise make absolutely sure the count is undefined node.count = undefined; } }); // sort tree dag.sort(SHACLSpecificationEntity.compare); return dag; } expandSparql(sparql, prefixes) { let postProc = new ShaclSparqlPostProcessor(new ShaclModel(this.store)); return postProc.expandSparql(sparql, prefixes); } getLanguages() { let shaclStoreModel = new ShaclModel(this.store); return shaclStoreModel.readAllLanguages(); } getEntity(uri) { if (SpecialSHACLSpecificationEntityRegistry.getInstance().getRegistry().has(uri)) { return SpecialSHACLSpecificationEntityRegistry.getInstance().getRegistry().get(uri); } return new SHACLSpecificationEntity(uri, this, this.store, this.lang); } getProperty(uri) { if (!this.graph.hasTriple(factory.namedNode(uri), null, null)) { console.warn("The requested property " + uri + " is unknown in the configuration. We cannot find any triple with this URI as subject."); return undefined; } return new SHACLSpecificationProperty(uri, this, this.store, this.lang); } getInitialEntityList() { const duplicatedNodeShapes = this.store.getQuads(null, SH.PROPERTY, null, null).map(triple => triple.subject); let dedupNodeShapes = [...new Set(duplicatedNodeShapes)]; // remove from the initial list the NodeShapes that are marked with sh:deactivated let that = this; dedupNodeShapes = dedupNodeShapes.filter(node => { return !that.isDeactivated(node); }); // remove from the initial list the NodeShapes that are connected to only properties that Sparnatural will not use // by checking the lenght of the list of properties we can make sure of that dedupNodeShapes = dedupNodeShapes.filter(node => { return this.getEntity(node.value).getProperties().length > 0; }); var items = []; for (const aNode of dedupNodeShapes) { items.push(this.getEntity(aNode.value)); } items = SHACLSpecificationEntry.sort(items); return items; } /** * @param node a NodeShape * @returns true if the NodeShape is the subject of sh:deactivated true */ isDeactivated(node) { return this.graph.hasTriple(node, SH.DEACTIVATED, factory.literal("true", XSD.BOOLEAN)); } } //# sourceMappingURL=SHACLSpecificationProvider.js.map