use of org.drools.javaparser.ast.expr.FieldAccessExpr in project drools by kiegroup.
the class AccumulateVisitor method visitAccInlineCustomCode.
/**
* By design this legacy accumulate (with inline custome code) visitor supports only with 1-and-only binding in the accumulate code/expressions.
*/
protected void visitAccInlineCustomCode(RuleContext context2, AccumulateDescr descr, MethodCallExpr accumulateDSL, PatternDescr basePattern, PatternDescr inputDescr) {
context.pushExprPointer(accumulateDSL::addArgument);
final MethodCallExpr functionDSL = new MethodCallExpr(null, "accFunction");
String code = null;
try {
code = new String(IoUtils.readBytesFromInputStream(this.getClass().getResourceAsStream("/AccumulateInlineFunction.java")));
} catch (IOException e1) {
e1.printStackTrace();
throw new RuntimeException("Unable to locate template.");
}
String targetClassName = StringUtil.toId(context2.getRuleDescr().getName()) + "Accumulate" + descr.getLine();
code = code.replaceAll("AccumulateInlineFunction", targetClassName);
CompilationUnit templateCU = JavaParser.parse(code);
ClassOrInterfaceDeclaration templateClass = templateCU.getClassByName(targetClassName).orElseThrow(() -> new RuntimeException("Template did not contain expected type definition."));
ClassOrInterfaceDeclaration templateContextClass = templateClass.getMembers().stream().filter(m -> m instanceof ClassOrInterfaceDeclaration && ((ClassOrInterfaceDeclaration) m).getNameAsString().equals("ContextData")).map(ClassOrInterfaceDeclaration.class::cast).findFirst().orElseThrow(() -> new RuntimeException("Template did not contain expected type definition."));
List<String> contextFieldNames = new ArrayList<>();
MethodDeclaration initMethod = templateClass.getMethodsByName("init").get(0);
BlockStmt initBlock = JavaParser.parseBlock("{" + descr.getInitCode() + "}");
for (Statement stmt : initBlock.getStatements()) {
if (stmt instanceof ExpressionStmt && ((ExpressionStmt) stmt).getExpression() instanceof VariableDeclarationExpr) {
VariableDeclarationExpr vdExpr = (VariableDeclarationExpr) ((ExpressionStmt) stmt).getExpression();
for (VariableDeclarator vd : vdExpr.getVariables()) {
contextFieldNames.add(vd.getNameAsString());
templateContextClass.addField(vd.getType(), vd.getNameAsString(), Modifier.PUBLIC);
if (vd.getInitializer().isPresent()) {
Expression initializer = vd.getInitializer().get();
Expression target = new FieldAccessExpr(new NameExpr("data"), vd.getNameAsString());
Statement initStmt = new ExpressionStmt(new AssignExpr(target, initializer, AssignExpr.Operator.ASSIGN));
initMethod.getBody().get().addStatement(initStmt);
}
}
} else {
// add as-is.
initMethod.getBody().get().addStatement(stmt);
}
}
Type singleAccumulateType = JavaParser.parseType("java.lang.Object");
MethodDeclaration accumulateMethod = templateClass.getMethodsByName("accumulate").get(0);
BlockStmt actionBlock = JavaParser.parseBlock("{" + descr.getActionCode() + "}");
Collection<String> allNamesInActionBlock = collectNamesInBlock(context2, actionBlock);
if (allNamesInActionBlock.size() == 1) {
String nameExpr = allNamesInActionBlock.iterator().next();
accumulateMethod.getParameter(1).setName(nameExpr);
singleAccumulateType = context2.getDeclarationById(nameExpr).get().getType();
} else {
new LegacyAccumulate(context, descr, basePattern).build();
return;
}
writeAccumulateMethod(contextFieldNames, singleAccumulateType, accumulateMethod, actionBlock);
// <result expression>: this is a semantic expression in the selected dialect that is executed after all source objects are iterated.
MethodDeclaration resultMethod = templateClass.getMethodsByName("getResult").get(0);
Type returnExpressionType = JavaParser.parseType("java.lang.Object");
Expression returnExpression = JavaParser.parseExpression(descr.getResultCode());
if (returnExpression instanceof NameExpr) {
returnExpression = new EnclosedExpr(returnExpression);
}
rescopeNamesToNewScope(new NameExpr("data"), contextFieldNames, returnExpression);
resultMethod.getBody().get().addStatement(new ReturnStmt(returnExpression));
MethodDeclaration getResultTypeMethod = templateClass.getMethodsByName("getResultType").get(0);
getResultTypeMethod.getBody().get().addStatement(new ReturnStmt(new ClassExpr(returnExpressionType)));
if (descr.getReverseCode() != null) {
MethodDeclaration supportsReverseMethod = templateClass.getMethodsByName("supportsReverse").get(0);
supportsReverseMethod.getBody().get().addStatement(JavaParser.parseStatement("return true;"));
MethodDeclaration reverseMethod = templateClass.getMethodsByName("reverse").get(0);
BlockStmt reverseBlock = JavaParser.parseBlock("{" + descr.getReverseCode() + "}");
Collection<String> allNamesInReverseBlock = collectNamesInBlock(context2, reverseBlock);
if (allNamesInReverseBlock.size() == 1) {
reverseMethod.getParameter(1).setName(allNamesInReverseBlock.iterator().next());
} else {
new LegacyAccumulate(context, descr, basePattern).build();
return;
}
writeAccumulateMethod(contextFieldNames, singleAccumulateType, reverseMethod, reverseBlock);
} else {
MethodDeclaration supportsReverseMethod = templateClass.getMethodsByName("supportsReverse").get(0);
supportsReverseMethod.getBody().get().addStatement(JavaParser.parseStatement("return false;"));
MethodDeclaration reverseMethod = templateClass.getMethodsByName("reverse").get(0);
reverseMethod.getBody().get().addStatement(JavaParser.parseStatement("throw new UnsupportedOperationException(\"This function does not support reverse.\");"));
}
// add resulting accumulator class into the package model
this.packageModel.addGeneratedPOJO(templateClass);
functionDSL.addArgument(new ClassExpr(JavaParser.parseType(targetClassName)));
functionDSL.addArgument(new NameExpr(toVar(inputDescr.getIdentifier())));
final String bindingId = basePattern.getIdentifier();
final MethodCallExpr asDSL = new MethodCallExpr(functionDSL, "as");
asDSL.addArgument(new NameExpr(toVar(bindingId)));
accumulateDSL.addArgument(asDSL);
context.popExprPointer();
}
use of org.drools.javaparser.ast.expr.FieldAccessExpr in project drools by kiegroup.
the class DrlxParseUtil method toMethodCallWithClassCheck.
public static TypedExpression toMethodCallWithClassCheck(RuleContext context, Expression expr, String bindingId, Class<?> clazz, TypeResolver typeResolver) {
final Deque<ParsedMethod> callStackLeftToRight = new LinkedList<>();
createExpressionCall(expr, callStackLeftToRight);
Class<?> previousClass = clazz;
Expression previousScope = null;
for (ParsedMethod e : callStackLeftToRight) {
if (e.expression instanceof NameExpr || e.expression instanceof FieldAccessExpr) {
if (e.fieldToResolve.equals(bindingId)) {
continue;
}
if (previousClass == null) {
try {
previousClass = typeResolver.resolveType(e.fieldToResolve);
previousScope = new NameExpr(e.fieldToResolve);
} catch (ClassNotFoundException e1) {
// ignore
}
if (previousClass == null) {
previousClass = context.getDeclarationById(e.fieldToResolve).map(DeclarationSpec::getDeclarationClass).orElseThrow(() -> new RuntimeException("Unknown field: " + e.fieldToResolve));
previousScope = e.expression;
}
} else {
TypedExpression te = nameExprToMethodCallExpr(e.fieldToResolve, previousClass, previousScope);
Class<?> returnType = te.getType();
previousScope = te.getExpression();
previousClass = returnType;
}
} else if (e.expression instanceof MethodCallExpr) {
Class<?> returnType = returnTypeOfMethodCallExpr(context, typeResolver, (MethodCallExpr) e.expression, previousClass, null);
MethodCallExpr cloned = ((MethodCallExpr) e.expression.clone()).setScope(previousScope);
previousScope = cloned;
previousClass = returnType;
}
}
return new TypedExpression(previousScope, previousClass);
}
use of org.drools.javaparser.ast.expr.FieldAccessExpr in project drools by kiegroup.
the class DrlxParseUtil method createExpressionCall.
private static Expression createExpressionCall(Expression expr, Deque<ParsedMethod> expressions) {
if (expr instanceof NodeWithSimpleName) {
NodeWithSimpleName fae = (NodeWithSimpleName) expr;
expressions.push(new ParsedMethod(expr, fae.getName().asString()));
}
if (expr instanceof NodeWithOptionalScope) {
final NodeWithOptionalScope<?> exprWithScope = (NodeWithOptionalScope) expr;
exprWithScope.getScope().map((Expression scope) -> createExpressionCall(scope, expressions));
} else if (expr instanceof FieldAccessExpr) {
// Cannot recurse over getScope() as FieldAccessExpr doesn't support the NodeWithOptionalScope,
// it will support a new interface to traverse among scopes called NodeWithTraversableScope so
// we can merge this and the previous branch
createExpressionCall(((FieldAccessExpr) expr).getScope(), expressions);
}
return expr;
}
use of org.drools.javaparser.ast.expr.FieldAccessExpr in project drools by kiegroup.
the class FlowExpressionBuilder method buildIndexedBy.
private MethodCallExpr buildIndexedBy(DrlxParseSuccess drlxParseResult, MethodCallExpr exprDSL) {
if (!hasIndex(drlxParseResult)) {
return exprDSL;
}
TypedExpression left = drlxParseResult.getLeft();
TypedExpression right = drlxParseResult.getRight();
Class<?> indexType = Stream.of(left, right).map(TypedExpression::getType).filter(Objects::nonNull).findFirst().get();
ClassExpr indexedBy_indexedClass = new ClassExpr(JavaParser.parseType(indexType.getCanonicalName()));
// not 100% accurate as the type in "nameExpr" is actually parsed if it was JavaParsers as a big chain of FieldAccessExpr
FieldAccessExpr indexedBy_constraintType = new FieldAccessExpr(new NameExpr("org.drools.model.Index.ConstraintType"), drlxParseResult.getDecodeConstraintType().toString());
LambdaExpr indexedBy_leftOperandExtractor = new LambdaExpr();
indexedBy_leftOperandExtractor.addParameter(new Parameter(new UnknownType(), "_this"));
boolean leftContainsThis = left.getExpression().toString().contains("_this");
indexedBy_leftOperandExtractor.setBody(new ExpressionStmt(leftContainsThis ? left.getExpression() : right.getExpression()));
MethodCallExpr indexedByDSL = new MethodCallExpr(exprDSL, INDEXED_BY_CALL);
indexedByDSL.addArgument(indexedBy_indexedClass);
indexedByDSL.addArgument(indexedBy_constraintType);
indexedByDSL.addArgument("" + indexIdGenerator.getFieldId(drlxParseResult.getPatternType(), left.getFieldName()));
indexedByDSL.addArgument(indexedBy_leftOperandExtractor);
Collection<String> usedDeclarations = drlxParseResult.getUsedDeclarations();
if (isAlphaIndex(usedDeclarations)) {
indexedByDSL.addArgument(right.getExpression());
} else {
LambdaExpr indexedBy_rightOperandExtractor = new LambdaExpr();
indexedBy_rightOperandExtractor.addParameter(new Parameter(new UnknownType(), usedDeclarations.iterator().next()));
indexedBy_rightOperandExtractor.setBody(new ExpressionStmt(!leftContainsThis ? left.getExpression() : right.getExpression()));
indexedByDSL.addArgument(indexedBy_rightOperandExtractor);
}
return indexedByDSL;
}
use of org.drools.javaparser.ast.expr.FieldAccessExpr in project drools by kiegroup.
the class PatternExpressionBuilder method buildIndexedBy.
private Optional<MethodCallExpr> buildIndexedBy(DrlxParseSuccess drlxParseResult) {
if (!hasIndex(drlxParseResult)) {
return Optional.empty();
}
IndexUtil.ConstraintType decodeConstraintType = drlxParseResult.getDecodeConstraintType();
TypedExpression left = drlxParseResult.getLeft();
TypedExpression right = drlxParseResult.getRight();
Class<?> indexType = Stream.of(left, right).map(TypedExpression::getType).filter(Objects::nonNull).findFirst().get();
ClassExpr indexedBy_indexedClass = new ClassExpr(JavaParser.parseType(indexType.getCanonicalName()));
// not 100% accurate as the type in "nameExpr" is actually parsed if it was JavaParsers as a big chain of FieldAccessExpr
FieldAccessExpr indexedBy_constraintType = new FieldAccessExpr(new NameExpr("org.drools.model.Index.ConstraintType"), decodeConstraintType.toString());
LambdaExpr indexedBy_leftOperandExtractor = new LambdaExpr();
indexedBy_leftOperandExtractor.addParameter(new Parameter(new UnknownType(), "_this"));
boolean leftContainsThis = left.getExpression().toString().contains("_this");
indexedBy_leftOperandExtractor.setBody(new ExpressionStmt(leftContainsThis ? left.getExpression() : right.getExpression()));
MethodCallExpr indexedByDSL = new MethodCallExpr(null, drlxParseResult.isBetaNode() ? BETA_INDEXED_BY_CALL : ALPHA_INDEXED_BY_CALL);
indexedByDSL.addArgument(indexedBy_indexedClass);
indexedByDSL.addArgument(indexedBy_constraintType);
indexedByDSL.addArgument("" + indexIdGenerator.getFieldId(drlxParseResult.getPatternType(), left.getFieldName()));
indexedByDSL.addArgument(indexedBy_leftOperandExtractor);
Collection<String> usedDeclarations = drlxParseResult.getUsedDeclarations();
if (isAlphaIndex(usedDeclarations)) {
indexedByDSL.addArgument(right.getExpression());
} else if (usedDeclarations.size() == 1) {
LambdaExpr indexedBy_rightOperandExtractor = new LambdaExpr();
indexedBy_rightOperandExtractor.addParameter(new Parameter(new UnknownType(), usedDeclarations.iterator().next()));
indexedBy_rightOperandExtractor.setBody(new ExpressionStmt(!leftContainsThis ? left.getExpression() : right.getExpression()));
indexedByDSL.addArgument(indexedBy_rightOperandExtractor);
}
return Optional.of(indexedByDSL);
}
Aggregations