annotate rdf/PluginRDFDescription.cpp @ 718:f3fd2988fc9b

Fix incorrect query structure for output type URIs. This led to some output RDF features being written with type URIs intended for different outputs. Also revert some SVDEBUGs to cerrs -- they are intended as user-visible errors or warnings rather than debug
author Chris Cannam
date Mon, 09 Jan 2012 16:28:54 +0000
parents 1424aa29ae95
children c789deb83bd4
rev   line source
Chris@439 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@439 2
Chris@439 3 /*
Chris@439 4 Sonic Visualiser
Chris@439 5 An audio file viewer and annotation editor.
Chris@439 6 Centre for Digital Music, Queen Mary, University of London.
Chris@439 7 This file copyright 2008 QMUL.
Chris@439 8
Chris@439 9 This program is free software; you can redistribute it and/or
Chris@439 10 modify it under the terms of the GNU General Public License as
Chris@439 11 published by the Free Software Foundation; either version 2 of the
Chris@439 12 License, or (at your option) any later version. See the file
Chris@439 13 COPYING included with this distribution for more information.
Chris@439 14 */
Chris@439 15
Chris@439 16 #include "PluginRDFDescription.h"
Chris@439 17
Chris@439 18 #include "PluginRDFIndexer.h"
Chris@439 19 #include "SimpleSPARQLQuery.h"
Chris@439 20
Chris@457 21 #include "base/Profiler.h"
Chris@457 22
Chris@439 23 #include "plugin/PluginIdentifier.h"
Chris@439 24
Chris@439 25 #include <iostream>
Chris@439 26 using std::cerr;
Chris@439 27 using std::endl;
Chris@439 28
Chris@439 29 PluginRDFDescription::PluginRDFDescription(QString pluginId) :
Chris@439 30 m_pluginId(pluginId),
Chris@439 31 m_haveDescription(false)
Chris@439 32 {
Chris@439 33 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance();
Chris@489 34 m_pluginUri = indexer->getURIForPluginId(pluginId);
Chris@489 35 if (m_pluginUri == "") {
Chris@439 36 cerr << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \""
Chris@686 37 << pluginId << "\"" << endl;
Chris@439 38 } else {
Chris@489 39 // All the data we need should be in our RDF model already:
Chris@489 40 // if it's not there, we don't know where to find it anyway
Chris@489 41 if (index()) {
Chris@439 42 m_haveDescription = true;
Chris@439 43 }
Chris@439 44 }
Chris@439 45 }
Chris@439 46
Chris@439 47 PluginRDFDescription::~PluginRDFDescription()
Chris@439 48 {
Chris@439 49 }
Chris@439 50
Chris@439 51 bool
Chris@439 52 PluginRDFDescription::haveDescription() const
Chris@439 53 {
Chris@439 54 return m_haveDescription;
Chris@439 55 }
Chris@439 56
Chris@457 57 QString
Chris@457 58 PluginRDFDescription::getPluginName() const
Chris@457 59 {
Chris@457 60 return m_pluginName;
Chris@457 61 }
Chris@457 62
Chris@457 63 QString
Chris@457 64 PluginRDFDescription::getPluginDescription() const
Chris@457 65 {
Chris@457 66 return m_pluginDescription;
Chris@457 67 }
Chris@457 68
Chris@457 69 QString
Chris@457 70 PluginRDFDescription::getPluginMaker() const
Chris@457 71 {
Chris@457 72 return m_pluginMaker;
Chris@457 73 }
Chris@457 74
Chris@462 75 QString
Chris@462 76 PluginRDFDescription::getPluginInfoURL() const
Chris@462 77 {
Chris@462 78 return m_pluginInfoURL;
Chris@462 79 }
Chris@462 80
Chris@457 81 QStringList
Chris@457 82 PluginRDFDescription::getOutputIds() const
Chris@457 83 {
Chris@457 84 QStringList ids;
Chris@457 85 for (OutputDispositionMap::const_iterator i = m_outputDispositions.begin();
Chris@457 86 i != m_outputDispositions.end(); ++i) {
Chris@457 87 ids.push_back(i->first);
Chris@457 88 }
Chris@457 89 return ids;
Chris@457 90 }
Chris@457 91
Chris@457 92 QString
Chris@457 93 PluginRDFDescription::getOutputName(QString outputId) const
Chris@457 94 {
Chris@457 95 if (m_outputNames.find(outputId) == m_outputNames.end()) {
Chris@457 96 return "";
Chris@457 97 }
Chris@457 98 return m_outputNames.find(outputId)->second;
Chris@457 99 }
Chris@457 100
Chris@439 101 PluginRDFDescription::OutputDisposition
Chris@439 102 PluginRDFDescription::getOutputDisposition(QString outputId) const
Chris@439 103 {
Chris@439 104 if (m_outputDispositions.find(outputId) == m_outputDispositions.end()) {
Chris@439 105 return OutputDispositionUnknown;
Chris@439 106 }
Chris@439 107 return m_outputDispositions.find(outputId)->second;
Chris@439 108 }
Chris@439 109
Chris@439 110 QString
Chris@439 111 PluginRDFDescription::getOutputEventTypeURI(QString outputId) const
Chris@439 112 {
Chris@439 113 if (m_outputEventTypeURIMap.find(outputId) ==
Chris@439 114 m_outputEventTypeURIMap.end()) {
Chris@439 115 return "";
Chris@439 116 }
Chris@439 117 return m_outputEventTypeURIMap.find(outputId)->second;
Chris@439 118 }
Chris@439 119
Chris@439 120 QString
Chris@440 121 PluginRDFDescription::getOutputFeatureAttributeURI(QString outputId) const
Chris@440 122 {
Chris@440 123 if (m_outputFeatureAttributeURIMap.find(outputId) ==
Chris@440 124 m_outputFeatureAttributeURIMap.end()) {
Chris@440 125 return "";
Chris@440 126 }
Chris@440 127 return m_outputFeatureAttributeURIMap.find(outputId)->second;
Chris@440 128 }
Chris@440 129
Chris@440 130 QString
Chris@440 131 PluginRDFDescription::getOutputSignalTypeURI(QString outputId) const
Chris@440 132 {
Chris@440 133 if (m_outputSignalTypeURIMap.find(outputId) ==
Chris@440 134 m_outputSignalTypeURIMap.end()) {
Chris@440 135 return "";
Chris@440 136 }
Chris@440 137 return m_outputSignalTypeURIMap.find(outputId)->second;
Chris@440 138 }
Chris@440 139
Chris@440 140 QString
Chris@439 141 PluginRDFDescription::getOutputUnit(QString outputId) const
Chris@439 142 {
Chris@439 143 if (m_outputUnitMap.find(outputId) == m_outputUnitMap.end()) {
Chris@439 144 return "";
Chris@439 145 }
Chris@439 146 return m_outputUnitMap.find(outputId)->second;
Chris@439 147 }
Chris@439 148
Chris@494 149 QString
Chris@494 150 PluginRDFDescription::getOutputUri(QString outputId) const
Chris@494 151 {
Chris@494 152 if (m_outputUriMap.find(outputId) == m_outputUriMap.end()) {
Chris@494 153 return "";
Chris@494 154 }
Chris@494 155 return m_outputUriMap.find(outputId)->second;
Chris@494 156 }
Chris@494 157
Chris@439 158 bool
Chris@489 159 PluginRDFDescription::index()
Chris@439 160 {
Chris@489 161 Profiler profiler("PluginRDFDescription::index");
Chris@439 162
Chris@457 163 bool success = true;
Chris@489 164 if (!indexMetadata()) success = false;
Chris@489 165 if (!indexOutputs()) success = false;
Chris@457 166
Chris@457 167 return success;
Chris@457 168 }
Chris@457 169
Chris@457 170 bool
Chris@489 171 PluginRDFDescription::indexMetadata()
Chris@457 172 {
Chris@489 173 Profiler profiler("PluginRDFDescription::index");
Chris@489 174
Chris@489 175 SimpleSPARQLQuery::QueryType m = SimpleSPARQLQuery::QueryFromModel;
Chris@457 176
Chris@457 177 QString queryTemplate =
Chris@457 178 QString(
Chris@457 179 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@457 180 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
Chris@457 181 " PREFIX dc: <http://purl.org/dc/elements/1.1/> "
Chris@489 182 " SELECT ?%3 "
Chris@457 183 " WHERE { "
Chris@489 184 " <%1> %2 ?%3 . "
Chris@457 185 " }")
Chris@489 186 .arg(m_pluginUri);
Chris@457 187
Chris@457 188 SimpleSPARQLQuery::Value v;
Chris@457 189
Chris@457 190 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 191 (m, queryTemplate.arg("vamp:name").arg("name"), "name");
Chris@457 192
Chris@457 193 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
Chris@457 194 m_pluginName = v.value;
Chris@457 195 }
Chris@457 196
Chris@457 197 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 198 (m, queryTemplate.arg("dc:description").arg("description"), "description");
Chris@457 199
Chris@457 200 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
Chris@457 201 m_pluginDescription = v.value;
Chris@457 202 }
Chris@457 203
Chris@457 204 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 205 (m,
Chris@480 206 QString(
Chris@457 207 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@457 208 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
Chris@489 209 " SELECT ?name "
Chris@457 210 " WHERE { "
Chris@489 211 " <%1> foaf:maker ?maker . "
Chris@457 212 " ?maker foaf:name ?name . "
Chris@457 213 " }")
Chris@489 214 .arg(m_pluginUri),
Chris@489 215 "name");
Chris@457 216
Chris@457 217 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
Chris@457 218 m_pluginMaker = v.value;
Chris@457 219 }
Chris@457 220
Chris@462 221 // If we have a more-information URL for this plugin, then we take
Chris@463 222 // that. Otherwise, a more-information URL for the plugin
Chris@462 223 // library would do nicely. Failing that, we could perhaps use
Chris@462 224 // any foaf:page URL at all that appears in the file -- but
Chris@462 225 // perhaps that would be unwise
Chris@462 226
Chris@462 227 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 228 (m,
Chris@480 229 QString(
Chris@462 230 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@462 231 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
Chris@489 232 " SELECT ?page "
Chris@462 233 " WHERE { "
Chris@489 234 " <%1> foaf:page ?page . "
Chris@462 235 " }")
Chris@489 236 .arg(m_pluginUri),
Chris@489 237 "page");
Chris@462 238
Chris@462 239 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@462 240
Chris@462 241 m_pluginInfoURL = v.value;
Chris@462 242
Chris@462 243 } else {
Chris@462 244
Chris@462 245 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 246 (m,
Chris@480 247 QString(
Chris@462 248 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@462 249 " PREFIX foaf: <http://xmlns.com/foaf/0.1/> "
Chris@489 250 " SELECT ?page "
Chris@462 251 " WHERE { "
Chris@489 252 " ?library vamp:available_plugin <%1> ; "
Chris@489 253 " a vamp:PluginLibrary ; "
Chris@462 254 " foaf:page ?page . "
Chris@462 255 " }")
Chris@489 256 .arg(m_pluginUri),
Chris@489 257 "page");
Chris@462 258
Chris@462 259 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@462 260
Chris@462 261 m_pluginInfoURL = v.value;
Chris@462 262 }
Chris@462 263 }
Chris@462 264
Chris@457 265 return true;
Chris@457 266 }
Chris@457 267
Chris@457 268 bool
Chris@489 269 PluginRDFDescription::indexOutputs()
Chris@457 270 {
Chris@457 271 Profiler profiler("PluginRDFDescription::indexOutputs");
Chris@489 272
Chris@489 273 SimpleSPARQLQuery::QueryType m = SimpleSPARQLQuery::QueryFromModel;
Chris@457 274
Chris@439 275 SimpleSPARQLQuery query
Chris@489 276 (m,
Chris@480 277 QString
Chris@439 278 (
Chris@439 279 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@439 280
Chris@718 281 " SELECT ?output "
Chris@439 282
Chris@439 283 " WHERE { "
Chris@489 284 " <%1> vamp:output ?output . "
Chris@439 285 " } "
Chris@439 286 )
Chris@489 287 .arg(m_pluginUri));
Chris@439 288
Chris@439 289 SimpleSPARQLQuery::ResultList results = query.execute();
Chris@439 290
Chris@439 291 if (!query.isOK()) {
Chris@489 292 cerr << "ERROR: PluginRDFDescription::index: ERROR: Failed to query outputs for <"
Chris@686 293 << m_pluginUri << ">: "
Chris@686 294 << query.getErrorString() << endl;
Chris@439 295 return false;
Chris@439 296 }
Chris@439 297
Chris@439 298 if (results.empty()) {
Chris@718 299 cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: No outputs defined for <"
Chris@686 300 << m_pluginUri << ">" << endl;
Chris@439 301 return false;
Chris@439 302 }
Chris@439 303
Chris@439 304 // Note that an output may appear more than once, if it inherits
Chris@439 305 // more than one type (e.g. DenseOutput and QuantizedOutput). So
Chris@439 306 // these results must accumulate
Chris@439 307
Chris@439 308 for (int i = 0; i < results.size(); ++i) {
Chris@439 309
Chris@718 310 if (results[i]["output"].type != SimpleSPARQLQuery::URIValue ||
Chris@718 311 results[i]["output"].value == "") {
Chris@718 312 cerr << "ERROR: PluginRDFDescription::indexURL: No valid URI for output " << i << " of plugin <" << m_pluginUri << ">" << endl;
Chris@718 313 return false;
Chris@718 314 }
Chris@718 315
Chris@440 316 QString outputUri = results[i]["output"].value;
Chris@718 317
Chris@718 318 SimpleSPARQLQuery::Value v;
Chris@718 319
Chris@718 320 v = SimpleSPARQLQuery::singleResultQuery
Chris@718 321 (m,
Chris@718 322 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@718 323 " SELECT ?output_id "
Chris@718 324 " WHERE { <%1> vamp:identifier ?output_id } ")
Chris@718 325 .arg(outputUri), "output_id");
Chris@718 326
Chris@718 327 if (v.type != SimpleSPARQLQuery::LiteralValue || v.value == "") {
Chris@718 328 cerr << "ERROR: PluginRDFDescription::indexURL: No identifier for output <" << outputUri << ">" << endl;
Chris@718 329 return false;
Chris@718 330 }
Chris@718 331 QString outputId = v.value;
Chris@718 332
Chris@718 333 v = SimpleSPARQLQuery::singleResultQuery
Chris@718 334 (m,
Chris@718 335 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@718 336 " SELECT ?output_type "
Chris@718 337 " WHERE { <%1> a ?output_type } ")
Chris@718 338 .arg(outputUri), "output_type");
Chris@718 339
Chris@718 340 QString outputType;
Chris@718 341 if (v.type == SimpleSPARQLQuery::URIValue) outputType = v.value;
Chris@718 342
Chris@718 343 v = SimpleSPARQLQuery::singleResultQuery
Chris@718 344 (m,
Chris@718 345 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@718 346 " SELECT ?unit "
Chris@718 347 " WHERE { <%1> vamp:unit ?unit } ")
Chris@718 348 .arg(outputUri), "unit");
Chris@718 349
Chris@718 350 QString outputUnit;
Chris@718 351 if (v.type == SimpleSPARQLQuery::LiteralValue) outputUnit = v.value;
Chris@439 352
Chris@494 353 m_outputUriMap[outputId] = outputUri;
Chris@494 354
Chris@439 355 if (outputType.contains("DenseOutput")) {
Chris@439 356 m_outputDispositions[outputId] = OutputDense;
Chris@439 357 } else if (outputType.contains("SparseOutput")) {
Chris@439 358 m_outputDispositions[outputId] = OutputSparse;
Chris@439 359 } else if (outputType.contains("TrackLevelOutput")) {
Chris@439 360 m_outputDispositions[outputId] = OutputTrackLevel;
Chris@457 361 } else {
Chris@457 362 m_outputDispositions[outputId] = OutputDispositionUnknown;
Chris@439 363 }
Chris@439 364
Chris@718 365 if (outputUnit != "") {
Chris@718 366 m_outputUnitMap[outputId] = outputUnit;
Chris@439 367 }
Chris@440 368
Chris@457 369 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 370 (m,
Chris@480 371 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@457 372 " PREFIX dc: <http://purl.org/dc/elements/1.1/> "
Chris@489 373 " SELECT ?title "
Chris@718 374 " WHERE { <%1> dc:title ?title } ")
Chris@489 375 .arg(outputUri), "title");
Chris@457 376
Chris@457 377 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
Chris@457 378 m_outputNames[outputId] = v.value;
Chris@457 379 }
Chris@457 380
Chris@440 381 QString queryTemplate =
Chris@440 382 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@718 383 " SELECT ?%2 "
Chris@718 384 " WHERE { <%1> vamp:computes_%2 ?%2 } ")
Chris@489 385 .arg(outputUri);
Chris@440 386
Chris@440 387 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 388 (m, queryTemplate.arg("event_type"), "event_type");
Chris@440 389
Chris@440 390 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 391 m_outputEventTypeURIMap[outputId] = v.value;
Chris@440 392 }
Chris@440 393
Chris@440 394 v = SimpleSPARQLQuery::singleResultQuery
Chris@507 395 (m, queryTemplate.arg("feature"), "feature");
Chris@440 396
Chris@440 397 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 398 m_outputFeatureAttributeURIMap[outputId] = v.value;
Chris@507 399 }
Chris@440 400
Chris@440 401 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 402 (m, queryTemplate.arg("signal_type"), "signal_type");
Chris@440 403
Chris@440 404 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 405 m_outputSignalTypeURIMap[outputId] = v.value;
Chris@440 406 }
Chris@439 407 }
Chris@439 408
Chris@439 409 return true;
Chris@439 410 }
Chris@439 411