Search in sources :

Example 11 with DataInterceptor

use of io.micronaut.data.intercept.DataInterceptor in project micronaut-data by micronaut-projects.

the class QueryCriteriaMethodMatch method build.

@Override
protected MethodMatchInfo build(MethodMatchContext matchContext) {
    ClassElement queryResultType = matchContext.getRootEntity().getClassElement();
    MethodMatchSourcePersistentEntityCriteriaBuilderImpl cb = new MethodMatchSourcePersistentEntityCriteriaBuilderImpl(matchContext);
    PersistentEntityCriteriaQuery<Object> criteriaQuery = cb.createQuery();
    apply(matchContext, criteriaQuery.from(matchContext.getRootEntity()), criteriaQuery, cb);
    Map.Entry<ClassElement, Class<? extends DataInterceptor>> entry = resolveReturnTypeAndInterceptor(matchContext);
    ClassElement resultType = entry.getKey();
    Class<? extends DataInterceptor> interceptorType = entry.getValue();
    boolean optimisticLock = ((AbstractPersistentEntityCriteriaQuery<?>) criteriaQuery).hasVersionRestriction();
    SourcePersistentEntityCriteriaQuery<?> query = (SourcePersistentEntityCriteriaQuery) criteriaQuery;
    String selectedType = query.getQueryResultTypeName();
    if (selectedType != null) {
        queryResultType = matchContext.getVisitorContext().getClassElement(selectedType).orElse(null);
        if (queryResultType == null) {
            try {
                queryResultType = PrimitiveElement.valueOf(selectedType);
            } catch (Exception e) {
            // Ignore
            }
        }
    }
    boolean isDto = resultType != null && !TypeUtils.areTypesCompatible(resultType, queryResultType) && (isDtoType(resultType) || resultType.hasStereotype(Introspected.class) && queryResultType.hasStereotype(MappedEntity.class));
    if (isDto) {
        if (!isDtoType(resultType)) {
            List<SourcePersistentProperty> dtoProjectionProperties = getDtoProjectionProperties(matchContext.getRootEntity(), resultType);
            if (!dtoProjectionProperties.isEmpty()) {
                Root<?> root = query.getRoots().iterator().next();
                query.multiselect(dtoProjectionProperties.stream().map(p -> {
                    if (matchContext.getQueryBuilder().shouldAliasProjections()) {
                        return root.get(p.getName()).alias(p.getName());
                    } else {
                        return root.get(p.getName());
                    }
                }).collect(Collectors.toList()));
            }
        }
    } else {
        if (resultType == null || (!resultType.isAssignable(void.class) && !resultType.isAssignable(Void.class))) {
            if (resultType == null || TypeUtils.areTypesCompatible(resultType, queryResultType)) {
                if (!queryResultType.isPrimitive() || resultType == null) {
                    resultType = queryResultType;
                }
            } else {
                throw new MatchFailedException("Query results in a type [" + queryResultType.getName() + "] whilst method returns an incompatible type: " + resultType.getName());
            }
        }
    }
    final AnnotationMetadataHierarchy annotationMetadataHierarchy = new AnnotationMetadataHierarchy(matchContext.getRepositoryClass().getAnnotationMetadata(), matchContext.getAnnotationMetadata());
    QueryBuilder queryBuilder = matchContext.getQueryBuilder();
    QueryModel queryModel = ((QueryModelPersistentEntityCriteriaQuery) criteriaQuery).getQueryModel();
    QueryResult queryResult = queryBuilder.buildQuery(annotationMetadataHierarchy, queryModel);
    ClassElement genericReturnType = matchContext.getReturnType();
    if (TypeUtils.isReactiveOrFuture(genericReturnType)) {
        genericReturnType = genericReturnType.getFirstTypeArgument().orElse(matchContext.getRootEntity().getType());
    }
    QueryResult countQueryResult = null;
    if (matchContext.isTypeInRole(genericReturnType, TypeRole.PAGE)) {
        // SourcePersistentEntityCriteriaQuery<Object> count = cb.createQuery();
        // count.select(cb.count(query.getRoots().iterator().next()));
        // CommonAbstractCriteria countQueryCriteria = defineQuery(matchContext, matchContext.getRootEntity(), cb);
        QueryModel countQuery = QueryModel.from(queryModel.getPersistentEntity());
        countQuery.projections().count();
        QueryModel.Junction junction = queryModel.getCriteria();
        for (QueryModel.Criterion criterion : junction.getCriteria()) {
            countQuery.add(criterion);
        }
        for (JoinPath joinPath : queryModel.getJoinPaths()) {
            Join.Type joinType = joinPath.getJoinType();
            switch(joinType) {
                case INNER:
                case FETCH:
                    joinType = Join.Type.DEFAULT;
                    break;
                case LEFT_FETCH:
                    joinType = Join.Type.LEFT;
                    break;
                case RIGHT_FETCH:
                    joinType = Join.Type.RIGHT;
                    break;
                default:
            }
            countQuery.join(joinPath.getPath(), joinType, null);
        }
        countQueryResult = queryBuilder.buildQuery(countQuery);
    }
    return new MethodMatchInfo(DataMethod.OperationType.QUERY, resultType, getInterceptorElement(matchContext, interceptorType)).dto(isDto).optimisticLock(optimisticLock).queryResult(queryResult).countQueryResult(countQueryResult);
}
Also used : MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) JoinPath(io.micronaut.data.model.query.JoinPath) ClassElement(io.micronaut.inject.ast.ClassElement) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) QueryModelPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.QueryModelPersistentEntityCriteriaQuery) QueryResult(io.micronaut.data.model.query.builder.QueryResult) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) MethodMatchSourcePersistentEntityCriteriaBuilderImpl(io.micronaut.data.processor.model.criteria.impl.MethodMatchSourcePersistentEntityCriteriaBuilderImpl) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) Join(io.micronaut.data.annotation.Join) AnnotationMetadataHierarchy(io.micronaut.data.processor.visitors.AnnotationMetadataHierarchy) QueryModel(io.micronaut.data.model.query.QueryModel) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) SourcePersistentEntityCriteriaQuery(io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaQuery) MethodMatchInfo(io.micronaut.data.processor.visitors.finders.MethodMatchInfo) Map(java.util.Map) AbstractPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery)

