-
-
Save ckristo/93630ad51b3937fe4246 to your computer and use it in GitHub Desktop.
rdf-ext fetching and parsing based on content type / content negotiation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Util functions for rdf-ext that allow to fetch and parse RDF data based on specifying its content type. | |
* @author Christoph Kindl <mail@ckristo.net> | |
*/ | |
/** | |
* Parses a given content while choosing the correct parser on the content type. | |
* @param {string} content - the content type of parse. | |
* @param {string} contentType - the content type of the content to determine the correct parser. | |
* @param {function} callback - the callback function that will be invoked with the parsed data (as RDF Interfaces Graph instance). | |
*/ | |
rdf.parse = function(content, contentType, callback) { | |
// - check arguments | |
if (!(typeof content === 'string')) { | |
throw new Error("1st argument needs to be a string"); | |
} | |
if (!(typeof contentType === 'string')) { | |
throw new Error("2nd argument needs to be a string"); | |
} | |
if (!(typeof callback === 'function')) { | |
throw new Error("3rd argument needs to be a function"); | |
} | |
// - parse the content with the correct parser for the content type | |
switch (contentType) { | |
case 'application/rdf+xml' : | |
rdf.parseRdfXml(content, callback); | |
break; | |
case 'text/turtle' : | |
case 'text/n3' : | |
rdf.parseTurtle(content, callback); | |
break; | |
case 'application/n-triples' : | |
rdf.parseNTriples(content, callback); | |
break; | |
case 'application/ld+json' : | |
rdf.parseJsonLd(content, callback); | |
break; | |
/* | |
case 'text/html' : | |
case 'application/xhtml+xml' : | |
// TODO try to parse with RDF-a / Microdata parser | |
break; | |
*/ | |
default : | |
callback(new Error("No parser available for parsing content type '"+contentType+"'")); | |
break; | |
} | |
}; | |
/** | |
* Helper function for fetching and parsing a remote document with RDF-ext means. | |
* @param {string} remoteURL - the remote URL of the document to fetch. | |
* @param {string} [contentType] - the content type of the document to determine the parser -- if omitted, content negotiation will be used. | |
* @param {Object} [options] - some options used for executing the HTTP request to get the document | |
* @param {string} [options.method=GET] - the HTTP method to use (e.g. 'GET', 'POST') -- defaults to 'GET' | |
* @param {string} [options.content=null] - the content to use for the HTTP request | |
* @param {Object} [options.headers={}] - the HTTP request headers to set | |
* @param {Function} callback - the callback function that will be invoked with an error indicator and the parsed data (as RDF Interfaces Graph instance). | |
*/ | |
rdf.fetchAndParse = function(remoteURL, contentType, options, callback) { | |
// - check arguments & determine correct argument configuration | |
if (!(typeof remoteURL === "string")) { | |
throw new Error("1st argument needs to be a string"); | |
} | |
if (arguments.length === 2) { | |
if (!(typeof contentType === "function")) { | |
throw new Error("2nd argument needs to be a function"); | |
} | |
callback = contentType; | |
contentType = undefined; | |
options = undefined; | |
} | |
else if (arguments.length === 3) { | |
if (!(typeof options === "function")) { | |
throw new Error("3rd argument needs to be a function"); | |
} | |
callback = options; | |
if (typeof contentType === "object") { | |
contentType = undefined; | |
options = contentType; | |
} | |
else if (typeof contentType === "string") { | |
options = undefined; | |
} | |
else { | |
throw new Error("2nd argument needs to be either a string or an object"); | |
} | |
} | |
else { | |
if (!(typeof callback === "function")) { | |
throw new Error("4th argument needs to be a function"); | |
} | |
if (!(typeof options === 'object')) { | |
throw new Error("3rd argument needs to be an object"); | |
} | |
if (!(typeof contentType === 'string')) { | |
throw new Error("2nd argument needs to be a string"); | |
} | |
} | |
// - set default parameters | |
var method, headers, content; | |
if (typeof options === 'undefined' | |
|| !"method" in options) { | |
method = 'GET'; | |
} | |
if (typeof options === 'undefined' | |
|| !"headers" in options) { | |
headers = {}; | |
} | |
if (typeof options === 'undefined' | |
|| !"content" in options) { | |
content = null; | |
} | |
// - fetch remote document | |
rdf.defaultRequest(method, remoteURL, headers, content, | |
function(statusCode, headers, content, error) { | |
if (error) { | |
callback(error); | |
} | |
if (statusCode >= 200 && statusCode < 300) { | |
callback(new Error("Response status code for fetched document != 2XX")); | |
} | |
if (typeof contentType === 'undefined') { | |
if (!("content-type" in headers)) { | |
callback(new Error("Response does not include 'Content-Type' header for content negotiation")); | |
} | |
else { | |
contentType = headers["content-type"]; | |
} | |
} | |
rdf.parse(content, contentType, function(graph) { callback(null, graph); }); | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment