Package org.openrdf.query.parser.serql

Source Code of org.openrdf.query.parser.serql.QueryModelBuilder

/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2008.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.query.parser.serql;

import java.util.ArrayList;
import java.util.List;

import org.openrdf.model.Literal;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.algebra.And;
import org.openrdf.query.algebra.Bound;
import org.openrdf.query.algebra.Compare;
import org.openrdf.query.algebra.CompareAll;
import org.openrdf.query.algebra.CompareAny;
import org.openrdf.query.algebra.Datatype;
import org.openrdf.query.algebra.Difference;
import org.openrdf.query.algebra.Distinct;
import org.openrdf.query.algebra.Exists;
import org.openrdf.query.algebra.Extension;
import org.openrdf.query.algebra.ExtensionElem;
import org.openrdf.query.algebra.FunctionCall;
import org.openrdf.query.algebra.In;
import org.openrdf.query.algebra.Intersection;
import org.openrdf.query.algebra.IsBNode;
import org.openrdf.query.algebra.IsLiteral;
import org.openrdf.query.algebra.IsResource;
import org.openrdf.query.algebra.IsURI;
import org.openrdf.query.algebra.Label;
import org.openrdf.query.algebra.Lang;
import org.openrdf.query.algebra.LocalName;
import org.openrdf.query.algebra.Namespace;
import org.openrdf.query.algebra.Not;
import org.openrdf.query.algebra.Or;
import org.openrdf.query.algebra.Projection;
import org.openrdf.query.algebra.ProjectionElem;
import org.openrdf.query.algebra.ProjectionElemList;
import org.openrdf.query.algebra.Regex;
import org.openrdf.query.algebra.SameTerm;
import org.openrdf.query.algebra.SingletonSet;
import org.openrdf.query.algebra.Slice;
import org.openrdf.query.algebra.StatementPattern;
import org.openrdf.query.algebra.TupleExpr;
import org.openrdf.query.algebra.Union;
import org.openrdf.query.algebra.ValueConstant;
import org.openrdf.query.algebra.ValueExpr;
import org.openrdf.query.algebra.Var;
import org.openrdf.query.algebra.Compare.CompareOp;
import org.openrdf.query.parser.serql.ast.ASTAnd;
import org.openrdf.query.parser.serql.ast.ASTBNode;
import org.openrdf.query.parser.serql.ast.ASTBasicPathExpr;
import org.openrdf.query.parser.serql.ast.ASTBasicPathExprTail;
import org.openrdf.query.parser.serql.ast.ASTBooleanConstant;
import org.openrdf.query.parser.serql.ast.ASTBooleanExpr;
import org.openrdf.query.parser.serql.ast.ASTBound;
import org.openrdf.query.parser.serql.ast.ASTCompare;
import org.openrdf.query.parser.serql.ast.ASTCompareAll;
import org.openrdf.query.parser.serql.ast.ASTCompareAny;
import org.openrdf.query.parser.serql.ast.ASTConstruct;
import org.openrdf.query.parser.serql.ast.ASTConstructQuery;
import org.openrdf.query.parser.serql.ast.ASTDatatype;
import org.openrdf.query.parser.serql.ast.ASTEdge;
import org.openrdf.query.parser.serql.ast.ASTExists;
import org.openrdf.query.parser.serql.ast.ASTFrom;
import org.openrdf.query.parser.serql.ast.ASTFunctionCall;
import org.openrdf.query.parser.serql.ast.ASTGraphIntersect;
import org.openrdf.query.parser.serql.ast.ASTGraphMinus;
import org.openrdf.query.parser.serql.ast.ASTGraphUnion;
import org.openrdf.query.parser.serql.ast.ASTIn;
import org.openrdf.query.parser.serql.ast.ASTIsBNode;
import org.openrdf.query.parser.serql.ast.ASTIsLiteral;
import org.openrdf.query.parser.serql.ast.ASTIsResource;
import org.openrdf.query.parser.serql.ast.ASTIsURI;
import org.openrdf.query.parser.serql.ast.ASTLabel;
import org.openrdf.query.parser.serql.ast.ASTLang;
import org.openrdf.query.parser.serql.ast.ASTLike;
import org.openrdf.query.parser.serql.ast.ASTLimit;
import org.openrdf.query.parser.serql.ast.ASTLiteral;
import org.openrdf.query.parser.serql.ast.ASTLocalName;
import org.openrdf.query.parser.serql.ast.ASTNamespace;
import org.openrdf.query.parser.serql.ast.ASTNode;
import org.openrdf.query.parser.serql.ast.ASTNodeElem;
import org.openrdf.query.parser.serql.ast.ASTNot;
import org.openrdf.query.parser.serql.ast.ASTNull;
import org.openrdf.query.parser.serql.ast.ASTOffset;
import org.openrdf.query.parser.serql.ast.ASTOptPathExpr;
import org.openrdf.query.parser.serql.ast.ASTOptPathExprTail;
import org.openrdf.query.parser.serql.ast.ASTOr;
import org.openrdf.query.parser.serql.ast.ASTPathExpr;
import org.openrdf.query.parser.serql.ast.ASTPathExprTail;
import org.openrdf.query.parser.serql.ast.ASTProjectionElem;
import org.openrdf.query.parser.serql.ast.ASTQueryBody;
import org.openrdf.query.parser.serql.ast.ASTQueryContainer;
import org.openrdf.query.parser.serql.ast.ASTReifiedStat;
import org.openrdf.query.parser.serql.ast.ASTSelect;
import org.openrdf.query.parser.serql.ast.ASTSelectQuery;
import org.openrdf.query.parser.serql.ast.ASTString;
import org.openrdf.query.parser.serql.ast.ASTTupleIntersect;
import org.openrdf.query.parser.serql.ast.ASTTupleMinus;
import org.openrdf.query.parser.serql.ast.ASTTupleUnion;
import org.openrdf.query.parser.serql.ast.ASTURI;
import org.openrdf.query.parser.serql.ast.ASTValueExpr;
import org.openrdf.query.parser.serql.ast.ASTVar;
import org.openrdf.query.parser.serql.ast.ASTWhere;
import org.openrdf.query.parser.serql.ast.VisitorException;

