Search in sources :

Example 81 with ClassOrInterfaceTypeDetails

use of org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails 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 82 with ClassOrInterfaceTypeDetails

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

the class RepositoryJpaMetadataProviderImpl method getEntityDetails.

@Override
public MemberDetails getEntityDetails(JavaType entity) {
    Validate.notNull(entity, "ERROR: Entity should be provided");
    if (entitiesDetails.containsKey(entity)) {
        return entitiesDetails.get(entity);
    }
    // We know the file exists, as there's already entity metadata for it
    final ClassOrInterfaceTypeDetails cid = getTypeLocationService().getTypeDetails(entity);
    if (cid == null) {
        return null;
    }
    if (cid.getAnnotation(RooJavaType.ROO_JPA_ENTITY) == null) {
        return null;
    }
    entitiesDetails.put(entity, getMemberDetailsScanner().getMemberDetails(getClass().getName(), cid));
    return entitiesDetails.get(entity);
}
Also used : ClassOrInterfaceTypeDetails(org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails)

Example 83 with ClassOrInterfaceTypeDetails

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

the class RepositoryJpaOperationsImpl method addRepository.

@Override
public void addRepository(JavaType interfaceType, final JavaType domainType, JavaType defaultReturnType, boolean failOnComposition) {
    Validate.notNull(domainType, "ERROR: You must specify a valid Entity. ");
    if (getProjectOperations().isMultimoduleProject()) {
        Validate.notNull(interfaceType, "ERROR: You must specify an interface repository type on multimodule projects.");
        Validate.notNull(interfaceType.getModule(), "ERROR: interfaceType module is required on multimodule projects.");
    } else if (interfaceType == null) {
        interfaceType = new JavaType(String.format("%s.repository.%sRepository", getProjectOperations().getFocusedTopLevelPackage(), domainType.getSimpleTypeName()), "");
    }
    // Check if entity provided type is annotated with @RooJpaEntity
    ClassOrInterfaceTypeDetails entityDetails = getTypeLocationService().getTypeDetails(domainType);
    AnnotationMetadata entityAnnotation = entityDetails.getAnnotation(RooJavaType.ROO_JPA_ENTITY);
    // Show an error indicating that entity should be annotated with
    // @RooJpaEntity
    Validate.notNull(entityAnnotation, "ERROR: Provided entity should be annotated with @RooJpaEntity");
    if (!shouldGenerateRepository(entityDetails)) {
        if (failOnComposition) {
            throw new IllegalArgumentException("%s is child part of a composition relation. Can't create repository (entity should be handle in parent part)");
        } else {
            // Nothing to do: silently exit
            return;
        }
    }
    if (defaultReturnType != null) {
        ClassOrInterfaceTypeDetails defaultReturnTypeDetails = getTypeLocationService().getTypeDetails(defaultReturnType);
        AnnotationMetadata defaultReturnTypeAnnotation = defaultReturnTypeDetails.getAnnotation(RooJavaType.ROO_ENTITY_PROJECTION);
        // Show an error indicating that defaultReturnType should be annotated with
        // @RooEntityProjection
        Validate.notNull(defaultReturnTypeAnnotation, "ERROR: Provided defaultReturnType should be annotated with @RooEntityProjection");
    }
    // Check if the new interface to be created already exists
    final String interfaceIdentifier = getPathResolver().getCanonicalPath(interfaceType.getModule(), Path.SRC_MAIN_JAVA, interfaceType);
    if (getFileManager().exists(interfaceIdentifier)) {
        // Type already exists - return.
        LOGGER.log(Level.INFO, String.format("INFO: The repository '%s' already exists.", interfaceType.getSimpleTypeName()));
        return;
    }
    // Check if already exists a repository that manage current entity
    // Only one repository per entity is allowed
    Set<ClassOrInterfaceTypeDetails> existingRepositories = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_REPOSITORY_JPA);
    for (ClassOrInterfaceTypeDetails existingRepository : existingRepositories) {
        AnnotationAttributeValue<Object> relatedEntity = existingRepository.getAnnotation(RooJavaType.ROO_REPOSITORY_JPA).getAttribute("entity");
        if (relatedEntity.getValue().equals(domainType)) {
            LOGGER.log(Level.INFO, String.format("INFO: Already exists a repository associated to the entity '%s'. Only one repository per entity is allowed.", domainType.getSimpleTypeName()));
            return;
        }
    }
    // Add Springlets base repository class
    addRepositoryConfigurationClass();
    // Check if current entity is defined as "readOnly".
    AnnotationAttributeValue<Boolean> readOnlyAttr = entityDetails.getAnnotation(RooJavaType.ROO_JPA_ENTITY).getAttribute("readOnly");
    boolean readOnly = readOnlyAttr != null && readOnlyAttr.getValue() ? true : false;
    if (readOnly) {
        // If is readOnly entity, generates common ReadOnlyRepository interface
        generateReadOnlyRepository(interfaceType.getPackage());
    }
    // Generates repository interface
    addRepositoryInterface(interfaceType, domainType, entityDetails, interfaceIdentifier, defaultReturnType);
    // By default, generate RepositoryCustom interface and its
    // implementation that allow developers to include its dynamic queries
    // using QueryDSL
    addRepositoryCustom(domainType, interfaceType, interfaceType.getPackage());
    // Add dependencies between modules
    getProjectOperations().addModuleDependency(interfaceType.getModule(), domainType.getModule());
    // Add dependencies and plugins
    generateConfiguration(interfaceType, domainType);
}
Also used : RooJavaType(org.springframework.roo.model.RooJavaType) SpringJavaType(org.springframework.roo.model.SpringJavaType) JavaType(org.springframework.roo.model.JavaType) ClassOrInterfaceTypeDetails(org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails) AnnotationMetadata(org.springframework.roo.classpath.details.annotations.AnnotationMetadata)

