diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java index 3552ca8e4..9d426baa6 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilder.java @@ -30,6 +30,7 @@ import org.springframework.cglib.proxy.MethodProxy; import org.springframework.data.domain.Sort; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; /** @@ -123,11 +124,14 @@ public class RepositoryItemReaderBuilder } /** - * Specifies a repository and the type-safe method to call for the reader. This method - * must take {@link org.springframework.data.domain.Pageable} as the last - * argument. This method can be used in place of {@link #methodName(String)}, - * {@link #arguments(List)} and {@link #repository(PagingAndSortingRepository)}. The - * repository that is used by the repositoryMethodReference must be non-final. + * Specifies a repository and the type-safe method to call for the reader. The method + * configured via this mechanism must take + * {@link org.springframework.data.domain.Pageable} as the last + * argument. This method can be used in place of {@link #repository(PagingAndSortingRepository)}, + * {@link #methodName(String)}, and {@link #arguments(List)}. + * + * Note: The repository that is used by the repositoryMethodReference must be + * non-final. * * @param repositoryMethodReference of the used to get a repository and type-safe * method for use by the reader. @@ -151,7 +155,10 @@ public class RepositoryItemReaderBuilder if (this.repositoryMethodReference != null) { this.methodName = this.repositoryMethodReference.getMethodName(); this.repository = this.repositoryMethodReference.getRepository(); - this.arguments = this.repositoryMethodReference.getArguments(); + + if(CollectionUtils.isEmpty(this.arguments)) { + this.arguments = this.repositoryMethodReference.getArguments(); + } } Assert.notNull(this.sorts, "sorts map is required."); @@ -177,7 +184,8 @@ public class RepositoryItemReaderBuilder /** * Establishes a proxy that will capture a the Repository and the associated * methodName that will be used by the reader. - * @param The type of repository that will be used by the reader. + * @param The type of repository that will be used by the reader. The class must + * not be final. */ public static class RepositoryMethodReference { private RepositoryMethodIterceptor repositoryInvocationHandler; @@ -201,15 +209,15 @@ public class RepositoryItemReaderBuilder return (T) enhancer.create(); } - public PagingAndSortingRepository getRepository() { + PagingAndSortingRepository getRepository() { return this.repository; } - public String getMethodName() { + String getMethodName() { return this.repositoryInvocationHandler.getMethodName(); } - public List getArguments() { + List getArguments() { return this.repositoryInvocationHandler.getArguments(); } } @@ -231,11 +239,11 @@ public class RepositoryItemReaderBuilder return null; } - public String getMethodName() { + String getMethodName() { return this.methodName; } - public List getArguments() { + List getArguments() { return arguments; } } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java index f0c7efaaa..be37188f0 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/data/builder/RepositoryItemReaderBuilderTests.java @@ -47,7 +47,7 @@ public class RepositoryItemReaderBuilderTests { private static final String ARG2 = "bar"; private static final String ARG3 = "baz"; - public static final String TEST_CONTENT = "FOOBAR"; + private static final String TEST_CONTENT = "FOOBAR"; @Mock private TestRepository repository; @@ -57,18 +57,16 @@ public class RepositoryItemReaderBuilderTests { private Map sorts; - private List testResult; - private ArgumentCaptor pageRequestContainer; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - this.sorts = new HashMap(); + this.sorts = new HashMap<>(); this.sorts.put("id", Sort.Direction.ASC); this.pageRequestContainer = ArgumentCaptor.forClass(PageRequest.class); - testResult = new ArrayList<>(); + List testResult = new ArrayList<>(); testResult.add(TEST_CONTENT); when(page.getContent()).thenReturn(testResult); when(page.getSize()).thenReturn(5); @@ -77,8 +75,12 @@ public class RepositoryItemReaderBuilderTests { @Test public void testBasicRead() throws Exception { - RepositoryItemReader reader = new RepositoryItemReaderBuilder().repository(this.repository) - .sorts(this.sorts).maxItemCount(5).methodName("foo").name("bar").build(); + RepositoryItemReader reader = new RepositoryItemReaderBuilder<>().repository(this.repository) + .sorts(this.sorts) + .maxItemCount(5) + .methodName("foo") + .name("bar") + .build(); String result = (String) reader.read(); assertEquals("Result returned from reader was not expected value.", TEST_CONTENT, result); assertEquals("page size was not expected value.", 10, this.pageRequestContainer.getValue().getPageSize()); @@ -86,10 +88,10 @@ public class RepositoryItemReaderBuilderTests { @Test public void testRepositoryMethodReference() throws Exception { - RepositoryItemReaderBuilder.RepositoryMethodReference repositoryMethodReference = new RepositoryItemReaderBuilder.RepositoryMethodReference( - this.repository); + RepositoryItemReaderBuilder.RepositoryMethodReference repositoryMethodReference = + new RepositoryItemReaderBuilder.RepositoryMethodReference<>(this.repository); repositoryMethodReference.methodIs().foo(null); - RepositoryItemReader reader = new RepositoryItemReaderBuilder() + RepositoryItemReader reader = new RepositoryItemReaderBuilder<>() .repository(repositoryMethodReference) .sorts(this.sorts) .maxItemCount(5) @@ -101,10 +103,10 @@ public class RepositoryItemReaderBuilderTests { @Test public void testRepositoryMethodReferenceWithArgs() throws Exception { - RepositoryItemReaderBuilder.RepositoryMethodReference repositoryMethodReference = new RepositoryItemReaderBuilder.RepositoryMethodReference( - this.repository); + RepositoryItemReaderBuilder.RepositoryMethodReference repositoryMethodReference = + new RepositoryItemReaderBuilder.RepositoryMethodReference<>(this.repository); repositoryMethodReference.methodIs().foo(ARG1, ARG2, ARG3, null); - RepositoryItemReader reader = new RepositoryItemReaderBuilder() + RepositoryItemReader reader = new RepositoryItemReaderBuilder<>() .repository(repositoryMethodReference) .sorts(this.sorts) .maxItemCount(5) @@ -122,15 +124,25 @@ public class RepositoryItemReaderBuilderTests { @Test public void testCurrentItemCount() throws Exception { - RepositoryItemReader reader = new RepositoryItemReaderBuilder().repository(this.repository) - .sorts(this.sorts).currentItemCount(6).maxItemCount(5).methodName("foo").name("bar").build(); + RepositoryItemReader reader = new RepositoryItemReaderBuilder<>().repository(this.repository) + .sorts(this.sorts) + .currentItemCount(6) + .maxItemCount(5) + .methodName("foo") + .name("bar") + .build(); assertNull("Result returned from reader was not null.", reader.read()); } @Test public void testPageSize() throws Exception { - RepositoryItemReader reader = new RepositoryItemReaderBuilder().repository(this.repository) - .sorts(this.sorts).maxItemCount(5).methodName("foo").name("bar").pageSize(2).build(); + RepositoryItemReader reader = new RepositoryItemReaderBuilder<>().repository(this.repository) + .sorts(this.sorts) + .maxItemCount(5) + .methodName("foo") + .name("bar") + .pageSize(2) + .build(); reader.read(); assertEquals("page size was not expected value.", 2, this.pageRequestContainer.getValue().getPageSize()); } @@ -138,7 +150,9 @@ public class RepositoryItemReaderBuilderTests { @Test public void testNoMethodName() throws Exception { try { - new RepositoryItemReaderBuilder().repository(this.repository).sorts(this.sorts).maxItemCount(10) + new RepositoryItemReaderBuilder<>().repository(this.repository) + .sorts(this.sorts) + .maxItemCount(10) .build(); fail("IllegalArgumentException should have been thrown"); @@ -148,8 +162,11 @@ public class RepositoryItemReaderBuilderTests { "methodName is required.", iae.getMessage()); } try { - new RepositoryItemReaderBuilder().repository(this.repository).sorts(this.sorts).methodName("") - .maxItemCount(5).build(); + new RepositoryItemReaderBuilder<>().repository(this.repository) + .sorts(this.sorts) + .methodName("") + .maxItemCount(5) + .build(); fail("IllegalArgumentException should have been thrown"); } @@ -162,8 +179,11 @@ public class RepositoryItemReaderBuilderTests { @Test public void testSaveState() throws Exception { try { - new RepositoryItemReaderBuilder().repository(repository).methodName("foo").sorts(sorts) - .maxItemCount(5).build(); + new RepositoryItemReaderBuilder<>().repository(repository) + .methodName("foo") + .sorts(sorts) + .maxItemCount(5) + .build(); fail("IllegalArgumentException should have been thrown"); } @@ -173,15 +193,21 @@ public class RepositoryItemReaderBuilderTests { } // No IllegalStateException for a name that is not set, should not be thrown since // saveState was false. - new RepositoryItemReaderBuilder().repository(repository).saveState(false).methodName("foo").sorts(sorts) - .maxItemCount(5).build(); + new RepositoryItemReaderBuilder<>().repository(repository) + .saveState(false) + .methodName("foo") + .sorts(sorts) + .maxItemCount(5) + .build(); } @Test public void testNullSort() throws Exception { try { - new RepositoryItemReaderBuilder().repository(repository).methodName("foo") - .maxItemCount(5).build(); + new RepositoryItemReaderBuilder<>().repository(repository) + .methodName("foo") + .maxItemCount(5) + .build(); fail("IllegalArgumentException should have been thrown"); } @@ -194,7 +220,10 @@ public class RepositoryItemReaderBuilderTests { @Test public void testNoRepository() throws Exception { try { - new RepositoryItemReaderBuilder().sorts(this.sorts).maxItemCount(10).methodName("foo").build(); + new RepositoryItemReaderBuilder<>().sorts(this.sorts) + .maxItemCount(10) + .methodName("foo") + .build(); fail("IllegalArgumentException should have been thrown"); } @@ -216,18 +245,23 @@ public class RepositoryItemReaderBuilderTests { when(this.repository.foo(arg1Captor.capture(), arg2Captor.capture(), arg3Captor.capture(), this.pageRequestContainer.capture())).thenReturn(this.page); - RepositoryItemReader reader = new RepositoryItemReaderBuilder().repository(this.repository) - .sorts(this.sorts).maxItemCount(5).methodName("foo").name("bar").arguments(args).build(); + RepositoryItemReader reader = new RepositoryItemReaderBuilder<>().repository(this.repository) + .sorts(this.sorts) + .maxItemCount(5) + .methodName("foo") + .name("bar") + .arguments(args) + .build(); String result = (String) reader.read(); verifyMultiArgRead(arg1Captor, arg2Captor, arg3Captor, result); } - public static interface TestRepository extends PagingAndSortingRepository { + public interface TestRepository extends PagingAndSortingRepository { - public Object foo(PageRequest request); + Object foo(PageRequest request); - public Object foo(String arg1, String arg2, String arg3, PageRequest request); + Object foo(String arg1, String arg2, String arg3, PageRequest request); } private void verifyMultiArgRead(ArgumentCaptor arg1Captor, ArgumentCaptor arg2Captor, ArgumentCaptor arg3Captor, String result) {