DATACMNS-293 - General improvements to the augmentation subsystem.

Added QueryMode constants FOR_UPDATE and FOR_DELETE to indicate a query is executed to guard an update or delete. Updated Javadoc and copyright headers. Added Javadoc to explain generic type parameters.
This commit is contained in:
Oliver Gierke
2015-06-29 12:18:48 +02:00
parent fcdba49c35
commit ce16d590f9
8 changed files with 47 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;
/**
* Base class to implement a {@link QueryAugmentor} to soft-delete entities.
*
* @since 1.9
* @since 1.11
* @author Oliver Gierke
*/
public abstract class AbstractSoftDeleteQueryAugmentor<Q extends QueryContext<?>, N extends QueryContext<?>, U extends UpdateContext<?>>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,8 +31,12 @@ import org.springframework.data.repository.core.EntityMetadata;
* {@link #prepareQuery(QueryContext, Annotation)} and {@link #prepareUpdate(UpdateContext, Annotation)} methods. Opts
* out of augmentation in case the annotation cannot be found on the method invoked or in the type.
*
* @since 1.9
* @since 1.11
* @author Oliver Gierke
* @param T the annotation type
* @param Q the {@link QueryContext} type to be used for store specific queries.
* @param N the {@link QueryContext} type to be used to native queries.
* @param U the {@link UpdateContext} type to be used.
*/
public abstract class AnnotationBasedQueryAugmentor<T extends Annotation, Q extends QueryContext<?>, N extends QueryContext<?>, U extends UpdateContext<?>>
implements QueryAugmentor<Q, N, U> {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import org.springframework.data.repository.CrudRepository;
/**
* Interface to abstract {@link MethodMetadata} to be looked up for the repository method invoked.
*
* @see 1.9
* @see 1.11
* @author Oliver Gierke
*/
public interface MethodMetadata {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ import org.springframework.util.MultiValueMap;
* Wrapper for a collection of {@link QueryAugmentor}s. Groups them by the context type they're referring to for the
* appropriate invocation later on.
*
* @since 1.9
* @since 1.11
* @author Oliver Gierke
*/
public class QueryAugmentationEngine {
@@ -125,7 +125,8 @@ public class QueryAugmentationEngine {
return invokeAugmentor(new AugmentorInvoker<T>() {
@SuppressWarnings("unchecked")
public T invokeAugmentor(QueryAugmentor<QueryContext<?>, QueryContext<?>, UpdateContext<?>> augmentor, T context) {
public T invokeAugmentor(QueryAugmentor<QueryContext<?>, QueryContext<?>, UpdateContext<?>> augmentor,
T context) {
return (T) augmentor.augmentNativeQuery(context, methodMetadata);
}
}, context);
@@ -140,7 +141,8 @@ public class QueryAugmentationEngine {
return invokeAugmentor(new AugmentorInvoker<N>() {
@SuppressWarnings("unchecked")
public N invokeAugmentor(QueryAugmentor<QueryContext<?>, QueryContext<?>, UpdateContext<?>> augmentor, N context) {
public N invokeAugmentor(QueryAugmentor<QueryContext<?>, QueryContext<?>, UpdateContext<?>> augmentor,
N context) {
return (N) augmentor.augmentQuery(context, methodMetadata);
}
}, context);
@@ -156,7 +158,8 @@ public class QueryAugmentationEngine {
return invokeAugmentor(new AugmentorInvoker<U>() {
@SuppressWarnings("unchecked")
public U invokeAugmentor(QueryAugmentor<QueryContext<?>, QueryContext<?>, UpdateContext<?>> augmentor, U context) {
public U invokeAugmentor(QueryAugmentor<QueryContext<?>, QueryContext<?>, UpdateContext<?>> augmentor,
U context) {
return (U) augmentor.augmentUpdate(context, methodMetadata);
}
}, context);
@@ -167,8 +170,8 @@ public class QueryAugmentationEngine {
Assert.notNull(context, "UpdateContext must not be null!");
T augmentedContext = context;
for (QueryAugmentor<QueryContext<?>, QueryContext<?>, UpdateContext<?>> augmentor : augmentors.get(context
.getClass())) {
for (QueryAugmentor<QueryContext<?>, QueryContext<?>, UpdateContext<?>> augmentor : augmentors
.get(context.getClass())) {
LOGGER.debug("Invoking augmentor {} for context {}", augmentor, context);
augmentedContext = invoker.invokeAugmentor(augmentor, augmentedContext);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import org.springframework.data.repository.core.support.RepositoryFactorySupport
* Injection interface to express the dependency to a {@link QueryAugmentationEngine}. Usually implemented by repository
* implementations. The {@link RepositoryFactorySupport} base class will inject the {@link QueryAugmentationEngine}.
*
* @since 1.9
* @since 1.11
* @author Oliver Gierke
*/
public interface QueryAugmentationEngineAware {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,10 +21,13 @@ import org.springframework.data.repository.core.EntityMetadata;
/**
* SPI to abstract components that want to augment queries executed by the repositories.
*
* @since 1.9
* @since 1.11
* @author Oliver Gierke
* @param Q the {@link QueryContext} type to be used for store specific queries.
* @param N the {@link QueryContext} type to be used to native queries.
* @param U the {@link UpdateContext} type to be used.
*/
public interface QueryAugmentor<Q extends QueryContext<?>, N extends QueryContext<?>, S extends UpdateContext<?>> {
public interface QueryAugmentor<Q extends QueryContext<?>, N extends QueryContext<?>, U extends UpdateContext<?>> {
/**
* Determines whether the implementation is interested in augmentation at all. The implementations can expect to only
@@ -39,26 +42,26 @@ public interface QueryAugmentor<Q extends QueryContext<?>, N extends QueryContex
*/
boolean supports(MethodMetadata method, QueryMode queryMode, EntityMetadata<?> entityMetadata);
N augmentNativeQuery(N query, MethodMetadata methodMetadata);
N augmentNativeQuery(N context, MethodMetadata methodMetadata);
/**
* Augments the query by either adding further constraints to it or entirely replacing it. Clients will use
* {@link QueryContext#getQuery()} proceeding with the query execution.
*
* @param query the query context of the query about to be executed.
* @param context the query context of the query about to be executed.
* @param methodMetadata metadata about the repository method being invoked.
* @return must not be {@literal null}.
*/
Q augmentQuery(Q query, MethodMetadata methodMetadata);
Q augmentQuery(Q context, MethodMetadata methodMetadata);
/**
* Augments the update about to be executed. Implementations can prevent the original update from being executed by
* returning null.
*
* @param update the update context of the update about to be executed
* @param context the update context of the update about to be executed
* @param methodMetadata metadata about the repository method being invoked.
* @return the update to continue to work with or {@literal null} in case the implementation already executed custom
* update and wants to prevent the execution of the original update.
*/
S augmentUpdate(S update, MethodMetadata methodMetadata);
U augmentUpdate(U context, MethodMetadata methodMetadata);
}

View File

@@ -57,7 +57,17 @@ public class QueryContext<T> {
/**
* To be used for the execution of the additional count query to be executed when paging.
*/
COUNT_FOR_PAGING;
COUNT_FOR_PAGING,
/**
* To be used for the execution of queries that precede an update.
*/
FOR_UPDATE,
/**
* To be used for the execution of queries that precede a delete.
*/
FOR_DELETE;
/**
* Returns whether the {@link QueryMode} is one of the given ones.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import org.springframework.util.Assert;
/**
* Context to be handed around for update executions.
*
* @since 1.9
* @since 1.11
* @author Oliver Gierke
*/
public class UpdateContext<T> {
@@ -28,7 +28,7 @@ public class UpdateContext<T> {
/**
* The mode of the update execution.
*
* @since 1.9
* @since 1.11
* @author Oliver Gierke
*/
public static enum UpdateMode {