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.sparql;
007:
008: import java.util.ArrayList;
009: import java.util.Collection;
010: import java.util.HashMap;
011: import java.util.LinkedHashSet;
012: import java.util.List;
013: import java.util.Map;
014: import java.util.Set;
015:
016: import org.openrdf.model.Literal;
017: import org.openrdf.model.URI;
018: import org.openrdf.model.Value;
019: import org.openrdf.model.ValueFactory;
020: import org.openrdf.model.vocabulary.RDF;
021: import org.openrdf.query.algebra.And;
022: import org.openrdf.query.algebra.BNodeGenerator;
023: import org.openrdf.query.algebra.Bound;
024: import org.openrdf.query.algebra.Compare;
025: import org.openrdf.query.algebra.Datatype;
026: import org.openrdf.query.algebra.Distinct;
027: import org.openrdf.query.algebra.EmptySet;
028: import org.openrdf.query.algebra.Extension;
029: import org.openrdf.query.algebra.ExtensionElem;
030: import org.openrdf.query.algebra.Filter;
031: import org.openrdf.query.algebra.FunctionCall;
032: import org.openrdf.query.algebra.IsBNode;
033: import org.openrdf.query.algebra.IsLiteral;
034: import org.openrdf.query.algebra.IsURI;
035: import org.openrdf.query.algebra.Join;
036: import org.openrdf.query.algebra.Lang;
037: import org.openrdf.query.algebra.LangMatches;
038: import org.openrdf.query.algebra.LeftJoin;
039: import org.openrdf.query.algebra.MathExpr;
040: import org.openrdf.query.algebra.MultiProjection;
041: import org.openrdf.query.algebra.Not;
042: import org.openrdf.query.algebra.Or;
043: import org.openrdf.query.algebra.Order;
044: import org.openrdf.query.algebra.OrderElem;
045: import org.openrdf.query.algebra.Projection;
046: import org.openrdf.query.algebra.ProjectionElem;
047: import org.openrdf.query.algebra.ProjectionElemList;
048: import org.openrdf.query.algebra.Regex;
049: import org.openrdf.query.algebra.SameTerm;
050: import org.openrdf.query.algebra.Slice;
051: import org.openrdf.query.algebra.StatementPattern;
052: import org.openrdf.query.algebra.Str;
053: import org.openrdf.query.algebra.TupleExpr;
054: import org.openrdf.query.algebra.Union;
055: import org.openrdf.query.algebra.ValueConstant;
056: import org.openrdf.query.algebra.ValueExpr;
057: import org.openrdf.query.algebra.Var;
058: import org.openrdf.query.algebra.StatementPattern.Scope;
059: import org.openrdf.query.algebra.helpers.StatementPatternCollector;
060: import org.openrdf.query.parser.sparql.ast.ASTAnd;
061: import org.openrdf.query.parser.sparql.ast.ASTAskQuery;
062: import org.openrdf.query.parser.sparql.ast.ASTBlankNode;
063: import org.openrdf.query.parser.sparql.ast.ASTBlankNodePropertyList;
064: import org.openrdf.query.parser.sparql.ast.ASTBound;
065: import org.openrdf.query.parser.sparql.ast.ASTCollection;
066: import org.openrdf.query.parser.sparql.ast.ASTCompare;
067: import org.openrdf.query.parser.sparql.ast.ASTConstraint;
068: import org.openrdf.query.parser.sparql.ast.ASTConstruct;
069: import org.openrdf.query.parser.sparql.ast.ASTConstructQuery;
070: import org.openrdf.query.parser.sparql.ast.ASTDatatype;
071: import org.openrdf.query.parser.sparql.ast.ASTDescribe;
072: import org.openrdf.query.parser.sparql.ast.ASTDescribeQuery;
073: import org.openrdf.query.parser.sparql.ast.ASTFalse;
074: import org.openrdf.query.parser.sparql.ast.ASTFunctionCall;
075: import org.openrdf.query.parser.sparql.ast.ASTGraphGraphPattern;
076: import org.openrdf.query.parser.sparql.ast.ASTGraphPatternGroup;
077: import org.openrdf.query.parser.sparql.ast.ASTIRI;
078: import org.openrdf.query.parser.sparql.ast.ASTIsBlank;
079: import org.openrdf.query.parser.sparql.ast.ASTIsIRI;
080: import org.openrdf.query.parser.sparql.ast.ASTIsLiteral;
081: import org.openrdf.query.parser.sparql.ast.ASTLang;
082: import org.openrdf.query.parser.sparql.ast.ASTLangMatches;
083: import org.openrdf.query.parser.sparql.ast.ASTLimit;
084: import org.openrdf.query.parser.sparql.ast.ASTMath;
085: import org.openrdf.query.parser.sparql.ast.ASTNot;
086: import org.openrdf.query.parser.sparql.ast.ASTNumericLiteral;
087: import org.openrdf.query.parser.sparql.ast.ASTObjectList;
088: import org.openrdf.query.parser.sparql.ast.ASTOffset;
089: import org.openrdf.query.parser.sparql.ast.ASTOptionalGraphPattern;
090: import org.openrdf.query.parser.sparql.ast.ASTOr;
091: import org.openrdf.query.parser.sparql.ast.ASTOrderClause;
092: import org.openrdf.query.parser.sparql.ast.ASTOrderCondition;
093: import org.openrdf.query.parser.sparql.ast.ASTPropertyList;
094: import org.openrdf.query.parser.sparql.ast.ASTQName;
095: import org.openrdf.query.parser.sparql.ast.ASTQueryContainer;
096: import org.openrdf.query.parser.sparql.ast.ASTRDFLiteral;
097: import org.openrdf.query.parser.sparql.ast.ASTRegexExpression;
098: import org.openrdf.query.parser.sparql.ast.ASTSameTerm;
099: import org.openrdf.query.parser.sparql.ast.ASTSelect;
100: import org.openrdf.query.parser.sparql.ast.ASTSelectQuery;
101: import org.openrdf.query.parser.sparql.ast.ASTStr;
102: import org.openrdf.query.parser.sparql.ast.ASTString;
103: import org.openrdf.query.parser.sparql.ast.ASTTrue;
104: import org.openrdf.query.parser.sparql.ast.ASTUnionGraphPattern;
105: import org.openrdf.query.parser.sparql.ast.ASTVar;
106: import org.openrdf.query.parser.sparql.ast.Node;
107: import org.openrdf.query.parser.sparql.ast.VisitorException;
108:
109: /**
110: * @author Arjohn Kampman
111: */
112: class TupleExprBuilder extends ASTVisitorBase {
113:
114: /*-----------*
115: * Variables *
116: *-----------*/
117:
118: private ValueFactory valueFactory;
119:
120: private GraphPattern graphPattern;
121:
122: private int constantVarID = 1;
123:
124: /*--------------*
125: * Constructors *
126: *--------------*/
127:
128: public TupleExprBuilder(ValueFactory valueFactory) {
129: this .valueFactory = valueFactory;
130: }
131:
132: /*---------*
133: * Methods *
134: *---------*/
135:
136: private Var valueExpr2Var(ValueExpr valueExpr) {
137: if (valueExpr instanceof Var) {
138: return (Var) valueExpr;
139: } else if (valueExpr instanceof ValueConstant) {
140: return createConstVar(((ValueConstant) valueExpr)
141: .getValue());
142: } else if (valueExpr == null) {
143: throw new IllegalArgumentException("valueExpr is null");
144: } else {
145: throw new IllegalArgumentException("valueExpr is a: "
146: + valueExpr.getClass());
147: }
148: }
149:
150: private Var createConstVar(Value value) {
151: Var var = createAnonVar("-const-" + constantVarID++);
152: var.setValue(value);
153: return var;
154: }
155:
156: private Var createAnonVar(String varName) {
157: Var var = new Var(varName);
158: var.setAnonymous(true);
159: return var;
160: }
161:
162: @Override
163: public TupleExpr visit(ASTQueryContainer node, Object data)
164: throws VisitorException {
165: // Skip the prolog, any information it contains should already have been
166: // processed
167: return (TupleExpr) node.getQuery().jjtAccept(this , null);
168: }
169:
170: @Override
171: public TupleExpr visit(ASTSelectQuery node, Object data)
172: throws VisitorException {
173: // Start with building the graph pattern
174: graphPattern = new GraphPattern();
175: node.getWhereClause().jjtAccept(this , null);
176: TupleExpr tupleExpr = graphPattern.buildTupleExpr();
177:
178: // Apply result ordering
179: ASTOrderClause orderNode = node.getOrderClause();
180: if (orderNode != null) {
181: List<OrderElem> orderElemements = (List<OrderElem>) orderNode
182: .jjtAccept(this , null);
183: tupleExpr = new Order(tupleExpr, orderElemements);
184: }
185:
186: // Apply projection
187: tupleExpr = (TupleExpr) node.getSelect().jjtAccept(this ,
188: tupleExpr);
189:
190: // Process limit and offset clauses
191: ASTLimit limitNode = node.getLimit();
192: int limit = -1;
193: if (limitNode != null) {
194: limit = (Integer) limitNode.jjtAccept(this , null);
195: }
196:
197: ASTOffset offsetNode = node.getOffset();
198: int offset = -1;
199: if (offsetNode != null) {
200: offset = (Integer) offsetNode.jjtAccept(this , null);
201: }
202:
203: if (offset >= 1 || limit >= 0) {
204: tupleExpr = new Slice(tupleExpr, offset, limit);
205: }
206:
207: return tupleExpr;
208: }
209:
210: @Override
211: public TupleExpr visit(ASTSelect node, Object data)
212: throws VisitorException {
213: TupleExpr result = (TupleExpr) data;
214:
215: ProjectionElemList projElemList = new ProjectionElemList();
216:
217: for (int i = 0; i < node.jjtGetNumChildren(); i++) {
218: Var projVar = (Var) node.jjtGetChild(i).jjtAccept(this ,
219: null);
220: projElemList.addElement(new ProjectionElem(projVar
221: .getName()));
222: }
223:
224: result = new Projection(result, projElemList);
225:
226: if (node.isDistinct()) {
227: result = new Distinct(result);
228: }
229:
230: return result;
231: }
232:
233: @Override
234: public TupleExpr visit(ASTConstructQuery node, Object data)
235: throws VisitorException {
236: // Start with building the graph pattern
237: graphPattern = new GraphPattern();
238: node.getWhereClause().jjtAccept(this , null);
239: TupleExpr tupleExpr = graphPattern.buildTupleExpr();
240:
241: // Apply result ordering
242: ASTOrderClause orderNode = node.getOrderClause();
243: if (orderNode != null) {
244: List<OrderElem> orderElemements = (List<OrderElem>) orderNode
245: .jjtAccept(this , null);
246: tupleExpr = new Order(tupleExpr, orderElemements);
247: }
248:
249: // Process construct clause
250: tupleExpr = (TupleExpr) node.getConstruct().jjtAccept(this ,
251: tupleExpr);
252:
253: // process limit and offset clauses
254: ASTLimit limitNode = node.getLimit();
255: int limit = -1;
256: if (limitNode != null) {
257: limit = (Integer) limitNode.jjtAccept(this , null);
258: }
259:
260: ASTOffset offsetNode = node.getOffset();
261: int offset = -1;
262: if (offsetNode != null) {
263: offset = (Integer) offsetNode.jjtAccept(this , null);
264: }
265:
266: if (offset >= 1 || limit >= 0) {
267: tupleExpr = new Slice(tupleExpr, offset, limit);
268: }
269:
270: return tupleExpr;
271: }
272:
273: @Override
274: public TupleExpr visit(ASTConstruct node, Object data)
275: throws VisitorException {
276: TupleExpr result = (TupleExpr) data;
277:
278: // Collect construct triples
279: graphPattern = new GraphPattern();
280: super .visit(node, null);
281: TupleExpr constructExpr = graphPattern.buildTupleExpr();
282:
283: // Retrieve all StatementPattern's from the construct expression
284: List<StatementPattern> statementPatterns = StatementPatternCollector
285: .process(constructExpr);
286:
287: Set<Var> constructVars = getConstructVars(statementPatterns);
288:
289: // Create BNodeGenerator's for all anonymous variables
290: Map<Var, ExtensionElem> extElemMap = new HashMap<Var, ExtensionElem>();
291:
292: for (Var var : constructVars) {
293: if (var.isAnonymous() && !extElemMap.containsKey(var)) {
294: ValueExpr valueExpr;
295:
296: if (var.hasValue()) {
297: valueExpr = new ValueConstant(var.getValue());
298: } else {
299: valueExpr = new BNodeGenerator();
300: }
301:
302: extElemMap.put(var, new ExtensionElem(valueExpr, var
303: .getName()));
304: }
305: }
306:
307: if (!extElemMap.isEmpty()) {
308: result = new Extension(result, extElemMap.values());
309: }
310:
311: // Create a Projection for each StatementPattern in the constructor
312: List<ProjectionElemList> projList = new ArrayList<ProjectionElemList>();
313:
314: for (StatementPattern sp : statementPatterns) {
315: ProjectionElemList projElemList = new ProjectionElemList();
316:
317: projElemList.addElement(new ProjectionElem(sp
318: .getSubjectVar().getName(), "subject"));
319: projElemList.addElement(new ProjectionElem(sp
320: .getPredicateVar().getName(), "predicate"));
321: projElemList.addElement(new ProjectionElem(sp
322: .getObjectVar().getName(), "object"));
323:
324: projList.add(projElemList);
325: }
326:
327: if (projList.size() == 1) {
328: result = new Projection(result, projList.get(0));
329: } else if (projList.size() > 1) {
330: result = new MultiProjection(result, projList);
331: } else {
332: // Empty constructor
333: result = new EmptySet();
334: }
335:
336: return result;
337: }
338:
339: /**
340: * Gets the set of variables that are relevant for the constructor. This
341: * method accumulates all subject, predicate and object variables from the
342: * supplied statement patterns, but ignores any context variables.
343: */
344: private Set<Var> getConstructVars(
345: Collection<StatementPattern> statementPatterns) {
346: Set<Var> vars = new LinkedHashSet<Var>(
347: statementPatterns.size() * 2);
348:
349: for (StatementPattern sp : statementPatterns) {
350: vars.add(sp.getSubjectVar());
351: vars.add(sp.getPredicateVar());
352: vars.add(sp.getObjectVar());
353: }
354:
355: return vars;
356: }
357:
358: @Override
359: public TupleExpr visit(ASTDescribeQuery node, Object data)
360: throws VisitorException {
361: TupleExpr tupleExpr = null;
362:
363: if (node.getWhereClause() != null) {
364: // Start with building the graph pattern
365: graphPattern = new GraphPattern();
366: node.getWhereClause().jjtAccept(this , null);
367: tupleExpr = graphPattern.buildTupleExpr();
368:
369: // Apply result ordering
370: ASTOrderClause orderNode = node.getOrderClause();
371: if (orderNode != null) {
372: List<OrderElem> orderElemements = (List<OrderElem>) orderNode
373: .jjtAccept(this , null);
374: tupleExpr = new Order(tupleExpr, orderElemements);
375: }
376:
377: // Process limit and offset clauses
378: ASTLimit limitNode = node.getLimit();
379: int limit = -1;
380: if (limitNode != null) {
381: limit = (Integer) limitNode.jjtAccept(this , null);
382: }
383:
384: ASTOffset offsetNode = node.getOffset();
385: int offset = -1;
386: if (offsetNode != null) {
387: offset = (Integer) offsetNode.jjtAccept(this , null);
388: }
389:
390: if (offset >= 1 || limit >= 0) {
391: tupleExpr = new Slice(tupleExpr, offset, limit);
392: }
393: }
394:
395: // Process describe clause last
396: return (TupleExpr) node.getDescribe()
397: .jjtAccept(this , tupleExpr);
398: }
399:
400: @Override
401: public TupleExpr visit(ASTDescribe node, Object data)
402: throws VisitorException {
403: TupleExpr result = (TupleExpr) data;
404:
405: // Create a graph query that produces the statements that have the
406: // requests resources as subject or object
407: Var subjVar = createAnonVar("-descr-subj");
408: Var predVar = createAnonVar("-descr-pred");
409: Var objVar = createAnonVar("-descr-obj");
410: StatementPattern sp = new StatementPattern(subjVar, predVar,
411: objVar);
412:
413: if (result == null) {
414: result = sp;
415: } else {
416: result = new Join(result, sp);
417: }
418:
419: List<SameTerm> sameTerms = new ArrayList<SameTerm>(2 * node
420: .jjtGetNumChildren());
421:
422: for (int i = 0; i < node.jjtGetNumChildren(); i++) {
423: ValueExpr resource = (ValueExpr) node.jjtGetChild(i)
424: .jjtAccept(this , null);
425:
426: sameTerms.add(new SameTerm(subjVar.clone(), resource));
427: sameTerms.add(new SameTerm(objVar.clone(), resource));
428: }
429:
430: ValueExpr constraint = sameTerms.get(0);
431: for (int i = 0; i < sameTerms.size(); i++) {
432: constraint = new Or(constraint, sameTerms.get(i));
433: }
434:
435: result = new Filter(result, constraint);
436:
437: ProjectionElemList projElemList = new ProjectionElemList();
438: projElemList.addElement(new ProjectionElem(subjVar.getName(),
439: "subject"));
440: projElemList.addElement(new ProjectionElem(predVar.getName(),
441: "predicate"));
442: projElemList.addElement(new ProjectionElem(objVar.getName(),
443: "object"));
444: result = new Projection(result, projElemList);
445:
446: return result;
447: }
448:
449: @Override
450: public TupleExpr visit(ASTAskQuery node, Object data)
451: throws VisitorException {
452: graphPattern = new GraphPattern();
453:
454: super .visit(node, null);
455:
456: TupleExpr tupleExpr = graphPattern.buildTupleExpr();
457: tupleExpr = new Slice(tupleExpr, 0, 1);
458:
459: return tupleExpr;
460: }
461:
462: @Override
463: public List<OrderElem> visit(ASTOrderClause node, Object data)
464: throws VisitorException {
465: int childCount = node.jjtGetNumChildren();
466: List<OrderElem> elements = new ArrayList<OrderElem>(childCount);
467:
468: for (int i = 0; i < childCount; i++) {
469: elements.add((OrderElem) node.jjtGetChild(i).jjtAccept(
470: this , null));
471: }
472:
473: return elements;
474: }
475:
476: @Override
477: public OrderElem visit(ASTOrderCondition node, Object data)
478: throws VisitorException {
479: ValueExpr valueExpr = (ValueExpr) node.jjtGetChild(0)
480: .jjtAccept(this , null);
481: return new OrderElem(valueExpr, node.isAscending());
482: }
483:
484: @Override
485: public Integer visit(ASTLimit node, Object data)
486: throws VisitorException {
487: return node.getValue();
488: }
489:
490: @Override
491: public Integer visit(ASTOffset node, Object data)
492: throws VisitorException {
493: return node.getValue();
494: }
495:
496: @Override
497: public Object visit(ASTGraphPatternGroup node, Object data)
498: throws VisitorException {
499: GraphPattern parentGP = graphPattern;
500: graphPattern = new GraphPattern(parentGP);
501:
502: super .visit(node, null);
503:
504: // Filters are scoped to the graph pattern group and do not affect
505: // bindings
506: // external to the group
507: parentGP.addRequiredTE(graphPattern.buildTupleExpr());
508: graphPattern = parentGP;
509:
510: return null;
511: }
512:
513: @Override
514: public Object visit(ASTOptionalGraphPattern node, Object data)
515: throws VisitorException {
516: GraphPattern parentGP = graphPattern;
517: graphPattern = new GraphPattern(parentGP);
518:
519: super .visit(node, null);
520:
521: // Optional constraints also apply to left hand side of operator
522: List<ValueExpr> constraints = graphPattern
523: .removeAllConstraints();
524:
525: TupleExpr leftArg = parentGP.buildTupleExpr();
526: TupleExpr rightArg = graphPattern.buildTupleExpr();
527:
528: LeftJoin leftJoin;
529:
530: if (constraints.isEmpty()) {
531: leftJoin = new LeftJoin(leftArg, rightArg);
532: } else {
533: ValueExpr constraint = constraints.get(0);
534: for (int i = 1; i < constraints.size(); i++) {
535: constraint = new And(constraint, constraints.get(i));
536: }
537:
538: leftJoin = new LeftJoin(leftArg, rightArg, constraint);
539: }
540:
541: graphPattern = parentGP;
542:
543: graphPattern.clear();
544: graphPattern.addRequiredTE(leftJoin);
545:
546: return null;
547: }
548:
549: @Override
550: public Object visit(ASTGraphGraphPattern node, Object data)
551: throws VisitorException {
552: Var oldContext = graphPattern.getContextVar();
553: Scope oldScope = graphPattern.getStatementPatternScope();
554:
555: ValueExpr newContext = (ValueExpr) node.jjtGetChild(0)
556: .jjtAccept(this , null);
557:
558: graphPattern.setContextVar(valueExpr2Var(newContext));
559: graphPattern.setStatementPatternScope(Scope.NAMED_CONTEXTS);
560:
561: node.jjtGetChild(1).jjtAccept(this , null);
562:
563: graphPattern.setContextVar(oldContext);
564: graphPattern.setStatementPatternScope(oldScope);
565:
566: return null;
567: }
568:
569: @Override
570: public Object visit(ASTUnionGraphPattern node, Object data)
571: throws VisitorException {
572: GraphPattern parentGP = graphPattern;
573:
574: graphPattern = new GraphPattern(parentGP);
575: node.jjtGetChild(0).jjtAccept(this , null);
576: TupleExpr leftArg = graphPattern.buildTupleExpr();
577:
578: graphPattern = new GraphPattern(parentGP);
579: node.jjtGetChild(1).jjtAccept(this , null);
580: TupleExpr rightArg = graphPattern.buildTupleExpr();
581:
582: parentGP.addRequiredTE(new Union(leftArg, rightArg));
583: graphPattern = parentGP;
584:
585: return null;
586: }
587:
588: @Override
589: public Object visit(ASTPropertyList propListNode, Object data)
590: throws VisitorException {
591: ValueExpr subject = (ValueExpr) data;
592: ValueExpr predicate = (ValueExpr) propListNode.getVerb()
593: .jjtAccept(this , null);
594: @SuppressWarnings("unchecked")
595: List<ValueExpr> objectList = (List<ValueExpr>) propListNode
596: .getObjectList().jjtAccept(this , null);
597:
598: Var subjVar = valueExpr2Var(subject);
599: Var predVar = valueExpr2Var(predicate);
600:
601: for (ValueExpr object : objectList) {
602: Var objVar = valueExpr2Var(object);
603: graphPattern.addRequiredSP(subjVar, predVar, objVar);
604: }
605:
606: ASTPropertyList nextPropList = propListNode
607: .getNextPropertyList();
608: if (nextPropList != null) {
609: nextPropList.jjtAccept(this , subject);
610: }
611:
612: return null;
613: }
614:
615: @Override
616: public List<ValueExpr> visit(ASTObjectList node, Object data)
617: throws VisitorException {
618: int childCount = node.jjtGetNumChildren();
619: List<ValueExpr> result = new ArrayList<ValueExpr>(childCount);
620:
621: for (int i = 0; i < childCount; i++) {
622: result.add((ValueExpr) node.jjtGetChild(i).jjtAccept(this ,
623: null));
624: }
625:
626: return result;
627: }
628:
629: @Override
630: public Var visit(ASTBlankNodePropertyList node, Object data)
631: throws VisitorException {
632: Var bnodeVar = createAnonVar(node.getVarName());
633: super .visit(node, bnodeVar);
634: return bnodeVar;
635: }
636:
637: @Override
638: public Var visit(ASTCollection node, Object data)
639: throws VisitorException {
640: String listVarName = node.getVarName();
641: Var rootListVar = createAnonVar(listVarName);
642:
643: Var listVar = rootListVar;
644:
645: int childCount = node.jjtGetNumChildren();
646: for (int i = 0; i < childCount; i++) {
647: ValueExpr childValue = (ValueExpr) node.jjtGetChild(i)
648: .jjtAccept(this , null);
649:
650: Var childVar = valueExpr2Var(childValue);
651: graphPattern.addRequiredSP(listVar,
652: createConstVar(RDF.FIRST), childVar);
653:
654: Var nextListVar;
655: if (i == childCount - 1) {
656: nextListVar = createConstVar(RDF.NIL);
657: } else {
658: nextListVar = createAnonVar(listVarName + "-" + (i + 1));
659: }
660:
661: graphPattern.addRequiredSP(listVar,
662: createConstVar(RDF.REST), nextListVar);
663: listVar = nextListVar;
664: }
665:
666: return rootListVar;
667: }
668:
669: @Override
670: public Object visit(ASTConstraint node, Object data)
671: throws VisitorException {
672: ValueExpr valueExpr = (ValueExpr) super .visit(node, null);
673: graphPattern.addConstraint(valueExpr);
674:
675: return null;
676: }
677:
678: @Override
679: public Or visit(ASTOr node, Object data) throws VisitorException {
680: ValueExpr leftArg = (ValueExpr) node.jjtGetChild(0).jjtAccept(
681: this , null);
682: ValueExpr rightArg = (ValueExpr) node.jjtGetChild(1).jjtAccept(
683: this , null);
684: return new Or(leftArg, rightArg);
685: }
686:
687: @Override
688: public Object visit(ASTAnd node, Object data)
689: throws VisitorException {
690: ValueExpr leftArg = (ValueExpr) node.jjtGetChild(0).jjtAccept(
691: this , null);
692: ValueExpr rightArg = (ValueExpr) node.jjtGetChild(1).jjtAccept(
693: this , null);
694: return new And(leftArg, rightArg);
695: }
696:
697: @Override
698: public Not visit(ASTNot node, Object data) throws VisitorException {
699: ValueExpr arg = (ValueExpr) super .visit(node, null);
700: return new Not(arg);
701: }
702:
703: @Override
704: public Compare visit(ASTCompare node, Object data)
705: throws VisitorException {
706: ValueExpr leftArg = (ValueExpr) node.jjtGetChild(0).jjtAccept(
707: this , null);
708: ValueExpr rightArg = (ValueExpr) node.jjtGetChild(1).jjtAccept(
709: this , null);
710: return new Compare(leftArg, rightArg, node.getOperator());
711: }
712:
713: @Override
714: public SameTerm visit(ASTSameTerm node, Object data)
715: throws VisitorException {
716: ValueExpr leftArg = (ValueExpr) node.jjtGetChild(0).jjtAccept(
717: this , null);
718: ValueExpr rightArg = (ValueExpr) node.jjtGetChild(1).jjtAccept(
719: this , null);
720: return new SameTerm(leftArg, rightArg);
721: }
722:
723: @Override
724: public MathExpr visit(ASTMath node, Object data)
725: throws VisitorException {
726: ValueExpr leftArg = (ValueExpr) node.jjtGetChild(0).jjtAccept(
727: this , null);
728: ValueExpr rightArg = (ValueExpr) node.jjtGetChild(1).jjtAccept(
729: this , null);
730: return new MathExpr(leftArg, rightArg, node.getOperator());
731: }
732:
733: @Override
734: public Object visit(ASTFunctionCall node, Object data)
735: throws VisitorException {
736: ValueConstant uriNode = (ValueConstant) node.jjtGetChild(0)
737: .jjtAccept(this , null);
738: URI functionURI = (URI) uriNode.getValue();
739:
740: FunctionCall functionCall = new FunctionCall(functionURI
741: .toString());
742:
743: for (int i = 1; i < node.jjtGetNumChildren(); i++) {
744: Node argNode = node.jjtGetChild(i);
745: functionCall.addArg((ValueExpr) argNode.jjtAccept(this ,
746: null));
747: }
748:
749: return functionCall;
750: }
751:
752: @Override
753: public Object visit(ASTStr node, Object data)
754: throws VisitorException {
755: ValueExpr arg = (ValueExpr) node.jjtGetChild(0).jjtAccept(this ,
756: null);
757: return new Str(arg);
758: }
759:
760: @Override
761: public Lang visit(ASTLang node, Object data)
762: throws VisitorException {
763: ValueExpr arg = (ValueExpr) node.jjtGetChild(0).jjtAccept(this ,
764: null);
765: return new Lang(arg);
766: }
767:
768: @Override
769: public Datatype visit(ASTDatatype node, Object data)
770: throws VisitorException {
771: ValueExpr arg = (ValueExpr) node.jjtGetChild(0).jjtAccept(this ,
772: null);
773: return new Datatype(arg);
774: }
775:
776: @Override
777: public Object visit(ASTLangMatches node, Object data)
778: throws VisitorException {
779: ValueExpr leftArg = (ValueExpr) node.jjtGetChild(0).jjtAccept(
780: this , null);
781: ValueExpr rightArg = (ValueExpr) node.jjtGetChild(1).jjtAccept(
782: this , null);
783: return new LangMatches(leftArg, rightArg);
784: }
785:
786: @Override
787: public ValueExpr visit(ASTBound node, Object data)
788: throws VisitorException {
789: Var var = (Var) node.getArg().jjtAccept(this , null);
790: return new Bound(var);
791: }
792:
793: @Override
794: public IsURI visit(ASTIsIRI node, Object data)
795: throws VisitorException {
796: ValueExpr arg = (ValueExpr) node.jjtGetChild(0).jjtAccept(this ,
797: null);
798: return new IsURI(arg);
799: }
800:
801: @Override
802: public IsBNode visit(ASTIsBlank node, Object data)
803: throws VisitorException {
804: ValueExpr arg = (ValueExpr) node.jjtGetChild(0).jjtAccept(this ,
805: null);
806: return new IsBNode(arg);
807: }
808:
809: @Override
810: public IsLiteral visit(ASTIsLiteral node, Object data)
811: throws VisitorException {
812: ValueExpr arg = (ValueExpr) node.jjtGetChild(0).jjtAccept(this ,
813: null);
814: return new IsLiteral(arg);
815: }
816:
817: @Override
818: public Object visit(ASTRegexExpression node, Object data)
819: throws VisitorException {
820: ValueExpr arg = (ValueExpr) node.jjtGetChild(0).jjtAccept(this ,
821: null);
822: ValueExpr pattern = (ValueExpr) node.jjtGetChild(1).jjtAccept(
823: this , null);
824: ValueExpr flags = null;
825: if (node.jjtGetNumChildren() > 2) {
826: flags = (ValueExpr) node.jjtGetChild(2).jjtAccept(this ,
827: null);
828: }
829: return new Regex(arg, pattern, flags);
830: }
831:
832: @Override
833: public Var visit(ASTVar node, Object data) throws VisitorException {
834: Var var = new Var(node.getName());
835: var.setAnonymous(node.isAnonymous());
836: return var;
837: }
838:
839: @Override
840: public ValueConstant visit(ASTIRI node, Object data)
841: throws VisitorException {
842: return new ValueConstant(valueFactory
843: .createURI(node.getValue()));
844: }
845:
846: @Override
847: public Object visit(ASTQName node, Object data)
848: throws VisitorException {
849: throw new VisitorException(
850: "QNames must be resolved before building the query model");
851: }
852:
853: @Override
854: public Object visit(ASTBlankNode node, Object data)
855: throws VisitorException {
856: throw new VisitorException(
857: "Blank nodes must be replaced with variables before building the query model");
858: }
859:
860: @Override
861: public ValueConstant visit(ASTRDFLiteral node, Object data)
862: throws VisitorException {
863: String label = (String) node.getLabel().jjtAccept(this , null);
864: String lang = node.getLang();
865: ASTIRI datatypeNode = node.getDatatype();
866:
867: Literal literal;
868: if (datatypeNode != null) {
869: URI datatype = valueFactory.createURI(datatypeNode
870: .getValue());
871: literal = valueFactory.createLiteral(label, datatype);
872: } else if (lang != null) {
873: literal = valueFactory.createLiteral(label, lang);
874: } else {
875: literal = valueFactory.createLiteral(label);
876: }
877:
878: return new ValueConstant(literal);
879: }
880:
881: @Override
882: public ValueConstant visit(ASTNumericLiteral node, Object data)
883: throws VisitorException {
884: Literal literal = valueFactory.createLiteral(node.getValue(),
885: node.getDatatype());
886: return new ValueConstant(literal);
887: }
888:
889: @Override
890: public ValueConstant visit(ASTTrue node, Object data)
891: throws VisitorException {
892: return new ValueConstant(valueFactory.createLiteral(true));
893: }
894:
895: @Override
896: public ValueConstant visit(ASTFalse node, Object data)
897: throws VisitorException {
898: return new ValueConstant(valueFactory.createLiteral(false));
899: }
900:
901: @Override
902: public String visit(ASTString node, Object data)
903: throws VisitorException {
904: return node.getValue();
905: }
906: }
|