/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* 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.core;
import com.espertech.esper.core.context.util.AgentInstanceContext;
import com.espertech.esper.epl.expression.core.ExprValidationException;
import com.espertech.esper.epl.spec.RowLimitSpec;
import com.espertech.esper.epl.variable.VariableMetaData;
import com.espertech.esper.epl.variable.VariableReader;
import com.espertech.esper.epl.variable.VariableService;
import com.espertech.esper.epl.variable.VariableServiceUtil;
import com.espertech.esper.util.JavaClassHelper;
/**
* A factory for row-limit processor instances.
*/
public class RowLimitProcessorFactory {
private final VariableMetaData numRowsVariableMetaData;
private final VariableMetaData offsetVariableMetaData;
private int currentRowLimit;
private int currentOffset;
/**
* Ctor.
*
* @param rowLimitSpec specification for row limit, or null if no row limit is defined
* @param variableService for retrieving variable state for use with row limiting
* @param optionalContextName context name
* @throws com.espertech.esper.epl.expression.core.ExprValidationException if row limit specification validation fails
*/
public RowLimitProcessorFactory(RowLimitSpec rowLimitSpec, VariableService variableService, String optionalContextName)
throws ExprValidationException {
if (rowLimitSpec.getNumRowsVariable() != null) {
numRowsVariableMetaData = variableService.getVariableMetaData(rowLimitSpec.getNumRowsVariable());
if (numRowsVariableMetaData == null) {
throw new ExprValidationException("Limit clause variable by name '" + rowLimitSpec.getNumRowsVariable() + "' has not been declared");
}
String message = VariableServiceUtil.checkVariableContextName(optionalContextName, numRowsVariableMetaData);
if (message != null) {
throw new ExprValidationException(message);
}
if (!JavaClassHelper.isNumeric(numRowsVariableMetaData.getType())) {
throw new ExprValidationException("Limit clause requires a variable of numeric type");
}
} else {
numRowsVariableMetaData = null;
currentRowLimit = rowLimitSpec.getNumRows();
if (currentRowLimit < 0) {
currentRowLimit = Integer.MAX_VALUE;
}
}
if (rowLimitSpec.getOptionalOffsetVariable() != null) {
offsetVariableMetaData = variableService.getVariableMetaData(rowLimitSpec.getOptionalOffsetVariable());
if (offsetVariableMetaData == null) {
throw new ExprValidationException("Limit clause variable by name '" + rowLimitSpec.getOptionalOffsetVariable() + "' has not been declared");
}
String message = VariableServiceUtil.checkVariableContextName(optionalContextName, offsetVariableMetaData);
if (message != null) {
throw new ExprValidationException(message);
}
if (!JavaClassHelper.isNumeric(offsetVariableMetaData.getType())) {
throw new ExprValidationException("Limit clause requires a variable of numeric type");
}
} else {
offsetVariableMetaData = null;
if (rowLimitSpec.getOptionalOffset() != null) {
currentOffset = rowLimitSpec.getOptionalOffset();
if (currentOffset <= 0) {
throw new ExprValidationException("Limit clause requires a positive offset");
}
} else {
currentOffset = 0;
}
}
}
public RowLimitProcessor instantiate(AgentInstanceContext agentInstanceContext) {
VariableReader numRowsVariableReader = null;
if (numRowsVariableMetaData != null) {
numRowsVariableReader = agentInstanceContext.getStatementContext().getVariableService().getReader(numRowsVariableMetaData.getVariableName(), agentInstanceContext.getAgentInstanceId());
}
VariableReader offsetVariableReader = null;
if (offsetVariableMetaData != null) {
offsetVariableReader = agentInstanceContext.getStatementContext().getVariableService().getReader(offsetVariableMetaData.getVariableName(), agentInstanceContext.getAgentInstanceId());
}
return new RowLimitProcessor(numRowsVariableReader, offsetVariableReader,
currentRowLimit, currentOffset);
}
}