annotate rdf/PluginRDFDescription.cpp @ 735:66c3f4e060e9

Merge
author Chris Cannam
date Wed, 23 May 2012 17:17:17 +0100
parents f3fd2988fc9b
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