Search in sources :

Example 11 with AnnotationMetadata

use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.

the class ToStringMetadataProviderImpl method getMetadata.

@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
    final ToStringAnnotationValues annotationValues = new ToStringAnnotationValues(governorPhysicalTypeMetadata);
    if (!annotationValues.isAnnotationFound()) {
        return null;
    }
    final MemberDetails memberDetails = getMemberDetails(governorPhysicalTypeMetadata);
    if (memberDetails == null || memberDetails.getFields().isEmpty()) {
        return null;
    }
    AnnotationMetadata javaBeanAnnotation = memberDetails.getAnnotation(ROO_JAVA_BEAN);
    if (javaBeanAnnotation != null) {
        // Return an empty metadata as @RooJavaBean do the work
        return new ToStringMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, new ArrayList<FieldMetadata>(), true);
    }
    // Exclude fields which are in superclass
    List<FieldMetadata> toStringFields = getToStringFields(governorPhysicalTypeMetadata, memberDetails.getFields());
    return new ToStringMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, toStringFields, false);
}
Also used : FieldMetadata(org.springframework.roo.classpath.details.FieldMetadata) MemberDetails(org.springframework.roo.classpath.scanner.MemberDetails) AnnotationMetadata(org.springframework.roo.classpath.details.annotations.AnnotationMetadata)

Example 12 with AnnotationMetadata

use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.

the class JpaEntityMetadata method getTableAnnotation.

/**
 * Generates the JPA @Table annotation to be applied to the entity
 *
 * @param annotationValues
 * @return
 */
private AnnotationMetadata getTableAnnotation() {
    final AnnotationMetadata tableAnnotation = getTypeAnnotation(TABLE);
    if (tableAnnotation == null) {
        return null;
    }
    final String catalog = annotationValues.getCatalog();
    final String schema = annotationValues.getSchema();
    final String table = annotationValues.getTable();
    if (StringUtils.isNotBlank(table) || StringUtils.isNotBlank(schema) || StringUtils.isNotBlank(catalog)) {
        final AnnotationMetadataBuilder tableBuilder = new AnnotationMetadataBuilder(tableAnnotation);
        if (StringUtils.isNotBlank(catalog)) {
            tableBuilder.addStringAttribute("catalog", catalog);
        }
        if (StringUtils.isNotBlank(schema)) {
            tableBuilder.addStringAttribute("schema", schema);
        }
        if (StringUtils.isNotBlank(table)) {
            tableBuilder.addStringAttribute("name", table);
        }
        return tableBuilder.build();
    }
    return null;
}
Also used : AnnotationMetadata(org.springframework.roo.classpath.details.annotations.AnnotationMetadata) AnnotationMetadataBuilder(org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder)

Example 13 with AnnotationMetadata

use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.

the class JavaParserAnnotationMetadataBuilder method convert.

