UNPKG

sparnatural

Version:

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

286 lines 20.7 kB
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _BranchTranslator_instances, _BranchTranslator_branch, _BranchTranslator_fullQuery, _BranchTranslator_specProvider, _BranchTranslator_isVeryFirst, _BranchTranslator_isInOption, _BranchTranslator_valueBuilder, _BranchTranslator_startClassPtrn, _BranchTranslator_endClassPtrn, _BranchTranslator_intersectionPtrn, _BranchTranslator_whereChildPtrns, _BranchTranslator_valuePtrns, _BranchTranslator_executedAfterPtrns, _BranchTranslator_resultPtrns, _BranchTranslator_defaultVars, _BranchTranslator_buildChildrenPatterns, _BranchTranslator_buildValuePtrn, _BranchTranslator_buildSubjectClassPtrn, _BranchTranslator_buildObjectClassPtrn, _BranchTranslator_buildIntersectionPtrn, _BranchTranslator_buildFinalResultPtrn, _BranchTranslator_createOptionStatePtrn; import { DataFactory } from "rdf-data-factory"; import SparqlFactory from "../SparqlFactory"; import { ValueBuilderFactory } from "../ValueBuilder"; import TypedVariableTranslator from "./TypedVariableTranslator"; const factory = new DataFactory(); /** * Translates a Branch JSON structure into SparqlJs structure */ export default class BranchTranslator { constructor( // the branch to convert branch, // the full query (we need it to test if variables are selected) fullQuery, // the sparnatural spec specProvider, // true if this branch is the very first of the query (not a child of another, not a sibling of the first one) isVeryFirst, // true if this branch is under (recursively) of another that is itself in an option isInOption, settings) { _BranchTranslator_instances.add(this); // The JSON branch to convert to SPARQL _BranchTranslator_branch.set(this, void 0); // The full query from which the branch is extracted _BranchTranslator_fullQuery.set(this, void 0); _BranchTranslator_specProvider.set(this, void 0); // whether this branch is a children of another branch _BranchTranslator_isVeryFirst.set(this, void 0); _BranchTranslator_isInOption.set(this, void 0); // to translate widget values to SPARQL _BranchTranslator_valueBuilder.set(this, void 0); // intermediate patterns _BranchTranslator_startClassPtrn.set(this, []); _BranchTranslator_endClassPtrn.set(this, []); _BranchTranslator_intersectionPtrn.set(this, []); _BranchTranslator_whereChildPtrns.set(this, []); _BranchTranslator_valuePtrns.set(this, []); _BranchTranslator_executedAfterPtrns.set(this, []); // final result _BranchTranslator_resultPtrns.set(this, []); // default vars gathered from children _BranchTranslator_defaultVars.set(this, []); __classPrivateFieldSet(this, _BranchTranslator_branch, branch, "f"); __classPrivateFieldSet(this, _BranchTranslator_fullQuery, fullQuery, "f"); __classPrivateFieldSet(this, _BranchTranslator_specProvider, specProvider, "f"); __classPrivateFieldSet(this, _BranchTranslator_isVeryFirst, isVeryFirst, "f"); __classPrivateFieldSet(this, _BranchTranslator_isInOption, isInOption, "f"); this.settings = settings; /* console.log( `BranchTranslator: variable="${ this.#branch.line.o }", isSelected=${BranchTranslator.isVarSelected( fullQuery, this.#branch.line.o, )}, selectVars=`, fullQuery.variables.map( (v: any) => v.value || v.expression?.expression?.value, ), );*/ // create the object to convert widget values to SPARQL let endClassValue = __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.oType; // this is because the query generation may be triggered while the end class is not there yet if (endClassValue != null) { __classPrivateFieldSet(this, _BranchTranslator_valueBuilder, new ValueBuilderFactory().buildValueBuilder(__classPrivateFieldGet(this, _BranchTranslator_specProvider, "f") .getProperty(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.p) .getPropertyType(endClassValue)), "f"); // pass everything needed to generate SPARQL __classPrivateFieldGet(this, _BranchTranslator_valueBuilder, "f").init(__classPrivateFieldGet(this, _BranchTranslator_specProvider, "f"), { variable: __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.s, type: __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.sType }, { variable: null, type: __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.p }, { variable: __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o, type: __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.oType }, BranchTranslator.isVarSelected(fullQuery, __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o), __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.criterias.map((v) => v.criteria)); } } build() { __classPrivateFieldGet(this, _BranchTranslator_instances, "m", _BranchTranslator_buildChildrenPatterns).call(this); __classPrivateFieldGet(this, _BranchTranslator_instances, "m", _BranchTranslator_buildSubjectClassPtrn).call(this); __classPrivateFieldGet(this, _BranchTranslator_instances, "m", _BranchTranslator_buildIntersectionPtrn).call(this); __classPrivateFieldGet(this, _BranchTranslator_instances, "m", _BranchTranslator_buildObjectClassPtrn).call(this); __classPrivateFieldGet(this, _BranchTranslator_instances, "m", _BranchTranslator_buildValuePtrn).call(this); __classPrivateFieldGet(this, _BranchTranslator_instances, "m", _BranchTranslator_buildFinalResultPtrn).call(this); } /** * @param query The query to test * @param varName The variable to test the selection for * @returns true if the varName is selected in the query */ static isVarSelected(query, varName) { return (query.variables.filter((v) => { // if it is an aggregated variable... if (v.expression) { let vExpression = v; if (vExpression.expression.expression.value == varName) { return true; } } else { if (v.value == varName) { return true; } } return false; }).length == 1); } getResultPtrns() { return __classPrivateFieldGet(this, _BranchTranslator_resultPtrns, "f"); } getDefaultVars() { return __classPrivateFieldGet(this, _BranchTranslator_defaultVars, "f"); } getExecutedAfterPtrns() { return __classPrivateFieldGet(this, _BranchTranslator_executedAfterPtrns, "f"); } } _BranchTranslator_branch = new WeakMap(), _BranchTranslator_fullQuery = new WeakMap(), _BranchTranslator_specProvider = new WeakMap(), _BranchTranslator_isVeryFirst = new WeakMap(), _BranchTranslator_isInOption = new WeakMap(), _BranchTranslator_valueBuilder = new WeakMap(), _BranchTranslator_startClassPtrn = new WeakMap(), _BranchTranslator_endClassPtrn = new WeakMap(), _BranchTranslator_intersectionPtrn = new WeakMap(), _BranchTranslator_whereChildPtrns = new WeakMap(), _BranchTranslator_valuePtrns = new WeakMap(), _BranchTranslator_executedAfterPtrns = new WeakMap(), _BranchTranslator_resultPtrns = new WeakMap(), _BranchTranslator_defaultVars = new WeakMap(), _BranchTranslator_instances = new WeakSet(), _BranchTranslator_buildChildrenPatterns = function _BranchTranslator_buildChildrenPatterns() { __classPrivateFieldGet(this, _BranchTranslator_branch, "f").children?.forEach((branch) => { const builder = new BranchTranslator(branch, __classPrivateFieldGet(this, _BranchTranslator_fullQuery, "f"), __classPrivateFieldGet(this, _BranchTranslator_specProvider, "f"), // children are never the very first false, // children branch will be in option if this one is optional or not exists __classPrivateFieldGet(this, _BranchTranslator_branch, "f").optional || __classPrivateFieldGet(this, _BranchTranslator_branch, "f").notExists, this.settings); builder.build(); __classPrivateFieldGet(this, _BranchTranslator_whereChildPtrns, "f").push(...builder.getResultPtrns()); // gather default vars from children __classPrivateFieldGet(this, _BranchTranslator_defaultVars, "f").push(...builder.getDefaultVars()); // gather patterns to be executed after __classPrivateFieldGet(this, _BranchTranslator_executedAfterPtrns, "f").push(...builder.getExecutedAfterPtrns()); }); }, _BranchTranslator_buildValuePtrn = function _BranchTranslator_buildValuePtrn() { if (__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.criterias?.length > 0) { __classPrivateFieldSet(this, _BranchTranslator_valuePtrns, __classPrivateFieldGet(this, _BranchTranslator_valueBuilder, "f").build(), "f"); } }, _BranchTranslator_buildSubjectClassPtrn = function _BranchTranslator_buildSubjectClassPtrn() { let typeTranslator = new TypedVariableTranslator(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.s, __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.sType, // Note : on subject position, the only variable that can be selected is the very first one // Otherwise it can be selected in the object position, but not inside a WHERE clause // Anyway if it not the very first, all the startClassPtrn is ignored when building the final query BranchTranslator.isVarSelected(__classPrivateFieldGet(this, _BranchTranslator_fullQuery, "f"), __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.s) && __classPrivateFieldGet(this, _BranchTranslator_isVeryFirst, "f"), __classPrivateFieldGet(this, _BranchTranslator_valueBuilder, "f")?.isBlockingStart(), __classPrivateFieldGet(this, _BranchTranslator_specProvider, "f"), this.settings); typeTranslator.build(); __classPrivateFieldSet(this, _BranchTranslator_startClassPtrn, typeTranslator.resultPtrns, "f"); // if there was any default label patterns generated, gather the variable names of the default label if (typeTranslator.defaultLblPatterns.length > 0) { __classPrivateFieldGet(this, _BranchTranslator_defaultVars, "f").push(factory.variable(typeTranslator.defaultLabelVarName)); } }, _BranchTranslator_buildObjectClassPtrn = function _BranchTranslator_buildObjectClassPtrn() { let typeTranslator = new TypedVariableTranslator(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o, __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.oType, BranchTranslator.isVarSelected(__classPrivateFieldGet(this, _BranchTranslator_fullQuery, "f"), __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o), __classPrivateFieldGet(this, _BranchTranslator_valueBuilder, "f")?.isBlockingEnd(), __classPrivateFieldGet(this, _BranchTranslator_specProvider, "f"), this.settings); typeTranslator.build(); __classPrivateFieldSet(this, _BranchTranslator_endClassPtrn, typeTranslator.resultPtrns, "f"); /* console.log( `BranchTranslator.#buildObjectClassPtrn: var="${ this.#branch.line.o }", endClassPtrn=${ this.#endClassPtrn.length } patterns, defaultLblPatterns=${ typeTranslator.defaultLblPatterns.length }`, );*/ if (typeTranslator.defaultLblPatterns.length > 0) { __classPrivateFieldGet(this, _BranchTranslator_defaultVars, "f").push(factory.variable(typeTranslator.defaultLabelVarName)); } }, _BranchTranslator_buildIntersectionPtrn = function _BranchTranslator_buildIntersectionPtrn() { // Vérification des conditions de génération de l'intersection triple if (__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.s && __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o && !__classPrivateFieldGet(this, _BranchTranslator_valueBuilder, "f")?.isBlockingObjectProp()) { const specProperty = __classPrivateFieldGet(this, _BranchTranslator_specProvider, "f").getProperty(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.p); if (specProperty.getBeginDateProperty() && specProperty.getEndDateProperty()) { // Génération des triples pour les dates de début, de fin et exactes, si disponibles if (specProperty.getBeginDateProperty()) { __classPrivateFieldGet(this, _BranchTranslator_intersectionPtrn, "f").push(SparqlFactory.buildOptionalPattern([ SparqlFactory.buildBgpPattern([ SparqlFactory.buildIntersectionTriple(factory.variable(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.s), specProperty.getBeginDateProperty(), factory.variable(`${__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o}_begin`)), ]), ])); } if (specProperty.getEndDateProperty()) { __classPrivateFieldGet(this, _BranchTranslator_intersectionPtrn, "f").push(SparqlFactory.buildOptionalPattern([ SparqlFactory.buildBgpPattern([ SparqlFactory.buildIntersectionTriple(factory.variable(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.s), specProperty.getEndDateProperty(), factory.variable(`${__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o}_end`)), ]), ])); } if (specProperty.getExactDateProperty()) { __classPrivateFieldGet(this, _BranchTranslator_intersectionPtrn, "f").push(SparqlFactory.buildOptionalPattern([ SparqlFactory.buildBgpPattern([ SparqlFactory.buildIntersectionTriple(factory.variable(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.s), specProperty.getExactDateProperty(), factory.variable(`${__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o}_exact`)), ]), ])); } } else { // Génération du triple d'intersection normal si aucune propriété de date n'est spécifiée __classPrivateFieldGet(this, _BranchTranslator_intersectionPtrn, "f").push(SparqlFactory.buildBgpPattern([ SparqlFactory.buildIntersectionTriple(factory.variable(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.s), __classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.p, factory.variable(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o)), ])); } // Ajout du filtre de langue si la propriété est multilingue if (specProperty.isMultilingual()) { __classPrivateFieldGet(this, _BranchTranslator_intersectionPtrn, "f").push(SparqlFactory.buildFilterLangEquals(factory.variable(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o), factory.literal(this.settings.language))); } } }, _BranchTranslator_buildFinalResultPtrn = function _BranchTranslator_buildFinalResultPtrn() { // always store the startClassPattern in the final result pattern (no OPTIONAL, no NOT EXISTS, no SERVICE) // the subject type criteria is generated only for the first criteria, // not if it is inside a WHERE or an AND if (__classPrivateFieldGet(this, _BranchTranslator_isVeryFirst, "f")) __classPrivateFieldGet(this, _BranchTranslator_resultPtrns, "f").push(...__classPrivateFieldGet(this, _BranchTranslator_startClassPtrn, "f")); // concat all the patterns together, except the start pattern which is handled differntly let exceptStartPtrn = []; if (__classPrivateFieldGet(this, _BranchTranslator_intersectionPtrn, "f")) { exceptStartPtrn.push(...__classPrivateFieldGet(this, _BranchTranslator_intersectionPtrn, "f")); } /* console.log( `BranchTranslator.#buildFinalResultPtrn: var="${ this.#branch.line.o }", isLiteral=${this.#specProvider .getEntity(this.#branch.line.oType) .isLiteralEntity()},endClassPtrn=${this.#endClassPtrn.length}`, );*/ if (__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.o && !__classPrivateFieldGet(this, _BranchTranslator_specProvider, "f").getEntity(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.oType).isLiteralEntity()) { exceptStartPtrn.push(...__classPrivateFieldGet(this, _BranchTranslator_endClassPtrn, "f")); } else { //console.log(` ⚠️ endClassPtrn SKIPPED for "${this.#branch.line.o}"`); } exceptStartPtrn.push(...__classPrivateFieldGet(this, _BranchTranslator_valuePtrns, "f")); exceptStartPtrn.push(...__classPrivateFieldGet(this, _BranchTranslator_whereChildPtrns, "f")); // this will wrap everything except start inside the OPTIONAL or NOT EXISTS __classPrivateFieldGet(this, _BranchTranslator_instances, "m", _BranchTranslator_createOptionStatePtrn).call(this, exceptStartPtrn); }, _BranchTranslator_createOptionStatePtrn = function _BranchTranslator_createOptionStatePtrn(exceptStartPtrn) { // create a SERVICE clause if needed const sparqlService = __classPrivateFieldGet(this, _BranchTranslator_specProvider, "f") .getProperty(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.p) ?.getServiceEndpoint(); let servicePtrn = null; if (sparqlService) { const endpoint = factory.namedNode(sparqlService); // to be on the safe side : when rollback an endclass group, we may come here with only the start class group criteria // and nothing in this array if (exceptStartPtrn.length > 0) { servicePtrn = SparqlFactory.buildServicePattern(exceptStartPtrn, endpoint); } } let normalOrServicePatterns = servicePtrn ? [servicePtrn] : exceptStartPtrn; // produce the generated patterns, maybe wrapped in OPTIONAL or NOT EXISTS let finalResultPtrns = []; // if this branch is optional and is not inside an optional branch if (__classPrivateFieldGet(this, _BranchTranslator_branch, "f").optional && !__classPrivateFieldGet(this, _BranchTranslator_isInOption, "f")) { finalResultPtrns.push(SparqlFactory.buildOptionalPattern(normalOrServicePatterns)); } else if (__classPrivateFieldGet(this, _BranchTranslator_branch, "f").notExists && !__classPrivateFieldGet(this, _BranchTranslator_isInOption, "f")) { finalResultPtrns.push(SparqlFactory.buildNotExistsPattern(SparqlFactory.buildGroupPattern(normalOrServicePatterns))); } else { // nothing special, just retain the patterns in the final result pattern finalResultPtrns.push(...normalOrServicePatterns); } // then decide where to store the generated patterns : either in "normal" patterns // or in patterns that shall be executed after the rest of the query if (servicePtrn && __classPrivateFieldGet(this, _BranchTranslator_specProvider, "f") .getProperty(__classPrivateFieldGet(this, _BranchTranslator_branch, "f").line.p) ?.isLogicallyExecutedAfter()) { __classPrivateFieldGet(this, _BranchTranslator_executedAfterPtrns, "f").push(...finalResultPtrns); } else { __classPrivateFieldGet(this, _BranchTranslator_resultPtrns, "f").push(...finalResultPtrns); } }; //# sourceMappingURL=BranchTranslator.js.map