Example 84 with ClassOrInterfaceTypeDetails

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

the class RepositoryJpaOperationsImpl method generateConfiguration.

@SuppressWarnings({ "unchecked", "rawtypes" })
private void generateConfiguration(JavaType interfaceType, JavaType domainType) {
    final Element configuration = XmlUtils.getConfiguration(getClass());
    // Add querydsl dependency
    final List<Element> dependencies;
    final List<Element> plugins;
    if (getProjectOperations().isMultimoduleProject()) {
        dependencies = XmlUtils.findElements("/configuration/multimodule/dependencies/dependency", configuration);
        plugins = XmlUtils.findElements("/configuration/multimodule/plugins/plugin", configuration);
        // Add database test dependency
        getJpaOperations().addDatabaseDependencyWithTestScope(interfaceType.getModule(), null, null);
    } else {
        dependencies = XmlUtils.findElements("/configuration/monomodule/dependencies/dependency", configuration);
        plugins = XmlUtils.findElements("/configuration/monomodule/plugins/plugin", configuration);
    }
    for (final Element dependencyElement : dependencies) {
        getProjectOperations().addDependency(interfaceType.getModule(), new Dependency(dependencyElement));
    }
    // Add querydsl plugin
    Plugin queryDslPlugin = null;
    for (final Element pluginElement : plugins) {
        Plugin plugin = new Plugin(pluginElement);
        if (plugin.getArtifactId().equals("querydsl-maven-plugin")) {
            queryDslPlugin = plugin;
        }
        getProjectOperations().addBuildPlugin(interfaceType.getModule(), plugin);
    }
    if (getProjectOperations().isMultimoduleProject()) {
        if (queryDslPlugin == null) {
            throw new RuntimeException("Error: Missing QueryDSL plugin");
        }
        // Add entity package to find Q classes.
        Set<String> packages = new HashSet();
        for (ClassOrInterfaceTypeDetails cid : getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_REPOSITORY_JPA)) {
            if (cid.getType().getModule().equals(interfaceType.getModule())) {
                JavaType relatedEntity = (JavaType) cid.getAnnotation(RooJavaType.ROO_REPOSITORY_JPA).getAttribute("entity").getValue();
                String module = getTypeLocationService().getTypeDetails(relatedEntity).getType().getModule();
                if (!packages.contains(module)) {
                    packages.add(module);
                    getProjectOperations().addPackageToPluginExecution(interfaceType.getModule(), queryDslPlugin, "generate-qtypes", getProjectOperations().getTopLevelPackage(module).getFullyQualifiedPackageName());
                }
            }
        }
        getProjectOperations().addPackageToPluginExecution(interfaceType.getModule(), queryDslPlugin, "generate-qtypes", getProjectOperations().getTopLevelPackage(domainType.getModule()).getFullyQualifiedPackageName());
    } else {
        // Add querydsl processor repository
        List<Element> repositories = XmlUtils.findElements("/configuration/monomodule/repositories/repository", configuration);
        for (final Element repositoryElement : repositories) {
            getProjectOperations().addRepository(interfaceType.getModule(), new Repository(repositoryElement));
        }
    }
}
Also used : RooJavaType(org.springframework.roo.model.RooJavaType) SpringJavaType(org.springframework.roo.model.SpringJavaType) JavaType(org.springframework.roo.model.JavaType) Repository(org.springframework.roo.project.Repository) Element(org.w3c.dom.Element) Dependency(org.springframework.roo.project.Dependency) ClassOrInterfaceTypeDetails(org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails) Plugin(org.springframework.roo.project.Plugin) HashSet(java.util.HashSet)

