Search in sources :

Example 46 with FieldMetadata

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

the class RepositoryJpaCustomImplMetadataProviderImpl method getMetadata.

@Override
protected ItdTypeDetailsProvidingMetadataItem getMetadata(final String metadataIdentificationString, final JavaType aspectName, final PhysicalTypeMetadata governorPhysicalTypeMetadata, final String itdFilename) {
    final RepositoryJpaCustomImplAnnotationValues annotationValues = new RepositoryJpaCustomImplAnnotationValues(governorPhysicalTypeMetadata);
    // Getting repository custom
    JavaType repositoryCustom = annotationValues.getRepository();
    // Validate that contains repository interface
    Validate.notNull(repositoryCustom, "ERROR: You need to specify interface repository to be implemented.");
    ClassOrInterfaceTypeDetails repositoryDetails = getTypeLocationService().getTypeDetails(repositoryCustom);
    AnnotationMetadata repositoryCustomAnnotation = repositoryDetails.getAnnotation(ROO_REPOSITORY_JPA_CUSTOM);
    Validate.notNull(repositoryCustomAnnotation, "ERROR: Repository interface should be annotated with @RooJpaRepositoryCustom");
    AnnotationAttributeValue<JavaType> entityAttribute = repositoryCustomAnnotation.getAttribute("entity");
    Validate.notNull(entityAttribute, "ERROR: Repository interface should be contain an entity on @RooJpaRepositoryCustom annotation");
    JavaType entity = entityAttribute.getValue();
    RepositoryJpaMetadata repositoryMetadata = getRepositoryJpaLocator().getRepositoryMetadata(entity);
    if (repositoryMetadata == null) {
        // Can't generate it jet
        return null;
    }
    // Register downstream dependency for RepositoryJpaCustomImplMetadata to update projection
    // finders implementations
    String repositoryCustomMetadataKey = RepositoryJpaCustomMetadata.createIdentifier(repositoryDetails);
    registerDependency(repositoryCustomMetadataKey, metadataIdentificationString);
    ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(entity);
    // Check if default return type is a Projection
    JavaType returnType = repositoryMetadata.getDefaultReturnType();
    ClassOrInterfaceTypeDetails returnTypeDetails = getTypeLocationService().getTypeDetails(returnType);
    AnnotationMetadata entityProjectionAnnotation = returnTypeDetails.getAnnotation(RooJavaType.ROO_ENTITY_PROJECTION);
    boolean returnTypeIsProjection = entityProjectionAnnotation != null;
    // Get projection constructor fields from @RooEntityProjection and add it to a Map with
    // domain type's variable names
    Map<JavaType, List<Pair<String, String>>> typesFieldMaps = new LinkedHashMap<JavaType, List<Pair<String, String>>>();
    Map<JavaType, Boolean> typesAreProjections = new HashMap<JavaType, Boolean>();
    if (returnTypeIsProjection) {
        buildFieldNamesMap(entity, returnType, entityProjectionAnnotation, typesFieldMaps);
        typesAreProjections.put(returnType, true);
    }
    final RepositoryJpaCustomMetadata repositoryCustomMetadata = getMetadataService().get(repositoryCustomMetadataKey);
    // Prevent empty metadata
    if (repositoryCustomMetadata == null) {
        return null;
    }
    // Getting java bean metadata
    final String javaBeanMetadataKey = JavaBeanMetadata.createIdentifier(entityDetails);
    // Getting jpa entity metadata
    final String jpaEntityMetadataKey = JpaEntityMetadata.createIdentifier(entityDetails);
    JpaEntityMetadata entityMetadata = getMetadataService().get(jpaEntityMetadataKey);
    // Create dependency between repository and java bean annotation
    registerDependency(javaBeanMetadataKey, metadataIdentificationString);
    // Create dependency between repository and jpa entity annotation
    registerDependency(jpaEntityMetadataKey, metadataIdentificationString);
    // Getting entity properties
    MemberDetails entityMemberDetails = getMemberDetailsScanner().getMemberDetails(getClass().getName(), entityDetails);
    // Getting valid fields to construct the findAll query
    List<FieldMetadata> validFields = new ArrayList<FieldMetadata>();
    loadValidFields(entityMemberDetails, entityMetadata, validFields);
    // Getting all necessary information about referencedFields
    Map<FieldMetadata, MethodMetadata> referencedFieldsMethods = repositoryCustomMetadata.getReferencedFieldsFindAllMethods();
    Map<FieldMetadata, String> referencedFieldsIdentifierNames = new HashMap<FieldMetadata, String>();
    List<Pair<MethodMetadata, PartTree>> customFinderMethods = repositoryCustomMetadata.getCustomFinderMethods();
    List<Pair<MethodMetadata, PartTree>> customCountMethods = repositoryCustomMetadata.getCustomCountMethods();
    if (customCountMethods == null) {
        customCountMethods = new ArrayList<Pair<MethodMetadata, PartTree>>();
    }
    for (Entry<FieldMetadata, MethodMetadata> referencedFields : referencedFieldsMethods.entrySet()) {
        // Get identifier field name in path format
        String fieldPathName = String.format("%s.%s", StringUtils.uncapitalize(entity.getSimpleTypeName()), referencedFields.getKey().getFieldName().getSymbolNameUnCapitalisedFirstLetter());
        // Put keys and values in map
        referencedFieldsIdentifierNames.put(referencedFields.getKey(), fieldPathName);
    }
    // Add valid entity fields to mappings
    Map<JavaType, Map<String, FieldMetadata>> typesFieldsMetadataMap = new HashMap<JavaType, Map<String, FieldMetadata>>();
    Map<String, FieldMetadata> entityFieldMetadata = new LinkedHashMap<String, FieldMetadata>();
    List<Pair<String, String>> entityFieldMappings = new ArrayList<Pair<String, String>>();
    typesAreProjections.put(entity, false);
    for (FieldMetadata field : validFields) {
        entityFieldMetadata.put(field.getFieldName().getSymbolName(), field);
        entityFieldMappings.add(Pair.of(field.getFieldName().getSymbolName(), StringUtils.uncapitalize(entity.getSimpleTypeName()).concat(".").concat(field.getFieldName().getSymbolName())));
    }
    typesFieldsMetadataMap.put(entity, entityFieldMetadata);
    typesFieldMaps.put(entity, entityFieldMappings);
    // Make a list with all domain types, excepting entities
    List<JavaType> domainTypes = new ArrayList<JavaType>();
    domainTypes.add(returnType);
    for (Pair<MethodMetadata, PartTree> methodInfo : customFinderMethods) {
        // Get finder return type from first parameter of method return type (Page)
        JavaType finderReturnType = getDomainTypeOfFinderMethod(methodInfo.getKey());
        domainTypes.add(finderReturnType);
        // If type is a DTO, add finder fields to mappings
        JavaType parameterType = methodInfo.getKey().getParameterTypes().get(0).getJavaType();
        typesAreProjections.put(parameterType, false);
    }
    // Add typesFieldMaps for each projection finder and check for id fields
    for (JavaType type : domainTypes) {
        // Check if projection fields has been added already
        if (typesFieldMaps.containsKey(type)) {
            continue;
        }
        // Build Map with FieldMetadata of each projection
        ClassOrInterfaceTypeDetails typeDetails = getTypeLocationService().getTypeDetails(type);
        if (typeDetails == null) {
            LOGGER.warning("Detail not found for type: " + type);
            continue;
        }
        List<FieldMetadata> typeFieldList = getMemberDetailsScanner().getMemberDetails(this.getClass().getName(), typeDetails).getFields();
        Map<String, FieldMetadata> fieldMetadataMap = new LinkedHashMap<String, FieldMetadata>();
        for (FieldMetadata field : typeFieldList) {
            fieldMetadataMap.put(field.getFieldName().getSymbolName(), field);
        }
        typesFieldsMetadataMap.put(type, fieldMetadataMap);
        AnnotationMetadata projectionAnnotation = typeDetails.getAnnotation(RooJavaType.ROO_ENTITY_PROJECTION);
        if (projectionAnnotation != null) {
            typesAreProjections.put(type, true);
            // Type is a Projection
            JavaType associatedEntity = (JavaType) projectionAnnotation.getAttribute("entity").getValue();
            // Add fields to typesFieldMaps
            buildFieldNamesMap(associatedEntity, type, projectionAnnotation, typesFieldMaps);
        }
    }
    return new RepositoryJpaCustomImplMetadata(metadataIdentificationString, aspectName, governorPhysicalTypeMetadata, annotationValues, entity, entityMetadata, entityMetadata.getCurrentIndentifierField(), validFields, repositoryCustomMetadata.getCurrentFindAllGlobalSearchMethod(), repositoryCustomMetadata.getCurrentFindAllByIdsInGlobalSearchMethod(), repositoryCustomMetadata.getDefaultReturnType(), referencedFieldsMethods, referencedFieldsIdentifierNames, typesFieldMaps, customFinderMethods, customCountMethods, typesFieldsMetadataMap, typesAreProjections);
}
Also used : FieldMetadata(org.springframework.roo.classpath.details.FieldMetadata) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) AnnotationMetadata(org.springframework.roo.classpath.details.annotations.AnnotationMetadata) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) List(java.util.List) JpaEntityMetadata(org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata) Pair(org.apache.commons.lang3.tuple.Pair) RooJavaType(org.springframework.roo.model.RooJavaType) SpringJavaType(org.springframework.roo.model.SpringJavaType) JpaJavaType(org.springframework.roo.model.JpaJavaType) JavaType(org.springframework.roo.model.JavaType) MethodMetadata(org.springframework.roo.classpath.details.MethodMetadata) ClassOrInterfaceTypeDetails(org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails) MemberDetails(org.springframework.roo.classpath.scanner.MemberDetails) PartTree(org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 47 with FieldMetadata

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

the class RepositoryJpaMetadataProviderImpl method checkDtoFieldsForFinder.

/**
 * Validates that all dto fields matches with parameters on finder of a repository
 *
 * @param formBeanDetails
 * @param finder
 * @param repository
 */
private void checkDtoFieldsForFinder(ClassOrInterfaceTypeDetails formBeanDetails, PartTree finder, JavaType repository) {
    final JavaType dtoType = formBeanDetails.getName();
    final String finderName = finder.getOriginalQuery();
    FieldMetadata paramField, dtoField;
    JavaType paramType, dtoFieldType;
    for (FinderParameter param : finder.getParameters()) {
        paramField = param.getPath().peek();
        dtoField = formBeanDetails.getField(paramField.getFieldName());
        Validate.notNull(dtoField, "Field '%s' not found on DTO %s for finder '%s' of %s", paramField.getFieldName(), dtoType, finderName, repository);
        paramType = paramField.getFieldType().getBaseType();
        dtoFieldType = dtoField.getFieldType().getBaseType();
        Validate.isTrue(paramType.equals(dtoFieldType), "Type missmatch for field '%s' on DTO %s for finder '%s' of %s: excepted %s and got %s", dtoField.getFieldName(), dtoType, finderName, repository, paramType, dtoFieldType);
    }
}
Also used : RooJavaType(org.springframework.roo.model.RooJavaType) JavaType(org.springframework.roo.model.JavaType) FieldMetadata(org.springframework.roo.classpath.details.FieldMetadata) FinderParameter(org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.FinderParameter)

Example 48 with FieldMetadata

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

the class ServiceImplMetadata method getSetRelation.

private MethodMetadata getSetRelation(MethodMetadata methodToBeImplemented, RelationInfo relationInfo) {
    InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
    // Prepare constants
    final JavaSymbolName param0 = methodToBeImplemented.getParameterNames().get(0);
    final JavaType childType = relationInfo.childType;
    final FieldMetadata childServideField = requiredServiceFieldByEntity.get(childType);
    final String childTypeNameJavaType = getNameOfJavaType(childType);
    final JavaSymbolName param1 = methodToBeImplemented.getParameterNames().get(1);
    final String saveMethod = serviceMetadata.getCurrentSaveMethod().getMethodName().getSymbolName();
    String childListVariable = "items";
    // List<{childType}> {parentFieldName} =
    // {childService}.findAll({param1});
    bodyBuilder.appendFormalLine("%s<%s> %s = %s().findAll(%s);", getNameOfJavaType(JavaType.LIST), childTypeNameJavaType, childListVariable, getAccessorMethod(childServideField).getMethodName(), param1);
    // Set<{childType}> currents = {param0}.get{rel.property}();
    bodyBuilder.appendFormalLine("%s currents = %s.get%s();", getNameOfJavaType(relationInfo.fieldMetadata.getFieldType()), param0, relationInfo.fieldMetadata.getFieldName().getSymbolNameCapitalisedFirstLetter());
    // Set<{childType}> toRemove = new
    // HashSet<{childType}>({parentFieldName});
    bodyBuilder.appendFormalLine("%s<%s> toRemove = new %s<%s>();", getNameOfJavaType(JavaType.SET), childTypeNameJavaType, getNameOfJavaType(JdkJavaType.HASH_SET), childTypeNameJavaType);
    // for (Iterator<{childType}> iterator = current.iterator();
    // iterator.hasNext();) {
    bodyBuilder.appendFormalLine("for (%s<%s> iterator = currents.iterator(); iterator.hasNext();) {", getNameOfJavaType(JavaType.ITERATOR), childTypeNameJavaType);
    bodyBuilder.indent();
    final String itemName = "next".concat(StringUtils.capitalize(childType.getSimpleTypeName()));
    // {childType} {itemName} = iterator.next();
    bodyBuilder.appendFormalLine("%s %s = iterator.next();", childTypeNameJavaType, itemName);
    // if ({childListVariable}.contains({itemName})) {
    bodyBuilder.appendFormalLine("if (%s.contains(%s)) {", childListVariable, itemName);
    bodyBuilder.indent();
    // {childListVariable}.remove({itemName});
    bodyBuilder.appendFormalLine("%s.remove(%s);", childListVariable, itemName);
    bodyBuilder.indentRemove();
    // } else {
    bodyBuilder.appendFormalLine("} else {");
    bodyBuilder.indent();
    // toRemove.add(product);
    bodyBuilder.appendFormalLine("toRemove.add(%s);", itemName);
    bodyBuilder.indentRemove();
    // }
    bodyBuilder.appendFormalLine("}");
    // }
    bodyBuilder.indentRemove();
    bodyBuilder.appendFormalLine("}");
    // {param0}.{removeFromMethod}(toRemove);
    bodyBuilder.appendFormalLine("%s.%s(toRemove);", param0, relationInfo.removeMethod.getMethodName());
    // {param0}.{addToMethod}({childListVariable);
    bodyBuilder.appendFormalLine("%s.%s(%s);", param0, relationInfo.addMethod.getMethodName(), childListVariable);
    // Concurrency control
    if (this.entityMetadata.getCurrentVersionField() != null) {
        // // Force the version update of the parent side to know that the parent has changed
        bodyBuilder.appendFormalLine("// Force the version update of the parent side to know that the parent has changed");
        // // because it has new books assigned
        bodyBuilder.appendFormalLine("// because it has new books assigned");
        // {param0}.setVersion({param0}.getVersion() + 1);
        bodyBuilder.appendFormalLine("%s.setVersion(%s.getVersion() + 1);", param0, param0);
    }
    // return {repoField}.{saveMethod}({param0});
    bodyBuilder.appendFormalLine("return %s().%s(%s);", getAccessorMethod(repositoryFieldMetadata).getMethodName(), saveMethod, param0);
    return getMethod(methodToBeImplemented, true, bodyBuilder);
}
Also used : JavaSymbolName(org.springframework.roo.model.JavaSymbolName) AnnotatedJavaType(org.springframework.roo.classpath.details.annotations.AnnotatedJavaType) JdkJavaType(org.springframework.roo.model.JdkJavaType) SpringJavaType(org.springframework.roo.model.SpringJavaType) JavaType(org.springframework.roo.model.JavaType) FieldMetadata(org.springframework.roo.classpath.details.FieldMetadata) InvocableMemberBodyBuilder(org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder)

Example 49 with FieldMetadata

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

the class ServiceImplMetadata method getMethodAddRemoveRel.

private MethodMetadata getMethodAddRemoveRel(MethodMetadata methodToBeImplemented, RelationInfo relationInfo, MethodMetadata operationMethod) {
    InvocableMemberBodyBuilder bodyBuilder = new InvocableMemberBodyBuilder();
    // Prepare constants
    final String operation = operationMethod.getMethodName().getSymbolName();
    final JavaSymbolName param0 = methodToBeImplemented.getParameterNames().get(0);
    final JavaType childType = relationInfo.childType;
    final FieldMetadata childServideField = requiredServiceFieldByEntity.get(childType);
    final String parentFieldName = relationInfo.fieldName;
    final JavaSymbolName param1 = methodToBeImplemented.getParameterNames().get(1);
    final JavaType param1TypeWrapped = methodToBeImplemented.getParameterTypes().get(1).getJavaType().getParameters().get(0);
    final String saveMethod = serviceMetadata.getCurrentSaveMethod().getMethodName().getSymbolName();
    String childListVariable;
    if (childType.equals(param1TypeWrapped)) {
        childListVariable = param1.getSymbolName();
    } else {
        // List<{childType}> {parentFieldName} =
        // {childService}.findAll({param1});
        bodyBuilder.appendFormalLine("%s<%s> %s = %s().findAll(%s);", getNameOfJavaType(JavaType.LIST), getNameOfJavaType(childType), parentFieldName, getAccessorMethod(childServideField).getMethodName(), param1);
        childListVariable = parentFieldName;
    }
    // {param0}.{operation}({childListVariable});
    bodyBuilder.appendFormalLine("%s.%s(%s);", param0, operation, childListVariable);
    // return {repoField}.{saveMethod}({param0});
    bodyBuilder.appendFormalLine("return %s().%s(%s);", getAccessorMethod(repositoryFieldMetadata).getMethodName(), saveMethod, param0);
    return getMethod(methodToBeImplemented, true, bodyBuilder);
}
Also used : JavaSymbolName(org.springframework.roo.model.JavaSymbolName) AnnotatedJavaType(org.springframework.roo.classpath.details.annotations.AnnotatedJavaType) JdkJavaType(org.springframework.roo.model.JdkJavaType) SpringJavaType(org.springframework.roo.model.SpringJavaType) JavaType(org.springframework.roo.model.JavaType) FieldMetadata(org.springframework.roo.classpath.details.FieldMetadata) InvocableMemberBodyBuilder(org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder)

Example 50 with FieldMetadata

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

the class Predicate method getOptions.

/**
 * Returns the different queries that can be build based on the current predicate expressions.
 * The options are joined to the current query expression.
 *
 * @param query that represents the subject information
 * @return
 */
public List<String> getOptions(String subject) {
    List<String> options = new ArrayList<String>();
    OrPart lastOr = null;
    Part lastAnd = null;
    // Extract the last condition
    if (!nodes.isEmpty()) {
        lastOr = nodes.get(nodes.size() - 1);
        lastAnd = lastOr.getChildren().isEmpty() ? null : lastOr.getChildren().get(lastOr.getChildren().size() - 1);
    }
    // Builds the current query by joining the subject expression with the predicate information
    subject = subject.concat(toString());
    // Check if last condition has a property
    if (lastAnd == null || !lastAnd.hasProperty()) {
        // If options are added after Or, OrderBy keyword is added. It makes possible transform an Or into an OrderBy expression
        if (subject.endsWith("Or")) {
            options.add(StringUtils.removeEnd(subject, "Or").concat(ORDER_BY));
        }
        // Show all fields with correct format
        for (FieldMetadata field : fields) {
            options.add(subject.concat(StringUtils.capitalize(field.getFieldName().toString())));
        }
    } else {
        // Once a property is defined, the query is complete and no more information is necessary but optional
        options.add(subject.concat(""));
        // Once a property is defined, OrderBy option can be added
        options.add(subject.concat(ORDER_BY));
        // AlwaysIgnoreCase option ends search criteria definition.
        if (!alwaysIgnoreCase) {
            options.add(subject.concat("AllIgnoreCase"));
            options.add(subject.concat("AllIgnoringCase"));
            options.add(subject.concat("And"));
            options.add(subject.concat("Or"));
            if (!lastAnd.hasOperator()) {
                // If condition does not have an operator, optionally, it can be included
                List<String> types = lastAnd.getSupportedOperators();
                for (String type : types) {
                    options.add(subject.concat(type));
                }
            } else if (lastAnd.shouldIgnoreCase() != IgnoreCaseType.ALWAYS) {
                // If the condition has an operator, but it also acts as prefix of other operators, they are included
                List<String> types = lastAnd.getSupportedOperatorsByPrefix(lastAnd.getOperator());
                for (String type : types) {
                    if (StringUtils.isNotBlank(type)) {
                        options.add(subject.concat(type));
                    }
                }
            }
            // IgnoreCase option is available only for string properties
            if (lastAnd.shouldIgnoreCase() != IgnoreCaseType.ALWAYS && lastAnd.getProperty().getKey().peek().getFieldType().equals(JavaType.STRING)) {
                options.add(subject.concat("IgnoreCase"));
                options.add(subject.concat("IgnoringCase"));
            }
            // If the property condition is a reference to other entity, the related entity fields are shown
            if (!lastAnd.hasOperator() && lastAnd.shouldIgnoreCase() != IgnoreCaseType.ALWAYS) {
                List<FieldMetadata> fields = currentPartTreeInstance.getValidProperties(lastAnd.getProperty().getLeft().peek().getFieldType());
                if (fields != null) {
                    for (FieldMetadata field : fields) {
                        options.add(subject.concat(StringUtils.capitalize(field.getFieldName().toString())));
                    }
                }
            }
        }
    }
    return options;
}
Also used : FieldMetadata(org.springframework.roo.classpath.details.FieldMetadata) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

FieldMetadata (org.springframework.roo.classpath.details.FieldMetadata)141 JavaType (org.springframework.roo.model.JavaType)76 ArrayList (java.util.ArrayList)69 JavaSymbolName (org.springframework.roo.model.JavaSymbolName)59 ClassOrInterfaceTypeDetails (org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails)40 InvocableMemberBodyBuilder (org.springframework.roo.classpath.itd.InvocableMemberBodyBuilder)40 MethodMetadata (org.springframework.roo.classpath.details.MethodMetadata)39 AnnotatedJavaType (org.springframework.roo.classpath.details.annotations.AnnotatedJavaType)38 RooJavaType (org.springframework.roo.model.RooJavaType)38 JdkJavaType (org.springframework.roo.model.JdkJavaType)33 JpaJavaType (org.springframework.roo.model.JpaJavaType)32 MethodMetadataBuilder (org.springframework.roo.classpath.details.MethodMetadataBuilder)30 SpringJavaType (org.springframework.roo.model.SpringJavaType)30 MemberDetails (org.springframework.roo.classpath.scanner.MemberDetails)29 AnnotationMetadataBuilder (org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder)26 AnnotationMetadata (org.springframework.roo.classpath.details.annotations.AnnotationMetadata)21 SpringletsJavaType (org.springframework.roo.model.SpringletsJavaType)21 Jsr303JavaType (org.springframework.roo.model.Jsr303JavaType)18 RelationInfo (org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata.RelationInfo)17 ServiceMetadata (org.springframework.roo.addon.layers.service.addon.ServiceMetadata)15