/** * Copyright 2004-2016 Riccardo Solmi. All rights reserved. * This file is part of the Whole Platform. * * The Whole Platform is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Whole Platform is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>. */ package org.whole.gen; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ArrayCreation; import org.eclipse.jdt.core.dom.ArrayInitializer; import org.eclipse.jdt.core.dom.ArrayType; import org.eclipse.jdt.core.dom.Assignment; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.BooleanLiteral; import org.eclipse.jdt.core.dom.CastExpression; import org.eclipse.jdt.core.dom.CatchClause; import org.eclipse.jdt.core.dom.CharacterLiteral; import org.eclipse.jdt.core.dom.ClassInstanceCreation; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.ConstructorInvocation; import org.eclipse.jdt.core.dom.DoStatement; import org.eclipse.jdt.core.dom.EmptyStatement; import org.eclipse.jdt.core.dom.EnhancedForStatement; import org.eclipse.jdt.core.dom.Expression; import org.eclipse.jdt.core.dom.ExpressionStatement; import org.eclipse.jdt.core.dom.FieldAccess; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.ForStatement; import org.eclipse.jdt.core.dom.IfStatement; import org.eclipse.jdt.core.dom.ImportDeclaration; import org.eclipse.jdt.core.dom.InfixExpression; import org.eclipse.jdt.core.dom.Initializer; import org.eclipse.jdt.core.dom.InstanceofExpression; import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Name; import org.eclipse.jdt.core.dom.NullLiteral; import org.eclipse.jdt.core.dom.NumberLiteral; import org.eclipse.jdt.core.dom.PackageDeclaration; import org.eclipse.jdt.core.dom.ParameterizedType; import org.eclipse.jdt.core.dom.ParenthesizedExpression; import org.eclipse.jdt.core.dom.PostfixExpression; import org.eclipse.jdt.core.dom.PrefixExpression; import org.eclipse.jdt.core.dom.PrimitiveType; import org.eclipse.jdt.core.dom.ReturnStatement; import org.eclipse.jdt.core.dom.SimpleName; import org.eclipse.jdt.core.dom.SingleMemberAnnotation; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.Statement; import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.dom.SuperConstructorInvocation; import org.eclipse.jdt.core.dom.SuperFieldAccess; import org.eclipse.jdt.core.dom.SuperMethodInvocation; import org.eclipse.jdt.core.dom.SwitchCase; import org.eclipse.jdt.core.dom.SwitchStatement; import org.eclipse.jdt.core.dom.TagElement; import org.eclipse.jdt.core.dom.TextElement; import org.eclipse.jdt.core.dom.ThrowStatement; import org.eclipse.jdt.core.dom.TryStatement; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.TypeLiteral; import org.eclipse.jdt.core.dom.VariableDeclarationExpression; import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import org.eclipse.jdt.core.dom.VariableDeclarationStatement; import org.eclipse.jdt.core.dom.WhileStatement; import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword; import org.whole.gen.lang.LanguageGenerator; import org.whole.lang.exceptions.IWholeRuntimeException; import org.whole.lang.factories.EntityBuilder; import org.whole.lang.factories.IEntityBuilder; import org.whole.lang.model.AbstractEntity; import org.whole.lang.model.EnumValue; import org.whole.lang.reflect.EntityDescriptor; import org.whole.lang.util.StringUtils; /** * @author Riccardo Solmi */ public class CompilationUnitBuilder extends AbstractEntity { public static final String LANG_PACKAGE = "org.whole.lang"; public final JavaModelGenerator generator; public final AST ast; public final List<CompilationUnit> cuList; public CompilationUnit cu; public PackageDeclaration packageDec; public TypeDeclaration typeDec; public MethodDeclaration methodDec; public Block block; public Statement stm; public Name name; public Expression exp; public List<Expression> expList; public Type type; protected boolean isInterface = false; public CompilationUnitBuilder(JavaModelGenerator generator) { this.generator = generator; ast = generator.ast; cuList = generator.cuList; newCompilationUnit(); } public CompilationUnitBuilder(JavaModelGenerator generator, String packageSuffix) { this(generator); putPackageDeclaration(generator.packagePrefix+"."+packageSuffix); } public CompilationUnit getCompilationUnit() { return cu; } public TypeDeclaration getType() { return typeDec; } protected CompilationUnit newCompilationUnit() { cuList.add(cu = ast.newCompilationUnit()); return cu; } public void putCUDocComment() { String copyright = generator.getCopyright(); String license = generator.getLicense(); String comment = copyright; if (comment != null && comment.length() > 0) comment += "\n "+license; else comment = license; if (comment != null && comment.length() > 0) { TagElement te = newTagElement(null, comment); Javadoc cuDoc = newJavadoc(); cuDoc.tags().add(te); packageDec.setJavadoc(cuDoc); } } public void putPackageDeclaration(String packageName) { if (packageDec == null) { packageDec = ast.newPackageDeclaration(); packageDec.setName(newQualifiedName(packageName)); cu.setPackage(packageDec); putCUDocComment(); packageImportSet.add(packageName); } } private Set<String> classImportSet = new HashSet<String>(32); private Set<String> packageImportSet = new HashSet<String>(32); protected Set<String> simpleNameImportSet = new HashSet<String>(32); private Set<String> packageNoImportSet = new HashSet<String>(32); public void noImportPackage(String packageName) { packageNoImportSet.add(packageName); } public boolean addImportDeclaration(String typeName) { return addImportDeclaration(typeName, false); } public boolean addImportDeclaration(String typeName, boolean onDemand) { return addImportDeclaration(typeName, onDemand, false); } public boolean addImportDeclaration(String typeName, boolean onDemand, boolean isStatic) { if (onDemand) { if (packageImportSet.contains(typeName)) return true; packageImportSet.add(typeName); } else { String packageName = StringUtils.toPackageName(typeName); String simpleName = StringUtils.toSimpleName(typeName); if (classImportSet.contains(typeName)) return true; if ("java.lang".equals(packageName))//&& StringUtils.isAmbiguous(simpleName) return !simpleNameImportSet.contains(simpleName); if (!StringUtils.isAmbiguous(simpleName)) { if (packageNoImportSet.contains(packageName) || simpleNameImportSet.contains(simpleName)) return false; else if (packageImportSet.contains(packageName)) { classImportSet.add(typeName); simpleNameImportSet.add(simpleName); return true; } } classImportSet.add(typeName); simpleNameImportSet.add(simpleName); } ImportDeclaration id = ast.newImportDeclaration(); id.setName(newQualifiedName(typeName)); id.setOnDemand(onDemand); id.setStatic(isStatic); cu.imports().add(id); return true; } public SingleMemberAnnotation newSingleMemberAnnotation(String typeName, String value) { return newSingleMemeberAnnotation(typeName, newLiteral(value)); } public SingleMemberAnnotation newSingleMemeberAnnotation(String typeName, Expression exp) { SingleMemberAnnotation annotation = ast.newSingleMemberAnnotation(); annotation.setTypeName(newSimpleName(typeName)); annotation.setValue(exp); return annotation; } public TextElement newTextElement(String text) { TextElement elem = ast.newTextElement(); elem.setText(text); return elem; } public TagElement newTagElement(String tagName) { TagElement tag = ast.newTagElement(); tag.setTagName(tagName); return tag; } public TagElement newTagElement(String tagName, String text) { TagElement tag = newTagElement(tagName); tag.fragments().add(newTextElement(" "+text)); return tag; } public Javadoc newJavadoc() { return ast.newJavadoc(); } public Javadoc newJavadoc(String author) { Javadoc doc = ast.newJavadoc(); if (author != null) doc.tags().add(newTagElement(TagElement.TAG_AUTHOR, author)); doc.tags().add(newTagElement("@generator", "Whole")); return doc; } public String getAuthor() { if (generator != null) return generator.getAuthor(); else return ""; } public TypeDeclaration addClassDeclaration(String name) { putPackageDeclaration(StringUtils.toPackageName(name)); typeDec = ast.newTypeDeclaration(); typeDec.setJavadoc(newJavadoc(getAuthor())); typeDec.setInterface(isInterface = false); typeDec.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); typeDec.setName(ast.newSimpleName(StringUtils.toSimpleName(name))); cu.types().add(typeDec); return typeDec; } public TypeDeclaration addClassDeclaration(String name, String superclassName) { addClassDeclaration(name); setSuperclass(superclassName); return typeDec; } public TypeDeclaration addClassDeclaration(String name, Type superclassName) { addClassDeclaration(name); setSuperclass(superclassName); return typeDec; } public TypeDeclaration addInterfaceDeclaration(String name) { putPackageDeclaration(StringUtils.toPackageName(name)); typeDec = ast.newTypeDeclaration(); typeDec.setJavadoc(newJavadoc(getAuthor())); typeDec.setInterface(isInterface = true); typeDec.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); typeDec.setName(ast.newSimpleName(StringUtils.toSimpleName(name))); cu.types().add(typeDec); return typeDec; } public TypeDeclaration addInterfaceDeclaration(String name, String superclassName) { addInterfaceDeclaration(name); addSuperInterface(superclassName); return typeDec; } public TypeDeclaration addInterfaceDeclaration(String name, Type superclassName) { addInterfaceDeclaration(name); addSuperInterface(superclassName); return typeDec; } public CompilationUnit addImplementationType(String implementationName, CompilationUnit interfaceCU) { TypeDeclaration interfaceType = (TypeDeclaration)interfaceCU.types().get(0); addClassDeclaration(implementationName); // addSuperInterface(interfaceType.getName().getIdentifier()); // addImportDeclaration(interfaceCU.getPackage().getName().toString()+"."+interfaceType.getName().getIdentifier()); Iterator i = interfaceCU.imports().iterator(); while (i.hasNext()) { ImportDeclaration importDec = (ImportDeclaration)i.next(); if (importDec.isOnDemand()) addImportDeclaration(importDec.getName().getFullyQualifiedName(), true); // else // addImportDeclaration(importDec.getName().toString()); } i = interfaceType.bodyDeclarations().iterator(); while (i.hasNext()) { Object declaration = i.next(); if (declaration instanceof MethodDeclaration) { String typeName = ((SingleVariableDeclaration)((MethodDeclaration)declaration).parameters().get(0)).getType().toString(); addVisitMethod(typeName); } } return cu; } public void setSuperclass(String superClass) { typeDec.setSuperclassType(newType(superClass)); } public void setSuperclass(Type superClass) { typeDec.setSuperclassType(superClass); } public void addSuperInterface(String superInterface) { typeDec.superInterfaceTypes().add(newType(superInterface)); } public void addSuperInterface(Type superInterface) { typeDec.superInterfaceTypes().add(superInterface); } public List bodyDeclarations() { return typeDec.bodyDeclarations(); } public void addBodyDeclaration(BodyDeclaration declaration) { if (declaration instanceof MethodDeclaration) methodDec = (MethodDeclaration)declaration; bodyDeclarations().add(declaration); } public void addBodyDeclaration(int index, BodyDeclaration declaration) { if (declaration instanceof MethodDeclaration) methodDec = (MethodDeclaration)declaration; bodyDeclarations().add(index, declaration); } public FieldDeclaration newSerialVersionUID(long value) { FieldDeclaration field = newFieldDeclaration("long", "serialVersionUID", newLiteral(value)); field.modifiers().add(ast.newModifier(ModifierKeyword.STATIC_KEYWORD)); field.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD)); return field; } public void addSerialVersionUID(long value) { addBodyDeclaration(newSerialVersionUID(value)); } //TODO rename to newName public Name newSimpleName(String name) { if (StringUtils.isQualified(name)) { if (addImportDeclaration(name)) { return ast.newSimpleName(StringUtils.toSimpleName(name)); } else { String[] names = name.split("\\."); Name qName = ast.newSimpleName(names[0]); for (int i=1; i<names.length; i++) { qName = ast.newQualifiedName(qName, ast.newSimpleName(names[i])); } return qName; } } else return ast.newSimpleName(name); } public Name newSimpleQualifiedName(String name) { if (StringUtils.isQualified2(name)) if (addImportDeclaration(StringUtils.toPackageName(name))) return newQualifiedName(StringUtils.toSimpleQualifiedName(name)); return newQualifiedName(name); } public Name newQualifiedName(String name) { if (StringUtils.isQualified(name)) { String[] names = name.split("\\."); Name qName = ast.newSimpleName(names[0]); for (int i=1; i<names.length; i++) { qName = ast.newQualifiedName(qName, ast.newSimpleName(names[i])); } return qName; } else return ast.newSimpleName(name); } public Type newQualifiedType(String name) { if (StringUtils.isQualified(name)) return ast.newSimpleType(newQualifiedName(name)); else return newType(name); } public Type newSimpleQualifiedType(String name) { return ast.newSimpleType(newSimpleQualifiedName(name)); } public MethodDeclaration newCloneMethod() { MethodDeclaration cloneMethod = ast.newMethodDeclaration(); cloneMethod.setConstructor(false); cloneMethod.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); cloneMethod.setReturnType2(ast.newSimpleType(newSimpleName("java.lang.Object"))); cloneMethod.setName(ast.newSimpleName("clone")); Block body = newBlock(); CastExpression castExp = ast.newCastExpression(); castExp.setType(newType(typeDec.getName().getIdentifier())); SuperMethodInvocation superCall = ast.newSuperMethodInvocation(); superCall.setName(ast.newSimpleName("clone")); castExp.setExpression(superCall); VariableDeclarationFragment varDec = ast.newVariableDeclarationFragment(); varDec.setName(ast.newSimpleName("obj")); varDec.setInitializer(castExp); VariableDeclarationStatement varDecStm = ast.newVariableDeclarationStatement(varDec); varDecStm.setType(newType(typeDec.getName().getIdentifier())); body.statements().add(varDecStm); ReturnStatement returnStm = ast.newReturnStatement(); returnStm.setExpression(ast.newSimpleName("obj")); body.statements().add(returnStm); cloneMethod.setBody(body); return cloneMethod; } public MethodDeclaration newAcceptMethod(String visitorInterfaceName) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); method.setName(ast.newSimpleName("accept")); method.parameters().add(newSingleVariableDeclaration(visitorInterfaceName, "visitor")); if (!isInterface) { Block body = newBlock(); TryStatement tryStm = newTryStatement(); MethodInvocation callExp = ast.newMethodInvocation(); callExp.setExpression(ast.newSimpleName("visitor")); callExp.setName(ast.newSimpleName("visit")); callExp.arguments().add(ast.newThisExpression()); tryStm.getBody().statements().add(newExpressionStatement(callExp)); callExp = ast.newMethodInvocation(); callExp.setExpression(newSimpleName(IWholeRuntimeException.class.getName())); callExp.setName(ast.newSimpleName("asWholeException")); callExp.arguments().add(newSimpleName("e")); callExp.arguments().add(ast.newThisExpression()); callExp.arguments().add(newMethodInvocation(ast.newSimpleName("visitor"), "getBindings")); tryStm.catchClauses().add(newCatchClause( newSingleVariableDeclaration("Exception", "e"), newThrowStatement(callExp))); body.statements().add(tryStm); method.setBody(body); } return method; } public CastExpression newCastExpression(Type type, Expression exp) { CastExpression castExp = ast.newCastExpression(); castExp.setType(type); castExp.setExpression(exp); return castExp; } public CastExpression newCastExpression(String type, Expression exp) { return newCastExpression(type, exp, false); } public CastExpression newCastExpression(String type, Expression exp, boolean useQualifiedType) { return newCastExpression(useQualifiedType ? newQualifiedType(type) : newType(type), exp); } public ReturnStatement newReturnStatement(Expression exp) { ReturnStatement stm = ast.newReturnStatement(); stm.setExpression(exp); return stm; } public ThrowStatement newThrowStatement(Expression exp) { ThrowStatement stm = ast.newThrowStatement(); stm.setExpression(exp); return stm; } public Assignment newAssignment(Expression exp1, String op, Expression exp2) { Assignment eqExp = ast.newAssignment(); eqExp.setLeftHandSide(exp1); eqExp.setOperator(Assignment.Operator.toOperator(op)); eqExp.setRightHandSide(exp2); return eqExp; } public Assignment newAssignment(Expression exp1, Expression exp2) { return newAssignment(exp1, "=", exp2); } public Assignment newAssignment(String name, Expression exp) { return newAssignment(ast.newSimpleName(name), exp); } public PostfixExpression newPostfixExpression(String id, String op) { return newPostfixExpression(ast.newSimpleName(id), op); } public PostfixExpression newPostfixExpression(Expression exp, String op) { PostfixExpression postfixExp = ast.newPostfixExpression(); postfixExp.setOperand(exp); postfixExp.setOperator(PostfixExpression.Operator.toOperator(op)); return postfixExp; } public PrefixExpression newPrefixExpression(String id, String op) { return newPrefixExpression(ast.newSimpleName(id), op); } public PrefixExpression newPrefixExpression(Expression exp, String op) { PrefixExpression prefixExp = ast.newPrefixExpression(); prefixExp.setOperand(exp); prefixExp.setOperator(PrefixExpression.Operator.toOperator(op)); return prefixExp; } public InfixExpression newInfixExpression(Expression exp1, String op, Expression exp2) { InfixExpression infixExp = ast.newInfixExpression(); infixExp.setLeftOperand(exp1); infixExp.setOperator(InfixExpression.Operator.toOperator(op)); infixExp.setRightOperand(exp2); return infixExp; } public InstanceofExpression newInstanceofExpression(String exp1, String type) { return newInstanceofExpression(ast.newSimpleName(exp1), type); } public InstanceofExpression newInstanceofExpression(Expression exp1, String type) { return newInstanceofExpression(exp1, newType(type)); } public InstanceofExpression newInstanceofExpression(Expression exp1, Type type) { InstanceofExpression exp = ast.newInstanceofExpression(); exp.setLeftOperand(exp1); exp.setRightOperand(type); return exp; } public ClassInstanceCreation newClassInstanceCreation(Type type) { ClassInstanceCreation stm = ast.newClassInstanceCreation(); stm.setType(type); return stm; } public ClassInstanceCreation newClassInstanceCreation(Type type, Expression arg0) { ClassInstanceCreation stm = newClassInstanceCreation(type); stm.arguments().add(arg0); return stm; } public ClassInstanceCreation newClassInstanceCreation(Type type, Expression arg0, Expression arg1) { ClassInstanceCreation stm = newClassInstanceCreation(type); stm.arguments().add(arg0); stm.arguments().add(arg1); return stm; } public ClassInstanceCreation newClassInstanceCreation(Type type, Expression arg0, Expression arg1, Expression arg2) { ClassInstanceCreation stm = newClassInstanceCreation(type); stm.arguments().add(arg0); stm.arguments().add(arg1); stm.arguments().add(arg2); return stm; } public ClassInstanceCreation newClassInstanceCreation(String type) { return newClassInstanceCreation(newType(type)); } public ClassInstanceCreation newClassInstanceCreation(String type, Expression arg0) { return newClassInstanceCreation(newType(type), arg0); } public ClassInstanceCreation newClassInstanceCreation(String type, Expression arg0, Expression arg1) { return newClassInstanceCreation(newType(type), arg0, arg1); } public ClassInstanceCreation newClassInstanceCreation(String type, Expression arg0, Expression arg1, Expression arg2) { return newClassInstanceCreation(newType(type), arg0, arg1, arg2); } public ArrayInitializer newArrayInitializer() { return ast.newArrayInitializer(); } public ArrayCreation newArrayCreation(String type, ArrayInitializer initializer) { ArrayCreation stm = newArrayCreation(type); stm.setInitializer(initializer); return stm; } public ArrayCreation newArrayCreation(String type) { return newArrayCreation(type, 1); } public ArrayCreation newArrayCreation(String type, int dimensions) { ArrayCreation stm = ast.newArrayCreation(); stm.setType(newArrayType(type, dimensions)); return stm; } public TryStatement newTryStatement(Statement stm, SingleVariableDeclaration exc, Statement body) { TryStatement tryStm = newTryStatement(); tryStm.getBody().statements().add(stm); tryStm.catchClauses().add(newCatchClause(exc, body)); return tryStm; } public TryStatement newTryStatement() { return ast.newTryStatement(); } public CatchClause newCatchClause() { return ast.newCatchClause(); } public CatchClause newCatchClause(SingleVariableDeclaration exc) { CatchClause clause = newCatchClause(); clause.setException(exc); return clause; } public CatchClause newCatchClause(SingleVariableDeclaration exc, Statement body) { CatchClause clause = newCatchClause(exc); clause.getBody().statements().add(body); return clause; } public VariableDeclarationStatement newVariableDeclarationStatement(String type, String name) { return newVariableDeclarationStatement(type, name, null); } public VariableDeclarationStatement newVariableDeclarationStatement(String type, String name, Expression initializer) { return newVariableDeclarationStatement(newType(type), newVariableDeclarationFragment(name, initializer)); } public void addVariableDeclarationStatement(String type, String name, Expression initializer) { addStatement(newVariableDeclarationStatement(type, name, initializer)); } public VariableDeclarationStatement newVariableDeclarationStatement(Type fType, VariableDeclarationFragment varDec) { VariableDeclarationStatement varDecStm = ast.newVariableDeclarationStatement(varDec); varDecStm.setType(fType); return varDecStm; } public VariableDeclarationExpression newVariableDeclarationExpression(String type, String name) { return newVariableDeclarationExpression(type, name, null); } public VariableDeclarationExpression newVariableDeclarationExpression(String type, String name, Expression initializer) { return newVariableDeclarationExpression(newType(type), newVariableDeclarationFragment(name, initializer)); } public VariableDeclarationExpression newVariableDeclarationExpression(Type fType, VariableDeclarationFragment varDec) { VariableDeclarationExpression varDecExp = ast.newVariableDeclarationExpression(varDec); varDecExp.setType(fType); return varDecExp; } public void addConstructorCase(MethodDeclaration constructor, String fType, String fName) { constructor.parameters().add(newSingleVariableDeclaration(fType, fName)); constructor.getBody().statements().add(ast.newExpressionStatement( newMethodInvocation(StringUtils.setterName(fName), ast.newSimpleName(fName)) )); /* FieldAccess fieldAcc = ast.newFieldAccess(); fieldAcc.setExpression(ast.newThisExpression()); fieldAcc.setName(ast.newSimpleName(fName)); Assignment eq = ast.newAssignment(); eq.setLeftHandSide(fieldAcc); eq.setRightHandSide(ast.newSimpleName(fName)); constructor.getBody().statements().add(ast.newExpressionStatement(eq));*/ } public void addConstructorCase(MethodDeclaration constructor, String setterName, String fType, String fName) { constructor.parameters().add(newSingleVariableDeclaration(fType, fName)); MethodInvocation callExp = newMethodInvocation(setterName); callExp.arguments().add(ast.newSimpleName(fName)); constructor.getBody().statements().add(ast.newExpressionStatement(callExp)); } public FieldDeclaration newFieldDeclaration(String fType, String fName) { return newFieldDeclaration(fType, fName, false); } public FieldDeclaration newFieldDeclaration(String fType, String fName, boolean useQualifiedType) { return newFieldDeclaration(fType, fName, null, useQualifiedType); } public FieldDeclaration newFieldDeclaration(String fType, String fName, Expression initializer) { return newFieldDeclaration(fType, fName, initializer, false); } public FieldDeclaration newFieldDeclaration(String fType, String fName, Expression initializer, boolean useQualifiedType) { return newFieldDeclaration(useQualifiedType ? newQualifiedType(fType) : newType(fType), newVariableDeclarationFragment(fName, initializer)); } public FieldDeclaration newFieldDeclaration(Type fType, VariableDeclarationFragment varDec) { FieldDeclaration fieldDec = ast.newFieldDeclaration(varDec); fieldDec.modifiers().add(ast.newModifier(ModifierKeyword.PRIVATE_KEYWORD)); fieldDec.setType(fType); return fieldDec; } public FieldDeclaration newFieldDeclaration(String fType, VariableDeclarationFragment fragment) { return newFieldDeclaration(newType(fType), fragment); } public VariableDeclarationFragment newVariableDeclarationFragment(String fName, Expression initializer) { try { return newVariableDeclarationFragment(ast.newSimpleName(fName), initializer); } catch(IllegalArgumentException e) { throw new IllegalStateException("illegal name: "+fName, e); } } public VariableDeclarationFragment newVariableDeclarationFragment(SimpleName fName, Expression initializer) { VariableDeclarationFragment varDec = ast.newVariableDeclarationFragment(); varDec.setName(fName); if (initializer != null) varDec.setInitializer(initializer); return varDec; } public ParameterizedType newParameterizedType(String type) { return ast.newParameterizedType(newType(type)); } public ParameterizedType newParameterizedType(String type, String type1) { ParameterizedType ptype = newParameterizedType(type); ptype.typeArguments().add(newType(type1)); return ptype; } public ParameterizedType newParameterizedType(String type, Type type1) { ParameterizedType ptype = newParameterizedType(type); ptype.typeArguments().add(type1); return ptype; } public ParameterizedType newParameterizedType(String type, String type1, String type2) { ParameterizedType ptype = newParameterizedType(type); ptype.typeArguments().add(newType(type1)); ptype.typeArguments().add(newType(type2)); return ptype; } public ParameterizedType newParameterizedType(String type, Type type1, Type type2) { ParameterizedType ptype = newParameterizedType(type); ptype.typeArguments().add(type1); ptype.typeArguments().add(type2); return ptype; } public Type newType(String fType) { if (StringUtils.isPrimitive(fType)) return ast.newPrimitiveType(PrimitiveType.toCode(fType)); return ast.newSimpleType(newSimpleName(fType)); } public ArrayType newArrayType(String type) { return ast.newArrayType(newType(type)); } public ArrayType newArrayType(String type, int dimensions) { return ast.newArrayType(newType(type), dimensions); } public FieldAccess newFieldAccess(String exp, String fName) { return newFieldAccess(newSimpleName(exp), fName); } public FieldAccess newFieldAccess(Expression exp, String fName) { FieldAccess fieldExp = ast.newFieldAccess(); fieldExp.setExpression(exp); fieldExp.setName(ast.newSimpleName(fName)); return fieldExp; } public SuperFieldAccess newSuperFieldAccess(String fName) { SuperFieldAccess fieldExp = ast.newSuperFieldAccess(); fieldExp.setName(ast.newSimpleName(fName)); return fieldExp; } public MethodDeclaration newGetterMethod(String fType, String fName) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(newType(fType)); method.setName(ast.newSimpleName(StringUtils.getterName(fType, fName))); if (!isInterface) { Block body = newBlock(); ReturnStatement returnStm = ast.newReturnStatement(); returnStm.setExpression(ast.newSimpleName(fName)); body.statements().add(returnStm); method.setBody(body); } return method; } public MethodDeclaration newGetterMethodWithNotification(String featuresEnum, String fType, String fName, String name) { return newGetterMethodWithNotification(featuresEnum, fType, fName, name, false); } public MethodDeclaration newGetterMethodWithNotification(String featuresEnum, String fType, String fName, String name, boolean useQualifiedType) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(useQualifiedType ? newQualifiedType(fType) : newType(fType)); method.setName(ast.newSimpleName(StringUtils.getterName(fType, StringUtils.isJavaKeyword(name) ? name : fName))); if (!isInterface) { Block body = newBlock(); MethodInvocation callExp = newMethodInvocation("notifyRequested", ast.newSimpleName(fName)); if (featuresEnum != null) callExp.arguments().add(0, newFieldAccess(featuresEnum, fName)); body.statements().add(newReturnStatement(callExp)); method.setBody(body); } return method; } public MethodDeclaration newGetterMethodWithGenericForward(String featuresEnum, String fType, String fName, String name) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(newType(fType)); method.setName(ast.newSimpleName(StringUtils.getterName(fType, StringUtils.isJavaKeyword(name) ? name : fName))); if (!isInterface) { Block body = newBlock(); MethodInvocation callExp = newMethodInvocation("wGet"); callExp.arguments().add(newFieldAccess(featuresEnum, fName)); body.statements().add(newReturnStatement (newMethodInvocation(callExp, "wGetAdapter", newFieldAccess(((LanguageGenerator) generator).specificEntityDescriptorEnumName(), fType)))); method.setBody(body); } return method; } public MethodDeclaration newDataGetterMethodWithGenericForward(String fType, String fName) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(newType(fType)); method.setName(ast.newSimpleName(StringUtils.getterName(fType, fName))); if (!isInterface) { Block body = newBlock(); String getValueMethod = specificGetValueName(fType); if (getValueMethod.equals("wEnumValue") || getValueMethod.equals("wGetValue")) body.statements().add(newReturnStatement( newCastExpression(newType(fType), newMethodInvocation(getValueMethod)))); else body.statements().add(newReturnStatement( newMethodInvocation(getValueMethod))); method.setBody(body); } return method; } private String specificGetValueName(String fType) { String methodName; if (StringUtils.isPrimitive(fType)) methodName = "w"+StringUtils.toUpperCap(fType)+"Value"; else if (StringUtils.isString(fType)) methodName = "wStringValue"; else if (fType.endsWith("Enum.Value") || fType.equals(EntityDescriptor.class.getName())) methodName = "wEnumValue"; else if (fType.equals("Date") || fType.equals("java.util.Date")) methodName = "wDateValue"; else methodName = "wGetValue"; return methodName; } public MethodDeclaration newSetterMethodWithGenericForward(String featuresEnum, String fType, String fName, String name) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); method.setName(ast.newSimpleName(StringUtils.setterName(StringUtils.isJavaKeyword(name) ? name : fName))); method.parameters().add(newSingleVariableDeclaration(fType, fName)); if (!isInterface) { Block body = newBlock(); MethodInvocation callExp = newMethodInvocation("wSet"); callExp.arguments().add(newFieldAccess(featuresEnum, fName)); callExp.arguments().add(ast.newSimpleName(fName)); body.statements().add(ast.newExpressionStatement(callExp)); method.setBody(body); } return method; } public MethodDeclaration newDataSetterMethodWithGenericForward(String fType, String fName) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); method.setName(ast.newSimpleName(StringUtils.setterName(fName))); method.parameters().add(newSingleVariableDeclaration(fType, fName)); if (!isInterface) { Block body = newBlock(); MethodInvocation callExp = newMethodInvocation("wSetValue"); if (StringUtils.isPrimitiveOrString(fType) || fType.equals("java.util.Date") || fType.endsWith("Enum.Value")) callExp.arguments().add(ast.newSimpleName(fName)); else callExp.arguments().add(newCastExpression("java.lang.Object", ast.newSimpleName(fName))); body.statements().add(ast.newExpressionStatement(callExp)); method.setBody(body); } return method; } public MethodDeclaration newSetterMethod(String fType, String fName) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); method.setName(ast.newSimpleName(StringUtils.setterName(fName))); method.parameters().add(newSingleVariableDeclaration(fType, fName)); if (!isInterface) { Block body = newBlock(); Assignment eq = ast.newAssignment(); FieldAccess fieldAcc = ast.newFieldAccess(); fieldAcc.setExpression(ast.newThisExpression()); fieldAcc.setName(ast.newSimpleName(fName)); eq.setLeftHandSide(fieldAcc); eq.setRightHandSide(ast.newSimpleName(fName)); body.statements().add(ast.newExpressionStatement(eq)); method.setBody(body); } return method; } public MethodDeclaration newSetterMethod(String setterName, String pType, String fType, String fName) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); method.setName(ast.newSimpleName(setterName)); method.parameters().add(newSingleVariableDeclaration(pType, fName)); if (!isInterface) { Block body = newBlock(); Assignment eq = ast.newAssignment(); FieldAccess fieldAcc = ast.newFieldAccess(); fieldAcc.setExpression(ast.newThisExpression()); fieldAcc.setName(ast.newSimpleName(fName)); eq.setLeftHandSide(fieldAcc); if (pType.equals(fType)) eq.setRightHandSide(ast.newSimpleName(fName)); else eq.setRightHandSide(newCastExpression(fType, ast.newSimpleName(fName))); body.statements().add(ast.newExpressionStatement(eq)); method.setBody(body); } return method; } public void addParameter(SingleVariableDeclaration param) { methodDec.parameters().add(param); } public SingleVariableDeclaration newSingleVariableDeclaration(String pType, String pName) { return newSingleVariableDeclaration(pType, pName, false); } public SingleVariableDeclaration newSingleVariableDeclaration(String pType, String pName, boolean useQualifiedType) { return newSingleVariableDeclaration(useQualifiedType ? newQualifiedType(pType) : newType(pType), pName); } public SingleVariableDeclaration newSingleVariableDeclaration(Type pType, String pName) { return newSingleVariableDeclaration(pType, ast.newSimpleName(pName)); } public SingleVariableDeclaration newSingleVariableDeclaration(Type pType, SimpleName pName) { SingleVariableDeclaration param = ast.newSingleVariableDeclaration(); param.setType(pType); param.setName(pName); return param; } public MethodDeclaration newSetterMethodWithNotification(String featuresEnum, String fType, String fName, String name, boolean isReference) { return newSetterMethodWithNotification(featuresEnum, fType, fName, name, isReference, false); } public MethodDeclaration newSetterMethodWithNotification(String featuresEnum, String fType, String fName, String name, boolean isReference, boolean useQualifiedType) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); method.setName(ast.newSimpleName(StringUtils.setterName(StringUtils.isJavaKeyword(name) ? name : fName))); method.parameters().add(newSingleVariableDeclaration(useQualifiedType ? newQualifiedType(fType) : newType(fType), fName)); if (!isInterface) { Block body = newBlock(); MethodInvocation callExp = ast.newMethodInvocation(); callExp.setName(ast.newSimpleName("notifyChanged")); if (featuresEnum != null) callExp.arguments().add(newFieldAccess(featuresEnum, fName)); FieldAccess fieldAcc = ast.newFieldAccess(); fieldAcc.setExpression(ast.newThisExpression()); fieldAcc.setName(ast.newSimpleName(fName)); callExp.arguments().add(fieldAcc); fieldAcc = ast.newFieldAccess(); fieldAcc.setExpression(ast.newThisExpression()); fieldAcc.setName(ast.newSimpleName(fName)); Assignment eq = ast.newAssignment(); eq.setLeftHandSide(fieldAcc); eq.setRightHandSide(ast.newSimpleName(fName)); callExp.arguments().add(eq); if (isReference) callExp.arguments().add(newLiteral(false)); body.statements().add(ast.newExpressionStatement(callExp)); method.setBody(body); } return method; } public ParenthesizedExpression newParenthesizedExpression(Expression exp) { ParenthesizedExpression parExp = ast.newParenthesizedExpression(); parExp.setExpression(exp); return parExp; } public MethodDeclaration addConstructorDeclaration() { MethodDeclaration constructor = newConstructorDeclaration(typeDec); addBodyDeclaration(constructor); return constructor; } public MethodDeclaration newConstructorDeclaration(TypeDeclaration type) { return newConstructorDeclaration(type.getName().getIdentifier()); } public MethodDeclaration newConstructorDeclaration(String typeName) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(true); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setName(ast.newSimpleName(StringUtils.toSimpleName(typeName))); method.setBody(newBlock()); return method; } public MethodDeclaration newMethodDeclaration(Type returnType, SimpleName name) { MethodDeclaration method = ast.newMethodDeclaration(); method.setConstructor(false); method.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); method.setReturnType2(returnType); method.setName(name); if (!isInterface) method.setBody(newBlock()); return method; } public MethodDeclaration newMethodDeclaration(Type returnType, String name) { return newMethodDeclaration(returnType, ast.newSimpleName(name)); } public MethodDeclaration newMethodDeclaration(String returnType, String name) { return newMethodDeclaration(newType(returnType), name); } public MethodDeclaration newMethodDeclaration(String returnType, String name, SingleVariableDeclaration par0) { MethodDeclaration method = newMethodDeclaration(newType(returnType), name); method.parameters().add(par0); return method; } public MethodDeclaration newMethodDeclaration(String returnType, String name, SingleVariableDeclaration par0, SingleVariableDeclaration par1) { MethodDeclaration method = newMethodDeclaration(newType(returnType), name); method.parameters().add(par0); method.parameters().add(par1); return method; } public MethodDeclaration newMethodDeclaration(String returnType, String name, SingleVariableDeclaration par0, SingleVariableDeclaration par1, SingleVariableDeclaration par2) { MethodDeclaration method = newMethodDeclaration(newType(returnType), name); method.parameters().add(par0); method.parameters().add(par1); method.parameters().add(par2); return method; } public MethodDeclaration findMethodDeclaration(String methodName, List bodyDeclarations) { Iterator i = bodyDeclarations.iterator(); while (i.hasNext()) { Object declaration = i.next(); if (declaration instanceof MethodDeclaration) { MethodDeclaration method = (MethodDeclaration)declaration; if (method.getName().getIdentifier().equals(methodName)) return method; } } throw new MethodNotFoundException("method declaration not found: "+methodName); } public MethodDeclaration findMethodDeclaration(String methodName, String[] paramTypes, List bodyDeclarations) { Iterator i = bodyDeclarations.iterator(); while (i.hasNext()) { Object declaration = i.next(); if (declaration instanceof MethodDeclaration) { MethodDeclaration method = (MethodDeclaration)declaration; if (method.getName().getIdentifier().equals(methodName)) { List params = method.parameters(); if (params.size() == paramTypes.length) { int j; for (j=0; j<paramTypes.length; j++) { Type paramType = ((SingleVariableDeclaration) params.get(j)).getType(); if (!paramType.toString().equals(paramTypes[j])) break; } if (j == paramTypes.length) return method; } } } } throw new MethodNotFoundException("method declaration not found: "+methodName); } public TypeDeclaration addSingletonHolder(String holderName, String fieldTypeName) { return addSingletonHolder(holderName, fieldTypeName, Collections.<BodyDeclaration>emptyList()); } public TypeDeclaration addSingletonHolder(String holderName, String fieldTypeName, List<BodyDeclaration> declarations) { TypeDeclaration classDeclaration = ast.newTypeDeclaration(); classDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.PRIVATE_KEYWORD)); classDeclaration.modifiers().add(ast.newModifier(ModifierKeyword.STATIC_KEYWORD)); classDeclaration.setName(ast.newSimpleName(holderName)); VariableDeclarationFragment varDec = newVariableDeclarationFragment("instance", newClassInstanceCreation(fieldTypeName)); FieldDeclaration instanceField = ast.newFieldDeclaration(varDec); instanceField.modifiers().add(ast.newModifier(ModifierKeyword.PRIVATE_KEYWORD)); instanceField.modifiers().add(ast.newModifier(ModifierKeyword.STATIC_KEYWORD)); instanceField.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD)); instanceField.setType(ast.newSimpleType(ast.newSimpleName(fieldTypeName))); classDeclaration.bodyDeclarations().add(instanceField); classDeclaration.bodyDeclarations().addAll(declarations); addBodyDeclaration(classDeclaration); return classDeclaration; } public MethodDeclaration addSingletonHolderMethod() { String typeName = typeDec.getName().getIdentifier(); String holderName = "SingletonHolder"; addSingletonHolder(holderName, typeName); MethodDeclaration instanceMethod = newMethodDeclaration(typeName, "instance"); instanceMethod.modifiers().add(ast.newModifier(ModifierKeyword.STATIC_KEYWORD)); addBodyDeclaration(instanceMethod); Block body = newBlock(); FieldAccess instanceFieldAccess = ast.newFieldAccess(); instanceFieldAccess.setExpression(ast.newSimpleName(holderName)); instanceFieldAccess.setName(ast.newSimpleName("instance")); body.statements().add(newReturnStatement(instanceFieldAccess)); instanceMethod.setBody(body); MethodDeclaration constructor = newConstructorDeclaration(typeDec); constructor.modifiers().remove(0);//assume ModifierKeyword.PUBLIC_KEYWORD constructor.modifiers().add(ast.newModifier(ModifierKeyword.PRIVATE_KEYWORD)); addBodyDeclaration(constructor); return constructor; } public MethodDeclaration addSingletonMethod() { String typeName = typeDec.getName().getIdentifier(); FieldDeclaration instanceField = newFieldDeclaration(typeName, "instance"); instanceField.modifiers().add(ast.newModifier(ModifierKeyword.STATIC_KEYWORD)); addBodyDeclaration(0, instanceField); MethodDeclaration instanceMethod = newMethodDeclaration(typeName, "instance"); instanceMethod.modifiers().add(ast.newModifier(ModifierKeyword.STATIC_KEYWORD)); addBodyDeclaration(1, instanceMethod); Block body = newBlock(); IfStatement ifStm = ast.newIfStatement(); InfixExpression infixExp = ast.newInfixExpression(); infixExp.setLeftOperand(ast.newSimpleName("instance")); infixExp.setOperator(InfixExpression.Operator.EQUALS); infixExp.setRightOperand(ast.newNullLiteral()); ifStm.setExpression(infixExp); ifStm.setThenStatement(ast.newExpressionStatement(newAssignment("instance", newClassInstanceCreation(typeName)))); body.statements().add(ifStm); body.statements().add(newReturnStatement(ast.newSimpleName("instance"))); instanceMethod.setBody(body); MethodDeclaration constructor = newConstructorDeclaration(typeDec); constructor.modifiers().remove(0);//assume ModifierKeyword.PUBLIC_KEYWORD constructor.modifiers().add(ast.newModifier(ModifierKeyword.PRIVATE_KEYWORD)); addBodyDeclaration(2, constructor); return constructor; } public MethodDeclaration addSingletonField() { String implName = typeDec.getName().getIdentifier(); return addSingletonField(implName, implName); } public MethodDeclaration addSingletonField(String typeName) { if (isInterface) return addSingletonField(typeDec.getName().getIdentifier(), typeName); else return addSingletonField(typeName, typeDec.getName().getIdentifier()); } public MethodDeclaration addSingletonField(String typeName, String implName) { FieldDeclaration instanceField = newFieldDeclaration(typeName, "instance", newClassInstanceCreation(implName)); instanceField.modifiers().remove(0);//assume ModifierKeyword.PRIVATE_KEYWORD instanceField.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD)); instanceField.modifiers().add(ast.newModifier(ModifierKeyword.STATIC_KEYWORD)); instanceField.modifiers().add(ast.newModifier(ModifierKeyword.FINAL_KEYWORD)); addBodyDeclaration(0, instanceField); MethodDeclaration constructor = null; if (!isInterface) { constructor = newConstructorDeclaration(typeDec); constructor.modifiers().remove(0);//assume ModifierKeyword.PUBLIC_KEYWORD constructor.modifiers().add(ast.newModifier(ModifierKeyword.PRIVATE_KEYWORD)); addBodyDeclaration(1, constructor); } return constructor; } private String visitReturnType = "void"; public void setVisitMethodReturnType(String type) { visitReturnType = type; } public MethodDeclaration addVisitMethod(String type) { return addVisitMethod("visit", generator.entityInterfaceQName(type)); } public MethodDeclaration addVisitMethod(String name, String type) { return addVisitMethod(visitReturnType, "visit", type); } public MethodDeclaration addVisitMethod(String returnType, String name, String type) { MethodDeclaration method = newMethodDeclaration(returnType, name); method.parameters().add(newSingleVariableDeclaration(type, "entity")); if (!isInterface) method.setBody(newBlock()); addBodyDeclaration(method); return method; } public MethodDeclaration addBuildMethod(String entityType) { return addBuildMethod(entityType, newParameterizedType(IEntityBuilder.class.getName(), entityType)); } public MethodDeclaration addBuildMethod(String entityType, Type buildType) { return addBuildMethod("build", entityType, buildType, entityType); } public MethodDeclaration addBuildMethod(String prefix, String entityType, Type builderType, String builderName) { String prefixFactoryName = prefix.length() == 0 ? StringUtils.toLowerCap(StringUtils.toSimpleName(builderName)) : prefix+StringUtils.toSimpleName(builderName); methodDec = newMethodDeclaration(builderType, prefixFactoryName); if (!isInterface) { Block body = newBlock(); body.statements().add(newReturnStatement(newClassInstanceCreation( newParameterizedType(EntityBuilder.class.getName(), entityType), newMethodInvocation("create", newFieldAccess(generator.specificEntityDescriptorEnumName(), entityType))))); methodDec.setBody(body); } addBodyDeclaration(methodDec); return methodDec; } public MethodDeclaration addFactoryForwardMethod(String entityType, String targetMethodName) { assert isInterface; return addFactoryMethod(entityType); } public MethodDeclaration addFactoryMethod(String entityType) { return addFactoryMethod("create", entityType, entityType, entityType); } public MethodDeclaration addFactoryMethod(String entityType, String entityImplType) { return addFactoryMethod("create", entityType, entityType, entityImplType); } public MethodDeclaration addFactoryMethod(String factoryType, String entityType, String entityImplType) { return addFactoryMethod("create", factoryType, entityType, entityImplType); } public MethodDeclaration addFactoryMethod(String prefix, String factoryType, String factoryName, String typeName) { String prefixFactoryName = prefix.length() == 0 ? StringUtils.toLowerCap(StringUtils.toSimpleName(factoryName)) : prefix+StringUtils.toSimpleName(factoryName); methodDec = newMethodDeclaration(factoryType, prefixFactoryName); if (!isInterface) { Block body = newBlock(); body.statements().add(newReturnStatement(newClassInstanceCreation(typeName))); methodDec.setBody(body); } addBodyDeclaration(methodDec); return methodDec; } private static Set<String> nocastTypes; private static Set<String> nocastTypes() { if (nocastTypes == null) { nocastTypes = new HashSet<String>(); nocastTypes.addAll(Arrays.<String>asList(new String[] { "String","Object","Date"})); } return nocastTypes; } public static boolean needObjectCast(String type) { return !type.startsWith("java.") && !nocastTypes().contains(type); } public void addDataFactoryMethodCase(MethodDeclaration factoryMethod, String fType, String fName, boolean useQualifiedType) { if (fType.endsWith("Enum.Value")) addFactoryMethodCase(factoryMethod, newSimpleQualifiedType(fType), fName); else { Type type = useQualifiedType ? newQualifiedType(fType) : newType(fType); factoryMethod.parameters().add(newSingleVariableDeclaration(type, fName)); if (!isInterface) ((MethodInvocation)((ReturnStatement)factoryMethod.getBody().statements().get(0)).getExpression()).arguments().add( (type.isSimpleType() || type.isQualifiedType()) && needObjectCast(fType) ? newCastExpression(newQualifiedType("java.lang.Object"), ast.newSimpleName(fName)) : ast.newSimpleName(fName)); } } public void addFactoryMethodCase(MethodDeclaration factoryMethod, String fType, String fName, boolean useQualifiedType) { if (fType.endsWith("Enum.Value")) addFactoryMethodCase(factoryMethod, newSimpleQualifiedType(fType), fName); else addFactoryMethodCase(factoryMethod, useQualifiedType ? newQualifiedType(fType) : newType(fType), fName); } public void addFactoryMethodCase(MethodDeclaration factoryMethod, Type fType, String fName) { factoryMethod.parameters().add(newSingleVariableDeclaration(fType, fName)); if (!isInterface) ((ClassInstanceCreation)((ReturnStatement)factoryMethod.getBody().statements().get(0)).getExpression()).arguments().add(ast.newSimpleName(fName)); } public void addFactoryMethodArrayCase(MethodDeclaration method, String componentType, String fName) { addFactoryMethodCase(method, newArrayType(componentType), fName); } public void addFactoryMethodVarArgsCase(MethodDeclaration method, String componentType, String fName) { SingleVariableDeclaration varDecl = newSingleVariableDeclaration(componentType, fName); varDecl.setVarargs(true); method.parameters().add(varDecl); if (!isInterface) ((ClassInstanceCreation)((ReturnStatement)method.getBody().statements().get(0)).getExpression()).arguments().add(ast.newSimpleName(fName)); } public MethodInvocation newMethodInvocation(SimpleName method) { MethodInvocation callExp = ast.newMethodInvocation(); callExp.setName(method); return callExp; } public MethodInvocation newMethodInvocation(String method) { return newMethodInvocation(ast.newSimpleName(method)); } public MethodInvocation newMethodInvocation(String method, Expression arg0) { MethodInvocation callExp = newMethodInvocation(method); callExp.arguments().add(arg0); return callExp; } public MethodInvocation newMethodInvocation(String method, Expression arg0, Expression arg1) { MethodInvocation callExp = newMethodInvocation(method, arg0); callExp.arguments().add(arg1); return callExp; } public MethodInvocation newMethodInvocation(String method, Expression arg0, Expression arg1, Expression arg2) { MethodInvocation callExp = newMethodInvocation(method, arg0, arg1); callExp.arguments().add(arg2); return callExp; } public MethodInvocation newMethodInvocation(String obj, String method) { return newMethodInvocation(newSimpleName(obj), method); } public MethodInvocation newMethodInvocation(Expression exp, String method) { MethodInvocation callExp = ast.newMethodInvocation(); callExp.setExpression(exp); callExp.setName(ast.newSimpleName(method)); return callExp; } public MethodInvocation newMethodInvocation(String obj, String method, Expression arg0) { return newMethodInvocation(newSimpleName(obj), method, arg0); } public MethodInvocation newMethodInvocation(Expression exp, String method, Expression arg0) { MethodInvocation callExp = newMethodInvocation(exp, method); callExp.arguments().add(arg0); return callExp; } public MethodInvocation newMethodInvocation(String obj, String method, Expression arg0, Expression arg1) { return newMethodInvocation(newSimpleName(obj), method, arg0, arg1); } public MethodInvocation newMethodInvocation(Expression exp, String method, Expression arg0, Expression arg1) { MethodInvocation callExp = newMethodInvocation(exp, method, arg0); callExp.arguments().add(arg1); return callExp; } public MethodInvocation newMethodInvocation(String obj, String method, Expression arg0, Expression arg1, Expression arg2) { return newMethodInvocation(newSimpleName(obj), method, arg0, arg1, arg2); } public MethodInvocation newMethodInvocation(Expression exp, String method, Expression arg0, Expression arg1, Expression arg2) { MethodInvocation callExp = newMethodInvocation(exp, method, arg0, arg1); callExp.arguments().add(arg2); return callExp; } public SuperMethodInvocation newSuperMethodInvocation(String method) { SuperMethodInvocation callExp = ast.newSuperMethodInvocation(); callExp.setName(ast.newSimpleName(method)); return callExp; } public SuperMethodInvocation newSuperMethodInvocation(String method, Expression arg0) { SuperMethodInvocation callExp = newSuperMethodInvocation(method); callExp.arguments().add(arg0); return callExp; } public ConstructorInvocation newConstructorInvocation() { return ast.newConstructorInvocation(); } public ConstructorInvocation newConstructorInvocation(Expression arg0) { ConstructorInvocation callExp = newConstructorInvocation(); callExp.arguments().add(arg0); return callExp; } public ConstructorInvocation newConstructorInvocation(Expression arg0, Expression arg1) { ConstructorInvocation callExp = newConstructorInvocation(arg0); callExp.arguments().add(arg1); return callExp; } public SuperConstructorInvocation newSuperConstructorInvocation() { return ast.newSuperConstructorInvocation(); } public SuperConstructorInvocation newSuperConstructorInvocation(Expression arg0) { SuperConstructorInvocation callExp = newSuperConstructorInvocation(); callExp.arguments().add(arg0); return callExp; } public SuperConstructorInvocation newSuperConstructorInvocation(Expression arg0, Expression arg1) { SuperConstructorInvocation callExp = newSuperConstructorInvocation(arg0); callExp.arguments().add(arg1); return callExp; } public Expression newValueOfMethodInvocation(Expression stringExp, String primitiveType) { MethodInvocation callExp; if (primitiveType.equals("boolean")) { callExp = newMethodInvocation("java.lang.Boolean", "valueOf"); callExp.arguments().add(stringExp); return newMethodInvocation(callExp, "booleanValue"); } else if (primitiveType.equals("byte")) { callExp = newMethodInvocation("java.lang.Byte", "valueOf"); callExp.arguments().add(stringExp); return newMethodInvocation(callExp, "byteValue"); } else if (primitiveType.equals("char")) { callExp = newMethodInvocation(newParenthesizedExpression(stringExp), "charAt"); callExp.arguments().add(newLiteral(0)); return callExp; } else if (primitiveType.equals("double")) { callExp = newMethodInvocation("java.lang.Double", "valueOf"); callExp.arguments().add(stringExp); return newMethodInvocation(callExp, "doubleValue"); } else if (primitiveType.equals("float")) { callExp = newMethodInvocation("java.lang.Float", "valueOf"); callExp.arguments().add(stringExp); return newMethodInvocation(callExp, "floatValue"); } else if (primitiveType.equals("int")) { callExp = newMethodInvocation("java.lang.Integer", "valueOf"); callExp.arguments().add(stringExp); return newMethodInvocation(callExp, "intValue"); } else if (primitiveType.equals("long")) { callExp = newMethodInvocation("java.lang.Long", "valueOf"); callExp.arguments().add(stringExp); return newMethodInvocation(callExp, "longValue"); } else if (primitiveType.equals("short")) { callExp = newMethodInvocation("java.lang.Short", "valueOf"); callExp.arguments().add(stringExp); return newMethodInvocation(callExp, "shortValue"); } else if (primitiveType.endsWith("java.lang.Date")) { return newMethodInvocation( StringUtils.class.getName(), "parseDate", stringExp); } else if (primitiveType.endsWith("Enum.Value")) { return newMethodInvocation( newFieldAccess(primitiveType.substring(0,primitiveType.lastIndexOf('.')), "instance"), "valueOf", stringExp); } else if (primitiveType.equals(EntityDescriptor.class.getName())) { return newMethodInvocation( newFieldAccess(generator.specificEntityDescriptorEnumName(), "instance"), "valueOf", stringExp); } else if (StringUtils.isString(primitiveType)) return stringExp; throw new IllegalArgumentException(primitiveType); } public Expression newToStringMethodInvocation(Expression exp) { MethodInvocation callExp = newMethodInvocation(StringUtils.class.getName(), "toString"); callExp.arguments().add(exp); return callExp; } public Block newBlock() { return block = ast.newBlock(); } public void addStatement(Expression exp) { block.statements().add(newExpressionStatement(exp)); } public void addStatement(Statement stm) { block.statements().add(stm); } public void addStatement(MethodDeclaration method, Expression exp) { addStatement(method, newExpressionStatement(exp)); } public void addStatement(MethodDeclaration method, Statement stm) { method.getBody().statements().add(stm); } public Initializer newInitializer(Block body) { Initializer initializer = ast.newInitializer(); initializer.setBody(body); return initializer; } public EmptyStatement newEmptyStatement() { return ast.newEmptyStatement(); } public ExpressionStatement newExpressionStatement(Expression exp) { return ast.newExpressionStatement(exp); } public IfStatement newIfStatement(Expression exp) { IfStatement stm = ast.newIfStatement(); stm.setExpression(exp); return stm; } public IfStatement newIfStatement(Expression exp, Statement thenStm) { IfStatement stm = newIfStatement(exp); stm.setThenStatement(thenStm); return stm; } public IfStatement newIfStatement(Expression exp, Statement thenStm, Statement elseStm) { IfStatement stm = newIfStatement(exp, thenStm); stm.setElseStatement(elseStm); return stm; } public SwitchStatement newSwitchStatement(Expression exp) { SwitchStatement stm = ast.newSwitchStatement(); stm.setExpression(exp); return stm; } public SwitchCase newCaseStatement(Expression exp) { SwitchCase stm = ast.newSwitchCase(); stm.setExpression(exp); return stm; } public SwitchCase newDefaultCaseStatement() { SwitchCase stm = ast.newSwitchCase(); stm.setExpression(null); return stm; } public WhileStatement newWhileStatement(Expression exp) { WhileStatement stm = ast.newWhileStatement(); stm.setExpression(exp); return stm; } public WhileStatement newWhileStatement(Expression exp, Statement body) { WhileStatement stm = newWhileStatement(exp); stm.setBody(body); return stm; } public DoStatement newDoStatement(Expression exp) { DoStatement stm = ast.newDoStatement(); stm.setExpression(exp); return stm; } public DoStatement newDoStatement(Expression exp, Statement body) { DoStatement stm = newDoStatement(exp); stm.setBody(body); return stm; } public ForStatement newForStatement(Expression exp, Statement body) { ForStatement stm = ast.newForStatement(); stm.setExpression(exp); stm.setBody(body); return stm; } public ForStatement newForStatement(Expression initializer, Expression exp, Expression updater, Statement body) { ForStatement stm = ast.newForStatement(); stm.initializers().add(initializer); stm.setExpression(exp); stm.updaters().add(updater); stm.setBody(body); return stm; } public EnhancedForStatement newEnhancedForStatement(SingleVariableDeclaration parameter, Expression exp, Statement body) { EnhancedForStatement stm = ast.newEnhancedForStatement(); stm.setParameter(parameter); stm.setExpression(exp); stm.setBody(body); return stm; } public BooleanLiteral newLiteral(boolean value) { return ast.newBooleanLiteral(value); } public NumberLiteral newLiteral(byte value) { return ast.newNumberLiteral(Byte.toString(value)); } public CharacterLiteral newLiteral(char value) { CharacterLiteral str = ast.newCharacterLiteral(); str.setCharValue(value); return str; } public NumberLiteral newLiteral(double value) { return ast.newNumberLiteral(String.valueOf(value)); } public NumberLiteral newLiteral(float value) { return ast.newNumberLiteral(String.valueOf(value)); } public NumberLiteral newLiteral(int value) { return ast.newNumberLiteral(String.valueOf(value)); } public NumberLiteral newLiteral(long value) { return ast.newNumberLiteral(String.valueOf(value)); } public NumberLiteral newLiteral(short value) { return ast.newNumberLiteral(Short.toString(value)); } public StringLiteral newLiteral(String text) { StringLiteral str = ast.newStringLiteral(); str.setLiteralValue(text); return str; } public NumberLiteral newLiteral(Date value) { return newLiteral(value.getTime()); } public StringLiteral newLiteral(EnumValue value) { return newLiteral(value.getName()); } public Expression newLiteral(Object value) { if (value instanceof String) return newLiteral((String) value); else if (value instanceof EnumValue) return newLiteral((EnumValue) value); else if (value instanceof Date) return newLiteral((Date) value); else if (value instanceof Boolean) return ast.newBooleanLiteral(((Boolean) value).booleanValue()); else return ast.newNumberLiteral(value.toString()); } public NumberLiteral newNumberLiteral(String value) { return ast.newNumberLiteral(value); } public NullLiteral newNullLiteral() { return ast.newNullLiteral(); } public TypeLiteral newTypeLiteral(String type) { TypeLiteral typeLiteral = ast.newTypeLiteral(); typeLiteral.setType(newType(type)); return typeLiteral; } public TypeLiteral newQualifiedTypeLiteral(String type) { TypeLiteral typeLiteral = ast.newTypeLiteral(); typeLiteral.setType(newQualifiedType(type)); return typeLiteral; } public Expression newWrapperInstanceCreation(String literalType, String name) { return newWrapperInstanceCreation(literalType, newSimpleName(name)); } public Expression newWrapperInstanceCreation(String literalType, Expression literalExp) { ClassInstanceCreation exp; if (literalType.equals("boolean")) { exp = newClassInstanceCreation("java.lang.Boolean"); } else if (literalType.equals("byte")) { exp = newClassInstanceCreation("java.lang.Byte"); } else if (literalType.equals("char")) { exp = newClassInstanceCreation("java.lang.Character"); } else if (literalType.equals("double")) { exp = newClassInstanceCreation("java.lang.Double"); } else if (literalType.equals("float")) { exp = newClassInstanceCreation("java.lang.Float"); } else if (literalType.equals("int")) { exp = newClassInstanceCreation("java.lang.Integer"); } else if (literalType.equals("long")) { exp = newClassInstanceCreation("java.lang.Long"); } else if (literalType.equals("short")) { exp = newClassInstanceCreation("java.lang.Short"); } else return literalExp; exp.arguments().add(literalExp); return exp; } public Expression newUnwrapperExpression(String literalType, String name, boolean useQualifiedType) { return newUnwrapperExpression(literalType, newSimpleName(name), useQualifiedType); } public Expression newUnwrapperExpression(String literalType, Expression literalExp, boolean useQualifiedType) { String wrapperType; String unwrapMethod; Expression exp; if (literalType.equals("boolean")) { wrapperType = "java.lang.Boolean"; unwrapMethod = "booleanValue"; } else if (literalType.equals("byte")) { wrapperType = "java.lang.Byte"; unwrapMethod = "byteValue"; } else if (literalType.equals("char")) { wrapperType = "java.lang.Character"; unwrapMethod = "charValue"; } else if (literalType.equals("double")) { wrapperType = "java.lang.Double"; unwrapMethod = "doubleValue"; } else if (literalType.equals("float")) { wrapperType = "java.lang.Float"; unwrapMethod = "floatValue"; } else if (literalType.equals("int")) { wrapperType = "java.lang.Integer"; unwrapMethod = "intValue"; } else if (literalType.equals("long")) { wrapperType = "java.lang.Long"; unwrapMethod = "longValue"; exp = newClassInstanceCreation("java.lang.Long"); } else if (literalType.equals("short")) { wrapperType = "java.lang.Short"; unwrapMethod = "shortValue"; exp = newClassInstanceCreation("java.lang.Short"); } else if (!literalType.equals("java.lang.Object")) { return newCastExpression(useQualifiedType ? newQualifiedType(literalType) : newType(literalType), literalExp); } else return literalExp; exp = newMethodInvocation(newParenthesizedExpression(newCastExpression(wrapperType, literalExp)), unwrapMethod); return exp; } @Override public EntityDescriptor<?> wGetEntityDescriptor() { throw new UnsupportedOperationException(); } }