Package org.openrdf.query.parser.sparql

Source Code of org.openrdf.query.parser.sparql.TupleExprBuilder

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.algebra.And;
import org.openrdf.query.algebra.BNodeGenerator;
import org.openrdf.query.algebra.Bound;
import org.openrdf.query.algebra.Compare;
import org.openrdf.query.algebra.Datatype;
import org.openrdf.query.algebra.Distinct;
import org.openrdf.query.algebra.EmptySet;
import org.openrdf.query.algebra.Extension;
import org.openrdf.query.algebra.ExtensionElem;
import org.openrdf.query.algebra.Filter;
import org.openrdf.query.algebra.FunctionCall;
import org.openrdf.query.algebra.IsBNode;
import org.openrdf.query.algebra.IsLiteral;
import org.openrdf.query.algebra.IsURI;
import org.openrdf.query.algebra.Join;
import org.openrdf.query.algebra.Lang;
import org.openrdf.query.algebra.LangMatches;
import org.openrdf.query.algebra.LeftJoin;
import org.openrdf.query.algebra.MathExpr;
import org.openrdf.query.algebra.MultiProjection;
import org.openrdf.query.algebra.Not;
import org.openrdf.query.algebra.Or;
import org.openrdf.query.algebra.Order;
import org.openrdf.query.algebra.OrderElem;
import org.openrdf.query.algebra.Projection;
import org.openrdf.query.algebra.ProjectionElem;
import org.openrdf.query.algebra.ProjectionElemList;
import org.openrdf.query.algebra.Reduced;
import org.openrdf.query.algebra.Regex;
import org.openrdf.query.algebra.SameTerm;
import org.openrdf.query.algebra.Slice;
import org.openrdf.query.algebra.StatementPattern;
import org.openrdf.query.algebra.Str;
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.StatementPattern.Scope;
import org.openrdf.query.algebra.helpers.StatementPatternCollector;
import org.openrdf.query.parser.sparql.ast.ASTAnd;
import org.openrdf.query.parser.sparql.ast.ASTAskQuery;
import org.openrdf.query.parser.sparql.ast.ASTBlankNode;
import org.openrdf.query.parser.sparql.ast.ASTBlankNodePropertyList;
import org.openrdf.query.parser.sparql.ast.ASTBound;
import org.openrdf.query.parser.sparql.ast.ASTCollection;
import org.openrdf.query.parser.sparql.ast.ASTCompare;
import org.openrdf.query.parser.sparql.ast.ASTConstraint;
import org.openrdf.query.parser.sparql.ast.ASTConstruct;
import org.openrdf.query.parser.sparql.ast.ASTConstructQuery;
import org.openrdf.query.parser.sparql.ast.ASTDatatype;
import org.openrdf.query.parser.sparql.ast.ASTDescribe;
import org.openrdf.query.parser.sparql.ast.ASTDescribeQuery;
import org.openrdf.query.parser.sparql.ast.ASTFalse;
import org.openrdf.query.parser.sparql.ast.ASTFunctionCall;
import org.openrdf.query.parser.sparql.ast.ASTGraphGraphPattern;
import org.openrdf.query.parser.sparql.ast.ASTGraphPatternGroup;
import org.openrdf.query.parser.sparql.ast.ASTIRI;
import org.openrdf.query.parser.sparql.ast.ASTIsBlank;
import org.openrdf.query.parser.sparql.ast.ASTIsIRI;
import org.openrdf.query.parser.sparql.ast.ASTIsLiteral;
import org.openrdf.query.parser.sparql.ast.ASTLang;
import org.openrdf.query.parser.sparql.ast.ASTLangMatches;
import org.openrdf.query.parser.sparql.ast.ASTLimit;
import org.openrdf.query.parser.sparql.ast.ASTMath;
import org.openrdf.query.parser.sparql.ast.ASTNot;
import org.openrdf.query.parser.sparql.ast.ASTNumericLiteral;
import org.openrdf.query.parser.sparql.ast.ASTObjectList;
import org.openrdf.query.parser.sparql.ast.ASTOffset;
import org.openrdf.query.parser.sparql.ast.ASTOptionalGraphPattern;
import org.openrdf.query.parser.sparql.ast.ASTOr;
import org.openrdf.query.parser.sparql.ast.ASTOrderClause;
import org.openrdf.query.parser.sparql.ast.ASTOrderCondition;
import org.openrdf.query.parser.sparql.ast.ASTPropertyList;
import org.openrdf.query.parser.sparql.ast.ASTQName;
import org.openrdf.query.parser.sparql.ast.ASTQueryContainer;
import org.openrdf.query.parser.sparql.ast.ASTRDFLiteral;
import org.openrdf.query.parser.sparql.ast.ASTRegexExpression;
import org.openrdf.query.parser.sparql.ast.ASTSameTerm;
import org.openrdf.query.parser.sparql.ast.ASTSelect;
import org.openrdf.query.parser.sparql.ast.ASTSelectQuery;
import org.openrdf.query.parser.sparql.ast.ASTStr;
import org.openrdf.query.parser.sparql.ast.ASTString;
import org.openrdf.query.parser.sparql.ast.ASTTrue;
import org.openrdf.query.parser.sparql.ast.ASTUnionGraphPattern;
import org.openrdf.query.parser.sparql.ast.ASTVar;
import org.openrdf.query.parser.sparql.ast.Node;
import org.openrdf.query.parser.sparql.ast.VisitorException;

