package eu.play_project.play_platformservices_querydispatcher.bdpl.visitor.realtime; import java.util.Stack; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.hp.hpl.jena.sparql.expr.ExprAggregator; import com.hp.hpl.jena.sparql.expr.ExprFunction2; import com.hp.hpl.jena.sparql.expr.ExprVar; import com.hp.hpl.jena.sparql.expr.NodeValue; import com.hp.hpl.jena.sparql.expr.aggregate.AggAvg; import com.hp.hpl.jena.sparql.expr.aggregate.AggCount; import com.hp.hpl.jena.sparql.expr.aggregate.AggMax; import com.hp.hpl.jena.sparql.expr.aggregate.AggMin; import com.hp.hpl.jena.sparql.expr.aggregate.AggSample; import com.hp.hpl.jena.sparql.expr.aggregate.AggSum; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueBoolean; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueDT; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueDecimal; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueDouble; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueDuration; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueFloat; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueInteger; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueNode; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueString; import com.hp.hpl.jena.sparql.expr.nodevalue.NodeValueVisitor; public class MathExprFunctionXVisitor extends GenericVisitor { Logger logger; Stack<String> stack; StringBuffer code; UniqueNameManager uniqueNameManager; public MathExprFunctionXVisitor(){ logger = LoggerFactory.getLogger(MathExprFunctionXVisitor.class); uniqueNameManager = UniqueNameManager.getVarNameManager(); stack = new Stack<String>(); code = new StringBuffer(); } /** * Generate CEP-Engine code for expressions with two value. * Transform infix operators to prefix operators. E.g. (1 + 2)-3 -> plus(1, 2, R), minus(R, 3, R2) */ @Override public void visit(ExprFunction2 func) { // Use post-order traversal except if node is a infix operator in prolog. In this case use in-order traversal. // Get left values func.getArg1().visit(this); //Infix operator if (func instanceof com.hp.hpl.jena.sparql.expr.E_LogicalAnd) { code.append("), ("); // AND representation in prolog. stack.push(""); //NOP }else if (func instanceof com.hp.hpl.jena.sparql.expr.E_LogicalOr) { code.append("); ("); // OR representation in prolog stack.push(""); //NOP } // Right values func.getArg2().visit(this); String rightElem = stack.pop(); // Operator if (func instanceof com.hp.hpl.jena.sparql.expr.E_LogicalAnd) { // Do nothing AND is infix operator } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_LessThan) { if(code.length()>2) code.append(","); // At the beginning of a string no ",". code.append("less(" + stack.pop() + ", " + rightElem + ")"); } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_Subtract) { code.append("minus(" + stack.pop() + "," + rightElem + ", " + uniqueNameManager.getNextFilterVar() + ")"); stack.push(uniqueNameManager.getFilterVar()); } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_Multiply) { code.append("multiply(" + stack.pop() + "," + rightElem + ", " + uniqueNameManager.getNextFilterVar() + ")"); stack.push(uniqueNameManager.getFilterVar()); } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_Divide) { code.append("/"); } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_Add) { code.append("plus(" + stack.pop() + "," + rightElem + ", " + uniqueNameManager.getNextFilterVar() + ")"); stack.push(uniqueNameManager.getFilterVar()); } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_GreaterThanOrEqual) { code.append("greaterOrEqual(" + stack.pop() + "," + rightElem + ")"); stack.push(uniqueNameManager.getFilterVar()); } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_GreaterThan) { if(code.length()>2 && !code.toString().endsWith(",")) code.append(","); // TODO look if this is needed for other operators code.append("greater(" + stack.pop() + "," + rightElem + ")"); stack.push(uniqueNameManager.getFilterVar()); } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_Equals) { code.append("equal(" + stack.pop() + "," + rightElem +")"); stack.push(uniqueNameManager.getFilterVar()); } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_NotEquals) { code.append("notEqual(" + stack.pop() + "," + rightElem +")"); stack.push(uniqueNameManager.getFilterVar()); } else if (func instanceof com.hp.hpl.jena.sparql.expr.E_StrContains) { code.append( " (xpath(element(sparqlFilter, [keyWord=" + stack.pop() + "], []), //sparqlFilter(contains(@keyWord,'" //Cutting away opening and closing quotes. + rightElem.substring(1, (rightElem.length()-1)) + "')), _))"); stack.push(uniqueNameManager.getFilterVar()); } else { throw new RuntimeException("Operator not implemented " + func.getClass().getName()); } } @Override public void visit(ExprVar nv) { stack.push("V" + nv.getVarName()); } @Override public void visit(NodeValueDecimal nv) { stack.push(nv.toString()); } @Override public void visit(NodeValue nv) { nv.visit(new MathExprNodeVisitor()); //stack.push(nv.visit(visitor) + ""); } @Override public void visit(ExprAggregator arg0) { // This expression contains possibly more expressions. E.g. (1 + 2 - t). // For this reason visit the element and make post-order traversal. code.append("calcAverage(" + uniqueNameManager.getAggrDbId() + ", " + uniqueNameManager.getWindowTime() + ", " + uniqueNameManager.getResultVar1() + "), "); stack.push(uniqueNameManager.getResultVar1()); if (arg0.getAggregator() instanceof AggMax){ }else if(arg0.getAggregator() instanceof AggMin){ }else if(arg0.getAggregator() instanceof AggSum){ }else if(arg0.getAggregator() instanceof AggCount){ }else if(arg0.getAggregator() instanceof AggAvg){ //code.append("calcAverage(" + uniqueNameManager.g); }else if(arg0.getAggregator() instanceof AggSample){ } } public void visit1(ExprAggregator arg0) { // For not nested expressions. E.g. AVG(?value) code.append("calcAverage(" + uniqueNameManager.getAggrDbId() + ", " + uniqueNameManager.getWindowTime() + ", " + uniqueNameManager.getResultVar1() + ")"); } public StringBuffer getCode() { return code; } class MathExprNodeVisitor implements NodeValueVisitor{ @Override public void visit(NodeValueBoolean nv) { throw new RuntimeException(nv.toString() + "is not a valid value in math expressions."); } @Override public void visit(NodeValueDouble nv) { stack.push(nv.getDouble() + ""); } @Override public void visit(NodeValueFloat nv) { stack.push(nv.getFloat() + ""); } @Override public void visit(NodeValueInteger nv) { stack.push(nv.getInteger() + ""); } @Override public void visit(NodeValueString nv) { throw new RuntimeException(nv.toString() + "is not a valid value in math expressions."); } @Override public void visit(NodeValueDT nv) { throw new RuntimeException(nv.toString() + "is not a valid value in math expressions."); } @Override public void visit(NodeValueDuration nodeValueDuration) { stack.push(nodeValueDuration.getDuration() + ""); } @Override public void visit(NodeValueDecimal nv) { stack.push(nv.getDecimal() + ""); } @Override public void visit(NodeValueNode nv) { throw new RuntimeException(nv.toString() + "unknown datatype."); } } }