Page MenuHomec4science

statement-handler.ts
No OneTemporary

File Metadata

Created
Fri, Nov 15, 19:04

statement-handler.ts

import {EDITINGURL} from '../constants';
import {
DELETE_LIST_ENTRIES_RQ, DELETE_SPO_RQ, RQ_ASK_IF_PROPERTY, RQ_CONSTRUCT_LISTS, RQ_GET_DOMAIN, RQ_GET_RANGE,
RQ_GET_SP_WHERE_THING_IN_LIST,
RQ_GET_SPO
} from './constants';
import {QueryService, TlnQueryParametrizer} from '../services/query.service';
import * as N3 from "node_modules/n3/src";
import {RdfEditorData, RdfStoredData} from './rdf-editor-DataSets';
/**
* Class for Handling all statements
**/
export class StatementHandler {
protected _agentStatements: Map<string, TlnStatementCollection>; // all the statements of a given thing as agent, e.g. subject
protected _agentListStatements: Map<string, string>; // For Resources/Subjects: Contains all connected lists
protected _agentListsAsStatements: Map<string, TlnStatementCollection>; // all the lists converted to real spo
protected _patientStatements: Map<string, TlnStatementCollection>; // all the statements containing the thing as patient, e.g. as object
protected _patientListStatements: Map<string, string>; // all the lists containing a given thing
protected _patientListsAsStatements: Map<string, TlnStatementCollection>; // all the s p to lists in which a given thing is listed
protected _editorDef: ChangeMgmntDef;
constructor(editorDef?: ChangeMgmntDef) {
this._agentStatements = new Map<string, TlnStatementCollection>();
this._agentListStatements = new Map<string, string>();
this._agentListsAsStatements = new Map<string, TlnStatementCollection>();
this._patientStatements = new Map<string, TlnStatementCollection>();
this._patientListStatements = new Map<string, string>();
this._patientListsAsStatements = new Map<string, TlnStatementCollection>();
if (editorDef) {this._editorDef = editorDef} else { this._editorDef = new ChangeMgmntDef()}
}
// async builder
// gets all statements from store for each given predicate
// listPatient: if patient === true, also all patient statements are loaded from store, i.e. all staments where the given iri acts as a object. This will take
// some time and there might even result in a server side timeout.
public static async buildFromStoreAsync(qService: QueryService,
iri: string,
availablePreds: Map<string,TlnPredicate>,
editorDef: ChangeMgmntDef): Promise<StatementHandler> {
let build = new StatementHandler(editorDef);
for (const [key, value] of availablePreds) {
if (value.takesListAsObject()) { // if the predicate expects a list as object we set the list and also
const list = await StatementHandler.getListDataFromStore(qService, iri, key);
build.setListStatement(value, list.toString() );
build._agentListsAsStatements = await build.convertListToIndividualStatements(value, list.toString());
} if (!value.takesListAsObject()) { // getting objects and adding statements
const spo = await StatementHandler.getSPOFromStore(qService, iri, key);
const objects = spo.map(p => p['o'].value );
for (const obj of objects) {
build.putAgentStatement(value, obj); }
}
}
// getting also all patient statements of the iri if patient or listPatient = true
if (build._editorDef.patientStatements) {
build._patientStatements = await StatementHandler.getPatientStatementsFromStoreAsync(qService, iri);
}
if (build._editorDef.patientListStatements) {
build._patientListsAsStatements = await build.getPatientListStatementsFromStoreAsync(qService, iri);
}
return build;
}
// returns a Promise of a clone of the statementHandler. Iterates every property of STatementHandler and copies that to the
// the new StatementHandler stmClone which will be returned.
public async selfCloneAsync(): Promise<StatementHandler> {
let stmClone = new StatementHandler();
for (let key of Object.keys(this)) {
if (this[key] instanceof Map) {
StatementHandler.statementCloneAsync(this[key]).then( clone => stmClone[key] = clone);
}
else { stmClone[key] = this[key] } // for editorDef
}
return stmClone;
}
// private methods
// gets the list as ttl for a given predicate
private static getListDataFromStore(qService: QueryService, subjectIri?: string, predicateIri?: string, objectIri?: string): Promise<ArrayBuffer> {
if (!subjectIri && !predicateIri && !objectIri) {return} // guard
let query = QueryService.parametrizeWhereClauseWithItem(RQ_CONSTRUCT_LISTS, subjectIri, predicateIri, objectIri);
return qService.getData(EDITINGURL, query, 'CONSTRUCT' );
}
// gets the the objects for a given subje predicate
private static async getSPOFromStore(qService: QueryService, subjectIri?: string, predicateIri?: string, objectIri?: string) {
if (!subjectIri && !predicateIri && !objectIri) {return} // guard
const query = qService.parametrizeWhereClauseWithItems(RQ_GET_SPO, subjectIri , predicateIri, objectIri );
return await qService.getData(EDITINGURL, query, 'SELECT').then(
result => {
return result['results']['bindings'];
}
)
}
private static async getPatientStatementsFromStoreAsync(qService: QueryService, objectIri: string): Promise<Map<string, TlnStatementCollection>> {
let patientStatements = new Map<string, TlnStatementCollection>(); // RQ_GET_SPO
const statements = await StatementHandler.getSPOFromStore(qService,'', '', objectIri);
for (const statement of statements) {
if (statement.hasOwnProperty('p') && statement.hasOwnProperty('s') && statement['s'].type !== 'bnode' ) {
if (!patientStatements.has(statement['p'].value)) {// if there is not yet a key for that property we create a new statement
patientStatements.set(statement['p'].value, new TlnStatementCollection(new TlnPredicate(statement['p'].value))) }
patientStatements.get(statement['p'].value).put(statement['s'].value);
}
}
return patientStatements;
}
// clones a given StatementCollection Map
public static async statementCloneAsync(stms: Map<string, any>) {
let stmColClone = new Map<string, any>();
if (stms.size === 0) {return stmColClone} // guard
for (let [key, value] of stms) {
if ( value instanceof TlnStatementCollection) { // then we have to deep clone it as well
stmColClone.set(key, value.selfClone());
}
if ( value instanceof String) { // for lists: we just set the string
stmColClone.set(key, value);
}
}
return stmColClone;
}
// gets all statements s p to lists which contain the given iri.
private async getPatientListStatementsFromStoreAsync(qService: QueryService, iri: string): Promise<Map<string, TlnStatementCollection>> {
let patientListAsStatements = new Map<string, TlnStatementCollection>();
// getting also the patient statements/incoming statements
let statements = await this.getPatientStatementsForListOccurencies(qService, iri);
for (const stm of statements) {
patientListAsStatements.set(stm.predicate().iri(), stm) }
return patientListAsStatements;
}
// Gets all the patient statements containing to lists containing the given objectIri
// and returns the connecting outer predicate & resource
private async getPatientStatementsForListOccurencies(qService: QueryService, objectIri: string): Promise<TlnStatementCollection[]> {
const query = qService.bindVariableWithIri(RQ_GET_SP_WHERE_THING_IN_LIST, 'thing', objectIri);
return await qService.getData(EDITINGURL, query, 'SELECT').then(
result => {
return result['results']['bindings'].map(entry =>
new TlnStatementCollection(new TlnPredicate(entry['s'].value, new Set(['http://www.w3.org/1999/02/22-rdf-syntax-ns#List'])),
[entry['p'].value]));
}
)
}
// creates proper statements from a list to listAsStatements
private async convertListToIndividualStatements(predicate: TlnPredicate, list: string): Promise<Map<string, TlnStatementCollection>>{
let listsAsStatements = new Map<string, TlnStatementCollection>();
const parser = new N3.Parser();
await parser.parse(list, // parsing the list to quads
async (error, quad) => { // adding all predicates/objects to statements
if (quad && (quad.object.termType === 'NamedNode' || quad.object.termType === 'Literal') &&
quad.object.value &&
quad.object.value !== 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil') {
if (!listsAsStatements.has(predicate.iri())) {// if there is not yet a key for that property we create a new TlnStatement
listsAsStatements.set(predicate.iri(), new TlnStatementCollection(predicate))
}
listsAsStatements.get(predicate.iri()).put(quad.object.value ); // setting the object
}
});
return listsAsStatements;
}
// returns all agent statements as n3 quads
public getAgentStmQuads(iri: string) {
let quads: N3.Quad[] = [];
if (this._agentStatements.size === 0) { return quads } // guard
this._agentStatements.forEach((stm) => {
stm.getNodes().forEach(object => {
if (iri && stm.n3Predicate() && object) {
quads.push(new N3.Quad(new N3.Term(iri), stm.n3Predicate(), object));
}
});
});
return quads;
}
// returns all listStatements as a new n3 list quad
public getAgentListsAsQuads(iri: string): N3.Quad[] {
let quads: N3.Quad[] = []; // guard
if (this._agentListsAsStatements.size === 0) { return quads }
this._agentListsAsStatements.forEach(stm => {
quads.push(new N3.Quad(iri, stm.n3Predicate(), new N3.Writer().list(stm.getNodes()))) // list
});
return quads;
}
// returns all patient statements inverted back into the original triples s p o as n3 quads
public getPatientStmAsQuads(iri: string) {
let quads: N3.Quad[] = [];
if (this._patientStatements.size === 0) { return quads } // guard
this._patientStatements.forEach((stm) => {
stm.getNodes().forEach(object => {
if (iri && stm.n3Predicate() && object) {
// inverting object with subject, hence in patient statements the iri is the actual object in the statements
quads.push(object, stm.n3Predicate(), new N3.Quad(new N3.Term(iri) ));
}
});
});
return quads;
}
// public methods
// puts as object to a
public putAgentStatement(predicate: TlnPredicate, objectIri: string, index?: number) {
if (!this._agentStatements.has(predicate.iri())) {// if there is not yet a key for that property we create a new statement
this._agentStatements.set(predicate.iri(), new TlnStatementCollection(predicate)) }
this._agentStatements.get(predicate.iri()).put(objectIri, index);
}
//
public setAgentStatement(predicate: TlnPredicate, objectIri: string, index: number) {
if (!this._agentStatements.has(predicate.iri())) {// if there is not yet a key for that property we create a new statement
this._agentStatements.set(predicate.iri(), new TlnStatementCollection(predicate))}
this._agentStatements.get(predicate.iri()).set(objectIri, index);
}
// As there should be only one list as object per subject and predicate - everything else is a data mess - we simply set it
public setListStatement(predicate: TlnPredicate, list: string) {
if (!this._agentListsAsStatements.has(predicate.iri())) {// if there is not yet a key for that property we create a new statement
this._agentListsAsStatements.set(predicate.iri(), new TlnStatementCollection(predicate)) }
this._agentListStatements.set(predicate.iri(), list);
}
// puts as object to a
public putListAsStmStatement(predicate: TlnPredicate, objectIri: string, index?: number) {
if (!this._agentListsAsStatements.has(predicate.iri())) {// if there is not yet a key for that property we create a new statement
this._agentListsAsStatements.set(predicate.iri(), new TlnStatementCollection(predicate)) }
this._agentListsAsStatements.get(predicate.iri()).put(objectIri, index);
}
// sets a statement in _listAsStatements
public setListAsStmStatement(predicate: TlnPredicate, objectIri: string, index) {
this._agentListsAsStatements.get(predicate.iri()).set(objectIri, index); // setting the object
}
public deleteAllStatementsForPredicate(predicateIri: string) {
if (this.hasStatementForPredicate(predicateIri) && this.hasStatementEntriesForPredicate(predicateIri)) {
this._agentStatements.delete(predicateIri);
}
}
public deleteAllObjectPresence(objectIri: string) {
this.deleteAgentStatementsWithO(objectIri);
this.deleteAllListAsStatementsWithObject(objectIri);
}
//deletes all agentStatements as well as the agentListAsStatements
public deleteAllAgentStatements() {
this._agentStatements.forEach((value, key) => {
this._agentStatements.get(key).deleteAll();
});
this._agentListsAsStatements.forEach((value, key) => {
this._agentListsAsStatements.get(key).deleteAll();
});
}
// deletes all _agentStatements containing a given object
public deleteAgentStatementsWithO(objectIri: string) {
this._agentStatements.forEach(statement => {
const idx = statement.nodeIdx(objectIri);
if (idx > -1) {
statement.del(idx);
}
});
}
// deletes all listasaStaments
public deleteAllListAsStatementsWithObject(objectIri: string) {
console.log('HHHHHHHHHHHHHHHHHH', objectIri)
this._agentListsAsStatements.forEach((value, key) => {
console.log(value);
let idx = value.nodeIdx(objectIri);
if (idx !== -1) {
value.del(idx);
console.log('deleting ', objectIri)
} else {console.warn(`Resource ${objectIri} not found.`)}
});
}
// Obviously not needed in RDF itself, but useful for gui xperience and testing
public moveObjectInAgentStatement(predicate: string, previousIndex, newIndex) {
this._agentStatements.get(predicate).move(previousIndex, newIndex);
}
public moveObjectInListAsStatement(predicate: string, previousIndex, newIndex) {
this._agentListsAsStatements.get(predicate).move(previousIndex, newIndex);
}
// sets all _statements to a given statementCollection or empties all
public resetAgentStatements(statements: Map<string, TlnStatementCollection> = new Map<string, TlnStatementCollection>()) {
this._agentStatements= new Map(statements);
}
// sets or resets all _statements
public resetListStatements(listStatements: Map<string, string> = new Map<string, string>()) {
this._agentListStatements = new Map(listStatements);
}
public resetListAsStatements(listAsStatements: Map<string, TlnStatementCollection>) {
this._agentListsAsStatements = new Map(listAsStatements);
}
public resetPatientStatements(patientStatements: Map<string, TlnStatementCollection>) {
this._patientStatements = new Map(patientStatements);
}
public resetPatientListAsStatements(patientListAsStatements: Map<string, TlnStatementCollection>) {
this._patientListsAsStatements= new Map(patientListAsStatements);
}
public resetPatientListStatements(patientListStatements: Map<string, string>) {
this._patientListStatements = new Map(patientListStatements);
}
// returns whether a thing has a statements built with a certain property or not
public hasStatementForPredicate(predicateIri: string): boolean {
return this._agentStatements.get(predicateIri) !== undefined && this._agentStatements.get(predicateIri) !== null;
}
// Todo: remove
// returns all statementsAsList objects
public async getListObjectsForPredicate(predicate: string) {
if (this._agentListsAsStatements.size) {
let fuu = this._agentListsAsStatements.get(predicate)
}
let fuu = this._agentListsAsStatements.get(predicate)
return fuu;
}
// returns whether there is a statement conecting an object
public hasStatementWithObject(objectIri: string) {
let hasStatement = false;
this._agentStatements.forEach(statement => {
if (statement.hasNode(objectIri)) { hasStatement = true}
});
return hasStatement
}
public hasStatementEntriesForPredicate(predicateIri) {
return this.hasStatementForPredicate(predicateIri) && this._agentStatements.get(predicateIri).getNodes().length > 0;
}
public agentStatements() {
return this._agentStatements;
}
public agentListStatements() {
return this._agentListStatements;
}
public agentListsAsStatements() {
return this._agentListsAsStatements;
}
public patientStatements() {
return this._patientStatements;
}
public patientListStatements() {
return this._patientListStatements;
}
public patientListAsStatements() {
return this._patientListsAsStatements;
}
// returns all agent statements & agentLists statements of a thing as n3.Quad[];
public getAllAgentStmAsQuads(iri: string): N3.Quad[] {
let quads: N3.Quad[];
quads = [... this.getAgentStmQuads(iri), ... this.getAgentListsAsQuads(iri)];
return quads;
}
// returns all patient statements inverted as agent statements as n3.Quad[];
public getAllPatientStmAsAgentQuads(iri: string): N3.Quad[] {
let quads: N3.Quad[];
//quads = [... this.getAgentStmQuads(iri), ... this.getAgentListsAsQuads(iri)];
return quads;
}
// returns all patient statements & patient listAsstatements of a thing as n3.Quad[];
public getAllPatientStmAsQuads(iri: string): N3.Quad[] {
let quads: N3.Quad[];
// quads = [... this.getAgentStmQuads(iri), ... this.getAgentListsAsQuads(iri)];
return quads;
}
}
export class TlnStatementCollection {
private _predicate: TlnPredicate;
protected _n3PredicateNode: N3.NamedNode;
protected _nodes: N3.NamedNode|N3.Literal[];
constructor(predicate: TlnPredicate, nNodes: string[] = []) {
this._n3PredicateNode = new N3.NamedNode(predicate.iri());
this._predicate = predicate;
this._nodes = nNodes.map(val => this.createNode(val) );
}
private createNode(value: string) {
const { DataFactory } = N3;
if (this._predicate.takesLiteralAsObject()) {
const { literal } = DataFactory;
return literal(value) } else {
const { namedNode } = DataFactory;
namedNode.id = `${Date.now().valueOf().toString(36)}-${(Math.random()).toString(36).replace('.', '')}`;
return namedNode(value) }
}
// returns a cloned version of the TlnStatementCollection
public selfClone() {
let stmCol = new TlnStatementCollection(this.predicate());
stmCol._nodes = [...this._nodes];
return stmCol;
}
// puts a given object to a given index or adds it to the end if no index passed
// if no index the object will be added at the end as default
public put(value: string, index = this.getNodes().length) {
if (this._nodes.findIndex(obj => obj.id === value) !== -1) {
console.warn('Node already in statement', value);
}
this._nodes.splice(index, 0, this.createNode(value));
}
// overwrites an object at a given index
public set(value: string, index: number) {
this._nodes.splice(index, 1, this.createNode(value));
}
// deletes an object/one node
public del(index) {
this._nodes.splice(index, 1);
}
// deletes all nodes/objects
public deleteAll() {
this._nodes = [];
}
// moves a node in the _nodes array
public move(previousIndex, newIndex) {
const node = this._nodes[previousIndex];
this._nodes.splice(previousIndex, 1);
this._nodes.splice(newIndex, 0, node);
}
public setNodes(values: string[]) {
this._nodes = values.map(iri => this.createNode(iri));
}
public predicate() {
return this._predicate;
}
public n3Predicate() {
return this._n3PredicateNode;
}
public getNodes(): N3.NamedNode|N3.Literal[] {
return this._nodes;
}
// returns whether a TlnStatements instance contains a node with a given iri
public hasNode(iri: string) {
return this._nodes.findIndex(node => node.id === iri)>-1;
}
// returns the index of the object in this._nodese
public nodeIdx(objectIri: string): number {
return this._nodes.findIndex(node => node.id === objectIri);
}
}
// Operations to perform on the valid, productive dataset. No dep/deprecation-namespace here
export class StatementOperations {
additions: N3.Quad[] = [];
changes: N3.Quad[] = [];
deletions: N3.Quad[] = [];
delListQueries: string[] = []; // the sparql queries to delete listEntries & to delete the "s p list" triples
listsToWrite: N3.Quad[] = []; // the updated lists as quads to be imported
constructor() {
}
// builds the operation to perform by comparing two Maps of statement collections.
public static async getProductiveOperationsAsync(predecessor: RdfStoredData,
derivate: RdfEditorData,
updateLists: boolean): Promise<StatementOperations> {
let ops: StatementOperations = new StatementOperations();
predecessor.agentStatements().forEach(async (value, key) => {
// for every stm we check if it has been deleted or changed
if (derivate.agentStatements().has(key)) { // if the derivate statements contain at least one statement with the given predicate
// we check which ones have been deleted or changed ...
let difPerPredicate = await ops.compare(predecessor.iri(), key, value.getNodes(), derivate.agentStatements().get(key).getNodes());
// and push them
difPerPredicate.additions.forEach(a => ops.additions.push(a));
difPerPredicate.changes.forEach(c => ops.changes.push(c));
difPerPredicate.deletions.forEach(d => ops.deletions.push(d));
} else { // they have all been deleted
for (let node of value.getNodes()) {
const quad = new N3.Quad(new N3.Term(predecessor.iri()), new N3.Term(key), node);
ops.deletions.push(quad);
}
}
// checking also if there are completely new statements
derivate.agentStatements().forEach(async (value, key) => {
if (!predecessor.agentStatements().has(key)) { // then the predicate is completely new
value.getNodes().forEach(node => {
const addedQuad = new N3.Quad(new N3.Term(derivate.iri()), new N3.Term(key), node);
ops.additions.push(addedQuad);
});
}
})
});
// processing listStatements
if (updateLists) {
if (derivate.iri() === 'http://rdfh.ch/projects/0068#_Mp_XIV_IdentifiedTextVersion0') {console.log('LISTS UPDATING', predecessor, derivate)}
ops.setListUpdates(predecessor, derivate);
}
return ops;
}
setListUpdates(ancestor: RdfStoredData, derivate?: RdfEditorData) {
ancestor.listsAsStatements().forEach(async (value, key) => {
let delListEntriesQuery: string;
let delSPOToList: string;
// for every stm we check if it has been deleted or changed
if (!derivate) {
[delListEntriesQuery, delSPOToList] = TlnQueryParametrizer.getDelQueriesOfListsOfSP(ancestor.iri(),key);
}
if (derivate && derivate.listsAsStatements().has(key) ) {
// if the derivate statements have statements with the given predicate/key
if (this.listHasChanges(ancestor.iri(), key, value.getNodes(), derivate.listsAsStatements().get(key).getNodes())) {
// and if there have been made changes within the list
if (derivate.iri() === 'http://rdfh.ch/projects/0068#_Mp_XIV_IdentifiedTextVersion0') {console.log('hasChanges');}
// getting queries to delete lists and their entries
[delListEntriesQuery, delSPOToList] = TlnQueryParametrizer.getDelQueriesOfListsOfSP(derivate.iri(),key);
// set the new lists to write
let listToWrite = derivate.statements().getAgentListsAsQuads(derivate.iri());
console.log('listToWrite', listToWrite);
this.listsToWrite = [this.listsToWrite, ...derivate.statements().getAgentListsAsQuads(derivate.iri())];
}
}
if (delListEntriesQuery && delListEntriesQuery!== '') { this.delListQueries.push(delListEntriesQuery) }
if (delSPOToList && delSPOToList!== '') { this.delListQueries.push(delSPOToList) }
});
}
// returns whether there are any changes or not
public hasChanges() {
return (this.deletions.length + this.additions.length + this.changes.length + this.delListQueries.length + this.listsToWrite.length > 0 );
}
// compares all statements for one given predicate and returns a dif for the passed nodes
public async compare(subject: string, predicateIri: string, ancestorNodes: N3.NamedNode|N3.Literal[], derivateNodes: N3.NamedNode|N3.Literal[]): Promise<StatementOperations> {;
let ops: StatementOperations = new StatementOperations();
// first check if every ancestorNode has changed or been deleted
for ( let i = 0; i < ancestorNodes.length; i++ ) { // checking every stm
let derIdx = derivateNodes.findIndex(_node => _node.id === ancestorNodes[i].id);
if (derIdx === -1) {
// if the id is not in derivateNodes it has been deleted
const delQuad = new N3.Quad(new N3.Term(subject), new N3.Term(predicateIri), ancestorNodes[i]);
ops.deletions.push(delQuad) } else {
// we check if it has been moved in the array
if (derIdx !== i) { // it has been moved
}
// it is in the array, so we check for possible changes
if (JSON.stringify(derivateNodes[derIdx]) !== JSON.stringify(ancestorNodes[i])) { // it has been changed
const changedQuad = new N3.Quad(new N3.Term(subject), new N3.Term(predicateIri), derivateNodes[derIdx]);
ops.changes.push(changedQuad);
}
}
}
// then checking additions backwards
for (let node of derivateNodes) {
if (node.id === 'http://rdfh.ch/projects/0068#_Mp_XIV_Page419a') {
console.log('node', node);
console.log('ancestorNodes', ancestorNodes);
}
if (ancestorNodes.findIndex(n => n.id === node.id) === -1) {
const addedQuad = new N3.Quad(new N3.Term(subject), new N3.Term(predicateIri), node);
ops.additions.push(addedQuad);
console.log('addedQuad', addedQuad)
}
}
return ops;
}
// compares all statements for one given predicate and returns a dif for the passed nodes
public listHasChanges(subject: string, predicateIri: string, ancestorNodes: N3.NamedNode|N3.Literal[], derivateNodes: N3.NamedNode|N3.Literal[]): boolean {
// If length differs; covers
let changed = false;
if (ancestorNodes.length !== derivateNodes.length) {changed = true}
// first check if every ancestorNode has been exchanged, deleted or moved in the derivate array; covers also deletion of x addition of y
for ( let i = 0; i < ancestorNodes.length; i++ ) { // checking every stm
let derIdx = derivateNodes.findIndex(_node => _node.id === ancestorNodes[i].id);
if (derIdx === -1 || derIdx !== i) { // has been deleted, exchanged or moved
changed = true;
break; }
}
return changed;
}
}
export class TlnPredicate {
private _iri: string;
private _ranges: Set<string>;
private _domains: Set<string>;
private _label: string; // if no label passed generates a label from the iri per default
private _displayable = true;
private _mutable = true;
constructor(iri: string,
ranges = new Set<string>(),
domains = new Set<string>(),
label?, // if no label passed generates a label from the iri per default
displayable = true,
mutable = true ) {
this._iri = iri;
this._ranges = ranges;
this._domains = domains;
if (!label || label === '') { this._label = iri.split('#')[1] }
this._displayable = displayable;
this._mutable = mutable;
}
// static functions
// async builder
public static async buildFromStoreAsync(queryService: QueryService, predicateIri: string, displayable = true, mutable = true) {
let ranges = await TlnPredicate.getRangesFromStore(queryService, predicateIri);
let domains = await TlnPredicate.getDomainsFromStore(queryService, predicateIri);
// Todo: get label from store ...
return new TlnPredicate(predicateIri, new Set(ranges), new Set(domains), '' , displayable, mutable);
}
public static async askIfPredicate(qService: QueryService, iri: string): Promise<boolean> {
const query = qService.parametrizeWhereClauseWithItems(RQ_ASK_IF_PROPERTY, iri);
return await qService.getData(EDITINGURL, query, 'ASK')
.then(isPredicate => (isPredicate['boolean']));
}
private static async getDomainsFromStore(qService: QueryService, owlPropertyIri: string): Promise<string[]> {
const query = qService.parametrizeWhereClauseWithItems(RQ_GET_DOMAIN, owlPropertyIri);
return await qService.getData(EDITINGURL, query, 'SELECT')
.then(result => result['results']['bindings'].map(p => p['domain'].value))
}
private static async getRangesFromStore(qService: QueryService, owlPropertyIri: string): Promise<string[]> {
const query = qService.parametrizeWhereClauseWithItems(RQ_GET_RANGE, owlPropertyIri);
return await qService.getData(EDITINGURL, query, 'SELECT')
.then(result => result['results']['bindings'].map(p => p['range'].value))
}
private putRange(range: string) {
if (this._ranges.values())
this._ranges.add(range);
}
// accessors
public iri() {
return this._iri
}
public label() {
return this._label;
}
public ranges() {
return this._ranges
}
public domains() {
return this._domains
}
public displayable() {
return this._displayable
}
public mutable(): boolean {
return this._mutable
}
// returns whether a the range is a list or not
public takesListAsObject(): boolean {
return this._ranges.has('http://www.w3.org/1999/02/22-rdf-syntax-ns#List');
}
// returns whether a the range is a Literal
public takesLiteralAsObject(): boolean {
return this._ranges.has('http://www.w3.org/2001/XMLSchema#string');
}
// returns whether a the range is a Literal
public takesUrlAsObject(): boolean {
return this._ranges.has('http://www.w3.org/2001/XMLSchema#anyURI');
}
}
// setting parameters for a StatementHandler: The recipe on how to build it
// param: agentStatement: get agent statemreents from store
// param: agentListStatements ...
// whiteListedPredicates: only these properties will be loaded from store by the statementHandler
export class ChangeMgmntDef {
constructor(
public agentStatements = true,
public agentListStatements = true,
public patientStatements = false,
public patientListStatements = false,
public updateLists = true,
public displayedPredicates: string[] = [], // whiteList
public mutablePredicates: string[] = [], // whiteList
public hiddenPredicates: string[] = [],
public immutablePredicates: string[] = [],
public metaData = true, // whether metadata is written on change or not
onDelete?: OnDelete // what should be deleted/kept on deleteing a resource
) {
if (onDelete && onDelete !== undefined) { this.onDelete = onDelete } else {
this.onDelete = {keepAgentStatements: false, keepAgentLists: false, keepPatientStatements: false, keepPatientLists: false}
}
}
onDelete: OnDelete;
}
export interface OnDelete {
keepAgentStatements: boolean;
keepAgentLists: boolean;
keepPatientStatements: boolean;
keepPatientLists: boolean;
}

Event Timeline