use of org.drools.core.base.mvel.MVELCompilationUnit in project drools by kiegroup.
the class MVELConstraintBuilder method buildCompilationUnit.
public MVELCompilationUnit buildCompilationUnit(final RuleBuildContext context, final Declaration[] previousDeclarations, final Declaration[] localDeclarations, final PredicateDescr predicateDescr, final AnalysisResult analysis) {
if (context.isTypesafe() && analysis instanceof MVELAnalysisResult) {
Class<?> returnClass = ((MVELAnalysisResult) analysis).getReturnType();
if (returnClass != Boolean.class && returnClass != Boolean.TYPE) {
context.addError(new DescrBuildError(context.getParentDescr(), predicateDescr, null, "Predicate '" + predicateDescr.getContent() + "' must be a Boolean expression\n" + predicateDescr.positionAsString()));
}
}
MVELDialect dialect = (MVELDialect) context.getDialect("mvel");
MVELCompilationUnit unit = null;
try {
Map<String, Class<?>> declIds = context.getDeclarationResolver().getDeclarationClasses(context.getRule());
Pattern p = (Pattern) context.getDeclarationResolver().peekBuildStack();
if (p.getObjectType() instanceof ClassObjectType) {
declIds.put("this", ((ClassObjectType) p.getObjectType()).getClassType());
}
unit = dialect.getMVELCompilationUnit((String) predicateDescr.getContent(), analysis, previousDeclarations, localDeclarations, null, context, "drools", KnowledgeHelper.class, context.isInXpath(), MVELCompilationUnit.Scope.CONSTRAINT);
} catch (final Exception e) {
copyErrorLocation(e, predicateDescr);
context.addError(new DescrBuildError(context.getParentDescr(), predicateDescr, e, "Unable to build expression for 'inline-eval' : " + e.getMessage() + "'" + predicateDescr.getContent() + "'\n" + e.getMessage()));
}
return unit;
}
use of org.drools.core.base.mvel.MVELCompilationUnit in project drools by kiegroup.
the class MVELConstraintBuilder method buildLiteralConstraint.
public Constraint buildLiteralConstraint(RuleBuildContext context, Pattern pattern, ValueType vtype, FieldValue field, String expression, String leftValue, String operator, String rightValue, InternalReadAccessor extractor, LiteralRestrictionDescr restrictionDescr, Map<String, OperatorDescr> aliases) {
if (!isMvelOperator(operator)) {
Evaluator evaluator = buildLiteralEvaluator(context, extractor, restrictionDescr, vtype);
if (evaluator != null && evaluator.isTemporal()) {
try {
field = context.getCompilerFactory().getFieldFactory().getFieldValue(field.getValue(), ValueType.DATE_TYPE);
} catch (Exception e) {
context.addError(new DescrBuildError(context.getParentDescr(), restrictionDescr, null, e.getMessage()));
}
}
return new EvaluatorConstraint(field, evaluator, extractor);
}
String mvelExpr = normalizeMVELLiteralExpression(vtype, field, expression, leftValue, operator, rightValue, restrictionDescr);
IndexUtil.ConstraintType constraintType = IndexUtil.ConstraintType.decode(operator);
MVELCompilationUnit compilationUnit = buildCompilationUnit(context, pattern, mvelExpr, aliases);
EvaluatorWrapper[] operators = getOperators(buildOperators(context, pattern, restrictionDescr, aliases));
return new MvelConstraint(context.getPkg().getName(), mvelExpr, compilationUnit, constraintType, field, extractor, operators);
}
use of org.drools.core.base.mvel.MVELCompilationUnit in project drools by kiegroup.
the class MVELConstraintBuilder method buildVariableConstraint.
public Constraint buildVariableConstraint(RuleBuildContext context, Pattern pattern, String expression, Declaration[] declarations, String leftValue, OperatorDescr operatorDescr, String rightValue, InternalReadAccessor extractor, Declaration requiredDeclaration, RelationalExprDescr relDescr, Map<String, OperatorDescr> aliases) {
if (!isMvelOperator(operatorDescr.getOperator())) {
if (requiredDeclaration == null) {
return null;
}
EvaluatorDefinition.Target right = getRightTarget(extractor);
EvaluatorDefinition.Target left = (requiredDeclaration.isPatternDeclaration() && !(Date.class.isAssignableFrom(requiredDeclaration.getDeclarationClass()) || Number.class.isAssignableFrom(requiredDeclaration.getDeclarationClass()))) ? EvaluatorDefinition.Target.HANDLE : EvaluatorDefinition.Target.FACT;
final Evaluator evaluator = getEvaluator(context, relDescr, extractor.getValueType(), operatorDescr.getOperator(), relDescr.isNegated(), relDescr.getParametersText(), left, right);
return new EvaluatorConstraint(new Declaration[] { requiredDeclaration }, evaluator, extractor);
}
boolean isUnification = requiredDeclaration != null && requiredDeclaration.getPattern().getObjectType().equals(new ClassObjectType(DroolsQuery.class)) && Operator.EQUAL.getOperatorString().equals(operatorDescr.getOperator());
if (isUnification && leftValue.equals(rightValue)) {
expression = resolveUnificationAmbiguity(expression, declarations, leftValue, rightValue);
}
expression = normalizeMVELVariableExpression(expression, leftValue, rightValue, relDescr);
IndexUtil.ConstraintType constraintType = IndexUtil.ConstraintType.decode(operatorDescr.getOperator());
MVELCompilationUnit compilationUnit = isUnification ? null : buildCompilationUnit(context, pattern, expression, aliases);
EvaluatorWrapper[] operators = getOperators(buildOperators(context, pattern, relDescr, aliases));
return new MvelConstraint(Collections.singletonList(context.getPkg().getName()), expression, declarations, operators, compilationUnit, constraintType, requiredDeclaration, extractor, isUnification);
}
use of org.drools.core.base.mvel.MVELCompilationUnit in project drools by kiegroup.
the class PatternBuilder method combineConstraints.
private void combineConstraints(RuleBuildContext context, Pattern pattern, MVELDumper.MVELDumperContext mvelCtx) {
List<MvelConstraint> combinableConstraints = pattern.getCombinableConstraints();
if (combinableConstraints == null || combinableConstraints.size() < 2) {
return;
}
List<Declaration> declarations = new ArrayList<Declaration>();
List<EvaluatorWrapper> operators = new ArrayList<EvaluatorWrapper>();
Set<String> declarationNames = new HashSet<String>();
boolean isFirst = true;
Collection<String> packageNames = null;
StringBuilder expressionBuilder = new StringBuilder(combinableConstraints.size() * 25);
for (MvelConstraint constraint : combinableConstraints) {
pattern.removeConstraint(constraint);
if (isFirst) {
packageNames = constraint.getPackageNames();
isFirst = false;
} else {
expressionBuilder.append(" && ");
}
String constraintExpression = constraint.getExpression();
boolean isComplex = constraintExpression.contains("&&") || constraintExpression.contains("||");
if (isComplex) {
expressionBuilder.append("( ");
}
expressionBuilder.append(constraintExpression);
if (isComplex) {
expressionBuilder.append(" )");
}
for (Declaration declaration : constraint.getRequiredDeclarations()) {
if (declarationNames.add(declaration.getBindingName())) {
declarations.add(declaration);
}
}
Collections.addAll(operators, constraint.getOperators());
}
String expression = expressionBuilder.toString();
MVELCompilationUnit compilationUnit = getConstraintBuilder(context).buildCompilationUnit(context, pattern, expression, mvelCtx.getAliases());
Constraint combinedConstraint = getConstraintBuilder(context).buildMvelConstraint(packageNames, expression, declarations.toArray(new Declaration[declarations.size()]), operators.toArray(new EvaluatorWrapper[operators.size()]), compilationUnit, IndexUtil.ConstraintType.UNKNOWN, null, null, false);
pattern.addConstraint(combinedConstraint);
}
use of org.drools.core.base.mvel.MVELCompilationUnit 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;
}
Aggregations