comparison rdf/PluginRDFDescription.cpp @ 489:82ab61fa9223

* Reorganise our sparql queries on the basis that Redland must be available, not only optional. So for anything querying the pool of data about plugins, we use a single datastore and model which is initialised at the outset by PluginRDFIndexer and then queried directly; for anything that "reads from a file" (e.g. loading annotations) we query directly using Rasqal, going to the datastore when we need additional plugin-related information. This may improve performance, but mostly it simplifies the code and fixes a serious issue with RDF import in the previous versions (namely that multiple sequential RDF imports would end up sharing the same RDF data pool!)
author Chris Cannam
date Fri, 21 Nov 2008 16:12:29 +0000
parents a82645e788fc
children 81963c51b488
comparison
equal deleted inserted replaced
488:1c66e199e7d9 489:82ab61fa9223
32 PluginRDFDescription::PluginRDFDescription(QString pluginId) : 32 PluginRDFDescription::PluginRDFDescription(QString pluginId) :
33 m_pluginId(pluginId), 33 m_pluginId(pluginId),
34 m_haveDescription(false) 34 m_haveDescription(false)
35 { 35 {
36 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance(); 36 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance();
37 QString url = indexer->getDescriptionURLForPluginId(pluginId); 37 m_pluginUri = indexer->getURIForPluginId(pluginId);
38 if (url == "") { 38 if (m_pluginUri == "") {
39 cerr << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \"" 39 cerr << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \""
40 << pluginId.toStdString() << "\"" << endl; 40 << pluginId.toStdString() << "\"" << endl;
41 } else { 41 } else {
42 if (!indexURL(url)) { 42 // All the data we need should be in our RDF model already:
43 cerr << "PluginRDFDescription: ERROR: Failed to query RDF description for plugin ID \"" 43 // if it's not there, we don't know where to find it anyway
44 << pluginId.toStdString() << "\"" << endl; 44 if (index()) {
45 } else {
46 m_haveDescription = true; 45 m_haveDescription = true;
47 } 46 }
48 } 47 }
49 } 48 }
50 49
149 } 148 }
150 return m_outputUnitMap.find(outputId)->second; 149 return m_outputUnitMap.find(outputId)->second;
151 } 150 }
152 151
153 bool 152 bool
154 PluginRDFDescription::indexURL(QString url) 153 PluginRDFDescription::index()
155 { 154 {
156 Profiler profiler("PluginRDFDescription::indexURL"); 155 Profiler profiler("PluginRDFDescription::index");
157
158 QString type, soname, label;
159 PluginIdentifier::parseIdentifier(m_pluginId, type, soname, label);
160 156
161 bool success = true; 157 bool success = true;
162 158 if (!indexMetadata()) success = false;
163 QString local = url; 159 if (!indexOutputs()) success = false;
164
165 if (FileSource::isRemote(url) &&
166 FileSource::canHandleScheme(url)) {
167
168 CachedFile cf(url);
169 if (!cf.isOK()) {
170 return false;
171 }
172
173 local = QUrl::fromLocalFile(cf.getLocalFilename()).toString();
174 }
175
176 if (!indexMetadata(local, label)) success = false;
177 if (!indexOutputs(local, label)) success = false;
178 160
179 return success; 161 return success;
180 } 162 }
181 163
182 bool 164 bool
183 PluginRDFDescription::indexMetadata(QString url, QString label) 165 PluginRDFDescription::indexMetadata()
184 { 166 {
185 Profiler profiler("PluginRDFDescription::indexMetadata"); 167 Profiler profiler("PluginRDFDescription::index");
168
169 SimpleSPARQLQuery::QueryType m = SimpleSPARQLQuery::QueryFromModel;
186 170
187 QString queryTemplate = 171 QString queryTemplate =
188 QString( 172 QString(
189 " PREFIX vamp: <http://purl.org/ontology/vamp/> " 173 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
190 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> " 174 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
191 " PREFIX dc: <http://purl.org/dc/elements/1.1/> " 175 " PREFIX dc: <http://purl.org/dc/elements/1.1/> "
192 " SELECT ?%4 FROM <%1> " 176 " SELECT ?%3 "
193 " WHERE { " 177 " WHERE { "
194 " ?plugin vamp:identifier \"%2\" ; " 178 " <%1> %2 ?%3 . "
195 " a vamp:Plugin ; "
196 " %3 ?%4 . "
197 " }") 179 " }")
198 .arg(url) 180 .arg(m_pluginUri);
199 .arg(label);
200 181
201 SimpleSPARQLQuery::Value v; 182 SimpleSPARQLQuery::Value v;
202 183
203 v = SimpleSPARQLQuery::singleResultQuery 184 v = SimpleSPARQLQuery::singleResultQuery
204 (url, queryTemplate.arg("vamp:name").arg("name"), "name"); 185 (m, queryTemplate.arg("vamp:name").arg("name"), "name");
205 186
206 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") { 187 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
207 m_pluginName = v.value; 188 m_pluginName = v.value;
208 } 189 }
209 190
210 v = SimpleSPARQLQuery::singleResultQuery 191 v = SimpleSPARQLQuery::singleResultQuery
211 (url, queryTemplate.arg("dc:description").arg("description"), "description"); 192 (m, queryTemplate.arg("dc:description").arg("description"), "description");
212 193
213 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") { 194 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
214 m_pluginDescription = v.value; 195 m_pluginDescription = v.value;
215 } 196 }
216 197
217 v = SimpleSPARQLQuery::singleResultQuery 198 v = SimpleSPARQLQuery::singleResultQuery
218 (url, 199 (m,
219 QString( 200 QString(
220 " PREFIX vamp: <http://purl.org/ontology/vamp/> " 201 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
221 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> " 202 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
222 " SELECT ?name FROM <%1> " 203 " SELECT ?name "
223 " WHERE { " 204 " WHERE { "
224 " ?plugin vamp:identifier \"%2\" ; " 205 " <%1> foaf:maker ?maker . "
225 " a vamp:Plugin ; "
226 " foaf:maker ?maker . "
227 " ?maker foaf:name ?name . " 206 " ?maker foaf:name ?name . "
228 " }") 207 " }")
229 .arg(url) 208 .arg(m_pluginUri),
230 .arg(label), "name"); 209 "name");
231 210
232 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") { 211 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
233 m_pluginMaker = v.value; 212 m_pluginMaker = v.value;
234 } 213 }
235 214
238 // library would do nicely. Failing that, we could perhaps use 217 // library would do nicely. Failing that, we could perhaps use
239 // any foaf:page URL at all that appears in the file -- but 218 // any foaf:page URL at all that appears in the file -- but
240 // perhaps that would be unwise 219 // perhaps that would be unwise
241 220
242 v = SimpleSPARQLQuery::singleResultQuery 221 v = SimpleSPARQLQuery::singleResultQuery
243 (url, 222 (m,
244 QString( 223 QString(
245 " PREFIX vamp: <http://purl.org/ontology/vamp/> " 224 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
246 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> " 225 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
247 " SELECT ?page from <%1> " 226 " SELECT ?page "
248 " WHERE { " 227 " WHERE { "
249 " ?plugin vamp:identifier \"%2\" ; " 228 " <%1> foaf:page ?page . "
250 " a vamp:Plugin ; "
251 " foaf:page ?page . "
252 " }") 229 " }")
253 .arg(url) 230 .arg(m_pluginUri),
254 .arg(label), "page"); 231 "page");
255 232
256 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { 233 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
257 234
258 m_pluginInfoURL = v.value; 235 m_pluginInfoURL = v.value;
259 236
260 } else { 237 } else {
261 238
262 v = SimpleSPARQLQuery::singleResultQuery 239 v = SimpleSPARQLQuery::singleResultQuery
263 (url, 240 (m,
264 QString( 241 QString(
265 " PREFIX vamp: <http://purl.org/ontology/vamp/> " 242 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
266 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> " 243 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
267 " SELECT ?page from <%1> " 244 " SELECT ?page "
268 " WHERE { " 245 " WHERE { "
269 " ?library a vamp:PluginLibrary ; " 246 " ?library vamp:available_plugin <%1> ; "
270 " vamp:available_plugin ?plugin ; " 247 " a vamp:PluginLibrary ; "
271 " foaf:page ?page . " 248 " foaf:page ?page . "
272 " ?plugin a vamp:Plugin ; "
273 " vamp:identifier \"%2\" . "
274 " }") 249 " }")
275 .arg(url) 250 .arg(m_pluginUri),
276 .arg(label), "page"); 251 "page");
277 252
278 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { 253 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
279 254
280 m_pluginInfoURL = v.value; 255 m_pluginInfoURL = v.value;
281 } 256 }
283 258
284 return true; 259 return true;
285 } 260 }
286 261
287 bool 262 bool
288 PluginRDFDescription::indexOutputs(QString url, QString label) 263 PluginRDFDescription::indexOutputs()
289 { 264 {
290 Profiler profiler("PluginRDFDescription::indexOutputs"); 265 Profiler profiler("PluginRDFDescription::indexOutputs");
266
267 SimpleSPARQLQuery::QueryType m = SimpleSPARQLQuery::QueryFromModel;
291 268
292 SimpleSPARQLQuery query 269 SimpleSPARQLQuery query
293 (url, 270 (m,
294 QString 271 QString
295 ( 272 (
296 " PREFIX vamp: <http://purl.org/ontology/vamp/> " 273 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
297 274
298 " SELECT ?output ?output_id ?output_type ?unit " 275 " SELECT ?output ?output_id ?output_type ?unit "
299 " FROM <%1> "
300 276
301 " WHERE { " 277 " WHERE { "
302 278
303 " ?plugin vamp:identifier \"%2\" ; " 279 " <%1> vamp:output ?output . "
304 " a vamp:Plugin ; "
305 " vamp:output ?output . "
306 280
307 " ?output vamp:identifier ?output_id ; " 281 " ?output vamp:identifier ?output_id ; "
308 " a ?output_type . " 282 " a ?output_type . "
309 283
310 " OPTIONAL { " 284 " OPTIONAL { "
311 " ?output vamp:unit ?unit " 285 " ?output vamp:unit ?unit "
312 " } . " 286 " } . "
313 287
314 " } " 288 " } "
315 ) 289 )
316 .arg(url) 290 .arg(m_pluginUri));
317 .arg(label));
318 291
319 SimpleSPARQLQuery::ResultList results = query.execute(); 292 SimpleSPARQLQuery::ResultList results = query.execute();
320 293
321 if (!query.isOK()) { 294 if (!query.isOK()) {
322 cerr << "ERROR: PluginRDFDescription::indexURL: ERROR: Failed to query document at <" 295 cerr << "ERROR: PluginRDFDescription::index: ERROR: Failed to query outputs for <"
323 << url.toStdString() << ">: " 296 << m_pluginUri.toStdString() << ">: "
324 << query.getErrorString().toStdString() << endl; 297 << query.getErrorString().toStdString() << endl;
325 return false; 298 return false;
326 } 299 }
327 300
328 if (results.empty()) { 301 if (results.empty()) {
329 cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: Document at <" 302 cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: No outputs defined for <"
330 << url.toStdString() 303 << m_pluginUri.toStdString() << ">" << endl;
331 << "> does not appear to describe any outputs for plugin with id \""
332 << label.toStdString() << "\"" << endl;
333 return false; 304 return false;
334 } 305 }
335 306
336 // Note that an output may appear more than once, if it inherits 307 // Note that an output may appear more than once, if it inherits
337 // more than one type (e.g. DenseOutput and QuantizedOutput). So 308 // more than one type (e.g. DenseOutput and QuantizedOutput). So
363 } 334 }
364 335
365 SimpleSPARQLQuery::Value v; 336 SimpleSPARQLQuery::Value v;
366 337
367 v = SimpleSPARQLQuery::singleResultQuery 338 v = SimpleSPARQLQuery::singleResultQuery
368 (url, 339 (m,
369 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> " 340 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
370 " PREFIX dc: <http://purl.org/dc/elements/1.1/> " 341 " PREFIX dc: <http://purl.org/dc/elements/1.1/> "
371 " SELECT ?title FROM <%1> " 342 " SELECT ?title "
372 " WHERE { <%2> dc:title ?title } ") 343 " WHERE { <%2> dc:title ?title } ")
373 .arg(url).arg(outputUri), "title"); 344 .arg(outputUri), "title");
374 345
375 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") { 346 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
376 m_outputNames[outputId] = v.value; 347 m_outputNames[outputId] = v.value;
377 } 348 }
378 349
379 QString queryTemplate = 350 QString queryTemplate =
380 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> " 351 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
381 " SELECT ?%3 FROM <%1> " 352 " SELECT ?%3 "
382 " WHERE { <%2> vamp:computes_%3 ?%3 } ") 353 " WHERE { <%2> vamp:computes_%3 ?%3 } ")
383 .arg(url).arg(outputUri); 354 .arg(outputUri);
384 355
385 v = SimpleSPARQLQuery::singleResultQuery 356 v = SimpleSPARQLQuery::singleResultQuery
386 (url, queryTemplate.arg("event_type"), "event_type"); 357 (m, queryTemplate.arg("event_type"), "event_type");
387 358
388 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { 359 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
389 m_outputEventTypeURIMap[outputId] = v.value; 360 m_outputEventTypeURIMap[outputId] = v.value;
390 } 361 }
391 362
392 v = SimpleSPARQLQuery::singleResultQuery 363 v = SimpleSPARQLQuery::singleResultQuery
393 (url, queryTemplate.arg("feature_attribute"), "feature_attribute"); 364 (m, queryTemplate.arg("feature_attribute"), "feature_attribute");
394 365
395 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { 366 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
396 m_outputFeatureAttributeURIMap[outputId] = v.value; 367 m_outputFeatureAttributeURIMap[outputId] = v.value;
397 } 368 }
398 369
399 v = SimpleSPARQLQuery::singleResultQuery 370 v = SimpleSPARQLQuery::singleResultQuery
400 (url, queryTemplate.arg("signal_type"), "signal_type"); 371 (m, queryTemplate.arg("signal_type"), "signal_type");
401 372
402 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") { 373 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
403 m_outputSignalTypeURIMap[outputId] = v.value; 374 m_outputSignalTypeURIMap[outputId] = v.value;
404 } 375 }
405 } 376 }