private AnnotationAttributeValue<?> convert(JavaSymbolName annotationName, final Expression expression, final CompilationUnitServices compilationUnitServices) {
    if (annotationName == null) {
        annotationName = new JavaSymbolName("__ARRAY_ELEMENT__");
    }
    if (expression instanceof AnnotationExpr) {
        final AnnotationExpr annotationExpr = (AnnotationExpr) expression;
        final AnnotationMetadata value = getInstance(annotationExpr, compilationUnitServices).build();
        return new NestedAnnotationAttributeValue(annotationName, value);
    }
    if (expression instanceof BooleanLiteralExpr) {
        final boolean value = ((BooleanLiteralExpr) expression).getValue();
        return new BooleanAttributeValue(annotationName, value);
    }
    if (expression instanceof CharLiteralExpr) {
        final String value = ((CharLiteralExpr) expression).getValue();
        Validate.isTrue(value.length() == 1, "Expected a char expression, but instead received '%s' for attribute '%s'", value, annotationName);
        final char c = value.charAt(0);
        return new CharAttributeValue(annotationName, c);
    }
    if (expression instanceof LongLiteralExpr) {
        String value = ((LongLiteralExpr) expression).getValue();
        Validate.isTrue(value.toUpperCase().endsWith("L"), "Expected long literal expression '%s' to end in 'l' or 'L'", value);
        value = value.substring(0, value.length() - 1);
        final long l = new Long(value);
        return new LongAttributeValue(annotationName, l);
    }
    if (expression instanceof IntegerLiteralExpr) {
        final String value = ((IntegerLiteralExpr) expression).getValue();
        final int i = new Integer(value);
        return new IntegerAttributeValue(annotationName, i);
    }
    if (expression instanceof DoubleLiteralExpr) {
        String value = ((DoubleLiteralExpr) expression).getValue();
        boolean floatingPrecisionOnly = false;
        if (value.toUpperCase().endsWith("F")) {
            value = value.substring(0, value.length() - 1);
            floatingPrecisionOnly = true;
        }
        if (value.toUpperCase().endsWith("D")) {
            value = value.substring(0, value.length() - 1);
        }
        final double d = new Double(value);
        return new DoubleAttributeValue(annotationName, d, floatingPrecisionOnly);
    }
    if (expression instanceof BinaryExpr) {
        String result = "";
        BinaryExpr current = (BinaryExpr) expression;
        while (current != null) {
            String right = "";
            if (current.getRight() instanceof StringLiteralExpr) {
                right = ((StringLiteralExpr) current.getRight()).getValue();
            } else if (current.getRight() instanceof NameExpr) {
                right = ((NameExpr) current.getRight()).getName();
            }
            result = right + result;
            if (current.getLeft() instanceof StringLiteralExpr) {
                final String left = ((StringLiteralExpr) current.getLeft()).getValue();
                result = left + result;
            }
            if (current.getLeft() instanceof BinaryExpr) {
                current = (BinaryExpr) current.getLeft();
            } else {
                current = null;
            }
        }
        return new StringAttributeValue(annotationName, result);
    }
    if (expression instanceof StringLiteralExpr) {
        final String value = ((StringLiteralExpr) expression).getValue();
        return new StringAttributeValue(annotationName, value);
    }
    if (expression instanceof FieldAccessExpr) {
        final FieldAccessExpr field = (FieldAccessExpr) expression;
        final String fieldName = field.getField();
        // Determine the type
        final Expression scope = field.getScope();
        NameExpr nameToFind = null;
        if (scope instanceof FieldAccessExpr) {
            final FieldAccessExpr fScope = (FieldAccessExpr) scope;
            nameToFind = JavaParserUtils.getNameExpr(fScope.toString());
        } else if (scope instanceof NameExpr) {
            nameToFind = (NameExpr) scope;
        } else {
            throw new UnsupportedOperationException("A FieldAccessExpr for '" + field.getScope() + "' should return a NameExpr or FieldAccessExpr (was " + field.getScope().getClass().getName() + ")");
        }
        final JavaType fieldType = JavaParserUtils.getJavaType(compilationUnitServices, nameToFind, null);
        final EnumDetails enumDetails = new EnumDetails(fieldType, new JavaSymbolName(fieldName));
        return new EnumAttributeValue(annotationName, enumDetails);
    }
    if (expression instanceof NameExpr) {
        final NameExpr field = (NameExpr) expression;
        final String name = field.getName();
        // As we have no way of finding out the real type
        final JavaType fieldType = new JavaType("unknown.Object");
        final EnumDetails enumDetails = new EnumDetails(fieldType, new JavaSymbolName(name));
        return new EnumAttributeValue(annotationName, enumDetails);
    }
    if (expression instanceof ClassExpr) {
        final ClassExpr clazz = (ClassExpr) expression;
        final Type nameToFind = clazz.getType();
        final JavaType javaType = JavaParserUtils.getJavaType(compilationUnitServices, nameToFind, null);
        return new ClassAttributeValue(annotationName, javaType);
    }
    if (expression instanceof ArrayInitializerExpr) {
        final ArrayInitializerExpr castExp = (ArrayInitializerExpr) expression;
        final List<AnnotationAttributeValue<?>> arrayElements = new ArrayList<AnnotationAttributeValue<?>>();
        for (final Expression e : castExp.getValues()) {
            arrayElements.add(convert(null, e, compilationUnitServices));
        }
        return new ArrayAttributeValue<AnnotationAttributeValue<?>>(annotationName, arrayElements);
    }
    if (expression instanceof UnaryExpr) {
        final UnaryExpr castExp = (UnaryExpr) expression;
        if (castExp.getOperator() == Operator.negative) {
            String value = castExp.toString();
            value = value.toUpperCase().endsWith("L") ? value.substring(0, value.length() - 1) : value;
            final long l = new Long(value);
            return new LongAttributeValue(annotationName, l);
        } else {
            throw new UnsupportedOperationException("Only negative operator in UnaryExpr is supported");
        }
    }
    throw new UnsupportedOperationException("Unable to parse annotation attribute '" + annotationName + "' due to unsupported annotation expression '" + expression.getClass().getName() + "'");
}
Also used : IntegerLiteralExpr(com.github.antlrjavaparser.api.expr.IntegerLiteralExpr) ClassAttributeValue(org.springframework.roo.classpath.details.annotations.ClassAttributeValue) AnnotationExpr(com.github.antlrjavaparser.api.expr.AnnotationExpr) MarkerAnnotationExpr(com.github.antlrjavaparser.api.expr.MarkerAnnotationExpr) SingleMemberAnnotationExpr(com.github.antlrjavaparser.api.expr.SingleMemberAnnotationExpr) NormalAnnotationExpr(com.github.antlrjavaparser.api.expr.NormalAnnotationExpr) DoubleAttributeValue(org.springframework.roo.classpath.details.annotations.DoubleAttributeValue) StringLiteralExpr(com.github.antlrjavaparser.api.expr.StringLiteralExpr) NameExpr(com.github.antlrjavaparser.api.expr.NameExpr) ArrayList(java.util.ArrayList) CharAttributeValue(org.springframework.roo.classpath.details.annotations.CharAttributeValue) EnumDetails(org.springframework.roo.model.EnumDetails) EnumAttributeValue(org.springframework.roo.classpath.details.annotations.EnumAttributeValue) AnnotationMetadata(org.springframework.roo.classpath.details.annotations.AnnotationMetadata) JavaSymbolName(org.springframework.roo.model.JavaSymbolName) ArrayInitializerExpr(com.github.antlrjavaparser.api.expr.ArrayInitializerExpr) BooleanLiteralExpr(com.github.antlrjavaparser.api.expr.BooleanLiteralExpr) LongLiteralExpr(com.github.antlrjavaparser.api.expr.LongLiteralExpr) FieldAccessExpr(com.github.antlrjavaparser.api.expr.FieldAccessExpr) StringAttributeValue(org.springframework.roo.classpath.details.annotations.StringAttributeValue) NestedAnnotationAttributeValue(org.springframework.roo.classpath.details.annotations.NestedAnnotationAttributeValue) ArrayAttributeValue(org.springframework.roo.classpath.details.annotations.ArrayAttributeValue) AnnotationAttributeValue(org.springframework.roo.classpath.details.annotations.AnnotationAttributeValue) NestedAnnotationAttributeValue(org.springframework.roo.classpath.details.annotations.NestedAnnotationAttributeValue) BinaryExpr(com.github.antlrjavaparser.api.expr.BinaryExpr) IntegerAttributeValue(org.springframework.roo.classpath.details.annotations.IntegerAttributeValue) CharLiteralExpr(com.github.antlrjavaparser.api.expr.CharLiteralExpr) UnaryExpr(com.github.antlrjavaparser.api.expr.UnaryExpr) BooleanAttributeValue(org.springframework.roo.classpath.details.annotations.BooleanAttributeValue) JavaType(org.springframework.roo.model.JavaType) JavaType(org.springframework.roo.model.JavaType) Type(com.github.antlrjavaparser.api.type.Type) LongAttributeValue(org.springframework.roo.classpath.details.annotations.LongAttributeValue) DoubleLiteralExpr(com.github.antlrjavaparser.api.expr.DoubleLiteralExpr) Expression(com.github.antlrjavaparser.api.expr.Expression) ClassExpr(com.github.antlrjavaparser.api.expr.ClassExpr)