Aggregations

DataInterceptor (io.micronaut.data.intercept.DataInterceptor)11 Map (java.util.Map)10 ClassElement (io.micronaut.inject.ast.ClassElement)9 NonNull (io.micronaut.core.annotation.NonNull)5 DataMethod (io.micronaut.data.intercept.annotation.DataMethod)5 QueryResult (io.micronaut.data.model.query.builder.QueryResult)5 MatchFailedException (io.micronaut.data.processor.visitors.MatchFailedException)5 MethodMatchContext (io.micronaut.data.processor.visitors.MethodMatchContext)5 ParameterElement (io.micronaut.inject.ast.ParameterElement)5 Parameter (io.micronaut.context.annotation.Parameter)4 MappedEntity (io.micronaut.data.annotation.MappedEntity)4 SourcePersistentEntity (io.micronaut.data.processor.model.SourcePersistentEntity)4 MethodElement (io.micronaut.inject.ast.MethodElement)4 List (java.util.List)4 RepositoryConfiguration (io.micronaut.data.annotation.RepositoryConfiguration)3 PersistentPropertyPath (io.micronaut.data.model.PersistentPropertyPath)3 AnnotationMetadataHierarchy (io.micronaut.data.processor.visitors.AnnotationMetadataHierarchy)3 MethodMatchInfo (io.micronaut.data.processor.visitors.finders.MethodMatchInfo)3 Introspected (io.micronaut.core.annotation.Introspected)2 Id (io.micronaut.data.annotation.Id)2