/**
* @author Arjohn Kampman
*/
class TupleExprBuilder extends ASTVisitorBase {

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

  private ValueFactory valueFactory;

  private GraphPattern graphPattern;

  private int constantVarID = 1;

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

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

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

  private Var valueExpr2Var(ValueExpr valueExpr) {
    if (valueExpr instanceof Var) {
      return (Var)valueExpr;
    }
    else if (valueExpr instanceof ValueConstant) {
      return createConstVar(((ValueConstant)valueExpr).getValue());
    }
    else if (valueExpr == null) {
      throw new IllegalArgumentException("valueExpr is null");
    }
    else {
      throw new IllegalArgumentException("valueExpr is a: " + valueExpr.getClass());
    }
  }

  private Var createConstVar(Value value) {
    Var var = createAnonVar("-const-" + constantVarID++);
    var.setValue(value);
    return var;
  }

  private Var createAnonVar(String varName) {
    Var var = new Var(varName);
    var.setAnonymous(true);
    return var;
  }

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

  @Override
  public TupleExpr visit(ASTSelectQuery node, Object data)
    throws VisitorException
  {
    // Start with building the graph pattern
    graphPattern = new GraphPattern();
    node.getWhereClause().jjtAccept(this, null);
    TupleExpr tupleExpr = graphPattern.buildTupleExpr();

    // Apply result ordering
    ASTOrderClause orderNode = node.getOrderClause();
    if (orderNode != null) {
      List<OrderElem> orderElemements = (List<OrderElem>)orderNode.jjtAccept(this, null);
      tupleExpr = new Order(tupleExpr, orderElemements);
    }

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

    // Process limit and offset clauses
    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;

    ProjectionElemList projElemList = new ProjectionElemList();

    for (int i = 0; i < node.jjtGetNumChildren(); i++) {
      Var projVar = (Var)node.jjtGetChild(i).jjtAccept(this, null);
      projElemList.addElement(new ProjectionElem(projVar.getName()));
    }

    result = new Projection(result, projElemList);

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

    return result;
  }

