1
2
3
4
5
6 package org.openrdf.query.parser.serqo;
7
8 import java.lang.reflect.UndeclaredThrowableException;
9 import java.util.ArrayList;
10 import java.util.Collection;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14
15 import org.openrdf.model.Literal;
16 import org.openrdf.model.Resource;
17 import org.openrdf.model.Statement;
18 import org.openrdf.model.URI;
19 import org.openrdf.model.Value;
20 import org.openrdf.model.vocabulary.RDF;
21 import org.openrdf.query.MalformedQueryException;
22 import org.openrdf.query.algebra.AggregateOperator;
23 import org.openrdf.query.algebra.BinaryTupleOperator;
24 import org.openrdf.query.algebra.BinaryValueOperator;
25 import org.openrdf.query.algebra.Compare;
26 import org.openrdf.query.algebra.CompareAll;
27 import org.openrdf.query.algebra.CompareAny;
28 import org.openrdf.query.algebra.CompareSubQueryValueOperator;
29 import org.openrdf.query.algebra.Extension;
30 import org.openrdf.query.algebra.ExtensionElem;
31 import org.openrdf.query.algebra.Filter;
32 import org.openrdf.query.algebra.FunctionCall;
33 import org.openrdf.query.algebra.Group;
34 import org.openrdf.query.algebra.GroupElem;
35 import org.openrdf.query.algebra.LeftJoin;
36 import org.openrdf.query.algebra.Like;
37 import org.openrdf.query.algebra.MathExpr;
38 import org.openrdf.query.algebra.MultiProjection;
39 import org.openrdf.query.algebra.Order;
40 import org.openrdf.query.algebra.OrderElem;
41 import org.openrdf.query.algebra.Projection;
42 import org.openrdf.query.algebra.ProjectionElem;
43 import org.openrdf.query.algebra.ProjectionElemList;
44 import org.openrdf.query.algebra.QueryModelNode;
45 import org.openrdf.query.algebra.Regex;
46 import org.openrdf.query.algebra.Slice;
47 import org.openrdf.query.algebra.StatementPattern;
48 import org.openrdf.query.algebra.SubQueryValueOperator;
49 import org.openrdf.query.algebra.TupleExpr;
50 import org.openrdf.query.algebra.UnaryTupleOperator;
51 import org.openrdf.query.algebra.UnaryValueOperator;
52 import org.openrdf.query.algebra.ValueConstant;
53 import org.openrdf.query.algebra.ValueExpr;
54 import org.openrdf.query.algebra.Var;
55 import org.openrdf.query.algebra.Compare.CompareOp;
56 import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
57 import org.openrdf.query.parser.ParsedGraphQuery;
58 import org.openrdf.query.parser.ParsedQuery;
59 import org.openrdf.query.parser.ParsedTupleQuery;
60 import org.openrdf.rio.RDFHandler;
61 import org.openrdf.rio.RDFHandlerException;
62 import org.openrdf.rio.helpers.StatementCollector;
63
64
65
66
67
68
69
70 @SuppressWarnings("unchecked")
71 public class SeRQOHandler extends QueryModelVisitorBase<RuntimeException>
72 implements RDFHandler {
73
74 private Map<Resource, Object> model;
75
76 private Value object;
77
78 private URI predicate;
79
80 private ParsedQuery query;
81
82 private StatementCollector statements;
83
84 public ParsedQuery getQuery() {
85 return query;
86 }
87
88 public void startRDF() throws RDFHandlerException {
89 init();
90 statements.startRDF();
91 }
92
93 public void handleStatement(Statement st) throws RDFHandlerException {
94 Resource subj = st.getSubject();
95 URI pred = st.getPredicate();
96 Value obj = st.getObject();
97 if (pred.equals(RDF.TYPE)) {
98 Object o;
99 if (obj.equals(SeRQO.TUPLEQUERY)) {
100 o = query = new ParsedTupleQuery();
101 } else if (obj.equals(SeRQO.GRAPHQUERY)) {
102 o = query = new ParsedGraphQuery(statements.getNamespaces());
103 } else if (obj.equals(RDF.SEQ)) {
104 o = new ArrayList();
105 } else {
106 o = createNode((URI) obj);
107 }
108 model.put(subj, o);
109 } else {
110 statements.handleStatement(st);
111 }
112 }
113
114 public void endRDF() throws RDFHandlerException {
115 statements.endRDF();
116 try {
117 digest(statements.getStatements());
118 } catch (UndeclaredThrowableException e) {
119 try {
120 throw e.getCause();
121 } catch (Exception e1) {
122 throw new RDFHandlerException(e1);
123 } catch (Throwable e1) {
124 throw e;
125 }
126 }
127 }
128
129 public void handleComment(String comment) throws RDFHandlerException {
130 statements.handleComment(comment);
131 }
132
133 public void handleNamespace(String prefix, String uri)
134 throws RDFHandlerException {
135 statements.handleNamespace(prefix, uri);
136 }
137
138 @Override
139 public void meet(Compare node) {
140 if (predicate.equals(SeRQO.OPERATOR)) {
141 Literal lit = (Literal) object;
142 node.setOperator(CompareOp.valueOf(lit.getLabel()));
143 } else {
144 super.meet(node);
145 }
146 }
147
148 @Override
149 public void meet(CompareAll node) {
150 if (predicate.equals(SeRQO.OPERATOR)) {
151 Literal lit = (Literal) object;
152 node.setOperator(CompareOp.valueOf(lit.getLabel()));
153 } else {
154 super.meet(node);
155 }
156 }
157
158 @Override
159 public void meet(CompareAny node) {
160 if (predicate.equals(SeRQO.OPERATOR)) {
161 Literal lit = (Literal) object;
162 node.setOperator(CompareOp.valueOf(lit.getLabel()));
163 } else {
164 super.meet(node);
165 }
166 }
167
168 @Override
169 public void meet(Extension node) {
170 if (predicate.equals(SeRQO.ELEMENTS)) {
171 node.setElements((List) model.get(object));
172 } else {
173 super.meet(node);
174 }
175 }
176
177 @Override
178 public void meet(ExtensionElem node) {
179 if (predicate.equals(SeRQO.NAME)) {
180 Literal lit = (Literal) object;
181 node.setName(lit.getLabel());
182 } else if (predicate.equals(SeRQO.ARG)) {
183 node.setExpr((ValueExpr) model.get(object));
184 } else {
185 super.meet(node);
186 }
187 }
188
189 @Override
190 public void meet(FunctionCall node) {
191 if (predicate.equals(SeRQO.ARGS)) {
192 node.setArgs((List) model.get(object));
193 } else if (predicate.equals(SeRQO.URI)) {
194 Literal lit = (Literal) object;
195 node.setURI(lit.getLabel());
196 } else {
197 super.meet(node);
198 }
199 }
200
201 @Override
202 public void meet(Group node) {
203 if (predicate.equals(SeRQO.GROUPNAMES)) {
204 node.setGroupBindingNames((List<String>) model.get(object));
205 } else if (predicate.equals(SeRQO.ELEMENTS)) {
206 node.setGroupElements((List<GroupElem>) model.get(object));
207 } else {
208 super.meet(node);
209 }
210 }
211
212 @Override
213 public void meet(GroupElem node) {
214 if (predicate.equals(SeRQO.NAME)) {
215 Literal lit = (Literal) object;
216 node.setName(lit.getLabel());
217 } else if (predicate.equals(SeRQO.OPERATOR)) {
218 node.setOperator((AggregateOperator) model.get(object));
219 } else {
220 super.meet(node);
221 }
222 }
223
224 @Override
225 public void meet(Like node) {
226 if (predicate.equals(SeRQO.PATTERN)) {
227 Literal lit = (Literal) object;
228 node.setPattern(lit.getLabel(), node.isCaseSensitive());
229 } else if (predicate.equals(SeRQO.CASESENSITIVE)) {
230 Literal lit = (Literal) object;
231 node.setPattern(node.getPattern(), lit.booleanValue());
232 } else {
233 super.meet(node);
234 }
235 }
236
237 @Override
238 public void meet(MathExpr node) {
239 if (predicate.equals(SeRQO.OPERATOR)) {
240 Literal lit = (Literal) object;
241 node.setOperator(MathExpr.MathOp.valueOf(lit.getLabel()));
242 } else {
243 super.meet(node);
244 }
245 }
246
247 @Override
248 public void meet(Order node) {
249 if (predicate.equals(SeRQO.ELEMENTS)) {
250 node.setElements((List) model.get(object));
251 } else {
252 super.meet(node);
253 }
254 }
255
256 @Override
257 public void meet(OrderElem node) {
258 if (predicate.equals(SeRQO.ASC)) {
259 Literal lit = (Literal) object;
260 node.setAscending(lit.booleanValue());
261 } else if (predicate.equals(SeRQO.ARG)) {
262 node.setExpr((ValueExpr) model.get(object));
263 } else {
264 super.meet(node);
265 }
266 }
267
268 @Override
269 public void meet(LeftJoin node) {
270 if (predicate.equals(SeRQO.CONDITION)) {
271 node.setCondition((ValueExpr) model.get(object));
272 } else {
273 super.meet(node);
274 }
275 }
276
277 @Override
278 public void meet(MultiProjection node) {
279 if (predicate.equals(SeRQO.ELEMENTS)) {
280 node.setProjections((List<ProjectionElemList>) model.get(object));
281 } else {
282 super.meet(node);
283 }
284 }
285
286 @Override
287 public void meet(Projection node) {
288 if (predicate.equals(SeRQO.ELEMENT)) {
289 node.setProjectionElemList((ProjectionElemList) model.get(object));
290 } else {
291 super.meet(node);
292 }
293 }
294
295 @Override
296 public void meet(ProjectionElemList node) {
297 if (predicate.equals(SeRQO.ELEMENTS)) {
298 node.setElements((List<ProjectionElem>) model.get(object));
299 } else {
300 super.meet(node);
301 }
302 }
303
304 @Override
305 public void meet(ProjectionElem node) {
306 if (predicate.equals(SeRQO.SOURCENAME)) {
307 Literal lit = (Literal) object;
308 node.setSourceName(lit.getLabel());
309 } else if (predicate.equals(SeRQO.TARGETNAME)) {
310 Literal lit = (Literal) object;
311 node.setTargetName(lit.getLabel());
312 } else {
313 super.meet(node);
314 }
315 }
316
317 @Override
318 public void meet(Regex node) {
319 if (predicate.equals(SeRQO.FLAGS)) {
320 node.setFlagsArg((ValueExpr) model.get(object));
321 } else {
322 super.meet(node);
323 }
324 }
325
326 @Override
327 public void meet(Slice node) {
328 if (predicate.equals(SeRQO.LIMIT)) {
329 Literal lit = (Literal) object;
330 node.setLimit(lit.intValue());
331 } else if (predicate.equals(SeRQO.OFFSET)) {
332 Literal lit = (Literal) object;
333 node.setOffset(lit.intValue());
334 } else {
335 super.meet(node);
336 }
337 }
338
339 @Override
340 public void meet(Filter node) {
341 if (predicate.equals(SeRQO.CONDITION)) {
342 node.setCondition((ValueExpr) model.get(object));
343 } else {
344 super.meet(node);
345 }
346 }
347
348 @Override
349 public void meet(StatementPattern node) {
350 if (predicate.equals(SeRQO.SCOPE)) {
351 Literal lit = (Literal) object;
352 node.setScope(StatementPattern.Scope.valueOf(lit.getLabel()));
353 } else if (predicate.equals(SeRQO.SUBJECTVAR)) {
354 node.setSubjectVar((Var) model.get(object));
355 } else if (predicate.equals(SeRQO.PREDICATEVAR)) {
356 node.setPredicateVar((Var) model.get(object));
357 } else if (predicate.equals(SeRQO.OBJECTVAR)) {
358 node.setObjectVar((Var) model.get(object));
359 } else if (predicate.equals(SeRQO.CONTEXTVAR)) {
360 node.setContextVar((Var) model.get(object));
361 } else {
362 super.meet(node);
363 }
364 }
365
366 @Override
367 public void meet(ValueConstant node) {
368 if (predicate.equals(SeRQO.VALUE)) {
369 node.setValue(object);
370 } else {
371 super.meet(node);
372 }
373 }
374
375 @Override
376 public void meet(Var node) {
377 if (predicate.equals(SeRQO.NAME)) {
378 Literal lit = (Literal) object;
379 node.setName(lit.getLabel());
380 } else if (predicate.equals(SeRQO.VALUE)) {
381 node.setValue(object);
382 } else {
383 super.meet(node);
384 }
385 }
386
387 @Override
388 protected void meetBinaryTupleOperator(BinaryTupleOperator node) {
389 if (predicate.equals(SeRQO.LEFTARG)) {
390 node.setLeftArg((TupleExpr) model.get(object));
391 } else if (predicate.equals(SeRQO.RIGHTARG)) {
392 node.setRightArg((TupleExpr) model.get(object));
393 } else {
394 super.meetBinaryTupleOperator(node);
395 }
396 }
397
398 @Override
399 protected void meetBinaryValueOperator(BinaryValueOperator node) {
400 if (predicate.equals(SeRQO.LEFTARG)) {
401 node.setLeftArg((ValueExpr) model.get(object));
402 } else if (predicate.equals(SeRQO.RIGHTARG)) {
403 node.setRightArg((ValueExpr) model.get(object));
404 } else {
405 super.meetBinaryValueOperator(node);
406 }
407 }
408
409 @Override
410 protected void meetCompareSubQueryValueOperator(
411 CompareSubQueryValueOperator node) {
412 if (predicate.equals(SeRQO.ARG)) {
413 node.setArg((ValueExpr) model.get(object));
414 } else {
415 super.meetCompareSubQueryValueOperator(node);
416 }
417 }
418
419 @Override
420 protected void meetNode(QueryModelNode node) {
421 MalformedQueryException initCause;
422 String msg = "Unknown statement: " + predicate + " " + object;
423 initCause = new MalformedQueryException(msg);
424 throw new UndeclaredThrowableException(initCause);
425 }
426
427 @Override
428 protected void meetSubQueryValueOperator(SubQueryValueOperator node) {
429 if (predicate.equals(SeRQO.SUBQUERY)) {
430 node.setSubQuery((TupleExpr) model.get(object));
431 } else {
432 super.meetSubQueryValueOperator(node);
433 }
434 }
435
436 @Override
437 protected void meetUnaryTupleOperator(UnaryTupleOperator node) {
438 if (predicate.equals(SeRQO.ARG)) {
439 node.setArg((TupleExpr) model.get(object));
440 } else {
441 super.meetUnaryTupleOperator(node);
442 }
443 }
444
445 @Override
446 protected void meetUnaryValueOperator(UnaryValueOperator node) {
447 if (predicate.equals(SeRQO.ARG)) {
448 node.setArg((ValueExpr) model.get(object));
449 } else {
450 super.meetUnaryValueOperator(node);
451 }
452 }
453
454 private QueryModelNode createNode(URI uri) {
455 assert uri.getNamespace().equals(SeRQO.NAMESPACE_URL);
456 String pkg = QueryModelNode.class.getPackage().getName();
457 String name = pkg + '.' + uri.getLocalName();
458 try {
459 Class type = Class.forName(name);
460 return (QueryModelNode) type.newInstance();
461 } catch (Exception e) {
462 throw new UndeclaredThrowableException(e);
463 }
464 }
465
466 private void digest(Collection<Statement> statements) {
467 for (Statement st : statements) {
468 predicate = st.getPredicate();
469 object = st.getObject();
470 Object o = model.get(st.getSubject());
471 if (o instanceof ParsedQuery) {
472 meetQuery((ParsedQuery) o);
473 } else if (o instanceof List) {
474 meetList((List) o);
475 } else {
476 assert o instanceof QueryModelNode;
477 QueryModelNode node = (QueryModelNode) o;
478 node.visit(this);
479 }
480 }
481 }
482
483 private void init() {
484 query = null;
485 model = new HashMap<Resource, Object>();
486 statements = new StatementCollector();
487 }
488
489 private void meetList(List list) {
490 String ln = predicate.getLocalName();
491 assert predicate.getNamespace().equals(RDF.NAMESPACE);
492 assert ln.startsWith("_");
493 int i = Integer.parseInt(ln.substring(1)) - 1;
494 Object o = model.get(object);
495 if (i == list.size()) {
496 list.add(o);
497 } else if (i < list.size()) {
498 list.set(i, o);
499 } else {
500 while (i > list.size())
501 list.add(null);
502 list.add(o);
503 }
504 }
505
506 private void meetQuery(ParsedQuery node) {
507 assert predicate.equals(SeRQO.TUPLEEXPR);
508 node.setTupleExpr((TupleExpr) model.get(object));
509 }
510
511 }