class QueryModelBuilder extends ASTVisitorBase {

  public static TupleExpr buildQueryModel(ASTQueryContainer node, ValueFactory valueFactory)
    throws MalformedQueryException
  {
    try {
      QueryModelBuilder qmBuilder = new QueryModelBuilder(valueFactory);
      return (TupleExpr)node.jjtAccept(qmBuilder, null);
    }
    catch (VisitorException e) {
      throw new MalformedQueryException(e.getMessage(), e);
    }
  }

  /*-----------*
   * Variables *
   *-----------*/

  private ValueFactory valueFactory;

  private int constantVarID = 1;

  private GraphPattern graphPattern;

  /*--------------*
   * Constructors *
   *--------------*/

  public QueryModelBuilder(ValueFactory valueFactory) {
    this.valueFactory = valueFactory;
  }

  /*---------*
   * Methods *
   *---------*/

  private Var createConstantVar(Value value) {
    Var var = new Var("-const-" + constantVarID++);
    var.setAnonymous(true);
    var.setValue(value);
    return var;
  }

  @Override
  public TupleExpr visit(ASTQueryContainer node, Object data)
    throws VisitorException
  {
    // Skip the namespace declarations, any information it contains should
    // already have been processed
    return (TupleExpr)node.getQuery().jjtAccept(this, null);
  }

  @Override
  public TupleExpr visit(ASTTupleUnion node, Object data)
    throws VisitorException
  {
    TupleExpr leftArg = (TupleExpr)node.getLeftArg().jjtAccept(this, null);
    TupleExpr rightArg = (TupleExpr)node.getRightArg().jjtAccept(this, null);

    TupleExpr result = new Union(leftArg, rightArg);

    if (node.isDistinct()) {
      result = new Distinct(result);
    }

    return result;
  }

  @Override
  public TupleExpr visit(ASTTupleMinus node, Object data)
    throws VisitorException
  {
    TupleExpr leftArg = (TupleExpr)node.getLeftArg().jjtAccept(this, null);
    TupleExpr rightArg = (TupleExpr)node.getRightArg().jjtAccept(this, null);

    return new Difference(leftArg, rightArg);
  }

