Search in sources :

Example 6 with DataInterceptor

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

the class CoherenceDataIntroductionAdvice method findInterceptor.

@NonNull
private DataInterceptor<Object, Object> findInterceptor(@Nullable String dataSourceName, @NonNull Class<?> operationsType, @NonNull Class<?> interceptorType) {
    DataInterceptor interceptor;
    if (!RepositoryOperations.class.isAssignableFrom(operationsType)) {
        throw new IllegalArgumentException("Repository type must be an instance of RepositoryOperations!");
    }
    Qualifier qualifier = Qualifiers.byName(dataSourceName);
    RepositoryOperations datastore;
    try {
        datastore = (RepositoryOperations) beanLocator.getBean(operationsType, qualifier);
    } catch (NoSuchBeanException e) {
        // if there is no explicit configuration, use a DefaultCoherenceRepositoryOperations implementation
        // using the default Coherence session
        datastore = new DefaultCoherenceRepositoryOperations(dataSourceName, (ApplicationContext) beanLocator, (BeanContext) beanLocator);
        ((ApplicationContext) beanLocator).registerSingleton(RepositoryOperations.class, datastore, qualifier);
    }
    BeanIntrospection<Object> introspection = BeanIntrospector.SHARED.findIntrospections(ref -> interceptorType.isAssignableFrom(ref.getBeanType())).stream().findFirst().orElseThrow(() -> new DataAccessException("No Data interceptor found for type: " + interceptorType));
    if (introspection.getConstructorArguments().length == 0) {
        interceptor = (DataInterceptor) introspection.instantiate();
    } else {
        interceptor = (DataInterceptor) introspection.instantiate(datastore);
    }
    return interceptor;
}
Also used : RepositoryConfiguration(io.micronaut.data.annotation.RepositoryConfiguration) BeanContext(io.micronaut.context.BeanContext) Qualifier(io.micronaut.context.Qualifier) DefaultCoherenceRepositoryOperations(io.micronaut.coherence.data.ops.DefaultCoherenceRepositoryOperations) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) DataMethod(io.micronaut.data.intercept.annotation.DataMethod) ApplicationContext(io.micronaut.context.ApplicationContext) MethodInterceptor(io.micronaut.aop.MethodInterceptor) Nullable(io.micronaut.core.annotation.Nullable) PrimaryRepositoryOperations(io.micronaut.data.operations.PrimaryRepositoryOperations) Map(java.util.Map) Ordered(io.micronaut.core.order.Ordered) DataAccessException(io.micronaut.data.exceptions.DataAccessException) BeanLocator(io.micronaut.context.BeanLocator) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Qualifiers(io.micronaut.inject.qualifiers.Qualifiers) Singleton(jakarta.inject.Singleton) NonNull(io.micronaut.core.annotation.NonNull) RepositoryOperations(io.micronaut.data.operations.RepositoryOperations) NoSuchBeanException(io.micronaut.context.exceptions.NoSuchBeanException) MethodInvocationContext(io.micronaut.aop.MethodInvocationContext) AnnotationValue(io.micronaut.core.annotation.AnnotationValue) BeanIntrospection(io.micronaut.core.beans.BeanIntrospection) Repository(io.micronaut.data.annotation.Repository) RepositoryMethodKey(io.micronaut.data.intercept.RepositoryMethodKey) BeanIntrospector(io.micronaut.core.beans.BeanIntrospector) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) DefaultCoherenceRepositoryOperations(io.micronaut.coherence.data.ops.DefaultCoherenceRepositoryOperations) PrimaryRepositoryOperations(io.micronaut.data.operations.PrimaryRepositoryOperations) RepositoryOperations(io.micronaut.data.operations.RepositoryOperations) NoSuchBeanException(io.micronaut.context.exceptions.NoSuchBeanException) DefaultCoherenceRepositoryOperations(io.micronaut.coherence.data.ops.DefaultCoherenceRepositoryOperations) Qualifier(io.micronaut.context.Qualifier) DataAccessException(io.micronaut.data.exceptions.DataAccessException) NonNull(io.micronaut.core.annotation.NonNull)

Example 7 with DataInterceptor

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

