import DataFactory from './factories/extended-term-factory'; import jsonldParser from './jsonldparser'; // @ts-ignore is this injected? import { Parser as N3jsParser } from 'n3'; // @@ Goal: remove this dependency import N3Parser from './n3parser'; import { parseRDFaDOM } from './rdfaparser'; import RDFParser from './rdfxmlparser'; import sparqlUpdateParser from './patch-parser'; import * as Util from './utils-js'; import { TurtleContentType, N3ContentType, RDFXMLContentType, XHTMLContentType, HTMLContentType, SPARQLUpdateContentType, SPARQLUpdateSingleMatchContentType, JSONLDContentType, NQuadsContentType, NQuadsAltContentType } from './types'; /** * Parse a string and put the result into the graph kb. * Normal method is sync. * Unfortunately jsdonld is currently written to need to be called async. * Hence the mess below with executeCallback. * @param str - The input string to parse * @param kb - The store to use * @param base - The base URI to use * @param contentType - The MIME content type string for the input - defaults to text/turtle * @param [callback] - The callback to call when the data has been loaded */ export default function parse(str, kb, base) { var contentType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'text/turtle'; var callback = arguments.length > 4 ? arguments[4] : undefined; contentType = contentType || TurtleContentType; contentType = contentType.split(';')[0]; try { if (contentType === N3ContentType || contentType === TurtleContentType) { var p = N3Parser(kb, kb, base, base, null, null, '', null); p.loadBuf(str); executeCallback(); } else if (contentType === RDFXMLContentType) { var parser = new RDFParser(kb); parser.parse(Util.parseXML(str), base, kb.sym(base)); executeCallback(); } else if (contentType === XHTMLContentType) { parseRDFaDOM(Util.parseXML(str, { contentType: XHTMLContentType }), kb, base); executeCallback(); } else if (contentType === HTMLContentType) { parseRDFaDOM(Util.parseXML(str, { contentType: HTMLContentType }), kb, base); executeCallback(); } else if (contentType === SPARQLUpdateContentType || contentType === SPARQLUpdateSingleMatchContentType) { // @@ we handle a subset sparqlUpdateParser(str, kb, base); executeCallback(); } else if (contentType === JSONLDContentType) { jsonldParser(str, kb, base, executeCallback); } else if (contentType === NQuadsContentType || contentType === NQuadsAltContentType) { var n3Parser = new N3jsParser({ factory: DataFactory }); nquadCallback(null, str); } else if (contentType === undefined) { throw new Error("contentType is undefined"); } else { throw new Error("Don't know how to parse " + contentType + ' yet'); } } catch (e) { // @ts-ignore executeErrorCallback(e); } parse.handled = { 'text/n3': true, 'text/turtle': true, 'application/rdf+xml': true, 'application/xhtml+xml': true, 'text/html': true, 'application/sparql-update': true, 'application/sparql-update-single-match': true, 'application/ld+json': true, 'application/nquads': true, 'application/n-quads': true }; function executeCallback() { if (callback) { callback(null, kb); } else { return; } } function executeErrorCallback(e) { if ( // TODO: Always true, what is the right behavior contentType !== JSONLDContentType || // @ts-ignore always true? contentType !== NQuadsContentType || // @ts-ignore always true? contentType !== NQuadsAltContentType) { if (callback) { callback(e, kb); } else { var e2 = new Error('' + e + ' while trying to parse <' + base + '> as ' + contentType); //@ts-ignore .cause is not a default error property e2.cause = e; throw e2; } } } /* function setJsonLdBase (doc, base) { if (doc instanceof Array) { return } if (!('@context' in doc)) { doc['@context'] = {} } doc['@context']['@base'] = base } */ function nquadCallback(err, nquads) { if (err) { callback(err, kb); } try { n3Parser.parse(nquads, tripleCallback); } catch (err) { callback(err, kb); } } function tripleCallback(err, triple) { if (triple) { kb.add(triple.subject, triple.predicate, triple.object, triple.graph); } else { callback(err, kb); } } }