use of org.drools.compiler.compiler.DescrBuildError in project drools by kiegroup.
the class DialectUtil method rewriteModifyDescr.
private static void rewriteModifyDescr(RuleBuildContext context, JavaBlockDescr d, String originalBlock, StringBuilder consequence, Declaration declr, String obj) {
List<String> settableProperties = null;
Class<?> typeClass = findModifiedClass(context, d, declr);
TypeDeclaration typeDeclaration = typeClass == null ? null : context.getKnowledgeBuilder().getTypeDeclaration(typeClass);
boolean isPropertyReactive = typeDeclaration != null && typeDeclaration.isPropertyReactive();
if (isPropertyReactive) {
typeDeclaration.setTypeClass(typeClass);
settableProperties = typeDeclaration.getAccessibleProperties();
}
ConsequenceMetaData.Statement statement = null;
if (typeDeclaration != null) {
statement = new ConsequenceMetaData.Statement(ConsequenceMetaData.Statement.Type.MODIFY, typeClass);
context.getRule().getConsequenceMetaData().addStatement(statement);
}
BitMask modificationMask = isPropertyReactive ? getEmptyPropertyReactiveMask(settableProperties.size()) : allSetButTraitBitMask();
int end = originalBlock.indexOf("{");
if (end == -1) {
// no block
context.addError(new DescrBuildError(context.getParentDescr(), context.getRuleDescr(), null, "Block missing after modify" + d.getTargetExpression() + " ?\n"));
return;
}
addLineBreaks(consequence, originalBlock.substring(0, end));
int start = end + 1;
// adding each of the expressions:
for (String exprStr : ((JavaModifyBlockDescr) d).getExpressions()) {
end = originalBlock.indexOf(exprStr, start);
addLineBreaks(consequence, originalBlock.substring(start, end));
consequence.append(obj).append(".");
consequence.append(exprStr);
consequence.append("; ");
start = end + exprStr.length();
if (typeDeclaration != null) {
modificationMask = parseModifiedProperties(statement, settableProperties, typeDeclaration, isPropertyReactive, modificationMask, exprStr);
}
}
addLineBreaks(consequence, originalBlock.substring(end));
appendUpdateStatement(consequence, declr, obj, modificationMask, typeClass);
}
use of org.drools.compiler.compiler.DescrBuildError 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.compiler.compiler.DescrBuildError 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.compiler.compiler.DescrBuildError in project drools by kiegroup.
the class JavaAccumulateBuilder method getAccumulateFunction.
private AccumulateFunction getAccumulateFunction(RuleBuildContext context, AccumulateDescr accumDescr, AccumulateFunctionCallDescr fc, RuleConditionElement source, Map<String, Class<?>> declCls) {
String functionName = AccumulateUtil.getFunctionName(() -> MVELExprAnalyzer.getExpressionType(context, declCls, source, fc.getParams()[0]), fc.getFunction());
// find the corresponding function
AccumulateFunction function = context.getConfiguration().getAccumulateFunction(functionName);
if (function == null) {
// might have been imported in the package
function = context.getPkg().getAccumulateFunctions().get(functionName);
}
if (function == null) {
context.addError(new DescrBuildError(accumDescr, context.getRuleDescr(), null, "Unknown accumulate function: '" + functionName + "' on rule '" + context.getRuleDescr().getName() + "'. All accumulate functions must be registered before building a resource."));
}
return function;
}
use of org.drools.compiler.compiler.DescrBuildError in project drools by kiegroup.
the class MVELDialect method analyzeExpression.
public AnalysisResult analyzeExpression(final PackageBuildContext context, final BaseDescr descr, final Object content, final BoundIdentifiers availableIdentifiers, final Map<String, Class<?>> localTypes) {
AnalysisResult result = null;
// the following is required for proper error handling
BaseDescr temp = context.getParentDescr();
context.setParentDescr(descr);
try {
result = MVELExprAnalyzer.analyzeExpression(context, (String) content, availableIdentifiers, localTypes, "drools", KnowledgeHelper.class);
} catch (final Exception e) {
DialectUtil.copyErrorLocation(e, descr);
context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Unable to determine the used declarations.\n" + e.getMessage()));
} finally {
// setting it back to original parent descr
context.setParentDescr(temp);
}
return result;
}
Aggregations