the class MongoRawQueryMethodMatcher method methodMatchByFilterQuery.

private MethodMatch methodMatchByFilterQuery(DataMethod.OperationType operationType) {
    return new MethodMatch() {

        @Override
        public MethodMatchInfo buildMatchInfo(MethodMatchContext matchContext) {
            ParameterElement[] parameters = matchContext.getParameters();
            ParameterElement entityParameter;
            ParameterElement entitiesParameter;
            if (parameters.length > 1) {
                entityParameter = null;
                entitiesParameter = null;
            } else {
                entityParameter = Arrays.stream(parameters).filter(p -> TypeUtils.isEntity(p.getGenericType())).findFirst().orElse(null);
                entitiesParameter = Arrays.stream(parameters).filter(p -> TypeUtils.isIterableOfEntity(p.getGenericType())).findFirst().orElse(null);
            }
            Map.Entry<ClassElement, Class<? extends DataInterceptor>> entry = FindersUtils.resolveInterceptorTypeByOperationType(entityParameter != null, entitiesParameter != null, operationType, matchContext);
            ClassElement resultType = entry.getKey();
            Class<? extends DataInterceptor> interceptorType = entry.getValue();
            boolean isDto = false;
            if (resultType == null) {
                resultType = matchContext.getRootEntity().getType();
            } else {
                if (resultType.hasAnnotation(Introspected.class)) {
                    if (!resultType.hasAnnotation(MappedEntity.class)) {
                        isDto = true;
                    }
                }
            }
            MethodMatchInfo methodMatchInfo = new MethodMatchInfo(operationType, resultType, FindersUtils.getInterceptorElement(matchContext, interceptorType));
            methodMatchInfo.dto(isDto);
            buildRawQuery(matchContext, methodMatchInfo, entityParameter, entitiesParameter, operationType);
            if (entityParameter != null) {
                methodMatchInfo.addParameterRole(TypeRole.ENTITY, entityParameter.getName());
            } else if (entitiesParameter != null) {
                methodMatchInfo.addParameterRole(TypeRole.ENTITIES, entitiesParameter.getName());
            }
            return methodMatchInfo;
        }
    };
}
Also used : QueryParameterBinding(io.micronaut.data.model.query.builder.QueryParameterBinding) Arrays(java.util.Arrays) Parameter(io.micronaut.context.annotation.Parameter) MongoAnnotations(io.micronaut.data.document.mongo.MongoAnnotations) TypeRole(io.micronaut.data.annotation.TypeRole) MappedEntity(io.micronaut.data.annotation.MappedEntity) ClassElement(io.micronaut.inject.ast.ClassElement) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) ParameterElement(io.micronaut.inject.ast.ParameterElement) ArrayList(java.util.ArrayList) DataMethod(io.micronaut.data.intercept.annotation.DataMethod) MethodMatcher(io.micronaut.data.processor.visitors.finders.MethodMatcher) Map(java.util.Map) QueryResult(io.micronaut.data.model.query.builder.QueryResult) TypeUtils(io.micronaut.data.processor.visitors.finders.TypeUtils) PersistentPropertyPath(io.micronaut.data.model.PersistentPropertyPath) SourceParameterExpressionImpl(io.micronaut.data.processor.model.criteria.impl.SourceParameterExpressionImpl) BindingContext(io.micronaut.data.model.query.BindingParameter.BindingContext) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) AnnotationMetadataHierarchy(io.micronaut.inject.annotation.AnnotationMetadataHierarchy) Query(io.micronaut.data.annotation.Query) FindersUtils(io.micronaut.data.processor.visitors.finders.FindersUtils) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Introspected(io.micronaut.core.annotation.Introspected) NonNull(io.micronaut.core.annotation.NonNull) List(java.util.List) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) MethodElement(io.micronaut.inject.ast.MethodElement) Optional(java.util.Optional) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) MethodMatchInfo(io.micronaut.data.processor.visitors.finders.MethodMatchInfo) Pattern(java.util.regex.Pattern) Collections(java.util.Collections) MutableAnnotationMetadata(io.micronaut.inject.annotation.MutableAnnotationMetadata) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) MappedEntity(io.micronaut.data.annotation.MappedEntity) ClassElement(io.micronaut.inject.ast.ClassElement) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) ParameterElement(io.micronaut.inject.ast.ParameterElement) MethodMatchInfo(io.micronaut.data.processor.visitors.finders.MethodMatchInfo) Map(java.util.Map)