  @Override
  public TupleExpr visit(ASTTupleIntersect node, Object data)
    throws VisitorException
  {
    TupleExpr leftArg = (TupleExpr)node.getLeftArg().jjtAccept(this, null);
    TupleExpr rightArg = (TupleExpr)node.getRightArg().jjtAccept(this, null);

    return new Intersection(leftArg, rightArg);
  }

  @Override
  public TupleExpr visit(ASTGraphUnion node, Object data)
    throws VisitorException
  {
    TupleExpr leftArg = (TupleExpr)node.getLeftArg().jjtAccept(this, null);
    TupleExpr rightArg = (TupleExpr)node.getRightArg().jjtAccept(this, null);

    TupleExpr result = new Union(leftArg, rightArg);

    if (node.isDistinct()) {
      result = new Distinct(result);
    }

    return result;
  }

  @Override
  public TupleExpr visit(ASTGraphMinus node, Object data)
    throws VisitorException
  {
    TupleExpr leftArg = (TupleExpr)node.getLeftArg().jjtAccept(this, null);
    TupleExpr rightArg = (TupleExpr)node.getRightArg().jjtAccept(this, null);

    return new Difference(leftArg, rightArg);
  }

  @Override
  public TupleExpr visit(ASTGraphIntersect node, Object data)
    throws VisitorException
  {
    TupleExpr leftArg = (TupleExpr)node.getLeftArg().jjtAccept(this, null);
    TupleExpr rightArg = (TupleExpr)node.getRightArg().jjtAccept(this, null);

    return new Intersection(leftArg, rightArg);
  }

  @Override
  public TupleExpr visit(ASTSelectQuery node, Object data)
    throws VisitorException
  {
    TupleExpr tupleExpr;

    ASTQueryBody queryBodyNode = node.getQueryBody();

    if (queryBodyNode != null) {
      // Build tuple expression for query body
      tupleExpr = (TupleExpr)queryBodyNode.jjtAccept(this, null);
    }
    else {
      tupleExpr = new SingletonSet();
    }

    // Apply projection
    tupleExpr = (TupleExpr)node.getSelectClause().jjtAccept(this, tupleExpr);

    // process limit and offset clauses, if present.
    ASTLimit limitNode = node.getLimit();
    int limit = -1;
    if (limitNode != null) {
      limit = (Integer)limitNode.jjtAccept(this, null);
    }

    ASTOffset offsetNode = node.getOffset();
    int offset = -1;
    if (offsetNode != null) {
      offset = (Integer)offsetNode.jjtAccept(this, null);
    }

    if (offset >= 1 || limit >= 0) {
      tupleExpr = new Slice(tupleExpr, offset, limit);
    }
    return tupleExpr;
  }

  @Override
  public TupleExpr visit(ASTSelect node, Object data)
    throws VisitorException
  {
    TupleExpr result = (TupleExpr)data;

    Extension extension = new Extension();
    ProjectionElemList projElemList = new ProjectionElemList();

    for (ASTProjectionElem projElemNode : node.getProjectionElemList()) {
      ValueExpr valueExpr = (ValueExpr)projElemNode.getValueExpr().jjtAccept(this, null);

      String alias = projElemNode.getAlias();
      if (alias != null) {
        // aliased projection element
        extension.addElement(new ExtensionElem(valueExpr, alias));
        projElemList.addElement(new ProjectionElem(alias));
      }
      else if (valueExpr instanceof Var) {
        // unaliased variable
        Var projVar = (Var)valueExpr;
        projElemList.addElement(new ProjectionElem(projVar.getName()));
      }
      else {
        throw new IllegalStateException("required alias for non-Var projection elements not found");
      }
    }

    if (!extension.getElements().isEmpty()) {
      extension.setArg(result);
      result = extension;
    }

    result = new Projection(result, projElemList);

    if (node.isDistinct()) {
      result = new Distinct(result);
    }

    return result;
  }

