-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsparql-lab.js
277 lines (241 loc) · 9.39 KB
/
sparql-lab.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
SPARQL Lab glue code
derived from an example at https://gist.github.com/LaurensRietveld/eebde750f87c52cdfa58
IDE for SPARQL queries based on YASGUI.
Optionally, load a query from a remote repository.
Optionally, substitute VALUES parameters in the query.
*/
"use strict";
// Certain arguments are interpreted by this code, and cannot be used to
// modify SPARQL VALUES parameters:
var reservedArgumentNames = ['endpoint', 'query', 'queryRef', 'hide'];
// The following VALUES replacement code originates from
// https://raw.githubusercontent.com/NatLibFi/Finto-data/04f88fd31200238fe1e094377e4248ef40fbe3f2/tools/ysa-to-yso/ysa-to-yso.js
// by Osma Suominen
// This regular expression will parse a VALUES clause from a SPARQL query
// and return the following match groups:
// 0: the whole VALUES clause
// 1: opening clause e.g. "VALUES (?var1 ?var2) {"
// 2: variables e.g. "?var1 ?var2"
// 3: content of the block (everything within {})
// 4: closing "}"
var valuesBlockRegExp = /(VALUES\s+\(([^)]+)\)\s+\{)([^}]*?)([ \t]*})/i;
// This regular expression matches SPARQL variable names from the
// variable list of a VALUES clause.
// e.g. ["var1", "var2"], no question marks
var variableNamesRegExp = /\w+/g;
// This regular expression matches a single row of a VALUES clause,
// i.e. a set of values enclosed in parentheses. Match groups:
// 1: the content of the row (i.e. what is within the parentheses)
var valueRowRegExp = /\(\s+([^\)]*\s+)/;
// Same as above, but with the global flag, so matches several rows.
var valueRowRegExp_all = /\(\s+([^\)]*\s+)/g;
// This regular expression matches all individual values from a VALUES row:
// either URI tokens (full URI or qname), or literals in quotation marks.
var individualValueRegExp = /(?:[^\s"]+|"[^"]*")+/g;
function getVariables(query) {
var matches = valuesBlockRegExp.exec(query);
if (matches == null) return [];
var variables = matches[2].match(variableNamesRegExp);
return variables;
}
function getDefaultValues(query) {
var matches = valuesBlockRegExp.exec(query);
if (matches == null) return {};
var valueRows = matches[3].match(valueRowRegExp_all);
var defaultValueRow = valueRows[0].match(valueRowRegExp)[1];
var originalValues = defaultValueRow.match(individualValueRegExp);
var variables = getVariables(query);
var defaultValues = {};
for (var i = 0; i < variables.length; ++i) {
defaultValues[variables[i]] = originalValues[i];
}
return defaultValues;
}
function replaceQueryValues(query, newValues) {
var values = getDefaultValues(query);
$.each(newValues, function (key, value) {
// need to determine proper quoting for the values
// (for 'undef' in the default values, we can't know what is expected,
// and presume a literal value will fit in most cases)
if (values[key][0] == '"' || values[key] == 'undef') {
// a literal value - make sure it's quoted
if (value[0] != '"') {
values[key] = JSON.stringify(value);
} else { // already in quotes
values[key] = value;
}
} else {
// a resource value, either full URI or qname
if (value.indexOf('http') == 0) {
// make sure full URIs are enclosed in angle brackets
values[key] = "<" + value + ">";
} else {
values[key] = value;
}
}
});
var variables = getVariables(query);
// Variables which not already defined in the VALUES clause are dropped here.
var vals = $.map(variables, function (varname) {
return values[varname];
});
var valueString = "( " + vals.join(" ") + " )";
var matches = valuesBlockRegExp.exec(query);
if (matches == null) return query;
var newquery = query.replace(valuesBlockRegExp, matches[1] + "\n" + valueString + "\n" + matches[4]);
return newquery;
}
// end of VALUES replacement code
function getNewValues (args) {
var newValues = {};
$.each(args, function (key, value) {
// Skip if one of the reserved argument names.
// VALUES with these names cannot be replaced!
if(reservedArgumentNames.indexOf(key) == -1) {
newValues[key] = value;
}
});
return newValues;
}
var extendShareLink = function (yasqe) {
var shareLink = YASQE.createShareLink(yasqe);
shareLink["endpoint"] = yasqe.options.sparql.endpoint;
return shareLink;
};
var consumeUrl = function (yasqe, args) {
var pageVars = {};
// default settings
yasqe.options.sparql.endpoint = "http://zbw.eu/beta/sparql/stwv/query";
if (args) {
// change endpoint value if there is any
if (args.endpoint) {
yasqe.options.sparql.endpoint = args.endpoint;
}
if (args.hide && args.hide === "1") {
document.getElementById("yasqe").style.display = "none";
document.getElementById("results").style.display = "none";
document.getElementById("results-link").style.display = "none";
//YASR.defaults.drawOutputSelector = false;
}
//want to consume other arguments such as the request type (POST/GET), or arguments to send to endpoint
//feel free to add them in this function as well.
//as you see, all options you can specify in the default settings, are configurable via yasqe.options as well
// change query value if provided in URL
// (takes precedence over queryref)
if (args.query) {
yasqe.setValue(args.query);
// asyncron execution
setTimeout(function() { yasqe.query(); }, 1);
}
//Or, if you want to configure yasqe via a remote url (e.g. a query in some file elsewhere),
//feel free to do so!
else if (args.queryRef) {
var re, queryHost;
// distinguish by host name -
// get the host name / first part of the URL
switch (args.queryRef.match("^http[s]?://([a-zA-Z0-9_\\.-]+?)/.*")[1]) {
// IIPT repository - available only within the ZBW intranet
case 'ite-git':
queryHost = 'IIPT';
re = new RegExp("http://ite-git/gitlist/(.*?)\\.git/raw/master/(.*)");
break;
// GitHub repository - use a cors proxy to access a github file
case 'api.github.com':
queryHost = 'GitHub';
re = new RegExp("https://api.github.com/repos/(.*?)/contents/(.*)");
break;
}
// set variables for use in HTML page
pageVars.queryRef = args.queryRef;
pageVars.queryHost = queryHost;
if (re !== 'undefined') {
var found = args.queryRef.match(re);
if (found) {
pageVars.queryRepo = found[1];
pageVars.queryFile = found[2];
}
}
// get the query and execute
$.get(args.queryRef, function (data) {
var query;
// a repository may return the query directly, or,
// in case of Github, as a JSON data structure with encoded content
if (queryHost === 'GitHub') {
query = atob(data.content);
} else {
query = data;
}
// replace VALUES parameters, if they exist
// (otherwise, leave query intact, in order to allow multi-row
// VALUES parameters in the loaded query)
var newValues = getNewValues(args);
if (!jQuery.isEmptyObject(newValues)) {
query = replaceQueryValues(query, newValues)
}
yasqe.setValue(query);
yasqe.query();
});
}
}
// set more variables for use in HTML page, and modify it
pageVars.endpoint = yasqe.options.sparql.endpoint;
setPageVars(pageVars);
};
// set specific elements on the html page
function setPageVars (vars) {
// endpoint has to be defined
document.getElementById("endpoint_url").innerHTML = vars.endpoint;
// additionally, if queryRef was assigned
if (vars.queryRef) {
document.getElementById("query_details").innerHTML = "Query: " + vars.queryRef;
}
// additionally, if the query reference could be parsed and split up
if (vars.queryRepo) {
document.getElementById("query_details").innerHTML =
vars.queryHost + " repo: " + vars.queryRepo + ", Query: " + vars.queryFile;
document.title = vars.queryFile + ' | SPARQL Lab';
}
}
var yasqe = YASQE(document.getElementById("yasqe"), {
// display full query
viewportMargin: Infinity,
// grey edit window during query execution
backdrop: 99,
// modify codemirror tab handling to solely use 2 spaces
tabSize: 2,
indentUnit: 2,
extraKeys: {
Tab: function (cm) {
var spaces = new Array(cm.getOption("indentUnit") + 1).join(" ");
cm.replaceSelection(spaces);
}
},
sparql: {
showQueryButton: true
},
// extended sharelink for sharelink button
createShareLink: extendShareLink,
// does not use the yasge/yasgui sharelink logic,
// but url get params
consumeShareLink: consumeUrl
});
// merge fitting labels into uris, don't try to fetch from preflabel.org
YASR.plugins.table.defaults.mergeLabelsWithUris = true;
YASR.plugins.table.defaults.fetchTitlesFromPreflabel = false;
YASR.plugins.table.defaults.datatable.pageLength = 50;
YASR.plugins.pivot.defaults.mergeLabelsWithUris = true;
// don't load google content (protect privacy)
YASR.plugins.pivot.defaults.useGoogleCharts = false;
// disable persistency
YASR.defaults.persistency.prefix = false;
var yasr = YASR(document.getElementById("yasr"), {
//this way, the URLs in the results are prettified using the defined prefixes in the query
getUsedPrefixes: yasqe.getPrefixesFromQuery,
useGoogleCharts: false
});
// link yasqe and yasr together
yasqe.options.sparql.callbacks.complete = function () {
window.yasr.setResponse.apply(this, arguments);
document.getElementById('results').scrollIntoView();
};