Example 8 with DataInterceptor

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

the class SaveOneMethodMatcher method match.

@Override
protected MethodMatch match(MethodMatchContext matchContext, java.util.regex.Matcher matcher) {
    List<ParameterElement> parameters = matchContext.getParametersNotInRole();
    if (parameters.size() == 0 || TypeUtils.isEntity(parameters.get(0).getGenericType()) || TypeUtils.isIterableOfEntity(parameters.get(0).getGenericType()) || !isValidSaveReturnType(matchContext, true)) {
        return null;
    }
    return new MethodMatch() {

        @Override
        public MethodMatchInfo buildMatchInfo(MethodMatchContext matchContext) {
            List<ParameterElement> parameters = matchContext.getParametersNotInRole();
            SourcePersistentEntity rootEntity = matchContext.getRootEntity();
            ClassElement returnType = matchContext.getReturnType();
            if (TypeUtils.isReactiveOrFuture(returnType)) {
                returnType = returnType.getFirstTypeArgument().orElse(null);
            }
            if (returnType == null || !TypeUtils.isNumber(returnType) && !rootEntity.getName().equals(returnType.getName())) {
                throw new MatchFailedException("The return type of the save method must be the same as the root entity type: " + rootEntity.getName());
            }
            Set<String> requiredProps = rootEntity.getPersistentProperties().stream().filter(this::isRequiredProperty).map(PersistentProperty::getName).collect(Collectors.toSet());
            ParameterElement[] parameterElements = rootEntity.getClassElement().getPrimaryConstructor().map(MethodElement::getParameters).orElse(null);
            Map<String, ParameterElement> constructorArgs = new HashMap<>(10);
            if (ArrayUtils.isNotEmpty(parameterElements)) {
                for (ParameterElement parameterElement : parameterElements) {
                    constructorArgs.put(getParameterValue(parameterElement), parameterElement);
                }
            }
            for (ParameterElement parameter : parameters) {
                String name = getParameterValue(parameter);
                ClassElement type = parameter.getGenericType();
                SourcePersistentProperty prop = rootEntity.getPropertyByName(name);
                ParameterElement constructorArg = constructorArgs.get(name);
                if (prop == null && constructorArg == null) {
                    throw new MatchFailedException("Cannot save with non-existent property or constructor argument: " + name);
                }
                if (prop != null) {
                    String typeName = prop.getTypeName();
                    if (!type.isAssignable(typeName) && !typeName.equals(type.getName())) {
                        throw new MatchFailedException("Type mismatch. Found parameter of type [" + type.getName() + "]. Required property of type: " + typeName);
                    }
                    requiredProps.remove(name);
                } else {
                    ClassElement argType = constructorArg.getGenericType();
                    String typeName = argType.getName();
                    if (!type.isAssignable(typeName) && !typeName.equals(type.getName())) {
                        throw new MatchFailedException("Type mismatch. Found parameter of type [" + type.getName() + "]. Required constructor argument of: " + typeName);
                    }
                }
                constructorArgs.remove(name);
            }
            if (!requiredProps.isEmpty()) {
                throw new MatchFailedException("Save method missing required properties: " + requiredProps);
            }
            if (!constructorArgs.isEmpty()) {
                Collection<ParameterElement> values = constructorArgs.values();
                Set<String> names = values.stream().filter(pe -> {
                    SourcePersistentProperty prop = rootEntity.getPropertyByName(pe.getName());
                    return prop != null && prop.isRequired() && !prop.getType().isPrimitive();
                }).map(p -> getParameterValue(p)).collect(Collectors.toSet());
                if (CollectionUtils.isNotEmpty(names)) {
                    throw new MatchFailedException("Save method missing required constructor arguments: " + names);
                }
            }
            final AnnotationMetadataHierarchy annotationMetadataHierarchy = new AnnotationMetadataHierarchy(matchContext.getRepositoryClass().getAnnotationMetadata(), matchContext.getAnnotationMetadata());
            Map.Entry<ClassElement, Class<? extends DataInterceptor>> e = FindersUtils.pickSaveOneInterceptor(matchContext, matchContext.getReturnType());
            return new MethodMatchInfo(DataMethod.OperationType.INSERT, e.getKey(), getInterceptorElement(matchContext, e.getValue())).encodeEntityParameters(true).queryResult(matchContext.getQueryBuilder().buildInsert(annotationMetadataHierarchy, matchContext.getRootEntity()));
        }

        private boolean isRequiredProperty(SourcePersistentProperty pp) {
            return pp.isRequired() && !ClassUtils.getPrimitiveType(pp.getTypeName()).isPresent();
        }
    };
}
Also used : Parameter(io.micronaut.context.annotation.Parameter) ArrayUtils(io.micronaut.core.util.ArrayUtils) MappedEntity(io.micronaut.data.annotation.MappedEntity) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ClassElement(io.micronaut.inject.ast.ClassElement) HashMap(java.util.HashMap) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) ParameterElement(io.micronaut.inject.ast.ParameterElement) DataMethod(io.micronaut.data.intercept.annotation.DataMethod) MatchContext(io.micronaut.data.processor.visitors.MatchContext) Map(java.util.Map) FindersUtils.getInterceptorElement(io.micronaut.data.processor.visitors.finders.FindersUtils.getInterceptorElement) PersistentProperty(io.micronaut.data.model.PersistentProperty) ClassUtils(io.micronaut.core.reflect.ClassUtils) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) Collection(java.util.Collection) Set(java.util.Set) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) Collectors(java.util.stream.Collectors) NonNull(io.micronaut.core.annotation.NonNull) List(java.util.List) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) CollectionUtils(io.micronaut.core.util.CollectionUtils) MethodElement(io.micronaut.inject.ast.MethodElement) AnnotationMetadataHierarchy(io.micronaut.data.processor.visitors.AnnotationMetadataHierarchy) MatchFailedException(io.micronaut.data.processor.visitors.MatchFailedException) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) SourcePersistentEntity(io.micronaut.data.processor.model.SourcePersistentEntity) HashMap(java.util.HashMap) ClassElement(io.micronaut.inject.ast.ClassElement) AnnotationMetadataHierarchy(io.micronaut.data.processor.visitors.AnnotationMetadataHierarchy) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) SourcePersistentProperty(io.micronaut.data.processor.model.SourcePersistentProperty) ParameterElement(io.micronaut.inject.ast.ParameterElement) HashMap(java.util.HashMap) Map(java.util.Map)