  @Override
  public TupleExpr visit(ASTConstructQuery node, Object data)
    throws VisitorException
  {
    // Start with building the graph pattern
    graphPattern = new GraphPattern();
    node.getWhereClause().jjtAccept(this, null);
    TupleExpr tupleExpr = graphPattern.buildTupleExpr();

    // Apply result ordering
    ASTOrderClause orderNode = node.getOrderClause();
    if (orderNode != null) {
      List<OrderElem> orderElemements = (List<OrderElem>)orderNode.jjtAccept(this, null);
      tupleExpr = new Order(tupleExpr, orderElemements);
    }

    // Process construct clause
    tupleExpr = (TupleExpr)node.getConstruct().jjtAccept(this, tupleExpr);

    // process limit and offset clauses
    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
  {
    TupleExpr result = (TupleExpr)data;

    // Collect construct triples
    graphPattern = new GraphPattern();
    super.visit(node, null);
    TupleExpr constructExpr = graphPattern.buildTupleExpr();

    // Retrieve all StatementPattern's from the construct expression
    List<StatementPattern> statementPatterns = StatementPatternCollector.process(constructExpr);

    Set<Var> constructVars = getConstructVars(statementPatterns);

    // Create BNodeGenerator's for all anonymous variables
    Map<Var, ExtensionElem> extElemMap = new HashMap<Var, ExtensionElem>();

    for (Var var : constructVars) {
      if (var.isAnonymous() && !extElemMap.containsKey(var)) {
        ValueExpr valueExpr;

        if (var.hasValue()) {
          valueExpr = new ValueConstant(var.getValue());
        }
        else {
          valueExpr = new BNodeGenerator();
        }

        extElemMap.put(var, new ExtensionElem(valueExpr, var.getName()));
      }
    }

    if (!extElemMap.isEmpty()) {
      result = new Extension(result, extElemMap.values());
    }

    // Create a Projection for each StatementPattern in the constructor
    List<ProjectionElemList> projList = new ArrayList<ProjectionElemList>();

    for (StatementPattern sp : statementPatterns) {
      ProjectionElemList projElemList = new ProjectionElemList();

      projElemList.addElement(new ProjectionElem(sp.getSubjectVar().getName(), "subject"));
      projElemList.addElement(new ProjectionElem(sp.getPredicateVar().getName(), "predicate"));
      projElemList.addElement(new ProjectionElem(sp.getObjectVar().getName(), "object"));

      projList.add(projElemList);
    }

    if (projList.size() == 1) {
      result = new Projection(result, projList.get(0));
    }
    else if (projList.size() > 1) {
      result = new MultiProjection(result, projList);
    }
    else {
      // Empty constructor
      result = new EmptySet();
    }

    return new Reduced(result);
  }

  /**
   * Gets the set of variables that are relevant for the constructor. This
   * method accumulates all subject, predicate and object variables from the
   * supplied statement patterns, but ignores any context variables.
   */
  private Set<Var> getConstructVars(Collection<StatementPattern> statementPatterns) {
    Set<Var> vars = new LinkedHashSet<Var>(statementPatterns.size() * 2);

    for (StatementPattern sp : statementPatterns) {
      vars.add(sp.getSubjectVar());
      vars.add(sp.getPredicateVar());
      vars.add(sp.getObjectVar());
    }

    return vars;
  }

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

    if (node.getWhereClause() != null) {
      // Start with building the graph pattern
      graphPattern = new GraphPattern();
      node.getWhereClause().jjtAccept(this, null);
      tupleExpr = graphPattern.buildTupleExpr();

      // Apply result ordering
      ASTOrderClause orderNode = node.getOrderClause();
      if (orderNode != null) {
        List<OrderElem> orderElemements = (List<OrderElem>)orderNode.jjtAccept(this, null);
        tupleExpr = new Order(tupleExpr, orderElemements);
      }

      // Process limit and offset clauses
      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);
      }
    }

    // Process describe clause last
    return (TupleExpr)node.getDescribe().jjtAccept(this, tupleExpr);
  }

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

    // Create a graph query that produces the statements that have the
    // requests resources as subject or object
    Var subjVar = createAnonVar("-descr-subj");
    Var predVar = createAnonVar("-descr-pred");
    Var objVar = createAnonVar("-descr-obj");
    StatementPattern sp = new StatementPattern(subjVar, predVar, objVar);

    if (result == null) {
      result = sp;
    }
    else {
      result = new Join(result, sp);
    }

    List<SameTerm> sameTerms = new ArrayList<SameTerm>(2 * node.jjtGetNumChildren());

    for (int i = 0; i < node.jjtGetNumChildren(); i++) {
      ValueExpr resource = (ValueExpr)node.jjtGetChild(i).jjtAccept(this, null);

      sameTerms.add(new SameTerm(subjVar.clone(), resource));
      sameTerms.add(new SameTerm(objVar.clone(), resource));
    }

    ValueExpr constraint = new Or(sameTerms);

    result = new Filter(result, constraint);

    ProjectionElemList projElemList = new ProjectionElemList();
    projElemList.addElement(new ProjectionElem(subjVar.getName(), "subject"));
    projElemList.addElement(new ProjectionElem(predVar.getName(), "predicate"));
    projElemList.addElement(new ProjectionElem(objVar.getName(), "object"));
    result = new Projection(result, projElemList);

    return new Reduced(result);
  }

  @Override
  public TupleExpr visit(ASTAskQuery node, Object data)
    throws VisitorException
  {
    graphPattern = new GraphPattern();

    super.visit(node, null);

    TupleExpr tupleExpr = graphPattern.buildTupleExpr();
    tupleExpr = new Slice(tupleExpr, 0, 1);

    return tupleExpr;
  }

  @Override
  public List<OrderElem> visit(ASTOrderClause node, Object data)
    throws VisitorException
  {
    int childCount = node.jjtGetNumChildren();
    List<OrderElem> elements = new ArrayList<OrderElem>(childCount);

    for (int i = 0; i < childCount; i++) {
      elements.add((OrderElem)node.jjtGetChild(i).jjtAccept(this, null));
    }

    return elements;
  }

  @Override
  public OrderElem visit(ASTOrderCondition node, Object data)
    throws VisitorException
  {
    ValueExpr valueExpr = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    return new OrderElem(valueExpr, node.isAscending());
  }

  @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(ASTGraphPatternGroup node, Object data)
    throws VisitorException
  {
    GraphPattern parentGP = graphPattern;
    graphPattern = new GraphPattern(parentGP);

    super.visit(node, null);

    // Filters are scoped to the graph pattern group and do not affect
    // bindings
    // external to the group
    parentGP.addRequiredTE(graphPattern.buildTupleExpr());
    graphPattern = parentGP;

    return null;
  }

  @Override
  public Object visit(ASTOptionalGraphPattern node, Object data)
    throws VisitorException
  {
    GraphPattern parentGP = graphPattern;
    graphPattern = new GraphPattern(parentGP);

    super.visit(node, null);

    // Optional constraints also apply to left hand side of operator
    List<ValueExpr> constraints = graphPattern.removeAllConstraints();

    TupleExpr leftArg = parentGP.buildTupleExpr();
    TupleExpr rightArg = graphPattern.buildTupleExpr();

    LeftJoin leftJoin;

    if (constraints.isEmpty()) {
      leftJoin = new LeftJoin(leftArg, rightArg);
    }
    else {
      ValueExpr constraint = new And(constraints);

      leftJoin = new LeftJoin(leftArg, rightArg, constraint);
    }

    graphPattern = parentGP;

    graphPattern.clear();
    graphPattern.addRequiredTE(leftJoin);

    return null;
  }

  @Override
  public Object visit(ASTGraphGraphPattern node, Object data)
    throws VisitorException
  {
    Var oldContext = graphPattern.getContextVar();
    Scope oldScope = graphPattern.getStatementPatternScope();

    ValueExpr newContext = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);

    graphPattern.setContextVar(valueExpr2Var(newContext));
    graphPattern.setStatementPatternScope(Scope.NAMED_CONTEXTS);

    node.jjtGetChild(1).jjtAccept(this, null);

    graphPattern.setContextVar(oldContext);
    graphPattern.setStatementPatternScope(oldScope);

    return null;
  }

  @Override
  public Object visit(ASTUnionGraphPattern node, Object data)
    throws VisitorException
  {
    GraphPattern parentGP = graphPattern;

    graphPattern = new GraphPattern(parentGP);
    node.jjtGetChild(0).jjtAccept(this, null);
    TupleExpr leftArg = graphPattern.buildTupleExpr();

    graphPattern = new GraphPattern(parentGP);
    node.jjtGetChild(1).jjtAccept(this, null);
    TupleExpr rightArg = graphPattern.buildTupleExpr();

    parentGP.addRequiredTE(new Union(leftArg, rightArg));
    graphPattern = parentGP;

    return null;
  }

  @Override
  public Object visit(ASTPropertyList propListNode, Object data)
    throws VisitorException
  {
    ValueExpr subject = (ValueExpr)data;
    ValueExpr predicate = (ValueExpr)propListNode.getVerb().jjtAccept(this, null);
    @SuppressWarnings("unchecked")
    List<ValueExpr> objectList = (List<ValueExpr>)propListNode.getObjectList().jjtAccept(this, null);

    Var subjVar = valueExpr2Var(subject);
    Var predVar = valueExpr2Var(predicate);

    for (ValueExpr object : objectList) {
      Var objVar = valueExpr2Var(object);
      graphPattern.addRequiredSP(subjVar, predVar, objVar);
    }

    ASTPropertyList nextPropList = propListNode.getNextPropertyList();
    if (nextPropList != null) {
      nextPropList.jjtAccept(this, subject);
    }

    return null;
  }

  @Override
  public List<ValueExpr> visit(ASTObjectList node, Object data)
    throws VisitorException
  {
    int childCount = node.jjtGetNumChildren();
    List<ValueExpr> result = new ArrayList<ValueExpr>(childCount);

    for (int i = 0; i < childCount; i++) {
      result.add((ValueExpr)node.jjtGetChild(i).jjtAccept(this, null));
    }

    return result;
  }

  @Override
  public Var visit(ASTBlankNodePropertyList node, Object data)
    throws VisitorException
  {
    Var bnodeVar = createAnonVar(node.getVarName());
    super.visit(node, bnodeVar);
    return bnodeVar;
  }

  @Override
  public Var visit(ASTCollection node, Object data)
    throws VisitorException
  {
    String listVarName = node.getVarName();
    Var rootListVar = createAnonVar(listVarName);

    Var listVar = rootListVar;

    int childCount = node.jjtGetNumChildren();
    for (int i = 0; i < childCount; i++) {
      ValueExpr childValue = (ValueExpr)node.jjtGetChild(i).jjtAccept(this, null);

      Var childVar = valueExpr2Var(childValue);
      graphPattern.addRequiredSP(listVar, createConstVar(RDF.FIRST), childVar);

      Var nextListVar;
      if (i == childCount - 1) {
        nextListVar = createConstVar(RDF.NIL);
      }
      else {
        nextListVar = createAnonVar(listVarName + "-" + (i + 1));
      }

      graphPattern.addRequiredSP(listVar, createConstVar(RDF.REST), nextListVar);
      listVar = nextListVar;
    }

    return rootListVar;
  }

  @Override
  public Object visit(ASTConstraint node, Object data)
    throws VisitorException
  {
    ValueExpr valueExpr = (ValueExpr)super.visit(node, null);
    graphPattern.addConstraint(valueExpr);

    return null;
  }

  @Override
  public Or visit(ASTOr node, Object data)
    throws VisitorException
  {
    ValueExpr leftArg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    ValueExpr rightArg = (ValueExpr)node.jjtGetChild(1).jjtAccept(this, null);
    return new Or(leftArg, rightArg);
  }

  @Override
  public Object visit(ASTAnd node, Object data)
    throws VisitorException
  {
    ValueExpr leftArg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    ValueExpr rightArg = (ValueExpr)node.jjtGetChild(1).jjtAccept(this, null);
    return new And(leftArg, rightArg);
  }

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

  @Override
  public Compare visit(ASTCompare node, Object data)
    throws VisitorException
  {
    ValueExpr leftArg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    ValueExpr rightArg = (ValueExpr)node.jjtGetChild(1).jjtAccept(this, null);
    return new Compare(leftArg, rightArg, node.getOperator());
  }

  @Override
  public SameTerm visit(ASTSameTerm node, Object data)
    throws VisitorException
  {
    ValueExpr leftArg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    ValueExpr rightArg = (ValueExpr)node.jjtGetChild(1).jjtAccept(this, null);
    return new SameTerm(leftArg, rightArg);
  }

  @Override
  public MathExpr visit(ASTMath node, Object data)
    throws VisitorException
  {
    ValueExpr leftArg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    ValueExpr rightArg = (ValueExpr)node.jjtGetChild(1).jjtAccept(this, null);
    return new MathExpr(leftArg, rightArg, node.getOperator());
  }

  @Override
  public Object visit(ASTFunctionCall node, Object data)
    throws VisitorException
  {
    ValueConstant uriNode = (ValueConstant)node.jjtGetChild(0).jjtAccept(this, null);
    URI functionURI = (URI)uriNode.getValue();

    FunctionCall functionCall = new FunctionCall(functionURI.toString());

    for (int i = 1; i < node.jjtGetNumChildren(); i++) {
      Node argNode = node.jjtGetChild(i);
      functionCall.addArg((ValueExpr)argNode.jjtAccept(this, null));
    }

    return functionCall;
  }

  @Override
  public Object visit(ASTStr node, Object data)
    throws VisitorException
  {
    ValueExpr arg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    return new Str(arg);
  }

  @Override
  public Lang visit(ASTLang node, Object data)
    throws VisitorException
  {
    ValueExpr arg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    return new Lang(arg);
  }

  @Override
  public Datatype visit(ASTDatatype node, Object data)
    throws VisitorException
  {
    ValueExpr arg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    return new Datatype(arg);
  }

  @Override
  public Object visit(ASTLangMatches node, Object data)
    throws VisitorException
  {
    ValueExpr leftArg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    ValueExpr rightArg = (ValueExpr)node.jjtGetChild(1).jjtAccept(this, null);
    return new LangMatches(leftArg, rightArg);
  }

  @Override
  public ValueExpr visit(ASTBound node, Object data)
    throws VisitorException
  {
    Var var = (Var)node.getArg().jjtAccept(this, null);
    return new Bound(var);
  }

  @Override
  public IsURI visit(ASTIsIRI node, Object data)
    throws VisitorException
  {
    ValueExpr arg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    return new IsURI(arg);
  }

  @Override
  public IsBNode visit(ASTIsBlank node, Object data)
    throws VisitorException
  {
    ValueExpr arg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    return new IsBNode(arg);
  }

  @Override
  public IsLiteral visit(ASTIsLiteral node, Object data)
    throws VisitorException
  {
    ValueExpr arg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    return new IsLiteral(arg);
  }

  @Override
  public Object visit(ASTRegexExpression node, Object data)
    throws VisitorException
  {
    ValueExpr arg = (ValueExpr)node.jjtGetChild(0).jjtAccept(this, null);
    ValueExpr pattern = (ValueExpr)node.jjtGetChild(1).jjtAccept(this, null);
    ValueExpr flags = null;
    if (node.jjtGetNumChildren() > 2) {
      flags = (ValueExpr)node.jjtGetChild(2).jjtAccept(this, null);
    }
    return new Regex(arg, pattern, flags);
  }

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

  @Override
  public ValueConstant visit(ASTIRI node, Object data)
    throws VisitorException
  {
    URI uri;
    try {
      uri = valueFactory.createURI(node.getValue());
    }
    catch (IllegalArgumentException e) {
      // invalid URI
      throw new VisitorException(e.getMessage());
    }

    return new ValueConstant(uri);
  }

  @Override
  public Object visit(ASTQName node, Object data)
    throws VisitorException
  {
    throw new VisitorException("QNames must be resolved before building the query model");
  }

  @Override
  public Object visit(ASTBlankNode node, Object data)
    throws VisitorException
  {
    throw new VisitorException(
        "Blank nodes must be replaced with variables before building the query model");
  }

  @Override
  public ValueConstant visit(ASTRDFLiteral node, Object data)
    throws VisitorException
  {
    String label = (String)node.getLabel().jjtAccept(this, null);
    String lang = node.getLang();
    ASTIRI datatypeNode = node.getDatatype();

    Literal literal;
    if (datatypeNode != null) {
      URI datatype;
      try {
        datatype = valueFactory.createURI(datatypeNode.getValue());
      }
      catch (IllegalArgumentException e) {
        // invalid URI
        throw new VisitorException(e.getMessage());
      }
      literal = valueFactory.createLiteral(label, datatype);
    }
    else if (lang != null) {
      literal = valueFactory.createLiteral(label, lang);
    }
    else {
      literal = valueFactory.createLiteral(label);
    }

    return new ValueConstant(literal);
  }

  @Override
  public ValueConstant visit(ASTNumericLiteral node, Object data)
    throws VisitorException
  {
    Literal literal = valueFactory.createLiteral(node.getValue(), node.getDatatype());
    return new ValueConstant(literal);
  }

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

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

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

Related Classes of org.openrdf.query.parser.sparql.TupleExprBuilder

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.