use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class PatternBuilder method buildRuleBindings.
protected void buildRuleBindings(RuleBuildContext context, PatternDescr patternDescr, Pattern pattern, BindingDescr fieldBindingDescr, TypeDeclaration typeDeclaration) {
if (context.getDeclarationResolver().isDuplicated(context.getRule(), fieldBindingDescr.getVariable(), null)) {
processDuplicateBindings(fieldBindingDescr.isUnification(), patternDescr, pattern, fieldBindingDescr, fieldBindingDescr.getBindingField(), fieldBindingDescr.getVariable(), context);
if (fieldBindingDescr.isUnification()) {
return;
}
}
Declaration declr = pattern.addDeclaration(fieldBindingDescr.getVariable());
final InternalReadAccessor extractor = getFieldReadAccessor(context, fieldBindingDescr, pattern, fieldBindingDescr.getBindingField(), declr, true);
if (extractor == null) {
registerDescrBuildError(context, patternDescr, "Field Reader does not exist for declaration '" + fieldBindingDescr.getVariable() + "' in '" + fieldBindingDescr + "' in the rule '" + context.getRule().getName() + "'");
return;
}
declr.setReadAccessor(extractor);
if (typeDeclaration != null && extractor instanceof ClassFieldReader) {
addFieldToPatternWatchlist(pattern, typeDeclaration, ((ClassFieldReader) extractor).getFieldName());
}
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class MVELAccumulateBuilder method buildExternalFunctions.
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);
int index = 0;
Pattern pattern = (Pattern) context.getDeclarationResolver().peekBuildStack();
for (AccumulateFunctionCallDescr func : functions) {
// build an external function executor
AccumulateFunction function = context.getConfiguration().getAccumulateFunction(func.getFunction());
if (function == null) {
// might have been imported in the package
function = context.getPkg().getAccumulateFunctions().get(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;
}
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, MVELCompilationUnit.Scope.CONSTRAINT);
accumulators[index] = new MVELAccumulatorFunctionExecutor(unit, function);
// if there is a binding, create the binding
if (func.getBind() != null) {
if (context.getDeclarationResolver().isDuplicated(context.getRule(), func.getBind(), function.getResultType().getName())) {
if (!func.isUnification()) {
context.addError(new DescrBuildError(context.getParentDescr(), accumDescr, null, "Duplicate declaration for variable '" + func.getBind() + "' in the rule '" + context.getRule().getName() + "'"));
} else {
Declaration inner = context.getDeclarationResolver().getDeclaration(func.getBind());
Constraint c = new MvelConstraint(Collections.singletonList(context.getPkg().getName()), accumDescr.isMultiFunction() ? "this[ " + index + " ] == " + func.getBind() : "this == " + func.getBind(), new Declaration[] { inner }, null, null, IndexUtil.ConstraintType.EQUAL, context.getDeclarationResolver().getDeclaration(func.getBind()), accumDescr.isMultiFunction() ? new ArrayElementReader(arrayReader, index, function.getResultType()) : new SelfReferenceClassFieldReader(function.getResultType()), true);
((MutableTypeConstraint) c).setType(Constraint.ConstraintType.BETA);
pattern.addConstraint(c);
index++;
}
} else {
Declaration declr = pattern.addDeclaration(func.getBind());
if (accumDescr.isMultiFunction()) {
declr.setReadAccessor(new ArrayElementReader(arrayReader, index, function.getResultType()));
} else {
declr.setReadAccessor(new SelfReferenceClassFieldReader(function.getResultType()));
}
}
}
index++;
}
return accumulators;
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class MVELAccumulateBuilder method getUsedDeclarations.
private Declaration[] getUsedDeclarations(Map<String, Declaration> decls, AnalysisResult analysis) {
final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers();
List<Declaration> usedDeclarations = new ArrayList<Declaration>();
for (String id : usedIdentifiers.getDeclrClasses().keySet()) {
if (decls.containsKey(id)) {
usedDeclarations.add(decls.get(id));
}
}
if (!usedDeclarations.isEmpty()) {
Collections.sort(usedDeclarations, SortDeclarations.instance);
}
return usedDeclarations.toArray(new Declaration[usedDeclarations.size()]);
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class MVELConsequenceBuilder method build.
public void build(final RuleBuildContext context, String consequenceName) {
// pushing consequence LHS into the stack for variable resolution
context.getDeclarationResolver().pushOnBuildStack(context.getRule().getLhs());
try {
MVELDialect dialect = (MVELDialect) context.getDialect("mvel");
final RuleDescr ruleDescr = context.getRuleDescr();
String text = (RuleImpl.DEFAULT_CONSEQUENCE_NAME.equals(consequenceName)) ? (String) ruleDescr.getConsequence() : (String) ruleDescr.getNamedConsequences().get(consequenceName);
text = processMacros(text);
Map<String, Declaration> decls = context.getDeclarationResolver().getDeclarations(context.getRule());
AnalysisResult analysis = dialect.analyzeBlock(context, text, new BoundIdentifiers(DeclarationScopeResolver.getDeclarationClasses(decls), context, Collections.EMPTY_MAP, KnowledgeHelper.class), null, "drools", KnowledgeHelper.class);
if (analysis == null) {
// something bad happened, issue already logged in errors
return;
}
final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers();
final Declaration[] declarations = new Declaration[usedIdentifiers.getDeclrClasses().size()];
String[] declrStr = new String[declarations.length];
int j = 0;
for (String str : usedIdentifiers.getDeclrClasses().keySet()) {
declrStr[j] = str;
declarations[j++] = decls.get(str);
}
Arrays.sort(declarations, SortDeclarations.instance);
for (int i = 0; i < declrStr.length; i++) {
declrStr[i] = declarations[i].getIdentifier();
}
context.getRule().setRequiredDeclarationsForConsequence(consequenceName, declrStr);
MVELCompilationUnit unit = dialect.getMVELCompilationUnit(text, analysis, declarations, null, null, context, "drools", KnowledgeHelper.class, false, MVELCompilationUnit.Scope.CONSEQUENCE);
MVELConsequence expr = new MVELConsequence(unit, dialect.getId(), consequenceName);
if (RuleImpl.DEFAULT_CONSEQUENCE_NAME.equals(consequenceName)) {
context.getRule().setConsequence(expr);
} else {
context.getRule().addNamedConsequence(consequenceName, expr);
}
MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel");
data.addCompileable(context.getRule(), expr);
expr.compile(data, context.getRule());
} catch (final Exception e) {
copyErrorLocation(e, context.getRuleDescr());
context.addError(new DescrBuildError(context.getParentDescr(), context.getRuleDescr(), null, "Unable to build expression for 'consequence': " + e.getMessage() + " '" + context.getRuleDescr().getConsequence() + "'"));
}
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class JavaAccumulateBuilder method build.
public RuleConditionElement build(final RuleBuildContext context, final BaseDescr descr, final Pattern prefixPattern) {
final AccumulateDescr accumDescr = (AccumulateDescr) descr;
if (!accumDescr.hasValidInput()) {
return null;
}
// build source
BaseDescr input = accumDescr.getInput();
if (input instanceof AndDescr && ((AndDescr) input).getDescrs().size() == 1) {
input = ((AndDescr) input).getDescrs().get(0);
}
final RuleConditionBuilder builder = (RuleConditionBuilder) context.getDialect().getBuilder(input.getClass());
final RuleConditionElement source = builder.build(context, input);
if (source == null) {
return null;
}
final boolean readLocalsFromTuple = PackageBuilderUtil.isReadLocalsFromTuple(context, accumDescr, source);
Map<String, Declaration> declsInScope = context.getDeclarationResolver().getDeclarations(context.getRule());
Map<String, Class<?>> declCls = DeclarationScopeResolver.getDeclarationClasses(declsInScope);
Accumulate accumulate;
if (accumDescr.isExternalFunction()) {
// if it uses 1+ external function, build methods for them
accumulate = buildExternalFunctionCall(context, accumDescr, source, declsInScope, declCls, readLocalsFromTuple);
} else {
// if it uses inline code, build the class for it
accumulate = buildInlineAccumulate(context, accumDescr, source, declsInScope, declCls, readLocalsFromTuple);
}
return accumulate;
}
Aggregations