UNPKG

sparnatural

Version:

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

124 lines 5.29 kB
import { UrlFetcher } from "./UrlFetcher"; export class SparqlHandlerFactory { constructor(lang, localCacheDataTtl, extraHeaders, customizedSparqlHandler, catalog) { this.lang = lang; this.localCacheDataTtl = localCacheDataTtl; this.extraHeaders = extraHeaders; this.customizedSparqlHandler = customizedSparqlHandler; this.catalog = catalog; } buildSparqlHandler(endpoints) { // if customized handler, use it if (this.customizedSparqlHandler) { return this.customizedSparqlHandler; } // if more than one endpoint if (endpoints.length > 1) { // extract selected endpoints from full catalog let subCatalog = this.catalog.extractSubCatalog(endpoints); return new MultipleEndpointSparqlHandler(new UrlFetcher(this.localCacheDataTtl, this.extraHeaders), subCatalog, this.lang); } else { // only one single endpoint let endpoint = endpoints[0]; return new EndpointSparqlHandler(new UrlFetcher(this.localCacheDataTtl, this.extraHeaders), endpoint); } } } /** * Executes a SPARQL query against a remote endpoint at a known URL */ export class EndpointSparqlHandler { constructor(urlFetcher, sparqlEndpointUrl) { this.urlFetcher = urlFetcher, this.sparqlEndpointUrl = sparqlEndpointUrl; } buildUrl(sparql) { var separator = this.sparqlEndpointUrl.indexOf("?") > 0 ? "&" : "?"; var url = this.sparqlEndpointUrl + separator + this.buildParameters(sparql); return url; } buildParameters(sparql) { return "query=" + encodeURIComponent(sparql) + "&format=json"; } executeSparqlPost(sparql, callback, errorCallback) { let url = this.sparqlEndpointUrl; const headers = new Headers(); headers.append("Content-Type", "application/x-www-form-urlencoded"); headers.append("Accept", "application/sparql-results+json,*/*;q=0.9"); return this.urlFetcher.fetchUrlWithParameters(url, { method: "POST", body: this.buildParameters(sparql), headers: headers }, callback, errorCallback); } executeSparqlGet(sparql, callback, errorCallback) { let url = this.buildUrl(sparql); this.urlFetcher.fetchUrl(url, callback, errorCallback); } executeSparql(sparql, callback, errorCallback) { if (sparql.length < 1024) this.executeSparqlGet(sparql, callback, errorCallback); else this.executeSparqlPost(sparql, callback, errorCallback); } } /** * Executes a SPARQL query against multiple endpoints * and returns the results merged in a single result set * with an extra column to express the source */ export class MultipleEndpointSparqlHandler { constructor(urlFetcher, catalog, lang) { // name of the extra column to add in the result set to express the endpoint this.extraColumnName = "group"; this.urlFetcher = urlFetcher, this.catalog = catalog; this.addExtraEndpointColumn = true; this.lang = lang; } executeSparql(sparql, callback, errorCallback) { const promises = []; for (const i in this.catalog.getServices()) { let fetcher = new EndpointSparqlHandler(this.urlFetcher, this.catalog.getServices()[i].getEndpointURL()); promises[promises.length] = new Promise((resolve, reject) => { fetcher.executeSparql(sparql, (data) => { resolve({ endpoint: this.catalog.getServices()[i], sparqlResult: data }); }, (error) => { reject(error); }); }); } // then wait for all Promises Promise.all(promises).then((values) => { let finalResult = {}; // copy the same head as first result, with an extra "endpoint" column finalResult.head = values[0].sparqlResult.head; finalResult.head.vars.push(this.extraColumnName); // prepare the "results" section finalResult.results = { // same distinct as first result distinct: values[0].sparqlResult.results.distinct, // never ordered ordered: false, // prepare bindings section bindings: [] }; // then for each SPARQL results of structure {endpoint : xx, sparqlJson: {...}} for (const v of values) { // add an extra "endpoint" column with the endpoint at the end of each binding finalResult.results.bindings.push( // remap each binding to add the endpoint column at the end // then unpack the array ...v.sparqlResult.results.bindings.map((b) => { if (this.addExtraEndpointColumn) { b[this.extraColumnName] = { type: "literal", value: v.endpoint.getTitle(this.lang) }; } return b; })); } // TODO : handle errors // and then call the callback callback(finalResult); }); } } //# sourceMappingURL=SparqlHandler.js.map