1 package com.github.javaparser.generator.core.node; 2 3 import com.github.javaparser.ast.CompilationUnit; 4 import com.github.javaparser.ast.Node; 5 import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; 6 import com.github.javaparser.ast.body.MethodDeclaration; 7 import com.github.javaparser.ast.stmt.BlockStmt; 8 import com.github.javaparser.generator.NodeGenerator; 9 import com.github.javaparser.utils.SourceRoot; 10 import com.github.javaparser.metamodel.BaseNodeMetaModel; 11 import com.github.javaparser.metamodel.PropertyMetaModel; 12 13 import static com.github.javaparser.JavaParser.*; 14 import static com.github.javaparser.utils.CodeGenerationUtils.f; 15 import static com.github.javaparser.utils.Utils.capitalize; 16 17 18 public class RemoveMethodGenerator extends NodeGenerator { 19 public RemoveMethodGenerator(SourceRoot sourceRoot) { 20 super(sourceRoot); 21 } 22 23 @Override 24 protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) { 25 MethodDeclaration removeNodeMethod = (MethodDeclaration) parseBodyDeclaration("public boolean remove(Node node) {}"); 26 nodeCu.addImport(Node.class); 27 nodeMetaModel.getSuperNodeMetaModel().ifPresent(s -> annotateOverridden(removeNodeMethod)); 28 29 final BlockStmt body = removeNodeMethod.getBody().get(); 30 31 body.addStatement("if (node == null) return false;"); 32 33 for (PropertyMetaModel property : nodeMetaModel.getDeclaredPropertyMetaModels()) { 34 if (!property.isNode()) { 35 continue; 36 } 37 String check; 38 if (property.isNodeList()) { 39 check = nodeListCheck(property); 40 } else { 41 if (property.isRequired()) { 42 continue; 43 } 44 String removeAttributeMethodName = generateRemoveMethodForAttribute(nodeCoid, nodeMetaModel, property); 45 check = attributeCheck(property, removeAttributeMethodName); 46 } 47 if (property.isOptional()) { 48 check = f("if (%s != null) { %s }", property.getName(), check); 49 } 50 body.addStatement(check); 51 } 52 if (nodeMetaModel.getSuperNodeMetaModel().isPresent()) { 53 body.addStatement("return super.remove(node);"); 54 } else { 55 body.addStatement("return false;"); 56 } 57 58 addOrReplaceWhenSameSignature(nodeCoid, removeNodeMethod); 59 } 60 61 private String attributeCheck(PropertyMetaModel property, String removeAttributeMethodName) { 62 return f("if (node == %s) {" + 63 " %s();" + 64 " return true;\n" + 65 "}", property.getName(), removeAttributeMethodName); 66 } 67 68 private String nodeListCheck(PropertyMetaModel property) { 69 return f("for (int i = 0; i < %s.size(); i++) {" + 70 " if (%s.get(i) == node) {" + 71 " %s.remove(i);" + 72 " return true;" + 73 " }" + 74 "}", property.getName(), property.getName(), property.getName()); 75 } 76 77 private String generateRemoveMethodForAttribute(ClassOrInterfaceDeclaration nodeCoid, BaseNodeMetaModel nodeMetaModel, PropertyMetaModel property) { 78 final String methodName = "remove" + capitalize(property.getName()); 79 final MethodDeclaration removeMethod = (MethodDeclaration) parseBodyDeclaration(f("public %s %s() {}", nodeMetaModel.getTypeName(), methodName)); 80 81 final BlockStmt block = removeMethod.getBody().get(); 82 block.addStatement(f("return %s((%s) null);", property.getSetterMethodName(), property.getTypeNameForSetter())); 83 84 addOrReplaceWhenSameSignature(nodeCoid, removeMethod); 85 return methodName; 86 } 87 } 88