Search in sources :

Example 1 with PartTree

use of org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree 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 2 with PartTree

use of org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree in project spring-roo by spring-projects.

the class RepositoryJpaMetadata method hashCode.

@Override
public int hashCode() {
    // Override hashCode to propagate changes in non-modified-itd changes
    // (as finders which will generate on RepositoryCustom)
    int result = super.hashCode();
    StringBuilder sb = new StringBuilder("");
    for (Pair<FinderMethod, PartTree> finder : findersToAddInCustom) {
        sb.append(finder.getLeft().getMethodName().getSymbolName());
    }
    // inside the annotation which triggers this metadata
    for (FinderMethod finder : findersDeclared) {
        sb.append(finder.getMethodName().getSymbolName());
    }
    // Combine hashCodes
    result += sb.toString().hashCode();
    return result;
}
Also used : ToStringBuilder(org.apache.commons.lang3.builder.ToStringBuilder) FinderMethod(org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.FinderMethod) PartTree(org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree)

Example 3 with PartTree

use of org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree in project spring-roo by spring-projects.

the class PartTreeUnitTest method validateOneParameter.

@Test
public void validateOneParameter() throws Exception {
    List<FinderParameter> parameters = new ArrayList<FinderParameter>();
    parameters.add(new FinderParameter(JavaType.STRING, new JavaSymbolName("text")));
    assertEqualsParameters(parameters, new PartTree("countByTextContaining", memberDetails).getParameters());
    parameters.add(new FinderParameter(JavaType.INT_OBJECT, new JavaSymbolName("number")));
    assertEqualsParameters(parameters, new PartTree("findByTextContainingAndNumberIsLessThan", memberDetails).getParameters());
    assertEqualsParameters(parameters, new PartTree("findByTextContainingAndNumberIsLessThanOrIsNull", memberDetails).getParameters());
}
Also used : JavaSymbolName(org.springframework.roo.model.JavaSymbolName) FinderParameter(org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.FinderParameter) ArrayList(java.util.ArrayList) PartTree(org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree) Test(org.junit.Test)

Example 4 with PartTree

use of org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree in project spring-roo by spring-projects.

the class PartTreeUnitTest method identifiesFindFirstKExplicit.

@Test
public void identifiesFindFirstKExplicit() {
    PartTree partTree = new PartTree("findFirst10ByText", memberDetails);
    assertTrue(partTree.isValid() && partTree.getMaxResults() == 10);
    partTree = new PartTree("findTop10ByText", memberDetails);
    assertTrue(partTree.isValid() && partTree.getMaxResults() == 10);
}
Also used : PartTree(org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree) Test(org.junit.Test)

Example 5 with PartTree

use of org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree in project spring-roo by spring-projects.

the class PartTreeUnitTest method identifiesCount.

@Test
public void identifiesCount() {
    PartTree partTree = new PartTree("countByText", memberDetails);
    assertTrue(partTree.isValid() && partTree.isCountProjection());
    partTree = new PartTree("countTextByText", memberDetails);
    assertTrue(partTree.isValid() && partTree.isCountProjection());
}
Also used : PartTree(org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree) Test(org.junit.Test)

Aggregations

PartTree (org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.PartTree)26 Test (org.junit.Test)17 ArrayList (java.util.ArrayList)10 JavaType (org.springframework.roo.model.JavaType)10 JavaSymbolName (org.springframework.roo.model.JavaSymbolName)8 FinderParameter (org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.FinderParameter)6 ClassOrInterfaceTypeDetails (org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails)6 List (java.util.List)4 MemberDetails (org.springframework.roo.classpath.scanner.MemberDetails)4 RooJavaType (org.springframework.roo.model.RooJavaType)4 HashMap (java.util.HashMap)3 LinkedHashMap (java.util.LinkedHashMap)3 JpaEntityMetadata (org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata)3 FieldMetadata (org.springframework.roo.classpath.details.FieldMetadata)3 AnnotationMetadata (org.springframework.roo.classpath.details.annotations.AnnotationMetadata)3 Pair (org.apache.commons.lang3.tuple.Pair)2 RepositoryJpaMetadata (org.springframework.roo.addon.layers.repository.jpa.addon.RepositoryJpaMetadata)2 FinderMethod (org.springframework.roo.addon.layers.repository.jpa.addon.finder.parser.FinderMethod)2 MethodMetadata (org.springframework.roo.classpath.details.MethodMetadata)2 NestedAnnotationAttributeValue (org.springframework.roo.classpath.details.annotations.NestedAnnotationAttributeValue)2