PluginRDFDescription.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2008-2012 QMUL.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "PluginRDFDescription.h"
17 
18 #include "PluginRDFIndexer.h"
19 
20 #include "base/Profiler.h"
21 #include "base/Debug.h"
22 
24 
25 #include <dataquay/BasicStore.h>
26 
27 #include <iostream>
28 
29 using Dataquay::Uri;
30 using Dataquay::Node;
31 using Dataquay::Nodes;
32 using Dataquay::Triple;
33 using Dataquay::Triples;
34 using Dataquay::BasicStore;
35 
36 //#define DEBUG_PLUGIN_RDF_DESCRIPTION 1
37 
39  m_pluginId(pluginId),
40  m_haveDescription(false)
41 {
43  m_pluginUri = indexer->getURIForPluginId(pluginId);
44  if (m_pluginUri == "") {
45  SVDEBUG << "PluginRDFDescription: WARNING: No RDF description available for plugin ID \""
46  << pluginId << "\"" << endl;
47  } else {
48  // All the data we need should be in our RDF model already:
49  // if it's not there, we don't know where to find it anyway
50  if (index()) {
51  m_haveDescription = true;
52  }
53  }
54 }
55 
57 {
58 }
59 
60 bool
62 {
63  return m_haveDescription;
64 }
65 
66 QString
68 {
69  return m_pluginName;
70 }
71 
72 QString
74 {
75  return m_pluginDescription;
76 }
77 
78 QString
80 {
81  return m_pluginMaker;
82 }
83 
86 {
87  return m_provider;
88 }
89 
90 QStringList
92 {
93  QStringList ids;
94  for (OutputDispositionMap::const_iterator i = m_outputDispositions.begin();
95  i != m_outputDispositions.end(); ++i) {
96  ids.push_back(i->first);
97  }
98  return ids;
99 }
100 
101 QString
102 PluginRDFDescription::getOutputName(QString outputId) const
103 {
104  if (m_outputNames.find(outputId) == m_outputNames.end()) {
105  return "";
106  }
107  return m_outputNames.find(outputId)->second;
108 }
109 
112 {
113  if (m_outputDispositions.find(outputId) == m_outputDispositions.end()) {
115  }
116  return m_outputDispositions.find(outputId)->second;
117 }
118 
119 QString
121 {
122  if (m_outputEventTypeURIMap.find(outputId) ==
123  m_outputEventTypeURIMap.end()) {
124  return "";
125  }
126  return m_outputEventTypeURIMap.find(outputId)->second;
127 }
128 
129 QString
131 {
132  if (m_outputFeatureAttributeURIMap.find(outputId) ==
134  return "";
135  }
136  return m_outputFeatureAttributeURIMap.find(outputId)->second;
137 }
138 
139 QString
141 {
142  if (m_outputSignalTypeURIMap.find(outputId) ==
143  m_outputSignalTypeURIMap.end()) {
144  return "";
145  }
146  return m_outputSignalTypeURIMap.find(outputId)->second;
147 }
148 
149 QString
150 PluginRDFDescription::getOutputUnit(QString outputId) const
151 {
152  if (m_outputUnitMap.find(outputId) == m_outputUnitMap.end()) {
153  return "";
154  }
155  return m_outputUnitMap.find(outputId)->second;
156 }
157 
158 QString
159 PluginRDFDescription::getOutputUri(QString outputId) const
160 {
161  if (m_outputUriMap.find(outputId) == m_outputUriMap.end()) {
162  return "";
163  }
164  return m_outputUriMap.find(outputId)->second;
165 }
166 
167 bool
169 {
170  Profiler profiler("PluginRDFDescription::index");
171 
172  bool success = true;
173  if (!indexMetadata()) success = false;
174  if (!indexOutputs()) success = false;
175 
176  return success;
177 }
178 
179 bool
181 {
182  Profiler profiler("PluginRDFDescription::index");
183 
185  const BasicStore *index = indexer->getIndex();
186  Uri plugin(m_pluginUri);
187 
188  Node n = index->complete
189  (Triple(plugin, index->expand("vamp:name"), Node()));
190 
191  if (n.type == Node::Literal && n.value != "") {
192  m_pluginName = n.value;
193  }
194 
195  n = index->complete
196  (Triple(plugin, index->expand("dc:description"), Node()));
197 
198  if (n.type == Node::Literal && n.value != "") {
199  m_pluginDescription = n.value;
200  }
201 
202  n = index->complete
203  (Triple(plugin, index->expand("foaf:maker"), Node()));
204 
205  if (n.type == Node::URI || n.type == Node::Blank) {
206  n = index->complete(Triple(n, index->expand("foaf:name"), Node()));
207  if (n.type == Node::Literal && n.value != "") {
208  m_pluginMaker = n.value;
209  }
210  }
211 
212  // If we have a more-information URL for this plugin, then we take
213  // that. Otherwise, a more-information URL for the plugin library
214  // would do nicely.
215 
216  n = index->complete
217  (Triple(plugin, index->expand("foaf:page"), Node()));
218 
219  if (n.type == Node::URI && n.value != "") {
220  m_provider.infoUrl = n.value;
221  }
222 
223  // There may be more than one library node claiming this
224  // plugin. That's because older RDF descriptions tend to use a
225  // library node URI derived from the description's own URI, so it
226  // varies depending on where you read the description from. It's
227  // common therefore to end up with both a file: URI (from an
228  // installed older version) and an http: one (from an online
229  // updated version). We have no way to pick an authoritative one,
230  // but it's also common that only one of them will have the
231  // resources we need anyway, so let's iterate through them all.
232 
233  Nodes libnodes = index->match
234  (Triple(Node(), index->expand("vamp:available_plugin"), plugin))
235  .subjects();
236 
237  for (Node libn: libnodes) {
238 
239  if (libn.type != Node::URI || libn.value == "") {
240  continue;
241  }
242 
243  n = index->complete
244  (Triple(libn, index->expand("foaf:page"), Node()));
245 
246  if (n.type == Node::URI && n.value != "") {
247  m_provider.infoUrl = n.value;
248  }
249 
250  n = index->complete
251  (Triple(libn, index->expand("doap:download-page"), Node()));
252 
253  if (n.type == Node::URI && n.value != "") {
254  m_provider.downloadUrl = n.value;
255 
256  n = index->complete
257  (Triple(libn, index->expand("vamp:has_source"), Node()));
258  if (n.type == Node::Literal && n.value == "true") {
260  }
261 
262  Nodes binaries = index->match
263  (Triple(libn, index->expand("vamp:has_binary"), Node()))
264  .objects();
265 
266  for (Node bin: binaries) {
267  if (bin.type != Node::Literal) continue;
268  if (bin.value == "linux32") {
270  } else if (bin.value == "linux64") {
272  } else if (bin.value == "win32") {
274  } else if (bin.value == "osx") {
276  }
277  }
278  }
279 
280  Nodes packs = index->match
281  (Triple(Node(), index->expand("vamp:available_library"), libn))
282  .subjects();
283 
284 #ifdef DEBUG_PLUGIN_RDF_DESCRIPTION
285  SVCERR << packs.size() << " matching pack(s) for library node "
286  << libn << endl;
287 #endif
288 
289  for (Node packn: packs) {
290  if (packn.type != Node::URI) continue;
291 
292  QString packName;
293  QString packUrl;
294  n = index->complete
295  (Triple(packn, index->expand("dc:title"), Node()));
296  if (n.type == Node::Literal) {
297  packName = n.value;
298  }
299  n = index->complete
300  (Triple(packn, index->expand("foaf:page"), Node()));
301  if (n.type == Node::URI) {
302  packUrl = n.value;
303  }
304 
305  if (packName != "" && packUrl != "") {
306  m_provider.foundInPacks[packName] = packUrl;
307  }
308  }
309  }
310 
311 #ifdef DEBUG_PLUGIN_RDF_DESCRIPTION
312  SVCERR << "PluginRDFDescription::indexMetadata:" << endl;
313  SVCERR << " * id: " << m_pluginId << endl;
314  SVCERR << " * uri: <" << m_pluginUri << ">" << endl;
315  SVCERR << " * name: " << m_pluginName << endl;
316  SVCERR << " * description: " << m_pluginDescription << endl;
317  SVCERR << " * maker: " << m_pluginMaker << endl;
318  SVCERR << " * info url: <" << m_provider.infoUrl << ">" << endl;
319  SVCERR << " * download url: <" << m_provider.downloadUrl << ">" << endl;
320  SVCERR << " * download types:" << endl;
321  for (auto t: m_provider.downloadTypes) {
322  SVCERR << " * " << int(t) << endl;
323  }
324  SVCERR << " * packs:" << endl;
325  for (auto t: m_provider.foundInPacks) {
326  SVCERR << " * " << t.first
327  << ", download url: <" << t.second << ">" << endl;
328  }
329  SVCERR << endl;
330 #endif
331 
332  return true;
333 }
334 
335 bool
337 {
338  Profiler profiler("PluginRDFDescription::indexOutputs");
339 
341  const BasicStore *index = indexer->getIndex();
342  Uri plugin(m_pluginUri);
343 
344  Nodes outputs = index->match
345  (Triple(plugin, index->expand("vamp:output"), Node())).objects();
346 
347  if (outputs.empty()) {
348  SVDEBUG << "ERROR: PluginRDFDescription::indexURL: NOTE: No outputs defined for <"
349  << m_pluginUri << ">" << endl;
350  return false;
351  }
352 
353  foreach (Node output, outputs) {
354 
355  if ((output.type != Node::URI && output.type != Node::Blank) ||
356  output.value == "") {
357  SVDEBUG << "ERROR: PluginRDFDescription::indexURL: No valid URI for output " << output << " of plugin <" << m_pluginUri << ">" << endl;
358  return false;
359  }
360 
361  Node n = index->complete(Triple(output, index->expand("vamp:identifier"), Node()));
362  if (n.type != Node::Literal || n.value == "") {
363  SVDEBUG << "ERROR: PluginRDFDescription::indexURL: No vamp:identifier for output <" << output << ">" << endl;
364  return false;
365  }
366  QString outputId = n.value;
367 
368  m_outputUriMap[outputId] = output.value;
369 
370  n = index->complete(Triple(output, Uri("a"), Node()));
371  QString outputType;
372  if (n.type == Node::URI) outputType = n.value;
373 
374  n = index->complete(Triple(output, index->expand("vamp:unit"), Node()));
375  QString outputUnit;
376  if (n.type == Node::Literal) outputUnit = n.value;
377 
378  if (outputType.contains("DenseOutput")) {
379  m_outputDispositions[outputId] = OutputDense;
380  } else if (outputType.contains("SparseOutput")) {
382  } else if (outputType.contains("TrackLevelOutput")) {
384  } else {
386  }
387 // SVDEBUG << "output " << output << " -> id " << outputId << ", type " << outputType << ", unit "
388 // << outputUnit << ", disposition " << m_outputDispositions[outputId] << endl;
389 
390  if (outputUnit != "") {
391  m_outputUnitMap[outputId] = outputUnit;
392  }
393 
394  n = index->complete(Triple(output, index->expand("dc:title"), Node()));
395  if (n.type == Node::Literal && n.value != "") {
396  m_outputNames[outputId] = n.value;
397  }
398 
399  n = index->complete(Triple(output, index->expand("vamp:computes_event_type"), Node()));
400 // SVDEBUG << output << " -> computes_event_type " << n << endl;
401  if (n.type == Node::URI && n.value != "") {
402  m_outputEventTypeURIMap[outputId] = n.value;
403  }
404 
405  n = index->complete(Triple(output, index->expand("vamp:computes_feature"), Node()));
406  if (n.type == Node::URI && n.value != "") {
407  m_outputFeatureAttributeURIMap[outputId] = n.value;
408  }
409 
410  n = index->complete(Triple(output, index->expand("vamp:computes_signal_type"), Node()));
411  if (n.type == Node::URI && n.value != "") {
412  m_outputSignalTypeURIMap[outputId] = n.value;
413  }
414  }
415 
416  return true;
417 }
418 
QString getURIForPluginId(QString pluginId)
OutputStringMap m_outputSignalTypeURIMap
Provider getPluginProvider() const
OutputStringMap m_outputNames
QString getOutputName(QString outputId) const
QStringList getOutputIds() const
QString getOutputUnit(QString outputId) const
QString getOutputFeatureAttributeURI(QString outputId) const
QString getOutputSignalTypeURI(QString outputId) const
const Dataquay::BasicStore * getIndex()
QString getPluginDescription() const
std::map< QString, QString > foundInPacks
Definition: Provider.h:37
OutputDispositionMap m_outputDispositions
OutputDisposition getOutputDisposition(QString outputId) const
std::set< DownloadType > downloadTypes
Definition: Provider.h:35
QString getOutputEventTypeURI(QString outputId) const
QString getPluginMaker() const
#define SVDEBUG
Definition: Debug.h:106
QString getPluginName() const
#define SVCERR
Definition: Debug.h:109
OutputStringMap m_outputEventTypeURIMap
OutputStringMap m_outputUnitMap
static PluginRDFIndexer * getInstance()
QString downloadUrl
Definition: Provider.h:25
OutputStringMap m_outputFeatureAttributeURIMap
QString getOutputUri(QString outputId) const
OutputStringMap m_outputUriMap
QString infoUrl
Definition: Provider.h:24
Profile point instance class.
Definition: Profiler.h:93