/**************************************************************************************
* 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.window;
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.agg.service.AggregationServiceFactoryDesc;
import com.espertech.esper.epl.agg.service.AggregationServiceFactoryFactory;
import com.espertech.esper.epl.agg.service.AggregationServiceFactoryServiceImpl;
import com.espertech.esper.epl.core.StreamTypeService;
import com.espertech.esper.epl.core.StreamTypeServiceImpl;
import com.espertech.esper.epl.expression.*;
import com.espertech.esper.event.map.MapEventBean;
import com.espertech.esper.util.JavaClassHelper;
import com.espertech.esper.view.*;
import java.util.*;
/**
* Base factory for expression-based window and batch view.
*/
public abstract class ExpressionViewFactoryBase implements DataWindowViewFactory, DataWindowViewWithPrevious
{
private EventType eventType;
protected ExprNode expiryExpression;
protected MapEventBean builtinMapBean;
protected Set<String> variableNames;
protected AggregationServiceFactoryDesc aggregationServiceFactoryDesc;
public void setViewParameters(ViewFactoryContext viewFactoryContext, List<ExprNode> expressionParameters) throws ViewParameterException
{
if (expressionParameters.size() != 1) {
String errorMessage = "Expression window view requires a single expression as a parameter";
throw new ViewParameterException(errorMessage);
}
expiryExpression = expressionParameters.get(0);
}
public void attach(EventType parentEventType, StatementContext statementContext, ViewFactory optionalParentFactory, List<ViewFactory> parentViewFactories) throws ViewParameterException
{
this.eventType = parentEventType;
// define built-in fields
Map<String, Object> builtinTypeDef = new LinkedHashMap<String, Object>();
builtinTypeDef.put(ExpressionViewUtil.CURRENT_COUNT, Integer.class);
builtinTypeDef.put(ExpressionViewUtil.OLDEST_TIMESTAMP, Long.class);
builtinTypeDef.put(ExpressionViewUtil.NEWEST_TIMESTAMP, Long.class);
builtinTypeDef.put(ExpressionViewUtil.EXPIRED_COUNT, Integer.class);
builtinTypeDef.put(ExpressionViewUtil.VIEW_REFERENCE, Object.class);
EventType builtinMapType = statementContext.getEventAdapterService().createAnonymousMapType(statementContext.getStatementId() + "_exprview", builtinTypeDef);
builtinMapBean = new MapEventBean(new HashMap<String, Object>(), builtinMapType);
StreamTypeService streamTypeService = new StreamTypeServiceImpl(new EventType[] {eventType, builtinMapType}, new String[2], new boolean[2], statementContext.getEngineURI(), false);
// validate expression
expiryExpression = ViewFactorySupport.validateExpr(statementContext, expiryExpression, streamTypeService, 0);
ExprNodeSummaryVisitor summaryVisitor = new ExprNodeSummaryVisitor();
expiryExpression.accept(summaryVisitor);
if (summaryVisitor.isHasSubselect() || summaryVisitor.isHasStreamSelect() || summaryVisitor.isHasPreviousPrior()) {
throw new ViewParameterException("Invalid expiry expression: Sub-select, previous or prior functions are not supported in this context");
}
Class returnType = expiryExpression.getExprEvaluator().getType();
if (JavaClassHelper.getBoxedType(returnType) != Boolean.class) {
throw new ViewParameterException("Invalid return value for expiry expression, expected a boolean return value but received " + JavaClassHelper.getParameterAsString(returnType));
}
// determine variables used, if any
ExprNodeVariableVisitor visitor = new ExprNodeVariableVisitor();
expiryExpression.accept(visitor);
variableNames = visitor.getVariableNames();
// determine aggregation nodes, if any
List<ExprAggregateNode> aggregateNodes = new ArrayList<ExprAggregateNode>();
ExprAggregateNodeUtil.getAggregatesBottomUp(expiryExpression, aggregateNodes);
if (!aggregateNodes.isEmpty()) {
try {
aggregationServiceFactoryDesc = AggregationServiceFactoryFactory.getService(Collections.<ExprAggregateNode>emptyList(), aggregateNodes, Collections.<ExprAggregateNode>emptyList(), false, new ExprEvaluatorContextStatement(statementContext), statementContext.getAnnotations(), statementContext.getVariableService(), false, null, null, AggregationServiceFactoryServiceImpl.DEFAULT_FACTORY, streamTypeService.getEventTypes());
}
catch (ExprValidationException ex) {
throw new ViewParameterException(ex.getMessage(), ex);
}
}
}
public EventType getEventType()
{
return eventType;
}
public boolean canReuse(View view)
{
return false;
}
}