/************************************************************************************** * 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.epl.expression; import com.espertech.esper.client.hook.AggregationFunctionFactory; import com.espertech.esper.epl.agg.service.AggregationMethodFactory; import com.espertech.esper.epl.agg.service.AggregationValidationContext; import com.espertech.esper.epl.core.MethodResolutionService; import com.espertech.esper.epl.core.StreamTypeService; /** * Represents a custom aggregation function in an expresson tree. */ public class ExprPlugInAggFunctionFactoryNode extends ExprAggregateNodeBase { private static final long serialVersionUID = 65459875362787079L; private transient AggregationFunctionFactory aggregationFunctionFactory; private final String functionName; /** * Ctor. * @param distinct - flag indicating unique or non-unique value aggregation * @param aggregationFunctionFactory - is the base class for plug-in aggregation functions * @param functionName is the aggregation function name */ public ExprPlugInAggFunctionFactoryNode(boolean distinct, AggregationFunctionFactory aggregationFunctionFactory, String functionName) { super(distinct); this.aggregationFunctionFactory = aggregationFunctionFactory; this.functionName = functionName; aggregationFunctionFactory.setFunctionName(functionName); } public AggregationMethodFactory validateAggregationChild(StreamTypeService streamTypeService, MethodResolutionService methodResolutionService, ExprEvaluatorContext exprEvaluatorContext) throws ExprValidationException { Class[] parameterTypes = new Class[this.getChildNodes().size()]; Object[] constant = new Object[this.getChildNodes().size()]; boolean[] isConstant = new boolean[this.getChildNodes().size()]; ExprNode[] expressions = new ExprNode[this.getChildNodes().size()]; int count = 0; boolean hasDataWindows = true; for (ExprNode child : this.getChildNodes()) { if (child.isConstantResult()) { isConstant[count] = true; constant[count] = child.getExprEvaluator().evaluate(null, true, exprEvaluatorContext); } parameterTypes[count] = child.getExprEvaluator().getType(); expressions[count] = child; count++; if (!ExprNodeUtility.hasRemoveStream(child, streamTypeService)) { hasDataWindows = false; } } AggregationValidationContext context = new AggregationValidationContext(parameterTypes, isConstant, constant, super.isDistinct(), hasDataWindows, expressions); try { aggregationFunctionFactory.validate(context); } catch (RuntimeException ex) { throw new ExprValidationException("Plug-in aggregation function factory '" + functionName + "' failed validation: " + ex.getMessage()); } Class childType = null; if (this.getChildNodes().size() > 0) { childType = this.getChildNodes().get(0).getExprEvaluator().getType(); } return new ExprPlugInAggFunctionFactory(aggregationFunctionFactory, super.isDistinct(), childType); } public String getAggregationFunctionName() { return functionName; } public final boolean equalsNodeAggregate(ExprAggregateNode node) { if (!(node instanceof ExprPlugInAggFunctionFactoryNode)) { return false; } ExprPlugInAggFunctionFactoryNode other = (ExprPlugInAggFunctionFactoryNode) node; return other.getAggregationFunctionName().equals(this.getAggregationFunctionName()); } }