comparison 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
comparison
equal deleted inserted replaced
439:beb2948baa77 440:5746c559af15
16 #include "RDFTransformFactory.h" 16 #include "RDFTransformFactory.h"
17 17
18 #include <map> 18 #include <map>
19 #include <vector> 19 #include <vector>
20 20
21 #include <redland.h>
22 #include <rasqal.h>
23
24 #include <iostream> 21 #include <iostream>
25 #include <cmath> 22 #include <cmath>
26 23
27 #include "SimpleSPARQLQuery.h" 24 #include "SimpleSPARQLQuery.h"
28 #include "PluginRDFIndexer.h" 25 #include "PluginRDFIndexer.h"
48 std::vector<Transform> getTransforms(ProgressReporter *); 45 std::vector<Transform> getTransforms(ProgressReporter *);
49 46
50 protected: 47 protected:
51 QString m_urlString; 48 QString m_urlString;
52 QString m_errorString; 49 QString m_errorString;
50 bool setOutput(Transform &, QString, QString);
51 bool setParameters(Transform &, QString, QString);
53 }; 52 };
54 53
55 54
56 QString 55 QString
57 RDFTransformFactory::getKnownExtensions() 56 RDFTransformFactory::getKnownExtensions()
111 std::vector<Transform> 110 std::vector<Transform>
112 RDFTransformFactoryImpl::getTransforms(ProgressReporter *reporter) 111 RDFTransformFactoryImpl::getTransforms(ProgressReporter *reporter)
113 { 112 {
114 std::vector<Transform> transforms; 113 std::vector<Transform> transforms;
115 114
116 SimpleSPARQLQuery query 115 // We have to do this a very long way round, to work around
116 // rasqal's current inability to handle correctly more than one
117 // OPTIONAL graph in a query
118
119 const char *optionals[] = {
120 "output",
121 "program",
122 "step_size",
123 "block_size",
124 "window_type",
125 "sample_rate",
126 "start",
127 "duration"
128 };
129
130 std::map<QString, Transform> uriTransformMap;
131
132 QString queryTemplate =
133 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
134
135 " SELECT ?transform ?plugin %1 "
136
137 " FROM <%2> "
138
139 " WHERE { "
140 " ?transform a vamp:Transform ; "
141 " vamp:plugin ?plugin . "
142 " %3 "
143 " } ";
144
145 SimpleSPARQLQuery transformsQuery
146 (queryTemplate.arg("").arg(m_urlString).arg(""));
147
148 SimpleSPARQLQuery::ResultList transformResults = transformsQuery.execute();
149
150 if (!transformsQuery.isOK()) {
151 m_errorString = transformsQuery.getErrorString();
152 return transforms;
153 }
154
155 if (transformResults.empty()) {
156 cerr << "RDFTransformFactory: NOTE: No RDF/TTL transform descriptions found in document at <" << m_urlString.toStdString() << ">" << endl;
157 return transforms;
158 }
159
160 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance();
161
162 for (int i = 0; i < transformResults.size(); ++i) {
163
164 SimpleSPARQLQuery::KeyValueMap &result = transformResults[i];
165
166 QString transformUri = result["transform"].value;
167 QString pluginUri = result["plugin"].value;
168
169 QString pluginId = indexer->getIdForPluginURI(pluginUri);
170 if (pluginId == "") {
171 cerr << "RDFTransformFactory: WARNING: Unknown plugin <"
172 << pluginUri.toStdString() << "> for transform <"
173 << transformUri.toStdString() << ">, skipping this transform"
174 << endl;
175 continue;
176 }
177
178 QString pluginDescriptionURL =
179 indexer->getDescriptionURLForPluginId(pluginId);
180 if (pluginDescriptionURL == "") {
181 cerr << "RDFTransformFactory: WARNING: No RDF description available for plugin <"
182 << pluginUri.toStdString() << ">, skipping transform <"
183 << transformUri.toStdString() << ">" << endl;
184 continue;
185 }
186
187 Transform transform;
188 transform.setPluginIdentifier(pluginId);
189
190 if (!setOutput(transform, transformUri, pluginDescriptionURL)) {
191 return transforms;
192 }
193
194 if (!setParameters(transform, transformUri, pluginDescriptionURL)) {
195 return transforms;
196 }
197
198 uriTransformMap[transformUri] = transform;
199 }
200
201 for (int i = 0; i < sizeof(optionals)/sizeof(optionals[0]); ++i) {
202
203 QString optional = optionals[i];
204
205 SimpleSPARQLQuery query
206 (queryTemplate
207 .arg(QString("?%1").arg(optional))
208 .arg(m_urlString)
209 .arg(QString("?transform vamp:%1 ?%2")
210 .arg(optionals[i]).arg(optional)));
211
212 SimpleSPARQLQuery::ResultList results = query.execute();
213
214 if (!query.isOK()) {
215 m_errorString = query.getErrorString();
216 return transforms;
217 }
218
219 if (results.empty()) continue;
220
221 for (int j = 0; j < results.size(); ++j) {
222
223 QString transformUri = results[j]["transform"].value;
224
225 if (uriTransformMap.find(transformUri) == uriTransformMap.end()) {
226 cerr << "RDFTransformFactory: ERROR: Transform URI <"
227 << transformUri.toStdString() << "> not found in internal map!" << endl;
228 continue;
229 }
230
231 Transform &transform = uriTransformMap[transformUri];
232 const SimpleSPARQLQuery::Value &v = results[j][optional];
233
234 if (v.type == SimpleSPARQLQuery::LiteralValue) {
235
236 if (optional == "program") {
237 transform.setProgram(v.value);
238 } else if (optional == "step_size") {
239 transform.setStepSize(v.value.toUInt());
240 } else if (optional == "block_size") {
241 transform.setBlockSize(v.value.toUInt());
242 } else if (optional == "window_type") {
243 cerr << "NOTE: can't handle window type yet (value is \""
244 << v.value.toStdString() << "\")" << endl;
245 } else if (optional == "sample_rate") {
246 transform.setSampleRate(v.value.toFloat());
247 } else if (optional == "start") {
248 transform.setStartTime
249 (RealTime::fromXsdDuration(v.value.toStdString()));
250 } else if (optional == "duration") {
251 transform.setDuration
252 (RealTime::fromXsdDuration(v.value.toStdString()));
253 } else {
254 cerr << "RDFTransformFactory: ERROR: Inconsistent optionals lists (unexpected optional \"" << optional.toStdString() << "\"" << endl;
255 }
256 }
257 }
258 }
259
260 for (std::map<QString, Transform>::iterator i = uriTransformMap.begin();
261 i != uriTransformMap.end(); ++i) {
262
263 Transform &transform = i->second;
264
265 cerr << "RDFTransformFactory: NOTE: Transform is: " << endl;
266 cerr << transform.toXmlString().toStdString() << endl;
267
268 transforms.push_back(transform);
269 }
270
271 return transforms;
272 }
273
274 bool
275 RDFTransformFactoryImpl::setOutput(Transform &transform,
276 QString transformUri,
277 QString pluginDescriptionURL)
278 {
279 SimpleSPARQLQuery outputQuery
117 (QString 280 (QString
118 ( 281 (
119 " PREFIX vamp: <http://purl.org/ontology/vamp/> " 282 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
120 283
121 " SELECT ?transform ?plugin ?output ?program " 284 " SELECT ?output_id "
122 " ?step_size ?block_size ?window_type " 285
123 " ?sample_rate ?start ?duration "
124
125 " FROM <%1> " 286 " FROM <%1> "
126 287 " FROM <%2> "
288
127 " WHERE { " 289 " WHERE { "
128 " ?transform a vamp:Transform ; " 290 " <%3> vamp:output ?output . "
129 " vamp:plugin ?plugin . " 291 " ?output vamp:identifier ?output_id "
130 " OPTIONAL { ?transform vamp:output ?output } . "
131 " OPTIONAL { ?transform vamp:program ?program } . "
132 " OPTIONAL { ?transform vamp:step_size ?step_size } . "
133 " OPTIONAL { ?transform vamp:block_size ?block_size } . "
134 " OPTIONAL { ?transform vamp:window_type ?window_type } . "
135 " OPTIONAL { ?transform vamp:sample_rate ?sample_rate } . "
136 " OPTIONAL { ?transform vamp:start ?start } . "
137 " OPTIONAL { ?transform vamp:duration ?duration } "
138 " } " 292 " } "
139 ) 293 )
140 .arg(m_urlString)); 294 .arg(m_urlString)
141 295 .arg(pluginDescriptionURL)
142 SimpleSPARQLQuery::ResultList results = query.execute(); 296 .arg(transformUri));
143 297
144 if (!query.isOK()) { 298 SimpleSPARQLQuery::ResultList outputResults = outputQuery.execute();
145 m_errorString = query.getErrorString(); 299
146 return transforms; 300 if (!outputQuery.isOK()) {
147 } 301 m_errorString = outputQuery.getErrorString();
148 302 return false;
149 if (query.wasCancelled()) { 303 }
304
305 if (outputQuery.wasCancelled()) {
150 m_errorString = "Query cancelled"; 306 m_errorString = "Query cancelled";
151 return transforms; 307 return false;
152 } 308 }
153 309
154 PluginRDFIndexer *indexer = PluginRDFIndexer::getInstance(); 310 for (int j = 0; j < outputResults.size(); ++j) {
155 311 QString outputId = outputResults[j]["output_id"].value;
156 for (int i = 0; i < results.size(); ++i) { 312 transform.setOutput(outputId);
157 313 }
158 SimpleSPARQLQuery::KeyValueMap &result = results[i]; 314
159 315 return true;
160 QString transformUri = result["transform"].value; 316 }
161 QString pluginUri = result["plugin"].value; 317
162 318
163 QString pluginId = indexer->getIdForPluginURI(pluginUri); 319 bool
164 320 RDFTransformFactoryImpl::setParameters(Transform &transform,
165 if (pluginId == "") { 321 QString transformUri,
166 cerr << "RDFTransformFactory: WARNING: Unknown plugin <" 322 QString pluginDescriptionURL)
167 << pluginUri.toStdString() << "> for transform <" 323 {
168 << transformUri.toStdString() << ">" << endl; 324 SimpleSPARQLQuery paramQuery
169 continue; 325 (QString
170 } 326 (
171 327 " PREFIX vamp: <http://purl.org/ontology/vamp/> "
172 Transform transform; 328
173 transform.setPluginIdentifier(pluginId); 329 " SELECT ?param_id ?param_value "
174 330
175 if (result["output"].type == SimpleSPARQLQuery::LiteralValue) { 331 " FROM <%1> "
176 transform.setOutput(result["output"].value); 332 " FROM <%2> "
177 } 333
178 334 " WHERE { "
179 if (result["program"].type == SimpleSPARQLQuery::LiteralValue) { 335 " <%3> vamp:parameter_binding ?binding . "
180 transform.setProgram(result["program"].value); 336 " ?binding vamp:parameter ?param ; "
181 } 337 " vamp:value ?param_value . "
182 338 " ?param vamp:identifier ?param_id "
183 if (result["step_size"].type == SimpleSPARQLQuery::LiteralValue) { 339 " } "
184 transform.setStepSize(result["step_size"].value.toUInt()); 340 )
185 } 341 .arg(m_urlString)
186 342 .arg(pluginDescriptionURL)
187 if (result["block_size"].type == SimpleSPARQLQuery::LiteralValue) { 343 .arg(transformUri));
188 transform.setBlockSize(result["block_size"].value.toUInt()); 344
189 } 345 SimpleSPARQLQuery::ResultList paramResults = paramQuery.execute();
190 346
191 if (result["window_type"].type == SimpleSPARQLQuery::LiteralValue) { 347 if (!paramQuery.isOK()) {
192 cerr << "NOTE: can't handle window type yet (value is \"" 348 m_errorString = paramQuery.getErrorString();
193 << result["window_type"].value.toStdString() << "\")" << endl; 349 return false;
194 } 350 }
195 351
196 if (result["sample_rate"].type == SimpleSPARQLQuery::LiteralValue) { 352 if (paramQuery.wasCancelled()) {
197 transform.setStepSize(result["sample_rate"].value.toFloat()); 353 m_errorString = "Query cancelled";
198 } 354 return false;
199 355 }
200 if (result["start"].type == SimpleSPARQLQuery::LiteralValue) { 356
201 transform.setStartTime(RealTime::fromXsdDuration 357 for (int j = 0; j < paramResults.size(); ++j) {
202 (result["start"].value.toStdString())); 358
203 } 359 QString paramId = paramResults[j]["param_id"].value;
204 360 QString paramValue = paramResults[j]["param_value"].value;
205 if (result["duration"].type == SimpleSPARQLQuery::LiteralValue) { 361
206 transform.setDuration(RealTime::fromXsdDuration 362 if (paramId == "" || paramValue == "") continue;
207 (result["duration"].value.toStdString())); 363
208 } 364 transform.setParameter(paramId, paramValue.toFloat());
209 365 }
210 SimpleSPARQLQuery paramQuery 366
211 (QString 367 return true;
212 ( 368 }
213 " PREFIX vamp: <http://purl.org/ontology/vamp/> " 369
214
215 " SELECT ?param_id ?param_value "
216
217 " FROM <%1> "
218
219 " WHERE { "
220 " <%2> vamp:parameter ?param . "
221 " ?param vamp:identifier ?param_id ; "
222 " vamp:value ?param_value "
223 " } "
224 )
225 .arg(m_urlString)
226 .arg(transformUri));
227
228 SimpleSPARQLQuery::ResultList paramResults = paramQuery.execute();
229
230 if (!paramQuery.isOK()) {
231 m_errorString = paramQuery.getErrorString();
232 return transforms;
233 }
234
235 if (paramQuery.wasCancelled()) {
236 m_errorString = "Query cancelled";
237 return transforms;
238 }
239
240 for (int j = 0; j < paramResults.size(); ++j) {
241
242 QString paramId = paramResults[j]["param_id"].value;
243 QString paramValue = paramResults[j]["param_value"].value;
244
245 if (paramId == "" || paramValue == "") continue;
246
247 transform.setParameter(paramId, paramValue.toFloat());
248 }
249
250 cerr << "RDFTransformFactory: NOTE: Transform is: " << endl;
251 cerr << transform.toXmlString().toStdString() << endl;
252
253 transforms.push_back(transform);
254 }
255
256 return transforms;
257 }
258