Example 14 with AnnotationMetadata

use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.

the class JavaParserFieldMetadataBuilder method addField.

public static void addField(final CompilationUnitServices compilationUnitServices, final List<BodyDeclaration> members, final FieldMetadata field) {
    Validate.notNull(compilationUnitServices, "Flushable compilation unit services required");
    Validate.notNull(members, "Members required");
    Validate.notNull(field, "Field required");
    JavaParserUtils.importTypeIfRequired(compilationUnitServices.getEnclosingTypeName(), compilationUnitServices.getImports(), field.getFieldType());
    final Type initType = JavaParserUtils.getResolvedName(compilationUnitServices.getEnclosingTypeName(), field.getFieldType(), compilationUnitServices);
    final ClassOrInterfaceType finalType = JavaParserUtils.getClassOrInterfaceType(initType);
    final FieldDeclaration newField = ASTHelper.createFieldDeclaration(JavaParserUtils.getJavaParserModifier(field.getModifier()), initType, field.getFieldName().getSymbolName());
    // Add parameterized types for the field type (not initializer)
    if (field.getFieldType().getParameters().size() > 0) {
        final List<Type> fieldTypeArgs = new ArrayList<Type>();
        finalType.setTypeArgs(fieldTypeArgs);
        for (final JavaType parameter : field.getFieldType().getParameters()) {
            fieldTypeArgs.add(JavaParserUtils.importParametersForType(compilationUnitServices.getEnclosingTypeName(), compilationUnitServices.getImports(), parameter));
        }
    }
    final List<VariableDeclarator> vars = newField.getVariables();
    Validate.notEmpty(vars, "Expected ASTHelper to have provided a single VariableDeclarator");
    Validate.isTrue(vars.size() == 1, "Expected ASTHelper to have provided a single VariableDeclarator");
    final VariableDeclarator vd = vars.iterator().next();
    if (StringUtils.isNotBlank(field.getFieldInitializer())) {
        // There is an initializer.
        // We need to make a fake field that we can have JavaParser parse.
        // Easiest way to do that is to build a simple source class
        // containing the required field and re-parse it.
        final StringBuilder sb = new StringBuilder();
        sb.append("class TemporaryClass {\n");
        sb.append("  private " + field.getFieldType() + " " + field.getFieldName() + " = " + field.getFieldInitializer() + ";\n");
        sb.append("}\n");
        final ByteArrayInputStream bais = new ByteArrayInputStream(sb.toString().getBytes());
        CompilationUnit ci;
        try {
            ci = JavaParser.parse(bais);
        } catch (final IOException e) {
            throw new IllegalStateException("Illegal state: Unable to parse input stream", e);
        } catch (final ParseException pe) {
            throw new IllegalStateException("Illegal state: JavaParser did not parse correctly", pe);
        }
        final List<TypeDeclaration> types = ci.getTypes();
        if (types == null || types.size() != 1) {
            throw new IllegalArgumentException("Field member invalid");
        }
        final TypeDeclaration td = types.get(0);
        final List<BodyDeclaration> bodyDeclarations = td.getMembers();
        if (bodyDeclarations == null || bodyDeclarations.size() != 1) {
            throw new IllegalStateException("Illegal state: JavaParser did not return body declarations correctly");
        }
        final BodyDeclaration bd = bodyDeclarations.get(0);
        if (!(bd instanceof FieldDeclaration)) {
            throw new IllegalStateException("Illegal state: JavaParser did not return a field declaration correctly");
        }
        final FieldDeclaration fd = (FieldDeclaration) bd;
        if (fd.getVariables() == null || fd.getVariables().size() != 1) {
            throw new IllegalStateException("Illegal state: JavaParser did not return a field declaration correctly");
        }
        final Expression init = fd.getVariables().get(0).getInit();
        // Resolve imports (ROO-1505)
        if (init instanceof ObjectCreationExpr) {
            final ObjectCreationExpr ocr = (ObjectCreationExpr) init;
            final JavaType typeToImport = JavaParserUtils.getJavaTypeNow(compilationUnitServices, ocr.getType(), null);
            final NameExpr nameExpr = JavaParserUtils.importTypeIfRequired(compilationUnitServices.getEnclosingTypeName(), compilationUnitServices.getImports(), typeToImport);
            final ClassOrInterfaceType classOrInterfaceType = JavaParserUtils.getClassOrInterfaceType(nameExpr);
            ocr.setType(classOrInterfaceType);
            if (typeToImport.getParameters().size() > 0) {
                final List<Type> initTypeArgs = new ArrayList<Type>();
                finalType.setTypeArgs(initTypeArgs);
                for (final JavaType parameter : typeToImport.getParameters()) {
                    initTypeArgs.add(JavaParserUtils.importParametersForType(compilationUnitServices.getEnclosingTypeName(), compilationUnitServices.getImports(), parameter));
                }
                classOrInterfaceType.setTypeArgs(initTypeArgs);
            }
        }
        vd.setInit(init);
    }
    // Add annotations
    final List<AnnotationExpr> annotations = new ArrayList<AnnotationExpr>();
    newField.setAnnotations(annotations);
    for (final AnnotationMetadata annotation : field.getAnnotations()) {
        JavaParserAnnotationMetadataBuilder.addAnnotationToList(compilationUnitServices, annotations, annotation);
    }
    // ROO-3678: Add-on which include new field should be the responsible to check if field
    // exists, not JavaParser.
    /*// Locate where to add this field; also verify if this field already
    // exists
    int nextFieldIndex = 0;
    int i = -1;
    for (final BodyDeclaration bd : members) {
        i++;
        if (bd instanceof FieldDeclaration) {
            // Next field should appear after this current field
            nextFieldIndex = i + 1;
            final FieldDeclaration bdf = (FieldDeclaration) bd;
            for (final VariableDeclarator v : bdf.getVariables()) {
                Validate.isTrue(!field.getFieldName().getSymbolName()
                        .equals(v.getId().getName()),
                        "A field with name '%s' already exists", field
                                .getFieldName().getSymbolName());
            }
        }
    }*/
    int nextFieldIndex = 0;
    int i = -1;
    for (final BodyDeclaration bd : members) {
        i++;
        if (bd instanceof FieldDeclaration) {
            // Next field should appear after this current field
            nextFieldIndex = i + 1;
        }
    }
    if (field.getCommentStructure() != null) {
        // annotation
        if (annotations != null && annotations.size() > 0) {
            AnnotationExpr firstAnnotation = annotations.get(0);
            JavaParserCommentMetadataBuilder.updateCommentsToJavaParser(firstAnnotation, field.getCommentStructure());
        // Otherwise, add comments to the field declaration line
        } else {
            JavaParserCommentMetadataBuilder.updateCommentsToJavaParser(newField, field.getCommentStructure());
        }
    } else {
        // ROO-3834: Append default Javadoc if not exists a comment structure
        CommentStructure defaultCommentStructure = new CommentStructure();
        JavadocComment javadocComment = new JavadocComment("TODO Auto-generated attribute documentation");
        defaultCommentStructure.addComment(javadocComment, CommentLocation.BEGINNING);
        field.setCommentStructure(defaultCommentStructure);
        // annotation
        if (annotations != null && annotations.size() > 0) {
            AnnotationExpr firstAnnotation = annotations.get(0);
            JavaParserCommentMetadataBuilder.updateCommentsToJavaParser(firstAnnotation, defaultCommentStructure);
        // Otherwise, add comments to the field declaration line
        } else {
            JavaParserCommentMetadataBuilder.updateCommentsToJavaParser(newField, defaultCommentStructure);
        }
    }
    // Add the field to the compilation unit
    members.add(nextFieldIndex, newField);
}
Also used : ObjectCreationExpr(com.github.antlrjavaparser.api.expr.ObjectCreationExpr) AnnotationExpr(com.github.antlrjavaparser.api.expr.AnnotationExpr) ArrayList(java.util.ArrayList) NameExpr(com.github.antlrjavaparser.api.expr.NameExpr) ClassOrInterfaceType(com.github.antlrjavaparser.api.type.ClassOrInterfaceType) FieldDeclaration(com.github.antlrjavaparser.api.body.FieldDeclaration) AnnotationMetadata(org.springframework.roo.classpath.details.annotations.AnnotationMetadata) CommentStructure(org.springframework.roo.classpath.details.comments.CommentStructure) VariableDeclarator(com.github.antlrjavaparser.api.body.VariableDeclarator) JavadocComment(org.springframework.roo.classpath.details.comments.JavadocComment) CompilationUnit(com.github.antlrjavaparser.api.CompilationUnit) IOException(java.io.IOException) ClassOrInterfaceType(com.github.antlrjavaparser.api.type.ClassOrInterfaceType) JavaType(org.springframework.roo.model.JavaType) Type(com.github.antlrjavaparser.api.type.Type) JavaType(org.springframework.roo.model.JavaType) ByteArrayInputStream(java.io.ByteArrayInputStream) Expression(com.github.antlrjavaparser.api.expr.Expression) BodyDeclaration(com.github.antlrjavaparser.api.body.BodyDeclaration) ParseException(com.github.antlrjavaparser.ParseException) TypeDeclaration(com.github.antlrjavaparser.api.body.TypeDeclaration)

