use of org.drools.javaparser.ast.body.ClassOrInterfaceDeclaration in project drools by kiegroup.
the class POJOGenerator method toClassDeclaration.
/**
* @param packageDescr
*/
public static ClassOrInterfaceDeclaration toClassDeclaration(TypeDeclarationDescr typeDeclaration, PackageDescr packageDescr) {
EnumSet<Modifier> classModifiers = EnumSet.of(Modifier.PUBLIC);
String generatedClassName = typeDeclaration.getTypeName();
ClassOrInterfaceDeclaration generatedClass = new ClassOrInterfaceDeclaration(classModifiers, false, generatedClassName);
generatedClass.addImplementedType(GeneratedFact.class.getName());
// Ref: {@link org.drools.core.factmodel.DefaultBeanClassBuilder} by default always receive is Serializable.
generatedClass.addImplementedType(Serializable.class.getName());
boolean hasSuper = typeDeclaration.getSuperTypeName() != null;
if (hasSuper) {
generatedClass.addExtendedType(typeDeclaration.getSuperTypeName());
}
List<AnnotationDescr> softAnnotations = new ArrayList<>();
for (AnnotationDescr ann : typeDeclaration.getAnnotations()) {
final String annFqn = Optional.ofNullable(ann.getFullyQualifiedName()).orElse(Optional.ofNullable(predefinedClassLevelAnnotation.get(ann.getName())).map(Class::getCanonicalName).orElse(null));
if (annFqn != null) {
NormalAnnotationExpr annExpr = generatedClass.addAndGetAnnotation(annFqn);
ann.getValueMap().forEach((k, v) -> annExpr.addPair(k, getAnnotationValue(annFqn, k, v.toString())));
} else {
softAnnotations.add(ann);
}
}
if (softAnnotations.size() > 0) {
String softAnnDictionary = softAnnotations.stream().map(a -> "<dt>" + a.getName() + "</dt><dd>" + a.getValuesAsString() + "</dd>").collect(Collectors.joining());
JavadocComment generatedClassJavadoc = new JavadocComment("<dl>" + softAnnDictionary + "</dl>");
generatedClass.setJavadocComment(generatedClassJavadoc);
}
// No-args ctor
generatedClass.addConstructor(Modifier.PUBLIC);
List<Statement> equalsFieldStatement = new ArrayList<>();
List<Statement> hashCodeFieldStatement = new ArrayList<>();
List<String> toStringFieldStatement = new ArrayList<>();
List<TypeFieldDescr> keyFields = new ArrayList<>();
Collection<TypeFieldDescr> inheritedFields = findInheritedDeclaredFields(typeDeclaration, packageDescr);
Collection<TypeFieldDescr> typeFields = typeDeclaration.getFields().values();
if (!inheritedFields.isEmpty() || !typeDeclaration.getFields().isEmpty()) {
ConstructorDeclaration fullArgumentsCtor = generatedClass.addConstructor(Modifier.PUBLIC);
NodeList<Statement> ctorFieldStatement = NodeList.nodeList();
MethodCallExpr superCall = new MethodCallExpr(null, "super");
for (TypeFieldDescr typeFieldDescr : inheritedFields) {
String fieldName = typeFieldDescr.getFieldName();
addCtorArg(fullArgumentsCtor, typeFieldDescr.getPattern().getObjectType(), fieldName);
superCall.addArgument(fieldName);
if (typeFieldDescr.getAnnotation("key") != null) {
keyFields.add(typeFieldDescr);
}
}
ctorFieldStatement.add(new ExpressionStmt(superCall));
int position = inheritedFields.size();
for (TypeFieldDescr typeFieldDescr : typeFields) {
String fieldName = typeFieldDescr.getFieldName();
Type returnType = addCtorArg(fullArgumentsCtor, typeFieldDescr.getPattern().getObjectType(), fieldName);
FieldDeclaration field = generatedClass.addField(returnType, fieldName, Modifier.PRIVATE);
field.createSetter();
field.addAndGetAnnotation(Position.class.getName()).addPair("value", "" + position++);
MethodDeclaration getter = field.createGetter();
equalsFieldStatement.add(generateEqualsForField(getter, fieldName));
hashCodeFieldStatement.addAll(generateHashCodeForField(getter, fieldName));
ctorFieldStatement.add(replaceFieldName(parseStatement("this.__fieldName = __fieldName;"), fieldName));
toStringFieldStatement.add(format("+ {0}+{1}", quote(fieldName + "="), fieldName));
if (typeFieldDescr.getAnnotation("key") != null) {
keyFields.add(typeFieldDescr);
}
}
fullArgumentsCtor.setBody(new BlockStmt(ctorFieldStatement));
if (!keyFields.isEmpty() && keyFields.size() != inheritedFields.size() + typeFields.size()) {
ConstructorDeclaration keyArgumentsCtor = generatedClass.addConstructor(Modifier.PUBLIC);
NodeList<Statement> ctorKeyFieldStatement = NodeList.nodeList();
MethodCallExpr keySuperCall = new MethodCallExpr(null, "super");
ctorKeyFieldStatement.add(new ExpressionStmt(keySuperCall));
for (TypeFieldDescr typeFieldDescr : keyFields) {
String fieldName = typeFieldDescr.getFieldName();
addCtorArg(keyArgumentsCtor, typeFieldDescr.getPattern().getObjectType(), fieldName);
if (typeDeclaration.getFields().get(fieldName) != null) {
ctorKeyFieldStatement.add(replaceFieldName(parseStatement("this.__fieldName = __fieldName;"), fieldName));
} else {
keySuperCall.addArgument(fieldName);
}
}
keyArgumentsCtor.setBody(new BlockStmt(ctorKeyFieldStatement));
}
if (hasSuper) {
generatedClass.addMember(generateEqualsMethod(generatedClassName, equalsFieldStatement));
generatedClass.addMember(generateHashCodeMethod(hashCodeFieldStatement));
}
}
generatedClass.addMember(generateToStringMethod(generatedClassName, toStringFieldStatement));
return generatedClass;
}
use of org.drools.javaparser.ast.body.ClassOrInterfaceDeclaration 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.ClassOrInterfaceDeclaration in project drools by kiegroup.
the class DrlxCompiler method compileSingleSource.
public static CompiledUnit compileSingleSource(Reader source) {
CompilationUnit compilationUnit = JavaParser.parse(source);
ClassOrInterfaceDeclaration unitClass = (ClassOrInterfaceDeclaration) compilationUnit.getType(0);
String pkg = compilationUnit.getPackageDeclaration().map(PackageDeclaration::getNameAsString).orElse("defaultpkg");
String unit = unitClass.getNameAsString();
KieServices ks = KieServices.get();
ReleaseId releaseId = ks.newReleaseId(pkg, unit, "1.0");
KieFileSystem kfs = createKieFileSystem(ks, releaseId);
String unitPath = pkg.replace(".", "/") + "/" + unit;
String javaPath = "src/main/java/" + unitPath + ".java";
String drlPath = "src/main/resources/" + unitPath + ".drl";
kfs.write(drlPath, toDrl(compilationUnit)).write(javaPath, toJava(compilationUnit));
KieContainer kieContainer = createKieContainer(ks, kfs, releaseId);
return new CompiledUnit(kieContainer, pkg + "." + unit);
}
use of org.drools.javaparser.ast.body.ClassOrInterfaceDeclaration in project drools by kiegroup.
the class JavaParserCompiler method writeModel.
private static String[] writeModel(List<GeneratedClassWithPackage> classes, MemoryFileSystem srcMfs) {
List<String> sources = new ArrayList<>();
for (GeneratedClassWithPackage generatedPojo : classes) {
final String pkgName = generatedPojo.getPackageName();
final String folderName = pkgName.replace('.', '/');
final ClassOrInterfaceDeclaration generatedClass = generatedPojo.getGeneratedClass();
final String varsSourceName = String.format("src/main/java/%s/%s.java", folderName, generatedClass.getName());
srcMfs.write(varsSourceName, toPojoSource(pkgName, generatedPojo.getImports(), generatedClass).getBytes());
sources.add(varsSourceName);
}
return sources.toArray(new String[sources.size()]);
}
use of org.drools.javaparser.ast.body.ClassOrInterfaceDeclaration in project drools by kiegroup.
the class ModelWriter method writeModel.
public Result writeModel(MemoryFileSystem srcMfs, Collection<PackageModel> packageModels) {
List<String> sourceFiles = new ArrayList<>();
List<String> modelFiles = new ArrayList<>();
PrettyPrinter prettyPrinter = getPrettyPrinter();
for (PackageModel pkgModel : packageModels) {
String pkgName = pkgModel.getName();
String folderName = pkgName.replace('.', '/');
for (ClassOrInterfaceDeclaration generatedPojo : pkgModel.getGeneratedPOJOsSource()) {
final String source = JavaParserCompiler.toPojoSource(pkgModel.getName(), pkgModel.getImports(), generatedPojo);
pkgModel.logRule(source);
String pojoSourceName = "src/main/java/" + folderName + "/" + generatedPojo.getName() + ".java";
srcMfs.write(pojoSourceName, source.getBytes());
sourceFiles.add(pojoSourceName);
}
for (GeneratedClassWithPackage generatedPojo : pkgModel.getGeneratedAccumulateClasses()) {
final String source = JavaParserCompiler.toPojoSource(pkgModel.getName(), generatedPojo.getImports(), generatedPojo.getGeneratedClass());
pkgModel.logRule(source);
String pojoSourceName = "src/main/java/" + folderName + "/" + generatedPojo.getGeneratedClass().getName() + ".java";
srcMfs.write(pojoSourceName, source.getBytes());
sourceFiles.add(pojoSourceName);
}
RuleSourceResult rulesSourceResult = pkgModel.getRulesSource();
// main rules file:
String rulesFileName = pkgModel.getRulesFileName();
String rulesSourceName = "src/main/java/" + folderName + "/" + rulesFileName + ".java";
String rulesSource = prettyPrinter.print(rulesSourceResult.getMainRuleClass());
pkgModel.logRule(rulesSource);
byte[] rulesBytes = rulesSource.getBytes();
srcMfs.write(rulesSourceName, rulesBytes);
modelFiles.add(pkgName + "." + rulesFileName);
sourceFiles.add(rulesSourceName);
// manage additional classes, please notice to not add to modelFiles.
for (CompilationUnit cu : rulesSourceResult.getSplitted()) {
String addFileName = cu.findFirst(ClassOrInterfaceDeclaration.class).get().getNameAsString();
String addSourceName = "src/main/java/" + folderName + "/" + addFileName + ".java";
String addSource = prettyPrinter.print(cu);
pkgModel.logRule(addSource);
byte[] addBytes = addSource.getBytes();
srcMfs.write(addSourceName, addBytes);
sourceFiles.add(addSourceName);
}
}
return new Result(sourceFiles, modelFiles);
}
Aggregations