if ( source == null ) {
return null;
}
Accumulate accumulate = null;
if ( accumDescr.isExternalFunction() ) {
// if it is an external function, build a method for it
AccumulateFunction function = context.getConfiguration().getAccumulateFunction( accumDescr.getFunctionIdentifier() );
if( function == null ) {
context.getErrors().add( new DescrBuildError( accumDescr,
context.getRuleDescr(),
null,
"Unknown accumulate function: '"+accumDescr.getFunctionIdentifier()+"' on rule '"+context.getRuleDescr().getName()+"'. All accumulate functions must be registered before building a resource." ) );
return null;
}
final JavaAnalysisResult analysis = (JavaAnalysisResult) context.getDialect().analyzeBlock( context,
accumDescr,
accumDescr.getExpression(),
new Map[]{context.getDeclarationResolver().getDeclarationClasses( context.getRule() ), context.getPackageBuilder().getGlobals()} );
final List[] usedIdentifiers = analysis.getBoundIdentifiers();
final List<Declaration> tupleDeclarations = new ArrayList<Declaration>();
for ( int i = 0, size = usedIdentifiers[0].size(); i < size; i++ ) {
tupleDeclarations.add( context.getDeclarationResolver().getDeclaration( context.getRule(),
(String) usedIdentifiers[0].get( i ) ) );
}
final Declaration[] previousDeclarations = tupleDeclarations.toArray( new Declaration[tupleDeclarations.size()] );
final String[] requiredGlobals = (String[]) usedIdentifiers[1].toArray( new String[usedIdentifiers[1].size()] );
final Declaration[] sourceDeclArr = (Declaration[]) source.getOuterDeclarations().values().toArray( new Declaration[0] );
final String className = "accumulateExpression" + context.getNextId();
final Map<String, Object> map = createVariableContext( className,
(String) accumDescr.getExpression(),
context,
previousDeclarations,
sourceDeclArr,
requiredGlobals );
map.put( "readLocalsFromTuple",
accumDescr.isMultiPattern() ? Boolean.TRUE : Boolean.FALSE );
JavaAccumulatorFunctionExecutor accumulator = new JavaAccumulatorFunctionExecutor( function );
accumulate = new Accumulate( source,
previousDeclarations,
sourceDeclArr,
accumulator );
generatTemplates( "returnValueMethod",
"returnValueInvoker",
context,
className,
map,
accumulator,
accumDescr );
} else {
// ELSE, if it is not an external function, build it using the regular java builder
final String className = "Accumulate" + context.getNextId();
accumDescr.setClassName( className );
Map<String, Class< ? >>[] available = new Map[]{context.getDeclarationResolver().getDeclarationClasses( context.getRule() ), context.getPackageBuilder().getGlobals()};
final JavaAnalysisResult initCodeAnalysis = (JavaAnalysisResult) context.getDialect().analyzeBlock( context,
accumDescr,
accumDescr.getInitCode(),
available );
final Dialect.AnalysisResult actionCodeAnalysis = context.getDialect().analyzeBlock( context,
accumDescr,
accumDescr.getActionCode(),
available );
final Dialect.AnalysisResult resultCodeAnalysis = context.getDialect().analyzeExpression( context,
accumDescr,
accumDescr.getResultCode(),
available );
final Set<String> requiredDeclarations = new HashSet<String>( initCodeAnalysis.getBoundIdentifiers()[0] );
requiredDeclarations.addAll( actionCodeAnalysis.getBoundIdentifiers()[0] );
requiredDeclarations.addAll( resultCodeAnalysis.getBoundIdentifiers()[0] );
final Set<String> requiredGlobals = new HashSet<String>( initCodeAnalysis.getBoundIdentifiers()[1] );
requiredGlobals.addAll( actionCodeAnalysis.getBoundIdentifiers()[1] );
requiredGlobals.addAll( resultCodeAnalysis.getBoundIdentifiers()[1] );
if ( accumDescr.getReverseCode() != null ) {
final Dialect.AnalysisResult reverseCodeAnalysis = context.getDialect().analyzeBlock( context,
accumDescr,
accumDescr.getActionCode(),
available );
requiredDeclarations.addAll( reverseCodeAnalysis.getBoundIdentifiers()[0] );
requiredGlobals.addAll( reverseCodeAnalysis.getBoundIdentifiers()[1] );
}
final Declaration[] declarations = new Declaration[requiredDeclarations.size()];
int i = 0;
for ( Iterator<String> it = requiredDeclarations.iterator(); it.hasNext(); i++ ) {
declarations[i] = context.getDeclarationResolver().getDeclaration( context.getRule(),
it.next() );
}
final Declaration[] sourceDeclArr = (Declaration[]) source.getOuterDeclarations().values().toArray( new Declaration[0] );
final String[] globals = requiredGlobals.toArray( new String[requiredGlobals.size()] );
final Map<String, Object> map = createVariableContext( className,
null,
context,
declarations,
null,
globals );
map.put( "className",
accumDescr.getClassName() );
map.put( "innerDeclarations",
sourceDeclArr );
map.put( "isMultiPattern",
accumDescr.isMultiPattern() ? Boolean.TRUE : Boolean.FALSE );
final String initCode = this.fixInitCode( initCodeAnalysis,
accumDescr.getInitCode() );
final String actionCode = accumDescr.getActionCode();
final String resultCode = accumDescr.getResultCode();
String[] attributesTypes = new String[initCodeAnalysis.getLocalVariablesMap().size()];
String[] attributes = new String[initCodeAnalysis.getLocalVariablesMap().size()];
int index = 0;
for ( Map.Entry<String, JavaLocalDeclarationDescr> entry : initCodeAnalysis.getLocalVariablesMap().entrySet() ) {
attributes[index] = entry.getKey();
attributesTypes[index] = entry.getValue().getType();
index++;
}
map.put( "attributes",
attributes );
map.put( "attributesTypes",
attributesTypes );
map.put( "initCode",
initCode );
map.put( "actionCode",
actionCode );
map.put( "resultCode",
resultCode );
if ( accumDescr.getReverseCode() == null ) {
map.put( "reverseCode",
"" );
map.put( "supportsReverse",
"false" );
} else {
map.put( "reverseCode",
accumDescr.getReverseCode() );
map.put( "supportsReverse",
"true" );
}
map.put( "hashCode",
new Integer( actionCode.hashCode() ) );
accumulate = new Accumulate( source,
declarations,
sourceDeclArr );
generatTemplates( "accumulateInnerClass",
"accumulateInvoker",