Package lupos.engine.operators.singleinput.filter.expressionevaluation

Source Code of lupos.engine.operators.singleinput.filter.expressionevaluation.EvaluationVisitorImplementation$NonEmptyApplication

/**
* Copyright (c) 2013, Institute of Information Systems (Sven Groppe and contributors of LUPOSDATE), University of Luebeck
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*   - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*     disclaimer.
*   - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*     following disclaimer in the documentation and/or other materials provided with the distribution.
*   - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*     products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lupos.engine.operators.singleinput.filter.expressionevaluation;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import lupos.datastructures.bindings.Bindings;
import lupos.datastructures.bindings.BindingsMap;
import lupos.datastructures.items.Item;
import lupos.datastructures.items.Variable;
import lupos.datastructures.items.VariableInInferenceRule;
import lupos.datastructures.items.literal.AnonymousLiteral;
import lupos.datastructures.items.literal.LanguageTaggedLiteral;
import lupos.datastructures.items.literal.LazyLiteral;
import lupos.datastructures.items.literal.Literal;
import lupos.datastructures.items.literal.LiteralFactory;
import lupos.datastructures.items.literal.TypedLiteral;
import lupos.datastructures.items.literal.URILiteral;
import lupos.datastructures.items.literal.codemap.CodeMapLiteral;
import lupos.datastructures.items.literal.string.StringLiteral;
import lupos.datastructures.queryresult.QueryResult;
import lupos.engine.evaluators.CommonCoreQueryEvaluator;
import lupos.engine.operators.BasicOperator;
import lupos.engine.operators.SimpleOperatorGraphVisitor;
import lupos.engine.operators.application.Application;
import lupos.engine.operators.application.CollectResult;
import lupos.engine.operators.index.BasicIndexScan;
import lupos.engine.operators.index.Root;
import lupos.engine.operators.messages.BoundVariablesMessage;
import lupos.engine.operators.multiinput.join.Join;
import lupos.engine.operators.singleinput.NotBoundException;
import lupos.engine.operators.singleinput.Result;
import lupos.engine.operators.singleinput.TypeErrorException;
import lupos.engine.operators.tripleoperator.TriplePattern;
import lupos.sparql1_1.ASTABSFuncNode;
import lupos.sparql1_1.ASTAdditionNode;
import lupos.sparql1_1.ASTAggregation;
import lupos.sparql1_1.ASTAndNode;
import lupos.sparql1_1.ASTBnodeFuncNode;
import lupos.sparql1_1.ASTBooleanLiteral;
import lupos.sparql1_1.ASTBoundFuncNode;
import lupos.sparql1_1.ASTCeilFuncNode;
import lupos.sparql1_1.ASTCoalesceFuncNode;
import lupos.sparql1_1.ASTConcatFuncNode;
import lupos.sparql1_1.ASTContainsFuncNode;
import lupos.sparql1_1.ASTDataTypeFuncNode;
import lupos.sparql1_1.ASTDayFuncNode;
import lupos.sparql1_1.ASTDivisionNode;
import lupos.sparql1_1.ASTDoubleCircumflex;
import lupos.sparql1_1.ASTEncodeForUriFuncNode;
import lupos.sparql1_1.ASTEqualsNode;
import lupos.sparql1_1.ASTExists;
import lupos.sparql1_1.ASTFilterConstraint;
import lupos.sparql1_1.ASTFloatingPoint;
import lupos.sparql1_1.ASTFloorFuncNode;
import lupos.sparql1_1.ASTFunctionCall;
import lupos.sparql1_1.ASTGreaterThanEqualsNode;
import lupos.sparql1_1.ASTGreaterThanNode;
import lupos.sparql1_1.ASTHoursFuncNode;
import lupos.sparql1_1.ASTIfFuncNode;
import lupos.sparql1_1.ASTInNode;
import lupos.sparql1_1.ASTInteger;
import lupos.sparql1_1.ASTIriFuncNode;
import lupos.sparql1_1.ASTLangFuncNode;
import lupos.sparql1_1.ASTLangMatchesFuncNode;
import lupos.sparql1_1.ASTLangTag;
import lupos.sparql1_1.ASTLcaseFuncNode;
import lupos.sparql1_1.ASTLessThanEqualsNode;
import lupos.sparql1_1.ASTLessThanNode;
import lupos.sparql1_1.ASTMD5FuncNode;
import lupos.sparql1_1.ASTMinusNode;
import lupos.sparql1_1.ASTMinutesFuncNode;
import lupos.sparql1_1.ASTMonthFuncNode;
import lupos.sparql1_1.ASTMultiplicationNode;
import lupos.sparql1_1.ASTNIL;
import lupos.sparql1_1.ASTNotEqualsNode;
import lupos.sparql1_1.ASTNotExists;
import lupos.sparql1_1.ASTNotInNode;
import lupos.sparql1_1.ASTNotNode;
import lupos.sparql1_1.ASTNowFuncNode;
import lupos.sparql1_1.ASTOrNode;
import lupos.sparql1_1.ASTPlusNode;
import lupos.sparql1_1.ASTQuotedURIRef;
import lupos.sparql1_1.ASTRDFLiteral;
import lupos.sparql1_1.ASTRandFuncNode;
import lupos.sparql1_1.ASTRegexFuncNode;
import lupos.sparql1_1.ASTRoundFuncNode;
import lupos.sparql1_1.ASTSHA1FuncNode;
import lupos.sparql1_1.ASTSHA256FuncNode;
import lupos.sparql1_1.ASTSHA384FuncNode;
import lupos.sparql1_1.ASTSHA512FuncNode;
import lupos.sparql1_1.ASTSTRUUIDFuncNode;
import lupos.sparql1_1.ASTSameTermFuncNode;
import lupos.sparql1_1.ASTSecondsFuncNode;
import lupos.sparql1_1.ASTStrAfterFuncNode;
import lupos.sparql1_1.ASTStrBeforeFuncNode;
import lupos.sparql1_1.ASTStrEndsFuncNode;
import lupos.sparql1_1.ASTStrFuncNode;
import lupos.sparql1_1.ASTStrLangFuncNode;
import lupos.sparql1_1.ASTStrReplaceFuncNode;
import lupos.sparql1_1.ASTStrdtFuncNode;
import lupos.sparql1_1.ASTStringLiteral;
import lupos.sparql1_1.ASTStrlenFuncNode;
import lupos.sparql1_1.ASTStrstartsFuncNode;
import lupos.sparql1_1.ASTSubstringFuncNode;
import lupos.sparql1_1.ASTSubtractionNode;
import lupos.sparql1_1.ASTTimeZoneFuncNode;
import lupos.sparql1_1.ASTTzFuncNode;
import lupos.sparql1_1.ASTUUIDFuncNode;
import lupos.sparql1_1.ASTUcaseFuncNode;
import lupos.sparql1_1.ASTUriFuncNode;
import lupos.sparql1_1.ASTVar;
import lupos.sparql1_1.ASTYearFuncNode;
import lupos.sparql1_1.ASTisBlankFuncNode;
import lupos.sparql1_1.ASTisIRIFuncNode;
import lupos.sparql1_1.ASTisLiteralFuncNode;
import lupos.sparql1_1.ASTisNumericFuncNode;
import lupos.sparql1_1.ASTisURIFuncNode;
import lupos.sparql1_1.Node;
import lupos.sparql1_1.SimpleNode;

public class EvaluationVisitorImplementation implements EvaluationVisitor<Map<Node, Object>, Object> {

  protected static HashMap<URILiteral, ExternalFunction> externalFunctions = new HashMap<URILiteral, ExternalFunction>();

  /**
   * call this function to register an external function
   * @param name name of the external function
   * @param externalFunction the external function
   */
  public static void registerExternalFunction(final URILiteral name, final ExternalFunction externalFunction){
    EvaluationVisitorImplementation.externalFunctions.put(name, externalFunction);
  }

  // for each ASTExists and ASTNotExists an Root and Result is
  // stored by the Filter
  // Additionally we hand over the evaluator in the filter
  // this is needed to process the actual subquery for each node
  private Map<SimpleNode, Root> collectionForExistNodes = new HashMap<SimpleNode, Root>();
  private final Map<SimpleNode, Boolean> simpleExistNodes = new HashMap<SimpleNode, Boolean>();
  protected Map<SimpleNode, QueryResult> queryResultsForExistNodes = new HashMap<SimpleNode, QueryResult>();
  private CommonCoreQueryEvaluator<Node> evaluator;

  @Override
  public void setCollectionForExistNodes(
      final Map<SimpleNode, Root> collectionForExistNodes) {
    this.collectionForExistNodes = collectionForExistNodes;
  }

  @Override
  public Map<SimpleNode, Root> getCollectionForExistNodes() {
    return this.collectionForExistNodes;
  }

  @Override
  public CommonCoreQueryEvaluator<Node> getEvaluator() {
    return this.evaluator;
  }

  @Override
  public void setEvaluator(final CommonCoreQueryEvaluator<Node> evaluator) {
    this.evaluator = evaluator;
  }

  @Override
  public void init() {
    EvaluationVisitorImplementation.resetNowDate();
    this.queryResultsForExistNodes.clear();
  }

  @Override
  public void release() {
    // nothing to release...
  }

  @Override
  public Object evaluate(final ASTOrNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    NotBoundException _exceptionNB = null;
    TypeErrorException _exceptionTE = null;
    try {
      if (Helper.booleanEffectiveValue(node.jjtGetChild(0).accept(this, b, d))) {
        return true;
      }
    } catch (final NotBoundException nbe) {
      _exceptionNB = nbe;
    } catch (final TypeErrorException tee) {
      _exceptionTE = tee;
    }
    try {
      if (Helper.booleanEffectiveValue(node.jjtGetChild(1).accept(this, b, d))) {
        return true;
      }
    } catch (final NotBoundException nbe) {
      _exceptionNB = nbe;
    } catch (final TypeErrorException tee) {
      _exceptionTE = tee;
    }
    if (_exceptionNB != null) {
      throw _exceptionNB;
    } else if (_exceptionTE != null) {
      throw _exceptionTE;
    } else {
      return false;
    }
  }

  @Override
  public Object evaluate(final ASTAndNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    try {
      return (Helper.booleanEffectiveValue(node.jjtGetChild(0).accept(this, b, d)) &&
          Helper.booleanEffectiveValue(node.jjtGetChild(1).accept(this, b, d)));
    } catch (final NotBoundException nbe) {
      throw (nbe);
    } catch (final TypeErrorException tee) {
      throw (tee);
    } catch (final Exception e) {
      System.out.println(e);
      return null;
    }
  }

  @Override
  public Object evaluate(final ASTEqualsNode node, final Bindings b, final Map<Node, Object> d) throws TypeErrorException, NotBoundException {
    return Helper.equals(node.jjtGetChild(0).accept(this, b, d), node.jjtGetChild(1).accept(this, b, d));
  }

  @Override
  public Object evaluate(final ASTNotEqualsNode node, final Bindings b,
      final Map<Node, Object> d) throws TypeErrorException, NotBoundException {
    return Helper.NOTequals(node.jjtGetChild(0).accept(this, b, d), node.jjtGetChild(1).accept(this, b, d));
  }

  @Override
  public Object evaluate(final ASTLessThanNode node, final Bindings b, final Map<Node, Object> d) throws TypeErrorException, NotBoundException {
    return Helper.less(node.jjtGetChild(0).accept(this, b, d), node.jjtGetChild(1).accept(this, b, d));
  }

  @Override
  public Object evaluate(final ASTLessThanEqualsNode node, final Bindings b, final Map<Node, Object> d) throws TypeErrorException, NotBoundException {
    return Helper.le(node.jjtGetChild(0).accept(this, b, d), node.jjtGetChild(1).accept(this, b, d));
  }

  @Override
  public Object evaluate(final ASTGreaterThanNode node, final Bindings b,
      final Map<Node, Object> d) throws TypeErrorException, NotBoundException {
    return Helper.greater(node.jjtGetChild(0).accept(this, b, d), node.jjtGetChild(1).accept(this, b, d));
  }

  @Override
  public Object evaluate(final ASTGreaterThanEqualsNode node, final Bindings b,
      final Map<Node, Object> d) throws TypeErrorException, NotBoundException {
    return Helper.ge(node.jjtGetChild(0).accept(this, b, d), node.jjtGetChild(1).accept(this, b, d));
  }

  @Override
  public Object evaluate(final ASTDivisionNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.divideNumericValues(this.resultOfChildZero(node, b, d), this.resultOfChildOne(node, b, d));
  }

  @Override
  public Object evaluate(final ASTAdditionNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.addNumericValues(this.resultOfChildZero(node, b, d), this.resultOfChildOne(node, b, d));
  }

  protected Object resultOfChildZero(final Node node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return node.jjtGetChild(0).accept(this, b, d);
  }

  protected Object resultOfChildOne(final Node node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return node.jjtGetChild(1).accept(this, b, d);
  }

  protected Object resultOfChildTwo(final Node node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return node.jjtGetChild(2).accept(this, b, d);
  }

  @Override
  public Object evaluate(final ASTRDFLiteral node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return this.resultOfChildZero(node, b, d);
  }

  protected Object[] getOperand(final Node node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object[] result = new Object[2];
    result[0] = this.resultOfChildZero(node, b, d);
    result[1] = Helper.getType(result[0]);
    return result;
  }

  @Override
  public Object evaluate(final ASTMinusNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object[] operand = this.getOperand(node, b, d);
    if (operand[1] == BigInteger.class) {
      return Helper.getInteger(operand[0]).negate();
    } else if (operand[1] == Float.class) {
      return -1 * Helper.getFloat(operand[0]);
    } else if (operand[1] == Double.class) {
      return -1 * Helper.getDouble(operand[0]);
    } else if (operand[1] == BigDecimal.class) {
      return Helper.getBigDecimal(operand[0]).negate();
    }
    throw new TypeErrorException();
  }

  @Override
  public Object evaluate(final ASTMultiplicationNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.multiplyNumericValues(this.resultOfChildZero(node, b, d), this.resultOfChildOne(node, b, d));
  }


  @Override
  public Object evaluate(final ASTNotNode node, final Bindings b, final Map<Node, Object> d) throws TypeErrorException, NotBoundException {
    return !Helper.booleanEffectiveValue(this.resultOfChildZero(node, b, d));
  }

  @Override
  public Object evaluate(final ASTPlusNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return this.resultOfChildZero(node, b, d);
  }

  @Override
  public Object evaluate(final ASTRegexFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if (o instanceof URILiteral || o instanceof AnonymousLiteral) {
      return false;
    }
    final String cmp = Helper.getString(o);
    String pattern = Helper.getString(Helper.unlazy(this.resultOfChildOne(node, b, d)));
    String oldPattern;
    do {
      oldPattern = pattern;
      pattern = pattern.replace("\\\\", "\\");
    } while (oldPattern.compareTo(pattern) != 0);
    String flags = "";
    if (node.jjtGetNumChildren() > 2){
      flags = Helper.getString(Helper.unlazy(this.resultOfChildTwo(node, b, d)));
    }
    // return match(cmp,pattern,flags); // does not support flag x!!!
    return Helper.matchXerces(cmp, pattern, flags);
  }

  @Override
  public Object evaluate(final ASTStringLiteral node, final Bindings b, final Map<Node, Object> d) {
    return node.getLiteral(true);
  }

  @Override
  public Object evaluate(final ASTBooleanLiteral node, final Bindings b,
      final Map<Node, Object> d) {
    return node.getState();
  }

  @Override
  public Object evaluate(final ASTSubtractionNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.subtractNumericValues(this.resultOfChildZero(node, b, d), this.resultOfChildOne(node, b, d));
  }

  @Override
  public Object evaluate(final ASTVar node, final Bindings b, final Map<Node, Object> d) throws NotBoundException {
    Literal l = b.get(new Variable(node.getName()));
    if (l == null) {
      l = b.get(new VariableInInferenceRule(node.getName()));
    }
    if (l == null) {
      throw new NotBoundException("Variable "
          + node.getName()
          + " is not bound!");
    } else {
      return l;
    }
  }

  @Override
  public Object evaluate(final ASTBoundFuncNode node, final Bindings b, final Map<Node, Object> d) throws TypeErrorException {
    try {
      this.resultOfChildZero(node, b, d);
      return true;
    } catch (final NotBoundException nbe) {
      return false;
    }
  }

  @Override
  public Object evaluate(final ASTLangFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if (o instanceof LanguageTaggedLiteral) {
      return "\"" + ((LanguageTaggedLiteral) o).getOriginalLanguage() + "\"";
    } else if (o instanceof TypedLiteral || o instanceof CodeMapLiteral || o instanceof StringLiteral) {
      return "\"\"";
    } else {
      throw new TypeErrorException();
    }
  }

  @Override
  public Object evaluate(final ASTLangMatchesFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object o1 = this.resultOfChildZero(node, b, d);
    final Object o2 = this.resultOfChildOne(node, b, d);
    final String s1 = o1.toString().toUpperCase();
    final String s2 = o2.toString().toUpperCase();
    if (s2.compareTo("\"*\"") == 0) {
      if (s1.compareTo("\"\"") == 0) {
        return false;
      } else {
        return true;
      }
    }
    if (s2.length() < s1.length()) {
      if (s2.compareTo("\"\"") == 0) {
        return false;
      } else {
        return s1.substring(1, s1.length() - 1).startsWith(
            s2.substring(1, s2.length() - 1));
      }
    }
    return (Helper.unquote(s1).compareTo(Helper.unquote(s2)) == 0);
  }

  @Override
  public Object evaluate(final ASTDataTypeFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if (o instanceof TypedLiteral) {
      return ((TypedLiteral) o).getTypeLiteral();
    } else {
      try {
        if (o instanceof BigInteger) {
          return LiteralFactory
          .createURILiteral("<http://www.w3.org/2001/XMLSchema#integer>");
        } else if (o instanceof Float) {
          return LiteralFactory
          .createURILiteral("<http://www.w3.org/2001/XMLSchema#float>");
        } else if (o instanceof Double) {
          return LiteralFactory
          .createURILiteral("<http://www.w3.org/2001/XMLSchema#double>");
        } else if (o instanceof BigDecimal) {
          return LiteralFactory
          .createURILiteral("<http://www.w3.org/2001/XMLSchema#decimal>");
        } else if (o instanceof String) {
          return LiteralFactory
          .createURILiteral("<http://www.w3.org/2001/XMLSchema#string>");
        }
      } catch (final URISyntaxException e) {
        System.err.println(e);
        e.printStackTrace();
      }
    }
    if (o instanceof CodeMapLiteral || o instanceof StringLiteral) {
      try {
        return LiteralFactory.createURILiteral("<http://www.w3.org/2001/XMLSchema#string>");
      } catch (final URISyntaxException e) {
        System.err.println(e);
        e.printStackTrace();
      }
    }
      throw new TypeErrorException();
  }

  @Override
  public Object evaluate(final ASTSameTermFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final String a = Helper.getOriginalValueString(this.resultOfChildZero(node, b, d));
    final String bs = Helper.getOriginalValueString(this.resultOfChildOne(node, b, d));
    return a.compareTo(bs) == 0;
  }

  public Object createURI_IRI(final Node node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if(o instanceof URILiteral){
      return o;
    }
    if(o instanceof TypedLiteral){
      final TypedLiteral tl = (TypedLiteral) o;
      if(tl.getType().compareTo("<http://www.w3.org/2001/XMLSchema#string>")==0) {
        o = tl.getContent();
      } else {
        throw new TypeErrorException();
      }
    }
    if(o instanceof String || o instanceof StringLiteral || o instanceof CodeMapLiteral){
      try {
        String s = Helper.trim(o.toString());
        if(s.startsWith("'") || s.startsWith("\"")) {
          s=s.substring(1, s.length()-1);
        }
        return LiteralFactory.createURILiteral("<"+s+">");
      } catch (final URISyntaxException e) {
        throw new TypeErrorException();
      }
    }
    throw new TypeErrorException();
  }

  @Override
  public Object evaluate(final ASTUriFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return this.createURI_IRI(node, b, d);
  }

  @Override
  public Object evaluate(final ASTIriFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return this.createURI_IRI(node, b, d);
  }

  protected static final String prefixInternalBlankNodes = "_:internal!";
  protected int id = 0;
  protected final HashMap<Object, Integer> mapForBlankNodeGeneration = new HashMap<Object, Integer>();

  @Override
  public Object evaluate(final ASTBnodeFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    Integer id_for_o;
    if(node.jjtGetNumChildren()>0){
      final Object o = this.resultOfChildZero(node, b, d);
      id_for_o = this.mapForBlankNodeGeneration.get(o);
      if(id_for_o == null){
        id_for_o = this.id++;
        this.mapForBlankNodeGeneration.put(o, id_for_o);
      }
    } else {
      id_for_o = this.id++;
    }
    return LiteralFactory.createAnonymousLiteral(prefixInternalBlankNodes+(id_for_o));
  }

  @Override
  public Object evaluate(final ASTisLiteralFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if (!(o instanceof AnonymousLiteral || o instanceof URILiteral)) {
      if (o instanceof Literal){
        return true;
      }
    }
    return false;
  }

  @Override
  public Object evaluate(final ASTFunctionCall node, final Bindings b, final Map<Node, Object> d) throws TypeErrorException, NotBoundException {
    final Literal name = LazyLiteral.getLiteral(node.jjtGetChild(0));
    final ExternalFunction externalFunction = EvaluationVisitorImplementation.externalFunctions.get(name);
    if(externalFunction!=null){
      final Node child1 = node.jjtGetChild(1);
      final int number = child1.jjtGetNumChildren();
      final Object[] args = new Object[number];
      for(int i=0; i<number; i++){
        args[i] = child1.jjtGetChild(i).accept(this, b, d);
      }
      return externalFunction.evaluate(args);
    }
    if (name.toString().startsWith("<http://www.w3.org/2001/XMLSchema#")) {
      return Helper.cast(name.toString(), this.resultOfChildZero(node.jjtGetChild(1), b, d));
    }
    System.err.println("Filter Error: unknown function "+ name.toString());
    return false;
  }

  @Override
  public Object evaluate(final ASTQuotedURIRef node, final Bindings b, final Map<Node, Object> d) {
    return node.getLiteral(true);
  }

  @Override
  public Object evaluate(final ASTDoubleCircumflex node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return node.getLiteral(true);
  }

  @Override
  public Object evaluate(final ASTFloatingPoint node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return node.getLiteral(true);
  }

  @Override
  public Object evaluate(final ASTisBlankFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object parameter = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if(parameter instanceof AnonymousLiteral) {
      return true;
    } else {
      return false;
    }
  }

  protected boolean isURI_IRI(final Node node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if (o instanceof URILiteral) {
      return true;
    }
    final String text = o.toString();
    if (URILiteral.isURI(text)) {
      return true;
    } else {
      return false;
    }
  }

  @Override
  public Object evaluate(final ASTisURIFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return this.isURI_IRI(node, b, d);
  }

  @Override
  public Object evaluate(final ASTisIRIFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return this.isURI_IRI(node, b, d);
  }

  @Override
  public Object evaluate(final ASTInteger node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return node.getLiteral(true);
  }

  @Override
  public Object evaluate(final ASTLangTag node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return node.getLiteral(true);
  }

  @Override
  public Object evaluate(final ASTFilterConstraint node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return this.resultOfChildZero(node, b, d);
  }


  @Override
  public Object evaluate(final ASTisNumericFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    // TODO check the domain!!!
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if(o instanceof BigInteger || o instanceof Float || o instanceof Double || o instanceof BigDecimal) {
      return true;
    }
    if(o instanceof TypedLiteral){
      return Helper.isNumeric(((TypedLiteral)o).getType());
    }
    return false;
  }

  @Override
  public Object evaluate(final ASTAggregation node, final Bindings b, final Map<Node, Object> d) {
    // the result of the aggregation function has already been previously computed...
    return d.get(node);
  }

  @Override
  public Object applyAggregationCOUNT(final Iterator<Object> values) {
    long l=0;
    while(values.hasNext()){
      values.next();
      l++;
    }
    return BigInteger.valueOf(l);
  }

  @Override
  public Object applyAggregationSUM(final Iterator<Object> values) {
    Object result=BigInteger.ZERO;
    while(values.hasNext()){
      final Object next = values.next();
      try {
        result = Helper.addNumericValues(result, next);
      } catch (final TypeErrorException e) {
        // ignore...
      }
    }
    return result;
  }

  @Override
  public Object applyAggregationMIN(final Iterator<Object> values) {
    Object result = null;
    while(values.hasNext()){
      final Object next = values.next();
      try {
        if(result == null || Helper.less(next, result)) {
          result = next;
        }
      } catch (final TypeErrorException e) {
        // ignore...
      }
    }
    return result;
  }

  @Override
  public Object applyAggregationMAX(final Iterator<Object> values) {
    Object result = null;
    while(values.hasNext()){
      final Object next = values.next();
      try {
        if(result == null || Helper.greater(next, result)) {
          result = next;
        }
      } catch (final TypeErrorException e) {
        // ignore...
      }
    }
    return result;
  }


  @Override
  public Object evaluate(final ASTExists node, final Bindings bindings,
      final Map<Node, Object> d) {
    return this.processSubquery(node, bindings, d, this.collectionForExistNodes.get(node), this.evaluator);

  }

  @Override
  public Object evaluate(final ASTNotExists node, final Bindings bindings,
      final Map<Node, Object> d) {
    return !this.processSubquery(node, bindings, d, this.collectionForExistNodes.get(node), this.evaluator);

  }

  /**
   * Checks whether the subquery represented by the {@link Root}
   * and {@link Result} has a non-empty result. Used for processing Exists and
   * Not Exists.
   *
   * @param node
   *            the node associated with this query, usually an instance of
   *            {@link ASTExists} or {@link ASTNotExists}
   * @param bindings
   *            a {@link Bindings}, {@link Variable}s, which are bounded in
   *            this {@link Bindings}, are replaced by the {@link Literal}s in
   *            the subquery.
   * @param d
   * @param collection
   *            the {@link Root} for the subquery
   * @param evaluator_param
   *            the {@link CommonCoreQueryEvaluator} which should be used to
   *            process the subquery
   * @param result
   *            the {@link Result} for the subquery
   */
  public boolean processSubquery(final SimpleNode node, final Bindings bindings,
      final Map<Node, Object> d, final Root collection,
      final CommonCoreQueryEvaluator<Node> evaluator_param) {
    Boolean simple = this.simpleExistNodes.get(node);
    if(simple==null){
      collection.visit(new SimpleOperatorGraphVisitor() {

        @Override
        public Object visit(final BasicOperator basicOperator) {
          // exclude more complicated cases, which might lead to errors...
          // maybe too strict, must be checked again to allow more...
          if (!(basicOperator instanceof BasicIndexScan ||
              basicOperator instanceof Join ||
              basicOperator instanceof Result)){
            EvaluationVisitorImplementation.this.simpleExistNodes.put(node, false);
          }
          return null;
        }
      });
      simple = this.simpleExistNodes.get(node);
      if(simple==null){
        this.simpleExistNodes.put(node, true);
        simple = true;
      }
    }
    if(simple) {
      return processSimpleSubquery(node, bindings, d, collection, evaluator_param);
    } else {
      return this.processSubqueryAndGetWholeResult(node, bindings, d, collection, evaluator_param);
    }
  }

  /**
   * Checks whether the subquery represented by the {@link Root}
   * and {@link Result} has a non-empty result. Used for processing Exists and
   * Not Exists.<br>
   * Implementation note: Contrary to {@link EvaluationVisitorImplementation}
   * the subquery is processed once per {@link ASTExists}/{@link ASTNotExists}
   * node and the evaluation is done by iterating over the result set.
   *
   * @param node
   *            the node associated with this query, usually an instance of
   *            {@link ASTExists} or {@link ASTNotExists}
   * @param bindings
   *            a {@link Bindings}, {@link Variable}s, which are bounded in
   *            this {@link Bindings}, are replaced by the {@link Literal}s in
   *            the subquery.
   * @param d
   * @param collection
   *            the {@link Root} for the subquery
   * @param evaluator_param
   *            the {@link CommonCoreQueryEvaluator} which should be used to
   *            process the subquery
   * @param result
   *            the {@link Result} for the subquery
   */
  public boolean processSubqueryAndGetWholeResult(final SimpleNode node, final Bindings bindings,
      final Map<Node, Object> d, final Root collection,
      final CommonCoreQueryEvaluator<Node> evaluator_param) {

    if (!this.queryResultsForExistNodes.containsKey(node)) {
      this.performSubQueryAndGetWholeResult(node, collection, evaluator_param);
    }

    final Iterator<Bindings> bindingsSet = this.queryResultsForExistNodes.get(node)
        .iterator();

    while (bindingsSet.hasNext()) {
      final Bindings bindings2 = bindingsSet.next();
      final Set<Variable> vars = bindings.getVariableSet();
      vars.retainAll(bindings2.getVariableSet());

      boolean isEqual = true;
      for (final Variable variable : vars) {
        if (bindings.get(variable)
            .compareToNotNecessarilySPARQLSpecificationConform(
                bindings2.get(variable)) != 0) {
          isEqual = false;
        }
      }

      if (isEqual || vars.isEmpty()) {
        return true;
      }
    }

    return false;
  }

  public static class GetResult implements SimpleOperatorGraphVisitor {

    protected Result result = null;

    public Result getResult() {
      return this.result;
    }

    @Override
    public Object visit(final BasicOperator basicOperator) {
      if(basicOperator instanceof Result) {
        this.result = (Result) basicOperator;
      }
      return null;
    }
  }


  public static Result setupEvaluator(final CommonCoreQueryEvaluator<Node> evaluator, final Root collection){
    evaluator.setRootNode(collection);
    collection.deleteParents();
    collection.setParents();
    collection.detectCycles();
    collection.sendMessage(new BoundVariablesMessage());

    evaluator.setBindingsVariablesBasedOnOperatorgraph();

    final GetResult getResult = new GetResult();
    collection.visit(getResult);
    final Result result = getResult.getResult();

    evaluator.setResult(result);
    result.clearApplications();

    return result;
  }

  /**
   * Computes the {@link QueryResult} for the subquery with the given node and
   * stores it in a {@link HashMap} in this class, so it can be used for
   * further processing.
   *
   * @param node
   *            the node associated with this query, usually an instance of
   *            {@link ASTExists} or {@link ASTNotExists}
   * @param collection
   *            the {@link Root} for the subquery
   * @param evaluator_param
   *            the {@link CommonCoreQueryEvaluator} which should be used to
   *            process the subquery
   * @param result
   *            the {@link Result} for the subquery
   */
  protected void performSubQueryAndGetWholeResult(final SimpleNode node,
      final Root collection,
      final CommonCoreQueryEvaluator<Node> evaluator_param) {
    final BasicOperator oldRoot = evaluator_param.getRootNode();
    final Result oldResult = evaluator_param.getResultOperator();
    final Map<Variable, Integer> oldBindingsFactory = evaluator_param.getBindingsFactory().getPosVariables();

    final Result result = setupEvaluator(evaluator_param, (Root) collection.deepClone());

    final CollectResult cr = new CollectResult(false);
    result.addApplication(cr);

    evaluator_param.logicalOptimization();
    evaluator_param.physicalOptimization();
    try {
      evaluator_param.evaluateQuery();
    } catch (final Exception e1) {
      e1.printStackTrace();
    }
    final QueryResult queryResult = cr.getResult();
    this.queryResultsForExistNodes.put(node, this.transformQueryResult(queryResult));
    evaluator_param.setRootNode(oldRoot);
    evaluator_param.setResult(oldResult);
    evaluator_param.getBindingsFactory().setPosVariables(oldBindingsFactory);
  }

  protected QueryResult transformQueryResult(final QueryResult queryResult) {
    final QueryResult result = QueryResult.createInstance();
    if (queryResult == null) {
      return result; // empty result
    } else {

      final Iterator<Bindings> it = queryResult.oneTimeIterator();
      while (it.hasNext()) {
        final Bindings b = new BindingsMap();
        final Bindings bindings = it.next();
        b.addAll(bindings);
        result.add(b);
      }
      return result;
    }
  }

  @SuppressWarnings("serial")
  public static boolean processSimpleSubquery(final SimpleNode node, final Bindings bindings,
      final Map<Node, Object> d, final Root collection,
      final CommonCoreQueryEvaluator<Node> evaluator) {

    final BasicOperator oldRoot = evaluator.getRootNode();
    final Result oldResult = evaluator.getResultOperator();
    final Map<Variable, Integer> oldBindingsFactory = evaluator.getBindingsFactory().getPosVariables();

    final Root collectionClone = (Root) collection.deepClone();
    collectionClone.visit(new SimpleOperatorGraphVisitor() {
;
      @Override
      public Object visit(final BasicOperator basicOperator) {

        if (basicOperator instanceof BasicIndexScan) {
          final BasicIndexScan basicIndex = (BasicIndexScan) basicOperator;
          final Collection<TriplePattern> triplePatterns = basicIndex
              .getTriplePattern();
          final Collection<TriplePattern> newTriplePatterns = new LinkedList<TriplePattern>();
          for (final TriplePattern t : triplePatterns) {
            final Item[] itemArray = t.getItems().clone();
            for (int i = 0; i < 3; i++) {
              if (itemArray[i].isVariable()) {
                final Literal literal = bindings
                    .get((Variable) itemArray[i]);
                if (literal != null) {
                  itemArray[i] = literal;
                }
              }
            }
            newTriplePatterns.add(new TriplePattern(itemArray));
          }
          basicIndex.setTriplePatterns(newTriplePatterns);
        } else {
          // TODO Filter
          // node.clone(false)
        }
        return null;
      }
    });

    final Result result = setupEvaluator(evaluator, collectionClone);

    result.clearApplications();
    final NonEmptyApplication application = new NonEmptyApplication();
    result.addApplication(application);

    evaluator.logicalOptimization();
    evaluator.physicalOptimization();
    try {
      evaluator.evaluateQuery();
    } catch (final Exception e1) {
      e1.printStackTrace();
    }
    evaluator.setRootNode(oldRoot);
    evaluator.setResult(oldResult);
    evaluator.getBindingsFactory().setPosVariables(oldBindingsFactory);
    return !application.getResultIsEmpty();
  }

  public static class NonEmptyApplication implements Application {

    protected boolean resultIsEmpty=true;

    public boolean getResultIsEmpty(){
      return this.resultIsEmpty;
    }

    @Override
    public void call(final QueryResult res) {
      if (res.oneTimeIterator().hasNext()) {
        this.resultIsEmpty = false;
      }
    }

    @Override
    public void deleteResult() {
      // not used...
    }

    @Override
    public void deleteResult(final QueryResult res) {
      // not used...
    }

    @Override
    public void start(final Type type) {
      // not used...
    }

    @Override
    public void stop() {
      // not used...
    }
  }

  /**
   * Method for computing the SAMPLE-statement by returning a random value of
   * the given values
   *
   * @param Iterator
   *            <Object>
   * @return Object
   */
  @Override
  public Object applyAggregationSAMPLE(final Iterator<Object> values) {
    final double r = Math.random();
    final LinkedList<Object> valueList = new LinkedList<Object>();
    while (values.hasNext()) {
      valueList.add(values.next());
    }
    final double randomValue = (valueList.size() - 1) * r;
    return valueList.get((int) Math.round(randomValue));
  }

  /**
   * Concatenates the values of a group and inserts between the values a separator
   * if given
   *
   * @param Iterator
   *            <Object> values
   * @param String
   *            separator
   */
  @Override
  public Object applyAggregationGROUP_CONCAT(final Iterator<Object> values,
      final String separator) {
    boolean firstTime = true;
    String concat = "";
    while (values.hasNext()) {
      if (firstTime) {
        concat = concat + Helper.getString(values.next());
        firstTime = false;
      } else {
        concat = concat + separator + Helper.getString(values.next());
      }

    }
    return Helper.quote(concat);
  }

  @Override
  public Object applyAggregationAVG(final Iterator<Object> values) {
    long count = 0;
    Object result = BigInteger.ZERO;
    while (values.hasNext()) {
      final Object next = values.next();
      try {
        result = Helper.addNumericValues(result, next);
        count++;
      } catch (final TypeErrorException e) {
        return null;
      }
    }
    try {
      return Helper.divideNumericValues(result, BigInteger.valueOf(count));
    } catch (final TypeErrorException e) {
      return null;
    }
  }

  @Override
  public Object evaluate(final ASTStrdtFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object arg0 = Helper.unlazy(this.resultOfChildZero(node, b, d));
    final Object arg1 = Helper.unlazy(this.resultOfChildOne(node, b, d));
    try {
      return LiteralFactory.createTypedLiteral("\""
          + Helper.getSimpleString(arg0) + "\"", Helper.getString(arg1));
    } catch (final URISyntaxException e) {
      throw new TypeErrorException();
    }
  }

  @Override
  public Object evaluate(final ASTStrFuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if (o instanceof TypedLiteral) {
      return ((TypedLiteral) o).getOriginalContent();
    } else if (o instanceof LanguageTaggedLiteral) {
      return ((LanguageTaggedLiteral) o).getContentLiteral();
    }
    return o.toString();
  }

  @Override
  public Object evaluate(final ASTStrLangFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final String content = Helper.quote(Helper.getSimpleString(Helper.unlazy(this.resultOfChildZero(
        node, b, d))));
    final String language = Helper.getSimpleString(Helper.unlazy(this.resultOfChildOne(node,
        b, d)));
    return LiteralFactory.createLanguageTaggedLiteral(content, language);
  }

  @Override
  public Object evaluate(final ASTABSFuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    final Object type = Helper.getType(o);
    if (type == BigInteger.class) {
      return Helper.getInteger(o).abs();
    }
    if (type == Double.class) {
      return Math.abs(Helper.getDouble(o));
    }
    if (type == Float.class) {
      return Math.abs(Helper.getFloat(o));
    }
    if (type == BigDecimal.class) {
      return Helper.getBigDecimal(o).abs();
    }
    throw new TypeErrorException();
  }

  @Override
  public Object evaluate(final ASTCeilFuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    final Object type = Helper.getType(o);
    if (type == BigInteger.class) {
      return Helper.getInteger(o);
    }
    if (type == Double.class) {
      return Math.ceil(Helper.getDouble(o));
    }
    if (type == Float.class) {
      return Math.ceil(Helper.getFloat(o));
    }
    if (type == BigDecimal.class) {
      final BigDecimal bd = Helper.getBigDecimal(o);
      return bd.setScale(0, RoundingMode.CEILING);
    }
    throw new TypeErrorException();
  }

  @Override
  public Object evaluate(final ASTFloorFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    final Object type = Helper.getType(o);
    if (type == BigInteger.class) {
      return Helper.getInteger(o);
    }
    if (type == Double.class) {
      return Math.floor(Helper.getDouble(o));
    }
    if (type == Float.class) {
      return Math.floor(Helper.getFloat(o));
    }
    if (type == BigDecimal.class) {
      final BigDecimal bd = Helper.getBigDecimal(o);
      return bd.setScale(0, RoundingMode.FLOOR);
    }
    throw new TypeErrorException();
  }

  @Override
  public Object evaluate(final ASTRoundFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    final Object type = Helper.getType(o);
    if (type == BigInteger.class) {
      return Helper.getInteger(o);
    }
    if (type == Double.class) {
      return Math.round(Helper.getDouble(o));
    }
    if (type == Float.class) {
      return Math.round(Helper.getFloat(o));
    }
    if (type == BigDecimal.class) {
      final BigDecimal bd = Helper.getBigDecimal(o);
      return bd.setScale(0, RoundingMode.HALF_UP);
    }
    throw new TypeErrorException();
  }

  @Override
  public Object evaluate(final ASTConcatFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    if (node.jjtGetNumChildren() == 0) {
      return "";
    }
    // jump over ASTExpressionList!
    final Node child0 = node.jjtGetChild(0);
    if (child0 instanceof ASTNIL || child0.jjtGetNumChildren() == 0) {
      return "";
    }
    Object result = Helper.unlazy(child0.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(result)) {
      return null;
    }
    for (int i = 1; i < child0.jjtGetNumChildren(); i++) {

      final Object child = Helper.unlazy(child0.jjtGetChild(i).accept(this, b, d));

      if (Helper.isNumeric(child)) {
        return null;
      }

      final String concatenatedContent = "\"" + Helper.unquote(Helper.getContent(result))
          + Helper.unquote(Helper.getContent(child)) + "\"";

      if (result instanceof TypedLiteral
          && child instanceof TypedLiteral
          && ((TypedLiteral) result).getTypeLiteral().equals(
              ((TypedLiteral) child).getTypeLiteral())) {
        try {
          result = LiteralFactory.createTypedLiteral(
              concatenatedContent, ((TypedLiteral) result)
                  .getTypeLiteral());
        } catch (final URISyntaxException e) {
          throw new TypeErrorException();
        }
      } else if (result instanceof LanguageTaggedLiteral
          && child instanceof LanguageTaggedLiteral
          && ((LanguageTaggedLiteral) result).getLanguage()
              .compareTo(
                  ((LanguageTaggedLiteral) child)
                      .getLanguage()) == 0) {
        result = LiteralFactory.createLanguageTaggedLiteral(
            concatenatedContent, ((LanguageTaggedLiteral) result)
                .getLanguage());
      } else {
        result = concatenatedContent;
      }
    }
    return result;
  }

  @Override
  public Object evaluate(final ASTSubstringFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    final int start = Helper.getInteger(
        Helper.unlazy(node.jjtGetChild(1).accept(this, b, d))).intValue() - 1;
    final String content = Helper.unquote(Helper.getContent(wholeString));
    final String resultantContent;
    if (node.jjtGetNumChildren() == 2) {
      resultantContent = content.substring(start);
    } else {
      final int end = Helper.getInteger(
          Helper.unlazy(node.jjtGetChild(2).accept(this, b, d))).intValue();
      resultantContent = content.substring(start, start + end);
    }
    return Helper.createWithSameType(resultantContent, wholeString);
  }

  @Override
  public Object evaluate(final ASTStrlenFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    final String content = Helper.unquote(Helper.getContent(wholeString));
    return BigInteger.valueOf(content.length());
  }

  @Override
  public Object evaluate(final ASTUcaseFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    return Helper.createWithSameType(Helper.unquote(Helper.getContent(wholeString))
        .toUpperCase(), wholeString);
  }

  @Override
  public Object evaluate(final ASTLcaseFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    return Helper.createWithSameType(Helper.unquote(Helper.getContent(wholeString))
        .toLowerCase(), wholeString);
  }

  // @SuppressWarnings("deprecation")
  @Override
  public Object evaluate(final ASTEncodeForUriFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    try {
      return Helper.quote(URLEncoder.encode(Helper.unquote(Helper.getContent(wholeString)), "UTF-8"));
    } catch (final UnsupportedEncodingException e) {
      throw new TypeErrorException(e.getMessage());
    }
  }

  @Override
  public Object evaluate(final ASTContainsFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    final Object containsString = Helper.unlazy(node.jjtGetChild(1).accept(this, b, d));
    if (Helper.isNumeric(containsString)) {
      return null;
    }
    return (Helper.unquote(Helper.getContent(wholeString))
        .contains(Helper.unquote(Helper.getContent(containsString))));
  }

  @Override
  public Object evaluate(final ASTStrstartsFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    final Object containsString = Helper.unlazy(node.jjtGetChild(1).accept(this, b, d));
    if (Helper.isNumeric(containsString)) {
      return null;
    }
    return (Helper.unquote(Helper.getContent(wholeString))
        .startsWith(Helper.unquote(Helper.getContent(containsString))));
  }

  @Override
  public Object evaluate(final ASTStrEndsFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    final Object containsString = Helper.unlazy(node.jjtGetChild(1).accept(this, b, d));
    if (Helper.isNumeric(containsString)) {
      return null;
    }
    return (Helper.unquote(Helper.getContent(wholeString))
        .endsWith(Helper.unquote(Helper.getContent(containsString))));
  }

  @Override
  public Object evaluate(final ASTStrBeforeFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    final Object containsString = Helper.unlazy(node.jjtGetChild(1).accept(this, b, d));
    if (Helper.isNumeric(containsString)) {
      return null;
    }
    final String stringOfWholeString = Helper.unquote(Helper.getContent(wholeString));
    final int index = stringOfWholeString
        .indexOf(Helper.unquote(Helper.getContent(containsString)));
    if (index > 0) {
      return Helper.createWithSameType(stringOfWholeString.substring(0, index),
          wholeString);
    } else {
      return Helper.createWithSameType("", wholeString);
    }
  }

  @Override
  public Object evaluate(final ASTStrAfterFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object wholeString = Helper.unlazy(node.jjtGetChild(0).accept(this, b, d));
    if (Helper.isNumeric(wholeString)) {
      return null;
    }
    final Object containsString = Helper.unlazy(node.jjtGetChild(1).accept(this, b, d));
    if (Helper.isNumeric(containsString)) {
      return null;
    }
    final String stringOfWholeString = Helper.unquote(Helper.getContent(wholeString));
    final int index = stringOfWholeString
        .indexOf(Helper.unquote(Helper.getContent(containsString)));
    if (index > 0) {
      return Helper.createWithSameType(stringOfWholeString.substring(index),
          wholeString);
    } else {
      return Helper.createWithSameType("", wholeString);
    }
  }

  @Override
  public Object evaluate(final ASTMD5FuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    return Helper.applyHashFunction("MD5", Helper.unquote(Helper.getContent(Helper.unlazy(node
        .jjtGetChild(0).accept(this, b, d)))));
  }

  @Override
  public Object evaluate(final ASTSHA1FuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    return Helper.applyHashFunction("SHA1", Helper.unquote(Helper.getContent(Helper.unlazy(node
        .jjtGetChild(0).accept(this, b, d)))));
  }

  @Override
  public Object evaluate(final ASTSHA256FuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.applyHashFunction("SHA-256", Helper.unquote(Helper.getContent(Helper.unlazy(node
        .jjtGetChild(0).accept(this, b, d)))));
  }

  @Override
  public Object evaluate(final ASTSHA384FuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.applyHashFunction("SHA-384", Helper.unquote(Helper.getContent(Helper.unlazy(node
        .jjtGetChild(0).accept(this, b, d)))));
  }

  @Override
  public Object evaluate(final ASTSHA512FuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.applyHashFunction("SHA-512", Helper.unquote(Helper.getContent(Helper.unlazy(node
        .jjtGetChild(0).accept(this, b, d)))));
  }

  @Override
  public Object evaluate(final ASTYearFuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    return Helper.getDateAndTypeCheck(
        Helper.unlazy(node.jjtGetChild(0).accept(this, b, d))).getYear() + 1900;
  }

  @Override
  public Object evaluate(final ASTMonthFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.getDateAndTypeCheck(
        Helper.unlazy(node.jjtGetChild(0).accept(this, b, d))).getMonth() + 1;
  }

  @Override
  public Object evaluate(final ASTDayFuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    return Helper.getDateAndTypeCheck(
        Helper.unlazy(node.jjtGetChild(0).accept(this, b, d))).getDate();
  }

  @Override
  public Object evaluate(final ASTHoursFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.getDateAndTypeCheck(
        Helper.unlazy(node.jjtGetChild(0).accept(this, b, d))).getHours();
  }

  @Override
  public Object evaluate(final ASTMinutesFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return Helper.getDateAndTypeCheck(
        Helper.unlazy(node.jjtGetChild(0).accept(this, b, d))).getMinutes();
  }

  @Override
  public Object evaluate(final ASTSecondsFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return BigDecimal.valueOf(Helper.getDateAndTypeCheck(
        Helper.unlazy(node.jjtGetChild(0).accept(this, b, d))).getSeconds());
  }

  @Override
  public Object evaluate(final ASTTimeZoneFuncNode node, final Bindings b,
      final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    try {
      return LiteralFactory.createTypedLiteral(Helper
          .getTimezoneAndTypeCheck(Helper.unlazy(node.jjtGetChild(0).accept(
              this, b, d))),
          "<http://www.w3.org/2001/XMLSchema#dayTimeDuration>");
    } catch (final URISyntaxException e) {
      throw new TypeErrorException();
    }
  }

  @Override
  public Object evaluate(final ASTTzFuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    return Helper.getTzAndTypeCheck(Helper.unlazy(node.jjtGetChild(0).accept(this,
        b, d)));
  }

  private static Date now = new Date();

  public static void resetNowDate(){
    now = new Date();
  }

  @Override
  public Object evaluate(final ASTNowFuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    return now;
  }

  @Override
  public Object evaluate(final ASTUUIDFuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    try {
      return LiteralFactory.createURILiteral("<urn:uuid:"+ UUID.randomUUID().toString() + ">");
    } catch (final URISyntaxException e) {
      throw new TypeErrorException(e.getMessage());
    }
  }

  @Override
  public Object evaluate(final ASTSTRUUIDFuncNode node, final Bindings b, final Map<Node, Object> d)
      throws NotBoundException, TypeErrorException {
    return "\"" + UUID.randomUUID().toString() + "\"";
  }

  @Override
  public Object evaluate(final ASTInNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
      return this.handleInAndNotIn(node, b, d);
  }

  @Override
  public Object evaluate(final ASTNotInNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
      return !this.handleInAndNotIn(node, b, d);
  }

  protected boolean handleInAndNotIn(final Node node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object arg1 = Helper.unlazy(this.resultOfChildZero(node, b, d));
    final Node child1 = node.jjtGetChild(1);
    for(int i=0; i<child1.jjtGetNumChildren(); i++) {
      final Object arg2 = Helper.unlazy(child1.jjtGetChild(i).accept(this, b, d));
      if(Helper.equals(arg1, arg2)) {
        return true;
      }
    }
    return false;
  }

  @Override
  public Object evaluate(final ASTRandFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
      return new Double(Math.random());
  }

  @Override
  public Object evaluate(final ASTIfFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object arg0 = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if(Helper.booleanEffectiveValue(arg0)){
      return this.resultOfChildOne(node, b, d);
    } else {
      return this.resultOfChildTwo(node, b, d);
    }
  }

  @Override
  public Object evaluate(final ASTCoalesceFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Node child0 = node.jjtGetChild(0);
    for(int i=0; i<child0.jjtGetNumChildren(); i++){
      try {
        return Helper.unlazy(child0.jjtGetChild(i).accept(this, b, d));
      } catch(final Error e){
        // ignore...
      } catch(final Exception e){
        // ignore...
      }
    }
    return null;
  }

  @Override
  public Object evaluate(final ASTStrReplaceFuncNode node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    final Object o = Helper.unlazy(this.resultOfChildZero(node, b, d));
    if (o instanceof URILiteral || o instanceof AnonymousLiteral || Helper.isNumeric(o)) {
      throw new TypeErrorException();
    }
    final String cmp = Helper.unquote(Helper.getContent(o));
    String pattern = Helper.getString(this.resultOfChildOne(node, b, d));
    final String replacement = Helper.getString(this.resultOfChildTwo(node, b, d));
    String oldPattern;
    do {
      oldPattern = pattern;
      pattern = pattern.replace("\\\\", "\\");
    } while (oldPattern.compareTo(pattern) != 0);
    String flags = "";
    if (node.jjtGetNumChildren() > 3) {
      flags = Helper.getString(this.resultOfChildThree(node, b, d));
    }
    // return match(cmp,pattern,flags); // does not support flag x!!!
    return Helper.createWithSameType(Helper.replaceXerces(cmp, pattern, flags, replacement), o);
  }

  protected Object resultOfChildThree(final Node node, final Bindings b, final Map<Node, Object> d) throws NotBoundException, TypeErrorException {
    return node.jjtGetChild(3).accept(this, b, d);
  }
}
TOP

Related Classes of lupos.engine.operators.singleinput.filter.expressionevaluation.EvaluationVisitorImplementation$NonEmptyApplication

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.