@comunica/actor-rdf-metadata-extract-sparql-service
Version:
Comunica RDF metadata extract actor that parses SPARQL Service Descriptions
137 lines • 8.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ActorRdfMetadataExtractSparqlService = void 0;
const bus_rdf_metadata_extract_1 = require("@comunica/bus-rdf-metadata-extract");
const core_1 = require("@comunica/core");
const relative_to_absolute_iri_1 = require("relative-to-absolute-iri");
/**
* Comunica RDF metadata extract actor for SPARQL Service Descriptions.
*/
class ActorRdfMetadataExtractSparqlService extends bus_rdf_metadata_extract_1.ActorRdfMetadataExtract {
static SD = 'http://www.w3.org/ns/sparql-service-description#';
static SPARQL = 'http://www.w3.org/ns/sparql#';
inferHttpsEndpoint;
constructor(args) {
super(args);
this.inferHttpsEndpoint = args.inferHttpsEndpoint;
}
async test(_action) {
return (0, core_1.passTestVoid)();
}
async run(action) {
return new Promise((resolve, reject) => {
// Forward errors
action.metadata.on('error', reject);
// Filter the subject URIs to consider, to avoid picking up unrelated entries
const acceptSubjectUris = new Set([action.url]);
const metadata = {};
const inputFormats = new Set();
const resultFormats = new Set();
const supportedLanguages = new Set();
const supportedVersions = new Set();
const extensionFunctions = new Set();
const propertyFeatures = new Set();
const sparql10Query = `${ActorRdfMetadataExtractSparqlService.SD}SPARQL10Query`;
const sparql11Query = `${ActorRdfMetadataExtractSparqlService.SD}SPARQL11Query`;
const sparqlQuery = `${ActorRdfMetadataExtractSparqlService.SD}SPARQLQuery`;
const sparqlVersion10 = `${ActorRdfMetadataExtractSparqlService.SPARQL}version-1.0`;
const sparqlVersion11 = `${ActorRdfMetadataExtractSparqlService.SPARQL}version-1.1`;
const sparqlVersion12 = `${ActorRdfMetadataExtractSparqlService.SPARQL}version-1.2`;
const sparqlVersion12Basic = `${ActorRdfMetadataExtractSparqlService.SPARQL}version-1.2-basic`;
action.metadata.on('data', (quad) => {
if (quad.predicate.value === 'http://rdfs.org/ns/void#subset' && quad.object.value === action.url) {
// When the requested URI is a subset of another dataset, as indicated by this predicate, then also
// consider that other dataset for the extraction of the following predicate values.
// This works an issue with Quad Pattern Fragments that has the sd:defaultGraph predicate associated
// with a subject value that is neither the data source URI nor the sd:defaultDataset.
acceptSubjectUris.add(quad.subject.value);
}
else if (quad.subject.value === metadata.defaultDataset ||
quad.subject.termType === 'BlankNode' ||
acceptSubjectUris.has(quad.subject.value)) {
switch (quad.predicate.value) {
case `${ActorRdfMetadataExtractSparqlService.SD}endpoint`:
// The VoID specification defines this as IRI, but does not specify whether or not it can be a literal.
// When the IRI is a literal, it can be relative, and needs to be resolved to absolute value.
metadata.sparqlService = quad.object.termType === 'Literal' ?
(0, relative_to_absolute_iri_1.resolve)(quad.object.value, action.url) :
quad.object.value;
// Also fix a common mistake in SPARQL endpoint setups where HTTPS SD's refer to a non-existing HTTP API.
if (this.inferHttpsEndpoint && action.url.startsWith('https') && !quad.object.value.startsWith('https')) {
metadata.sparqlService = metadata.sparqlService.replace(/^http:/u, 'https:');
}
break;
case `${ActorRdfMetadataExtractSparqlService.SD}defaultDataset`:
metadata.defaultDataset = quad.object.value;
break;
case `${ActorRdfMetadataExtractSparqlService.SD}defaultGraph`:
metadata.defaultGraph = quad.object.value;
break;
case `${ActorRdfMetadataExtractSparqlService.SD}inputFormat`:
inputFormats.add(quad.object.value);
break;
case `${ActorRdfMetadataExtractSparqlService.SD}resultFormat`:
resultFormats.add(quad.object.value);
break;
case `${ActorRdfMetadataExtractSparqlService.SD}supportedLanguage`:
supportedLanguages.add(quad.object.value);
switch (quad.object.value) {
case sparql10Query:
supportedLanguages.add(sparqlQuery);
supportedVersions.add(sparqlVersion10);
break;
case sparql11Query:
supportedLanguages.add(sparqlQuery);
supportedVersions.add(sparqlVersion11);
break;
}
break;
case `${ActorRdfMetadataExtractSparqlService.SD}supportedVersion`:
supportedVersions.add(quad.object.value);
// TODO: change in next major: stop emitting sd:SPARQL10Query/sd:SPARQL11Query in supportedLanguages.
switch (quad.object.value) {
case sparqlVersion10:
supportedLanguages.add(sparql10Query);
break;
case sparqlVersion11:
case sparqlVersion12:
case sparqlVersion12Basic:
// Legacy alias for compatibility with existing consumers expecting SPARQL11Query.
supportedLanguages.add(sparql11Query);
break;
}
break;
case `${ActorRdfMetadataExtractSparqlService.SD}propertyFeature`:
propertyFeatures.add(quad.object.value);
break;
case `${ActorRdfMetadataExtractSparqlService.SD}feature`:
if (quad.object.value === `${ActorRdfMetadataExtractSparqlService.SD}UnionDefaultGraph`) {
metadata.unionDefaultGraph = true;
}
else if (quad.object.value === `${ActorRdfMetadataExtractSparqlService.SD}BasicFederatedQuery`) {
metadata.basicFederatedQuery = true;
}
break;
case `${ActorRdfMetadataExtractSparqlService.SD}extensionFunction`:
extensionFunctions.add(quad.object.value);
break;
}
}
});
// Only return the metadata if an endpoint IRI was discovered
action.metadata.on('end', () => {
resolve({ metadata: {
...metadata,
...inputFormats.size > 0 ? { inputFormats: [...inputFormats.values()] } : {},
...resultFormats.size > 0 ? { resultFormats: [...resultFormats.values()] } : {},
...supportedLanguages.size > 0 ? { supportedLanguages: [...supportedLanguages.values()] } : {},
...supportedVersions.size > 0 ? { supportedVersions: [...supportedVersions.values()] } : {},
...extensionFunctions.size > 0 ? { extensionFunctions: [...extensionFunctions.values()] } : {},
...propertyFeatures.size > 0 ? { propertyFeatures: [...propertyFeatures.values()] } : {},
} });
});
});
}
}
exports.ActorRdfMetadataExtractSparqlService = ActorRdfMetadataExtractSparqlService;
//# sourceMappingURL=ActorRdfMetadataExtractSparqlService.js.map