annotate rdf/PluginRDFDescription.cpp @ 683:f84f147572b9

Avoid crash when generating/processing a very short file
author Chris Cannam
date Wed, 11 May 2011 11:04:02 +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