  @Override
  public TupleExpr visit(ASTConstructQuery node, Object data)
    throws VisitorException
  {
    TupleExpr tupleExpr;

    if (node.hasQueryBody()) {
      // Build tuple expression for query body
      tupleExpr = (TupleExpr)node.getQueryBody().jjtAccept(this, null);
    }
    else {
      tupleExpr = new SingletonSet();
    }

    // Create constructor
    ConstructorBuilder cb = new ConstructorBuilder();
    ASTConstruct constructNode = node.getConstructClause();

    if (!constructNode.isWildcard()) {
      TupleExpr constructExpr = (TupleExpr)constructNode.jjtAccept(this, null);
      tupleExpr = cb.buildConstructor(tupleExpr, constructExpr, constructNode.isDistinct());
    }
    else if (node.hasQueryBody()) {
      tupleExpr = cb.buildConstructor(tupleExpr, constructNode.isDistinct());
    }
    // else: "construct *" without query body, just return the SingletonSet

    // process limit and offset clauses, if present.
    ASTLimit limitNode = node.getLimit();
    int limit = -1;
    if (limitNode != null) {
      limit = (Integer)limitNode.jjtAccept(this, null);
    }

    ASTOffset offsetNode = node.getOffset();
    int offset = -1;

    if (offsetNode != null) {
      offset = (Integer)offsetNode.jjtAccept(this, null);
    }

    if (offset >= 1 || limit >= 0) {
      tupleExpr = new Slice(tupleExpr, offset, limit);
    }

    return tupleExpr;
  }

  @Override
  public TupleExpr visit(ASTConstruct node, Object data)
    throws VisitorException
  {
    assert !node.isWildcard() : "Cannot build constructor for wildcards";

    graphPattern = new GraphPattern(graphPattern);
    try {
      super.visit(node, data);
      return graphPattern.buildTupleExpr();
    }
    finally {
      graphPattern = graphPattern.getParent();
    }
  }

  @Override
  public TupleExpr visit(ASTQueryBody node, Object data)
    throws VisitorException
  {
    graphPattern = new GraphPattern(graphPattern);
    try {
      super.visit(node, data);
      return graphPattern.buildTupleExpr();
    }
    finally {
      graphPattern = graphPattern.getParent();
    }
  }

  @Override
  public Object visit(ASTFrom node, Object data)
    throws VisitorException
  {
    StatementPattern.Scope scope = StatementPattern.Scope.DEFAULT_CONTEXTS;
    Var contextVar = null;

    if (node.hasContextID()) {
      scope = StatementPattern.Scope.NAMED_CONTEXTS;
      ValueExpr contextID = (ValueExpr)node.getContextID().jjtAccept(this, null);

      if (contextID instanceof Var) {
        contextVar = (Var)contextID;
      }
      else if (contextID instanceof ValueConstant) {
        ValueConstant vc = (ValueConstant)contextID;
        contextVar = createConstantVar(vc.getValue());
      }
      else {
        throw new IllegalArgumentException("Unexpected contextID result type: " + contextID.getClass());
      }
    }

    graphPattern.setStatementPatternScope(scope);
    graphPattern.setContextVar(contextVar);

    for (ASTPathExpr pathExprNode : node.getPathExprList()) {
      pathExprNode.jjtAccept(this, null);
    }

    return null;
  }

  @Override
  public Integer visit(ASTWhere node, Object data)
    throws VisitorException
  {
    ValueExpr valueExpr = (ValueExpr)node.getCondition().jjtAccept(this, null);
    graphPattern.addConstraint(valueExpr);
    return null;
  }

  @Override
  public Integer visit(ASTLimit node, Object data)
    throws VisitorException
  {
    return node.getValue();
  }

  @Override
  public Integer visit(ASTOffset node, Object data)
    throws VisitorException
  {
    return node.getValue();
  }

  @Override
  public Object visit(ASTBasicPathExpr node, Object data)
    throws VisitorException
  {
    // process subject node
    List<Var> subjVars = (List<Var>)node.getHead().jjtAccept(this, null);

    // supply subject vars to tail segment
    node.getTail().jjtAccept(this, subjVars);

    return null;
  }

  @Override
  public Object visit(ASTOptPathExpr node, Object data)
    throws VisitorException
  {
    // Create new sub-graph pattern for optional path expressions
    graphPattern = new GraphPattern(graphPattern);

    super.visit(node, data);

    graphPattern.getParent().addOptionalTE(graphPattern);
    graphPattern = graphPattern.getParent();

    return null;
  }

