Mercurial > hg > svcore
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 |