Chris@439: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@439: Chris@439: /* Chris@439: Sonic Visualiser Chris@439: An audio file viewer and annotation editor. Chris@439: Centre for Digital Music, Queen Mary, University of London. Chris@439: This file copyright 2008 QMUL. Chris@439: Chris@439: This program is free software; you can redistribute it and/or Chris@439: modify it under the terms of the GNU General Public License as Chris@439: published by the Free Software Foundation; either version 2 of the Chris@439: License, or (at your option) any later version. See the file Chris@439: COPYING included with this distribution for more information. Chris@439: */ Chris@439: Chris@439: #include "PluginRDFDescription.h" Chris@439: Chris@439: #include "PluginRDFIndexer.h" Chris@439: #include "SimpleSPARQLQuery.h" Chris@439: Chris@439: #include "plugin/PluginIdentifier.h" Chris@439: Chris@439: #include Chris@439: using std::cerr; Chris@439: using std::endl; Chris@439: Chris@439: PluginRDFDescription::PluginRDFDescription(QString pluginId) : Chris@439: m_pluginId(pluginId), Chris@439: m_haveDescription(false) Chris@439: { Chris@439: PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance(); Chris@439: QString url = indexer->getDescriptionURLForPluginId(pluginId); Chris@439: if (url == "") { Chris@439: cerr << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \"" Chris@439: << pluginId.toStdString() << "\"" << endl; Chris@439: } else { Chris@439: if (!indexURL(url)) { Chris@439: cerr << "PluginRDFDescription: ERROR: Failed to query RDF description for plugin ID \"" Chris@439: << pluginId.toStdString() << "\"" << endl; Chris@439: } else { Chris@439: m_haveDescription = true; Chris@439: } Chris@439: } Chris@439: } Chris@439: Chris@439: PluginRDFDescription::~PluginRDFDescription() Chris@439: { Chris@439: } Chris@439: Chris@439: bool Chris@439: PluginRDFDescription::haveDescription() const Chris@439: { Chris@439: return m_haveDescription; Chris@439: } Chris@439: Chris@439: PluginRDFDescription::OutputType Chris@439: PluginRDFDescription::getOutputType(QString outputId) const Chris@439: { Chris@439: if (m_outputTypes.find(outputId) == m_outputTypes.end()) { Chris@439: return OutputTypeUnknown; Chris@439: } Chris@439: return m_outputTypes.find(outputId)->second; Chris@439: } Chris@439: Chris@439: PluginRDFDescription::OutputDisposition Chris@439: PluginRDFDescription::getOutputDisposition(QString outputId) const Chris@439: { Chris@439: if (m_outputDispositions.find(outputId) == m_outputDispositions.end()) { Chris@439: return OutputDispositionUnknown; Chris@439: } Chris@439: return m_outputDispositions.find(outputId)->second; Chris@439: } Chris@439: Chris@439: QString Chris@439: PluginRDFDescription::getOutputFeatureTypeURI(QString outputId) const Chris@439: { Chris@439: if (m_outputFeatureTypeURIMap.find(outputId) == Chris@439: m_outputFeatureTypeURIMap.end()) { Chris@439: return ""; Chris@439: } Chris@439: return m_outputFeatureTypeURIMap.find(outputId)->second; Chris@439: } Chris@439: Chris@439: QString Chris@439: PluginRDFDescription::getOutputEventTypeURI(QString outputId) const Chris@439: { Chris@439: if (m_outputEventTypeURIMap.find(outputId) == Chris@439: m_outputEventTypeURIMap.end()) { Chris@439: return ""; Chris@439: } Chris@439: return m_outputEventTypeURIMap.find(outputId)->second; Chris@439: } Chris@439: Chris@439: QString Chris@439: PluginRDFDescription::getOutputUnit(QString outputId) const Chris@439: { Chris@439: if (m_outputUnitMap.find(outputId) == m_outputUnitMap.end()) { Chris@439: return ""; Chris@439: } Chris@439: return m_outputUnitMap.find(outputId)->second; Chris@439: } Chris@439: Chris@439: bool Chris@439: PluginRDFDescription::indexURL(QString url) Chris@439: { Chris@439: QString type, soname, label; Chris@439: PluginIdentifier::parseIdentifier(m_pluginId, type, soname, label); Chris@439: Chris@439: SimpleSPARQLQuery query Chris@439: (QString Chris@439: ( Chris@439: " PREFIX vamp: " Chris@439: Chris@439: " SELECT ?output_id ?output_type ?feature_type ?event_type ?unit " Chris@439: " FROM <%1> " Chris@439: Chris@439: " WHERE { " Chris@439: Chris@439: " ?plugin a vamp:Plugin ; " Chris@439: " vamp:identifier \"%2\" ; " Chris@439: " vamp:output_descriptor ?output . " Chris@439: Chris@439: " ?output vamp:identifier ?output_id ; " Chris@439: " a ?output_type . " Chris@439: Chris@439: " OPTIONAL { " Chris@439: " ?output vamp:computes_feature_type ?feature_type " Chris@439: " } . " Chris@439: Chris@439: " OPTIONAL { " Chris@439: " ?output vamp:computes_event_type ?event_type " Chris@439: " } . " Chris@439: Chris@439: " OPTIONAL { " Chris@439: " ?output vamp:unit ?unit " Chris@439: " } . " Chris@439: Chris@439: " } " Chris@439: ) Chris@439: .arg(url) Chris@439: .arg(label)); Chris@439: Chris@439: SimpleSPARQLQuery::ResultList results = query.execute(); Chris@439: Chris@439: if (!query.isOK()) { Chris@439: cerr << "ERROR: PluginRDFDescription::indexURL: ERROR: Failed to query document at <" Chris@439: << url.toStdString() << ">: " Chris@439: << query.getErrorString().toStdString() << endl; Chris@439: return false; Chris@439: } Chris@439: Chris@439: if (results.empty()) { Chris@439: cerr << "ERROR: PluginRDFDescription::indexURL: NOTE: Document at <" Chris@439: << url.toStdString() Chris@439: << "> does not appear to describe any plugin outputs" << endl; Chris@439: return false; Chris@439: } Chris@439: Chris@439: // Note that an output may appear more than once, if it inherits Chris@439: // more than one type (e.g. DenseOutput and QuantizedOutput). So Chris@439: // these results must accumulate Chris@439: Chris@439: for (int i = 0; i < results.size(); ++i) { Chris@439: Chris@439: QString outputId = results[i]["output_id"].value; Chris@439: Chris@439: if (m_outputTypes.find(outputId) == m_outputTypes.end()) { Chris@439: m_outputTypes[outputId] = OutputTypeUnknown; Chris@439: } Chris@439: Chris@439: QString outputType = results[i]["output_type"].value; Chris@439: Chris@439: if (outputType.contains("DenseOutput")) { Chris@439: m_outputDispositions[outputId] = OutputDense; Chris@439: } else if (outputType.contains("SparseOutput")) { Chris@439: m_outputDispositions[outputId] = OutputSparse; Chris@439: } else if (outputType.contains("TrackLevelOutput")) { Chris@439: m_outputDispositions[outputId] = OutputTrackLevel; Chris@439: } Chris@439: Chris@439: if (results[i]["feature_type"].type == SimpleSPARQLQuery::URIValue) { Chris@439: Chris@439: QString featureType = results[i]["feature_type"].value; Chris@439: Chris@439: if (featureType != "") { Chris@439: if (m_outputTypes[outputId] == OutputEvents) { Chris@439: m_outputTypes[outputId] = OutputFeaturesAndEvents; Chris@439: } else { Chris@439: m_outputTypes[outputId] = OutputFeatures; Chris@439: } Chris@439: m_outputFeatureTypeURIMap[outputId] = featureType; Chris@439: } Chris@439: } Chris@439: Chris@439: if (results[i]["event_type"].type == SimpleSPARQLQuery::URIValue) { Chris@439: Chris@439: QString eventType = results[i]["event_type"].value; Chris@439: Chris@439: if (eventType != "") { Chris@439: if (m_outputTypes[outputId] == OutputFeatures) { Chris@439: m_outputTypes[outputId] = OutputFeaturesAndEvents; Chris@439: } else { Chris@439: m_outputTypes[outputId] = OutputEvents; Chris@439: } Chris@439: m_outputEventTypeURIMap[outputId] = eventType; Chris@439: } Chris@439: } Chris@439: Chris@439: if (results[i]["unit"].type == SimpleSPARQLQuery::LiteralValue) { Chris@439: Chris@439: QString unit = results[i]["unit"].value; Chris@439: Chris@439: if (unit != "") { Chris@439: m_outputUnitMap[outputId] = unit; Chris@439: } Chris@439: } Chris@439: } Chris@439: Chris@439: return true; Chris@439: } Chris@439: