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