Example 85 with ClassOrInterfaceTypeDetails

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

the class RepositoryJpaOperationsImpl method generateAllRepositories.

@Override
public void generateAllRepositories(JavaPackage repositoriesPackage) {
    // Getting all project entities
    Set<ClassOrInterfaceTypeDetails> entities = getTypeLocationService().findClassesOrInterfaceDetailsWithAnnotation(RooJavaType.ROO_JPA_ENTITY);
    Iterator<ClassOrInterfaceTypeDetails> it = entities.iterator();
    while (it.hasNext()) {
        ClassOrInterfaceTypeDetails entity = it.next();
        // Ignore abstract classes
        if (entity.isAbstract()) {
            continue;
        }
        // Generating new interface type using entity
        JavaType interfaceType = new JavaType(repositoriesPackage.getFullyQualifiedPackageName().concat(".").concat(entity.getType().getSimpleTypeName()).concat("Repository"), repositoriesPackage.getModule());
        // Delegate on simple add repository method
        addRepository(interfaceType, entity.getType(), null, false);
    }
}
Also used : RooJavaType(org.springframework.roo.model.RooJavaType) SpringJavaType(org.springframework.roo.model.SpringJavaType) JavaType(org.springframework.roo.model.JavaType) ClassOrInterfaceTypeDetails(org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails)

Aggregations

ClassOrInterfaceTypeDetails (org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetails)232 JavaType (org.springframework.roo.model.JavaType)114 ArrayList (java.util.ArrayList)87 RooJavaType (org.springframework.roo.model.RooJavaType)86 AnnotationMetadata (org.springframework.roo.classpath.details.annotations.AnnotationMetadata)52 ClassOrInterfaceTypeDetailsBuilder (org.springframework.roo.classpath.details.ClassOrInterfaceTypeDetailsBuilder)43 AnnotationMetadataBuilder (org.springframework.roo.classpath.details.annotations.AnnotationMetadataBuilder)42 FieldMetadata (org.springframework.roo.classpath.details.FieldMetadata)40 JavaSymbolName (org.springframework.roo.model.JavaSymbolName)39 MemberDetails (org.springframework.roo.classpath.scanner.MemberDetails)36 JpaJavaType (org.springframework.roo.model.JpaJavaType)34 SpringJavaType (org.springframework.roo.model.SpringJavaType)28 CliOptionAutocompleteIndicator (org.springframework.roo.shell.CliOptionAutocompleteIndicator)24 JpaEntityMetadata (org.springframework.roo.addon.jpa.addon.entity.JpaEntityMetadata)23 JdkJavaType (org.springframework.roo.model.JdkJavaType)22 Test (org.junit.Test)20 File (java.io.File)19 List (java.util.List)19 AnnotatedJavaType (org.springframework.roo.classpath.details.annotations.AnnotatedJavaType)19 MethodMetadata (org.springframework.roo.classpath.details.MethodMetadata)17