View Javadoc

1   /*
2    * Copyright James Leigh (c) 2007.
3    *
4    * Licensed under the Aduna BSD-style license.
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   * Converts RDF Statements into a Query Object.
66   * 
67   * @author James Leigh
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 }