private void createResultBind( final Pattern pattern, int index, InternalReadAccessor arrayReader, AccumulateFunctionCallDescr fc, AccumulateFunction function) { // bind function result on the result pattern Declaration declr = pattern.addDeclaration(fc.getBind()); Class<?> type = function.getResultType(); // this bit is different, notice its the ArrayElementReader that we wire up to, not the // declaration. ArrayElementReader reader = new ArrayElementReader(arrayReader, index, type); declr.setReadAccessor(reader); }
private Accumulator[] buildExternalFunctions( final RuleBuildContext context, final AccumulateDescr accumDescr, MVELDialect dialect, Map<String, Declaration> decls, Map<String, Declaration> sourceOuterDeclr, BoundIdentifiers boundIds, boolean readLocalsFromTuple) { Accumulator[] accumulators; List<AccumulateFunctionCallDescr> functions = accumDescr.getFunctions(); accumulators = new Accumulator[functions.size()]; // creating the custom array reader InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class, "this"); int index = 0; Pattern pattern = (Pattern) context.getBuildStack().peek(); for (AccumulateFunctionCallDescr func : functions) { // build an external function executor AccumulateFunction function = context.getConfiguration().getAccumulateFunction(func.getFunction()); if (function == null) { context.addError( new DescrBuildError( accumDescr, context.getRuleDescr(), null, "Unknown accumulate function: '" + func.getFunction() + "' on rule '" + context.getRuleDescr().getName() + "'. All accumulate functions must be registered before building a resource.")); return null; } // if there is a binding, create the binding if (func.getBind() != null) { if (pattern.getDeclaration(func.getBind()) != null) { context.addError( new DescrBuildError( context.getParentDescr(), accumDescr, null, "Duplicate declaration for variable '" + func.getBind() + "' in the rule '" + context.getRule().getName() + "'")); } else { createResultBind(pattern, index, arrayReader, func, function); } } final AnalysisResult analysis = dialect.analyzeExpression( context, accumDescr, func.getParams().length > 0 ? func.getParams()[0] : "\"\"", boundIds); MVELCompilationUnit unit = dialect.getMVELCompilationUnit( func.getParams().length > 0 ? func.getParams()[0] : "\"\"", analysis, getUsedDeclarations(decls, analysis), getUsedDeclarations(sourceOuterDeclr, analysis), null, context, "drools", KnowledgeHelper.class, readLocalsFromTuple); accumulators[index++] = new MVELAccumulatorFunctionExecutor(unit, function); } return accumulators; }