use of org.drools.javaparser.ast.body.MethodDeclaration 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.body.MethodDeclaration in project drools by kiegroup.
the class PatternVisitor method visit.
public DSLNode visit(PatternDescr pattern) {
String className = pattern.getObjectType();
List<? extends BaseDescr> constraintDescrs = pattern.getConstraint().getDescrs();
String queryName = "query_" + pattern.getObjectType();
final MethodDeclaration queryMethod = packageModel.getQueryMethod(queryName);
// Expression is a query, get bindings from query parameter type
if (queryMethod != null) {
return new Query(context, packageModel, pattern, constraintDescrs, queryName);
}
String queryDef = toQueryDef(pattern.getObjectType());
if (packageModel.getQueryDefWithType().containsKey(queryDef)) {
return new QueryCall(context, packageModel, pattern, queryDef);
}
if (pattern.getIdentifier() == null && pattern.getObjectType().equals("Object") && pattern.getSource() instanceof AccumulateDescr) {
if (context.isPatternDSL()) {
return new PatternAccumulateConstraint(context, packageModel, pattern, ((AccumulateDescr) pattern.getSource()), constraintDescrs);
} else {
return new FlowAccumulateConstraint(context, packageModel, pattern, ((AccumulateDescr) pattern.getSource()), constraintDescrs);
}
}
final boolean allConstraintsPositional = areAllConstraintsPositional(constraintDescrs);
final Class<?> patternType = getClassFromContext(context.getTypeResolver(), className);
if (context.isPatternDSL()) {
return new PatternDSLPattern(context, packageModel, pattern, constraintDescrs, patternType, allConstraintsPositional);
} else {
return new FlowDSLPattern(context, packageModel, pattern, constraintDescrs, patternType, allConstraintsPositional);
}
}
use of org.drools.javaparser.ast.body.MethodDeclaration in project drools by kiegroup.
the class PackageModel method getRulesSource.
public RuleSourceResult getRulesSource() {
CompilationUnit cu = new CompilationUnit();
cu.setPackageDeclaration(name);
manageImportForCompilationUnit(cu);
ClassOrInterfaceDeclaration rulesClass = cu.addClass(rulesFileName);
rulesClass.addImplementedType(Model.class);
BodyDeclaration<?> dateFormatter = JavaParser.parseBodyDeclaration("public final static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DateUtils.getDateFormatMask());\n");
rulesClass.addMember(dateFormatter);
BodyDeclaration<?> getNameMethod = JavaParser.parseBodyDeclaration(" @Override\n" + " public String getName() {\n" + " return \"" + name + "\";\n" + " }\n");
rulesClass.addMember(getNameMethod);
BodyDeclaration<?> getRulesMethod = JavaParser.parseBodyDeclaration(" @Override\n" + " public List<Rule> getRules() {\n" + " return rules;\n" + " }\n");
rulesClass.addMember(getRulesMethod);
StringBuilder sb = new StringBuilder("\n");
sb.append("With the following expression ID:\n");
sb.append(exprIdGenerator.toString());
sb.append("\n");
JavadocComment exprIdComment = new JavadocComment(sb.toString());
getRulesMethod.setComment(exprIdComment);
BodyDeclaration<?> getGlobalsMethod = JavaParser.parseBodyDeclaration(" @Override\n" + " public List<Global> getGlobals() {\n" + " return globals;\n" + " }\n");
rulesClass.addMember(getGlobalsMethod);
BodyDeclaration<?> getQueriesMethod = JavaParser.parseBodyDeclaration(" @Override\n" + " public List<Query> getQueries() {\n" + " return queries;\n" + " }\n");
rulesClass.addMember(getQueriesMethod);
BodyDeclaration<?> getTypeMetaDataMethod = JavaParser.parseBodyDeclaration(" @Override\n" + " public List<TypeMetaData> getTypeMetaDatas() {\n" + " return typeMetaDatas;\n" + " }\n");
rulesClass.addMember(getTypeMetaDataMethod);
for (Map.Entry<String, MethodCallExpr> windowReference : windowReferences.entrySet()) {
FieldDeclaration f = rulesClass.addField(WINDOW_REFERENCE_TYPE, windowReference.getKey(), Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
f.getVariables().get(0).setInitializer(windowReference.getValue());
}
for (Map.Entry<String, Class<?>> g : getGlobals().entrySet()) {
addGlobalField(rulesClass, getName(), g.getKey(), g.getValue());
}
for (Map.Entry<String, QueryGenerator.QueryDefWithType> queryDef : queryDefWithType.entrySet()) {
FieldDeclaration field = rulesClass.addField(queryDef.getValue().getQueryType(), queryDef.getKey(), Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
field.getVariables().get(0).setInitializer(queryDef.getValue().getMethodCallExpr());
}
for (Map.Entry<String, MethodDeclaration> methodName : queryMethods.entrySet()) {
FieldDeclaration field = rulesClass.addField(methodName.getValue().getType(), methodName.getKey(), Modifier.FINAL);
field.getVariables().get(0).setInitializer(new MethodCallExpr(null, methodName.getKey()));
}
// instance initializer block.
// add to `rules` list the result of invoking each method for rule
InitializerDeclaration rulesListInitializer = new InitializerDeclaration();
BlockStmt rulesListInitializerBody = new BlockStmt();
rulesListInitializer.setBody(rulesListInitializerBody);
queryMethods.values().forEach(rulesClass::addMember);
buildArtifactsDeclaration(queryMethods.keySet(), rulesClass, rulesListInitializerBody, "Query", "queries", false);
buildArtifactsDeclaration(windowReferences.keySet(), rulesClass, rulesListInitializerBody, "WindowReference", "windowReferences", false);
buildArtifactsDeclaration(getGlobals().keySet(), rulesClass, rulesListInitializerBody, "Global", "globals", true);
if (!typeMetaDataExpressions.isEmpty()) {
BodyDeclaration<?> typeMetaDatasList = JavaParser.parseBodyDeclaration("List<TypeMetaData> typeMetaDatas = new ArrayList<>();");
rulesClass.addMember(typeMetaDatasList);
for (Expression expr : typeMetaDataExpressions) {
addInitStatement(rulesListInitializerBody, expr, "typeMetaDatas");
}
} else {
BodyDeclaration<?> typeMetaDatasList = JavaParser.parseBodyDeclaration("List<TypeMetaData> typeMetaDatas = Collections.emptyList();");
rulesClass.addMember(typeMetaDatasList);
}
functions.forEach(rulesClass::addMember);
RuleSourceResult results = new RuleSourceResult(cu);
int ruleCount = ruleMethods.size();
boolean requiresMultipleRulesLists = ruleCount >= RULES_DECLARATION_PER_CLASS - 1;
MethodCallExpr rules = buildRulesField(rulesClass);
if (requiresMultipleRulesLists) {
addRulesList(rulesListInitializerBody, "rulesList");
}
// each method per Drlx parser result
int count = -1;
Map<Integer, ClassOrInterfaceDeclaration> splitted = new LinkedHashMap<>();
for (Entry<String, MethodDeclaration> ruleMethodKV : ruleMethods.entrySet()) {
ClassOrInterfaceDeclaration rulesMethodClass = splitted.computeIfAbsent(++count / RULES_PER_CLASS, i -> {
CompilationUnit cuRulesMethod = new CompilationUnit();
results.with(cuRulesMethod);
cuRulesMethod.setPackageDeclaration(name);
manageImportForCompilationUnit(cuRulesMethod);
cuRulesMethod.addImport(JavaParser.parseImport("import static " + name + "." + rulesFileName + ".*;"));
String currentRulesMethodClassName = rulesFileName + "RuleMethods" + i;
return cuRulesMethod.addClass(currentRulesMethodClassName);
});
rulesMethodClass.addMember(ruleMethodKV.getValue());
if (count % RULES_DECLARATION_PER_CLASS == RULES_DECLARATION_PER_CLASS - 1) {
int index = count / RULES_DECLARATION_PER_CLASS;
rules = buildRulesField(results, index);
addRulesList(rulesListInitializerBody, rulesFileName + "Rules" + index + ".rulesList");
}
// manage in main class init block:
rules.addArgument(new MethodCallExpr(new NameExpr(rulesMethodClass.getNameAsString()), ruleMethodKV.getKey()));
}
BodyDeclaration<?> rulesList = requiresMultipleRulesLists ? JavaParser.parseBodyDeclaration("List<Rule> rules = new ArrayList<>(" + ruleCount + ");") : JavaParser.parseBodyDeclaration("List<Rule> rules = rulesList;");
rulesClass.addMember(rulesList);
if (!rulesListInitializer.getBody().getStatements().isEmpty()) {
rulesClass.addMember(rulesListInitializer);
}
return results;
}
use of org.drools.javaparser.ast.body.MethodDeclaration in project drools by kiegroup.
the class FunctionGenerator method toFunction.
public static MethodDeclaration toFunction(FunctionDescr desc) {
List<Parameter> parameters = new ArrayList<>();
List<String> parameterTypes = desc.getParameterTypes();
for (int i = 0; i < parameterTypes.size(); i++) {
String type = parameterTypes.get(i);
String name = desc.getParameterNames().get(i);
parameters.add(new Parameter(parseType(type), name));
}
EnumSet<Modifier> modifiers = EnumSet.of(Modifier.PUBLIC, Modifier.STATIC);
MethodDeclaration methodDeclaration = new MethodDeclaration(modifiers, desc.getName(), parseType(desc.getReturnType()), nodeList(parameters));
methodDeclaration.setBody(DrlxParseUtil.parseBlock(desc.getBody()));
return methodDeclaration;
}
use of org.drools.javaparser.ast.body.MethodDeclaration in project drools by kiegroup.
the class POJOGenerator method generateHashCodeMethod.
private static MethodDeclaration generateHashCodeMethod(List<Statement> hashCodeFieldStatement) {
final Statement header = parseStatement("int result = super.hashCode();");
NodeList<Statement> hashCodeStatements = nodeList(header);
hashCodeStatements.addAll(hashCodeFieldStatement);
hashCodeStatements.add(parseStatement("return result;"));
final Type returnType = JavaParser.parseType(int.class.getSimpleName());
final MethodDeclaration equals = new MethodDeclaration(EnumSet.of(Modifier.PUBLIC), returnType, HASH_CODE);
equals.addAnnotation("Override");
equals.setBody(new BlockStmt(hashCodeStatements));
return equals;
}
Aggregations