diff rdf/RDFTransformFactory.cpp @ 440:5746c559af15

* Merge revisions 1131 to 1201 from sv-rdf-import branch
author Chris Cannam
date Thu, 18 Sep 2008 12:33:30 +0000
parents beb2948baa77
children 3ffce691c9bf
line wrap: on
line diff
--- a/rdf/RDFTransformFactory.cpp	Thu Sep 18 12:09:32 2008 +0000
+++ b/rdf/RDFTransformFactory.cpp	Thu Sep 18 12:33:30 2008 +0000
@@ -18,9 +18,6 @@
 #include <map>
 #include <vector>
 
-#include <redland.h>
-#include <rasqal.h>
-
 #include <iostream>
 #include <cmath>
 
@@ -50,6 +47,8 @@
 protected:
     QString m_urlString;
     QString m_errorString;
+    bool setOutput(Transform &, QString, QString);
+    bool setParameters(Transform &, QString, QString);
 };
 
 
@@ -113,140 +112,156 @@
 {
     std::vector<Transform> transforms;
 
-    SimpleSPARQLQuery query
-        (QString
-         (
-             " PREFIX vamp: <http://purl.org/ontology/vamp/> "
+    // We have to do this a very long way round, to work around
+    // rasqal's current inability to handle correctly more than one
+    // OPTIONAL graph in a query
 
-             " SELECT ?transform ?plugin ?output ?program "
-             "        ?step_size ?block_size ?window_type "
-             "        ?sample_rate ?start ?duration "
+    const char *optionals[] = {
+        "output",
+        "program",
+        "step_size",
+        "block_size",
+        "window_type",
+        "sample_rate",
+        "start", 
+        "duration"
+    };
 
-             " FROM <%1> "
+    std::map<QString, Transform> uriTransformMap;
 
-             " WHERE { "
-             "   ?transform a vamp:Transform ; "
-             "              vamp:plugin ?plugin . "
-             "   OPTIONAL { ?transform vamp:output ?output } . "
-             "   OPTIONAL { ?transform vamp:program ?program } . "
-             "   OPTIONAL { ?transform vamp:step_size ?step_size } . "
-             "   OPTIONAL { ?transform vamp:block_size ?block_size } . "
-             "   OPTIONAL { ?transform vamp:window_type ?window_type } . "
-             "   OPTIONAL { ?transform vamp:sample_rate ?sample_rate } . "
-             "   OPTIONAL { ?transform vamp:start ?start } . "
-             "   OPTIONAL { ?transform vamp:duration ?duration } "
-             " } "
-             )
-         .arg(m_urlString));
+    QString queryTemplate = 
+        " PREFIX vamp: <http://purl.org/ontology/vamp/> "
 
-    SimpleSPARQLQuery::ResultList results = query.execute();
+        " SELECT ?transform ?plugin %1 "
+        
+        " FROM <%2> "
 
-    if (!query.isOK()) {
-        m_errorString = query.getErrorString();
+        " WHERE { "
+        "   ?transform a vamp:Transform ; "
+        "              vamp:plugin ?plugin . "
+        "   %3 "
+        " } ";
+
+    SimpleSPARQLQuery transformsQuery
+        (queryTemplate.arg("").arg(m_urlString).arg(""));
+
+    SimpleSPARQLQuery::ResultList transformResults = transformsQuery.execute();
+
+    if (!transformsQuery.isOK()) {
+        m_errorString = transformsQuery.getErrorString();
         return transforms;
     }
 
-    if (query.wasCancelled()) {
-        m_errorString = "Query cancelled";
+    if (transformResults.empty()) {
+        cerr << "RDFTransformFactory: NOTE: No RDF/TTL transform descriptions found in document at <" << m_urlString.toStdString() << ">" << endl;
         return transforms;
     }
 
     PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance();
 
-    for (int i = 0; i < results.size(); ++i) {
+    for (int i = 0; i < transformResults.size(); ++i) {
 
-        SimpleSPARQLQuery::KeyValueMap &result = results[i];
+        SimpleSPARQLQuery::KeyValueMap &result = transformResults[i];
 
         QString transformUri = result["transform"].value;
         QString pluginUri = result["plugin"].value;
 
         QString pluginId = indexer->getIdForPluginURI(pluginUri);
-
         if (pluginId == "") {
             cerr << "RDFTransformFactory: WARNING: Unknown plugin <"
                  << pluginUri.toStdString() << "> for transform <"
+                 << transformUri.toStdString() << ">, skipping this transform"
+                 << endl;
+            continue;
+        }
+
+        QString pluginDescriptionURL =
+            indexer->getDescriptionURLForPluginId(pluginId);
+        if (pluginDescriptionURL == "") {
+            cerr << "RDFTransformFactory: WARNING: No RDF description available for plugin <"
+                 << pluginUri.toStdString() << ">, skipping transform <"
                  << transformUri.toStdString() << ">" << endl;
             continue;
         }
 
         Transform transform;
         transform.setPluginIdentifier(pluginId);
-        
-        if (result["output"].type == SimpleSPARQLQuery::LiteralValue) {
-            transform.setOutput(result["output"].value);
-        }
 
-        if (result["program"].type == SimpleSPARQLQuery::LiteralValue) {
-            transform.setProgram(result["program"].value);
-        }
-        
-        if (result["step_size"].type == SimpleSPARQLQuery::LiteralValue) {
-            transform.setStepSize(result["step_size"].value.toUInt());
-        }
-        
-        if (result["block_size"].type == SimpleSPARQLQuery::LiteralValue) {
-            transform.setBlockSize(result["block_size"].value.toUInt());
-        }
-        
-        if (result["window_type"].type == SimpleSPARQLQuery::LiteralValue) {
-            cerr << "NOTE: can't handle window type yet (value is \""
-                 << result["window_type"].value.toStdString() << "\")" << endl;
-        }
-        
-        if (result["sample_rate"].type == SimpleSPARQLQuery::LiteralValue) {
-            transform.setStepSize(result["sample_rate"].value.toFloat());
-        }
-
-        if (result["start"].type == SimpleSPARQLQuery::LiteralValue) {
-            transform.setStartTime(RealTime::fromXsdDuration
-                                   (result["start"].value.toStdString()));
-        }
-
-        if (result["duration"].type == SimpleSPARQLQuery::LiteralValue) {
-            transform.setDuration(RealTime::fromXsdDuration
-                                  (result["duration"].value.toStdString()));
-        }
-
-        SimpleSPARQLQuery paramQuery
-            (QString
-             (
-                 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
-
-                 " SELECT ?param_id ?param_value "
-
-                 " FROM <%1> "
-
-                 " WHERE { "
-                 "   <%2> vamp:parameter ?param . "
-                 "   ?param vamp:identifier ?param_id ; "
-                 "          vamp:value ?param_value "
-                 " } "
-                 )
-             .arg(m_urlString)
-             .arg(transformUri));
-        
-        SimpleSPARQLQuery::ResultList paramResults = paramQuery.execute();
-
-        if (!paramQuery.isOK()) {
-            m_errorString = paramQuery.getErrorString();
+        if (!setOutput(transform, transformUri, pluginDescriptionURL)) {
             return transforms;
         }
 
-        if (paramQuery.wasCancelled()) {
-            m_errorString = "Query cancelled";
+        if (!setParameters(transform, transformUri, pluginDescriptionURL)) {
             return transforms;
         }
 
-        for (int j = 0; j < paramResults.size(); ++j) {
+        uriTransformMap[transformUri] = transform;
+    }
 
-            QString paramId = paramResults[j]["param_id"].value;
-            QString paramValue = paramResults[j]["param_value"].value;
+    for (int i = 0; i < sizeof(optionals)/sizeof(optionals[0]); ++i) {
 
-            if (paramId == "" || paramValue == "") continue;
+        QString optional = optionals[i];
 
-            transform.setParameter(paramId, paramValue.toFloat());
+        SimpleSPARQLQuery query
+            (queryTemplate
+             .arg(QString("?%1").arg(optional))
+             .arg(m_urlString)
+             .arg(QString("?transform vamp:%1 ?%2")
+                  .arg(optionals[i]).arg(optional)));
+        
+        SimpleSPARQLQuery::ResultList results = query.execute();
+
+        if (!query.isOK()) {
+            m_errorString = query.getErrorString();
+            return transforms;
         }
 
+        if (results.empty()) continue;
+
+        for (int j = 0; j < results.size(); ++j) {
+
+            QString transformUri = results[j]["transform"].value;
+            
+            if (uriTransformMap.find(transformUri) == uriTransformMap.end()) {
+                cerr << "RDFTransformFactory: ERROR: Transform URI <"
+                     << transformUri.toStdString() << "> not found in internal map!" << endl;
+                continue;
+            }
+
+            Transform &transform = uriTransformMap[transformUri];
+            const SimpleSPARQLQuery::Value &v = results[j][optional];
+
+            if (v.type == SimpleSPARQLQuery::LiteralValue) {
+                
+                if (optional == "program") {
+                    transform.setProgram(v.value);
+                } else if (optional == "step_size") {
+                    transform.setStepSize(v.value.toUInt());
+                } else if (optional == "block_size") {
+                    transform.setBlockSize(v.value.toUInt());
+                } else if (optional == "window_type") {
+                    cerr << "NOTE: can't handle window type yet (value is \""
+                         << v.value.toStdString() << "\")" << endl;
+                } else if (optional == "sample_rate") {
+                    transform.setSampleRate(v.value.toFloat());
+                } else if (optional == "start") {
+                    transform.setStartTime
+                        (RealTime::fromXsdDuration(v.value.toStdString()));
+                } else if (optional == "duration") {
+                    transform.setDuration
+                        (RealTime::fromXsdDuration(v.value.toStdString()));
+                } else {
+                    cerr << "RDFTransformFactory: ERROR: Inconsistent optionals lists (unexpected optional \"" << optional.toStdString() << "\"" << endl;
+                }
+            }
+        }
+    }
+
+    for (std::map<QString, Transform>::iterator i = uriTransformMap.begin();
+         i != uriTransformMap.end(); ++i) {
+
+        Transform &transform = i->second;
+
         cerr << "RDFTransformFactory: NOTE: Transform is: " << endl;
         cerr << transform.toXmlString().toStdString() << endl;
 
@@ -256,3 +271,99 @@
     return transforms;
 }
 
+bool
+RDFTransformFactoryImpl::setOutput(Transform &transform,
+                                   QString transformUri,
+                                   QString pluginDescriptionURL)
+{
+    SimpleSPARQLQuery outputQuery
+        (QString
+         (
+             " PREFIX vamp: <http://purl.org/ontology/vamp/> "
+             
+             " SELECT ?output_id "
+             
+             " FROM <%1> "
+             " FROM <%2> "
+             
+             " WHERE { "
+             "   <%3> vamp:output ?output . "
+             "   ?output vamp:identifier ?output_id "
+             " } "
+             )
+         .arg(m_urlString)
+         .arg(pluginDescriptionURL)
+         .arg(transformUri));
+    
+    SimpleSPARQLQuery::ResultList outputResults = outputQuery.execute();
+    
+    if (!outputQuery.isOK()) {
+        m_errorString = outputQuery.getErrorString();
+        return false;
+    }
+    
+    if (outputQuery.wasCancelled()) {
+        m_errorString = "Query cancelled";
+        return false;
+    }
+    
+    for (int j = 0; j < outputResults.size(); ++j) {
+        QString outputId = outputResults[j]["output_id"].value;
+        transform.setOutput(outputId);
+    }
+
+    return true;
+}
+        
+
+bool
+RDFTransformFactoryImpl::setParameters(Transform &transform,
+                                       QString transformUri,
+                                       QString pluginDescriptionURL)
+{
+    SimpleSPARQLQuery paramQuery
+        (QString
+         (
+             " PREFIX vamp: <http://purl.org/ontology/vamp/> "
+             
+             " SELECT ?param_id ?param_value "
+             
+             " FROM <%1> "
+             " FROM <%2> "
+             
+             " WHERE { "
+             "   <%3> vamp:parameter_binding ?binding . "
+             "   ?binding vamp:parameter ?param ; "
+             "            vamp:value ?param_value . "
+             "   ?param vamp:identifier ?param_id "
+             " } "
+             )
+         .arg(m_urlString)
+         .arg(pluginDescriptionURL)
+         .arg(transformUri));
+    
+    SimpleSPARQLQuery::ResultList paramResults = paramQuery.execute();
+    
+    if (!paramQuery.isOK()) {
+        m_errorString = paramQuery.getErrorString();
+        return false;
+    }
+    
+    if (paramQuery.wasCancelled()) {
+        m_errorString = "Query cancelled";
+        return false;
+    }
+    
+    for (int j = 0; j < paramResults.size(); ++j) {
+        
+        QString paramId = paramResults[j]["param_id"].value;
+        QString paramValue = paramResults[j]["param_value"].value;
+        
+        if (paramId == "" || paramValue == "") continue;
+        
+        transform.setParameter(paramId, paramValue.toFloat());
+    }
+
+    return true;
+}
+