/**************************************************************************************
* Copyright (C) 2008 EsperTech, Inc. All rights reserved. *
* http://esper.codehaus.org *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
**************************************************************************************/
package com.espertech.esper.view;
import com.espertech.esper.client.EventType;
import com.espertech.esper.core.service.ExprEvaluatorContextStatement;
import com.espertech.esper.core.service.StatementContext;
import com.espertech.esper.epl.core.StreamTypeService;
import com.espertech.esper.epl.core.StreamTypeServiceImpl;
import com.espertech.esper.epl.expression.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.ArrayList;
import java.util.List;
/**
* Abstract base class for view factories that do not make re-useable views and that do
* not share view resources with expression nodes.
*/
public abstract class ViewFactorySupport implements ViewFactory
{
private static Log log = LogFactory.getLog(ViewFactorySupport.class);
public boolean canReuse(View view)
{
return false;
}
/**
* Validate the view parameter expression and evaluate the expression returning the result object.
* @param viewName textual name of view
* @param statementContext context with statement services
* @param expression view expression parameter to validate
* @return object result value of parameter expression
* @throws ViewParameterException if the expressions fail to validate
*/
public static Object validateAndEvaluate(String viewName, StatementContext statementContext, ExprNode expression)
throws ViewParameterException
{
return validateAndEvaluateExpr(statementContext, expression, new StreamTypeServiceImpl(statementContext.getEngineURI(), false), 0);
}
/**
* Validate the view parameter expressions and evaluate the expressions returning the result object.
* @param viewName textual name of view
* @param statementContext context with statement services
* @param expressions view expression parameter to validate
* @return object result value of parameter expressions
* @throws ViewParameterException if the expressions fail to validate
*/
public static List<Object> validateAndEvaluate(String viewName, StatementContext statementContext, List<ExprNode> expressions)
throws ViewParameterException
{
List<Object> results = new ArrayList<Object>();
int expressionNumber = 0;
StreamTypeService streamTypeService = new StreamTypeServiceImpl(statementContext.getEngineURI(), false);
for (ExprNode expr : expressions)
{
Object result = validateAndEvaluateExpr(statementContext, expr, streamTypeService, expressionNumber);
results.add(result);
expressionNumber++;
}
return results;
}
/**
* Validate the view parameter expressions and return the validated expression for later execution.
* <p>
* Does not evaluate the expression.
* @param viewName textual name of view
* @param eventType is the event type of the parent view or stream attached.
* @param statementContext context with statement services
* @param expressions view expression parameter to validate
* @param allowConstantResult true to indicate whether expressions that return a constant
* result should be allowed; false to indicate that if an expression is known to return a constant result
* the expression is considered invalid
* @return object result value of parameter expressions
* @throws ViewParameterException if the expressions fail to validate
*/
public static ExprNode[] validate(String viewName, EventType eventType, StatementContext statementContext, List<ExprNode> expressions, boolean allowConstantResult)
throws ViewParameterException
{
List<ExprNode> results = new ArrayList<ExprNode>();
int expressionNumber = 0;
StreamTypeService streamTypeService = new StreamTypeServiceImpl(eventType, null, false, statementContext.getEngineURI());
for (ExprNode expr : expressions)
{
ExprNode validated = validateExpr(statementContext, expr, streamTypeService, expressionNumber);
results.add(validated);
if ((!allowConstantResult) && (validated.isConstantResult()))
{
String message = "Invalid view parameter expression " + expressionNumber + ", the expression returns a constant result value, are you sure?";
log.error(message);
throw new ViewParameterException(message);
}
expressionNumber++;
}
return results.toArray(new ExprNode[results.size()]);
}
/**
* Assert and throws an exception if the expression passed returns a non-constant value.
* @param viewName textual name of view
* @param expression expression to check
* @param index number offset of expression in view parameters
* @throws ViewParameterException if assertion fails
*/
public static void assertReturnsNonConstant(String viewName, ExprNode expression, int index) throws ViewParameterException
{
if (expression.isConstantResult())
{
String message = "Invalid view parameter expression " + index + ", the expression returns a constant result value, are you sure?";
log.error(message);
throw new ViewParameterException(message);
}
}
/**
* Assert and throws an exception if the expression uses event property values.
* @param viewName textual name of view
* @param expression expression to check
* @param index number offset of expression in view parameters
* @param exprEvaluatorContext context for expression evaluation
* @return expression evaluation value
* @throws ViewParameterException if assertion fails
*/
public static Object evaluateAssertNoProperties(String viewName, ExprNode expression, int index, ExprEvaluatorContext exprEvaluatorContext) throws ViewParameterException
{
ExprNodeSummaryVisitor visitor = new ExprNodeSummaryVisitor();
expression.accept(visitor);
if (!visitor.isPlain())
{
String message = "Invalid view parameter expression " + index + ", " + visitor.getMessage() + " are not allowed within the expression";
throw new ViewParameterException(message);
}
return expression.getExprEvaluator().evaluate(null, false, exprEvaluatorContext);
}
private static Object validateAndEvaluateExpr(StatementContext statementContext, ExprNode expression, StreamTypeService streamTypeService, int expressionNumber)
throws ViewParameterException
{
ExprNode validated = validateExpr(statementContext, expression, streamTypeService, expressionNumber);
try
{
return validated.getExprEvaluator().evaluate(null, true, new ExprEvaluatorContextStatement(statementContext));
}
catch (RuntimeException ex)
{
String message = "Failed to evaluate parameter expression " + expressionNumber;
if (ex.getMessage() != null)
{
message += ": " + ex.getMessage();
}
log.error(message, ex);
throw new ViewParameterException(message, ex);
}
}
public static ExprNode validateExpr(StatementContext statementContext, ExprNode expression, StreamTypeService streamTypeService, int expressionNumber)
throws ViewParameterException
{
ExprNode validated;
try
{
ExprEvaluatorContextStatement exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext);
ExprValidationContext validationContext = new ExprValidationContext(streamTypeService, statementContext.getMethodResolutionService(),
null, statementContext.getSchedulingService(), statementContext.getVariableService(), exprEvaluatorContext, statementContext.getEventAdapterService(), statementContext.getStatementName(), statementContext.getStatementId(), statementContext.getAnnotations(), statementContext.getContextDescriptor());
validated = ExprNodeUtility.getValidatedSubtree(expression, validationContext);
}
catch (ExprValidationException ex)
{
String message = "Invalid parameter expression " + expressionNumber;
if (ex.getMessage() != null)
{
message += ": " + ex.getMessage();
}
log.error(message, ex);
throw new ViewParameterException(message, ex);
}
return validated;
}
}