Skip to content

Instantly share code, notes, and snippets.

@ckristo
Last active August 29, 2015 14:27
Show Gist options
  • Save ckristo/93630ad51b3937fe4246 to your computer and use it in GitHub Desktop.
Save ckristo/93630ad51b3937fe4246 to your computer and use it in GitHub Desktop.
rdf-ext fetching and parsing based on content type / content negotiation
/**
* 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