/** * Builds and returns an Eval Conditional Element * * @param context The current build context * @param utils The current build utils instance * @param patternBuilder not used by EvalBuilder * @param descr The Eval Descriptor to build the eval conditional element from * @return the Eval Conditional Element */ public RuleConditionElement build( final RuleBuildContext context, final BaseDescr descr, final Pattern prefixPattern) { // it must be an EvalDescr final EvalDescr evalDescr = (EvalDescr) descr; try { MVELDialect dialect = (MVELDialect) context.getDialect(context.getDialect().getId()); Map<String, Declaration> decls = context.getDeclarationResolver().getDeclarations(context.getRule()); AnalysisResult analysis = context .getDialect() .analyzeExpression( context, evalDescr, evalDescr.getContent(), new BoundIdentifiers( context.getDeclarationResolver().getDeclarationClasses(decls), context.getPackageBuilder().getGlobals())); Collection<Declaration> col = decls.values(); Declaration[] previousDeclarations = (Declaration[]) col.toArray(new Declaration[col.size()]); MVELCompilationUnit unit = dialect.getMVELCompilationUnit( (String) evalDescr.getContent(), analysis, previousDeclarations, null, null, context); final EvalCondition eval = new EvalCondition(previousDeclarations); MVELEvalExpression expr = new MVELEvalExpression(unit, dialect.getId()); eval.setEvalExpression(expr); MVELDialectRuntimeData data = (MVELDialectRuntimeData) context .getPkg() .getDialectRuntimeRegistry() .getDialectData(context.getDialect().getId()); data.addCompileable(eval, expr); expr.compile(context.getPackageBuilder().getRootClassLoader()); return eval; } catch (final Exception e) { context .getErrors() .add( new DescrBuildError( context.getParentDescr(), evalDescr, e, "Unable to build expression for 'eval':" + e.getMessage() + " '" + evalDescr.getContent() + "'")); return null; } }
public void build( final RuleBuildContext context, final BoundIdentifiers usedIdentifiers, final Declaration[] previousDeclarations, final Declaration[] localDeclarations, final PredicateConstraint predicate, final PredicateDescr predicateDescr, final AnalysisResult analysis) { MVELDialect dialect = (MVELDialect) context.getDialect(context.getDialect().getId()); try { Map<String, Class<?>> declIds = context.getDeclarationResolver().getDeclarationClasses(context.getRule()); Pattern p = (Pattern) context.getBuildStack().peek(); if (p.getObjectType() instanceof ClassObjectType) { declIds.put("this", ((ClassObjectType) p.getObjectType()).getClassType()); } MVELCompilationUnit unit = dialect.getMVELCompilationUnit( (String) predicateDescr.getContent(), analysis, previousDeclarations, localDeclarations, null, context); MVELPredicateExpression expr = new MVELPredicateExpression(unit, context.getDialect().getId()); predicate.setPredicateExpression(expr); MVELDialectRuntimeData data = (MVELDialectRuntimeData) context .getPkg() .getDialectRuntimeRegistry() .getDialectData(context.getDialect().getId()); data.addCompileable(predicate, expr); expr.compile(context.getPackageBuilder().getRootClassLoader()); } catch (final Exception e) { context .getErrors() .add( new DescrBuildError( context.getParentDescr(), predicateDescr, e, "Unable to build expression for 'inline-eval' : " + e.getMessage() + "'" + predicateDescr.getContent() + "'\n" + e.getMessage())); } }
/** * Builds and returns an Eval Conditional Element * * @param context The current build context * @param utils The current build utils instance * @param patternBuilder not used by EvalBuilder * @param descr The Eval Descriptor to build the eval conditional element from * @return the Eval Conditional Element */ public RuleConditionElement build( final RuleBuildContext context, final BaseDescr descr, final Pattern prefixPattern) { boolean typesafe = context.isTypesafe(); // it must be an EvalDescr final EvalDescr evalDescr = (EvalDescr) descr; try { MVELDialect dialect = (MVELDialect) context.getDialect(context.getDialect().getId()); Map<String, Declaration> decls = context.getDeclarationResolver().getDeclarations(context.getRule()); AnalysisResult analysis = context .getDialect() .analyzeExpression( context, evalDescr, evalDescr.getContent(), new BoundIdentifiers( context.getDeclarationResolver().getDeclarationClasses(decls), context.getPackageBuilder().getGlobals())); final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers(); int i = usedIdentifiers.getDeclrClasses().keySet().size(); Declaration[] previousDeclarations = new Declaration[i]; i = 0; for (String id : usedIdentifiers.getDeclrClasses().keySet()) { previousDeclarations[i++] = decls.get(id); } Arrays.sort(previousDeclarations, SortDeclarations.instance); MVELCompilationUnit unit = dialect.getMVELCompilationUnit( (String) evalDescr.getContent(), analysis, previousDeclarations, null, null, context, "drools", KnowledgeHelper.class, false); final EvalCondition eval = new EvalCondition(previousDeclarations); MVELEvalExpression expr = new MVELEvalExpression(unit, dialect.getId()); eval.setEvalExpression(expr); MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel"); data.addCompileable(eval, expr); expr.compile(data); return eval; } catch (final Exception e) { copyErrorLocation(e, evalDescr); context.addError( new DescrBuildError( context.getParentDescr(), evalDescr, e, "Unable to build expression for 'eval':" + e.getMessage() + " '" + evalDescr.getContent() + "'")); return null; } finally { context.setTypesafe(typesafe); } }
@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; } }
@SuppressWarnings("unchecked") public RuleConditionElement build( final RuleBuildContext context, final BaseDescr descr, final Pattern prefixPattern) { boolean typesafe = context.isTypesafe(); try { final AccumulateDescr accumDescr = (AccumulateDescr) descr; if (!accumDescr.hasValidInput()) { return null; } final RuleConditionBuilder builder = (RuleConditionBuilder) 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(); Map<String, Declaration> decls = context.getDeclarationResolver().getDeclarations(context.getRule()); Map<String, Declaration> sourceOuterDeclr = source.getOuterDeclarations(); Map<String, Declaration> mergedDecl = new HashMap(decls); mergedDecl.putAll(sourceOuterDeclr); Map<String, Class<?>> declarationClasses = context.getDeclarationResolver().getDeclarationClasses(decls); declarationClasses.putAll( context.getDeclarationResolver().getDeclarationClasses(sourceOuterDeclr)); BoundIdentifiers boundIds = new BoundIdentifiers(declarationClasses, context.getPackageBuilder().getGlobals()); boundIds.setDeclarations(mergedDecl); Accumulator[] accumulators = null; final boolean readLocalsFromTuple = PackageBuilderUtil.isReadLocalsFromTuple(accumDescr, source); if (accumDescr.isExternalFunction()) { // uses accumulate functions accumulators = buildExternalFunctions( context, accumDescr, dialect, decls, sourceOuterDeclr, boundIds, readLocalsFromTuple); } else { // it is a custom accumulate accumulators = buildCustomAccumulate( context, accumDescr, source, dialect, decls, sourceOuterDeclr, boundIds, readLocalsFromTuple); } final Accumulate accumulate = new Accumulate(source, null, accumulators, accumDescr.isMultiFunction()); MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel"); int index = 0; for (Accumulator accumulator : accumulators) { data.addCompileable(accumulate.new Wirer(index++), (MVELCompileable) accumulator); ((MVELCompileable) accumulator).compile(data); } return accumulate; } catch (Exception e) { copyErrorLocation(e, descr); context.addError( new DescrBuildError( context.getParentDescr(), descr, e, "Unable to build expression for 'accumulate' : " + e.getMessage())); return null; } finally { context.setTypesafe(typesafe); } }