annotate rdf/PluginRDFDescription.cpp @ 661:a4faa1840384

* If a FileSource URL won't convert at all in strict mode, try again in tolerant mode (necessary for e.g. filenames with square brackets in them)
author Chris Cannam
date Tue, 19 Oct 2010 21:47:55 +0100
parents e340b2fb9471
children b4a8d8221eaf
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@439 37 << pluginId.toStdString() << "\"" << 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@440 281 " SELECT ?output ?output_id ?output_type ?unit "
Chris@439 282
Chris@439 283 " WHERE { "
Chris@439 284
Chris@489 285 " <%1> vamp:output ?output . "
Chris@439 286
Chris@439 287 " ?output vamp:identifier ?output_id ; "
Chris@439 288 " a ?output_type . "
Chris@439 289
Chris@439 290 " OPTIONAL { "
Chris@439 291 " ?output vamp:unit ?unit "
Chris@439 292 " } . "
Chris@439 293
Chris@439 294 " } "
Chris@439 295 )
Chris@489 296 .arg(m_pluginUri));
Chris@439 297
Chris@439 298 SimpleSPARQLQuery::ResultList results = query.execute();
Chris@439 299
Chris@439 300 if (!query.isOK()) {
Chris@489 301 cerr << "ERROR: PluginRDFDescription::index: ERROR: Failed to query outputs for <"
Chris@489 302 << m_pluginUri.toStdString() << ">: "
Chris@439 303 << query.getErrorString().toStdString() << endl;
Chris@439 304 return false;
Chris@439 305 }
Chris@439 306
Chris@439 307 if (results.empty()) {
Chris@489 308 cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: No outputs defined for <"
Chris@489 309 << m_pluginUri.toStdString() << ">" << endl;
Chris@439 310 return false;
Chris@439 311 }
Chris@439 312
Chris@439 313 // Note that an output may appear more than once, if it inherits
Chris@439 314 // more than one type (e.g. DenseOutput and QuantizedOutput). So
Chris@439 315 // these results must accumulate
Chris@439 316
Chris@439 317 for (int i = 0; i < results.size(); ++i) {
Chris@439 318
Chris@440 319 QString outputUri = results[i]["output"].value;
Chris@439 320 QString outputId = results[i]["output_id"].value;
Chris@439 321 QString outputType = results[i]["output_type"].value;
Chris@439 322
Chris@494 323 m_outputUriMap[outputId] = outputUri;
Chris@494 324
Chris@439 325 if (outputType.contains("DenseOutput")) {
Chris@439 326 m_outputDispositions[outputId] = OutputDense;
Chris@439 327 } else if (outputType.contains("SparseOutput")) {
Chris@439 328 m_outputDispositions[outputId] = OutputSparse;
Chris@439 329 } else if (outputType.contains("TrackLevelOutput")) {
Chris@439 330 m_outputDispositions[outputId] = OutputTrackLevel;
Chris@457 331 } else {
Chris@457 332 m_outputDispositions[outputId] = OutputDispositionUnknown;
Chris@439 333 }
Chris@439 334
Chris@439 335 if (results[i]["unit"].type == SimpleSPARQLQuery::LiteralValue) {
Chris@439 336
Chris@439 337 QString unit = results[i]["unit"].value;
Chris@439 338
Chris@439 339 if (unit != "") {
Chris@439 340 m_outputUnitMap[outputId] = unit;
Chris@439 341 }
Chris@439 342 }
Chris@440 343
Chris@457 344 SimpleSPARQLQuery::Value v;
Chris@457 345
Chris@457 346 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 347 (m,
Chris@480 348 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@457 349 " PREFIX dc: <http://purl.org/dc/elements/1.1/> "
Chris@489 350 " SELECT ?title "
Chris@457 351 " WHERE { <%2> dc:title ?title } ")
Chris@489 352 .arg(outputUri), "title");
Chris@457 353
Chris@457 354 if (v.type == SimpleSPARQLQuery::LiteralValue && v.value != "") {
Chris@457 355 m_outputNames[outputId] = v.value;
Chris@457 356 }
Chris@457 357
Chris@440 358 QString queryTemplate =
Chris@440 359 QString(" PREFIX vamp: <http://purl.org/ontology/vamp/> "
Chris@489 360 " SELECT ?%3 "
Chris@440 361 " WHERE { <%2> vamp:computes_%3 ?%3 } ")
Chris@489 362 .arg(outputUri);
Chris@440 363
Chris@440 364 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 365 (m, queryTemplate.arg("event_type"), "event_type");
Chris@440 366
Chris@440 367 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 368 m_outputEventTypeURIMap[outputId] = v.value;
Chris@440 369 }
Chris@440 370
Chris@440 371 v = SimpleSPARQLQuery::singleResultQuery
Chris@507 372 (m, queryTemplate.arg("feature"), "feature");
Chris@440 373
Chris@440 374 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 375 m_outputFeatureAttributeURIMap[outputId] = v.value;
Chris@507 376 }
Chris@440 377
Chris@440 378 v = SimpleSPARQLQuery::singleResultQuery
Chris@489 379 (m, queryTemplate.arg("signal_type"), "signal_type");
Chris@440 380
Chris@440 381 if (v.type == SimpleSPARQLQuery::URIValue && v.value != "") {
Chris@440 382 m_outputSignalTypeURIMap[outputId] = v.value;
Chris@440 383 }
Chris@439 384 }
Chris@439 385
Chris@439 386 return true;
Chris@439 387 }
Chris@439 388