UNPKG

rdf2hk

Version:

This library converts RDF to Hyperknowledge Description

1,579 lines (1,351 loc) 34.5 kB
/* * copyright: IBM Confidential * copyright: OCO Source Materials * copyright: © IBM Corp. All Rights Reserved * date: 2020 * * IBM Certificate of Originality */ "use strict"; const Utils = require("./utils"); const Constants = require("./constants"); const HKUris = require("./hk"); const HKSerializer = require("./hkserializer"); const HKLib = require("hklib"); const HKTypes = HKLib.Types; const { HIERARCHY } = HKLib.ConnectorClass; const SparqlBuilder = require("./sparqlbuilder"); const ANY = "*"; const ENTITY_ANCHORS = ` ?s ${HKUris.HAS_ANCHOR_URI} ?a . GRAPH ?g {?a ?b ?c} `; const REFERENCES_FILTERS = ` ?g = ?g1 || !bound(?g1) `; const DEFAULT_GRAPH_PATTERN = `GRAPH ?g { ?s ?p ?o } .`; const FILTER_HK = `FILTER ( ?p != ${HKUris.ISA_URI} && ?p != ${HKUris.USES_CONNECTOR_URI} && ?p != ${HKUris.CLASSNAME_URI} && ?p != ${HKUris.REFERENCES_URI} && ?p != ${HKUris.REFERENCED_BY_URI} && ?p != ${HKUris.HAS_PARENT_URI} && !STRSTARTS(STR(?p), "hkrole") && ( isIRI(?o) || isBlank(?o) || datatype(?o) != ${HKUris.DATA_LIST_URI}))` const HKTypeUriMap = {}; HKTypeUriMap[HKTypes.NODE] = HKUris.NODE_URI; HKTypeUriMap[HKTypes.VIRTUAL_NODE] = HKUris.VIRTUAL_NODE_URI; HKTypeUriMap[HKTypes.CONNECTOR] = HKUris.CONNECTOR_URI; HKTypeUriMap[HKTypes.LINK] = HKUris.LINK_URI; HKTypeUriMap[HKTypes.CONTEXT] = HKUris.CONTEXT_URI; HKTypeUriMap[HKTypes.VIRTUAL_CONTEXT] = HKUris.VIRTUAL_CONTEXT_URI; HKTypeUriMap[HKTypes.REFERENCE] = HKUris.REF_URI; HKTypeUriMap[HKTypes.TRAIL] = HKUris.TRAIL_URI; function getAllEntitiesUncompressed () { let query= `SELECT ?s ?p ?o ?g where { { GRAPH ?g { ?s ?p ?o . } } . ?s ?hk ?x. values ?hk { ${HKUris.ISA_URI} ${HKUris.BOUND_COMPONENT_URI} } } `; // console.log(query); return query; } function getHKTypeUriMap() { return HKTypeUriMap; } function getAllEntities (sparqlType = "construct") { let builder = new SparqlBuilder(); if(sparqlType === "describe") { return "describe ?s ?o where {?s ?p ?o}" } builder.construct(); builder.where(() => { builder.closure(() => { builder.append("?s ?hk ?x ."); builder.addValues("?hk", [HKUris.ISA_URI, HKUris.USES_CONNECTOR_URI]); builder.append(DEFAULT_GRAPH_PATTERN); }); builder.appendUnion(); builder.closure(() => { // builder.append(DEFAULT_GRAPH_PATTERN); builder.addValues("?hk", [HKUris.ISA_URI, HKUris.USES_CONNECTOR_URI]); builder.append("?s ?hk ?x ."); builder.append(ENTITY_ANCHORS); }); builder.filter(REFERENCES_FILTERS); }); let sparql = builder.getQuery(); return sparql; } function getAllEntitiesLazy (sparqlType = "construct") { let builder = new SparqlBuilder(); builder[sparqlType](); builder.where(() => { builder.closure(() => { builder.append("?s ?hk ?x ."); builder.addValues("?hk", [HKUris.ISA_URI, HKUris.USES_CONNECTOR_URI]); }); }); let sparql = builder.getQuery(); return sparql; } function getEntities (ids) { if(!ids) { throw "Ids can not be null"; } let builder = new SparqlBuilder(); builder.construct(); builder.where(() => { builder.closure(() => { builder.addValues("?s", ids); builder.append("GRAPH ?g { ?s ?p ?o } ."); }) builder.appendUnion(); builder.closure(() => { builder.addValues("?s", ids); builder.append(ENTITY_ANCHORS); }); builder.filter(REFERENCES_FILTERS); }); let sparql = builder.getQuery(); return sparql; } function filterEntities (filters) { if(!filters) { throw "Filters can not be null"; } let builder = new SparqlBuilder(); builder.construct(" GRAPH ?g { ?s ?p ?o } . GRAPH ?g { ?a ?b ?c } . GRAPH ?g1 {?a1 ?b1 ?c1} "); builder.where(() => { for(let i = 0; i < filters.length; i++) { let andFilters = filters[i]; let hasNode = _checkIfHasNodeInConstraint(andFilters); if(i > 0) { builder.appendUnion(); } builder.closure(() => { builder.closure(() => { appendUnionFilters(builder, andFilters); builder.append(" GRAPH ?g {?s ?p ?o} ."); }); if(hasNode) { builder.appendUnion(); builder.closure(() => { appendUnionFilters(builder, andFilters); builder.append(`?s ${HKUris.HAS_ANCHOR_URI} ?a . GRAPH ?g {?a ?b ?c}`, true); }); builder.appendUnion(); builder.closure(() => { appendUnionFilters(builder, andFilters); }); } }) } }); let query = builder.getQuery(); return query; } function filterEntitiesLazy (filters, sparqlType = "construct") { if(!filters) { throw "Filters can not be null"; } let builder = new SparqlBuilder(); switch(sparqlType) { case "describe": builder.describe(); break; default : builder.construct("GRAPH ?g { ?s ?hk ?x }"); break; } builder.where(() => { for(let i = 0; i < filters.length; i++) { let andFilters = filters[i]; if(i > 0) { builder.appendUnion(); } builder.closure(() => { builder.closure(() => { appendUnionFilters(builder, andFilters); builder.append("GRAPH ?g { ?s ?hk ?x . }"); builder.addValues("?hk", [HKUris.ISA_URI, HKUris.USES_CONNECTOR_URI]); }); }) } }); let query = builder.getQuery(); return query; } function filterEntitiesSelect (filters) { if(!filters) { throw "Filters can not be null"; } let builder = new SparqlBuilder(); builder.select(null, true); builder.where(() => { for(let i = 0; i < filters.length; i++) { let andFilters = filters[i]; let hasNode = _checkIfHasNodeInConstraint(andFilters); if(i > 0) { builder.appendUnion(); } builder.closure(() => { builder.closure(() => { appendUnionFilters(builder, andFilters); builder.append(" GRAPH ?g {?s ?p ?o} ."); }); if(hasNode) { builder.appendUnion(); builder.closure(() => { appendUnionFilters(builder, andFilters, "n"); builder.append(`?n ${HKUris.HAS_ANCHOR_URI} ?s .`); builder.append("GRAPH ?g { ?s ?p ?o } ."); }); let filteredAndFilters = andFilters.filter(filter => { if (filter.hasOwnProperty("id") || (filter.hasOwnProperty("parent") && !(filter.parent instanceof Object)) ) return false; return true; }) if (filteredAndFilters.length > 0) { builder.appendUnion(); builder.closure(() => { appendUnionFilters(builder, filteredAndFilters); }); } } }); } }); let query = builder.getQuery(); return query; } function fromUris (uris, className, level, full) { if(!uris) { throw "Uri can not be null"; } if(uris.constructor !== Array) { uris = [uris]; } let sparql = ""; if(level === undefined || level === null) { level = 1; } if(level === 0) { sparql = "describe ?s where { "; } else { sparql = "describe ?s ?o where { "; } if(className) { sparql += ` ?s ${RDFS_TYPE_URI} ${className} . `; } sparql += "{values ?s {"; for(let i = 0; i < uris.length; i++) { sparql += `${_convertToUri(uris[i])} `; } sparql += "}"; sparql += " . ?s ?p ?o }" ; if(full) { sparql += "union {values ?o {"; for(let i = 0; i < uris.length; i++) { sparql += `${_convertToUri(uris[i])} `; } sparql += "}"; sparql += " . ?s ?p ?o }" ; } sparql += "}"; return sparql; } function getEntitiesFromUris(ids) { let builder = new SparqlBuilder(); builder.select(null, true); builder.where(() => { builder.closure(() => { builder.addValues("?s", ids); builder.append("GRAPH ?g { ?s ?p ?o } ."); }) builder.appendUnion(); builder.closure(() => { builder.addValues("?n", ids); builder.append("?n <http://research.ibm.com/ontologies/graph#hasAnchor> ?s ."); builder.append("GRAPH ?g { ?s ?p ?o } ."); }); }); let sparql = builder.getQuery(); return sparql; } // This query update the delete and insert triples // to update entities properties. // There are some scenarios: // I. Update properties // II. Update parents // III. Update properties and parents // // function updateTriples (changedEntities, changedParents) { let builder = new SparqlBuilder(); let changedEntitiesKeys = Object.keys(changedEntities); let changedParentKeys = Object.keys(changedParents); // If there a no changes, just go away if(changedEntitiesKeys.length === 0 && changedParentKeys.length === 0) { return null; } if(changedEntitiesKeys.length > 0) { // Delete previous properties builder.delete(() => { // Delete old properties builder.append(`GRAPH ?g {?s ?p ?o} .`); builder.append(`GRAPH ?g {?a ?b ?c} .`); }); // Here we have to collect all properties that should be removed // and be replaced to the new ones builder.where(() => { let first = true; for(let e in changedEntities) { let entityUpdates = changedEntities[e]; let properties = entityUpdates.properties; let interfacesToRemove = entityUpdates.interfacesToRemove; let interfaceProperties = entityUpdates.interfacesPropertites; if(!first) { if (properties.length > 0 || interfacesToRemove.length > 0 || Object.keys(interfaceProperties).length > 0) { builder.appendUnion(); first = true; } else { console.log(`STRANGE ENTITY: ${JSON.stringify(entityUpdates)}`); } } // Remove properties to be updated if(properties.length > 0) { first = false; builder.closure(() => { builder.bindVar(_convertToUri(e), "?s"); builder.addValues("?p", properties); builder.append(`GRAPH ?g {?s ?p ?o}`); }); } // Remove interfaces to be deleted if(interfacesToRemove.length > 0) { if(!first) { builder.appendUnion(); } first = false; builder.closure(() => { builder.bindVar(_convertToUri(e), "?s"); builder.append(`GRAPH ?g {?s ?p ?o} .`); builder.append(`bind (?o as ?a)`); // Trick builder.append(`GRAPH ?g {?a ?b ?c} .`); builder.addValues("?x", interfacesToRemove, false); builder.append(`?a ${HKUris.ANCHOR_KEY_URI} ?x .`); builder.append(`?s ${HKUris.HAS_ANCHOR_URI} ?a .`); }); } // Remove interfaces properties to be updated if(Object.keys(interfaceProperties).length > 0) { for(let k in interfaceProperties) { if(!first) { builder.appendUnion(); } first = false; let properties = interfaceProperties[k]; builder.closure(() => { builder.bindVar(_convertToUri(e), "?s"); builder.append(`GRAPH ?g {?a ?b ?c} .`); builder.addValues("?b", properties); builder.bindVar(k, "?x"); builder.append(`?a ${HKUris.ANCHOR_KEY_URI} ?x .`); builder.append(`?s ${HKUris.HAS_ANCHOR_URI} ?a .`); }); } } } }); builder.append(";"); // Add new properties for(let e = 0; e < changedEntitiesKeys.length; e++) { let entityId = changedEntitiesKeys[e]; let entity = changedEntities[entityId]; let newTriples = entity.triples || []; if(newTriples.length == 0) continue; const hasChangedParent = changedParents.hasOwnProperty(entityId); // If the entity did not changed its parent // then add again getting its previous parent if(hasChangedParent) { // The triple are plenty, just add them builder.insertData(() => { for(let i = 0; i < newTriples.length; i++) { let t = newTriples[i]; if(t[2].includes('\n') || (t[2].indexOf("^^") > 0 && ((t[2].match(/"/g) || []).length - (t[2].match(/\\/g) || []).length) > 2)) { builder.append(`GRAPH ${t[3]} { ${t[0]} ${t[1]} ${JSON.stringify(t[2])} } . `); } else if(t[2].match(/"/g) !== null && t[2].match(/"/g).length > 2 && t[2].indexOf(`"^^<`) == t[2].indexOf(`"^^`) ) { const unescapedLiteralStrBegin = t[2].indexOf(`"`) + 1; const unescapedLiteralStrEnd = t[2].lastIndexOf(`"`); const unescapedLiteralStr = t[2].substring(unescapedLiteralStrBegin, unescapedLiteralStrEnd); const escapedLiteralStr = JSON.stringify(unescapedLiteralStr); const escapedLiteral = t[2].replace(`"${unescapedLiteralStr}"`, escapedLiteralStr); builder.append(`GRAPH ${t[3]} { ${t[0]} ${t[1]} ${escapedLiteral} } . `); } else { builder.append(`GRAPH ${t[3]} { ${t[0]} ${t[1]} ${t[2]} } . `); } } }); } else { builder.insert(() => { for(let i = 0; i < newTriples.length; i++) { let t = newTriples[i]; if(t[2].includes('\n') || (t[2].indexOf("^^") > 0 && ((t[2].match(/"/g) || []).length - (t[2].match(/\\/g) || []).length) > 2)) { builder.append(`GRAPH ?g { ${t[0]} ${t[1]} ${JSON.stringify(t[2])} } . `); } else { builder.append(`GRAPH ?g { ${t[0]} ${t[1]} ${t[2]} } . `); } } }); builder.where(() => { builder.append(` bind(${_convertToUri(entityId)} as ?s) . `); builder.addValues("?p", [HKUris.USES_CONNECTOR_URI, HKUris.ISA_URI]); builder.append(`GRAPH ?g { ?s ?p ?o } . `); }); } builder.append(";"); } } // Move triples to new parent if(changedParentKeys.length > 0) { // Add all the previous entities to the new parent for(let i = 0; i < changedParentKeys.length; i++) { let id = changedParentKeys[i]; let entityUri = _convertToUri(id); let parentUri = _convertToUri(changedParents[id]); builder.delete(() => { // Delete old properties builder.append(`GRAPH ?g {?s ?p ?o} .`); builder.append(`GRAPH ?gOld { ?s ${HKUris.HAS_PARENT_URI} ?gOld. } `); }); builder.insert(() => { // Insert new properties // builder.append(`GRAPH ?g {?s ?p ?o} .`); builder.append(`GRAPH ${parentUri} { ?s ?p ?o . } `); builder.append(`GRAPH ${parentUri} { ?s ${HKUris.HAS_PARENT_URI} ${parentUri}. } `); }); builder.where(() => { builder.append(` bind(${entityUri} as ?s) . `); builder.addValues("?isa", [HKUris.ISA_URI, HKUris.USES_CONNECTOR_URI]); builder.append(` ?s ?isa ?x . `); builder.append(` GRAPH ?g { ?s ?p ?o } . `); builder.filter(` ?p != ${HKUris.HAS_PARENT_URI}`); builder.append(` OPTIONAL { GRAPH ?gOld { ?s ${HKUris.HAS_PARENT_URI} ?gOld } . }`); }); builder.append(";"); } } let query = builder.getQuery(); return query; } function removeEntities (ids) { if(!ids) { throw "Ids can not be null"; } let builder = new SparqlBuilder(); builder.delete("GRAPH ?g {?s ?p ?o} . GRAPH ?g {?a ?b ?c} . GRAPH ?g_ref {?s ?p ?o} . "); builder.where(() => { builder.closure(() => { builder.addValues("?s", ids) builder.append(ENTITY_ANCHORS); }); builder.appendUnion(); builder.closure(() => { builder.addValues("?o", ids); builder.append(DEFAULT_GRAPH_PATTERN); }); builder.appendUnion(); builder.closure(() => { builder.addValues("?s", ids) builder.append(DEFAULT_GRAPH_PATTERN); // builder.optional(ENTITY_ANCHORS); }); builder.appendUnion(); // removing triples where entities are predicates builder.closure(() => { builder.addValues("?l", ids); builder.append( `graph ?g { ?l ?subject_role ?ref_s ; ?object_role ?ref_o ; ${HKUris.USES_CONNECTOR_URI} ?p . OPTIONAL { BIND(${HKUris.REFERENCES_URI} as ?ref_predicate_s) ?ref_s ${HKUris.REFERENCES_URI}? ?s . } OPTIONAL { BIND(${HKUris.REFERENCED_BY_URI} as ?ref_predicate_s) ?s ${HKUris.REFERENCED_BY_URI}? ?ref_s . } OPTIONAL{ BIND(${HKUris.REFERENCES_URI} as ?ref_predicate_o) ?ref_o ${HKUris.REFERENCES_URI}? ?o . } OPTIONAL { BIND(${HKUris.REFERENCED_BY_URI} as ?ref_predicate_o) ?o ${HKUris.REFERENCED_BY_URI}? ?ref_o . } FILTER (bound(?ref_predicate_s) && bound(?ref_predicate_o)) } ?p ?subject_role "s"; ?object_role "o" . ${DEFAULT_GRAPH_PATTERN} ` ); }); }); return builder.getQuery(); } function removeAllEntities () { return "CLEAR ALL"; } function getContextHierarchy (uris, targetTypes, sparqlType = "construct") { if(!uris) { throw "Uri can not be null"; } if(uris.constructor !== Array) { uris = [uris]; } const targetTypesUris = []; if(Array.isArray(targetTypes)) { targetTypes.forEach((type) => { if(HKTypeUriMap.hasOwnProperty(type)) { targetTypesUris.push(HKTypeUriMap[type]) } }); } let builder = new SparqlBuilder(); switch(sparqlType) { case "describe": builder.describe(["?s"]); break; default : builder.construct(() => { builder.append("GRAPH ?g {?s ?p ?o}"); }); break; } builder.where( () => { builder.addValues("?parent", uris); builder.append(` ?s ${HKUris.HAS_PARENT_URI}* ?parent .`); builder.append(" GRAPH ?g {?s ?p ?o} ."); if(targetTypesUris) { builder.append(` ?s ${HKUris.ISA_URI} ?type`); builder.addValues("?type", targetTypesUris); } }); let query = builder.getQuery(); return query; } function getLinks (ids, sparqlType = "construct") { if(!ids) { throw "Uri can not be null"; } let builder = new SparqlBuilder(); builder[sparqlType](); builder.where(() => { builder.closure(() => { builder.closure(() => { builder.addValues("?s", ids); // Get the connector itself builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?x`); builder.append(`GRAPH ?g {?s ?p ?o}`); }); builder.appendUnion(); builder.closure(() => { builder.addValues("?x", ids); // Link with a bound entity builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?connector . ?s ?role ?x `); builder.append(`GRAPH ?g {?s ?p ?o}`); }); builder.appendUnion(); builder.closure(() => { builder.addValues("?x", ids); // Link with a bound entity builder.append(`?s ${HKUris.ISA_URI} ${HKUris.CONNECTOR_URI} .`); builder.append(`?link ?role ?x .`); builder.append(`GRAPH ?g {?s ?p ?o}.`); builder.append(`?link ${HKUris.USES_CONNECTOR_URI} ?s .`); }); // builder.appendUnion(); // builder.closure(() => // { // builder.addValues("?x", ids); // // Connector from a bound entity // // builder.append(`?s ${HKUris.ISA_URI} ${HKUris.CONNECTOR_URI} .`); // // builder.append(`?link ${HKUris.USES_CONNECTOR_URI} ?s . `); // builder.append(`?link ?role ?x `); // }) }); builder.append(DEFAULT_GRAPH_PATTERN); }); let sparql = builder.getQuery(); return sparql; } function deleteTriples (bgp) { let builder = new SparqlBuilder(); builder.delete(() => { builder.append("GRAPH ?g {?s ?p ?o}"); }); builder.where(() => { builder.closure(() => { if(bgp[0] !== null) { builder.bindVar(bgp[0], "s"); } if(bgp[1] !== null) { builder.bindVar(bgp[1], "p"); } if(bgp[2] !== null) { builder.bindVar(bgp[2], "o"); } if(bgp[3] !== null) { builder.bindVar(bgp[3], "g"); } builder.append("GRAPH ?g {?s ?p ?o}"); }); if(Utils.isUriOrBlankNode(bgp[0]) && !Utils.isUriOrBlankNode(bgp[2])) { builder.appendUnion(); builder.closure( () => { let referencedNodeURI = bgp[0]; if(Utils.isBlankNode(referencedNodeURI)) { builder.append(`${referencedNodeURI} ${HKUris.REFERENCED_BY_URI} ?s . `); } else { builder.append(`?s ${HKUris.REFERENCES_URI} ${referencedNodeURI} . `); } if(bgp[1] !== null) { builder.bindVar(bgp[1], "p"); } if(bgp[2] !== null) { builder.bindVar(bgp[2], "o"); } if(bgp[3] !== null) { builder.bindVar(bgp[3], "g"); } builder.append("GRAPH ?g {?s ?p ?o}"); }); } }); // console.log(builder.query); return builder.query; } function getRdf(bgp, sparqlType = "construct") { let builder = new SparqlBuilder(); switch(sparqlType) { case "select": builder.select(); break; default: builder.construct(() => { builder.append("GRAPH ?g {?s ?p ?o}"); }); } builder.where(() => { if(bgp[0] !== null) { builder.bindVar(bgp[0], "s"); } if(bgp[1] !== null) { builder.bindVar(bgp[1], "p"); } if(bgp[2] !== null) { builder.bindVar(bgp[2], "o"); } if(bgp[3] !== null) { builder.bindVar(bgp[3], "g"); } builder.append("GRAPH ?g {?s ?p ?o} ."); builder.append( FILTER_HK); }); let out = builder.query; return out; } function _filterForBinds(builder, binds, connector = null, parent = undefined) { function filterForRole(includeReferences = false) { if (!connector) { builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?conn . `); } for (let role in binds) { if (Array.isArray(binds[role])) { builder.filterIn("r", binds[role], true); if (role === ANY) { builder.append(`?s ?anyRole ?r . `); } else { let uri = HKSerializer.compressRoleInUri(role); // builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?conn . `); let referencedNodeURI = _convertToUri(binds[role]); if(includeReferences) { builder.closure(() => { if(Utils.isBlankNode(referencedNodeURI)) { builder.append(`${referencedNodeURI} ${uri}/${HKUris.REFERENCED_BY_URI}? ?s . `); } else { builder.append(`?s ${uri}/${HKUris.REFERENCES_URI}? ${referencedNodeURI} . `); } }); builder.appendUnion(); builder.closure(() => { builder.append(` OPTIONAL { BIND (${HKUris.REFERENCES_URI} as ?ref_predicate) ?s ${uri}/${HKUris.REFERENCES_URI}? ?referredNode . }`); builder.append(` OPTIONAL { BIND (${HKUris.REFERENCED_BY_URI} as ?ref_predicate) ?referredNode ${uri}/${HKUris.REFERENCED_BY_URI}? ?s . }`); builder.append(`FILTER (bound(?ref_predicate))`); builder.append(`?referredNode ?isa ${referencedNodeURI} .`); builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?connector2 .`); builder.append(`?connector2 ${HKUris.CLASSNAME_URI} "${HIERARCHY}" .`); }); builder.append(`?s ?anyRole ?node .`); builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?connector .`); builder.append(`?connector ${HKUris.CLASSNAME_URI} "${HIERARCHY}" .`); } else { builder.append(`?s ${uri} ?r . `); } } } else { if (role === ANY) { // builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?conn . `); builder.append(`?s ?anyRole ${_convertToUri(binds[role])} . `); } else { let uri = HKSerializer.compressRoleInUri(role); // builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?conn . `); let referencedNodeURI = _convertToUri(binds[role]); if(includeReferences) { builder.closure(() => { if(Utils.isBlankNode(referencedNodeURI)) { builder.append(`${referencedNodeURI} ${uri}/${HKUris.REFERENCED_BY_URI}? ?s . `); } else { builder.append(`?s ${uri}/${HKUris.REFERENCES_URI}? ${referencedNodeURI} . `); } }); builder.appendUnion(); builder.closure(() => { builder.append(` OPTIONAL { BIND (${HKUris.REFERENCES_URI} as ?ref_predicate) ?s ${uri}/${HKUris.REFERENCES_URI}? ?referredNode . }`); builder.append(`OPTIONAL { BIND (${HKUris.REFERENCED_BY_URI} as ?ref_predicate) ?referredNode ${uri}/${HKUris.REFERENCED_BY_URI}? ?s . }`); builder.append(`FILTER (bound(?ref_predicate))`); builder.append(`?referredNode ?isa ${referencedNodeURI} .`); builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?connector2 .`); builder.append(`?connector2 ${HKUris.CLASSNAME_URI} "${HIERARCHY}" .`); }); builder.append(`?s ?anyRole ?node .`); builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?connector .`); builder.append(`?connector ${HKUris.CLASSNAME_URI} "${HIERARCHY}" .`); } else { builder.append(`?s ${uri} ${referencedNodeURI} . `); } } } } } function filterForConnector(useGraph = true) { if (connector) { if(useGraph) { builder.append(`GRAPH ?g {?s ?p ?o} .`); } else { builder.append(`?s ?p ?o .`); } // builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ${_convertToUri(connector)} . `) // builder.bindVar(_convertToUri(connector), "conn"); if (Array.isArray(connector)) { builder.addValues("c", connector, true); builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?c `); } else { // builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ${_convertToUri(constraint[k])} .`, true); builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ${_convertToUri(connector)} . `); } } } builder.closure(() => { if(parent === undefined) { filterForRole(); filterForConnector(); } else { builder.closure(() => { filterForRole(); filterForConnector(); if(!connector) { builder.append(`GRAPH ?g {?s ?p ?o} .`); } }); builder.appendUnion(); builder.closure(() => { filterForRole(true); filterForConnector(false); builder.append(`GRAPH ?g { OPTIONAL { BIND (${HKUris.REFERENCES_URI} as ?ref_predicate) ?ref ${HKUris.REFERENCES_URI} ?node . } OPTIONAL { BIND (${HKUris.REFERENCED_BY_URI} as ?ref_predicate) ?node ${HKUris.REFERENCED_BY_URI} ?ref . } FILTER (bound(?ref_predicate)) } .`); }); _filterForParent(builder, parent); } }); } function appendUnionFilters(builder, andFilters, idVar = "s") { for(let j = 0; j < andFilters.length; j++) { let constraint = andFilters[j]; const constraintKeys = Object.keys(constraint).sort(); if(constraintKeys.length >= 2) { if(constraint.binds && constraint.connector) { _filterForBinds(builder, constraint.binds, constraint.connector, constraint.parent); continue; } } for(let k of constraintKeys) { let constraintValue = constraint[k]; switch(k) { case "parent": { _filterForParent(builder, constraintValue); break; } case "ref": { let referencedNodeURI = _convertToUri(constraintValue); if(Array.isArray(constraintValue)) { builder.addValues("r", constraintValue, true); builder.append(` { ?s ${HKUris.REFERENCES_URI} ?r . }`); builder.appendUnion(); builder.append(` { ?r ${HKUris.REFERENCED_BY_URI} ?s. }`); } else if(constraint.parent) { builder.closure(() => { builder.append('GRAPH ?g'); builder.closure(() => { if(Utils.isBlankNode(referencedNodeURI)) { builder.append(`${referencedNodeURI} ${HKUris.REFERENCED_BY_URI} ?s . `); } else { builder.append(`?s ${HKUris.REFERENCES_URI} ${referencedNodeURI} . `); } builder.append(`?s ?p ?o .`); }); }); builder.appendUnion(); builder.closure(() => { builder.append('GRAPH ?g'); builder.closure(() => { builder.append(` { BIND(${HKUris.REFERENCES_URI} as ?ref_predicate) ?s ${HKUris.REFERENCES_URI} ?referedNode . }`); builder.append(`UNION { BIND(${HKUris.REFERENCED_BY_URI} as ?ref_predicate) ?referedNode ${HKUris.REFERENCED_BY_URI} ?s . }`); }); builder.append(`?referedNode ?isa ${_convertToUri(referencedNodeURI)} .`); builder.append(`?isa ${HKUris.CLASSNAME_URI} "${HIERARCHY}" .`); }); builder.appendUnion(); builder.closure(() => { builder.append(` OPTIONAL { BIND(${HKUris.REFERENCES_URI} as ?ref_predicate) ?ref ${HKUris.REFERENCES_URI} ?referedNode . }`); builder.append(`OPTIONAL { BIND(${HKUris.REFERENCED_BY_URI} as ?ref_predicate) ?referedNode ${HKUris.REFERENCED_BY_URI} ?ref . }`); builder.append(`FILTER (bound(?ref_predicate))`); builder.append('GRAPH ?gref'); builder.closure(() => { builder.append(`?referedNode ?isa ${_convertToUri(constraint[k])} .`); if(Utils.isBlankNode(referencedNodeURI)) { builder.append(`${referencedNodeURI} ${HKUris.REFERENCED_BY_URI} ?s . `); } else { builder.append(`?s ${HKUris.REFERENCES_URI} ${referencedNodeURI} . `); } builder.append(`?s ?p ?o .`); }); builder.append(`?isa ${HKUris.CLASSNAME_URI} "${HIERARCHY}" .`); }); } else { if(Utils.isBlankNode(referencedNodeURI)) { builder.append(`${referencedNodeURI} ${HKUris.REFERENCED_BY_URI} ?s . `); } else { builder.append(`?s ${HKUris.REFERENCES_URI} ${referencedNodeURI} . `); } builder.append(`GRAPH ?g {?s ?p ?o} .`); } break; } case "type": { if(Array.isArray(constraintValue)) { builder.append(_filterForTypeArray(constraintValue, idVar), true); } else { builder.append(_filterForType(constraintValue, idVar), true); } break; } case "id": { if(Array.isArray(constraintValue)) { builder.addValues(idVar, constraintValue, true); } else { builder.bindVar(_convertToUri(constraintValue), idVar, true); } break; } case "connector": { if(Array.isArray(constraintValue)) { builder.addValues("c", constraintValue, true); builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ?c `); } else { builder.append(`?s ${HKUris.USES_CONNECTOR_URI} ${_convertToUri(constraint[k])} .`, true); } break; } case "className": { builder.append(`?s ${HKUris.CLASSNAME_URI} "${constraint[k]}" .`, true); break; } case "properties": { builder.append(_filterForProperties(constraint[k]), true); break; } case "binds": { _filterForBinds(builder, constraintValue); break; } default: { throw `Invalid filter: ${k}`; } } } } } function _checkIfHasNodeInConstraint(andFilters) { for(let i = 0; i < andFilters.length; i++) { let item = andFilters[i]; for(let k in item) { if(k === "id" || k === "properties" || k === "parent") { return true; } else if(k === "type") { if(item[k] === "node" || item[k] === "context" || item[k] === "ref") { return true; } } } } return false; } function _filterForParent(builder, parent) { if (Array.isArray(parent)) { builder.addValues("g", parent, true); } else if (parent instanceof Object) { const parentId = parent.parentId; const includeNestedContexts = parent.includeNestedContexts; if (includeNestedContexts) { let parentIds = []; if (Array.isArray(parentId)) { parentIds = parentId; } else { parentIds = [parentId]; } parentIds.forEach((g_root, index) => { builder.closure(() => { builder.append(`?g ${HKUris.HAS_PARENT_URI}* ${_convertToUri(g_root)} .`); }); if(index + 1 < parentIds.length) { builder.appendUnion(); } }) } else { builder.bindVar(_convertToUri(parentId), "g", true); } } else { builder.bindVar(_convertToUri(parent), "g", true); } } function _filterForTypeArray(typeArray, idVar="s") { let filter = ''; for(let i = 0; i < typeArray.length; i++) { const typeFilter = _filterForType(typeArray[i], idVar); if(typeFilter !== null) { if(filter !== '') { filter += ' UNION '; } filter += ` { ${typeFilter} } `; } } return filter; } function _filterForType(type, idVar = "s") { switch(type) { case HKTypes.NODE: { return `?${idVar} ${HKUris.ISA_URI} ${HKUris.NODE_URI} . `; } case HKTypes.VIRTUAL_NODE: { return `?${idVar} ${HKUris.ISA_URI} ${HKUris.VIRTUAL_NODE_URI} . `; } case HKTypes.CONNECTOR: { return `?s ${HKUris.ISA_URI} ${HKUris.CONNECTOR_URI} . `; } case HKTypes.CONTEXT: { return `?${idVar} ${HKUris.ISA_URI} ${HKUris.CONTEXT_URI} . `; } case HKTypes.VIRTUAL_CONTEXT: { return `?${idVar} ${HKUris.ISA_URI} ${HKUris.VIRTUAL_CONTEXT_URI} . `; } case HKTypes.TRAIL: { return `?s ${HKUris.ISA_URI} ${HKUris.TRAIL_URI} . `; } case HKTypes.REFERENCE: { return `GRAPH ?g { ?s ${HKUris.ISA_URI} ${HKUris.REF_URI}. ?s ?p ?o . } `; } case HKTypes.LINK: { return `?s ${HKUris.USES_CONNECTOR_URI} ?y . `; } default: { return `?s ${HKUris.ISA_URI} ${_convertToUri(type)} . `; } } } function _filterForProperties(properties) { let out = ""; for(let k in properties) { let v = properties[k]; let valueType = typeof v; const property = k == ANY ? '?filteredProperty' : _convertToUri(k); if(v == ANY) { out += `?s ${property} ?${Utils.getLabelFromUri(k)}_label . `; } else if(Array.isArray(v)) { for(let i = 0; i < v.length; i++) { out += `{ ?s ${property} "${v[i]}" . } `; if(i + 1 < v.length) { out += ' UNION '; } } } else if(valueType === "object") { // Assume $exist = true out += `?s ${property} ?x . `; } else if(valueType === "number" || valueType === "boolean") { out += `?s ${property} ${v} . `; } else { out += `?s ${property} "${v}" . `; } } return out; } function _convertToUri(id) { if(!id) { return `<${Constants.HK_NULL}>`; } else if(Utils.isUri(id)) { return id; } else if(Utils.isBlankNode(id)) { return Utils.createBlankNodeUri(id.substr(2)); } else { return `<${Utils.generateResourceFromId(id)}>`; } } exports.FILTER_HK = FILTER_HK; exports.deleteTriples = deleteTriples; exports.getContextHierarchy = getContextHierarchy; exports.getAllEntities = getAllEntities; exports.getAllEntitiesLazy = getAllEntitiesLazy; exports.getRdf = getRdf; exports.getAllEntitiesUncompressed = getAllEntitiesUncompressed; exports.getEntities = getEntities; exports.getHKTypeUriMap = getHKTypeUriMap; exports.removeEntities = removeEntities; exports.removeAllEntities = removeAllEntities; exports.filterEntities = filterEntities; exports.filterEntitiesSelect = filterEntitiesSelect; exports.filterEntitiesLazy = filterEntitiesLazy; exports.getLinks = getLinks; exports.updateTriples = updateTriples; exports.fromUris = fromUris; exports.getEntitiesFromUris = getEntitiesFromUris;