private VerifierAccumulateDescr visitAccumulateDescr(AccumulateDescr descr) throws UnknownDescriptionException { VerifierAccumulateDescr accumulate = new VerifierAccumulateDescr(pattern); PatternDescrVisitor visitor = new PatternDescrVisitor(data, rule, solvers); Pattern parentPattern = visitor.visitPatternDescr(descr.getInputPattern(), null, 0); accumulate.setInitCode(descr.getInitCode()); accumulate.setActionCode(descr.getActionCode()); accumulate.setReverseCode(descr.getReverseCode()); accumulate.setResultCode(descr.getResultCode()); // XXX: Array seems to be always null. // accumulate.setDeclarations(descr.getDeclarations()); accumulate.setClassName(descr.getClassName()); accumulate.setExternalFunction(descr.isExternalFunction()); accumulate.setFunctionIdentifier(descr.getFunctions().get(0).getFunction()); accumulate.setExpression(descr.getFunctions().get(0).getParams()[0]); accumulate.setParentPath(parentPattern.getPath()); accumulate.setParentType(parentPattern.getVerifierComponentType()); data.add(accumulate); return accumulate; }
public RuleConditionElement build( final RuleBuildContext context, final BaseDescr descr, final Pattern prefixPattern) { final AccumulateDescr accumDescr = (AccumulateDescr) descr; if (!accumDescr.hasValidInput()) { return null; } final RuleConditionBuilder builder = context.getDialect().getBuilder(accumDescr.getInput().getClass()); // create source CE final RuleConditionElement source = builder.build(context, accumDescr.getInput()); if (source == null) { return null; } MVELDialect dialect = (MVELDialect) context.getDialect(); final Declaration[] sourceDeclArr = (Declaration[]) source.getOuterDeclarations().values().toArray(new Declaration[0]); Accumulator accumulator = null; Declaration[] declarations = null; if (accumDescr.isExternalFunction()) { // build an external function executor final Dialect.AnalysisResult analysis = dialect.analyzeExpression( context, accumDescr, accumDescr.getExpression(), new Set[] { context.getDeclarationResolver().getDeclarations().keySet(), context.getPkg().getGlobals().keySet() }); int size = analysis.getBoundIdentifiers()[0].size(); declarations = new Declaration[size]; for (int i = 0; i < size; i++) { declarations[i] = context .getDeclarationResolver() .getDeclaration((String) analysis.getBoundIdentifiers()[0].get(i)); } final Serializable expression = dialect.compile( (String) accumDescr.getExpression(), analysis, null, source.getOuterDeclarations(), null, context); AccumulateFunction function = context.getConfiguration().getAccumulateFunction(accumDescr.getFunctionIdentifier()); final DroolsMVELFactory factory = new DroolsMVELFactory( context.getDeclarationResolver().getDeclarations(), source.getOuterDeclarations(), context.getPkg().getGlobals()); MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel"); factory.setNextFactory(data.getFunctionFactory()); accumulator = new MVELAccumulatorFunctionExecutor(factory, expression, function); } else { // it is a custom accumulate final MVELAnalysisResult initCodeAnalysis = (MVELAnalysisResult) dialect.analyzeBlock( context, accumDescr, accumDescr.getInitCode(), new Set[] { context.getDeclarationResolver().getDeclarations().keySet(), context.getPkg().getGlobals().keySet() }); final MVELAnalysisResult actionCodeAnalysis = (MVELAnalysisResult) dialect.analyzeBlock( context, accumDescr, null, accumDescr.getActionCode(), new Set[] { context.getDeclarationResolver().getDeclarations().keySet(), context.getPkg().getGlobals().keySet() }, initCodeAnalysis.getMvelVariables()); // actionCodeAnalysis.setMvelVariables( initCodeAnalysis.getMvelVariables() ); final MVELAnalysisResult resultCodeAnalysis = (MVELAnalysisResult) dialect.analyzeExpression( context, accumDescr, accumDescr.getResultCode(), new Set[] { context.getDeclarationResolver().getDeclarations().keySet(), context.getPkg().getGlobals().keySet() }, initCodeAnalysis.getMvelVariables()); // resultCodeAnalysis.setMvelVariables( initCodeAnalysis.getMvelVariables() ); final List requiredDeclarations = new ArrayList(initCodeAnalysis.getBoundIdentifiers()[0]); requiredDeclarations.addAll(actionCodeAnalysis.getBoundIdentifiers()[0]); requiredDeclarations.addAll(resultCodeAnalysis.getBoundIdentifiers()[0]); Dialect.AnalysisResult reverseCodeAnalysis = null; if (accumDescr.getReverseCode() != null) { reverseCodeAnalysis = context .getDialect() .analyzeBlock( context, accumDescr, accumDescr.getActionCode(), new Set[] { context.getDeclarationResolver().getDeclarations().keySet(), context.getPkg().getGlobals().keySet() }); requiredDeclarations.addAll(reverseCodeAnalysis.getBoundIdentifiers()[0]); } declarations = new Declaration[requiredDeclarations.size()]; for (int i = 0, size = requiredDeclarations.size(); i < size; i++) { declarations[i] = context.getDeclarationResolver().getDeclaration((String) requiredDeclarations.get(i)); } final Serializable init = dialect.compile( (String) accumDescr.getInitCode(), initCodeAnalysis, null, source.getOuterDeclarations(), null, context); final Serializable action = dialect.compile( (String) accumDescr.getActionCode(), actionCodeAnalysis, null, source.getOuterDeclarations(), initCodeAnalysis.getMvelVariables(), context); Serializable reverse = null; if (accumDescr.getReverseCode() != null) { reverse = dialect.compile( (String) accumDescr.getReverseCode(), resultCodeAnalysis, null, source.getOuterDeclarations(), initCodeAnalysis.getMvelVariables(), context); } final Serializable result = dialect.compile( (String) accumDescr.getResultCode(), resultCodeAnalysis, null, source.getOuterDeclarations(), initCodeAnalysis.getMvelVariables(), context); DroolsMVELFactory factory = null; if (reverse == null) { // does not support reverse, so create a regular factory factory = new DroolsMVELFactory( context.getDeclarationResolver().getDeclarations(), source.getOuterDeclarations(), context.getPkg().getGlobals()); } else { Set<String> shadow = new HashSet<String>(source.getOuterDeclarations().keySet()); shadow.retainAll(reverseCodeAnalysis.getNotBoundedIdentifiers()); shadow.addAll(reverseCodeAnalysis.getBoundIdentifiers()[0]); // supports reverse, so create a shadowing factory factory = new DroolsMVELShadowFactory( context.getDeclarationResolver().getDeclarations(), source.getOuterDeclarations(), context.getPkg().getGlobals(), shadow); } MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel"); factory.setNextFactory(data.getFunctionFactory()); accumulator = new MVELAccumulator(factory, init, action, reverse, result); } final Accumulate accumulate = new Accumulate(source, declarations, sourceDeclArr, accumulator); return accumulate; }
@SuppressWarnings("unchecked") public RuleConditionElement build( final RuleBuildContext context, final BaseDescr descr, final Pattern prefixPattern) { try { final AccumulateDescr accumDescr = (AccumulateDescr) descr; if (!accumDescr.hasValidInput()) { return null; } final RuleConditionBuilder builder = (RuleConditionBuilder) context.getDialect().getBuilder(accumDescr.getInput().getClass()); Declaration[] previousDeclarations = (Declaration[]) context .getDeclarationResolver() .getDeclarations(context.getRule()) .values() .toArray( new Declaration [context .getDeclarationResolver() .getDeclarations(context.getRule()) .size()]); // create source CE final RuleConditionElement source = builder.build(context, accumDescr.getInput()); if (source == null) { return null; } MVELDialect dialect = (MVELDialect) context.getDialect(); final Declaration[] sourceDeclArr = (Declaration[]) source .getOuterDeclarations() .values() .toArray(new Declaration[source.getOuterDeclarations().size()]); Accumulator accumulator = null; Declaration[] declarations = null; if (accumDescr.isExternalFunction()) { // build an external function executor 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; } Map<String, Class<?>> declarationsMap = context.getDeclarationResolver().getDeclarationClasses(context.getRule()); final Dialect.AnalysisResult analysis = dialect.analyzeExpression( context, accumDescr, accumDescr.getExpression(), new Map[] {declarationsMap, context.getPackageBuilder().getGlobals()}); MVELCompilationUnit unit = dialect.getMVELCompilationUnit( (String) accumDescr.getExpression(), analysis, previousDeclarations, (Declaration[]) source .getOuterDeclarations() .values() .toArray(new Declaration[source.getOuterDeclarations().size()]), null, context); accumulator = new MVELAccumulatorFunctionExecutor(unit, function); } else { // it is a custom accumulate Map<String, Class<?>> declarationsMap = context.getDeclarationResolver().getDeclarationClasses(context.getRule()); final MVELAnalysisResult initCodeAnalysis = (MVELAnalysisResult) dialect.analyzeBlock( context, accumDescr, accumDescr.getInitCode(), new Map[] {declarationsMap, context.getPackageBuilder().getGlobals()}); final MVELAnalysisResult actionCodeAnalysis = (MVELAnalysisResult) dialect.analyzeBlock( context, accumDescr, null, accumDescr.getActionCode(), new Map[] {declarationsMap, context.getPackageBuilder().getGlobals()}, initCodeAnalysis.getMvelVariables()); final MVELAnalysisResult resultCodeAnalysis = (MVELAnalysisResult) dialect.analyzeExpression( context, accumDescr, accumDescr.getResultCode(), new Map[] {declarationsMap, context.getPackageBuilder().getGlobals()}, initCodeAnalysis.getMvelVariables()); Dialect.AnalysisResult reverseCodeAnalysis = null; if (accumDescr.getReverseCode() != null) { reverseCodeAnalysis = dialect.analyzeBlock( context, accumDescr, null, accumDescr.getActionCode(), new Map[] {declarationsMap, context.getPackageBuilder().getGlobals()}, initCodeAnalysis.getMvelVariables()); } MVELCompilationUnit initUnit = dialect.getMVELCompilationUnit( (String) accumDescr.getInitCode(), initCodeAnalysis, previousDeclarations, (Declaration[]) source .getOuterDeclarations() .values() .toArray(new Declaration[source.getOuterDeclarations().size()]), null, context); MVELCompilationUnit actionUnit = dialect.getMVELCompilationUnit( (String) accumDescr.getActionCode(), actionCodeAnalysis, previousDeclarations, (Declaration[]) source .getOuterDeclarations() .values() .toArray(new Declaration[source.getOuterDeclarations().size()]), initCodeAnalysis.getMvelVariables(), context); MVELCompilationUnit reverseUnit = null; if (accumDescr.getReverseCode() != null) { reverseUnit = dialect.getMVELCompilationUnit( (String) accumDescr.getReverseCode(), reverseCodeAnalysis, previousDeclarations, (Declaration[]) source .getOuterDeclarations() .values() .toArray(new Declaration[source.getOuterDeclarations().size()]), initCodeAnalysis.getMvelVariables(), context); } MVELCompilationUnit resultUnit = dialect.getMVELCompilationUnit( (String) accumDescr.getResultCode(), resultCodeAnalysis, previousDeclarations, (Declaration[]) source .getOuterDeclarations() .values() .toArray(new Declaration[source.getOuterDeclarations().size()]), initCodeAnalysis.getMvelVariables(), context); if (reverseUnit != null) { Set<String> shadow = new HashSet<String>(source.getOuterDeclarations().keySet()); shadow.retainAll(reverseCodeAnalysis.getNotBoundedIdentifiers()); shadow.addAll(reverseCodeAnalysis.getBoundIdentifiers()[0]); String[] shadowVars = (String[]) shadow.toArray(new String[shadow.size()]); actionUnit.setShadowIdentifiers(shadowVars); reverseUnit.setShadowIdentifiers(shadowVars); } accumulator = new MVELAccumulator(initUnit, actionUnit, reverseUnit, resultUnit); } final Accumulate accumulate = new Accumulate(source, declarations, sourceDeclArr, new Accumulator[] {accumulator}); MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel"); data.addCompileable(accumulate, (MVELCompileable) accumulator); ((MVELCompileable) accumulator).compile(context.getPackageBuilder().getRootClassLoader()); return accumulate; } catch (Exception e) { context .getErrors() .add( new DescrBuildError( context.getParentDescr(), descr, e, "Unable to build expression for 'accumulate' : " + e.getMessage())); return null; } }
private Accumulator[] buildCustomAccumulate( final RuleBuildContext context, final AccumulateDescr accumDescr, final RuleConditionElement source, MVELDialect dialect, Map<String, Declaration> decls, Map<String, Declaration> sourceOuterDeclr, BoundIdentifiers boundIds, boolean readLocalsFromTuple) { Accumulator[] accumulators; final MVELAnalysisResult initCodeAnalysis = (MVELAnalysisResult) dialect.analyzeBlock(context, accumDescr, accumDescr.getInitCode(), boundIds); // need to copy boundIds, as this as a "this" object. final MVELAnalysisResult actionCodeAnalysis = (MVELAnalysisResult) dialect.analyzeBlock( context, accumDescr, null, accumDescr.getActionCode(), boundIds, initCodeAnalysis.getMvelVariables(), "drools", KnowledgeHelper.class); final MVELAnalysisResult resultCodeAnalysis = (MVELAnalysisResult) dialect.analyzeExpression( context, accumDescr, accumDescr.getResultCode(), boundIds, initCodeAnalysis.getMvelVariables()); // MVELAnalysisResult reverseCodeAnalysis = null; // if ( accumDescr.getReverseCode() != null ) { // reverseCodeAnalysis = (MVELAnalysisResult) dialect.analyzeBlock( context, // accumDescr, // null, // // accumDescr.getActionCode(), // boundIds, // // initCodeAnalysis.getMvelVariables(), // "drools", // // KnowledgeHelper.class ); // } context.setTypesafe(initCodeAnalysis.isTypesafe()); MVELCompilationUnit initUnit = dialect.getMVELCompilationUnit( (String) accumDescr.getInitCode(), initCodeAnalysis, getUsedDeclarations(decls, initCodeAnalysis), getUsedDeclarations(sourceOuterDeclr, initCodeAnalysis), initCodeAnalysis.getMvelVariables(), context, "drools", KnowledgeHelper.class, readLocalsFromTuple); context.setTypesafe(actionCodeAnalysis.isTypesafe()); MVELCompilationUnit actionUnit = dialect.getMVELCompilationUnit( (String) accumDescr.getActionCode(), actionCodeAnalysis, getUsedDeclarations(decls, actionCodeAnalysis), getUsedDeclarations(sourceOuterDeclr, actionCodeAnalysis), initCodeAnalysis.getMvelVariables(), context, "drools", KnowledgeHelper.class, readLocalsFromTuple); MVELCompilationUnit reverseUnit = null; if (accumDescr.getReverseCode() != null) { context.setTypesafe(actionCodeAnalysis.isTypesafe()); reverseUnit = dialect.getMVELCompilationUnit( (String) accumDescr.getReverseCode(), actionCodeAnalysis, getUsedDeclarations(decls, actionCodeAnalysis), getUsedDeclarations(sourceOuterDeclr, actionCodeAnalysis), initCodeAnalysis.getMvelVariables(), context, "drools", KnowledgeHelper.class, readLocalsFromTuple); } context.setTypesafe(resultCodeAnalysis.isTypesafe()); MVELCompilationUnit resultUnit = dialect.getMVELCompilationUnit( (String) accumDescr.getResultCode(), resultCodeAnalysis, getUsedDeclarations(decls, resultCodeAnalysis), getUsedDeclarations(sourceOuterDeclr, resultCodeAnalysis), initCodeAnalysis.getMvelVariables(), context, "drools", KnowledgeHelper.class, readLocalsFromTuple); // if ( reverseUnit != null ) { // Set<String> shadow = new HashSet<String>( source.getOuterDeclarations().keySet() // ); // shadow.retainAll( reverseCodeAnalysis.getNotBoundedIdentifiers() ); // shadow.addAll( // reverseCodeAnalysis.getBoundIdentifiers().getDeclrClasses().keySet() ); // // String[] shadowVars = (String[]) shadow.toArray( new String[shadow.size()] ); // // actionUnit.setShadowIdentifiers( shadowVars ); // reverseUnit.setShadowIdentifiers( shadowVars ); // } accumulators = new Accumulator[] {new MVELAccumulator(initUnit, actionUnit, reverseUnit, resultUnit)}; return accumulators; }