/*
***************************************************************************************
* 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.expression.table;
import com.espertech.esper.epl.expression.core.*;
import com.espertech.esper.epl.table.mgmt.TableMetadata;
import com.espertech.esper.epl.table.mgmt.TableMetadataColumn;
import java.io.StringWriter;
public abstract class ExprTableAccessNode extends ExprNodeBase {
private static final long serialVersionUID = -2048267912299812034L;
protected final String tableName;
protected transient ExprTableAccessEvalStrategy strategy;
protected transient ExprEvaluator[] groupKeyEvaluators;
protected abstract void validateBindingInternal(ExprValidationContext validationContext, TableMetadata tableMetadata)
throws ExprValidationException;
protected abstract boolean equalsNodeInternal(ExprTableAccessNode other);
protected ExprTableAccessNode(String tableName) {
this.tableName = tableName;
}
public String getTableName() {
return tableName;
}
public ExprEvaluator[] getGroupKeyEvaluators() {
return groupKeyEvaluators;
}
public void setStrategy(ExprTableAccessEvalStrategy strategy) {
this.strategy = strategy;
}
public boolean isConstantResult() {
return false;
}
public final ExprNode validate(ExprValidationContext validationContext) throws ExprValidationException {
if (validationContext.getTableService() == null || !validationContext.isAllowBindingConsumption()) {
throw new ExprValidationException("Invalid use of table access expression, expression '" + tableName + "' is not allowed here");
}
TableMetadata metadata = validationContext.getTableService().getTableMetadata(tableName);
if (metadata == null) {
throw new ExprValidationException("A table '" + tableName + "' could not be found");
}
if (metadata.getContextName() != null &&
validationContext.getContextDescriptor() != null &&
!metadata.getContextName().equals(validationContext.getContextDescriptor().getContextName())) {
throw new ExprValidationException("Table by name '" + tableName + "' has been declared for context '" + metadata.getContextName() + "' and can only be used within the same context");
}
// additional validations depend on detail
validateBindingInternal(validationContext, metadata);
return null;
}
protected void validateGroupKeys(TableMetadata metadata) throws ExprValidationException {
if (this.getChildNodes().length > 0) {
groupKeyEvaluators = ExprNodeUtility.getEvaluators(this.getChildNodes());
} else {
groupKeyEvaluators = new ExprEvaluator[0];
}
Class[] typesReturned = ExprNodeUtility.getExprResultTypes(groupKeyEvaluators);
ExprTableNodeUtil.validateExpressions(tableName, typesReturned, "key", this.getChildNodes(), metadata.getKeyTypes(), "key");
}
public final ExprPrecedenceEnum getPrecedence() {
return ExprPrecedenceEnum.UNARY;
}
protected void toPrecedenceFreeEPLInternal(StringWriter writer, String subprop) {
toPrecedenceFreeEPLInternal(writer);
writer.append(".");
writer.append(subprop);
}
protected void toPrecedenceFreeEPLInternal(StringWriter writer) {
writer.append(tableName);
if (this.getChildNodes().length > 0) {
writer.append("[");
String delimiter = "";
for (ExprNode expr : this.getChildNodes()) {
writer.append(delimiter);
expr.toEPL(writer, ExprPrecedenceEnum.MINIMUM);
delimiter = ",";
}
writer.append("]");
}
}
protected TableMetadataColumn validateSubpropertyGetCol(TableMetadata tableMetadata, String subpropName)
throws ExprValidationException {
TableMetadataColumn column = tableMetadata.getTableColumns().get(subpropName);
if (column == null) {
throw new ExprValidationException("A column '" + subpropName + "' could not be found for table '" + tableName + "'");
}
return column;
}
public boolean equalsNode(ExprNode o, boolean ignoreStreamPrefix) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ExprTableAccessNode that = (ExprTableAccessNode) o;
if (!tableName.equals(that.tableName)) return false;
return equalsNodeInternal(that);
}
public int hashCode() {
return tableName != null ? tableName.hashCode() : 0;
}
}