  @Override
  public Object visit(ASTBasicPathExprTail tailNode, Object data)
    throws VisitorException
  {
    List<Var> subjVars = (List<Var>)data;
    Var predVar = (Var)tailNode.getEdge().jjtAccept(this, null);
    List<Var> objVars = (List<Var>)tailNode.getNode().jjtAccept(this, null);

    Var contextVar = graphPattern.getContextVar();
    StatementPattern.Scope spScope = graphPattern.getStatementPatternScope();

    for (Var subjVar : subjVars) {
      for (Var objVar : objVars) {
        StatementPattern sp = new StatementPattern(spScope, subjVar, predVar, objVar, contextVar);
        graphPattern.addRequiredTE(sp);
      }
    }

    // Process next tail segment
    ASTPathExprTail nextTailNode = tailNode.getNextTail();
    if (nextTailNode != null) {
      List<Var> joinVars = nextTailNode.isBranch() ? subjVars : objVars;
      nextTailNode.jjtAccept(this, joinVars);
    }

    return null;
  }

  @Override
  public Object visit(ASTOptPathExprTail tailNode, Object data)
    throws VisitorException
  {
    List<Var> subjVars = (List<Var>)data;

    // Create new sub-graph pattern for optional path expressions
    graphPattern = new GraphPattern(graphPattern);

    // optional path expression tail
    tailNode.getOptionalTail().jjtAccept(this, subjVars);

    ASTWhere whereNode = tailNode.getWhereClause();
    if (whereNode != null) {
      // boolean contraint on optional path expression tail
      whereNode.jjtAccept(this, null);
    }

    graphPattern.getParent().addOptionalTE(graphPattern);
    graphPattern = graphPattern.getParent();

    ASTPathExprTail nextTailNode = tailNode.getNextTail();
    if (nextTailNode != null) {
      // branch after optional path expression tail
      nextTailNode.jjtAccept(this, subjVars);
    }

    return null;
  }

  @Override
  public Var visit(ASTEdge node, Object data)
    throws VisitorException
  {
    ValueExpr arg = (ValueExpr)node.getValueExpr().jjtAccept(this, null);

    if (arg instanceof Var) {
      return (Var)arg;
    }
    else if (arg instanceof ValueConstant) {
      ValueConstant vc = (ValueConstant)arg;
      return createConstantVar(vc.getValue());
    }
    else {
      throw new IllegalArgumentException("Unexpected edge argument type: " + arg.getClass());
    }
  }

  @Override
  public List<Var> visit(ASTNode node, Object data)
    throws VisitorException
  {
    List<Var> nodeVars = new ArrayList<Var>();

    for (ASTNodeElem nodeElem : node.getNodeElemList()) {
      Var nodeVar = (Var)nodeElem.jjtAccept(this, null);
      nodeVars.add(nodeVar);
    }

    // Create any implicit unequalities
    for (int i = 0; i < nodeVars.size() - 1; i++) {
      Var var1 = nodeVars.get(i);

      for (int j = i + 1; j < nodeVars.size(); j++) {
        Var var2 = nodeVars.get(j);

        // At least one of the variables should be non-constant
        // for the unequality to make any sense:
        if (!var1.hasValue() || !var2.hasValue()) {
          graphPattern.addConstraint(new Not(new SameTerm(var1, var2)));
        }
      }
    }

    return nodeVars;
  }

  @Override
  public Var visit(ASTNodeElem node, Object data)
    throws VisitorException
  {
    ValueExpr valueExpr = (ValueExpr)node.getChild().jjtAccept(this, null);

    if (valueExpr instanceof Var) {
      return (Var)valueExpr;
    }
    else if (valueExpr instanceof ValueConstant) {
      ValueConstant vc = (ValueConstant)valueExpr;
      return createConstantVar(vc.getValue());
    }
    else {
      throw new IllegalArgumentException("Unexpected node element result type: " + valueExpr.getClass());
    }
  }