Example 15 with AnnotationMetadata

use of org.springframework.roo.classpath.details.annotations.AnnotationMetadata in project spring-roo by spring-projects.

the class JavaParserMethodMetadataBuilder method addMethod.

public static void addMethod(final CompilationUnitServices compilationUnitServices, final List<BodyDeclaration> members, final MethodMetadata method, Set<JavaSymbolName> typeParameters) {
    Validate.notNull(compilationUnitServices, "Flushable compilation unit services required");
    Validate.notNull(members, "Members required");
    Validate.notNull(method, "Method required");
    if (typeParameters == null) {
        typeParameters = new HashSet<JavaSymbolName>();
    }
    // Create the return type we should use
    Type returnType = null;
    if (method.getReturnType().isPrimitive()) {
        returnType = JavaParserUtils.getType(method.getReturnType());
    } else {
        final NameExpr importedType = JavaParserUtils.importTypeIfRequired(compilationUnitServices.getEnclosingTypeName(), compilationUnitServices.getImports(), method.getReturnType());
        final ClassOrInterfaceType cit = JavaParserUtils.getClassOrInterfaceType(importedType);
        // Add any type arguments presented for the return type
        if (method.getReturnType().getParameters().size() > 0) {
            final List<Type> typeArgs = new ArrayList<Type>();
            cit.setTypeArgs(typeArgs);
            for (final JavaType parameter : method.getReturnType().getParameters()) {
                typeArgs.add(JavaParserUtils.importParametersForType(compilationUnitServices.getEnclosingTypeName(), compilationUnitServices.getImports(), parameter));
            }
        }
        // Handle arrays
        if (method.getReturnType().isArray()) {
            final ReferenceType rt = new ReferenceType();
            rt.setArrayCount(method.getReturnType().getArray());
            rt.setType(cit);
            returnType = rt;
        } else {
            returnType = cit;
        }
    }
    // Start with the basic method
    final MethodDeclaration d = new MethodDeclaration();
    d.setModifiers(JavaParserUtils.getJavaParserModifier(method.getModifier()));
    d.setName(method.getMethodName().getSymbolName());
    d.setType(returnType);
    // Add any method-level annotations (not parameter annotations)
    final List<AnnotationExpr> annotations = new ArrayList<AnnotationExpr>();
    d.setAnnotations(annotations);
    for (final AnnotationMetadata annotation : method.getAnnotations()) {
        JavaParserAnnotationMetadataBuilder.addAnnotationToList(compilationUnitServices, annotations, annotation);
    }
    // Add any method parameters, including their individual annotations and
    // type parameters
    final List<Parameter> parameters = new ArrayList<Parameter>();
    d.setParameters(parameters);
    int index = -1;
    for (final AnnotatedJavaType methodParameter : method.getParameterTypes()) {
        index++;
        // Add the parameter annotations applicable for this parameter type
        final List<AnnotationExpr> parameterAnnotations = new ArrayList<AnnotationExpr>();
        for (final AnnotationMetadata parameterAnnotation : methodParameter.getAnnotations()) {
            JavaParserAnnotationMetadataBuilder.addAnnotationToList(compilationUnitServices, parameterAnnotations, parameterAnnotation);
        }
        // Compute the parameter name
        final String parameterName = method.getParameterNames().get(index).getSymbolName();
        // Compute the parameter type
        Type parameterType = null;
        if (methodParameter.getJavaType().isPrimitive()) {
            parameterType = JavaParserUtils.getType(methodParameter.getJavaType());
        } else {
            final NameExpr type = JavaParserUtils.importTypeIfRequired(compilationUnitServices.getEnclosingTypeName(), compilationUnitServices.getImports(), methodParameter.getJavaType());
            final ClassOrInterfaceType cit = JavaParserUtils.getClassOrInterfaceType(type);
            // Add any type arguments presented for the return type
            if (methodParameter.getJavaType().getParameters().size() > 0) {
                final List<Type> typeArgs = new ArrayList<Type>();
                cit.setTypeArgs(typeArgs);
                for (final JavaType parameter : methodParameter.getJavaType().getParameters()) {
                    typeArgs.add(JavaParserUtils.importParametersForType(compilationUnitServices.getEnclosingTypeName(), compilationUnitServices.getImports(), parameter));
                }
            }
            // Handle arrays
            if (methodParameter.getJavaType().isArray()) {
                final ReferenceType rt = new ReferenceType();
                rt.setArrayCount(methodParameter.getJavaType().getArray());
                rt.setType(cit);
                parameterType = rt;
            } else {
                parameterType = cit;
            }
        }
        // Create a Java Parser method parameter and add it to the list of
        // parameters
        final Parameter p = new Parameter(parameterType, new VariableDeclaratorId(parameterName));
        p.setVarArgs(methodParameter.isVarArgs());
        p.setAnnotations(parameterAnnotations);
        parameters.add(p);
    }
    // Add exceptions which the method my throw
    if (method.getThrowsTypes().size() > 0) {
        final List<NameExpr> throwsTypes = new ArrayList<NameExpr>();
        for (final JavaType javaType : method.getThrowsTypes()) {
            final NameExpr importedType = JavaParserUtils.importTypeIfRequired(compilationUnitServices.getEnclosingTypeName(), compilationUnitServices.getImports(), javaType);
            throwsTypes.add(importedType);
        }
        d.setThrows(throwsTypes);
    }
    // Set the body
    if (StringUtils.isBlank(method.getBody())) {
        // Never set the body if an abstract method
        if (!Modifier.isAbstract(method.getModifier()) && !PhysicalTypeCategory.INTERFACE.equals(compilationUnitServices.getPhysicalTypeCategory())) {
            d.setBody(new BlockStmt());
        }
    } else {
        // There is a body.
        // We need to make a fake method that we can have JavaParser parse.
        // Easiest way to do that is to build a simple source class
        // containing the required method and re-parse it.
        final StringBuilder sb = new StringBuilder();
        sb.append("class TemporaryClass {\n");
        sb.append("  public void temporaryMethod() {\n");
        sb.append(method.getBody());
        sb.append("\n");
        sb.append("  }\n");
        sb.append("}\n");
        final ByteArrayInputStream bais = new ByteArrayInputStream(sb.toString().getBytes());
        CompilationUnit ci;
        try {
            ci = JavaParser.parse(bais);
        } catch (final IOException e) {
            throw new IllegalStateException("Illegal state: Unable to parse input stream", e);
        } catch (final ParseException pe) {
            throw new IllegalStateException("Illegal state: JavaParser did not parse correctly", pe);
        }
        final List<TypeDeclaration> types = ci.getTypes();
        if (types == null || types.size() != 1) {
            throw new IllegalArgumentException("Method body invalid");
        }
        final TypeDeclaration td = types.get(0);
        final List<BodyDeclaration> bodyDeclarations = td.getMembers();
        if (bodyDeclarations == null || bodyDeclarations.size() != 1) {
            throw new IllegalStateException("Illegal state: JavaParser did not return body declarations correctly");
        }
        final BodyDeclaration bd = bodyDeclarations.get(0);
        if (!(bd instanceof MethodDeclaration)) {
            throw new IllegalStateException("Illegal state: JavaParser did not return a method declaration correctly");
        }
        final MethodDeclaration md = (MethodDeclaration) bd;
        d.setBody(md.getBody());
    }
    // ROO-3678: Add-on which include new method should be the responsible to check if method
    // exists, not JavaParser.
    /*// Locate where to add this method; also verify if this method already
    // exists
    for (final BodyDeclaration bd : members) {
        if (bd instanceof MethodDeclaration) {
            // Next method should appear after this current method
            final MethodDeclaration md = (MethodDeclaration) bd;
            /*if (md.getName().equals(d.getName())) {
                if ((md.getParameters() == null || md.getParameters()
                        .isEmpty())
                        && (d.getParameters() == null || d.getParameters()
                                .isEmpty())) {
                    throw new IllegalStateException("Method '"
                            + method.getMethodName().getSymbolName()
                            + "' already exists");
                }
                else if (md.getParameters() != null
                        && md.getParameters().size() == d.getParameters()
                                .size()) {
                    // Possible match, we need to consider parameter types
                    // as well now
                    final MethodMetadata methodMetadata = JavaParserMethodMetadataBuilder
                            .getInstance(method.getDeclaredByMetadataId(),
                                    md, compilationUnitServices,
                                    typeParameters).build();
                    boolean matchesFully = true;
                    index = -1;
                    for (final AnnotatedJavaType existingParameter : methodMetadata
                            .getParameterTypes()) {
                        index++;
                        final AnnotatedJavaType parameterType = method
                                .getParameterTypes().get(index);
                        if (!existingParameter.getJavaType().equals(
                                parameterType.getJavaType())) {
                            matchesFully = false;
                            break;
                        }
                    }
                    if (matchesFully) {
                        throw new IllegalStateException(
                                "Method '"
                                        + method.getMethodName()
                                                .getSymbolName()
                                        + "' already exists with identical parameters");
                    }
                }
            }
        }
    }*/
    // ROO-3834: Append Javadoc
    CommentStructure commentStructure = method.getCommentStructure();
    if (commentStructure != null) {
        // annotation
        if (annotations != null && annotations.size() > 0) {
            AnnotationExpr firstAnnotation = annotations.get(0);
            JavaParserCommentMetadataBuilder.updateCommentsToJavaParser(firstAnnotation, commentStructure);
        // Otherwise, add comments to the method declaration line
        } else {
            JavaParserCommentMetadataBuilder.updateCommentsToJavaParser(d, commentStructure);
        }
    } else {
        // ROO-3834: Include default documentation
        CommentStructure defaultCommentStructure = new CommentStructure();
        // ROO-3834: Append default Javadoc if not exists a comment structure,
        // including method params, return and throws.
        List<String> parameterNames = new ArrayList<String>();
        for (JavaSymbolName name : method.getParameterNames()) {
            parameterNames.add(name.getSymbolName());
        }
        List<String> throwsTypesNames = new ArrayList<String>();
        for (JavaType type : method.getThrowsTypes()) {
            throwsTypesNames.add(type.getSimpleTypeName());
        }
        String returnInfo = null;
        JavaType returnJavaType = method.getReturnType();
        if (!returnJavaType.equals(JavaType.VOID_OBJECT) && !returnJavaType.equals(JavaType.VOID_PRIMITIVE)) {
            returnInfo = returnJavaType.getSimpleTypeName();
        }
        JavadocComment javadocComment = new JavadocComment("TODO Auto-generated method documentation", parameterNames, returnInfo, throwsTypesNames);
        defaultCommentStructure.addComment(javadocComment, CommentLocation.BEGINNING);
        method.setCommentStructure(defaultCommentStructure);
        // annotation
        if (annotations != null && annotations.size() > 0) {
            AnnotationExpr firstAnnotation = annotations.get(0);
            JavaParserCommentMetadataBuilder.updateCommentsToJavaParser(firstAnnotation, defaultCommentStructure);
        // Otherwise, add comments to the method declaration line
        } else {
            JavaParserCommentMetadataBuilder.updateCommentsToJavaParser(d, defaultCommentStructure);
        }
    }
    // Add the method to the end of the compilation unit
    members.add(d);
}
Also used : AnnotationExpr(com.github.antlrjavaparser.api.expr.AnnotationExpr) NameExpr(com.github.antlrjavaparser.api.expr.NameExpr) ArrayList(java.util.ArrayList) ClassOrInterfaceType(com.github.antlrjavaparser.api.type.ClassOrInterfaceType) ReferenceType(com.github.antlrjavaparser.api.type.ReferenceType) AnnotationMetadata(org.springframework.roo.classpath.details.annotations.AnnotationMetadata) CommentStructure(org.springframework.roo.classpath.details.comments.CommentStructure) JavaSymbolName(org.springframework.roo.model.JavaSymbolName) VariableDeclaratorId(com.github.antlrjavaparser.api.body.VariableDeclaratorId) JavadocComment(org.springframework.roo.classpath.details.comments.JavadocComment) CompilationUnit(com.github.antlrjavaparser.api.CompilationUnit) MethodDeclaration(com.github.antlrjavaparser.api.body.MethodDeclaration) AnnotatedJavaType(org.springframework.roo.classpath.details.annotations.AnnotatedJavaType) BlockStmt(com.github.antlrjavaparser.api.stmt.BlockStmt) IOException(java.io.IOException) ClassOrInterfaceType(com.github.antlrjavaparser.api.type.ClassOrInterfaceType) AnnotatedJavaType(org.springframework.roo.classpath.details.annotations.AnnotatedJavaType) JavaType(org.springframework.roo.model.JavaType) ReferenceType(com.github.antlrjavaparser.api.type.ReferenceType) Type(com.github.antlrjavaparser.api.type.Type) AnnotatedJavaType(org.springframework.roo.classpath.details.annotations.AnnotatedJavaType) JavaType(org.springframework.roo.model.JavaType) ByteArrayInputStream(java.io.ByteArrayInputStream) TypeParameter(com.github.antlrjavaparser.api.TypeParameter) Parameter(com.github.antlrjavaparser.api.body.Parameter) BodyDeclaration(com.github.antlrjavaparser.api.body.BodyDeclaration) ParseException(com.github.antlrjavaparser.ParseException) TypeDeclaration(com.github.antlrjavaparser.api.body.TypeDeclaration)