Example 9 with DataInterceptor

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

the class DeleteCriteriaMethodMatch method build.

@Override
protected MethodMatchInfo build(MethodMatchContext matchContext) {
    MethodMatchSourcePersistentEntityCriteriaBuilderImpl cb = new MethodMatchSourcePersistentEntityCriteriaBuilderImpl(matchContext);
    PersistentEntityCriteriaDelete<Object> criteriaQuery = cb.createCriteriaDelete(null);
    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 = ((AbstractPersistentEntityCriteriaDelete<?>) criteriaQuery).hasVersionRestriction();
    final AnnotationMetadataHierarchy annotationMetadataHierarchy = new AnnotationMetadataHierarchy(matchContext.getRepositoryClass().getAnnotationMetadata(), matchContext.getAnnotationMetadata());
    QueryBuilder queryBuilder = matchContext.getQueryBuilder();
    QueryModel queryModel = ((QueryModelPersistentEntityCriteriaQuery) criteriaQuery).getQueryModel();
    QueryResult queryResult = queryBuilder.buildDelete(annotationMetadataHierarchy, queryModel);
    return new MethodMatchInfo(DataMethod.OperationType.DELETE, resultType, getInterceptorElement(matchContext, interceptorType)).optimisticLock(optimisticLock).queryResult(queryResult);
}
Also used : DataInterceptor(io.micronaut.data.intercept.DataInterceptor) ClassElement(io.micronaut.inject.ast.ClassElement) QueryBuilder(io.micronaut.data.model.query.builder.QueryBuilder) AnnotationMetadataHierarchy(io.micronaut.data.processor.visitors.AnnotationMetadataHierarchy) QueryModel(io.micronaut.data.model.query.QueryModel) QueryModelPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.QueryModelPersistentEntityCriteriaQuery) QueryResult(io.micronaut.data.model.query.builder.QueryResult) MethodMatchInfo(io.micronaut.data.processor.visitors.finders.MethodMatchInfo) MethodMatchSourcePersistentEntityCriteriaBuilderImpl(io.micronaut.data.processor.model.criteria.impl.MethodMatchSourcePersistentEntityCriteriaBuilderImpl) AbstractPersistentEntityCriteriaDelete(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaDelete) Map(java.util.Map)