  @Override
  public Var visit(ASTReifiedStat node, Object data)
    throws VisitorException
  {
    assert node.getID() != null : "ID variable not set";

    Var subjVar = (Var)node.getSubject().jjtAccept(this, null);
    Var predVar = (Var)node.getPredicate().jjtAccept(this, null);
    Var objVar = (Var)node.getObject().jjtAccept(this, null);
    Var idVar = (Var)node.getID().jjtAccept(this, null);

    Var contextVar = graphPattern.getContextVar();
    StatementPattern.Scope spScope = graphPattern.getStatementPatternScope();

    Var rdfType = new Var("_rdfType", RDF.TYPE);
    Var rdfStatement = new Var("_rdfStatement", RDF.STATEMENT);
    Var rdfSubject = new Var("_rdfSubject", RDF.SUBJECT);
    Var rdfPredicate = new Var("_rdfPredicate", RDF.PREDICATE);
    Var rdfObject = new Var("_rdfObject", RDF.OBJECT);

    graphPattern.addRequiredTE(new StatementPattern(spScope, idVar, rdfType, rdfStatement, contextVar));
    graphPattern.addRequiredTE(new StatementPattern(spScope, idVar, rdfSubject, subjVar, contextVar));
    graphPattern.addRequiredTE(new StatementPattern(spScope, idVar, rdfPredicate, predVar, contextVar));
    graphPattern.addRequiredTE(new StatementPattern(spScope, idVar, rdfObject, objVar, contextVar));

    return idVar;
  }

  @Override
  public ValueExpr visit(ASTOr node, Object data)
    throws VisitorException
  {
    Or or = new Or();

    for (ASTBooleanExpr expr : node.getOperandList()) {
      ValueExpr arg = (ValueExpr)expr.jjtAccept(this, null);
      or.addArg(arg);
    }

    return or;
  }

  @Override
  public ValueExpr visit(ASTAnd node, Object data)
    throws VisitorException
  {
    And and = new And();

    for (ASTBooleanExpr expr : node.getOperandList()) {
      ValueExpr arg = (ValueExpr)expr.jjtAccept(this, null);
      and.addArg(arg);
    }

    return and;
  }

  @Override
  public ValueConstant visit(ASTBooleanConstant node, Object data)
    throws VisitorException
  {
    return new ValueConstant(valueFactory.createLiteral(node.getValue()));
  }

  @Override
  public Not visit(ASTNot node, Object data)
    throws VisitorException
  {
    return new Not((ValueExpr)super.visit(node, data));
  }

  @Override
  public Bound visit(ASTBound node, Object data)
    throws VisitorException
  {
    return new Bound((Var)super.visit(node, data));
  }

  @Override
  public IsResource visit(ASTIsResource node, Object data)
    throws VisitorException
  {
    return new IsResource((ValueExpr)super.visit(node, data));
  }

  @Override
  public IsLiteral visit(ASTIsLiteral node, Object data)
    throws VisitorException
  {
    return new IsLiteral((ValueExpr)super.visit(node, data));
  }

  @Override
  public IsURI visit(ASTIsURI node, Object data)
    throws VisitorException
  {
    return new IsURI((ValueExpr)super.visit(node, data));
  }

  @Override
  public IsBNode visit(ASTIsBNode node, Object data)
    throws VisitorException
  {
    return new IsBNode((ValueExpr)super.visit(node, data));
  }

  @Override
  public Exists visit(ASTExists node, Object data)
    throws VisitorException
  {
    return new Exists((TupleExpr)super.visit(node, data));
  }

  @Override
  public Compare visit(ASTCompare node, Object data)
    throws VisitorException
  {
    ValueExpr leftArg = (ValueExpr)node.getLeftOperand().jjtAccept(this, null);
    ValueExpr rightArg = (ValueExpr)node.getRightOperand().jjtAccept(this, null);
    CompareOp operator = node.getOperator().getValue();

    return new Compare(leftArg, rightArg, operator);
  }

  @Override
  public CompareAny visit(ASTCompareAny node, Object data)
    throws VisitorException
  {
    ValueExpr valueExpr = (ValueExpr)node.getLeftOperand().jjtAccept(this, null);
    TupleExpr tupleExpr = (TupleExpr)node.getRightOperand().jjtAccept(this, null);
    CompareOp op = node.getOperator().getValue();

    return new CompareAny(valueExpr, tupleExpr, op);
  }