Aggregations

AnnotationMetadata (org.springframework.roo.classpath.details.annotations.AnnotationMetadata)109 JavaType (org.springframework.roo.model.JavaType)59 ClassOrInterfaceTypeDetails (org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails)52 JavaSymbolName (org.springframework.roo.model.JavaSymbolName)47 ArrayList (java.util.ArrayList)40 RooJavaType (org.springframework.roo.model.RooJavaType)34 AnnotationMetadataBuilder (org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder)30 AnnotatedJavaType (org.springframework.roo.classpath.details.annotations.AnnotatedJavaType)24 FieldMetadata (org.springframework.roo.classpath.details.FieldMetadata)21 MemberDetails (org.springframework.roo.classpath.scanner.MemberDetails)20 List (java.util.List)19 ClassOrInterfaceTypeDetailsBuilder (org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder)19 MethodMetadata (org.springframework.roo.classpath.details.MethodMetadata)18 AnnotationAttributeValue (org.springframework.roo.classpath.details.annotations.AnnotationAttributeValue)17 NestedAnnotationAttributeValue (org.springframework.roo.classpath.details.annotations.NestedAnnotationAttributeValue)16 SpringJavaType (org.springframework.roo.model.SpringJavaType)15 JdkJavaType (org.springframework.roo.model.JdkJavaType)12 JpaJavaType (org.springframework.roo.model.JpaJavaType)12 ArrayAttributeValue (org.springframework.roo.classpath.details.annotations.ArrayAttributeValue)11 LinkedHashMap (java.util.LinkedHashMap)10