Example 10 with DataInterceptor

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

the class FindMethodMatcher method match.

@Override
protected MethodMatch match(MethodMatchContext matchContext, java.util.regex.Matcher matcher) {
    if (isCompatibleReturnType(matchContext)) {
        return new QueryCriteriaMethodMatch(matcher) {

            boolean hasIdMatch;

            @Override
            protected <T> void apply(MethodMatchContext matchContext, PersistentEntityRoot<T> root, PersistentEntityCriteriaQuery<T> query, SourcePersistentEntityCriteriaBuilder cb) {
                super.apply(matchContext, root, query, cb);
                if (query instanceof AbstractPersistentEntityCriteriaQuery) {
                    hasIdMatch = ((AbstractPersistentEntityCriteriaQuery<T>) query).hasOnlyIdRestriction();
                }
            }

            @Override
            protected Map.Entry<ClassElement, Class<? extends DataInterceptor>> resolveReturnTypeAndInterceptor(MethodMatchContext matchContext) {
                Map.Entry<ClassElement, Class<? extends DataInterceptor>> e = super.resolveReturnTypeAndInterceptor(matchContext);
                Class<? extends DataInterceptor> interceptorType = e.getValue();
                ClassElement queryResultType = e.getKey();
                if (isFindByIdQuery(matchContext, queryResultType)) {
                    if (interceptorType == FindOneInterceptor.class) {
                        interceptorType = FindByIdInterceptor.class;
                    } else if (interceptorType == FindOneAsyncInterceptor.class) {
                        interceptorType = FindByIdAsyncInterceptor.class;
                    } else if (interceptorType == FindOneReactiveInterceptor.class) {
                        interceptorType = FindByIdReactiveInterceptor.class;
                    }
                }
                return new AbstractMap.SimpleEntry<>(queryResultType, interceptorType);
            }

            private boolean isFindByIdQuery(@NonNull MethodMatchContext matchContext, @NonNull ClassElement queryResultType) {
                return hasIdMatch && matchContext.supportsImplicitQueries() && queryResultType.getName().equals(matchContext.getRootEntity().getName()) && hasNoWhereAndJoinDeclaration(matchContext);
            }
        };
    }
    return null;
}
Also used : QueryCriteriaMethodMatch(io.micronaut.data.processor.visitors.finders.criteria.QueryCriteriaMethodMatch) DataInterceptor(io.micronaut.data.intercept.DataInterceptor) FindByIdAsyncInterceptor(io.micronaut.data.intercept.async.FindByIdAsyncInterceptor) ClassElement(io.micronaut.inject.ast.ClassElement) PersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.PersistentEntityCriteriaQuery) AbstractPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery) SourcePersistentEntityCriteriaBuilder(io.micronaut.data.processor.model.criteria.SourcePersistentEntityCriteriaBuilder) MethodMatchContext(io.micronaut.data.processor.visitors.MethodMatchContext) PersistentEntityRoot(io.micronaut.data.model.jpa.criteria.PersistentEntityRoot) NonNull(io.micronaut.core.annotation.NonNull) AbstractPersistentEntityCriteriaQuery(io.micronaut.data.model.jpa.criteria.impl.AbstractPersistentEntityCriteriaQuery) AbstractMap(java.util.AbstractMap) Map(java.util.Map) FindOneAsyncInterceptor(io.micronaut.data.intercept.async.FindOneAsyncInterceptor)

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