  @Override
  public CompareAll visit(ASTCompareAll node, Object data)
    throws VisitorException
  {
    ValueExpr valueExpr = (ValueExpr)node.getLeftOperand().jjtAccept(this, null);
    TupleExpr tupleExpr = (TupleExpr)node.getRightOperand().jjtAccept(this, null);
    CompareOp op = node.getOperator().getValue();

    return new CompareAll(valueExpr, tupleExpr, op);
  }

  @Override
  public Regex visit(ASTLike node, Object data)
    throws VisitorException
  {
    ValueExpr expr = (ValueExpr)node.getValueExpr().jjtAccept(this, null);
    String pattern = (String)node.getPattern().jjtAccept(this, null);
    boolean caseSensitive = !node.ignoreCase();

    return new Regex(expr, pattern, caseSensitive);
  }

  @Override
  public In visit(ASTIn node, Object data)
    throws VisitorException
  {
    ValueExpr valueExpr = (ValueExpr)node.getLeftOperand().jjtAccept(this, null);
    TupleExpr tupleExpr = (TupleExpr)node.getRightOperand().jjtAccept(this, null);
    return new In(valueExpr, tupleExpr);
  }

  @Override
  public Var visit(ASTVar node, Object data)
    throws VisitorException
  {
    Var var = new Var(node.getName());
    var.setAnonymous(node.isAnonymous());
    return var;
  }

  @Override
  public Datatype visit(ASTDatatype node, Object data)
    throws VisitorException
  {
    return new Datatype((ValueExpr)super.visit(node, data));
  }

  @Override
  public Lang visit(ASTLang node, Object data)
    throws VisitorException
  {
    return new Lang((ValueExpr)super.visit(node, data));
  }

  @Override
  public Label visit(ASTLabel node, Object data)
    throws VisitorException
  {
    return new Label((ValueExpr)super.visit(node, data));
  }

  @Override
  public Namespace visit(ASTNamespace node, Object data)
    throws VisitorException
  {
    return new Namespace((ValueExpr)super.visit(node, data));
  }

  @Override
  public LocalName visit(ASTLocalName node, Object data)
    throws VisitorException
  {
    return new LocalName((ValueExpr)super.visit(node, data));
  }

  @Override
  public FunctionCall visit(ASTFunctionCall node, Object data)
    throws VisitorException
  {
    ValueConstant vc = (ValueConstant)node.getURI().jjtAccept(this, null);
    assert vc.getValue() instanceof URI;

    FunctionCall functionCall = new FunctionCall(vc.getValue().toString());

    for (ASTValueExpr argExpr : node.getArgList()) {
      functionCall.addArg((ValueExpr)argExpr.jjtAccept(this, null));
    }

    return functionCall;
  }

  @Override
  public Object visit(ASTNull node, Object data)
    throws VisitorException
  {
    throw new VisitorException(
        "Use of NULL values in SeRQL queries has been deprecated, use BOUND(...) instead");
  }

  @Override
  public ValueConstant visit(ASTURI node, Object data)
    throws VisitorException
  {
    return new ValueConstant(valueFactory.createURI(node.getValue()));
  }

  @Override
  public ValueConstant visit(ASTBNode node, Object data)
    throws VisitorException
  {
    return new ValueConstant(valueFactory.createBNode(node.getID()));
  }

  @Override
  public ValueConstant visit(ASTLiteral litNode, Object data)
    throws VisitorException
  {
    URI datatype = null;

    // Get datatype URI from child URI node, if present
    ASTValueExpr dtNode = litNode.getDatatypeNode();
    if (dtNode instanceof ASTURI) {
      datatype = valueFactory.createURI(((ASTURI)dtNode).getValue());
    }
    else if (dtNode != null) {
      throw new IllegalArgumentException("Unexpected datatype type: " + dtNode.getClass());
    }

    Literal literal;
    if (datatype != null) {
      literal = valueFactory.createLiteral(litNode.getLabel(), datatype);
    }
    else if (litNode.hasLang()) {
      literal = valueFactory.createLiteral(litNode.getLabel(), litNode.getLang());
    }
    else {
      literal = valueFactory.createLiteral(litNode.getLabel());
    }

    return new ValueConstant(literal);
  }

  @Override
  public String visit(ASTString node, Object data)
    throws VisitorException
  {
    return node.getValue();
  }
}
TOP

Related Classes of org.openrdf.query.parser.serql.QueryModelBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.