Annotation[] annotations)
throws ExprValidationException
{
int length = spec.getAtoms().size();
EventPropertyGetter[] getters = new EventPropertyGetter[length];
FragmentEventType types[] = new FragmentEventType[length];
EventType currentEventType = sourceEventType;
ExprEvaluator whereClauses[] = new ExprEvaluator[length];
List<EventType> streamEventTypes = new ArrayList<EventType>();
List<String> streamNames = new ArrayList<String>();
Map<String, Integer> streamNameAndNumber = new HashMap<String,Integer>();
List<String> propertyNames = new ArrayList<String>();
ExprEvaluatorContext validateContext = new ExprEvaluatorContext()
{
public TimeProvider getTimeProvider()
{
return timeProvider;
}
public ExpressionResultCacheService getExpressionResultCacheService() {
return null;
}
};
streamEventTypes.add(sourceEventType);
streamNames.add(optionalSourceStreamName);
streamNameAndNumber.put(optionalSourceStreamName, 0);
propertyNames.add(sourceEventType.getName());
List<SelectClauseElementCompiled> cumulativeSelectClause = new ArrayList<SelectClauseElementCompiled>();
for (int i = 0; i < length; i++)
{
PropertyEvalAtom atom = spec.getAtoms().get(i);
// obtain property info
String propertyName = atom.getPropertyName();
FragmentEventType fragmentEventType = currentEventType.getFragmentType(propertyName);
if (fragmentEventType == null)
{
throw new ExprValidationException("Property expression '" + propertyName + "' against type '" + currentEventType.getName() + "' does not return a fragmentable property value");
}
EventPropertyGetter getter = currentEventType.getGetter(propertyName);
if (getter == null)
{
throw new ExprValidationException("Property expression '" + propertyName + "' against type '" + currentEventType.getName() + "' does not return a fragmentable property value");
}
// validate where clause, if any
streamEventTypes.add(fragmentEventType.getFragmentType());
streamNames.add(atom.getOptionalAsName());
streamNameAndNumber.put(atom.getOptionalAsName(), i + 1);
propertyNames.add(atom.getPropertyName());
if (atom.getOptionalWhereClause() != null)
{
EventType[] whereTypes = streamEventTypes.toArray(new EventType[streamEventTypes.size()]);
String[] whereStreamNames = streamNames.toArray(new String[streamNames.size()]);
boolean[] isIStreamOnly = new boolean[streamNames.size()];
Arrays.fill(isIStreamOnly, true);
StreamTypeService streamTypeService = new StreamTypeServiceImpl(whereTypes, whereStreamNames, isIStreamOnly, engineURI, false);
ExprValidationContext validationContext = new ExprValidationContext(streamTypeService, methodResolutionService, null, timeProvider, variableService, validateContext, eventAdapterService, statementName, annotations);
whereClauses[i] = ExprNodeUtil.getValidatedSubtree(atom.getOptionalWhereClause(), validationContext).getExprEvaluator();
}
// validate select clause
if (atom.getOptionalSelectClause() != null)
{
EventType[] whereTypes = streamEventTypes.toArray(new EventType[streamEventTypes.size()]);
String[] whereStreamNames = streamNames.toArray(new String[streamNames.size()]);
boolean[] isIStreamOnly = new boolean[streamNames.size()];
Arrays.fill(isIStreamOnly, true);
StreamTypeService streamTypeService = new StreamTypeServiceImpl(whereTypes, whereStreamNames, isIStreamOnly, engineURI, false);
ExprValidationContext validationContext = new ExprValidationContext(streamTypeService, methodResolutionService, null, timeProvider, variableService, validateContext, eventAdapterService, statementName, annotations);
for (SelectClauseElementRaw raw : atom.getOptionalSelectClause().getSelectExprList())
{
if (raw instanceof SelectClauseStreamRawSpec)
{
SelectClauseStreamRawSpec rawStreamSpec = (SelectClauseStreamRawSpec) raw;
if (!streamNames.contains(rawStreamSpec.getStreamName()))
{
throw new ExprValidationException("Property rename '" + rawStreamSpec.getStreamName() + "' not found in path");
}
SelectClauseStreamCompiledSpec streamSpec = new SelectClauseStreamCompiledSpec(rawStreamSpec.getStreamName(), rawStreamSpec.getOptionalAsName());
int streamNumber = streamNameAndNumber.get(rawStreamSpec.getStreamName());
streamSpec.setStreamNumber(streamNumber);
cumulativeSelectClause.add(streamSpec);
}
else if (raw instanceof SelectClauseExprRawSpec)
{
SelectClauseExprRawSpec exprSpec = (SelectClauseExprRawSpec) raw;
ExprNode exprCompiled = ExprNodeUtil.getValidatedSubtree(exprSpec.getSelectExpression(), validationContext);
String resultName = exprSpec.getOptionalAsName();
if (resultName == null)
{
resultName = exprCompiled.toExpressionString();
}
cumulativeSelectClause.add(new SelectClauseExprCompiledSpec(exprCompiled, resultName));
String isMinimal = ExprNodeUtility.isMinimalExpression(exprCompiled);
if (isMinimal != null)
{
throw new ExprValidationException("Expression in a property-selection may not utilize " + isMinimal);
}
}
else if (raw instanceof SelectClauseElementWildcard)
{
// wildcards are stream selects: we assign a stream name (any) and add a stream wildcard select
String streamNameAtom = atom.getOptionalAsName();
if (streamNameAtom == null)
{
streamNameAtom = UuidGenerator.generate();
}
SelectClauseStreamCompiledSpec streamSpec = new SelectClauseStreamCompiledSpec(streamNameAtom, atom.getOptionalAsName());
int streamNumber = i + 1;
streamSpec.setStreamNumber(streamNumber);
cumulativeSelectClause.add(streamSpec);
}
else
{
throw new IllegalStateException("Unknown select clause item:" + raw);
}
}
}
currentEventType = fragmentEventType.getFragmentType();
types[i] = fragmentEventType;
getters[i] = getter;
}
if (cumulativeSelectClause.isEmpty())