From ff0fb97272526ca548d42ae76fc747338d1291bf Mon Sep 17 00:00:00 2001 From: Jimmy Praet Date: Sat, 2 Mar 2024 22:41:51 +0100 Subject: [PATCH] Implement jumpToItem in JsonItemReader Issue #4557 --- .../batch/item/json/GsonJsonObjectReader.java | 10 +++++++- .../item/json/JacksonJsonObjectReader.java | 12 +++++++++- .../batch/item/json/JsonItemReader.java | 8 ++++++- .../batch/item/json/JsonObjectReader.java | 18 ++++++++++++++- .../json/JsonItemReaderFunctionalTests.java | 23 ++++++++++++++++++- 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/GsonJsonObjectReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/GsonJsonObjectReader.java index 48787430f..c1b49fb4b 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/GsonJsonObjectReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/GsonJsonObjectReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2024 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. @@ -37,6 +37,7 @@ import org.springframework.util.Assert; * * @param type of the target object * @author Mahmoud Ben Hassine + * @author Jimmy Praet * @since 4.1 */ public class GsonJsonObjectReader implements JsonObjectReader { @@ -102,4 +103,11 @@ public class GsonJsonObjectReader implements JsonObjectReader { this.jsonReader.close(); } + @Override + public void jumpToItem(int itemIndex) throws Exception { + for (int i = 0; i < itemIndex; i++) { + this.jsonReader.skipValue(); + } + } + } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JacksonJsonObjectReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JacksonJsonObjectReader.java index 04d7a7b97..df1879240 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JacksonJsonObjectReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JacksonJsonObjectReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 the original author or authors. + * Copyright 2018-2024 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. @@ -34,6 +34,7 @@ import org.springframework.util.Assert; * * @param type of the target object * @author Mahmoud Ben Hassine + * @author Jimmy Praet * @since 4.1 */ public class JacksonJsonObjectReader implements JsonObjectReader { @@ -98,4 +99,13 @@ public class JacksonJsonObjectReader implements JsonObjectReader { this.jsonParser.close(); } + @Override + public void jumpToItem(int itemIndex) throws Exception { + for (int i = 0; i < itemIndex; i++) { + if (this.jsonParser.nextToken() == JsonToken.START_OBJECT) { + this.jsonParser.skipChildren(); + } + } + } + } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonItemReader.java index c39f9886e..a7fdc830f 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonItemReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020 the original author or authors. + * Copyright 2018-2024 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. @@ -47,6 +47,7 @@ import org.springframework.util.ClassUtils; * * @param the type of json objects to read * @author Mahmoud Ben Hassine + * @author Jimmy Praet * @since 4.1 */ public class JsonItemReader extends AbstractItemCountingItemStreamItemReader @@ -136,4 +137,9 @@ public class JsonItemReader extends AbstractItemCountingItemStreamItemReader< this.jsonObjectReader.close(); } + @Override + protected void jumpToItem(int itemIndex) throws Exception { + this.jsonObjectReader.jumpToItem(itemIndex); + } + } diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java index 5793d2e09..d143b71c8 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/json/JsonObjectReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 the original author or authors. + * Copyright 2018-2024 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. @@ -25,6 +25,7 @@ import org.springframework.lang.Nullable; * * @param type of the target object * @author Mahmoud Ben Hassine + * @author Jimmy Praet * @since 4.1 */ public interface JsonObjectReader { @@ -54,4 +55,19 @@ public interface JsonObjectReader { } + /** + * Move to the given item index. Implementations should override this method if there + * is a more efficient way of moving to given index than re-reading the input using + * {@link #read()}. + * @param itemIndex index of item (0 based) to jump to. + * @throws Exception Allows implementations to throw checked exceptions for + * interpretation by the framework + * @since 5.2 + */ + default void jumpToItem(int itemIndex) throws Exception { + for (int i = 0; i < itemIndex; i++) { + read(); + } + } + } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonItemReaderFunctionalTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonItemReaderFunctionalTests.java index 665356f1c..7b6561f45 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonItemReaderFunctionalTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/json/JsonItemReaderFunctionalTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 the original author or authors. + * Copyright 2018-2024 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. @@ -130,4 +130,25 @@ abstract class JsonItemReaderFunctionalTests { assertTrue(getJsonParsingException().isInstance(expectedException.getCause())); } + @Test + void testJumpToItem() throws Exception { + // given + JsonItemReader itemReader = new JsonItemReaderBuilder().jsonObjectReader(getJsonObjectReader()) + .resource(new ClassPathResource("org/springframework/batch/item/json/trades.json")) + .name("tradeJsonItemReader") + .build(); + itemReader.open(new ExecutionContext()); + + // when + itemReader.jumpToItem(3); + + // then + Trade trade = itemReader.read(); + assertNotNull(trade); + assertEquals("100", trade.getIsin()); + assertEquals("barfoo", trade.getCustomer()); + assertEquals(new BigDecimal("1.8"), trade.getPrice()); + assertEquals(4, trade.getQuantity()); + } + }