001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2007.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.query.parser.serql;
007:
008: import java.util.ArrayList;
009: import java.util.Iterator;
010: import java.util.List;
011:
012: import org.openrdf.model.Literal;
013: import org.openrdf.model.URI;
014: import org.openrdf.model.Value;
015: import org.openrdf.model.ValueFactory;
016: import org.openrdf.model.vocabulary.RDF;
017: import org.openrdf.query.MalformedQueryException;
018: import org.openrdf.query.algebra.And;
019: import org.openrdf.query.algebra.Bound;
020: import org.openrdf.query.algebra.Compare;
021: import org.openrdf.query.algebra.CompareAll;
022: import org.openrdf.query.algebra.CompareAny;
023: import org.openrdf.query.algebra.Datatype;
024: import org.openrdf.query.algebra.Difference;
025: import org.openrdf.query.algebra.Distinct;
026: import org.openrdf.query.algebra.Exists;
027: import org.openrdf.query.algebra.Extension;
028: import org.openrdf.query.algebra.ExtensionElem;
029: import org.openrdf.query.algebra.FunctionCall;
030: import org.openrdf.query.algebra.In;
031: import org.openrdf.query.algebra.Intersection;
032: import org.openrdf.query.algebra.IsBNode;
033: import org.openrdf.query.algebra.IsLiteral;
034: import org.openrdf.query.algebra.IsResource;
035: import org.openrdf.query.algebra.IsURI;
036: import org.openrdf.query.algebra.Label;
037: import org.openrdf.query.algebra.Lang;
038: import org.openrdf.query.algebra.Like;
039: import org.openrdf.query.algebra.LocalName;
040: import org.openrdf.query.algebra.Namespace;
041: import org.openrdf.query.algebra.Not;
042: import org.openrdf.query.algebra.Or;
043: import org.openrdf.query.algebra.Projection;
044: import org.openrdf.query.algebra.ProjectionElem;
045: import org.openrdf.query.algebra.ProjectionElemList;
046: import org.openrdf.query.algebra.SameTerm;
047: import org.openrdf.query.algebra.SingletonSet;
048: import org.openrdf.query.algebra.Slice;
049: import org.openrdf.query.algebra.StatementPattern;
050: import org.openrdf.query.algebra.TupleExpr;
051: import org.openrdf.query.algebra.Union;
052: import org.openrdf.query.algebra.ValueConstant;
053: import org.openrdf.query.algebra.ValueExpr;
054: import org.openrdf.query.algebra.Var;
055: import org.openrdf.query.algebra.Compare.CompareOp;
056: import org.openrdf.query.parser.serql.ast.ASTAnd;
057: import org.openrdf.query.parser.serql.ast.ASTBNode;
058: import org.openrdf.query.parser.serql.ast.ASTBasicPathExpr;
059: import org.openrdf.query.parser.serql.ast.ASTBasicPathExprTail;
060: import org.openrdf.query.parser.serql.ast.ASTBooleanConstant;
061: import org.openrdf.query.parser.serql.ast.ASTBooleanExpr;
062: import org.openrdf.query.parser.serql.ast.ASTBound;
063: import org.openrdf.query.parser.serql.ast.ASTCompare;
064: import org.openrdf.query.parser.serql.ast.ASTCompareAll;
065: import org.openrdf.query.parser.serql.ast.ASTCompareAny;
066: import org.openrdf.query.parser.serql.ast.ASTConstruct;
067: import org.openrdf.query.parser.serql.ast.ASTConstructQuery;
068: import org.openrdf.query.parser.serql.ast.ASTDatatype;
069: import org.openrdf.query.parser.serql.ast.ASTEdge;
070: import org.openrdf.query.parser.serql.ast.ASTExists;
071: import org.openrdf.query.parser.serql.ast.ASTFrom;
072: import org.openrdf.query.parser.serql.ast.ASTFunctionCall;
073: import org.openrdf.query.parser.serql.ast.ASTGraphIntersect;
074: import org.openrdf.query.parser.serql.ast.ASTGraphMinus;
075: import org.openrdf.query.parser.serql.ast.ASTGraphUnion;
076: import org.openrdf.query.parser.serql.ast.ASTIn;
077: import org.openrdf.query.parser.serql.ast.ASTIsBNode;
078: import org.openrdf.query.parser.serql.ast.ASTIsLiteral;
079: import org.openrdf.query.parser.serql.ast.ASTIsResource;
080: import org.openrdf.query.parser.serql.ast.ASTIsURI;
081: import org.openrdf.query.parser.serql.ast.ASTLabel;
082: import org.openrdf.query.parser.serql.ast.ASTLang;
083: import org.openrdf.query.parser.serql.ast.ASTLike;
084: import org.openrdf.query.parser.serql.ast.ASTLimit;
085: import org.openrdf.query.parser.serql.ast.ASTLiteral;
086: import org.openrdf.query.parser.serql.ast.ASTLocalName;
087: import org.openrdf.query.parser.serql.ast.ASTNamespace;
088: import org.openrdf.query.parser.serql.ast.ASTNode;
089: import org.openrdf.query.parser.serql.ast.ASTNodeElem;
090: import org.openrdf.query.parser.serql.ast.ASTNot;
091: import org.openrdf.query.parser.serql.ast.ASTNull;
092: import org.openrdf.query.parser.serql.ast.ASTOffset;
093: import org.openrdf.query.parser.serql.ast.ASTOptPathExpr;
094: import org.openrdf.query.parser.serql.ast.ASTOptPathExprTail;
095: import org.openrdf.query.parser.serql.ast.ASTOr;
096: import org.openrdf.query.parser.serql.ast.ASTPathExpr;
097: import org.openrdf.query.parser.serql.ast.ASTPathExprTail;
098: import org.openrdf.query.parser.serql.ast.ASTProjectionElem;
099: import org.openrdf.query.parser.serql.ast.ASTQueryBody;
100: import org.openrdf.query.parser.serql.ast.ASTQueryContainer;
101: import org.openrdf.query.parser.serql.ast.ASTReifiedStat;
102: import org.openrdf.query.parser.serql.ast.ASTSelect;
103: import org.openrdf.query.parser.serql.ast.ASTSelectQuery;
104: import org.openrdf.query.parser.serql.ast.ASTString;
105: import org.openrdf.query.parser.serql.ast.ASTTupleIntersect;
106: import org.openrdf.query.parser.serql.ast.ASTTupleMinus;
107: import org.openrdf.query.parser.serql.ast.ASTTupleUnion;
108: import org.openrdf.query.parser.serql.ast.ASTURI;
109: import org.openrdf.query.parser.serql.ast.ASTValueExpr;
110: import org.openrdf.query.parser.serql.ast.ASTVar;
111: import org.openrdf.query.parser.serql.ast.ASTWhere;
112: import org.openrdf.query.parser.serql.ast.VisitorException;
113:
114: class QueryModelBuilder extends ASTVisitorBase {
115:
116: public static TupleExpr buildQueryModel(ASTQueryContainer node,
117: ValueFactory valueFactory) throws MalformedQueryException {
118: try {
119: QueryModelBuilder qmBuilder = new QueryModelBuilder(
120: valueFactory);
121: return (TupleExpr) node.jjtAccept(qmBuilder, null);
122: } catch (VisitorException e) {
123: throw new MalformedQueryException(e.getMessage(), e);
124: }
125: }
126:
127: /*-----------*
128: * Variables *
129: *-----------*/
130:
131: private ValueFactory valueFactory;
132:
133: private int constantVarID = 1;
134:
135: private GraphPattern graphPattern;
136:
137: /*--------------*
138: * Constructors *
139: *--------------*/
140:
141: public QueryModelBuilder(ValueFactory valueFactory) {
142: this .valueFactory = valueFactory;
143: }
144:
145: /*---------*
146: * Methods *
147: *---------*/
148:
149: private Var createConstantVar(Value value) {
150: Var var = new Var("-const-" + constantVarID++);
151: var.setAnonymous(true);
152: var.setValue(value);
153: return var;
154: }
155:
156: @Override
157: public TupleExpr visit(ASTQueryContainer node, Object data)
158: throws VisitorException {
159: // Skip the namespace declarations, any information it contains should
160: // already have been processed
161: return (TupleExpr) node.getQuery().jjtAccept(this , null);
162: }
163:
164: @Override
165: public TupleExpr visit(ASTTupleUnion node, Object data)
166: throws VisitorException {
167: TupleExpr leftArg = (TupleExpr) node.getLeftArg().jjtAccept(
168: this , null);
169: TupleExpr rightArg = (TupleExpr) node.getRightArg().jjtAccept(
170: this , null);
171:
172: TupleExpr result = new Union(leftArg, rightArg);
173:
174: if (node.isDistinct()) {
175: result = new Distinct(result);
176: }
177:
178: return result;
179: }
180:
181: @Override
182: public TupleExpr visit(ASTTupleMinus node, Object data)
183: throws VisitorException {
184: TupleExpr leftArg = (TupleExpr) node.getLeftArg().jjtAccept(
185: this , null);
186: TupleExpr rightArg = (TupleExpr) node.getRightArg().jjtAccept(
187: this , null);
188:
189: return new Difference(leftArg, rightArg);
190: }
191:
192: @Override
193: public TupleExpr visit(ASTTupleIntersect node, Object data)
194: throws VisitorException {
195: TupleExpr leftArg = (TupleExpr) node.getLeftArg().jjtAccept(
196: this , null);
197: TupleExpr rightArg = (TupleExpr) node.getRightArg().jjtAccept(
198: this , null);
199:
200: return new Intersection(leftArg, rightArg);
201: }
202:
203: @Override
204: public TupleExpr visit(ASTGraphUnion node, Object data)
205: throws VisitorException {
206: TupleExpr leftArg = (TupleExpr) node.getLeftArg().jjtAccept(
207: this , null);
208: TupleExpr rightArg = (TupleExpr) node.getRightArg().jjtAccept(
209: this , null);
210:
211: TupleExpr result = new Union(leftArg, rightArg);
212:
213: if (node.isDistinct()) {
214: result = new Distinct(result);
215: }
216:
217: return result;
218: }
219:
220: @Override
221: public TupleExpr visit(ASTGraphMinus node, Object data)
222: throws VisitorException {
223: TupleExpr leftArg = (TupleExpr) node.getLeftArg().jjtAccept(
224: this , null);
225: TupleExpr rightArg = (TupleExpr) node.getRightArg().jjtAccept(
226: this , null);
227:
228: return new Difference(leftArg, rightArg);
229: }
230:
231: @Override
232: public TupleExpr visit(ASTGraphIntersect node, Object data)
233: throws VisitorException {
234: TupleExpr leftArg = (TupleExpr) node.getLeftArg().jjtAccept(
235: this , null);
236: TupleExpr rightArg = (TupleExpr) node.getRightArg().jjtAccept(
237: this , null);
238:
239: return new Intersection(leftArg, rightArg);
240: }
241:
242: @Override
243: public TupleExpr visit(ASTSelectQuery node, Object data)
244: throws VisitorException {
245: TupleExpr tupleExpr;
246:
247: ASTQueryBody queryBodyNode = node.getQueryBody();
248:
249: if (queryBodyNode != null) {
250: // Build tuple expression for query body
251: tupleExpr = (TupleExpr) queryBodyNode.jjtAccept(this , null);
252: } else {
253: tupleExpr = new SingletonSet();
254: }
255:
256: // Apply projection
257: tupleExpr = (TupleExpr) node.getSelectClause().jjtAccept(this ,
258: tupleExpr);
259:
260: // process limit and offset clauses, if present.
261: ASTLimit limitNode = node.getLimit();
262: int limit = -1;
263: if (limitNode != null) {
264: limit = (Integer) limitNode.jjtAccept(this , null);
265: }
266:
267: ASTOffset offsetNode = node.getOffset();
268: int offset = -1;
269: if (offsetNode != null) {
270: offset = (Integer) offsetNode.jjtAccept(this , null);
271: }
272:
273: if (offset >= 1 || limit >= 0) {
274: tupleExpr = new Slice(tupleExpr, offset, limit);
275: }
276: return tupleExpr;
277: }
278:
279: @Override
280: public TupleExpr visit(ASTSelect node, Object data)
281: throws VisitorException {
282: TupleExpr result = (TupleExpr) data;
283:
284: Extension extension = new Extension();
285: ProjectionElemList projElemList = new ProjectionElemList();
286:
287: for (ASTProjectionElem projElemNode : node
288: .getProjectionElemList()) {
289: ValueExpr valueExpr = (ValueExpr) projElemNode
290: .getValueExpr().jjtAccept(this , null);
291:
292: String alias = projElemNode.getAlias();
293: if (alias != null) {
294: // aliased projection element
295: extension
296: .addElement(new ExtensionElem(valueExpr, alias));
297: projElemList.addElement(new ProjectionElem(alias));
298: } else if (valueExpr instanceof Var) {
299: // unaliased variable
300: Var projVar = (Var) valueExpr;
301: projElemList.addElement(new ProjectionElem(projVar
302: .getName()));
303: } else {
304: throw new IllegalStateException(
305: "required alias for non-Var projection elements not found");
306: }
307: }
308:
309: if (!extension.getElements().isEmpty()) {
310: extension.setArg(result);
311: result = extension;
312: }
313:
314: result = new Projection(result, projElemList);
315:
316: if (node.isDistinct()) {
317: result = new Distinct(result);
318: }
319:
320: return result;
321: }
322:
323: @Override
324: public TupleExpr visit(ASTConstructQuery node, Object data)
325: throws VisitorException {
326: TupleExpr tupleExpr;
327:
328: if (node.hasQueryBody()) {
329: // Build tuple expression for query body
330: tupleExpr = (TupleExpr) node.getQueryBody().jjtAccept(this ,
331: null);
332: } else {
333: tupleExpr = new SingletonSet();
334: }
335:
336: // Create constructor
337: ConstructorBuilder cb = new ConstructorBuilder();
338: ASTConstruct constructNode = node.getConstructClause();
339:
340: if (!constructNode.isWildcard()) {
341: TupleExpr constructExpr = (TupleExpr) constructNode
342: .jjtAccept(this , null);
343: tupleExpr = cb.buildConstructor(tupleExpr, constructExpr,
344: constructNode.isDistinct());
345: } else if (node.hasQueryBody()) {
346: tupleExpr = cb.buildConstructor(tupleExpr, constructNode
347: .isDistinct());
348: }
349: // else: "construct *" without query body, just return the SingletonSet
350:
351: // process limit and offset clauses, if present.
352: ASTLimit limitNode = node.getLimit();
353: int limit = -1;
354: if (limitNode != null) {
355: limit = (Integer) limitNode.jjtAccept(this , null);
356: }
357:
358: ASTOffset offsetNode = node.getOffset();
359: int offset = -1;
360:
361: if (offsetNode != null) {
362: offset = (Integer) offsetNode.jjtAccept(this , null);
363: }
364:
365: if (offset >= 1 || limit >= 0) {
366: tupleExpr = new Slice(tupleExpr, offset, limit);
367: }
368:
369: return tupleExpr;
370: }
371:
372: @Override
373: public TupleExpr visit(ASTConstruct node, Object data)
374: throws VisitorException {
375: assert !node.isWildcard() : "Cannot build constructor for wildcards";
376:
377: graphPattern = new GraphPattern(graphPattern);
378: try {
379: super .visit(node, data);
380: return graphPattern.buildTupleExpr();
381: } finally {
382: graphPattern = graphPattern.getParent();
383: }
384: }
385:
386: @Override
387: public TupleExpr visit(ASTQueryBody node, Object data)
388: throws VisitorException {
389: graphPattern = new GraphPattern(graphPattern);
390: try {
391: super .visit(node, data);
392: return graphPattern.buildTupleExpr();
393: } finally {
394: graphPattern = graphPattern.getParent();
395: }
396: }
397:
398: @Override
399: public Object visit(ASTFrom node, Object data)
400: throws VisitorException {
401: StatementPattern.Scope scope = StatementPattern.Scope.DEFAULT_CONTEXTS;
402: Var contextVar = null;
403:
404: if (node.hasContextID()) {
405: scope = StatementPattern.Scope.NAMED_CONTEXTS;
406: ValueExpr contextID = (ValueExpr) node.getContextID()
407: .jjtAccept(this , null);
408:
409: if (contextID instanceof Var) {
410: contextVar = (Var) contextID;
411: } else if (contextID instanceof ValueConstant) {
412: ValueConstant vc = (ValueConstant) contextID;
413: contextVar = createConstantVar(vc.getValue());
414: } else {
415: throw new IllegalArgumentException(
416: "Unexpected contextID result type: "
417: + contextID.getClass());
418: }
419: }
420:
421: graphPattern.setStatementPatternScope(scope);
422: graphPattern.setContextVar(contextVar);
423:
424: for (ASTPathExpr pathExprNode : node.getPathExprList()) {
425: pathExprNode.jjtAccept(this , null);
426: }
427:
428: return null;
429: }
430:
431: @Override
432: public Integer visit(ASTWhere node, Object data)
433: throws VisitorException {
434: ValueExpr valueExpr = (ValueExpr) node.getCondition()
435: .jjtAccept(this , null);
436: graphPattern.addConstraint(valueExpr);
437: return null;
438: }
439:
440: @Override
441: public Integer visit(ASTLimit node, Object data)
442: throws VisitorException {
443: return node.getValue();
444: }
445:
446: @Override
447: public Integer visit(ASTOffset node, Object data)
448: throws VisitorException {
449: return node.getValue();
450: }
451:
452: @Override
453: public Object visit(ASTBasicPathExpr node, Object data)
454: throws VisitorException {
455: // process subject node
456: List<Var> subjVars = (List<Var>) node.getHead().jjtAccept(this ,
457: null);
458:
459: // supply subject vars to tail segment
460: node.getTail().jjtAccept(this , subjVars);
461:
462: return null;
463: }
464:
465: @Override
466: public Object visit(ASTOptPathExpr node, Object data)
467: throws VisitorException {
468: // Create new sub-graph pattern for optional path expressions
469: graphPattern = new GraphPattern(graphPattern);
470:
471: super .visit(node, data);
472:
473: graphPattern.getParent().addOptionalTE(graphPattern);
474: graphPattern = graphPattern.getParent();
475:
476: return null;
477: }
478:
479: @Override
480: public Object visit(ASTBasicPathExprTail tailNode, Object data)
481: throws VisitorException {
482: List<Var> subjVars = (List<Var>) data;
483: Var predVar = (Var) tailNode.getEdge().jjtAccept(this , null);
484: List<Var> objVars = (List<Var>) tailNode.getNode().jjtAccept(
485: this , null);
486:
487: Var contextVar = graphPattern.getContextVar();
488: StatementPattern.Scope spScope = graphPattern
489: .getStatementPatternScope();
490:
491: for (Var subjVar : subjVars) {
492: for (Var objVar : objVars) {
493: StatementPattern sp = new StatementPattern(spScope,
494: subjVar, predVar, objVar, contextVar);
495: graphPattern.addRequiredTE(sp);
496: }
497: }
498:
499: // Process next tail segment
500: ASTPathExprTail nextTailNode = tailNode.getNextTail();
501: if (nextTailNode != null) {
502: List<Var> joinVars = nextTailNode.isBranch() ? subjVars
503: : objVars;
504: nextTailNode.jjtAccept(this , joinVars);
505: }
506:
507: return null;
508: }
509:
510: @Override
511: public Object visit(ASTOptPathExprTail tailNode, Object data)
512: throws VisitorException {
513: List<Var> subjVars = (List<Var>) data;
514:
515: // Create new sub-graph pattern for optional path expressions
516: graphPattern = new GraphPattern(graphPattern);
517:
518: // optional path expression tail
519: tailNode.getOptionalTail().jjtAccept(this , subjVars);
520:
521: ASTWhere whereNode = tailNode.getWhereClause();
522: if (whereNode != null) {
523: // boolean contraint on optional path expression tail
524: whereNode.jjtAccept(this , null);
525: }
526:
527: graphPattern.getParent().addOptionalTE(graphPattern);
528: graphPattern = graphPattern.getParent();
529:
530: ASTPathExprTail nextTailNode = tailNode.getNextTail();
531: if (nextTailNode != null) {
532: // branch after optional path expression tail
533: nextTailNode.jjtAccept(this , subjVars);
534: }
535:
536: return null;
537: }
538:
539: @Override
540: public Var visit(ASTEdge node, Object data) throws VisitorException {
541: ValueExpr arg = (ValueExpr) node.getValueExpr().jjtAccept(this ,
542: null);
543:
544: if (arg instanceof Var) {
545: return (Var) arg;
546: } else if (arg instanceof ValueConstant) {
547: ValueConstant vc = (ValueConstant) arg;
548: return createConstantVar(vc.getValue());
549: } else {
550: throw new IllegalArgumentException(
551: "Unexpected edge argument type: " + arg.getClass());
552: }
553: }
554:
555: @Override
556: public List<Var> visit(ASTNode node, Object data)
557: throws VisitorException {
558: List<Var> nodeVars = new ArrayList<Var>();
559:
560: for (ASTNodeElem nodeElem : node.getNodeElemList()) {
561: Var nodeVar = (Var) nodeElem.jjtAccept(this , null);
562: nodeVars.add(nodeVar);
563: }
564:
565: // Create any implicit unequalities
566: for (int i = 0; i < nodeVars.size() - 1; i++) {
567: Var var1 = nodeVars.get(i);
568:
569: for (int j = i + 1; j < nodeVars.size(); j++) {
570: Var var2 = nodeVars.get(j);
571:
572: // At least one of the variables should be non-constant
573: // for the unequality to make any sense:
574: if (!var1.hasValue() || !var2.hasValue()) {
575: graphPattern.addConstraint(new Not(new SameTerm(
576: var1, var2)));
577: }
578: }
579: }
580:
581: return nodeVars;
582: }
583:
584: @Override
585: public Var visit(ASTNodeElem node, Object data)
586: throws VisitorException {
587: ValueExpr valueExpr = (ValueExpr) node.getChild().jjtAccept(
588: this , null);
589:
590: if (valueExpr instanceof Var) {
591: return (Var) valueExpr;
592: } else if (valueExpr instanceof ValueConstant) {
593: ValueConstant vc = (ValueConstant) valueExpr;
594: return createConstantVar(vc.getValue());
595: } else {
596: throw new IllegalArgumentException(
597: "Unexpected node element result type: "
598: + valueExpr.getClass());
599: }
600: }
601:
602: @Override
603: public Var visit(ASTReifiedStat node, Object data)
604: throws VisitorException {
605: assert node.getID() != null : "ID variable not set";
606:
607: Var subjVar = (Var) node.getSubject().jjtAccept(this , null);
608: Var predVar = (Var) node.getPredicate().jjtAccept(this , null);
609: Var objVar = (Var) node.getObject().jjtAccept(this , null);
610: Var idVar = (Var) node.getID().jjtAccept(this , null);
611:
612: Var contextVar = graphPattern.getContextVar();
613: StatementPattern.Scope spScope = graphPattern
614: .getStatementPatternScope();
615:
616: Var rdfType = new Var("_rdfType", RDF.TYPE);
617: Var rdfStatement = new Var("_rdfStatement", RDF.STATEMENT);
618: Var rdfSubject = new Var("_rdfSubject", RDF.SUBJECT);
619: Var rdfPredicate = new Var("_rdfPredicate", RDF.PREDICATE);
620: Var rdfObject = new Var("_rdfObject", RDF.OBJECT);
621:
622: graphPattern.addRequiredTE(new StatementPattern(spScope, idVar,
623: rdfType, rdfStatement, contextVar));
624: graphPattern.addRequiredTE(new StatementPattern(spScope, idVar,
625: rdfSubject, subjVar, contextVar));
626: graphPattern.addRequiredTE(new StatementPattern(spScope, idVar,
627: rdfPredicate, predVar, contextVar));
628: graphPattern.addRequiredTE(new StatementPattern(spScope, idVar,
629: rdfObject, objVar, contextVar));
630:
631: return idVar;
632: }
633:
634: @Override
635: public ValueExpr visit(ASTOr node, Object data)
636: throws VisitorException {
637: Iterator<ASTBooleanExpr> iter = node.getOperandList()
638: .iterator();
639:
640: ValueExpr result = (ValueExpr) iter.next()
641: .jjtAccept(this , null);
642:
643: while (iter.hasNext()) {
644: ValueExpr operand = (ValueExpr) iter.next().jjtAccept(this ,
645: null);
646: result = new Or(result, operand);
647: }
648:
649: return result;
650: }
651:
652: @Override
653: public ValueExpr visit(ASTAnd node, Object data)
654: throws VisitorException {
655: Iterator<ASTBooleanExpr> iter = node.getOperandList()
656: .iterator();
657:
658: ValueExpr result = (ValueExpr) iter.next()
659: .jjtAccept(this , null);
660:
661: while (iter.hasNext()) {
662: ValueExpr operand = (ValueExpr) iter.next().jjtAccept(this ,
663: null);
664: result = new And(result, operand);
665: }
666:
667: return result;
668: }
669:
670: @Override
671: public ValueConstant visit(ASTBooleanConstant node, Object data)
672: throws VisitorException {
673: return new ValueConstant(valueFactory.createLiteral(node
674: .getValue()));
675: }
676:
677: @Override
678: public Not visit(ASTNot node, Object data) throws VisitorException {
679: return new Not((ValueExpr) super .visit(node, data));
680: }
681:
682: @Override
683: public Bound visit(ASTBound node, Object data)
684: throws VisitorException {
685: return new Bound((Var) super .visit(node, data));
686: }
687:
688: @Override
689: public IsResource visit(ASTIsResource node, Object data)
690: throws VisitorException {
691: return new IsResource((ValueExpr) super .visit(node, data));
692: }
693:
694: @Override
695: public IsLiteral visit(ASTIsLiteral node, Object data)
696: throws VisitorException {
697: return new IsLiteral((ValueExpr) super .visit(node, data));
698: }
699:
700: @Override
701: public IsURI visit(ASTIsURI node, Object data)
702: throws VisitorException {
703: return new IsURI((ValueExpr) super .visit(node, data));
704: }
705:
706: @Override
707: public IsBNode visit(ASTIsBNode node, Object data)
708: throws VisitorException {
709: return new IsBNode((ValueExpr) super .visit(node, data));
710: }
711:
712: @Override
713: public Exists visit(ASTExists node, Object data)
714: throws VisitorException {
715: return new Exists((TupleExpr) super .visit(node, data));
716: }
717:
718: @Override
719: public Compare visit(ASTCompare node, Object data)
720: throws VisitorException {
721: ValueExpr leftArg = (ValueExpr) node.getLeftOperand()
722: .jjtAccept(this , null);
723: ValueExpr rightArg = (ValueExpr) node.getRightOperand()
724: .jjtAccept(this , null);
725: CompareOp operator = node.getOperator().getValue();
726:
727: return new Compare(leftArg, rightArg, operator);
728: }
729:
730: @Override
731: public CompareAny visit(ASTCompareAny node, Object data)
732: throws VisitorException {
733: ValueExpr valueExpr = (ValueExpr) node.getLeftOperand()
734: .jjtAccept(this , null);
735: TupleExpr tupleExpr = (TupleExpr) node.getRightOperand()
736: .jjtAccept(this , null);
737: CompareOp op = node.getOperator().getValue();
738:
739: return new CompareAny(valueExpr, tupleExpr, op);
740: }
741:
742: @Override
743: public CompareAll visit(ASTCompareAll node, Object data)
744: throws VisitorException {
745: ValueExpr valueExpr = (ValueExpr) node.getLeftOperand()
746: .jjtAccept(this , null);
747: TupleExpr tupleExpr = (TupleExpr) node.getRightOperand()
748: .jjtAccept(this , null);
749: CompareOp op = node.getOperator().getValue();
750:
751: return new CompareAll(valueExpr, tupleExpr, op);
752: }
753:
754: @Override
755: public Like visit(ASTLike node, Object data)
756: throws VisitorException {
757: ValueExpr expr = (ValueExpr) node.getValueExpr().jjtAccept(
758: this , null);
759: String pattern = (String) node.getPattern().jjtAccept(this ,
760: null);
761: boolean caseSensitive = !node.ignoreCase();
762:
763: return new Like(expr, pattern, caseSensitive);
764: }
765:
766: @Override
767: public In visit(ASTIn node, Object data) throws VisitorException {
768: ValueExpr valueExpr = (ValueExpr) node.getLeftOperand()
769: .jjtAccept(this , null);
770: TupleExpr tupleExpr = (TupleExpr) node.getRightOperand()
771: .jjtAccept(this , null);
772: return new In(valueExpr, tupleExpr);
773: }
774:
775: @Override
776: public Var visit(ASTVar node, Object data) throws VisitorException {
777: Var var = new Var(node.getName());
778: var.setAnonymous(node.isAnonymous());
779: return var;
780: }
781:
782: @Override
783: public Datatype visit(ASTDatatype node, Object data)
784: throws VisitorException {
785: return new Datatype((ValueExpr) super .visit(node, data));
786: }
787:
788: @Override
789: public Lang visit(ASTLang node, Object data)
790: throws VisitorException {
791: return new Lang((ValueExpr) super .visit(node, data));
792: }
793:
794: @Override
795: public Label visit(ASTLabel node, Object data)
796: throws VisitorException {
797: return new Label((ValueExpr) super .visit(node, data));
798: }
799:
800: @Override
801: public Namespace visit(ASTNamespace node, Object data)
802: throws VisitorException {
803: return new Namespace((ValueExpr) super .visit(node, data));
804: }
805:
806: @Override
807: public LocalName visit(ASTLocalName node, Object data)
808: throws VisitorException {
809: return new LocalName((ValueExpr) super .visit(node, data));
810: }
811:
812: @Override
813: public FunctionCall visit(ASTFunctionCall node, Object data)
814: throws VisitorException {
815: ValueConstant vc = (ValueConstant) node.getURI().jjtAccept(
816: this , null);
817: assert vc.getValue() instanceof URI;
818:
819: FunctionCall functionCall = new FunctionCall(vc.getValue()
820: .toString());
821:
822: for (ASTValueExpr argExpr : node.getArgList()) {
823: functionCall.addArg((ValueExpr) argExpr.jjtAccept(this ,
824: null));
825: }
826:
827: return functionCall;
828: }
829:
830: @Override
831: public Object visit(ASTNull node, Object data)
832: throws VisitorException {
833: throw new VisitorException(
834: "Use of NULL values in SeRQL queries has been deprecated, use BOUND(...) instead");
835: }
836:
837: @Override
838: public ValueConstant visit(ASTURI node, Object data)
839: throws VisitorException {
840: return new ValueConstant(valueFactory
841: .createURI(node.getValue()));
842: }
843:
844: @Override
845: public ValueConstant visit(ASTBNode node, Object data)
846: throws VisitorException {
847: return new ValueConstant(valueFactory.createBNode(node.getID()));
848: }
849:
850: @Override
851: public ValueConstant visit(ASTLiteral litNode, Object data)
852: throws VisitorException {
853: URI datatype = null;
854:
855: // Get datatype URI from child URI node, if present
856: ASTValueExpr dtNode = litNode.getDatatypeNode();
857: if (dtNode instanceof ASTURI) {
858: datatype = valueFactory.createURI(((ASTURI) dtNode)
859: .getValue());
860: } else if (dtNode != null) {
861: throw new IllegalArgumentException(
862: "Unexpected datatype type: " + dtNode.getClass());
863: }
864:
865: Literal literal;
866: if (datatype != null) {
867: literal = valueFactory.createLiteral(litNode.getLabel(),
868: datatype);
869: } else if (litNode.hasLang()) {
870: literal = valueFactory.createLiteral(litNode.getLabel(),
871: litNode.getLang());
872: } else {
873: literal = valueFactory.createLiteral(litNode.getLabel());
874: }
875:
876: return new ValueConstant(literal);
877: }
878:
879: @Override
880: public String visit(ASTString node, Object data)
881: throws VisitorException {
882: return node.getValue();
883: }
884: }
|