/**
* Enum of all DataSource types
*
* @author Fabio Pavesi (fabio@adamassoft.it)
* @readonly
* @enum
*/
var DataSourceType = {
// Codelist based on a Virtuoso SPARQL Query
virtuosoCodelist: "virtuosoCodelist",
// Issues a generic SPARQL Query
sparql: "sparql"
};
/**
* DataSource class
*
* @class
* @author Fabio Pavesi (fabio@adamassoft.it)
*/
var DataSource = function(params) {
var parameters = {
/**
*
* @memberOf DataSource
*/
type: DataSourceType.virtuosoCodelist,
/**
*
* @memberOf DataSource
*/
url: "http://sp7.irea.cnr.it:8890/sparql",
// URI of the CodeList
/**
*
* @memberOf DataSource
*/
uri: "",
/**
* Callback to be called when data is ready
*
* @memberOf DataSource
* @type Callback
*/
ready: undefined,
/**
* Query to be issued
* @memberOf DataSource
* @type String
*/
query: "",
/**
* HTML control whose value represents the $search_param of the query
*
* @memberOf DataSource
*/
searchItem: undefined,
/**
* HTML control triggering a refresh in this datasource
*
* @memberOf DataSource
*/
triggerItem: undefined,
/**
* if true => requires explicit "refresh"
*
* @memberOf DataSource
*/
lazy: true,
/**
* if true => selected row is the same for all items referring to this datasource and all controls are notified if selection changes
*
* @memberOf DataSource
*/
singleton: false,
/**
* if true => this datasource is the product of a cloning operation: NEVER FORCE THIS VALUE
*
* @memberOf DataSource
*/
cloned: false,
/**
*
* @memberOf DataSource
*/
isFreshlyCreated: true,
/**
*
* @memberOf DataSource
*/
hasResultSet: false,
/**
*
* @memberOf DataSource
*/
hasErrors: false,
/**
*
* @memberOf DataSource
*/
errors: undefined,
/**
* Adapts dataset format to plain array
* see datasource_adapters.js
*
* @memberOf DataSource
*/
adapter: undefined
};
var resultSet = undefined;
var currentRow = -1;
var isLoading = false;
var language = "it";
var callbacks = [];
var listeners = [];
for ( var key in params ) {
parameters[key] = params[key];
}
if ( typeof DataSourceType[parameters.type] === "undefined" ) {
throw "Unknown datasource type";
}
if ( typeof parameters.adapter === "undefined" && parameters.type == DataSourceType.virtuosoCodelist || parameters.type == DataSourceType.sparql ) {
parameters.adapter = adapters.sparql;
}
if ( typeof parameters.id === "undefined" ) {
throw "DataSource id is mandatory";
}
var self;
function dataSuccess(data) {
resultSet = data;
parameters.isFreshlyCreated = false;
parameters.hasResultSet = true;
parameters.hasErrors = false;
if ( typeof parameters.adapter !== "undefined" ) {
resultSet = parameters.adapter(data);
}
/*
if ( parameters.type == "virtuosoCodelist" ) {
resultSet = data.results.bindings;
}
*/
if ( resultSet.length == 1 ) {
console.log(parameters.id + " has a single row");
currentRow = 0;
trigger("selectionChanged");
} else {
console.log(parameters.id + " has " + resultSet.length + " rows");
console.log(resultSet);
trigger("selectionChanged");
}
// console.log("Data Success " + parameters.id);
// console.log(resultSet);
if ( typeof parameters.ready === "function" ) {
parameters.ready(resultSet);
}
for ( var i = 0; i < callbacks.length; i++ ) {
callbacks[i](resultSet, parameters.id);
}
isLoading = false;
DataSourcePool.getInstance().queryEnd(self);
trigger("dataLoaded");
$("*[datasource='" + parameters.id + "']").removeClass("loading");
}
function dataError() {
parameters.isFreshlyCreated = false;
parameters.hasResultSet = false;
parameters.hasErrors = true;
parameters.errors = arguments;
// console.log("Data Error");
// console.log(arguments);
isLoading = false;
DataSourcePool.getInstance().queryEnd(self);
$("*[datasource='" + parameters.id + "']").removeClass("loading");
}
function loadData(justPrepareLoad) {
if ( typeof justPrepareLoad === "undefined" ) {
justPrepareLoad = false;
}
if ( isLoading ) {
return;
}
isLoading = true;
if ( typeof parameters.triggerItem !== "undefined" ) {
console.log("datasource " + parameters.id + " depends on trigger " + parameters.triggerItem);
console.log("trigger item has " + $("#" + parameters.triggerItem).length + " occurrences");
DataSourcePool.getInstance().setDatasourceTrigger(parameters.triggerItem, self);
/*
$("#" + ds.parameters.triggerItem).change(function() {
console.log($(this).attr("id") + " fired change towards datasource " + ds.getId() + " - " + i);
ds.refresh(false);
});
*/
}
DataSourcePool.getInstance().queryStart(self);
if ( justPrepareLoad ) {
return;
}
$("*[datasource='" + parameters.id + "']").addClass("loading");
resultSet = undefined;
currentResult = -1;
switch (parameters.type) {
case DataSourceType.virtuosoCodelist:
var sparql = new SPARQL(parameters.url, edi.getEndpointTypes(parameters.endpointType));
// console.log("load data for " + parameters.id);
sparql.query(parameters.uri, dataSuccess, dataError, language);
break;
case DataSourceType.sparql:
if ( typeof parameters.triggerItem !== "undefined" ) {
console.log(parameters.id + " is a datasource triggered by " + parameters.triggerItem);
parameters.searchItem = parameters.triggerItem;
}
/*
if ( typeof parameters.searchItem === "undefined" || typeof $("#" + parameters.searchItem) === "undefined" || $("#" + parameters.searchItem).val().toString().trim() == "" ) {
isLoading = false;
$("*[datasource='" + parameters.id + "']").removeClass("loading");
return;
}
*/
var sparql = new SPARQL(parameters.url, edi.getEndpointTypes(parameters.endpointType));
var newQuery = parameters.query.toString();
if ( typeof parameters.searchItem !== "undefined" && $("#" + parameters.searchItem).val() != "" ) {
newQuery = parameters.query.toString().replace(/\$search_param\$/g, $("#" + parameters.searchItem).val()).replace(/\$search_param/g, $("#" + parameters.searchItem).val());
}
console.log(newQuery);
sparql.specificQuery(newQuery, dataSuccess, dataError, language);
break;
default:
isLoading = false;
break;
}
}
function filter(field, value) {
var retVal = [];
for ( var i = 0; i < resultSet.length; i++ ) {
if ( resultSet[i][field].indexOf(value) >= 0 ) {
retVal.push(resultSet[i]);
}
}
return retVal;
}
function getId() {
return parameters.id;
}
function addListener(event, callback) {
for ( var i = 0; i < listeners.length; i++ ) {
if ( listeners[i].event == event ) {
listeners[i].callbacks.push(callback);
return;
}
}
listeners.push({
event: event,
callbacks: [callback]
});
console.log(listeners);
}
function trigger(event) {
// console.log("triggering event " + event);
for ( var i = 0; i < listeners.length; i++ ) {
if ( listeners[i].event == event ) {
// console.log(listeners[i].event);
if ( listeners[i].callbacks ) {
// console.log(listeners[i].callbacks);
for (var j = 0; j < listeners[i].callbacks.length; j++) {
if ( typeof listeners[i].callbacks[j] === "function") {
// console.log(listeners[i].callbacks[j]);
listeners[i].callbacks[j](event);
}
}
}
}
}
}
function setCurrentRow(field, value) {
if ( parameters.singleton == "true" ) {
// Current row only makes sense if datasource is a singleton
currentRow = -1;
for (var i = 0; i < resultSet.length; i++) {
// console.log("checking " + resultSet[i][field]);
if (resultSet[i][field] == value) {
currentRow = i;
// console.log("current row is " + i);
trigger("selectionChanged");
console.log("selectionChange event triggered with singleton datasource " + parameters.id + " and value found")
return;
}
}
trigger("selectionChanged");
console.log("selectionChange event triggered with singleton datasource " + parameters.id + " and value NOT found")
}
trigger("selectionChanged");
console.log("selectionChange event triggered with NON singleton datasource " + parameters.id + " ")
}
self = {
/**
* Returns the id
* @memberOf DataSource
* @function
*/
getId: getId,
/**
* @function
* @memberOf DataSource
* @returns {string[][]}
*/
getResultSet: function() {
return resultSet;
},
isReady: function() {
return ( typeof resultSet !== "undefined" );
},
/**
* Loads the data
* @memberOf DataSource
* @function
*/
refresh: function() {
loadData();
},
filter: filter,
/**
*
* @memberOf DataSource
* @param lang
*/
setLanguage: function(lang) {
language = lang;
},
/**
*
* @memberOf DataSource
* @returns {string}
*/
getLanguage: function() {
return language;
},
/**
*
* @memberOf DataSource
* @param callback
*/
addListener: function(callback) {
callbacks.push(callback);
},
/**
*
* @memberOf DataSource
* @returns {Array}
*/
getListeners: function() {
return callbacks;
},
setCurrentRow: setCurrentRow,
/**
* @function
* @memberOf DataSource
* @returns {string[]}
*/
getCurrentRow: function() {
// console.log("current row is " + currentRow);
var temp;
if ( resultSet && currentRow != -1 ) {
temp = resultSet[currentRow];
} else {
console.error("ds: " + parameters.id);
console.error(this);
console.error("resultSet: ");
console.error(resultSet );
console.error("currentRow: " + currentRow );
}
return temp;
},
/**
*
* @memberOf DataSource
* @param value
*/
setSearchItem: function(value) {
parameters.searchItem = value;
},
addEventListener: addListener,
triggerEvent: trigger,
getUrl: function() {
return parameters.url;
},
parameters: parameters
};
// console.log("adding self to datasourcepool");
// console.log(self);
DataSourcePool.getInstance().add(self);
if ( parameters.lazy != true ) {
loadData();
}
return self;
};