From c61a1dace10bd3848290088204c36f1d5ed79dc5 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Mon, 6 Nov 2023 12:24:02 +0530 Subject: [PATCH 01/71] BAEL-7091 Asserting Nested Map with JUnit --- testing-modules/hamcrest/pom.xml | 12 +++ .../AssertNestedMapUnitTest.java | 94 +++++++++++++++++++ .../matchers/NestedMapMatcher.java | 38 ++++++++ 3 files changed, 144 insertions(+) create mode 100644 testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java create mode 100644 testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java diff --git a/testing-modules/hamcrest/pom.xml b/testing-modules/hamcrest/pom.xml index df8c543edb..b5a8277deb 100644 --- a/testing-modules/hamcrest/pom.xml +++ b/testing-modules/hamcrest/pom.xml @@ -6,6 +6,18 @@ hamcrest 0.0.1-SNAPSHOT hamcrest + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + jar diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java new file mode 100644 index 0000000000..42c225695c --- /dev/null +++ b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java @@ -0,0 +1,94 @@ +package com.baeldung.hamcrest.assertnestedmap; + + +import org.junit.jupiter.api.Test; + +import java.util.Map; + +import static com.baeldung.hamcrest.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.*; + +public class AssertNestedMapUnitTest { + + @Test + void givenNestedMap_whenUseJupiterAssertTrueWithoutCasting_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + + assertTrue(outerMap.containsKey("address") && outerMap.get("address").get("city").equals("Chicago")); + } + + @Test + void givenNestedMap_whenUseJupiterAssertAllAndAssertTrue_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + + assertAll( + () -> assertTrue(outerMap.containsKey("address")), + () -> assertEquals(outerMap.get("address").get("city"), "Chicago") + ); + } + + @Test + void givenNestedMap_whenUseJupiterAssertTrueWithCasting_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); + + assertTrue(outerMap.containsKey("address") + && ((Map)outerMap.get("address")).get("city").equals("Chicago")); + } + + @Test + void givenNestedMap_whenUseHamcrestAssertThat_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + assertAll( + () -> assertThat(outerMap, hasKey("address")), + () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) + ); + } + + @Test + void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThat_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); + + assertThat(outerMap, hasEntry(equalTo("address"), hasEntry("city", "Chicago"))); + } + + @Test + void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map> outerMap = Map.of("address", innerMap); + + assertThat(outerMap, hasNestedMapEntry("address", innerMap)); + } + + @Test + void givenOuterMapOfStringAndObjectAndInnerMap_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map outerMap = Map.of("address", innerMap); + + assertThat(outerMap, hasNestedMapEntry("address", innerMap)); + } + + + @Test + void givenNestedMap_whenUseHamcrestAssertThatWithCasting_thenTest() { + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); + + assertThat((Map)outerMap.get("address"), hasEntry("city", "Chicago")); + } + +} diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java new file mode 100644 index 0000000000..760edebb35 --- /dev/null +++ b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java @@ -0,0 +1,38 @@ +package com.baeldung.hamcrest.assertnestedmap.matchers; + + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +import java.util.Map; + +public class NestedMapMatcher extends TypeSafeMatcher> { + private K key; + private V subMapValue; + + public NestedMapMatcher(K key, V subMapValue) { + this.key = key; + this.subMapValue = subMapValue; + } + + @Override + protected boolean matchesSafely(Map item) { + if (item.containsKey(key)) { + Object actualValue = item.get(key); + return subMapValue.equals(actualValue); + } + return false; + } + + @Override + public void describeTo(Description description) { + description.appendText("a map containing key ").appendValue(key) + .appendText(" with value ").appendValue(subMapValue); + } + + public static Matcher hasNestedMapEntry(K key, V expectedValue) { + return new NestedMapMatcher(key, expectedValue); + } +} + From e9431ce416773b07ea3efc42bc1a4cbaa783114a Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:27:07 +0530 Subject: [PATCH 02/71] BAEL-7091 Formatting fixed --- .../assertnestedmap/AssertNestedMapUnitTest.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java index 42c225695c..b5b4d652a0 100644 --- a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java +++ b/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java @@ -11,7 +11,6 @@ import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.*; public class AssertNestedMapUnitTest { - @Test void givenNestedMap_whenUseJupiterAssertTrueWithoutCasting_thenTest() { Map innerMap = Map.of("city", "Chicago"); @@ -26,8 +25,8 @@ public class AssertNestedMapUnitTest { Map> outerMap = Map.of("address", innerMap); assertAll( - () -> assertTrue(outerMap.containsKey("address")), - () -> assertEquals(outerMap.get("address").get("city"), "Chicago") + () -> assertTrue(outerMap.containsKey("address")), + () -> assertEquals(outerMap.get("address").get("city"), "Chicago") ); } @@ -45,8 +44,8 @@ public class AssertNestedMapUnitTest { Map innerMap = Map.of("city", "Chicago"); Map> outerMap = Map.of("address", innerMap); assertAll( - () -> assertThat(outerMap, hasKey("address")), - () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) + () -> assertThat(outerMap, hasKey("address")), + () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) ); } @@ -82,7 +81,6 @@ public class AssertNestedMapUnitTest { assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } - @Test void givenNestedMap_whenUseHamcrestAssertThatWithCasting_thenTest() { Map innerMap = Map.of("city", "Chicago"); From 47c755435251a26f72cdf64ed8d04b5c84aa3954 Mon Sep 17 00:00:00 2001 From: luca Date: Fri, 10 Nov 2023 14:30:22 +0100 Subject: [PATCH 03/71] feat: override spring bean --- .../com/baeldung/overridebean/Endpoint.java | 19 ++++++++++ .../com/baeldung/overridebean/Service.java | 5 +++ .../baeldung/overridebean/ServiceImpl.java | 8 ++++ .../overridebean/basic/Application.java | 14 +++++++ .../baeldung/overridebean/basic/Config.java | 16 ++++++++ .../overridebean/conditional/Application.java | 14 +++++++ .../conditional/ConditionalConfig.java | 18 +++++++++ .../overridebean/profile/Application.java | 14 +++++++ .../overridebean/profile/ProfileConfig.java | 18 +++++++++ .../src/main/resources/application.properties | 1 + .../conditional/ConditionIntegrationTest.java | 29 +++++++++++++++ .../conditional/ConditionalStub.java | 10 +++++ .../conditional/ConditionalTestConfig.java | 17 +++++++++ .../mockbean/MockBeanIntegrationTest.java | 37 +++++++++++++++++++ ...OverrideBeanDefinitionIntegrationTest.java | 31 ++++++++++++++++ .../OverrideBeanDefinitionServiceStub.java | 10 +++++ .../OverrideBeanDefinitionTestConfig.java | 15 ++++++++ .../primary/PrimaryIntegrationTest.java | 31 ++++++++++++++++ .../primary/PrimaryServiceStub.java | 10 +++++ .../primary/PrimaryTestConfig.java | 17 +++++++++ .../profile/ProfileIntegrationTest.java | 29 +++++++++++++++ .../profile/ProfileServiceStub.java | 10 +++++ .../profile/ProfileTestConfig.java | 15 ++++++++ 23 files changed, 388 insertions(+) create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java new file mode 100644 index 0000000000..e199d1f25b --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Endpoint.java @@ -0,0 +1,19 @@ +package com.baeldung.overridebean; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class Endpoint { + + private final Service service; + + public Endpoint(Service service) { + this.service = service; + } + + @GetMapping("/hello") + public String helloWorldEndpoint() { + return service.helloWorld(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java new file mode 100644 index 0000000000..0872fcc372 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Service.java @@ -0,0 +1,5 @@ +package com.baeldung.overridebean; + +public interface Service { + String helloWorld(); +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java new file mode 100644 index 0000000000..4d4b5582e6 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/ServiceImpl.java @@ -0,0 +1,8 @@ +package com.baeldung.overridebean; + +public class ServiceImpl implements Service { + + public String helloWorld() { + return "hello world"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java new file mode 100644 index 0000000000..6f9acde3d8 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.overridebean.basic; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java new file mode 100644 index 0000000000..67d999958d --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java @@ -0,0 +1,16 @@ +package com.baeldung.overridebean.basic; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.ServiceImpl; + +@Configuration +public class Config { + + @Bean + public Service helloWorld() { + return new ServiceImpl(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java new file mode 100644 index 0000000000..9c4cdbf8ec --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.overridebean.conditional; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java new file mode 100644 index 0000000000..e18689e042 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/ConditionalConfig.java @@ -0,0 +1,18 @@ +package com.baeldung.overridebean.conditional; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.ServiceImpl; + +@Configuration +public class ConditionalConfig { + + @Bean + @ConditionalOnProperty(name = "service.stub", havingValue = "false") + public Service helloWorld() { + return new ServiceImpl(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java new file mode 100644 index 0000000000..d3298b2eb4 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java @@ -0,0 +1,14 @@ +package com.baeldung.overridebean.profile; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; + +@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java new file mode 100644 index 0000000000..64cdfff8a5 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/ProfileConfig.java @@ -0,0 +1,18 @@ +package com.baeldung.overridebean.profile; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.ServiceImpl; + +@Configuration +@Profile("prod") +public class ProfileConfig { + + @Bean + public Service helloWorld() { + return new ServiceImpl(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties b/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties index b628a708bd..0982b7bac0 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties +++ b/spring-boot-modules/spring-boot-testing-2/src/main/resources/application.properties @@ -1,2 +1,3 @@ keycloak.enabled=true spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8180/auth/realms/baeldung-api +service.stub=false \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java new file mode 100644 index 0000000000..5f6b1d128f --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java @@ -0,0 +1,29 @@ +package com.baeldung.overridebean.conditional; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; + +@SpringBootTest(classes = { Application.class, ConditionalConfig.class, Endpoint.class, ConditionalTestConfig.class }, properties = "service.stub=true") +@AutoConfigureMockMvc +class ConditionIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenConditionalConfig_whenServiceStubIsTrue_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello conditional stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java new file mode 100644 index 0000000000..6b3e447108 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.conditional; + +import com.baeldung.overridebean.Service; + +public class ConditionalStub implements Service { + + public String helloWorld() { + return "hello conditional stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java new file mode 100644 index 0000000000..c48c4e2266 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.overridebean.conditional; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class ConditionalTestConfig { + + @ConditionalOnProperty(name = "service.stub", havingValue = "true") + @Bean + public Service helloWorld() { + return new ConditionalStub(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java new file mode 100644 index 0000000000..6a7be1cbda --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java @@ -0,0 +1,37 @@ +package com.baeldung.overridebean.mockbean; + +import static org.hamcrest.Matchers.containsString; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.basic.Application; + +@SpringBootTest(classes = { Application.class, Endpoint.class }) +@AutoConfigureMockMvc +class MockBeanIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private Service serviceExample; + + @Test + void givenServiceMockBean_whenGetHelloEndpoint_thenMockOk() throws Exception { + when(serviceExample.helloWorld()).thenReturn("hello mock bean"); + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello mock bean"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java new file mode 100644 index 0000000000..0f3753ef34 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java @@ -0,0 +1,31 @@ +package com.baeldung.overridebean.overridebeandefinition; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.basic.Application; +import com.baeldung.overridebean.basic.Config; + +@SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, OverrideBeanDefinitionTestConfig.class }, properties = "spring.main.allow-bean-definition-overriding=true") +@AutoConfigureMockMvc +class OverrideBeanDefinitionIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenNoProfile_whenAllowBeanDefinitionOverriding_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello no profile stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java new file mode 100644 index 0000000000..d06b43cf24 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionServiceStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.overridebeandefinition; + +import com.baeldung.overridebean.Service; + +public class OverrideBeanDefinitionServiceStub implements Service { + + public String helloWorld() { + return "hello no profile stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java new file mode 100644 index 0000000000..5c35304296 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionTestConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.overridebean.overridebeandefinition; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class OverrideBeanDefinitionTestConfig { + + @Bean + public Service helloWorld() { + return new OverrideBeanDefinitionServiceStub(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java new file mode 100644 index 0000000000..2bddfd4637 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java @@ -0,0 +1,31 @@ +package com.baeldung.overridebean.primary; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.basic.Application; +import com.baeldung.overridebean.basic.Config; + +@SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, PrimaryTestConfig.class }) +@AutoConfigureMockMvc +class PrimaryIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenTestConfiguration_whenPrimaryBeanIsDefined_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello primary stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java new file mode 100644 index 0000000000..1d3d887f99 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryServiceStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.primary; + +import com.baeldung.overridebean.Service; + +public class PrimaryServiceStub implements Service { + + public String helloWorld() { + return "hello primary stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java new file mode 100644 index 0000000000..3765377b41 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryTestConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.overridebean.primary; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class PrimaryTestConfig { + + @Primary + @Bean("service.stub") + public Service helloWorld() { + return new PrimaryServiceStub(); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java new file mode 100644 index 0000000000..deabfea9e5 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java @@ -0,0 +1,29 @@ +package com.baeldung.overridebean.profile; + +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; + +@SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) +@AutoConfigureMockMvc +class ProfileIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void givenConfigurationWithProfile_whenNoProductionProfileIsActive_thenStubOk() throws Exception { + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello profile stub"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java new file mode 100644 index 0000000000..ef1f2e7a22 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileServiceStub.java @@ -0,0 +1,10 @@ +package com.baeldung.overridebean.profile; + +import com.baeldung.overridebean.Service; + +public class ProfileServiceStub implements Service { + + public String helloWorld() { + return "hello profile stub"; + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java new file mode 100644 index 0000000000..edd33162e0 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java @@ -0,0 +1,15 @@ +package com.baeldung.overridebean.profile; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import com.baeldung.overridebean.Service; + +@TestConfiguration +public class ProfileTestConfig { + + @Bean + public Service helloWorld() { + return new ProfileServiceStub(); + } +} From 1e13611b4de219f646c491eeb382e5a04bfac856 Mon Sep 17 00:00:00 2001 From: luca Date: Fri, 10 Nov 2023 15:09:18 +0100 Subject: [PATCH 04/71] Trigger Jenkins From cd9ab90fc857627079b9f57c7fc894fdd63f8669 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Fri, 10 Nov 2023 20:51:43 +0530 Subject: [PATCH 05/71] BAEL-7091 Moved to new module --- testing-modules/hamcrest/pom.xml | 12 ------------ testing-modules/testing-assertions/pom.xml | 12 ++++++++++++ .../assertnestedmap/AssertNestedMapUnitTest.java | 4 ++-- .../assertnestedmap/matchers/NestedMapMatcher.java | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) rename testing-modules/{hamcrest/src/test/java/com/baeldung/hamcrest => testing-assertions/src/test/java/com/baeldung}/assertnestedmap/AssertNestedMapUnitTest.java (95%) rename testing-modules/{hamcrest/src/test/java/com/baeldung/hamcrest => testing-assertions/src/test/java/com/baeldung}/assertnestedmap/matchers/NestedMapMatcher.java (94%) diff --git a/testing-modules/hamcrest/pom.xml b/testing-modules/hamcrest/pom.xml index b5a8277deb..df8c543edb 100644 --- a/testing-modules/hamcrest/pom.xml +++ b/testing-modules/hamcrest/pom.xml @@ -6,18 +6,6 @@ hamcrest 0.0.1-SNAPSHOT hamcrest - - - - org.apache.maven.plugins - maven-compiler-plugin - - 9 - 9 - - - - jar diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml index 1da53bd77e..1f2b4e335d 100644 --- a/testing-modules/testing-assertions/pom.xml +++ b/testing-modules/testing-assertions/pom.xml @@ -4,6 +4,18 @@ 4.0.0 testing-assertions 0.0.1-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + com.baeldung diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java similarity index 95% rename from testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java rename to testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java index b5b4d652a0..7c48a5eb4a 100644 --- a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/AssertNestedMapUnitTest.java +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java @@ -1,11 +1,11 @@ -package com.baeldung.hamcrest.assertnestedmap; +package com.baeldung.assertnestedmap; import org.junit.jupiter.api.Test; import java.util.Map; -import static com.baeldung.hamcrest.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; +import static com.baeldung.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; import static org.junit.jupiter.api.Assertions.*; diff --git a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/matchers/NestedMapMatcher.java similarity index 94% rename from testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java rename to testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/matchers/NestedMapMatcher.java index 760edebb35..961130bb20 100644 --- a/testing-modules/hamcrest/src/test/java/com/baeldung/hamcrest/assertnestedmap/matchers/NestedMapMatcher.java +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/matchers/NestedMapMatcher.java @@ -1,4 +1,4 @@ -package com.baeldung.hamcrest.assertnestedmap.matchers; +package com.baeldung.assertnestedmap.matchers; import org.hamcrest.Description; From 87018d44aedd2f215c1598aec8c782c01d38adbb Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sat, 11 Nov 2023 06:55:11 +0200 Subject: [PATCH 06/71] [JAVA-26715] Upgraded pdfbox to latest version --- pdf-2/pom.xml | 2 +- .../pdfinfo/PdfInfoITextUnitTest.java | 22 ++++++++++--------- .../pdfinfo/PdfInfoPdfBoxUnitTest.java | 22 ++++++++++--------- pdf/pom.xml | 2 +- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/pdf-2/pom.xml b/pdf-2/pom.xml index ccbb5c9693..2079ff70e5 100644 --- a/pdf-2/pom.xml +++ b/pdf-2/pom.xml @@ -51,7 +51,7 @@ 5.5.13.3 7.2.3 3.0.1 - 3.0.0-RC1 + 3.0.0 \ No newline at end of file diff --git a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java index 422858d659..f54405a533 100644 --- a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java +++ b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoITextUnitTest.java @@ -1,29 +1,31 @@ package com.baeldung.pdfinfo; -import org.junit.Assert; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import java.io.IOException; import java.util.Map; -public class PdfInfoITextUnitTest { +import org.junit.jupiter.api.Test; + +class PdfInfoITextUnitTest { private static final String PDF_FILE = "src/test/resources/input.pdf"; @Test - public void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { - Assert.assertEquals(4, PdfInfoIText.getNumberOfPages(PDF_FILE)); + void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { + assertEquals(4, PdfInfoIText.getNumberOfPages(PDF_FILE)); } @Test - public void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { - Assert.assertFalse(PdfInfoIText.isPasswordRequired(PDF_FILE)); + void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { + assertFalse(PdfInfoIText.isPasswordRequired(PDF_FILE)); } @Test - public void givenPdf_whenGetInfo_thenOK() throws IOException { + void givenPdf_whenGetInfo_thenOK() throws IOException { Map info = PdfInfoIText.getInfo(PDF_FILE); - Assert.assertEquals("LibreOffice 4.2", info.get("Producer")); - Assert.assertEquals("Writer", info.get("Creator")); + assertEquals("LibreOffice 4.2", info.get("Producer")); + assertEquals("Writer", info.get("Creator")); } } diff --git a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java index 0fcbc7ee3c..5c4e5fc30d 100644 --- a/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java +++ b/pdf-2/src/test/java/com/baeldung/pdfinfo/PdfInfoPdfBoxUnitTest.java @@ -1,29 +1,31 @@ package com.baeldung.pdfinfo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + import org.apache.pdfbox.pdmodel.PDDocumentInformation; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.IOException; -public class PdfInfoPdfBoxUnitTest { +class PdfInfoPdfBoxUnitTest { private static final String PDF_FILE = "src/test/resources/input.pdf"; @Test - public void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { - Assert.assertEquals(4, PdfInfoPdfBox.getNumberOfPages(PDF_FILE)); + void givenPdf_whenGetNumberOfPages_thenOK() throws IOException { + assertEquals(4, PdfInfoPdfBox.getNumberOfPages(PDF_FILE)); } @Test - public void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { - Assert.assertFalse(PdfInfoPdfBox.isPasswordRequired(PDF_FILE)); + void givenPdf_whenIsPasswordRequired_thenOK() throws IOException { + assertFalse(PdfInfoPdfBox.isPasswordRequired(PDF_FILE)); } @Test - public void givenPdf_whenGetInfo_thenOK() throws IOException { + void givenPdf_whenGetInfo_thenOK() throws IOException { PDDocumentInformation info = PdfInfoPdfBox.getInfo(PDF_FILE); - Assert.assertEquals("LibreOffice 4.2", info.getProducer()); - Assert.assertEquals("Writer", info.getCreator()); + assertEquals("LibreOffice 4.2", info.getProducer()); + assertEquals("Writer", info.getCreator()); } } diff --git a/pdf/pom.xml b/pdf/pom.xml index cead1b2ded..0fe90b6eb5 100644 --- a/pdf/pom.xml +++ b/pdf/pom.xml @@ -104,7 +104,7 @@ - 2.0.25 + 3.0.0 2.0.1 5.5.13.3 5.5.10 From c5cbb3f0d98d88531bda791ee49463c4411129f0 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 08:52:18 +0200 Subject: [PATCH 07/71] [JAVA-26763] Upgraded powermock to latest version --- spring-web-modules/spring-mvc-velocity/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-web-modules/spring-mvc-velocity/pom.xml b/spring-web-modules/spring-mvc-velocity/pom.xml index 676fa09dac..cc92e8c6a5 100644 --- a/spring-web-modules/spring-mvc-velocity/pom.xml +++ b/spring-web-modules/spring-mvc-velocity/pom.xml @@ -64,7 +64,7 @@ org.powermock - powermock-api-mockito + powermock-api-mockito2 ${powermock.version} test @@ -106,7 +106,7 @@ - 1.6.6 + 2.0.9 4.4.5 4.5.2 1.7 From e6cb1a2e43c3c84dbfc1799dda2bb0052f47b2aa Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 17:34:55 +0200 Subject: [PATCH 08/71] [JAVA-26714] Upgraded commons-codec to latest version --- algorithms-modules/pom.xml | 2 +- apache-httpclient4/pom.xml | 2 +- aws-modules/aws-miscellaneous/pom.xml | 2 +- aws-modules/aws-s3/pom.xml | 2 +- core-java-modules/core-java-networking-2/pom.xml | 2 +- core-java-modules/core-java-numbers-6/pom.xml | 2 +- core-java-modules/core-java-security-2/pom.xml | 2 +- core-java-modules/core-java-security-3/pom.xml | 2 +- core-java-modules/core-java-string-operations-2/pom.xml | 2 +- httpclient-simple/pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/algorithms-modules/pom.xml b/algorithms-modules/pom.xml index 342662ce9c..fda8eea0e7 100644 --- a/algorithms-modules/pom.xml +++ b/algorithms-modules/pom.xml @@ -28,7 +28,7 @@ - 1.11 + 1.16.0 3.6.1 2.7 1.0.1 diff --git a/apache-httpclient4/pom.xml b/apache-httpclient4/pom.xml index f4c213687e..8b2fd76f0e 100644 --- a/apache-httpclient4/pom.xml +++ b/apache-httpclient4/pom.xml @@ -234,7 +234,7 @@ - 1.10 + 1.16.0 4.1.5 2.5.1 diff --git a/aws-modules/aws-miscellaneous/pom.xml b/aws-modules/aws-miscellaneous/pom.xml index 5fdd7fa04d..b6326b6eb1 100644 --- a/aws-modules/aws-miscellaneous/pom.xml +++ b/aws-modules/aws-miscellaneous/pom.xml @@ -75,7 +75,7 @@ 2.10.1 1.21.1 - 1.10.L001 + 1.16.0 0.9.4.0006L 3.1.1 diff --git a/aws-modules/aws-s3/pom.xml b/aws-modules/aws-s3/pom.xml index e2bc04964a..6cbdadabae 100644 --- a/aws-modules/aws-s3/pom.xml +++ b/aws-modules/aws-s3/pom.xml @@ -62,7 +62,7 @@ 2.20.52 - 1.10.L001 + 1.16.0 0.9.4.0006L diff --git a/core-java-modules/core-java-networking-2/pom.xml b/core-java-modules/core-java-networking-2/pom.xml index 34f16a9938..388e439e37 100644 --- a/core-java-modules/core-java-networking-2/pom.xml +++ b/core-java-modules/core-java-networking-2/pom.xml @@ -56,7 +56,7 @@ 2.4.5 2.3.3 2.0.0-alpha-3 - 1.15 + 1.16.0 \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-6/pom.xml b/core-java-modules/core-java-numbers-6/pom.xml index 7a3b3d4426..66e16c8030 100644 --- a/core-java-modules/core-java-numbers-6/pom.xml +++ b/core-java-modules/core-java-numbers-6/pom.xml @@ -42,7 +42,7 @@ - 1.15 + 1.16.0 32.1.2-jre \ No newline at end of file diff --git a/core-java-modules/core-java-security-2/pom.xml b/core-java-modules/core-java-security-2/pom.xml index 0fc121c070..05cd727638 100644 --- a/core-java-modules/core-java-security-2/pom.xml +++ b/core-java-modules/core-java-security-2/pom.xml @@ -34,7 +34,7 @@ 1.60 - 1.11 + 1.16.0 2.3.1 diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml index b979b56658..4633ba02e3 100644 --- a/core-java-modules/core-java-security-3/pom.xml +++ b/core-java-modules/core-java-security-3/pom.xml @@ -44,7 +44,7 @@ 1.70 - 1.15 + 1.16.0 2.3.1 6.0.3 diff --git a/core-java-modules/core-java-string-operations-2/pom.xml b/core-java-modules/core-java-string-operations-2/pom.xml index 383a3b4a40..27071e5427 100644 --- a/core-java-modules/core-java-string-operations-2/pom.xml +++ b/core-java-modules/core-java-string-operations-2/pom.xml @@ -87,7 +87,7 @@ 8.0.1.Final 5.0.0 - 1.14 + 1.16.0 5.3.0 diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml index a6049432ce..8cbc1237c2 100644 --- a/httpclient-simple/pom.xml +++ b/httpclient-simple/pom.xml @@ -205,7 +205,7 @@ 17 - 1.10 + 1.16.0 2.5.1 From fe7f89a08fbadbd8e87f518fc82f243b8cc807db Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 17:46:52 +0200 Subject: [PATCH 09/71] [JAVA-26714] Upgraded bouncycastle to latest version --- core-java-modules/core-java-security-2/pom.xml | 4 ++-- core-java-modules/core-java-security-3/pom.xml | 4 ++-- core-java-modules/core-java-security-4/pom.xml | 4 ++-- libraries-security/pom.xml | 6 +++--- .../oauth2-authorization-server/pom.xml | 11 +++++------ 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/core-java-modules/core-java-security-2/pom.xml b/core-java-modules/core-java-security-2/pom.xml index 05cd727638..b54afc31d8 100644 --- a/core-java-modules/core-java-security-2/pom.xml +++ b/core-java-modules/core-java-security-2/pom.xml @@ -21,7 +21,7 @@ org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on ${bouncycastle.version} @@ -33,7 +33,7 @@ - 1.60 + 1.76 1.16.0 2.3.1 diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml index 4633ba02e3..dae570e51d 100644 --- a/core-java-modules/core-java-security-3/pom.xml +++ b/core-java-modules/core-java-security-3/pom.xml @@ -21,7 +21,7 @@ org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on ${bouncycastle.version} @@ -43,7 +43,7 @@ - 1.70 + 1.76 1.16.0 2.3.1 6.0.3 diff --git a/core-java-modules/core-java-security-4/pom.xml b/core-java-modules/core-java-security-4/pom.xml index 2b9809b749..a4700c34ba 100644 --- a/core-java-modules/core-java-security-4/pom.xml +++ b/core-java-modules/core-java-security-4/pom.xml @@ -16,7 +16,7 @@ org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on ${bouncycastle.version} @@ -27,7 +27,7 @@ - 1.70 + 1.76 1.2.6 diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml index 62c476a82c..969f14ec43 100644 --- a/libraries-security/pom.xml +++ b/libraries-security/pom.xml @@ -40,12 +40,12 @@ org.bouncycastle - bcprov-jdk15on + bcprov-jdk18on ${bouncycastle.version} org.bouncycastle - bcpkix-jdk15on + bcpkix-jdk18on ${bouncycastle.version} @@ -122,7 +122,7 @@ 1.2.2 1.2.2 1.9.2 - 1.58 + 1.76 0.1.55 2.5.1 2.4.0.RELEASE diff --git a/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml b/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml index 7f13e5acea..1ebbb5e10f 100644 --- a/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml +++ b/security-modules/oauth2-framework-impl/oauth2-authorization-server/pom.xml @@ -21,13 +21,13 @@ org.bouncycastle - bcprov-jdk15on - ${bcprov-jdk15on.version} + bcprov-jdk18on + ${bouncycastle.version} org.bouncycastle - bcpkix-jdk15on - ${bcpkix-jdk15on.version} + bcpkix-jdk18on + ${bouncycastle.version} @@ -69,8 +69,7 @@ 9080 9443 7.3 - 1.62 - 1.62 + 1.76 \ No newline at end of file From 2c7a0d05e2a823cc74889d9e3ced74538f7c0bf0 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 18:00:46 +0200 Subject: [PATCH 10/71] [JAVA-26714] Clean up of commons-lang3 --- core-java-modules/core-java-collections-4/pom.xml | 1 - core-java-modules/core-java-collections-list-5/pom.xml | 1 - core-java-modules/core-java-date-operations-3/pom.xml | 1 - core-java-modules/core-java-function/pom.xml | 1 - core-java-modules/core-java-functional/pom.xml | 1 - core-java-modules/core-java-lang-5/pom.xml | 1 - core-java-modules/core-java-reflection/pom.xml | 1 - core-java-modules/core-java-string-algorithms-3/pom.xml | 1 - core-java-modules/core-java-string-operations-3/pom.xml | 1 - core-java-modules/core-java-string-operations-4/pom.xml | 7 +++---- 10 files changed, 3 insertions(+), 13 deletions(-) diff --git a/core-java-modules/core-java-collections-4/pom.xml b/core-java-modules/core-java-collections-4/pom.xml index 1a59411ecb..344ec6bc41 100644 --- a/core-java-modules/core-java-collections-4/pom.xml +++ b/core-java-modules/core-java-collections-4/pom.xml @@ -34,7 +34,6 @@ 2.2 - 3.12.0 \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list-5/pom.xml b/core-java-modules/core-java-collections-list-5/pom.xml index 2b4b0041b3..b8832df357 100644 --- a/core-java-modules/core-java-collections-list-5/pom.xml +++ b/core-java-modules/core-java-collections-list-5/pom.xml @@ -66,7 +66,6 @@ 1.21 2.2 - 3.12.0 2.10.1 2.15.2 20230618 diff --git a/core-java-modules/core-java-date-operations-3/pom.xml b/core-java-modules/core-java-date-operations-3/pom.xml index 9b7be18b85..8e4740785c 100644 --- a/core-java-modules/core-java-date-operations-3/pom.xml +++ b/core-java-modules/core-java-date-operations-3/pom.xml @@ -28,7 +28,6 @@ 2.12.5 - 3.12.0 \ No newline at end of file diff --git a/core-java-modules/core-java-function/pom.xml b/core-java-modules/core-java-function/pom.xml index e8b538ad24..4110b8f6d9 100644 --- a/core-java-modules/core-java-function/pom.xml +++ b/core-java-modules/core-java-function/pom.xml @@ -51,7 +51,6 @@ 3.8.0 3.22.0 - 3.12.0 0.10.4 diff --git a/core-java-modules/core-java-functional/pom.xml b/core-java-modules/core-java-functional/pom.xml index 4b0bf9f730..3b21dd6e8a 100644 --- a/core-java-modules/core-java-functional/pom.xml +++ b/core-java-modules/core-java-functional/pom.xml @@ -35,7 +35,6 @@ 3.8.0 3.22.0 - 3.12.0 0.10.4 diff --git a/core-java-modules/core-java-lang-5/pom.xml b/core-java-modules/core-java-lang-5/pom.xml index 8e95fc4405..b65f061fc7 100644 --- a/core-java-modules/core-java-lang-5/pom.xml +++ b/core-java-modules/core-java-lang-5/pom.xml @@ -24,7 +24,6 @@ - 3.12.0 0.10.2 diff --git a/core-java-modules/core-java-reflection/pom.xml b/core-java-modules/core-java-reflection/pom.xml index a836ee4a22..f77c791936 100644 --- a/core-java-modules/core-java-reflection/pom.xml +++ b/core-java-modules/core-java-reflection/pom.xml @@ -52,7 +52,6 @@ 1.8 1.8 0.10.2 - 3.12.0 \ No newline at end of file diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 507e830e8a..c47967a29f 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -61,7 +61,6 @@ 11 11 1.7 - 3.12.0 5.1.1 1.10.0 diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml index 39167271fa..7795d164a1 100644 --- a/core-java-modules/core-java-string-operations-3/pom.xml +++ b/core-java-modules/core-java-string-operations-3/pom.xml @@ -70,7 +70,6 @@ 11 11 5.3.9 - 3.12.0 3.6.3 6.1.1 2.11.1 diff --git a/core-java-modules/core-java-string-operations-4/pom.xml b/core-java-modules/core-java-string-operations-4/pom.xml index 27c2bf91bd..b9591763a0 100644 --- a/core-java-modules/core-java-string-operations-4/pom.xml +++ b/core-java-modules/core-java-string-operations-4/pom.xml @@ -27,12 +27,12 @@ org.apache.commons commons-lang3 - ${apache-commons-lang3.version} + ${commons-lang3.version} org.apache.commons commons-text - ${apache-commons-text.version} + ${commons-text.version} org.assertj @@ -60,8 +60,7 @@ 11 5.8 5.3.13 - 3.12.0 - 1.10.0 + 1.10.0 \ No newline at end of file From daea7e1edc1f746e4c1a1a3afc3c6ba5637a7033 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 18:03:56 +0200 Subject: [PATCH 11/71] [JAVA-26714] Revert typo --- aws-modules/aws-s3/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws-modules/aws-s3/pom.xml b/aws-modules/aws-s3/pom.xml index 6cbdadabae..e2bc04964a 100644 --- a/aws-modules/aws-s3/pom.xml +++ b/aws-modules/aws-s3/pom.xml @@ -62,7 +62,7 @@ 2.20.52 - 1.16.0 + 1.10.L001 0.9.4.0006L From 39c2f491713a429cd5f9c5b3b45eb62165ed0a0e Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Sun, 12 Nov 2023 18:10:31 +0200 Subject: [PATCH 12/71] [JAVA-26714] Upgraded guava to latest version --- core-java-modules/core-java-numbers-6/pom.xml | 1 - core-java-modules/core-java-streams-5/pom.xml | 1 - docker-modules/docker-caching/multi-module-caching/pom.xml | 2 +- docker-modules/docker-caching/single-module-caching/pom.xml | 2 +- json-modules/json-conversion/pom.xml | 1 - pom.xml | 2 +- spring-web-modules/spring-rest-http-2/pom.xml | 1 - 7 files changed, 3 insertions(+), 7 deletions(-) diff --git a/core-java-modules/core-java-numbers-6/pom.xml b/core-java-modules/core-java-numbers-6/pom.xml index 66e16c8030..34e53056a4 100644 --- a/core-java-modules/core-java-numbers-6/pom.xml +++ b/core-java-modules/core-java-numbers-6/pom.xml @@ -43,6 +43,5 @@ 1.16.0 - 32.1.2-jre \ No newline at end of file diff --git a/core-java-modules/core-java-streams-5/pom.xml b/core-java-modules/core-java-streams-5/pom.xml index d7baf84d30..e217271f4c 100644 --- a/core-java-modules/core-java-streams-5/pom.xml +++ b/core-java-modules/core-java-streams-5/pom.xml @@ -77,7 +77,6 @@ 12 12 0.10.2 - 32.1.2-jre \ No newline at end of file diff --git a/docker-modules/docker-caching/multi-module-caching/pom.xml b/docker-modules/docker-caching/multi-module-caching/pom.xml index 60f14a17e5..bebfb85e8a 100644 --- a/docker-modules/docker-caching/multi-module-caching/pom.xml +++ b/docker-modules/docker-caching/multi-module-caching/pom.xml @@ -27,7 +27,7 @@ UTF-8 1.8 - 32.1.2-jre + 32.1.3-jre \ No newline at end of file diff --git a/docker-modules/docker-caching/single-module-caching/pom.xml b/docker-modules/docker-caching/single-module-caching/pom.xml index 0e5174b7ca..bb44c21e10 100644 --- a/docker-modules/docker-caching/single-module-caching/pom.xml +++ b/docker-modules/docker-caching/single-module-caching/pom.xml @@ -49,7 +49,7 @@ 8 8 UTF-8 - 32.1.2-jre + 32.1.3-jre \ No newline at end of file diff --git a/json-modules/json-conversion/pom.xml b/json-modules/json-conversion/pom.xml index 638216f4c5..9eebac16b4 100644 --- a/json-modules/json-conversion/pom.xml +++ b/json-modules/json-conversion/pom.xml @@ -38,7 +38,6 @@ 2.10.1 - 32.1.2-jre diff --git a/pom.xml b/pom.xml index 47c566023d..7099dd8cbc 100644 --- a/pom.xml +++ b/pom.xml @@ -1236,7 +1236,7 @@ 3.21.0 1.18.28 2.1.214 - 32.1.2-jre + 32.1.3-jre 3.3.0 diff --git a/spring-web-modules/spring-rest-http-2/pom.xml b/spring-web-modules/spring-rest-http-2/pom.xml index 88294c7811..bcacdbbdb1 100644 --- a/spring-web-modules/spring-rest-http-2/pom.xml +++ b/spring-web-modules/spring-rest-http-2/pom.xml @@ -53,7 +53,6 @@ 2.9.2 1.6.1 1.7.0 - 31.0.1-jre \ No newline at end of file From 7465581d605e220bb4064d2b62d3f892ab4c8c28 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Mon, 13 Nov 2023 09:44:21 +0200 Subject: [PATCH 13/71] [JAVA-26714] --- core-java-modules/core-java-string-algorithms-3/pom.xml | 1 - core-java-modules/core-java-string-operations-3/pom.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index c47967a29f..96bb824f84 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -21,7 +21,6 @@ org.apache.commons commons-lang3 - ${apache-commons-lang3.version} com.vdurmont diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml index 7795d164a1..ce58669ba0 100644 --- a/core-java-modules/core-java-string-operations-3/pom.xml +++ b/core-java-modules/core-java-string-operations-3/pom.xml @@ -22,7 +22,6 @@ org.apache.commons commons-lang3 - ${apache-commons-lang3.version} org.apache.maven From 0415bc0ec7093073f1fe4960dbc491ef2733ed11 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Mon, 13 Nov 2023 09:48:20 +0200 Subject: [PATCH 14/71] [JAVA-26714] --- core-java-modules/core-java-string-algorithms-3/pom.xml | 1 + core-java-modules/core-java-string-operations-3/pom.xml | 1 + 2 files changed, 2 insertions(+) diff --git a/core-java-modules/core-java-string-algorithms-3/pom.xml b/core-java-modules/core-java-string-algorithms-3/pom.xml index 96bb824f84..548a3dc3f8 100644 --- a/core-java-modules/core-java-string-algorithms-3/pom.xml +++ b/core-java-modules/core-java-string-algorithms-3/pom.xml @@ -21,6 +21,7 @@ org.apache.commons commons-lang3 + ${commons-lang3.version} com.vdurmont diff --git a/core-java-modules/core-java-string-operations-3/pom.xml b/core-java-modules/core-java-string-operations-3/pom.xml index ce58669ba0..0558e71a35 100644 --- a/core-java-modules/core-java-string-operations-3/pom.xml +++ b/core-java-modules/core-java-string-operations-3/pom.xml @@ -22,6 +22,7 @@ org.apache.commons commons-lang3 + ${commons-lang3.version} org.apache.maven From 5040974af23bf29aec2fafb44ff94af538b7e026 Mon Sep 17 00:00:00 2001 From: panos-kakos Date: Mon, 13 Nov 2023 11:48:01 +0200 Subject: [PATCH 15/71] [JAVA-26714] --- libraries-security/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml index 969f14ec43..8a6dad6da2 100644 --- a/libraries-security/pom.xml +++ b/libraries-security/pom.xml @@ -40,12 +40,12 @@ org.bouncycastle - bcprov-jdk18on + bcprov-jdk15on ${bouncycastle.version} org.bouncycastle - bcpkix-jdk18on + bcpkix-jdk15on ${bouncycastle.version} @@ -122,7 +122,7 @@ 1.2.2 1.2.2 1.9.2 - 1.76 + 1.68 0.1.55 2.5.1 2.4.0.RELEASE From 25a02eb86de26a26bb983f4dfa357480d8384247 Mon Sep 17 00:00:00 2001 From: luca Date: Mon, 13 Nov 2023 12:24:40 +0100 Subject: [PATCH 16/71] fix: add only one spring boot app --- .../baeldung/overridebean/{basic => }/Config.java | 5 +---- .../overridebean/{basic => boot}/Application.java | 2 +- .../overridebean/conditional/Application.java | 14 -------------- .../baeldung/overridebean/profile/Application.java | 14 -------------- .../conditional/ConditionIntegrationTest.java | 1 + .../mockbean/MockBeanIntegrationTest.java | 2 +- .../OverrideBeanDefinitionIntegrationTest.java | 4 ++-- .../primary/PrimaryIntegrationTest.java | 4 ++-- .../profile/ProfileIntegrationTest.java | 1 + 9 files changed, 9 insertions(+), 38 deletions(-) rename spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/{basic => }/Config.java (64%) rename spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/{basic => boot}/Application.java (93%) delete mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java delete mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Config.java similarity index 64% rename from spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java rename to spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Config.java index 67d999958d..f0892338f8 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Config.java +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/Config.java @@ -1,11 +1,8 @@ -package com.baeldung.overridebean.basic; +package com.baeldung.overridebean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.baeldung.overridebean.Service; -import com.baeldung.overridebean.ServiceImpl; - @Configuration public class Config { diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/boot/Application.java similarity index 93% rename from spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java rename to spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/boot/Application.java index 6f9acde3d8..1eb0012493 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/basic/Application.java +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/boot/Application.java @@ -1,4 +1,4 @@ -package com.baeldung.overridebean.basic; +package com.baeldung.overridebean.boot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java deleted file mode 100644 index 9c4cdbf8ec..0000000000 --- a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/conditional/Application.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.overridebean.conditional; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; - -@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java deleted file mode 100644 index d3298b2eb4..0000000000 --- a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/overridebean/profile/Application.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.overridebean.profile; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; - -@SpringBootApplication(exclude = { SecurityAutoConfiguration.class, OAuth2ResourceServerAutoConfiguration.class }) -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java index 5f6b1d128f..b3a5164ff5 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionIntegrationTest.java @@ -12,6 +12,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ConditionalConfig.class, Endpoint.class, ConditionalTestConfig.class }, properties = "service.stub=true") @AutoConfigureMockMvc diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java index 6a7be1cbda..2ece28482d 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java @@ -15,7 +15,7 @@ import org.springframework.test.web.servlet.MockMvc; import com.baeldung.overridebean.Endpoint; import com.baeldung.overridebean.Service; -import com.baeldung.overridebean.basic.Application; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, Endpoint.class }) @AutoConfigureMockMvc diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java index 0f3753ef34..a8dba58b79 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/overridebeandefinition/OverrideBeanDefinitionIntegrationTest.java @@ -11,9 +11,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; +import com.baeldung.overridebean.Config; import com.baeldung.overridebean.Endpoint; -import com.baeldung.overridebean.basic.Application; -import com.baeldung.overridebean.basic.Config; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, OverrideBeanDefinitionTestConfig.class }, properties = "spring.main.allow-bean-definition-overriding=true") @AutoConfigureMockMvc diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java index 2bddfd4637..b6061c86d5 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/primary/PrimaryIntegrationTest.java @@ -11,9 +11,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; +import com.baeldung.overridebean.Config; import com.baeldung.overridebean.Endpoint; -import com.baeldung.overridebean.basic.Application; -import com.baeldung.overridebean.basic.Config; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, Config.class, Endpoint.class, PrimaryTestConfig.class }) @AutoConfigureMockMvc diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java index deabfea9e5..7f4aae026c 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java @@ -12,6 +12,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) @AutoConfigureMockMvc From 122ca1a996bb2e014d840eaf879e99dc7432371a Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 14 Nov 2023 11:17:53 +0530 Subject: [PATCH 17/71] JAVA-27197 Upgrade hibernate-validator version in spring-thymeleaf-5 module --- spring-web-modules/spring-thymeleaf-5/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web-modules/spring-thymeleaf-5/pom.xml b/spring-web-modules/spring-thymeleaf-5/pom.xml index 0717e41bac..2d178bd933 100644 --- a/spring-web-modules/spring-thymeleaf-5/pom.xml +++ b/spring-web-modules/spring-thymeleaf-5/pom.xml @@ -139,7 +139,7 @@ 3.0.4.RELEASE 2.4.1 2.0.1.Final - 6.0.11.Final + 8.0.1.Final 1.6.1 From f94f248f5a52c110615c827212eefe30b1d2cd82 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 14 Nov 2023 11:25:35 +0530 Subject: [PATCH 18/71] JAVA-27196 Upgrade hibernate-validator version in spring-mvc-xml module --- spring-web-modules/spring-mvc-xml/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web-modules/spring-mvc-xml/pom.xml b/spring-web-modules/spring-mvc-xml/pom.xml index bf0dc52b68..12f0a1a68a 100644 --- a/spring-web-modules/spring-mvc-xml/pom.xml +++ b/spring-web-modules/spring-mvc-xml/pom.xml @@ -142,7 +142,7 @@ 4.4.5 4.5.2 - 6.0.10.Final + 8.0.1.Final 3.0.1-b08 2.8.0 From 68f4c0517caaca2dc5e4fb41fa0e31aacd0fa761 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 14 Nov 2023 11:50:54 +0530 Subject: [PATCH 19/71] JAVA-27198 Upgrade hibernate-validator version in spring-thymeleaf module --- spring-web-modules/spring-thymeleaf/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web-modules/spring-thymeleaf/pom.xml b/spring-web-modules/spring-thymeleaf/pom.xml index 94ae05ca11..ce0c0a7e21 100644 --- a/spring-web-modules/spring-thymeleaf/pom.xml +++ b/spring-web-modules/spring-thymeleaf/pom.xml @@ -140,7 +140,7 @@ 3.0.4.RELEASE 2.4.1 2.0.1.Final - 6.0.11.Final + 8.0.1.Final 1.9.9 From bf4cc41cb4a77ea0b2be2124bb72af3647a7c7c5 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Tue, 14 Nov 2023 12:24:10 +0530 Subject: [PATCH 20/71] JAVA-27199 Upgrade hibernate validator version in vraptor module --- web-modules/vraptor/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web-modules/vraptor/pom.xml b/web-modules/vraptor/pom.xml index ecc6fe3313..25f8b5d5e5 100644 --- a/web-modules/vraptor/pom.xml +++ b/web-modules/vraptor/pom.xml @@ -49,7 +49,7 @@ provided - org.hibernate + org.hibernate.validator hibernate-validator-cdi ${hibernate-validator.version} @@ -115,7 +115,7 @@ 4.2.0.Final 2.1.2.Final 2.2 - 5.1.1.Final + 8.0.1.Final 4.1.0-RC3 4.0.4 8.0.8-dmr From f20a18ed9b97ead5c6f6e67f55993d3acc4c12dc Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 14 Nov 2023 10:28:22 +0100 Subject: [PATCH 21/71] clean, add mock example --- .../conditional/ConditionalTestConfig.java | 2 +- .../mockbean/MockBeanIntegrationTest.java | 4 +- .../profile/ProfileIntegrationMockTest.java | 38 +++++++++++++++++++ ...t.java => ProfileIntegrationStubTest.java} | 6 ++- .../profile/ProfileTestConfig.java | 12 +++++- 5 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java rename spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/{ProfileIntegrationTest.java => ProfileIntegrationStubTest.java} (84%) diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java index c48c4e2266..ce82b43df0 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/conditional/ConditionalTestConfig.java @@ -9,8 +9,8 @@ import com.baeldung.overridebean.Service; @TestConfiguration public class ConditionalTestConfig { - @ConditionalOnProperty(name = "service.stub", havingValue = "true") @Bean + @ConditionalOnProperty(name = "service.stub", havingValue = "true") public Service helloWorld() { return new ConditionalStub(); } diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java index 2ece28482d..9a63ad4113 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/mockbean/MockBeanIntegrationTest.java @@ -25,11 +25,11 @@ class MockBeanIntegrationTest { private MockMvc mockMvc; @MockBean - private Service serviceExample; + private Service service; @Test void givenServiceMockBean_whenGetHelloEndpoint_thenMockOk() throws Exception { - when(serviceExample.helloWorld()).thenReturn("hello mock bean"); + when(service.helloWorld()).thenReturn("hello mock bean"); this.mockMvc.perform(get("/hello")) .andExpect(status().isOk()) .andExpect(content().string(containsString("hello mock bean"))); diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java new file mode 100644 index 0000000000..43fb69860d --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java @@ -0,0 +1,38 @@ +package com.baeldung.overridebean.profile; + +import static org.hamcrest.Matchers.containsString; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; + +import com.baeldung.overridebean.Endpoint; +import com.baeldung.overridebean.Service; +import com.baeldung.overridebean.boot.Application; + +@SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) +@AutoConfigureMockMvc +@ActiveProfiles("mock") +class ProfileIntegrationMockTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private Service service; + + @Test + void givenConfigurationWithProfile_whenTestProfileIsActive_thenMockOk() throws Exception { + when(service.helloWorld()).thenReturn("hello profile mock"); + this.mockMvc.perform(get("/hello")) + .andExpect(status().isOk()) + .andExpect(content().string(containsString("hello profile mock"))); + } +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java similarity index 84% rename from spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java rename to spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java index 7f4aae026c..e1c88f2a31 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import com.baeldung.overridebean.Endpoint; @@ -16,13 +17,14 @@ import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) @AutoConfigureMockMvc -class ProfileIntegrationTest { +@ActiveProfiles("stub") +class ProfileIntegrationStubTest { @Autowired private MockMvc mockMvc; @Test - void givenConfigurationWithProfile_whenNoProductionProfileIsActive_thenStubOk() throws Exception { + void givenConfigurationWithProfile_whenTestProfileIsActive_thenStubOk() throws Exception { this.mockMvc.perform(get("/hello")) .andExpect(status().isOk()) .andExpect(content().string(containsString("hello profile stub"))); diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java index edd33162e0..7e1de309d3 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileTestConfig.java @@ -1,7 +1,10 @@ package com.baeldung.overridebean.profile; +import static org.mockito.Mockito.mock; + import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; import com.baeldung.overridebean.Service; @@ -9,7 +12,14 @@ import com.baeldung.overridebean.Service; public class ProfileTestConfig { @Bean - public Service helloWorld() { + @Profile("stub") + public Service helloWorldStub() { return new ProfileServiceStub(); } + + @Bean + @Profile("mock") + public Service helloWorldMock() { + return mock(Service.class); + } } From 6a7e63795d0f332c00eb2d06699da87dc94adca3 Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:15:27 +0530 Subject: [PATCH 22/71] BAEL-7091 removed Java 9 snippets --- testing-modules/testing-assertions/pom.xml | 12 ---- .../AssertNestedMapUnitTest.java | 68 ++++++++++++------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/testing-modules/testing-assertions/pom.xml b/testing-modules/testing-assertions/pom.xml index 1f2b4e335d..1da53bd77e 100644 --- a/testing-modules/testing-assertions/pom.xml +++ b/testing-modules/testing-assertions/pom.xml @@ -4,18 +4,6 @@ 4.0.0 testing-assertions 0.0.1-SNAPSHOT - - - - org.apache.maven.plugins - maven-compiler-plugin - - 9 - 9 - - - - com.baeldung diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java index 7c48a5eb4a..ceef5efdd2 100644 --- a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java @@ -3,6 +3,7 @@ package com.baeldung.assertnestedmap; import org.junit.jupiter.api.Test; +import java.util.HashMap; import java.util.Map; import static com.baeldung.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; @@ -13,16 +14,22 @@ import static org.junit.jupiter.api.Assertions.*; public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseJupiterAssertTrueWithoutCasting_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertTrue(outerMap.containsKey("address") && outerMap.get("address").get("city").equals("Chicago")); } @Test void givenNestedMap_whenUseJupiterAssertAllAndAssertTrue_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertAll( () -> assertTrue(outerMap.containsKey("address")), @@ -32,8 +39,11 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseJupiterAssertTrueWithCasting_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertTrue(outerMap.containsKey("address") && ((Map)outerMap.get("address")).get("city").equals("Chicago")); @@ -41,8 +51,12 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseHamcrestAssertThat_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); + assertAll( () -> assertThat(outerMap, hasKey("address")), () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) @@ -51,42 +65,46 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThat_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertThat(outerMap, hasEntry(equalTo("address"), hasEntry("city", "Chicago"))); } @Test void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { - Map innerMap = Map.of - ( - "city", "Chicago", - "zip", "10005" - ); - Map> outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + innerMap.put("zip", "10005"); + + Map> outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } @Test void givenOuterMapOfStringAndObjectAndInnerMap_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { - Map innerMap = Map.of - ( - "city", "Chicago", - "zip", "10005" - ); - Map outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + innerMap.put("zip", "10005"); + + Map outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } @Test void givenNestedMap_whenUseHamcrestAssertThatWithCasting_thenTest() { - Map innerMap = Map.of("city", "Chicago"); - Map outerMap = Map.of("address", innerMap); + Map innerMap = new HashMap<>(); + innerMap.put("city", "Chicago"); + Map outerMap = new HashMap<>(); + outerMap.put("address", innerMap); assertThat((Map)outerMap.get("address"), hasEntry("city", "Chicago")); } - } From 336ee922eb0933fef3f6ab6b554f4cc07f2f652d Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Thu, 16 Nov 2023 12:21:18 +0200 Subject: [PATCH 23/71] JAVA-26692 Go over tutorials - integration builds test results - Week 45 - 2023 (#15194) Co-authored-by: timis1 --- .../multipletopics/KafkaMultipleTopicsIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java index 345e84b65b..570670cdf9 100644 --- a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java +++ b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/multipletopics/KafkaMultipleTopicsIntegrationTest.java @@ -21,7 +21,7 @@ import org.springframework.kafka.test.context.EmbeddedKafka; import org.springframework.kafka.test.utils.ContainerTestUtils; @SpringBootTest(classes = KafkaMultipleTopicsApplication.class) -@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9092", "port=9092" }) +@EmbeddedKafka(partitions = 1, brokerProperties = { "listeners=PLAINTEXT://localhost:9099", "port=9099" }) public class KafkaMultipleTopicsIntegrationTest { private static final String CARD_PAYMENTS_TOPIC = "card-payments"; private static final String BANK_TRANSFERS_TOPIC = "bank-transfers"; From f12328011b0a0c254b5096c3ce0dbfd7dcbd4c7f Mon Sep 17 00:00:00 2001 From: parthiv39731 <70740707+parthiv39731@users.noreply.github.com> Date: Thu, 16 Nov 2023 20:10:00 +0530 Subject: [PATCH 24/71] BAEL-7091 reverted Java 9 snippets --- .../AssertNestedMapUnitTest.java | 68 +++++++------------ 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java index ceef5efdd2..7c48a5eb4a 100644 --- a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertnestedmap/AssertNestedMapUnitTest.java @@ -3,7 +3,6 @@ package com.baeldung.assertnestedmap; import org.junit.jupiter.api.Test; -import java.util.HashMap; import java.util.Map; import static com.baeldung.assertnestedmap.matchers.NestedMapMatcher.hasNestedMapEntry; @@ -14,22 +13,16 @@ import static org.junit.jupiter.api.Assertions.*; public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseJupiterAssertTrueWithoutCasting_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); assertTrue(outerMap.containsKey("address") && outerMap.get("address").get("city").equals("Chicago")); } @Test void givenNestedMap_whenUseJupiterAssertAllAndAssertTrue_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); assertAll( () -> assertTrue(outerMap.containsKey("address")), @@ -39,11 +32,8 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseJupiterAssertTrueWithCasting_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); assertTrue(outerMap.containsKey("address") && ((Map)outerMap.get("address")).get("city").equals("Chicago")); @@ -51,12 +41,8 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMap_whenUseHamcrestAssertThat_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); - + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); assertAll( () -> assertThat(outerMap, hasKey("address")), () -> assertThat(outerMap.get("address"), hasEntry("city", "Chicago")) @@ -65,46 +51,42 @@ public class AssertNestedMapUnitTest { @Test void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThat_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map> outerMap = Map.of("address", innerMap); assertThat(outerMap, hasEntry(equalTo("address"), hasEntry("city", "Chicago"))); } @Test void givenNestedMapOfStringAndObject_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - innerMap.put("zip", "10005"); - - Map> outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map> outerMap = Map.of("address", innerMap); assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } @Test void givenOuterMapOfStringAndObjectAndInnerMap_whenUseHamcrestAssertThatAndCustomMatcher_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - innerMap.put("zip", "10005"); - - Map outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of + ( + "city", "Chicago", + "zip", "10005" + ); + Map outerMap = Map.of("address", innerMap); assertThat(outerMap, hasNestedMapEntry("address", innerMap)); } @Test void givenNestedMap_whenUseHamcrestAssertThatWithCasting_thenTest() { - Map innerMap = new HashMap<>(); - innerMap.put("city", "Chicago"); - Map outerMap = new HashMap<>(); - outerMap.put("address", innerMap); + Map innerMap = Map.of("city", "Chicago"); + Map outerMap = Map.of("address", innerMap); assertThat((Map)outerMap.get("address"), hasEntry("city", "Chicago")); } + } From 58db4f7a091f29128ddbbacc99ccecec46a2c422 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Thu, 16 Nov 2023 20:22:43 +0100 Subject: [PATCH 25/71] JAVA-27338: Fix VehicleUnitTest --- .../com/baeldung/sealed/classes/VehicleUnitTest.java | 8 ++++---- .../com/baeldung/sealed/records/VehicleUnitTest.java | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java index 73d8aad810..0c437affd8 100644 --- a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/classes/VehicleUnitTest.java @@ -18,19 +18,19 @@ public class VehicleUnitTest { } @Test - public void givenCar_whenUsingReflectionAPI_thenSuperClassIsSealed() { + public void givenCar_whenUsingReflectionAPI_thenSuperClassIsSealed() throws ClassNotFoundException { Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(car.getClass().getSuperclass().isSealed()).isEqualTo(true); Assertions.assertThat(car.getClass().getSuperclass().getPermittedSubclasses()) - .contains(ClassDesc.of(car.getClass().getCanonicalName())); + .contains(Class.forName(car.getClass().getCanonicalName())); } @Test - public void givenTruck_whenUsingReflectionAPI_thenSuperClassIsSealed() { + public void givenTruck_whenUsingReflectionAPI_thenSuperClassIsSealed() throws ClassNotFoundException { Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(truck.getClass().getSuperclass().isSealed()).isEqualTo(true); Assertions.assertThat(truck.getClass().getSuperclass().getPermittedSubclasses()) - .contains(ClassDesc.of(truck.getClass().getCanonicalName())); + .contains(Class.forName(truck.getClass().getCanonicalName())); } @Test diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java index ac8a8c953c..8dd150b5e7 100644 --- a/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/sealed/records/VehicleUnitTest.java @@ -18,19 +18,19 @@ public class VehicleUnitTest { } @Test - public void givenCar_whenUsingReflectionAPI_thenInterfaceIsSealed() { + public void givenCar_whenUsingReflectionAPI_thenInterfaceIsSealed() throws ClassNotFoundException { Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(car.getClass().getInterfaces()[0].isSealed()).isEqualTo(true); - Assertions.assertThat(car.getClass().getInterfaces()[0].permittedSubclasses()) - .contains(ClassDesc.of(car.getClass().getCanonicalName())); + Assertions.assertThat(car.getClass().getInterfaces()[0].getPermittedSubclasses()) + .contains(Class.forName(car.getClass().getCanonicalName())); } @Test - public void givenTruck_whenUsingReflectionAPI_thenInterfaceIsSealed() { + public void givenTruck_whenUsingReflectionAPI_thenInterfaceIsSealed() throws ClassNotFoundException { Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false); Assertions.assertThat(truck.getClass().getInterfaces()[0].isSealed()).isEqualTo(true); - Assertions.assertThat(truck.getClass().getInterfaces()[0].permittedSubclasses()) - .contains(ClassDesc.of(truck.getClass().getCanonicalName())); + Assertions.assertThat(truck.getClass().getInterfaces()[0].getPermittedSubclasses()) + .contains(Class.forName(truck.getClass().getCanonicalName())); } @Test From 0b229a9af4cc321f4bebb278d47616f726c7cb48 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Thu, 16 Nov 2023 18:35:11 -0300 Subject: [PATCH 26/71] draft 1 (#15222) --- ...tSpecificDeserializationFilterFactory.java | 47 +++++++ .../pojo/ContextSpecific.java | 7 ++ .../pojo/NestedSample.java | 19 +++ .../deserializationfilters/pojo/Sample.java | 61 +++++++++ .../pojo/SampleExploit.java | 25 ++++ .../service/DeserializationService.java | 11 ++ .../service/LimitedArrayService.java | 15 +++ .../service/LowDepthService.java | 20 +++ .../service/SmallObjectService.java | 15 +++ .../utils/DeserializationUtils.java | 50 ++++++++ .../utils/FilterUtils.java | 32 +++++ .../utils/SerializationUtils.java | 17 +++ ...cDeserializationFilterIntegrationTest.java | 119 ++++++++++++++++++ 13 files changed, 438 insertions(+) create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java create mode 100644 core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java create mode 100644 core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java new file mode 100644 index 0000000000..25a855487e --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterFactory.java @@ -0,0 +1,47 @@ +package com.baeldung.deserializationfilters; + +import java.io.ObjectInputFilter; +import java.util.function.BinaryOperator; + +import com.baeldung.deserializationfilters.service.DeserializationService; +import com.baeldung.deserializationfilters.service.LimitedArrayService; +import com.baeldung.deserializationfilters.service.LowDepthService; +import com.baeldung.deserializationfilters.service.SmallObjectService; +import com.baeldung.deserializationfilters.utils.FilterUtils; + +public class ContextSpecificDeserializationFilterFactory implements BinaryOperator { + + @Override + public ObjectInputFilter apply(ObjectInputFilter current, ObjectInputFilter next) { + if (current == null) { + Class caller = findInStack(DeserializationService.class); + + if (caller == null) { + current = FilterUtils.fallbackFilter(); + } else if (caller.equals(SmallObjectService.class)) { + current = FilterUtils.safeSizeFilter(190); + } else if (caller.equals(LowDepthService.class)) { + current = FilterUtils.safeDepthFilter(2); + } else if (caller.equals(LimitedArrayService.class)) { + current = FilterUtils.safeArrayFilter(3); + } + } + + return ObjectInputFilter.merge(current, next); + } + + private static Class findInStack(Class superType) { + for (StackTraceElement element : Thread.currentThread() + .getStackTrace()) { + try { + Class subType = Class.forName(element.getClassName()); + if (superType.isAssignableFrom(subType)) { + return subType; + } + } catch (ClassNotFoundException e) { + return null; + } + } + return null; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java new file mode 100644 index 0000000000..add827d280 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/ContextSpecific.java @@ -0,0 +1,7 @@ +package com.baeldung.deserializationfilters.pojo; + +import java.io.Serializable; + +public interface ContextSpecific extends Serializable { + +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java new file mode 100644 index 0000000000..a1d41744e6 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/NestedSample.java @@ -0,0 +1,19 @@ +package com.baeldung.deserializationfilters.pojo; + +public class NestedSample implements ContextSpecific { + private static final long serialVersionUID = 1L; + + private Sample optional; + + public NestedSample(Sample optional) { + this.optional = optional; + } + + public Sample getOptional() { + return optional; + } + + public void setOptional(Sample optional) { + this.optional = optional; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java new file mode 100644 index 0000000000..fed3639c64 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/Sample.java @@ -0,0 +1,61 @@ +package com.baeldung.deserializationfilters.pojo; + +public class Sample implements ContextSpecific, Comparable { + private static final long serialVersionUID = 1L; + + private int[] array; + private String name; + private NestedSample nested; + + public Sample(String name) { + this.name = name; + } + + public Sample(int[] array) { + this.array = array; + } + + public Sample(NestedSample nested) { + this.nested = nested; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int[] getArray() { + return array; + } + + public void setArray(int[] array) { + this.array = array; + } + + public NestedSample getNested() { + return nested; + } + + public void setNested(NestedSample nested) { + this.nested = nested; + } + + @Override + public String toString() { + return name; + } + + @Override + public int compareTo(Sample o) { + if (name == null) + return -1; + + if (o == null || o.getName() == null) + return 1; + + return getName().compareTo(o.getName()); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java new file mode 100644 index 0000000000..24dce289c6 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/pojo/SampleExploit.java @@ -0,0 +1,25 @@ +package com.baeldung.deserializationfilters.pojo; + +public class SampleExploit extends Sample { + private static final long serialVersionUID = 1L; + + public SampleExploit() { + super("exploit"); + } + + public static void maliciousCode() { + System.out.println("exploit executed"); + } + + @Override + public String toString() { + maliciousCode(); + return "exploit"; + } + + @Override + public int compareTo(Sample o) { + maliciousCode(); + return super.compareTo(o); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java new file mode 100644 index 0000000000..9a66cb0e91 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/DeserializationService.java @@ -0,0 +1,11 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; + +public interface DeserializationService { + + Set process(InputStream... inputStreams); +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java new file mode 100644 index 0000000000..3aadbe7111 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LimitedArrayService.java @@ -0,0 +1,15 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; + +public class LimitedArrayService implements DeserializationService { + + @Override + public Set process(InputStream... inputStreams) { + return DeserializationUtils.deserializeIntoSet(inputStreams); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java new file mode 100644 index 0000000000..69350c1399 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/LowDepthService.java @@ -0,0 +1,20 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.io.ObjectInputFilter; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; + +public class LowDepthService implements DeserializationService { + + public Set process(ObjectInputFilter filter, InputStream... inputStreams) { + return DeserializationUtils.deserializeIntoSet(filter, inputStreams); + } + + @Override + public Set process(InputStream... inputStreams) { + return process(null, inputStreams); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java new file mode 100644 index 0000000000..a0690276b7 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/service/SmallObjectService.java @@ -0,0 +1,15 @@ +package com.baeldung.deserializationfilters.service; + +import java.io.InputStream; +import java.util.Set; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; + +public class SmallObjectService implements DeserializationService { + + @Override + public Set process(InputStream... inputStreams) { + return DeserializationUtils.deserializeIntoSet(inputStreams); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java new file mode 100644 index 0000000000..54db823102 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/DeserializationUtils.java @@ -0,0 +1,50 @@ +package com.baeldung.deserializationfilters.utils; + +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInputFilter; +import java.io.ObjectInputStream; +import java.util.Set; +import java.util.TreeSet; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; + +public class DeserializationUtils { + private DeserializationUtils() { + } + + public static Object deserialize(InputStream inStream) { + return deserialize(inStream, null); + } + + public static Object deserialize(InputStream inStream, ObjectInputFilter filter) { + try (ObjectInputStream in = new ObjectInputStream(inStream)) { + if (filter != null) { + in.setObjectInputFilter(filter); + } + return in.readObject(); + } catch (InvalidClassException e) { + return null; + } catch (Throwable e) { + e.printStackTrace(); + return null; + } + } + + public static Set deserializeIntoSet(InputStream... inputStreams) { + return deserializeIntoSet(null, inputStreams); + } + + public static Set deserializeIntoSet(ObjectInputFilter filter, InputStream... inputStreams) { + Set set = new TreeSet<>(); + + for (InputStream inputStream : inputStreams) { + Object object = deserialize(inputStream, filter); + if (object != null) { + set.add((ContextSpecific) object); + } + } + + return set; + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java new file mode 100644 index 0000000000..fac69a94b9 --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/FilterUtils.java @@ -0,0 +1,32 @@ +package com.baeldung.deserializationfilters.utils; + +import java.io.ObjectInputFilter; + +public class FilterUtils { + + private static final String DEFAULT_PACKAGE_PATTERN = "java.base/*;!*"; + private static final String POJO_PACKAGE = "com.baeldung.deserializationfilters.pojo"; + + private FilterUtils() { + } + + private static ObjectInputFilter baseFilter(String parameter, int max) { + return ObjectInputFilter.Config.createFilter(String.format("%s=%d;%s.**;%s", parameter, max, POJO_PACKAGE, DEFAULT_PACKAGE_PATTERN)); + } + + public static ObjectInputFilter fallbackFilter() { + return ObjectInputFilter.Config.createFilter(String.format("%s", DEFAULT_PACKAGE_PATTERN)); + } + + public static ObjectInputFilter safeSizeFilter(int max) { + return baseFilter("maxbytes", max); + } + + public static ObjectInputFilter safeArrayFilter(int max) { + return baseFilter("maxarray", max); + } + + public static ObjectInputFilter safeDepthFilter(int max) { + return baseFilter("maxdepth", max); + } +} diff --git a/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java new file mode 100644 index 0000000000..4f62e5d46b --- /dev/null +++ b/core-java-modules/core-java-17/src/main/java/com/baeldung/deserializationfilters/utils/SerializationUtils.java @@ -0,0 +1,17 @@ +package com.baeldung.deserializationfilters.utils; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +public class SerializationUtils { + + private SerializationUtils() { + } + + public static void serialize(Object object, OutputStream outStream) throws IOException { + try (ObjectOutputStream objStream = new ObjectOutputStream(outStream)) { + objStream.writeObject(object); + } + } +} diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java new file mode 100644 index 0000000000..3e7de20070 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/deserializationfilters/ContextSpecificDeserializationFilterIntegrationTest.java @@ -0,0 +1,119 @@ +package com.baeldung.deserializationfilters; + +import static org.junit.Assert.assertNull; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputFilter; +import java.util.Set; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import com.baeldung.deserializationfilters.pojo.ContextSpecific; +import com.baeldung.deserializationfilters.pojo.NestedSample; +import com.baeldung.deserializationfilters.pojo.Sample; +import com.baeldung.deserializationfilters.pojo.SampleExploit; +import com.baeldung.deserializationfilters.service.LimitedArrayService; +import com.baeldung.deserializationfilters.service.LowDepthService; +import com.baeldung.deserializationfilters.service.SmallObjectService; +import com.baeldung.deserializationfilters.utils.DeserializationUtils; +import com.baeldung.deserializationfilters.utils.FilterUtils; +import com.baeldung.deserializationfilters.utils.SerializationUtils; + +public class ContextSpecificDeserializationFilterIntegrationTest { + + private static ByteArrayOutputStream serialSampleA = new ByteArrayOutputStream(); + private static ByteArrayOutputStream serialBigSampleA = new ByteArrayOutputStream(); + + private static ByteArrayOutputStream serialSampleB = new ByteArrayOutputStream(); + private static ByteArrayOutputStream serialBigSampleB = new ByteArrayOutputStream(); + + private static ByteArrayOutputStream serialSampleC = new ByteArrayOutputStream(); + private static ByteArrayOutputStream serialBigSampleC = new ByteArrayOutputStream(); + + private static ByteArrayInputStream bytes(ByteArrayOutputStream stream) { + return new ByteArrayInputStream(stream.toByteArray()); + } + + @BeforeAll + static void setup() throws IOException { + ObjectInputFilter.Config.setSerialFilterFactory(new ContextSpecificDeserializationFilterFactory()); + + SerializationUtils.serialize(new Sample("simple"), serialSampleA); + SerializationUtils.serialize(new SampleExploit(), serialBigSampleA); + + SerializationUtils.serialize(new Sample(new int[] { 1, 2, 3 }), serialSampleB); + SerializationUtils.serialize(new Sample(new int[] { 1, 2, 3, 4, 5, 6 }), serialBigSampleB); + + SerializationUtils.serialize(new Sample(new NestedSample(null)), serialSampleC); + SerializationUtils.serialize(new Sample(new NestedSample(new Sample("deep"))), serialBigSampleC); + } + + @Test + void whenSmallObjectContext_thenCorrectFilterApplied() { + Set result = new SmallObjectService().process( // + bytes(serialSampleA), // + bytes(serialBigSampleA)); + + assertEquals(1, result.size()); + assertEquals("simple", ((Sample) result.iterator() + .next()).getName()); + } + + @Test + void whenLimitedArrayContext_thenCorrectFilterApplied() { + Set result = new LimitedArrayService().process( // + bytes(serialSampleB), // + bytes(serialBigSampleB)); + + assertEquals(1, result.size()); + } + + @Test + void whenLowDepthContext_thenCorrectFilterApplied() { + Set result = new LowDepthService().process( // + bytes(serialSampleC), // + bytes(serialBigSampleC)); + + assertEquals(1, result.size()); + } + + @Test + void givenExtraFilter_whenCombinedContext_thenMergedFiltersApplied() { + Set result = new LowDepthService().process( // + FilterUtils.safeSizeFilter(190), // + bytes(serialSampleA), // + bytes(serialBigSampleA), // + bytes(serialSampleC), // + bytes(serialBigSampleC)); + + assertEquals(1, result.size()); + assertEquals("simple", ((Sample) result.iterator() + .next()).getName()); + } + + @Test + void givenFallbackContext_whenUsingBaseClasses_thenRestrictiveFilterApplied() throws IOException { + String a = new String("a"); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + SerializationUtils.serialize(a, outStream); + + String deserializedA = (String) DeserializationUtils.deserialize(bytes(outStream)); + + assertEquals(a, deserializedA); + } + + @Test + void givenFallbackContext_whenUsingAppClasses_thenRejected() throws IOException { + Sample a = new Sample("a"); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + SerializationUtils.serialize(a, outStream); + + Sample deserializedA = (Sample) DeserializationUtils.deserialize(bytes(outStream)); + + assertNull(deserializedA); + } +} From 290147ff08d2d194a8a054a98301f51dc069f3a6 Mon Sep 17 00:00:00 2001 From: MohamedHelmyKassab <137485958+MohamedHelmyKassab@users.noreply.github.com> Date: Fri, 17 Nov 2023 00:27:43 +0200 Subject: [PATCH 27/71] This PR is related to BAEL-7181 (#15230) * Update TimestampToLongUnitTest.java * Update TimestampToLong.java --- .../timestamptolong/TimestampToLong.java | 31 +++++++-------- .../TimestampToLongUnitTest.java | 39 +++++++------------ 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java index 2ebe30f4ff..25a8a57ba7 100644 --- a/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java +++ b/core-java-modules/core-java-datetime-conversion/src/main/java/com/baeldung/timestamptolong/TimestampToLong.java @@ -1,32 +1,31 @@ package com.baeldung.timestamptolong; -import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Date; public class TimestampToLong { - public void usingSimpleDateFormat() throws ParseException { + + public long usingSimpleDateFormat(String timestampString) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - String currentDateString = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); - long actualTimestamp = sdf.parse(currentDateString).getTime(); + Date date = sdf.parse(timestampString); + String currentDateString = sdf.format(date); + return sdf.parse(currentDateString).getTime(); } - public void usingInstantClass() { - Instant instant = Instant.now(); - long actualTimestamp = instant.toEpochMilli(); + public long usingInstantClass(String timestampString) { + Instant instant = LocalDateTime.parse(timestampString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + .atZone(ZoneId.systemDefault()) + .toInstant(); + return instant.toEpochMilli(); } - public void usingTimestamp() { - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - long actualTimestamp = timestamp.getTime(); + public long usingJava8DateTime(String timestampString) { + LocalDateTime localDateTime = LocalDateTime.parse(timestampString.replace(" ", "T")); + return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); } - - public void usingJava8DateTime() { - LocalDateTime localDateTime = LocalDateTime.now(); - long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); - } -} \ No newline at end of file +} diff --git a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java index ede8f7792d..868d019cf2 100644 --- a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java +++ b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolong/TimestampToLongUnitTest.java @@ -2,51 +2,42 @@ package com.baeldung.timestamptolong; import org.junit.Test; -import java.sql.Timestamp; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Date; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; public class TimestampToLongUnitTest { - - private static final long TOLERANCE = 1000; + private static final String timestampString = "2023-11-15 01:02:03"; @Test - public void givenSimpleDateFormat_whenFormattingDate_thenTConvertToLong() throws ParseException { + public void givenSimpleDateFormat_whenFormattingDate_thenConvertToLong() throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = sdf.parse(timestampString); - String currentDateString = sdf.format(new Date()); + String currentDateString = sdf.format(date); long actualTimestamp = sdf.parse(currentDateString).getTime(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + assertEquals(1700010123000L, actualTimestamp); } @Test - public void givenInstantClass_whenGettingTimestamp_thenTConvertToLong() { - Instant instant = Instant.now(); + public void givenInstantClass_whenGettingTimestamp_thenConvertToLong() { + Instant instant = LocalDateTime.parse(timestampString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + .atZone(ZoneId.systemDefault()) + .toInstant(); long actualTimestamp = instant.toEpochMilli(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + assertEquals(1700010123000L, actualTimestamp); } @Test - public void givenTimestamp_whenCreatingTimestamp_thenTConvertToLong() { - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - long actualTimestamp = timestamp.getTime(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); - } - - @Test - public void givenJava8DateTime_whenGettingTimestamp_thenTConvertToLong() { - LocalDateTime localDateTime = LocalDateTime.now(); + public void givenJava8DateTime_whenGettingTimestamp_thenConvertToLong() { + LocalDateTime localDateTime = LocalDateTime.parse(timestampString.replace(" ", "T")); long actualTimestamp = localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); - - assertTrue(Math.abs(System.currentTimeMillis() - actualTimestamp) < TOLERANCE); + assertEquals(1700010123000L, actualTimestamp); } } From 9d441e11b8d53128f733643e3333809564ac6268 Mon Sep 17 00:00:00 2001 From: Mo Helmy <135069400+BenHelmyBen@users.noreply.github.com> Date: Fri, 17 Nov 2023 01:47:49 +0200 Subject: [PATCH 28/71] This commit is related to the article BAEL-7172 (#15232) This commit aims to add two classes that provide insights about the time complexity of Collections.sort(). --- .../CollectionsSortTimeComplexityJMH.java | 60 +++++++++++++++++++ .../CollectionsSortTimeComplexityMain.java | 33 ++++++++++ 2 files changed, 93 insertions(+) create mode 100644 core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java create mode 100644 core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java new file mode 100644 index 0000000000..766a89f674 --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityJMH.java @@ -0,0 +1,60 @@ +package com.baeldung.collectionssortcomplexity; + +import org.openjdk.jmh.annotations.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@Fork(value = 1, warmups = 1) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +public class CollectionsSortTimeComplexityJMH { + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + + } + + @Benchmark + public void measureCollectionsSortBestCase(BestCaseBenchmarkState state) { + List sortedList = new ArrayList<>(state.sortedList); + Collections.sort(sortedList); + } + + @Benchmark + public void measureCollectionsSortAverageWorstCase(AverageWorstCaseBenchmarkState state) { + List unsortedList = new ArrayList<>(state.unsortedList); + Collections.sort(unsortedList); + } + + @State(Scope.Benchmark) + public static class BestCaseBenchmarkState { + List sortedList; + + @Setup(Level.Trial) + public void setUp() { + sortedList = new ArrayList<>(); + for (int i = 1; i <= 1000000; i++) { + sortedList.add(i); + } + } + } + + @State(Scope.Benchmark) + public static class AverageWorstCaseBenchmarkState { + List unsortedList; + + @Setup(Level.Trial) + public void setUp() { + unsortedList = new ArrayList<>(); + for (int i = 1000000; i > 0; i--) { + unsortedList.add(i); + } + } + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java new file mode 100644 index 0000000000..f273d3562a --- /dev/null +++ b/core-java-modules/core-java-collections-5/src/main/java/com/baeldung/collectionssortcomplexity/CollectionsSortTimeComplexityMain.java @@ -0,0 +1,33 @@ +package com.baeldung.collectionssortcomplexity; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class CollectionsSortTimeComplexityMain { + // O(n log n) Time Complexity Example + public static void worstAndAverageCasesTimeComplexity() { + Integer[] sortedArray = {20, 21, 22, 23, 24, 25, 26, 17, 28, 29, 30, 31, 18, 19, 32, 33, 34, 27, 35}; + List list = Arrays.asList(sortedArray); + Collections.shuffle(list); + long startTime = System.nanoTime(); + Collections.sort(list); + long endTime = System.nanoTime(); + System.out.println("Execution Time for O(n log n): " + (endTime - startTime) + " nanoseconds"); + } + + // O(n) Time Complexity Example + public static void bestCaseTimeComplexity() { + Integer[] sortedArray = {19, 22, 19, 22, 24, 25, 17, 11, 22, 23, 28, 23, 0, 1, 12, 9, 13, 27, 15}; + List list = Arrays.asList(sortedArray); + long startTime = System.nanoTime(); + Collections.sort(list); + long endTime = System.nanoTime(); + System.out.println("Execution Time for O(n): " + (endTime - startTime) + " nanoseconds"); + } + + public static void main(String[] args) { + worstAndAverageCasesTimeComplexity(); + bestCaseTimeComplexity(); + } +} From e5215678f385ee012464311a3064835c70129325 Mon Sep 17 00:00:00 2001 From: timis1 Date: Thu, 16 Nov 2023 09:17:03 +0200 Subject: [PATCH 29/71] JAVA-27449 Fix test in libraries-data-io module --- .../com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java b/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java index 7cfe8984e7..6745b9be7f 100644 --- a/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java +++ b/libraries-data-io/src/test/java/com/baeldung/libraries/opencsv/OpenCsvIntegrationTest.java @@ -74,7 +74,7 @@ public class OpenCsvIntegrationTest { assertThat(contents.split(NEW_LINE)) .containsExactly( - "'colA','colB','colC'", + "'COLA','COLB','COLC'", "'Test1','sample','data'", "'Test2','ipso','facto'" ); From 7f88b9748e82bd6b51f37ae9bfb6981a062a9b98 Mon Sep 17 00:00:00 2001 From: Maiklins Date: Fri, 17 Nov 2023 21:24:13 +0100 Subject: [PATCH 30/71] Update and rename ProfileIntegrationStubTest.java to ProfileStubIntegrationTest.java Satisfy test naming convention --- ...IntegrationStubTest.java => ProfileStubIntegrationTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/{ProfileIntegrationStubTest.java => ProfileStubIntegrationTest.java} (97%) diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileStubIntegrationTest.java similarity index 97% rename from spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java rename to spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileStubIntegrationTest.java index e1c88f2a31..2d6eb06d32 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationStubTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileStubIntegrationTest.java @@ -18,7 +18,7 @@ import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) @AutoConfigureMockMvc @ActiveProfiles("stub") -class ProfileIntegrationStubTest { +class ProfileStubIntegrationTest { @Autowired private MockMvc mockMvc; From 92ef912fcf29b2fd755560dad3fdcdf67a89fb59 Mon Sep 17 00:00:00 2001 From: Maiklins Date: Fri, 17 Nov 2023 21:24:57 +0100 Subject: [PATCH 31/71] Update and rename ProfileIntegrationMockTest.java to ProfileMockIntegrationTest.java Satisfy naming convention --- ...IntegrationMockTest.java => ProfileMockIntegrationTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/{ProfileIntegrationMockTest.java => ProfileMockIntegrationTest.java} (97%) diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileMockIntegrationTest.java similarity index 97% rename from spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java rename to spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileMockIntegrationTest.java index 43fb69860d..2fac6d954a 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileIntegrationMockTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/overridebean/profile/ProfileMockIntegrationTest.java @@ -20,7 +20,7 @@ import com.baeldung.overridebean.boot.Application; @SpringBootTest(classes = { Application.class, ProfileConfig.class, Endpoint.class, ProfileTestConfig.class }) @AutoConfigureMockMvc @ActiveProfiles("mock") -class ProfileIntegrationMockTest { +class ProfileMockIntegrationTest { @Autowired private MockMvc mockMvc; From 6cbd1b5b5229d8839b265f41590580570e56f94b Mon Sep 17 00:00:00 2001 From: mikr Date: Fri, 17 Nov 2023 21:32:43 +0100 Subject: [PATCH 32/71] Update readme --- spring-boot-modules/spring-boot-testing-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot-modules/spring-boot-testing-2/README.md b/spring-boot-modules/spring-boot-testing-2/README.md index 1baf83bf34..fbf708381b 100644 --- a/spring-boot-modules/spring-boot-testing-2/README.md +++ b/spring-boot-modules/spring-boot-testing-2/README.md @@ -14,4 +14,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring Boot – Testing Redis With Testcontainers](https://www.baeldung.com/spring-boot-redis-testcontainers) - [Spring Boot – Keycloak Integration Testing with Testcontainers](https://www.baeldung.com/spring-boot-keycloak-integration-testing) - [Difference Between @Spy and @SpyBean](https://www.baeldung.com/spring-spy-vs-spybean) +- [Overriding Spring Beans in Integration Test](https://www.baeldung.com/overriding-spring-beans-in-integration-test) - More articles: [[<-- prev]](../spring-boot-testing) From c9321ed9be544b1444d99d43efa02042dece6e49 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:51:09 +0800 Subject: [PATCH 33/71] Update README.md [skip ci] --- patterns-modules/design-patterns-singleton/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/patterns-modules/design-patterns-singleton/README.md b/patterns-modules/design-patterns-singleton/README.md index edec116b93..a4915ebfaf 100644 --- a/patterns-modules/design-patterns-singleton/README.md +++ b/patterns-modules/design-patterns-singleton/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: - [How to Serialize a Singleton in Java](https://www.baeldung.com/java-serialize-singleton) +- [Bill Pugh Singleton Implementation](https://www.baeldung.com/java-bill-pugh-singleton-implementation) From e264651cfb45520cf11754df075734eae22eb650 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:53:19 +0800 Subject: [PATCH 34/71] Update README.md [skip ci] --- core-java-modules/core-java-io-conversions-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-conversions-2/README.md b/core-java-modules/core-java-io-conversions-2/README.md index 4e179a84d2..bcc1db5f89 100644 --- a/core-java-modules/core-java-io-conversions-2/README.md +++ b/core-java-modules/core-java-io-conversions-2/README.md @@ -12,4 +12,5 @@ This module contains articles about core Java input/output(IO) conversions. - [How to Convert InputStream to Base64 String](https://www.baeldung.com/java-inputstream-to-base64-string) - [Convert an OutputStream to an InputStream](https://www.baeldung.com/java-convert-outputstream-to-inputstream) - [Java PrintStream to String](https://www.baeldung.com/java-printstream-to-string) +- [Convert File to Byte Array in Java](https://www.baeldung.com/java-convert-file-byte-array) - More articles: [[<-- prev]](/core-java-modules/core-java-io-conversions) From a4ac49de8159bf845a8b259ad716293df789bd60 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:56:47 +0800 Subject: [PATCH 35/71] Update README.md [skip ci] --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index 28e2dccd39..b95153b5be 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -3,3 +3,4 @@ - [How to Center Text Output in Java](https://www.baeldung.com/java-center-text-output) - [Capitalize the First Letter of Each Word in a String](https://www.baeldung.com/java-string-initial-capital-letter-every-word) - [Check if a String Contains Only Unicode Letters](https://www.baeldung.com/java-string-all-unicode-characters) +- [Create a Mutable String in Java](https://www.baeldung.com/java-mutable-string) From c921fdcc1981ef629b1f67d0dacd91f9073a7c5f Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 18:59:00 +0800 Subject: [PATCH 36/71] Update README.md [skip ci] --- core-java-modules/core-java-hex/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-hex/README.md b/core-java-modules/core-java-hex/README.md index 0ba4d1372f..2424137b32 100644 --- a/core-java-modules/core-java-hex/README.md +++ b/core-java-modules/core-java-hex/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Convert Hex to RGB Using Java](https://www.baeldung.com/java-convert-hex-to-rgb) +- [Convert a Hex String to an Integer in Java](https://www.baeldung.com/java-convert-hex-string-to-integer) From 23830bfd79bd091ae8b7ec26b1133333edce5da2 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:02:24 +0800 Subject: [PATCH 37/71] Update README.md [skip ci] --- spring-kafka-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-kafka-2/README.md b/spring-kafka-2/README.md index 318312ace6..43b2f59147 100644 --- a/spring-kafka-2/README.md +++ b/spring-kafka-2/README.md @@ -8,3 +8,4 @@ This module contains articles about Spring with Kafka - [Spring Kafka: Configure Multiple Listeners on Same Topic](https://www.baeldung.com/spring-kafka-multiple-listeners-same-topic) - [Understanding Kafka Topics and Partitions](https://www.baeldung.com/kafka-topics-partitions) - [How to Subscribe a Kafka Consumer to Multiple Topics](https://www.baeldung.com/kafka-subscribe-consumer-multiple-topics) +- [Splitting Streams in Kafka](https://www.baeldung.com/kafka-splitting-streams) From de92bcb45d6a25dad5cf1991cc419fb41e154ad3 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:06:22 +0800 Subject: [PATCH 38/71] Update README.md [skip ci] --- core-java-modules/core-java-numbers-6/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-numbers-6/README.md b/core-java-modules/core-java-numbers-6/README.md index cf84e29710..3a2154efdd 100644 --- a/core-java-modules/core-java-numbers-6/README.md +++ b/core-java-modules/core-java-numbers-6/README.md @@ -7,4 +7,5 @@ - [Java Double vs. BigDecimal](https://www.baeldung.com/java-double-vs-bigdecimal) - [Finding the Square Root of a BigInteger in Java](https://www.baeldung.com/java-find-square-root-biginteger) - [Truncate a Double to Two Decimal Places in Java](https://www.baeldung.com/java-double-round-two-decimal-places) +- [Comparing the Values of Two Generic Numbers in Java](https://www.baeldung.com/java-generic-numbers-comparison-methods) - More articles: [[<-- prev]](../core-java-numbers-5) From 2d538b658253fb44713bc117ad9f5dac580e1ca6 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:08:25 +0800 Subject: [PATCH 39/71] Update README.md [skip ci] --- testing-modules/selenium-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/testing-modules/selenium-2/README.md b/testing-modules/selenium-2/README.md index 5403fb9f06..a1d180814d 100644 --- a/testing-modules/selenium-2/README.md +++ b/testing-modules/selenium-2/README.md @@ -2,6 +2,7 @@ - [Running Selenium Scripts with JMeter](https://www.baeldung.com/selenium-jmeter) - [Fixing Selenium WebDriver Executable Path Error](https://www.baeldung.com/java-selenium-webdriver-path-error) - [Implicit Wait vs Explicit Wait in Selenium Webdriver](https://www.baeldung.com/selenium-implicit-explicit-wait) +- [Switching Between Frames Using Selenium WebDriver in Java](https://www.baeldung.com/java-selenium-change-frames) #### Notes: - to run the live tests for the article *Fixing Selenium WebDriver Executable Path Error*, follow the manual setup described From 8459887d19faa6734e0263a8d774784d5d1e1d4c Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:10:58 +0800 Subject: [PATCH 40/71] Update README.md [skip ci] --- core-java-modules/core-java-sun/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core-java-modules/core-java-sun/README.md b/core-java-modules/core-java-sun/README.md index 107035cbe8..54eae58d3e 100644 --- a/core-java-modules/core-java-sun/README.md +++ b/core-java-modules/core-java-sun/README.md @@ -5,4 +5,5 @@ This module contains articles about the sun package ### Relevant Articles: - [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) -- [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) \ No newline at end of file +- [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) +- [Why Is sun.misc.Unsafe.park Actually Unsafe?](https://www.baeldung.com/java-sun-misc-unsafe-park-reason) From f589231fde9f5bb62ba2df6495d314e0e47accc1 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:14:42 +0800 Subject: [PATCH 41/71] Update README.md [skip ci] --- core-java-modules/core-java-collections-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index 4869158d2b..acee8154f7 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -9,4 +9,5 @@ - [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration) - [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue) - [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide) +- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-4) From e5fbd59087857f3940e45e308be553f47f3ec107 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:17:12 +0800 Subject: [PATCH 42/71] Create README.md [skip ci] --- persistence-modules/core-java-persistence-3/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 persistence-modules/core-java-persistence-3/README.md diff --git a/persistence-modules/core-java-persistence-3/README.md b/persistence-modules/core-java-persistence-3/README.md new file mode 100644 index 0000000000..6ca158560b --- /dev/null +++ b/persistence-modules/core-java-persistence-3/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Convert ResultSet Into Map](https://www.baeldung.com/java-resultset-map) From 47b2fef64f2d6a535073e06be9339a9ad014e43b Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:20:17 +0800 Subject: [PATCH 43/71] Update README.md [skip ci] --- persistence-modules/spring-boot-persistence-mongodb-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-boot-persistence-mongodb-3/README.md b/persistence-modules/spring-boot-persistence-mongodb-3/README.md index ee6a96397a..e234c2b3a1 100644 --- a/persistence-modules/spring-boot-persistence-mongodb-3/README.md +++ b/persistence-modules/spring-boot-persistence-mongodb-3/README.md @@ -1,4 +1,5 @@ # Relevant Articles - [How to Insert a HashMap Into MongoDB With Java?](https://www.baeldung.com/java-mongodb-insert-hashmap) - [MongoDB – Field Level Encryption](https://www.baeldung.com/mongodb-field-level-encryption) +- [MongoDB Atlas Search Using the Java Driver and Spring Data](https://www.baeldung.com/mongodb-spring-data-atlas-search) - More articles: [[<--prev]](../spring-boot-persistence-mongodb-2) From 3a3459f2b804a2ef5ee56700b83cd35141f18f23 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:22:32 +0800 Subject: [PATCH 44/71] Update README.md [skip ci] --- core-java-modules/core-java-sun/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-sun/README.md b/core-java-modules/core-java-sun/README.md index 54eae58d3e..82977bca6c 100644 --- a/core-java-modules/core-java-sun/README.md +++ b/core-java-modules/core-java-sun/README.md @@ -7,3 +7,4 @@ This module contains articles about the sun package - [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) - [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe) - [Why Is sun.misc.Unsafe.park Actually Unsafe?](https://www.baeldung.com/java-sun-misc-unsafe-park-reason) +- [Sharing Memory Between JVMs](https://www.baeldung.com/java-sharing-memory-between-jvms) From ccba711e86815cbb9bdd717ac863b9a70c43fad7 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:24:21 +0800 Subject: [PATCH 45/71] Update README.md [skip ci] --- core-java-modules/core-java-concurrency-basic-3/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-concurrency-basic-3/README.md b/core-java-modules/core-java-concurrency-basic-3/README.md index 09d085a32b..1021544e11 100644 --- a/core-java-modules/core-java-concurrency-basic-3/README.md +++ b/core-java-modules/core-java-concurrency-basic-3/README.md @@ -12,4 +12,5 @@ This module contains articles about basic Java concurrency. - [CompletableFuture allOf().join() vs. CompletableFuture.join()](https://www.baeldung.com/java-completablefuture-allof-join) - [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic) - [Convert From List of CompletableFuture to CompletableFuture List](https://www.baeldung.com/java-completablefuture-list-convert) +- [Synchronize a Static Variable Among Different Threads](https://www.baeldung.com/java-synchronize-static-variable-different-threads) - [[<-- Prev]](../core-java-concurrency-basic-2) From 2d7f1c60a7128a96aa347d435985cd61207819f3 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:26:37 +0800 Subject: [PATCH 46/71] Update README.md [skip ci] --- core-java-modules/core-java-console/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-console/README.md b/core-java-modules/core-java-console/README.md index 180193d8c1..77ad16d015 100644 --- a/core-java-modules/core-java-console/README.md +++ b/core-java-modules/core-java-console/README.md @@ -7,3 +7,4 @@ - [ASCII Art in Java](http://www.baeldung.com/ascii-art-in-java) - [System.console() vs. System.out](https://www.baeldung.com/java-system-console-vs-system-out) - [How to Log to the Console in Color](https://www.baeldung.com/java-log-console-in-color) +- [Create Table Using ASCII in a Console in Java](https://www.baeldung.com/java-console-ascii-make-table) From cf421052d972731820f5c9e74b87b457227ba116 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:30:06 +0800 Subject: [PATCH 47/71] Update README.md [skip ci] --- core-java-modules/core-java-8-datetime-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index 462a4be6f1..f7ada52da6 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -7,4 +7,5 @@ - [Difference Between Instant and LocalDateTime](https://www.baeldung.com/java-instant-vs-localdatetime) - [Add Minutes to a Time String in Java](https://www.baeldung.com/java-string-time-add-mins) - [Round the Date in Java](https://www.baeldung.com/java-round-the-date) +- [Representing Furthest Possible Date in Java](https://www.baeldung.com/java-date-represent-max) - [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) From b62d0436d4de59f26ece1b2808c2ecf5105963eb Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:33:12 +0800 Subject: [PATCH 48/71] Update README.md [skip ci] --- core-java-modules/core-java-streams-5/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-streams-5/README.md b/core-java-modules/core-java-streams-5/README.md index 64bc4e6b7a..dfd5a649b5 100644 --- a/core-java-modules/core-java-streams-5/README.md +++ b/core-java-modules/core-java-streams-5/README.md @@ -7,3 +7,4 @@ - [Taking Every N-th Element from Finite and Infinite Streams in Java](https://www.baeldung.com/java-nth-element-finite-infinite-streams) - [Modifying Objects Within Stream While Iterating](https://www.baeldung.com/java-stream-modify-objects-during-iteration) - [Convert a Stream into a Map or Multimap in Java](https://www.baeldung.com/java-convert-stream-map-multimap) +- [How to Avoid NoSuchElementException in Stream API](https://www.baeldung.com/java-streams-api-avoid-nosuchelementexception) From 66b8dc1411c5c82db4fc431859dde3e128eb248e Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 19:35:11 +0800 Subject: [PATCH 49/71] Update README.md [skip ci] --- apache-kafka-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/apache-kafka-2/README.md b/apache-kafka-2/README.md index 40ee701be1..3aa8fcf4ad 100644 --- a/apache-kafka-2/README.md +++ b/apache-kafka-2/README.md @@ -14,3 +14,4 @@ You can build the project from the command line using: *mvn clean install*, or i - [Get Partition Count for a Topic in Kafka](https://www.baeldung.com/java-kafka-partition-count-topic) - [bootstrap-server in Kafka Configuration](https://www.baeldung.com/java-kafka-bootstrap-server) - [Introduction to Apache Kafka](https://www.baeldung.com/apache-kafka) +- [Ensuring Message Ordering in Kafka: Strategies and Configurations](https://www.baeldung.com/kafka-message-ordering) From 607fc54bf009a23551a107dc2bcd3f45ba66280c Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 20:48:00 +0800 Subject: [PATCH 50/71] Update README.md --- core-java-modules/core-java-string-operations-6/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/core-java-modules/core-java-string-operations-6/README.md b/core-java-modules/core-java-string-operations-6/README.md index 9d92552dd1..506b548304 100644 --- a/core-java-modules/core-java-string-operations-6/README.md +++ b/core-java-modules/core-java-string-operations-6/README.md @@ -11,4 +11,3 @@ - [Check if a String Has All Unique Characters in Java](https://www.baeldung.com/java-check-string-all-unique-chars) - [Performance Comparison Between Different Java String Concatenation Methods](https://www.baeldung.com/java-string-concatenation-methods) - [Replacing Single Quote with \’ in Java String](https://www.baeldung.com/java-replacing-single-quote-string) -- [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence) From cf51f27dfc3bf62af25ef71b3a6b6e42ba510ec1 Mon Sep 17 00:00:00 2001 From: edizor <113095366+edizor@users.noreply.github.com> Date: Sat, 18 Nov 2023 20:48:36 +0800 Subject: [PATCH 51/71] Update README.md --- core-java-modules/core-java-string-operations-7/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-string-operations-7/README.md b/core-java-modules/core-java-string-operations-7/README.md index b95153b5be..2b9c4c25f3 100644 --- a/core-java-modules/core-java-string-operations-7/README.md +++ b/core-java-modules/core-java-string-operations-7/README.md @@ -4,3 +4,4 @@ - [Capitalize the First Letter of Each Word in a String](https://www.baeldung.com/java-string-initial-capital-letter-every-word) - [Check if a String Contains Only Unicode Letters](https://www.baeldung.com/java-string-all-unicode-characters) - [Create a Mutable String in Java](https://www.baeldung.com/java-mutable-string) +- [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence) From 80da8b957d2633c47de5973dd062722ada1b6312 Mon Sep 17 00:00:00 2001 From: Gaetano Piazzolla Date: Sun, 19 Nov 2023 11:48:20 +0100 Subject: [PATCH 52/71] JAVA-13263 | individual build (#15221) * JAVA-13263 | individual build * JAVA-13263 | updating wrapper to more recent version of gradle 7 * JAVA-13263 | adding wrapper jar --- gradle-modules/.gitignore | 1 + gradle-modules/gradle-5/README.md | 2 + .../gradle/wrapper/gradle-wrapper.properties | 3 +- .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes .../gradle/wrapper/gradle-wrapper.properties | 4 +- gradle-modules/gradle/gradle/shipkit.gradle | 41 ------------------ .../gradle/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 63721 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 ++- 10 files changed, 11 insertions(+), 45 deletions(-) create mode 100644 gradle-modules/.gitignore create mode 100644 gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle-modules/gradle/gradle/shipkit.gradle create mode 100644 gradle-modules/gradle/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle-modules/.gitignore b/gradle-modules/.gitignore new file mode 100644 index 0000000000..63b7142f43 --- /dev/null +++ b/gradle-modules/.gitignore @@ -0,0 +1 @@ +!gradle-wrapper.jar \ No newline at end of file diff --git a/gradle-modules/gradle-5/README.md b/gradle-modules/gradle-5/README.md index 7871c0e822..6d701ac43c 100644 --- a/gradle-modules/gradle-5/README.md +++ b/gradle-modules/gradle-5/README.md @@ -1,5 +1,7 @@ ### Relevant Articles: +This module is using gradle-8.3. + - [Run a Java main Method Using Gradle](https://www.baeldung.com/gradle-run-java-main) - [Finding Unused Gradle Dependencies](https://www.baeldung.com/gradle-finding-unused-dependencies) - [Intro to Gradle Lint Plugin](https://www.baeldung.com/java-gradle-lint-intro) diff --git a/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties index 94920145f3..cd141cfc9d 100644 --- a/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-6/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists + diff --git a/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-7/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 diff --git a/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-8/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et zwk~hMkhq;MOw^Q5`7oC{CUUyTw9x>^%*FHx^qJw(LB+E0WBX@{Ghw;)6aA-KyYg8p z7XDveQOpEr;B4je@2~usI5BlFadedX^ma{b{ypd|RNYqo#~d*mj&y`^iojR}s%~vF z(H!u`yx68D1Tj(3(m;Q+Ma}s2n#;O~bcB1`lYk%Irx60&-nWIUBr2x&@}@76+*zJ5 ze&4?q8?m%L9c6h=J$WBzbiTf1Z-0Eb5$IZs>lvm$>1n_Mezp*qw_pr8<8$6f)5f<@ zyV#tzMCs51nTv_5ca`x`yfE5YA^*%O_H?;tWYdM_kHPubA%vy47i=9>Bq) zRQ&0UwLQHeswmB1yP)+BiR;S+Vc-5TX84KUA;8VY9}yEj0eESSO`7HQ4lO z4(CyA8y1G7_C;6kd4U3K-aNOK!sHE}KL_-^EDl(vB42P$2Km7$WGqNy=%fqB+ zSLdrlcbEH=T@W8V4(TgoXZ*G1_aq$K^@ek=TVhoKRjw;HyI&coln|uRr5mMOy2GXP zwr*F^Y|!Sjr2YQXX(Fp^*`Wk905K%$bd03R4(igl0&7IIm*#f`A!DCarW9$h$z`kYk9MjjqN&5-DsH@8xh63!fTNPxWsFQhNv z#|3RjnP$Thdb#Ys7M+v|>AHm0BVTw)EH}>x@_f4zca&3tXJhTZ8pO}aN?(dHo)44Z z_5j+YP=jMlFqwvf3lq!57-SAuRV2_gJ*wsR_!Y4Z(trO}0wmB9%f#jNDHPdQGHFR; zZXzS-$`;7DQ5vF~oSgP3bNV$6Z(rwo6W(U07b1n3UHqml>{=6&-4PALATsH@Bh^W? z)ob%oAPaiw{?9HfMzpGb)@Kys^J$CN{uf*HX?)z=g`J(uK1YO^8~s1(ZIbG%Et(|q z$D@_QqltVZu9Py4R0Ld8!U|#`5~^M=b>fnHthzKBRr=i+w@0Vr^l|W;=zFT#PJ?*a zbC}G#It}rQP^Ait^W&aa6B;+0gNvz4cWUMzpv(1gvfw-X4xJ2Sv;mt;zb2Tsn|kSS zo*U9N?I{=-;a-OybL4r;PolCfiaL=y@o9{%`>+&FI#D^uy#>)R@b^1ue&AKKwuI*` zx%+6r48EIX6nF4o;>)zhV_8(IEX})NGU6Vs(yslrx{5fII}o3SMHW7wGtK9oIO4OM&@@ECtXSICLcPXoS|{;=_yj>hh*%hP27yZwOmj4&Lh z*Nd@OMkd!aKReoqNOkp5cW*lC)&C$P?+H3*%8)6HcpBg&IhGP^77XPZpc%WKYLX$T zsSQ$|ntaVVOoRat$6lvZO(G-QM5s#N4j*|N_;8cc2v_k4n6zx9c1L4JL*83F-C1Cn zaJhd;>rHXB%%ZN=3_o3&Qd2YOxrK~&?1=UuN9QhL$~OY-Qyg&})#ez*8NpQW_*a&kD&ANjedxT0Ar z<6r{eaVz3`d~+N~vkMaV8{F?RBVemN(jD@S8qO~L{rUw#=2a$V(7rLE+kGUZ<%pdr z?$DP|Vg#gZ9S}w((O2NbxzQ^zTot=89!0^~hE{|c9q1hVzv0?YC5s42Yx($;hAp*E zyoGuRyphQY{Q2ee0Xx`1&lv(l-SeC$NEyS~8iil3_aNlnqF_G|;zt#F%1;J)jnPT& z@iU0S;wHJ2$f!juqEzPZeZkjcQ+Pa@eERSLKsWf=`{R@yv7AuRh&ALRTAy z8=g&nxsSJCe!QLchJ=}6|LshnXIK)SNd zRkJNiqHwKK{SO;N5m5wdL&qK`v|d?5<4!(FAsDxR>Ky#0#t$8XCMptvNo?|SY?d8b z`*8dVBlXTUanlh6n)!EHf2&PDG8sXNAt6~u-_1EjPI1|<=33T8 zEnA00E!`4Ave0d&VVh0e>)Dc}=FfAFxpsC1u9ATfQ`-Cu;mhc8Z>2;uyXtqpLb7(P zd2F9<3cXS} znMg?{&8_YFTGRQZEPU-XPq55%51}RJpw@LO_|)CFAt62-_!u_Uq$csc+7|3+TV_!h z+2a7Yh^5AA{q^m|=KSJL+w-EWDBc&I_I1vOr^}P8i?cKMhGy$CP0XKrQzCheG$}G# zuglf8*PAFO8%xop7KSwI8||liTaQ9NCAFarr~psQt)g*pC@9bORZ>m`_GA`_K@~&% zijH0z;T$fd;-Liw8%EKZas>BH8nYTqsK7F;>>@YsE=Rqo?_8}UO-S#|6~CAW0Oz1} z3F(1=+#wrBJh4H)9jTQ_$~@#9|Bc1Pd3rAIA_&vOpvvbgDJOM(yNPhJJq2%PCcMaI zrbe~toYzvkZYQ{ea(Wiyu#4WB#RRN%bMe=SOk!CbJZv^m?Flo5p{W8|0i3`hI3Np# zvCZqY%o258CI=SGb+A3yJe~JH^i{uU`#U#fvSC~rWTq+K`E%J@ zasU07&pB6A4w3b?d?q}2=0rA#SA7D`X+zg@&zm^iA*HVi z009#PUH<%lk4z~p^l0S{lCJk1Uxi=F4e_DwlfHA`X`rv(|JqWKAA5nH+u4Da+E_p+ zVmH@lg^n4ixs~*@gm_dgQ&eDmE1mnw5wBz9Yg?QdZwF|an67Xd*x!He)Gc8&2!urh z4_uXzbYz-aX)X1>&iUjGp;P1u8&7TID0bTH-jCL&Xk8b&;;6p2op_=y^m@Nq*0{#o!!A;wNAFG@0%Z9rHo zcJs?Th>Ny6+hI`+1XoU*ED$Yf@9f91m9Y=#N(HJP^Y@ZEYR6I?oM{>&Wq4|v0IB(p zqX#Z<_3X(&{H+{3Tr|sFy}~=bv+l=P;|sBz$wk-n^R`G3p0(p>p=5ahpaD7>r|>pm zv;V`_IR@tvZreIuv2EM7ZQHhO+qUgw#kOs%*ekY^n|=1#x9&c;Ro&I~{rG-#_3ZB1 z?|9}IFdbP}^DneP*T-JaoYHt~r@EfvnPE5EKUwIxjPbsr$% zfWW83pgWST7*B(o=kmo)74$8UU)v0{@4DI+ci&%=#90}!CZz|rnH+Mz=HN~97G3~@ z;v5(9_2%eca(9iu@J@aqaMS6*$TMw!S>H(b z4(*B!|H|8&EuB%mITr~O?vVEf%(Gr)6E=>H~1VR z&1YOXluJSG1!?TnT)_*YmJ*o_Q@om~(GdrhI{$Fsx_zrkupc#y{DK1WOUR>tk>ZE) ziOLoBkhZZ?0Uf}cm>GsA>Rd6V8@JF)J*EQlQ<=JD@m<)hyElXR0`pTku*3MU`HJn| zIf7$)RlK^pW-$87U;431;Ye4Ie+l~_B3*bH1>*yKzn23cH0u(i5pXV! z4K?{3oF7ZavmmtTq((wtml)m6i)8X6ot_mrE-QJCW}Yn!(3~aUHYG=^fA<^~`e3yc z-NWTb{gR;DOUcK#zPbN^D*e=2eR^_!(!RKkiwMW@@yYtEoOp4XjOGgzi`;=8 zi3`Ccw1%L*y(FDj=C7Ro-V?q)-%p?Ob2ZElu`eZ99n14-ZkEV#y5C+{Pq87Gu3&>g zFy~Wk7^6v*)4pF3@F@rE__k3ikx(hzN3@e*^0=KNA6|jC^B5nf(XaoQaZN?Xi}Rn3 z$8&m*KmWvPaUQ(V<#J+S&zO|8P-#!f%7G+n_%sXp9=J%Z4&9OkWXeuZN}ssgQ#Tcj z8p6ErJQJWZ+fXLCco=RN8D{W%+*kko*2-LEb))xcHwNl~Xmir>kmAxW?eW50Osw3# zki8Fl$#fvw*7rqd?%E?}ZX4`c5-R&w!Y0#EBbelVXSng+kUfeUiqofPehl}$ormli zg%r)}?%=?_pHb9`Cq9Z|B`L8b>(!+8HSX?`5+5mm81AFXfnAt1*R3F z%b2RPIacKAddx%JfQ8l{3U|vK@W7KB$CdLqn@wP^?azRks@x8z59#$Q*7q!KilY-P zHUbs(IFYRGG1{~@RF;Lqyho$~7^hNC`NL3kn^Td%A7dRgr_&`2k=t+}D-o9&C!y^? z6MsQ=tc3g0xkK(O%DzR9nbNB(r@L;1zQrs8mzx&4dz}?3KNYozOW5;=w18U6$G4U2 z#2^qRLT*Mo4bV1Oeo1PKQ2WQS2Y-hv&S|C7`xh6=Pj7MNLC5K-zokZ67S)C;(F0Dd zloDK2_o1$Fmza>EMj3X9je7e%Q`$39Dk~GoOj89-6q9|_WJlSl!!+*{R=tGp z8u|MuSwm^t7K^nUe+^0G3dkGZr3@(X+TL5eah)K^Tn zXEtHmR9UIaEYgD5Nhh(s*fcG_lh-mfy5iUF3xxpRZ0q3nZ=1qAtUa?(LnT9I&~uxX z`pV?+=|-Gl(kz?w!zIieXT}o}7@`QO>;u$Z!QB${a08_bW0_o@&9cjJUXzVyNGCm8 zm=W+$H!;_Kzp6WQqxUI;JlPY&`V}9C$8HZ^m?NvI*JT@~BM=()T()Ii#+*$y@lTZBkmMMda>7s#O(1YZR+zTG@&}!EXFG{ zEWPSDI5bFi;NT>Yj*FjH((=oe%t%xYmE~AGaOc4#9K_XsVpl<4SP@E!TgC0qpe1oi zNpxU2b0(lEMcoibQ-G^cxO?ySVW26HoBNa;n0}CWL*{k)oBu1>F18X061$SP{Gu67 z-v-Fa=Fl^u3lnGY^o5v)Bux}bNZ~ z5pL+7F_Esoun8^5>z8NFoIdb$sNS&xT8_|`GTe8zSXQzs4r^g0kZjg(b0bJvz`g<70u9Z3fQILX1Lj@;@+##bP|FAOl)U^9U>0rx zGi)M1(Hce)LAvQO-pW!MN$;#ZMX?VE(22lTlJrk#pB0FJNqVwC+*%${Gt#r_tH9I_ z;+#)#8cWAl?d@R+O+}@1A^hAR1s3UcW{G+>;X4utD2d9X(jF555}!TVN-hByV6t+A zdFR^aE@GNNgSxxixS2p=on4(+*+f<8xrwAObC)D5)4!z7)}mTpb7&ofF3u&9&wPS< zB62WHLGMhmrmOAgmJ+|c>qEWTD#jd~lHNgT0?t-p{T=~#EMcB| z=AoDKOL+qXCfk~F)-Rv**V}}gWFl>liXOl7Uec_8v)(S#av99PX1sQIVZ9eNLkhq$ zt|qu0b?GW_uo}TbU8!jYn8iJeIP)r@;!Ze_7mj{AUV$GEz6bDSDO=D!&C9!M@*S2! zfGyA|EPlXGMjkH6x7OMF?gKL7{GvGfED=Jte^p=91FpCu)#{whAMw`vSLa`K#atdN zThnL+7!ZNmP{rc=Z>%$meH;Qi1=m1E3Lq2D_O1-X5C;!I0L>zur@tPAC9*7Jeh)`;eec}1`nkRP(%iv-`N zZ@ip-g|7l6Hz%j%gcAM}6-nrC8oA$BkOTz^?dakvX?`^=ZkYh%vUE z9+&)K1UTK=ahYiaNn&G5nHUY5niLGus@p5E2@RwZufRvF{@$hW{;{3QhjvEHMvduO z#Wf-@oYU4ht?#uP{N3utVzV49mEc9>*TV_W2TVC`6+oI)zAjy$KJrr=*q##&kobiQ z1vNbya&OVjK`2pdRrM?LuK6BgrLN7H_3m z!qpNKg~87XgCwb#I=Q&0rI*l$wM!qTkXrx1ko5q-f;=R2fImRMwt5Qs{P*p^z@9ex z`2#v(qE&F%MXlHpdO#QEZyZftn4f05ab^f2vjxuFaat2}jke{j?5GrF=WYBR?gS(^ z9SBiNi}anzBDBRc+QqizTTQuJrzm^bNA~A{j%ugXP7McZqJ}65l10({wk++$=e8O{ zxWjG!Qp#5OmI#XRQQM?n6?1ztl6^D40hDJr?4$Wc&O_{*OfMfxe)V0=e{|N?J#fgE>j9jAajze$iN!*yeF%jJU#G1c@@rm zolGW!j?W6Q8pP=lkctNFdfgUMg92wlM4E$aks1??M$~WQfzzzXtS)wKrr2sJeCN4X zY(X^H_c^PzfcO8Bq(Q*p4c_v@F$Y8cHLrH$`pJ2}=#*8%JYdqsqnGqEdBQMpl!Ot04tUGSXTQdsX&GDtjbWD=prcCT9(+ z&UM%lW%Q3yrl1yiYs;LxzIy>2G}EPY6|sBhL&X&RAQrSAV4Tlh2nITR?{6xO9ujGu zr*)^E`>o!c=gT*_@6S&>0POxcXYNQd&HMw6<|#{eSute2C3{&h?Ah|cw56-AP^f8l zT^kvZY$YiH8j)sk7_=;gx)vx-PW`hbSBXJGCTkpt;ap(}G2GY=2bbjABU5)ty%G#x zAi07{Bjhv}>OD#5zh#$0w;-vvC@^}F! z#X$@)zIs1L^E;2xDAwEjaXhTBw2<{&JkF*`;c3<1U@A4MaLPe{M5DGGkL}#{cHL%* zYMG+-Fm0#qzPL#V)TvQVI|?_M>=zVJr9>(6ib*#z8q@mYKXDP`k&A4A};xMK0h=yrMp~JW{L?mE~ph&1Y1a#4%SO)@{ zK2juwynUOC)U*hVlJU17%llUxAJFuKZh3K0gU`aP)pc~bE~mM!i1mi!~LTf>1Wp< zuG+ahp^gH8g8-M$u{HUWh0m^9Rg@cQ{&DAO{PTMudV6c?ka7+AO& z746QylZ&Oj`1aqfu?l&zGtJnpEQOt;OAFq19MXTcI~`ZcoZmyMrIKDFRIDi`FH)w; z8+*8tdevMDv*VtQi|e}CnB_JWs>fhLOH-+Os2Lh!&)Oh2utl{*AwR)QVLS49iTp{6 z;|172Jl!Ml17unF+pd+Ff@jIE-{Oxv)5|pOm@CkHW?{l}b@1>Pe!l}VccX#xp@xgJ zyE<&ep$=*vT=}7vtvif0B?9xw_3Gej7mN*dOHdQPtW5kA5_zGD zpA4tV2*0E^OUimSsV#?Tg#oiQ>%4D@1F5@AHwT8Kgen$bSMHD3sXCkq8^(uo7CWk`mT zuslYq`6Yz;L%wJh$3l1%SZv#QnG3=NZ=BK4yzk#HAPbqXa92;3K5?0kn4TQ`%E%X} z&>Lbt!!QclYKd6+J7Nl@xv!uD%)*bY-;p`y^ZCC<%LEHUi$l5biu!sT3TGGSTPA21 zT8@B&a0lJHVn1I$I3I1I{W9fJAYc+8 zVj8>HvD}&O`TqU2AAb={?eT;0hyL(R{|h23=4fDSZKC32;wWxsVj`P z3J3{M$PwdH!ro*Cn!D&=jnFR>BNGR<<|I8CI@+@658Dy(lhqbhXfPTVecY@L8%`3Q z1Fux2w?2C3th60jI~%OC9BtpNF$QPqcG+Pz96qZJ71_`0o0w_q7|h&O>`6U+^BA&5 zXd5Zp1Xkw~>M%RixTm&OqpNl8Q+ue=92Op_>T~_9UON?ZM2c0aGm=^A4ejrXj3dV9 zhh_bCt-b9`uOX#cFLj!vhZ#lS8Tc47OH>*)y#{O9?AT~KR9LntM|#l#Dlm^8{nZdk zjMl#>ZM%#^nK2TPzLcKxqx24P7R1FPlBy7LSBrRvx>fE$9AJ;7{PQm~^LBX^k#6Zq zw*Z(zJC|`!6_)EFR}8|n8&&Rbj8y028~P~sFXBFRt+tmqH-S3<%N;C&WGH!f3{7cm zy_fCAb9@HqaXa1Y5vFbxWf%#zg6SI$C+Uz5=CTO}e|2fjWkZ;Dx|84Ow~bkI=LW+U zuq;KSv9VMboRvs9)}2PAO|b(JCEC_A0wq{uEj|3x@}*=bOd zwr{TgeCGG>HT<@Zeq8y}vTpwDg#UBvD)BEs@1KP$^3$sh&_joQPn{hjBXmLPJ{tC) z*HS`*2+VtJO{|e$mM^|qv1R*8i(m1`%)}g=SU#T#0KlTM2RSvYUc1fP+va|4;5}Bfz98UvDCpq7}+SMV&;nX zQw~N6qOX{P55{#LQkrZk(e5YGzr|(B;Q;ju;2a`q+S9bsEH@i1{_Y0;hWYn1-79jl z5c&bytD*k)GqrVcHn6t-7kinadiD>B{Tl`ZY@`g|b~pvHh5!gKP4({rp?D0aFd_cN zhHRo4dd5^S6ViN(>(28qZT6E>??aRhc($kP`>@<+lIKS5HdhjVU;>f7<4))E*5|g{ z&d1}D|vpuV^eRj5j|xx9nwaCxXFG?Qbjn~_WSy=N}P0W>MP zG-F%70lX5Xr$a)2i6?i|iMyM|;Jtf*hO?=Jxj12oz&>P=1#h~lf%#fc73M2_(SUM- zf&qnjS80|_Y0lDgl&I?*eMumUklLe_=Td!9G@eR*tcPOgIShJipp3{A10u(4eT~DY zHezEj8V+7m!knn7)W!-5QI3=IvC^as5+TW1@Ern@yX| z7Nn~xVx&fGSr+L%4iohtS3w^{-H1A_5=r&x8}R!YZvp<2T^YFvj8G_vm}5q;^UOJf ztl=X3iL;;^^a#`t{Ae-%5Oq{?M#s6Npj+L(n-*LMI-yMR{)qki!~{5z{&`-iL}lgW zxo+tnvICK=lImjV$Z|O_cYj_PlEYCzu-XBz&XC-JVxUh9;6*z4fuBG+H{voCC;`~GYV|hj%j_&I zDZCj>Q_0RCwFauYoVMiUSB+*Mx`tg)bWmM^SwMA+?lBg12QUF_x2b)b?qb88K-YUd z0dO}3k#QirBV<5%jL$#wlf!60dizu;tsp(7XLdI=eQs?P`tOZYMjVq&jE)qK*6B^$ zBe>VvH5TO>s>izhwJJ$<`a8fakTL!yM^Zfr2hV9`f}}VVUXK39p@G|xYRz{fTI+Yq z20d=)iwjuG9RB$%$^&8#(c0_j0t_C~^|n+c`Apu|x7~;#cS-s=X1|C*YxX3ailhg_|0`g!E&GZJEr?bh#Tpb8siR=JxWKc{#w7g zWznLwi;zLFmM1g8V5-P#RsM@iX>TK$xsWuujcsVR^7TQ@!+vCD<>Bk9tdCo7Mzgq5 zv8d>dK9x8C@Qoh01u@3h0X_`SZluTb@5o;{4{{eF!-4405x8X7hewZWpz z2qEi4UTiXTvsa(0X7kQH{3VMF>W|6;6iTrrYD2fMggFA&-CBEfSqPlQDxqsa>{e2M z(R5PJ7uOooFc|9GU0ELA%m4&4Ja#cQpNw8i8ACAoK6?-px+oBl_yKmenZut#Xumjz zk8p^OV2KY&?5MUwGrBOo?ki`Sxo#?-Q4gw*Sh0k`@ zFTaYK2;}%Zk-68`#5DXU$2#=%YL#S&MTN8bF+!J2VT6x^XBci6O)Q#JfW{YMz) zOBM>t2rSj)n#0a3cjvu}r|k3od6W(SN}V-cL?bi*Iz-8uOcCcsX0L>ZXjLqk zZu2uHq5B|Kt>e+=pPKu=1P@1r9WLgYFq_TNV1p9pu0erHGd!+bBp!qGi+~4A(RsYN@CyXNrC&hxGmW)u5m35OmWwX`I+0yByglO`}HC4nGE^_HUs^&A(uaM zKPj^=qI{&ayOq#z=p&pnx@@k&I1JI>cttJcu@Ihljt?6p^6{|ds`0MoQwp+I{3l6` zB<9S((RpLG^>=Kic`1LnhpW2=Gu!x`m~=y;A`Qk!-w`IN;S8S930#vBVMv2vCKi}u z6<-VPrU0AnE&vzwV(CFC0gnZYcpa-l5T0ZS$P6(?9AM;`Aj~XDvt;Jua=jIgF=Fm? zdp=M$>`phx%+Gu};;-&7T|B1AcC#L4@mW5SV_^1BRbo6;2PWe$r+npRV`yc;T1mo& z+~_?7rA+(Um&o@Tddl zL_hxvWk~a)yY}%j`Y+200D%9$bWHy&;(yj{jpi?Rtz{J66ANw)UyPOm;t6FzY3$hx zcn)Ir79nhFvNa7^a{SHN7XH*|Vlsx`CddPnA&Qvh8aNhEA;mPVv;Ah=k<*u!Zq^7 z<=xs*iQTQOMMcg|(NA_auh@x`3#_LFt=)}%SQppP{E>mu_LgquAWvh<>L7tf9+~rO znwUDS52u)OtY<~!d$;m9+87aO+&`#2ICl@Y>&F{jI=H(K+@3M1$rr=*H^dye#~TyD z!){#Pyfn+|ugUu}G;a~!&&0aqQ59U@UT3|_JuBlYUpT$2+11;}JBJ`{+lQN9T@QFY z5+`t;6(TS0F?OlBTE!@7D`8#URDNqx2t6`GZ{ZgXeS@v%-eJzZOHz18aS|svxII$a zZeFjrJ*$IwX$f-Rzr_G>xbu@euGl)B7pC&S+CmDJBg$BoV~jxSO#>y z33`bupN#LDoW0feZe0%q8un0rYN|eRAnwDHQ6e_)xBTbtoZtTA=Fvk){q}9Os~6mQ zKB80VI_&6iSq`LnK7*kfHZoeX6?WE}8yjuDn=2#JG$+;-TOA1%^=DnXx%w{b=w}tS zQbU3XxtOI8E(!%`64r2`zog;5<0b4i)xBmGP^jiDZ2%HNSxIf3@wKs~uk4%3Mxz;~ zts_S~E4>W+YwI<-*-$U8*^HKDEa8oLbmqGg?3vewnaNg%Mm)W=)lcC_J+1ov^u*N3 zXJ?!BrH-+wGYziJq2Y#vyry6Z>NPgkEk+Ke`^DvNRdb>Q2Nlr#v%O@<5hbflI6EKE z9dWc0-ORk^T}jP!nkJ1imyjdVX@GrjOs%cpgA8-c&FH&$(4od#x6Y&=LiJZPINVyW z0snY$8JW@>tc2}DlrD3StQmA0Twck~@>8dSix9CyQOALcREdxoM$Sw*l!}bXKq9&r zysMWR@%OY24@e`?+#xV2bk{T^C_xSo8v2ZI=lBI*l{RciPwuE>L5@uhz@{!l)rtVlWC>)6(G)1~n=Q|S!{E9~6*fdpa*n z!()-8EpTdj=zr_Lswi;#{TxbtH$8*G=UM`I+icz7sr_SdnHXrv=?iEOF1UL+*6O;% zPw>t^kbW9X@oEXx<97%lBm-9?O_7L!DeD)Me#rwE54t~UBu9VZ zl_I1tBB~>jm@bw0Aljz8! zXBB6ATG6iByKIxs!qr%pz%wgqbg(l{65DP4#v(vqhhL{0b#0C8mq`bnqZ1OwFV z7mlZZJFMACm>h9v^2J9+^_zc1=JjL#qM5ZHaThH&n zXPTsR8(+)cj&>Un{6v*z?@VTLr{TmZ@-fY%*o2G}*G}#!bmqpoo*Ay@U!JI^Q@7gj;Kg-HIrLj4}#ec4~D2~X6vo;ghep-@&yOivYP zC19L0D`jjKy1Yi-SGPAn94(768Tcf$urAf{)1)9W58P`6MA{YG%O?|07!g9(b`8PXG1B1Sh0?HQmeJtP0M$O$hI z{5G`&9XzYhh|y@qsF1GnHN|~^ru~HVf#)lOTSrv=S@DyR$UKQk zjdEPFDz{uHM&UM;=mG!xKvp;xAGHOBo~>_=WFTmh$chpC7c`~7?36h)7$fF~Ii}8q zF|YXxH-Z?d+Q+27Rs3X9S&K3N+)OBxMHn1u(vlrUC6ckBY@@jl+mgr#KQUKo#VeFm zFwNYgv0<%~Wn}KeLeD9e1$S>jhOq&(e*I@L<=I5b(?G(zpqI*WBqf|Zge0&aoDUsC zngMRA_Kt0>La+Erl=Uv_J^p(z=!?XHpenzn$%EA`JIq#yYF?JLDMYiPfM(&Csr#f{ zdd+LJL1by?xz|D8+(fgzRs~(N1k9DSyK@LJygwaYX8dZl0W!I&c^K?7)z{2is;OkE zd$VK-(uH#AUaZrp=1z;O*n=b?QJkxu`Xsw&7yrX0?(CX=I-C#T;yi8a<{E~?vr3W> zQrpPqOW2M+AnZ&p{hqmHZU-;Q(7?- zP8L|Q0RM~sB0w1w53f&Kd*y}ofx@c z5Y6B8qGel+uT1JMot$nT1!Tim6{>oZzJXdyA+4euOLME?5Fd_85Uk%#E*ln%y{u8Q z$|?|R@Hpb~yTVK-Yr_S#%NUy7EBfYGAg>b({J|5b+j-PBpPy$Ns`PaJin4JdRfOaS zE|<HjH%NuJgsd2wOlv>~y=np%=2)$M9LS|>P)zJ+Fei5vYo_N~B0XCn+GM76 z)Xz3tg*FRVFgIl9zpESgdpWAavvVViGlU8|UFY{{gVJskg*I!ZjWyk~OW-Td4(mZ6 zB&SQreAAMqwp}rjy`HsG({l2&q5Y52<@AULVAu~rWI$UbFuZs>Sc*x+XI<+ez%$U)|a^unjpiW0l0 zj1!K0(b6$8LOjzRqQ~K&dfbMIE=TF}XFAi)$+h}5SD3lo z%%Qd>p9se=VtQG{kQ;N`sI)G^u|DN#7{aoEd zkksYP%_X$Rq08);-s6o>CGJ<}v`qs%eYf+J%DQ^2k68C%nvikRsN?$ap--f+vCS`K z#&~)f7!N^;sdUXu54gl3L=LN>FB^tuK=y2e#|hWiWUls__n@L|>xH{%8lIJTd5`w? zSwZbnS;W~DawT4OwSJVdAylbY+u5S+ZH{4hAi2&}Iv~W(UvHg(1GTZRPz`@{SOqzy z(8g&Dz=$PfRV=6FgxN~zo+G8OoPI&d-thcGVR*_^(R8COTM@bq?fDwY{}WhsQS1AK zF6R1t8!RdFmfocpJ6?9Yv~;WYi~XPgs(|>{5})j!AR!voO7y9&cMPo#80A(`za@t>cx<0;qxM@S*m(jYP)dMXr*?q0E`oL;12}VAep179uEr8c<=D zr5?A*C{eJ`z9Ee;E$8)MECqatHkbHH z&Y+ho0B$31MIB-xm&;xyaFCtg<{m~M-QDbY)fQ>Q*Xibb~8ytxZQ?QMf9!%cV zU0_X1@b4d+Pg#R!`OJ~DOrQz3@cpiGy~XSKjZQQ|^4J1puvwKeScrH8o{bscBsowomu z^f12kTvje`yEI3eEXDHJ6L+O{Jv$HVj%IKb|J{IvD*l6IG8WUgDJ*UGz z3!C%>?=dlfSJ>4U88)V+`U-!9r^@AxJBx8R;)J4Fn@`~k>8>v0M9xp90OJElWP&R5 zM#v*vtT}*Gm1^)Bv!s72T3PB0yVIjJW)H7a)ilkAvoaH?)jjb`MP>2z{%Y?}83 zUIwBKn`-MSg)=?R)1Q0z3b>dHE^)D8LFs}6ASG1|daDly_^lOSy&zIIhm*HXm1?VS=_iacG);_I9c zUQH1>i#*?oPIwBMJkzi_*>HoUe}_4o>2(SHWzqQ=;TyhAHS;Enr7!#8;sdlty&(>d zl%5cjri8`2X^Ds`jnw7>A`X|bl=U8n+3LKLy(1dAu8`g@9=5iw$R0qk)w8Vh_Dt^U zIglK}sn^)W7aB(Q>HvrX=rxB z+*L)3DiqpQ_%~|m=44LcD4-bxO3OO*LPjsh%p(k?&jvLp0py57oMH|*IMa(<|{m1(0S|x)?R-mqJ=I;_YUZA>J z62v*eSK;5w!h8J+6Z2~oyGdZ68waWfy09?4fU&m7%u~zi?YPHPgK6LDwphgaYu%0j zurtw)AYOpYKgHBrkX189mlJ`q)w-f|6>IER{5Lk97%P~a-JyCRFjejW@L>n4vt6#hq;!|m;hNE||LK3nw1{bJOy+eBJjK=QqNjI;Q6;Rp5 z&035pZDUZ#%Oa;&_7x0T<7!RW`#YBOj}F380Bq?MjjEhrvlCATPdkCTTl+2efTX$k zH&0zR1n^`C3ef~^sXzJK-)52(T}uTG%OF8yDhT76L~|^+hZ2hiSM*QA9*D5odI1>& z9kV9jC~twA5MwyOx(lsGD_ggYmztXPD`2=_V|ks_FOx!_J8!zM zTzh^cc+=VNZ&(OdN=y4Juw)@8-85lwf_#VMN!Ed(eQiRiLB2^2e`4dp286h@v@`O%_b)Y~A; zv}r6U?zs&@uD_+(_4bwoy7*uozNvp?bXFoB8?l8yG0qsm1JYzIvB_OH4_2G*IIOwT zVl%HX1562vLVcxM_RG*~w_`FbIc!(T=3>r528#%mwwMK}uEhJ()3MEby zQQjzqjWkwfI~;Fuj(Lj=Ug0y`>~C7`w&wzjK(rPw+Hpd~EvQ-ufQOiB4OMpyUKJhw zqEt~jle9d7S~LI~$6Z->J~QJ{Vdn3!c}g9}*KG^Kzr^(7VI5Gk(mHLL{itj_hG?&K4Ws0+T4gLfi3eu$N=`s36geNC?c zm!~}vG6lx9Uf^5M;bWntF<-{p^bruy~f?sk9 zcETAPQZLoJ8JzMMg<-=ju4keY@SY%Wo?u9Gx=j&dfa6LIAB|IrbORLV1-H==Z1zCM zeZcOYpm5>U2fU7V*h;%n`8 zN95QhfD994={1*<2vKLCNF)feKOGk`R#K~G=;rfq}|)s20&MCa65 zUM?xF5!&e0lF%|U!#rD@I{~OsS_?=;s_MQ_b_s=PuWdC)q|UQ&ea)DMRh5>fpQjXe z%9#*x=7{iRCtBKT#H>#v%>77|{4_slZ)XCY{s3j_r{tdpvb#|r|sbS^dU1x70$eJMU!h{Y7Kd{dl}9&vxQl6Jt1a` zHQZrWyY0?!vqf@u-fxU_@+}u(%Wm>0I#KP48tiAPYY!TdW(o|KtVI|EUB9V`CBBNaBLVih7+yMVF|GSoIQD0Jfb{ z!OXq;(>Z?O`1gap(L~bUcp>Lc@Jl-})^=6P%<~~9ywY=$iu8pJ0m*hOPzr~q`23eX zgbs;VOxxENe0UMVeN*>uCn9Gk!4siN-e>x)pIKAbQz!G)TcqIJ0`JBBaX>1-4_XO_-HCS^vr2vjv#7KltDZdyQ{tlWh4$Gm zB>|O1cBDC)yG(sbnc*@w6e%e}r*|IhpXckx&;sQCwGdKH+3oSG-2)Bf#x`@<4ETAr z0My%7RFh6ZLiZ_;X6Mu1YmXx7C$lSZ^}1h;j`EZd6@%JNUe=btBE z%s=Xmo1Ps?8G`}9+6>iaB8bgjUdXT?=trMu|4yLX^m0Dg{m7rpKNJey|EwHI+nN1e zL^>qN%5Fg)dGs4DO~uwIdXImN)QJ*Jhpj7$fq_^`{3fwpztL@WBB}OwQ#Epo-mqMO zsM$UgpFiG&d#)lzEQ{3Q;)&zTw;SzGOah-Dpm{!q7<8*)Ti_;xvV2TYXa}=faXZy? z3y?~GY@kl)>G&EvEijk9y1S`*=zBJSB1iet>0;x1Ai)*`^{pj0JMs)KAM=@UyOGtO z3y0BouW$N&TnwU6!%zS%nIrnANvZF&vB1~P5_d`x-giHuG zPJ;>XkVoghm#kZXRf>qxxEix;2;D1CC~NrbO6NBX!`&_$iXwP~P*c($EVV|669kDO zKoTLZNF4Cskh!Jz5ga9uZ`3o%7Pv`d^;a=cXI|>y;zC3rYPFLQkF*nv(r>SQvD*## z(Vo%^9g`%XwS0t#94zPq;mYGLKu4LU3;txF26?V~A0xZbU4Lmy`)>SoQX^m7fd^*E z+%{R4eN!rIk~K)M&UEzxp9dbY;_I^c} zOc{wlIrN_P(PPqi51k_$>Lt|X6A^|CGYgKAmoI#Li?;Wq%q~q*L7ehZkUrMxW67Jl zhsb~+U?33QS>eqyN{(odAkbopo=Q$Az?L+NZW>j;#~@wCDX?=L5SI|OxI~7!Pli;e zELMFcZtJY3!|=Gr2L4>z8yQ-{To>(f80*#;6`4IAiqUw`=Pg$%C?#1 z_g@hIGerILSU>=P>z{gM|DS91A4cT@PEIB^hSop!uhMo#2G;+tQSpDO_6nOnPWSLU zS;a9m^DFMXR4?*X=}d7l;nXuHk&0|m`NQn%d?8|Ab3A9l9Jh5s120ibWBdB z$5YwsK3;wvp!Kn@)Qae{ef`0#NwlRpQ}k^r>yos_Ne1;xyKLO?4)t_G4eK~wkUS2A&@_;)K0-03XGBzU+5f+uMDxC z(s8!8!RvdC#@`~fx$r)TKdLD6fWEVdEYtV#{ncT-ZMX~eI#UeQ-+H(Z43vVn%Yj9X zLdu9>o%wnWdvzA-#d6Z~vzj-}V3FQ5;axDIZ;i(95IIU=GQ4WuU{tl-{gk!5{l4_d zvvb&uE{%!iFwpymz{wh?bKr1*qzeZb5f6e6m_ozRF&zux2mlK=v_(_s^R6b5lu?_W4W3#<$zeG~Pd)^!4tzhs}-Sx$FJP>)ZGF(hVTH|C3(U zs0PO&*h_ zNA-&qZpTP$$LtIgfiCn07}XDbK#HIXdmv8zdz4TY;ifNIH-0jy(gMSByG2EF~Th#eb_TueZC` zE?3I>UTMpKQ})=C;6p!?G)M6w^u*A57bD?2X`m3X^6;&4%i_m(uGJ3Z5h`nwxM<)H z$I5m?wN>O~8`BGnZ=y^p6;0+%_0K}Dcg|K;+fEi|qoBqvHj(M&aHGqNF48~XqhtU? z^ogwBzRlOfpAJ+Rw7IED8lRbTdBdyEK$gPUpUG}j-M42xDj_&qEAQEtbs>D#dRd7Y z<&TpSZ(quQDHiCFn&0xsrz~4`4tz!CdL8m~HxZM_agu@IrBpyeL1Ft}V$HX_ZqDPm z-f89)pjuEzGdq-PRu`b1m+qBGY{zr_>{6Ss>F|xHZlJj9dt5HD$u`1*WZe)qEIuDSR)%z+|n zatVlhQ?$w#XRS7xUrFE;Y8vMGhQS5*T{ZnY=q1P?w5g$OKJ#M&e??tAmPWHMj3xhS ziGxapy?kn@$~2%ZY;M8Bc@%$pkl%Rvj!?o%agBvpQ-Q61n9kznC4ttrRNQ4%GFR5u zyv%Yo9~yxQJWJSfj z?#HY$y=O~F|2pZs22pu|_&Ajd+D(Mt!nPUG{|1nlvP`=R#kKH zO*s$r_%ss5h1YO7k0bHJ2CXN)Yd6CHn~W!R=SqkWe=&nAZu(Q1G!xgcUilM@YVei@2@a`8he z9@pM`)VB*=e7-MWgLlXlc)t;fF&-AwM{E-EX}pViFn0I0CNw2bNEnN2dj!^4(^zS3 zobUm1uQnpqk_4q{pl*n06=TfK_C>UgurKFjRXsK_LEn};=79`TB12tv6KzwSu*-C8 z;=~ohDLZylHQ|Mpx-?yql>|e=vI1Z!epyUpAcDCp4T|*RV&X`Q$0ogNwy6mFALo^@ z9=&(9txO8V@E!@6^(W0{*~CT>+-MA~vnJULBxCTUW>X5>r7*eXYUT0B6+w@lzw%n> z_VjJ<2qf|(d6jYq2(x$(ZDf!yVkfnbvNmb5c|hhZ^2TV_LBz`9w!e_V*W_(MiA7|= z&EeIIkw*+$Xd!)j8<@_<}A5;~A_>3JT*kX^@}cDoLd>Qj<`Se^wdUa(j0dp+Tl8EptwBm{9OGsdFEq zM`!pjf(Lm(`$e3FLOjqA5LnN5o!}z{ zNf}rJuZh@yUtq&ErjHeGzX4(!luV!jB&;FAP|!R_QHYw#^Z1LwTePAKJ6X&IDNO#; z)#I@Xnnzyij~C@UH~X51JCgQeF0&hTXnuoElz#m{heZRexWc0k4<>0+ClX7%0 zEBqCCld1tD9Zwkr4{?Nor19#E5-YKfB8d?qgR82-Ow2^AuNevly2*tHA|sK!ybYkX zm-sLQH72P&{vEAW6+z~O5d0qd=xW~rua~5a?ymYFSD@8&gV)E5@RNNBAj^C99+Z5Z zR@Pq55mbCQbz+Mn$d_CMW<-+?TU960agEk1J<>d>0K=pF19yN))a~4>m^G&tc*xR+yMD*S=yip-q=H zIlredHpsJV8H(32@Zxc@bX6a21dUV95Th--8pE6C&3F>pk=yv$yd6@Haw;$v4+Fcb zRwn{Qo@0`7aPa2LQOP}j9v>sjOo5Kqvn|`FLizX zB+@-u4Lw|jsvz{p^>n8Vo8H2peIqJJnMN}A)q6%$Tmig7eu^}K2 zrh$X?T|ZMsoh{6pdw1G$_T<`Ds-G=jc;qcGdK4{?dN2-XxjDNbb(7pk|3JUVCU4y; z)?LXR>f+AAu)JEiti_Zy#z5{RgsC}R(@jl%9YZ>zu~hKQ*AxbvhC378-I@{~#%Y`Z zy=a=9YpewPIC+gkEUUwtUL7|RU7=!^Aa}Mk^6uxOgRGA#JXjWLsjFUnix|Mau{hDT z7mn*z1m5g`vP(#tjT0Zy4eAY(br&!RiiXE=ZI!{sE1#^#%x^Z7t1U)b<;%Y}Q9=5v z;wpDCEZ@OE36TWT=|gxigT@VaW9BvHS05;_P(#s z8zI4XFQys}q)<`tkX$WnSarn{3e!s}4(J!=Yf>+Y>cP3f;vr63f2{|S^`_pWc)^5_!R z*(x-fuBxL51@xe!lnDBKi}Br$c$BMZ3%f2Sa6kLabiBS{pq*yj;q|k(86x`PiC{p6 z_bxCW{>Q2BA8~Ggz&0jkrcU+-$ANBsOop*ms>34K9lNYil@}jC;?cYP(m^P}nR6FV zk(M%48Z&%2Rx$A&FhOEirEhY0(dn;-k(qkTU)sFQ`+-ih+s@A8g?r8Pw+}2;35WYf zi}VO`jS`p(tc)$X$a>-#WXoW!phhatC*$}|rk>|wUU71eUJG^$c6_jwX?iSHM@6__ zvV|6%U*$sSXJu9SX?2%M^kK|}a2QJ8AhF{fuXrHZxXsI~O zGKX45!K7p*MCPEQ=gp?eu&#AW*pR{lhQR##P_*{c_DjMGL|3T3-bSJ(o$|M{ytU}> zAV>wq*uE*qFo9KvnA^@juy{x<-u*#2NvkV={Ly}ysKYB-k`K3@K#^S1Bb$8Y#0L0# z`6IkSG&|Z$ODy|VLS+y5pFJx&8tvPmMd8c9FhCyiU8~k6FwkakUd^(_ml8`rnl>JS zZV){9G*)xBqPz^LDqRwyS6w86#D^~xP4($150M)SOZRe9sn=>V#aG0Iy(_^YcPpIz8QYM-#s+n% z@Jd?xQq?Xk6=<3xSY7XYP$$yd&Spu{A#uafiIfy8gRC`o0nk{ezEDjb=q_qRAlR1d zFq^*9Gn)yTG4b}R{!+3hWQ+u3GT~8nwl2S1lpw`s0X_qpxv)g+JIkVKl${sYf_nV~B>Em>M;RlqGb5WVil(89 zs=ld@|#;dq1*vQGz=7--Br-|l) zZ%Xh@v8>B7P?~}?Cg$q9_={59l%m~O&*a6TKsCMAzG&vD>k2WDzJ6!tc!V)+oxF;h zJH;apM=wO?r_+*#;ulohuP=E>^zon}a$NnlcQ{1$SO*i=jnGVcQa^>QOILc)e6;eNTI>os=eaJ{*^DE+~jc zS}TYeOykDmJ=6O%>m`i*>&pO_S;qMySJIyP=}4E&J%#1zju$RpVAkZbEl+p%?ZP^C z*$$2b4t%a(e+%>a>d_f_<JjxI#J1x;=hPd1zFPx=6T$;;X1TD*2(edZ3f46zaAoW>L53vS_J*N8TMB|n+;LD| zC=GkQPpyDY#Am4l49chDv*gojhRj_?63&&8#doW`INATAo(qY#{q}%nf@eTIXmtU< zdB<7YWfyCmBs|c)cK>1)v&M#!yNj#4d$~pVfDWQc_ke1?fw{T1Nce_b`v|Vp5ig(H zJvRD^+ps46^hLX;=e2!2e;w9y1D@!D$c@Jc&%%%IL=+xzw55&2?darw=9g~>P z9>?Kdc$r?6c$m%x2S$sdpPl>GQZ{rC9mPS63*qjCVa?OIBj!fW zm|g?>CVfGXNjOfcyqImXR_(tXS(F{FcoNzKvG5R$IgGaxC@)i(e+$ME}vPVIhd|mx2IIE+f zM?9opQHIVgBWu)^A|RzXw!^??S!x)SZOwZaJkGjc<_}2l^eSBm!eAJG9T>EC6I_sy z?bxzDIAn&K5*mX)$RQzDA?s)-no-XF(g*yl4%+GBf`##bDXJ==AQk*xmnatI;SsLp zP9XTHq5mmS=iWu~9ES>b%Q=1aMa|ya^vj$@qz9S!ih{T8_PD%Sf_QrNKwgrXw9ldm zHRVR98*{C?_XNpJn{abA!oix_mowRMu^2lV-LPi;0+?-F(>^5#OHX-fPED zCu^l7u3E%STI}c4{J2!)9SUlGP_@!d?5W^QJXOI-Ea`hFMKjR7TluLvzC-ozCPn1`Tpy z!vlv@_Z58ILX6>nDjTp-1LlFMx~-%GA`aJvG$?8*Ihn;mH37eK**rmOEwqegf-Ccx zrIX4;{c~RK>XuTXxYo5kMiWMy)!IC{*DHG@E$hx?RwP@+wuad(P1{@%tRkyJRqD)3 zMHHHZ4boqDn>-=DgR5VlhQTpfVy182Gk;A_S8A1-;U1RR>+$62>(MUx@Nox$vTjHq z%QR=j!6Gdyb5wu7y(YUktwMuW5<@jl?m4cv4BODiT5o8qVdC0MBqGr@-YBIwnpZAY znX9(_uQjP}JJ=!~Ve9#5I~rUnN|P_3D$LqZcvBnywYhjlMSFHm`;u9GPla{5QD7(7*6Tb3Svr8;(nuAd81q$*uq6HC_&~je*Ca7hP4sJp0av{M8480wF zxASi7Qv+~@2U%Nu1Ud;s-G4CTVWIPyx!sg&8ZG0Wq zG_}i3C(6_1>q3w!EH7$Kwq8uBp2F2N7}l65mk1p*9v0&+;th=_E-W)E;w}P(j⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 diff --git a/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 diff --git a/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties index 774fae8767..878fe049c2 100644 --- a/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradle-modules/gradle/gradle/shipkit.gradle b/gradle-modules/gradle/gradle/shipkit.gradle deleted file mode 100644 index 144c01dc05..0000000000 --- a/gradle-modules/gradle/gradle/shipkit.gradle +++ /dev/null @@ -1,41 +0,0 @@ -//This default Shipkit configuration file was created automatically and is intended to be checked-in. -//Default configuration is sufficient for local testing and trying out Shipkit. -//To leverage Shipkit fully, please fix the TODO items, refer to our Getting Started Guide for help: -// -// https://github.com/mockito/shipkit/blob/master/docs/getting-started.md -// -shipkit { - //TODO is the repository correct? - gitHub.repository = "unspecified-user/unspecified-repo" - - //TODO generate and use your own read-only GitHub personal access token - gitHub.readOnlyAuthToken = "76826c9ec886612f504d12fd4268b16721c4f85d" - - //TODO generate GitHub write token, and ensure your Travis CI has this env variable exported - gitHub.writeAuthToken = System.getenv("GH_WRITE_TOKEN") -} - -allprojects { - plugins.withId("com.jfrog.bintray") { - - //Bintray configuration is handled by JFrog Bintray Gradle Plugin - //For reference see the official documentation: https://github.com/bintray/gradle-bintray-plugin - bintray { - - //TODO sign up for free open source account with https://bintray.com, then look up your API key on your profile page in Bintray - key = '7ea297848ca948adb7d3ee92a83292112d7ae989' - //TODO don't check in the key, remove above line and use env variable exported on CI: - //key = System.getenv("BINTRAY_API_KEY") - - pkg { - //TODO configure Bintray settings per your project (https://github.com/bintray/gradle-bintray-plugin) - repo = 'bootstrap' - user = 'shipkit-bootstrap-bot' - userOrg = 'shipkit-bootstrap' - name = 'maven' - licenses = ['MIT'] - labels = ['continuous delivery', 'release automation', 'shipkit'] - } - } - } -} diff --git a/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.jar b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..7f93135c49b765f8051ef9d0a6055ff8e46073d8 GIT binary patch literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc literal 0 HcmV?d00001 diff --git a/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties index ebf7ae9184..3fa8f862f7 100644 --- a/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties +++ b/gradle-modules/gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Thu Oct 12 16:43:02 BDT 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip From a4c6e7fd546d6ecdc3b859561c91f9d840cee81e Mon Sep 17 00:00:00 2001 From: timis1 Date: Sun, 19 Nov 2023 20:43:50 +0200 Subject: [PATCH 53/71] JAVA-26721 Upgrade okhttp to latest version --- apache-libraries/pom.xml | 2 +- java-spi/exchange-rate-impl/pom.xml | 2 +- libraries-http-2/pom.xml | 2 +- libraries-http/pom.xml | 2 +- osgi/pom.xml | 2 +- spring-reactive-modules/spring-reactive-client/pom.xml | 2 +- spring-web-modules/spring-rest-simple/pom.xml | 2 +- spring-web-modules/spring-resttemplate/pom.xml | 2 +- web-modules/jooby/pom.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apache-libraries/pom.xml b/apache-libraries/pom.xml index c1def03bee..02e9f08a8d 100644 --- a/apache-libraries/pom.xml +++ b/apache-libraries/pom.xml @@ -191,7 +191,7 @@ 2.0.6 2.0.1.Final 1.2.15 - 3.10.0 + 4.12.0 1.2.15 1.2.15 1.2.15 diff --git a/java-spi/exchange-rate-impl/pom.xml b/java-spi/exchange-rate-impl/pom.xml index 254a8bb809..7ec10b1c04 100644 --- a/java-spi/exchange-rate-impl/pom.xml +++ b/java-spi/exchange-rate-impl/pom.xml @@ -65,7 +65,7 @@ 1.0.0-SNAPSHOT - 3.10.0 + 4.12.0 1.0 1.0.1 1.1.2 diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml index c80c5729a7..b49e4b9387 100644 --- a/libraries-http-2/pom.xml +++ b/libraries-http-2/pom.xml @@ -109,7 +109,7 @@ - 4.9.1 + 4.12.0 2.10.1 4.9.1 1.0.3 diff --git a/libraries-http/pom.xml b/libraries-http/pom.xml index c726b56b5d..caf42639cc 100644 --- a/libraries-http/pom.xml +++ b/libraries-http/pom.xml @@ -105,7 +105,7 @@ 2.10.1 4.5.3 - 4.9.1 + 4.12.0 1.23.0 2.2.0 2.3.0 diff --git a/osgi/pom.xml b/osgi/pom.xml index ecc8758ef9..16b1f5d106 100644 --- a/osgi/pom.xml +++ b/osgi/pom.xml @@ -91,7 +91,7 @@ - 3.9.0 + 4.12.0 1.1 6.0.0 3.3.0 diff --git a/spring-reactive-modules/spring-reactive-client/pom.xml b/spring-reactive-modules/spring-reactive-client/pom.xml index 94134e5271..5736ce497f 100644 --- a/spring-reactive-modules/spring-reactive-client/pom.xml +++ b/spring-reactive-modules/spring-reactive-client/pom.xml @@ -179,7 +179,7 @@ 1.0.1.RELEASE 1.0 1.1.6 - 4.0.1 + 4.12.0 3.5.3 2.26.0 3.1.4 diff --git a/spring-web-modules/spring-rest-simple/pom.xml b/spring-web-modules/spring-rest-simple/pom.xml index 2764ac8393..089c5e411f 100644 --- a/spring-web-modules/spring-rest-simple/pom.xml +++ b/spring-web-modules/spring-rest-simple/pom.xml @@ -292,7 +292,7 @@ 1.6.0 3.0.4 - 3.4.1 + 4.12.0 2.2.0 diff --git a/spring-web-modules/spring-resttemplate/pom.xml b/spring-web-modules/spring-resttemplate/pom.xml index 4abaac5628..5cf1476f87 100644 --- a/spring-web-modules/spring-resttemplate/pom.xml +++ b/spring-web-modules/spring-resttemplate/pom.xml @@ -274,7 +274,7 @@ 1.6.1 3.0.4 - 3.4.1 + 4.12.0 3.6.3 1.8 1.8 diff --git a/web-modules/jooby/pom.xml b/web-modules/jooby/pom.xml index 238f17571f..998ceaef4e 100644 --- a/web-modules/jooby/pom.xml +++ b/web-modules/jooby/pom.xml @@ -77,7 +77,7 @@ com.baeldung.jooby.App 3.2.4 3.8.1 - 4.9.1 + 4.12.0 \ No newline at end of file From 3371e4fe5311c59f9797f0fd23c30b0d2872ce85 Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Sun, 19 Nov 2023 20:27:45 +0100 Subject: [PATCH 54/71] BAEL-6718: Setting a Spring Bean to Null (#15242) * BAEL-6718: Setting a Spring Bean to Null * BAEL-6718: Java Nullable Example --- .../baeldung/nullablebean/MainComponent.java | 21 ++++ .../baeldung/nullablebean/SubComponent.java | 8 ++ .../nonrequired/NonRequiredConfiguration.java | 8 ++ .../nonrequired/NonRequiredMainComponent.java | 19 ++++ .../nonrequired/NonRequiredSubComponent.java | 5 + .../NullableJavaConfiguration.java | 9 ++ .../nullablejava/NullableMainComponent.java | 22 +++++ .../nullablejava/NullableSubComponent.java | 5 + .../nullablespring/NullableConfiguration.java | 20 ++++ .../NullableSupplierConfiguration.java | 21 ++++ .../optionable/OptionableConfiguration.java | 17 ++++ .../NullableXMLComponentUnitTest.java | 95 +++++++++++++++++++ .../non-nullable-application-context.xml | 10 ++ ...-configurable-spel-application-context.xml | 14 +++ .../test/resources/non-nullable.properties | 1 + .../nullable-application-context.xml | 11 +++ ...-configurable-spel-application-context.xml | 14 +++ .../nullable-spel-application-context.xml | 9 ++ .../src/test/resources/nullable.properties | 1 + 19 files changed, 310 insertions(+) create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java create mode 100644 spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java create mode 100644 spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java create mode 100644 spring-di-4/src/test/resources/non-nullable-application-context.xml create mode 100644 spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml create mode 100644 spring-di-4/src/test/resources/non-nullable.properties create mode 100644 spring-di-4/src/test/resources/nullable-application-context.xml create mode 100644 spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml create mode 100644 spring-di-4/src/test/resources/nullable-spel-application-context.xml create mode 100644 spring-di-4/src/test/resources/nullable.properties diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java new file mode 100644 index 0000000000..9f97b108da --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/MainComponent.java @@ -0,0 +1,21 @@ +package com.baeldung.nullablebean; + +import org.springframework.stereotype.Component; + +@Component +public class MainComponent { + + private SubComponent subComponent; + + public MainComponent(final SubComponent subComponent) { + this.subComponent = subComponent; + } + + public SubComponent getSubComponent() { + return subComponent; + } + + public void setSubComponent(final SubComponent subComponent) { + this.subComponent = subComponent; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java new file mode 100644 index 0000000000..b171d28db4 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/SubComponent.java @@ -0,0 +1,8 @@ +package com.baeldung.nullablebean; + +import org.springframework.stereotype.Component; + +@Component +public class SubComponent { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java new file mode 100644 index 0000000000..d34479a565 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredConfiguration.java @@ -0,0 +1,8 @@ +package com.baeldung.nullablebean.nonrequired; + +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan +public class NonRequiredConfiguration { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java new file mode 100644 index 0000000000..f181d2068d --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredMainComponent.java @@ -0,0 +1,19 @@ +package com.baeldung.nullablebean.nonrequired; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class NonRequiredMainComponent { + + @Autowired(required = false) + private NonRequiredSubComponent subComponent; + + public NonRequiredSubComponent getSubComponent() { + return subComponent; + } + + public void setSubComponent(final NonRequiredSubComponent subComponent) { + this.subComponent = subComponent; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java new file mode 100644 index 0000000000..6678880a24 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nonrequired/NonRequiredSubComponent.java @@ -0,0 +1,5 @@ +package com.baeldung.nullablebean.nonrequired; + +public class NonRequiredSubComponent { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java new file mode 100644 index 0000000000..c13dbe3363 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableJavaConfiguration.java @@ -0,0 +1,9 @@ +package com.baeldung.nullablebean.nullablejava; + +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ComponentScan +public class NullableJavaConfiguration { +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java new file mode 100644 index 0000000000..f35ead7477 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableMainComponent.java @@ -0,0 +1,22 @@ +package com.baeldung.nullablebean.nullablejava; + +import jakarta.annotation.Nullable; +import org.springframework.stereotype.Component; + +@Component +public class NullableMainComponent { + + private NullableSubComponent subComponent; + + public NullableMainComponent(final @Nullable NullableSubComponent subComponent) { + this.subComponent = subComponent; + } + + public NullableSubComponent getSubComponent() { + return subComponent; + } + + public void setSubComponent(final NullableSubComponent subComponent) { + this.subComponent = subComponent; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java new file mode 100644 index 0000000000..c3cbd78c43 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablejava/NullableSubComponent.java @@ -0,0 +1,5 @@ +package com.baeldung.nullablebean.nullablejava; + +public class NullableSubComponent { + +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java new file mode 100644 index 0000000000..17942d31cd --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableConfiguration.java @@ -0,0 +1,20 @@ +package com.baeldung.nullablebean.nullablespring; + +import com.baeldung.nullablebean.MainComponent; +import com.baeldung.nullablebean.SubComponent; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class NullableConfiguration { + + @Bean + public MainComponent mainComponent(SubComponent subComponent) { + return new MainComponent(subComponent); + } + + @Bean + public SubComponent subComponent() { + return null; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java new file mode 100644 index 0000000000..debaa60fa9 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/nullablespring/NullableSupplierConfiguration.java @@ -0,0 +1,21 @@ +package com.baeldung.nullablebean.nullablespring; + +import com.baeldung.nullablebean.MainComponent; +import com.baeldung.nullablebean.SubComponent; +import java.util.function.Supplier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class NullableSupplierConfiguration { + + @Bean + public MainComponent mainComponent(Supplier subComponentSupplier) { + return new MainComponent(subComponentSupplier.get()); + } + + @Bean + public Supplier subComponentSupplier() { + return () -> null; + } +} diff --git a/spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java b/spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java new file mode 100644 index 0000000000..fd54553e8c --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/nullablebean/optionable/OptionableConfiguration.java @@ -0,0 +1,17 @@ +package com.baeldung.nullablebean.optionable; + +import com.baeldung.nullablebean.MainComponent; +import com.baeldung.nullablebean.SubComponent; +import java.util.Optional; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OptionableConfiguration { + + @Bean + public MainComponent mainComponent(Optional optionalSubComponent) { + return new MainComponent(optionalSubComponent.orElse(null)); + } + +} diff --git a/spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java b/spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java new file mode 100644 index 0000000000..2997da478c --- /dev/null +++ b/spring-di-4/src/test/java/com/baeldung/nullablebean/NullableXMLComponentUnitTest.java @@ -0,0 +1,95 @@ +package com.baeldung.nullablebean; + +import static org.junit.jupiter.api.Assertions.*; + +import com.baeldung.nullablebean.nonrequired.NonRequiredConfiguration; +import com.baeldung.nullablebean.nonrequired.NonRequiredMainComponent; +import com.baeldung.nullablebean.nullablejava.NullableJavaConfiguration; +import com.baeldung.nullablebean.nullablejava.NullableMainComponent; +import com.baeldung.nullablebean.nullablespring.NullableConfiguration; +import com.baeldung.nullablebean.nullablespring.NullableSupplierConfiguration; +import com.baeldung.nullablebean.optionable.OptionableConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +class NullableXMLComponentUnitTest { + + @Test + void givenContextWhenCreatingNullableMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + NullableJavaConfiguration.class); + final NullableMainComponent bean = context.getBean(NullableMainComponent.class); + assertNull(bean.getSubComponent()); + } + @Test + void givenNonRequiredContextWhenCreatingMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + NonRequiredConfiguration.class); + final NonRequiredMainComponent bean = context.getBean(NonRequiredMainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenOptionableContextWhenCreatingMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + OptionableConfiguration.class); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSupplierContextWhenCreatingMainComponentThenSubComponentIsNull() { + final AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + NullableSupplierConfiguration.class); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableContextWhenCreatingMainComponentThenSubComponentIsNull() { + assertThrows(UnsatisfiedDependencyException.class, () -> new AnnotationConfigApplicationContext( + NullableConfiguration.class)); + } + + @Test + void givenNullableXMLContextWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "nullable-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSpELXMLContextWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "nullable-spel-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSpELXMLContextWithNullablePropertiesWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "nullable-configurable-spel-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNull(bean.getSubComponent()); + } + + @Test + void givenNullableSpELXMLContextWithNonNullablePropertiesWhenCreatingMainComponentThenSubComponentIsNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "non-nullable-configurable-spel-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNotNull(bean.getSubComponent()); + } + + @Test + void givenXMLContextWhenCreatingMainComponentThenSubComponentNotNull() { + final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "non-nullable-application-context.xml"); + final MainComponent bean = context.getBean(MainComponent.class); + assertNotNull(bean.getSubComponent()); + } +} \ No newline at end of file diff --git a/spring-di-4/src/test/resources/non-nullable-application-context.xml b/spring-di-4/src/test/resources/non-nullable-application-context.xml new file mode 100644 index 0000000000..07a8115bac --- /dev/null +++ b/spring-di-4/src/test/resources/non-nullable-application-context.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml b/spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml new file mode 100644 index 0000000000..8a7b107ee4 --- /dev/null +++ b/spring-di-4/src/test/resources/non-nullable-configurable-spel-application-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/non-nullable.properties b/spring-di-4/src/test/resources/non-nullable.properties new file mode 100644 index 0000000000..76b127a2e5 --- /dev/null +++ b/spring-di-4/src/test/resources/non-nullable.properties @@ -0,0 +1 @@ +nullableBean = subComponent \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable-application-context.xml b/spring-di-4/src/test/resources/nullable-application-context.xml new file mode 100644 index 0000000000..9794dbbfff --- /dev/null +++ b/spring-di-4/src/test/resources/nullable-application-context.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml b/spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml new file mode 100644 index 0000000000..f6f04a6289 --- /dev/null +++ b/spring-di-4/src/test/resources/nullable-configurable-spel-application-context.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable-spel-application-context.xml b/spring-di-4/src/test/resources/nullable-spel-application-context.xml new file mode 100644 index 0000000000..c0a14b4cbb --- /dev/null +++ b/spring-di-4/src/test/resources/nullable-spel-application-context.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/spring-di-4/src/test/resources/nullable.properties b/spring-di-4/src/test/resources/nullable.properties new file mode 100644 index 0000000000..315f9b0d03 --- /dev/null +++ b/spring-di-4/src/test/resources/nullable.properties @@ -0,0 +1 @@ +nullableBean = null \ No newline at end of file From 684a14ce5f29d574486e8846c12d88d7575b88af Mon Sep 17 00:00:00 2001 From: Bhaskar Ghosh Dastidar Date: Mon, 20 Nov 2023 01:06:51 +0530 Subject: [PATCH 55/71] [BAEL-6787] increment value of a map (#15243) Co-authored-by: Bhaskar --- .../core-java-collections-maps-7/pom.xml | 5 + .../com/baeldung/map/BenchmarkMapMethods.java | 70 ++++++++++++ .../baeldung/map/IncrementMapValueWays.java | 80 ++++++++++++++ .../map/IncrementMapValueUnitTest.java | 103 ++++++++++++++++++ 4 files changed, 258 insertions(+) create mode 100644 core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java create mode 100644 core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java create mode 100644 core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java diff --git a/core-java-modules/core-java-collections-maps-7/pom.xml b/core-java-modules/core-java-collections-maps-7/pom.xml index a7acded9cf..a05b1b3528 100644 --- a/core-java-modules/core-java-collections-maps-7/pom.xml +++ b/core-java-modules/core-java-collections-maps-7/pom.xml @@ -33,6 +33,11 @@ commons-csv ${csv.version} + + com.google.guava + guava + 32.1.2-jre + diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java new file mode 100644 index 0000000000..eca028efe4 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/BenchmarkMapMethods.java @@ -0,0 +1,70 @@ +package com.baeldung.map; + +import java.util.HashMap; +import java.util.Map; + +public class BenchmarkMapMethods { + public static void main(String[] args) { + BenchmarkMapMethods bmm = new BenchmarkMapMethods(); + Map map = new HashMap<>(); + map.put("Guava", bmm.benchMarkGuavaMap()); + map.put("ContainsKey", bmm.benchContainsKeyMap()); + map.put("MergeMethod", bmm.benchMarkMergeMethod()); + map.put("ComputeMethod", bmm.benchMarComputeMethod()); + map.put("GetOrDefault", bmm.benchMarkGetOrDefaultMethod()); + } + + private long benchMarkGuavaMap() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingAtomicMap(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchContainsKeyMap() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingContainsKey(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchMarComputeMethod() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingCompute(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchMarkMergeMethod() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingMerge(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private long benchMarkGetOrDefaultMethod() { + long startTime = System.nanoTime(); + IncrementMapValueWays im = new IncrementMapValueWays(); + im.charFrequencyUsingGetOrDefault(getString()); + long endTime = System.nanoTime(); + return endTime - startTime; + } + + private String getString() { + return + "Once upon a time in a quaint village nestled between rolling hills and whispering forests, there lived a solitary storyteller named Elias. Elias was known for spinning tales that transported listeners to magical realms and awakened forgotten dreams.\n" + + "\n" + + "His favorite spot was beneath an ancient oak tree, its sprawling branches offering shade to those who sought refuge from the bustle of daily life. Villagers of all ages would gather around Elias, their faces illuminated by the warmth of his stories.\n" + + "\n" + "One evening, as dusk painted the sky in hues of orange and purple, a curious young girl named Lily approached Elias. Her eyes sparkled with wonder as she asked for a tale unlike any other.\n" + "\n" + + "Elias smiled, sensing her thirst for adventure, and began a story about a forgotten kingdom veiled by mist, guarded by mystical creatures and enchanted by ancient spells. With each word, the air grew thick with anticipation, and the listeners were transported into a world where magic danced on the edges of reality.\n" + + "\n" + "As Elias weaved the story, Lily's imagination took flight. She envisioned herself as a brave warrior, wielding a shimmering sword against dark forces, her heart fueled by courage and kindness.\n" + "\n" + + "The night wore on, but the spell of the tale held everyone captive. The villagers laughed, gasped, and held their breaths, journeying alongside the characters through trials and triumphs.\n" + "\n" + + "As the final words lingered in the air, a sense of enchantment settled upon the listeners. They thanked Elias for the gift of his storytelling, each carrying a piece of the magical kingdom within their hearts.\n" + "\n" + + "Lily, inspired by the story, vowed to cherish the spirit of adventure and kindness in her own life. With a newfound spark in her eyes, she bid Elias goodnight, already dreaming of the countless adventures awaiting her.\n" + "\n" + + "Under the star-studded sky, Elias remained beneath the ancient oak, his heart aglow with the joy of sharing tales that ignited imagination and inspired dreams. And as the night embraced the village, whispers of the enchanted kingdom lingered in the breeze, promising endless possibilities to those who dared to believe."; + } +} diff --git a/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java new file mode 100644 index 0000000000..70b3c6c54d --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/main/java/com/baeldung/map/IncrementMapValueWays.java @@ -0,0 +1,80 @@ +package com.baeldung.map; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + +import com.google.common.util.concurrent.AtomicLongMap; + +public class IncrementMapValueWays { + + public Map charFrequencyUsingContainsKey(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + int count = 0; + if (charMap.containsKey(sentence.charAt(c))) { + count = charMap.get(sentence.charAt(c)); + } + charMap.put(sentence.charAt(c), count + 1); + } + return charMap; + } + + public Map charFrequencyUsingGetOrDefault(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.put(sentence.charAt(c), charMap.getOrDefault(sentence.charAt(c), 0) + 1); + } + return charMap; + } + + public Map charFrequencyUsingMerge(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.merge(sentence.charAt(c), 1, Integer::sum); + } + return charMap; + } + + public Map charFrequencyUsingCompute(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.compute(sentence.charAt(c), (key, value) -> (value == null) ? 1 : value + 1); + } + return charMap; + } + + public Map charFrequencyUsingAtomicMap(String sentence) { + AtomicLongMap map = AtomicLongMap.create(); + for (int c = 0; c < sentence.length(); c++) { + map.getAndIncrement(sentence.charAt(c)); + } + return map.asMap(); + } + + public Map charFrequencyWithConcurrentMap(String sentence, Map charMap) { + for (int c = 0; c < sentence.length(); c++) { + charMap.compute(sentence.charAt(c), (key, value) -> (value == null) ? 1 : value + 1); + } + return charMap; + } + + public Map charFrequencyWithGetAndIncrement(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.putIfAbsent(sentence.charAt(c), new AtomicInteger(0)); + charMap.get(sentence.charAt(c)) + .incrementAndGet(); + } + return charMap; + } + + public Map charFrequencyWithGetAndIncrementComputeIfAbsent(String sentence) { + Map charMap = new HashMap<>(); + for (int c = 0; c < sentence.length(); c++) { + charMap.computeIfAbsent(sentence.charAt(c), k -> new AtomicInteger(0)) + .incrementAndGet(); + } + return charMap; + } +} diff --git a/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java new file mode 100644 index 0000000000..df4f2b787e --- /dev/null +++ b/core-java-modules/core-java-collections-maps-7/src/test/java/com/baeldung/map/IncrementMapValueUnitTest.java @@ -0,0 +1,103 @@ +package com.baeldung.map; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Assert; +import org.junit.Test; + +public class IncrementMapValueUnitTest { + + @Test + public void givenString_whenUsingContainsKey_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingContainsKey(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingGetOrDefault_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingGetOrDefault(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingMapMerge_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingMerge(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingMapCompute_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingCompute(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, actualMap); + } + + @Test + public void givenString_whenUsingGuava_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyUsingAtomicMap(string); + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap.keySet(), actualMap.keySet()); + } + + @Test + public void givenString_whenUsingIncrementAndGet_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyWithGetAndIncrement(string); + Assert.assertEquals(getExpectedMap().keySet(), actualMap.keySet()); + } + + @Test + public void givenString_whenUsingIncrementAndGetAndComputeIfAbsent_thenReturnFreqMap() { + String string = "the quick brown fox jumps over the lazy dog"; + IncrementMapValueWays ic = new IncrementMapValueWays(); + Map actualMap = ic.charFrequencyWithGetAndIncrementComputeIfAbsent(string); + Assert.assertEquals(getExpectedMap().keySet(), actualMap.keySet()); + } + + @Test + public void givenString_whenUsingConcurrentMapCompute_thenReturnFreqMap() throws InterruptedException { + Map charMap = new ConcurrentHashMap<>(); + Thread thread1 = new Thread(() -> { + IncrementMapValueWays ic = new IncrementMapValueWays(); + ic.charFrequencyWithConcurrentMap("the quick brown", charMap); + }); + + Thread thread2 = new Thread(() -> { + IncrementMapValueWays ic = new IncrementMapValueWays(); + ic.charFrequencyWithConcurrentMap(" fox jumps over the lazy dog", charMap); + }); + + thread1.start(); + thread2.start(); + thread1.join(); + thread2.join(); + + Map expectedMap = getExpectedMap(); + Assert.assertEquals(expectedMap, charMap); + } + + private Map getExpectedMap() { + return Stream.of( + new Object[][] { { ' ', 8 }, { 'a', 1 }, { 'b', 1 }, { 'c', 1 }, { 'd', 1 }, { 'e', 3 }, { 'f', 1 }, { 'g', 1 }, { 'h', 2 }, { 'i', 1 }, { 'j', 1 }, { 'k', 1 }, { 'l', 1 }, { 'm', 1 }, { 'n', 1 }, { 'o', 4 }, { 'p', 1 }, { 'q', 1 }, { 'r', 2 }, + { 's', 1 }, { 't', 2 }, { 'u', 2 }, { 'v', 1 }, { 'w', 1 }, { 'x', 1 }, { 'y', 1 }, { 'z', 1 } }) + .collect(Collectors.toMap(data -> (Character) data[0], data -> (Integer) data[1])); + } +} From a7ab16d81e505a46c56ca25fa60c89a72893416d Mon Sep 17 00:00:00 2001 From: Pedro Lopes Date: Mon, 20 Nov 2023 03:14:46 -0300 Subject: [PATCH 56/71] BAEL-6566: Manage Kafka Consumer Groups (#15007) * test removing consumer * test removing consumer * wrapping up * fix main class * addressing request changes * introducing constants for numbers. optimizing imports * introducing class level constants * using constant naming conventions --- .../KafkaConsumerConfiguration.java | 37 ++++++++++++ .../KafkaProducerConfiguration.java | 35 ++++++++++++ .../KafkaTopicConfiguration.java | 30 ++++++++++ ...gingConsumerGroupsApplicationKafkaApp.java | 13 +++++ .../MessageConsumerService.java | 34 +++++++++++ ...ManagingConsumerGroupsIntegrationTest.java | 57 +++++++++++++++++++ 6 files changed, 206 insertions(+) create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java create mode 100644 spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java create mode 100644 spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java new file mode 100644 index 0000000000..04025bf484 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaConsumerConfiguration.java @@ -0,0 +1,37 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.common.serialization.DoubleDeserializer; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class KafkaConsumerConfiguration { + + @Value(value = "${spring.kafka.bootstrap-servers}") + private String bootstrapAddress; + + @Bean + public ConsumerFactory kafkaConsumer() { + Map props = new HashMap<>(); + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, DoubleDeserializer.class); + return new DefaultKafkaConsumerFactory<>(props); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory kafkaConsumerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(kafkaConsumer()); + return factory; + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java new file mode 100644 index 0000000000..b5b10e8301 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaProducerConfiguration.java @@ -0,0 +1,35 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.DoubleSerializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class KafkaProducerConfiguration { + + @Value(value = "${spring.kafka.bootstrap-servers}") + private String bootstrapAddress; + + @Bean + public ProducerFactory kafkaProducer() { + Map configProps = new HashMap<>(); + configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, DoubleSerializer.class); + return new DefaultKafkaProducerFactory<>(configProps); + } + + @Bean + public KafkaTemplate kafkaProducerTemplate() { + return new KafkaTemplate<>(kafkaProducer()); + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java new file mode 100644 index 0000000000..1535f0c358 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/KafkaTopicConfiguration.java @@ -0,0 +1,30 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.admin.AdminClientConfig; +import org.apache.kafka.clients.admin.NewTopic; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.TopicBuilder; +import org.springframework.kafka.core.KafkaAdmin; + +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class KafkaTopicConfiguration { + + @Value(value = "${spring.kafka.bootstrap-servers}") + private String bootstrapAddress; + + public KafkaAdmin kafkaAdmin() { + Map configs = new HashMap<>(); + configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress); + return new KafkaAdmin(configs); + } + + public NewTopic celciusTopic() { + return TopicBuilder.name("topic-1") + .partitions(2) + .build(); + } +} diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java new file mode 100644 index 0000000000..c5c990ff9d --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsApplicationKafkaApp.java @@ -0,0 +1,13 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Import; + +@SpringBootApplication +@Import(value = {KafkaConsumerConfiguration.class, KafkaProducerConfiguration.class, KafkaTopicConfiguration.class}) +public class ManagingConsumerGroupsApplicationKafkaApp { + public static void main(String[] args) { + SpringApplication.run(ManagingConsumerGroupsApplicationKafkaApp.class, args); + } +} \ No newline at end of file diff --git a/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java new file mode 100644 index 0000000000..d010b19a80 --- /dev/null +++ b/spring-kafka-2/src/main/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/MessageConsumerService.java @@ -0,0 +1,34 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Service; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +@Service +public class MessageConsumerService { + + Map> consumedPartitions = new ConcurrentHashMap<>(); + + @KafkaListener(topics = "topic-1", groupId = "group-1") + public void consumer0(ConsumerRecord consumerRecord) { + trackConsumedPartitions("consumer-0", consumerRecord); + } + + @KafkaListener(topics = "topic-1", groupId = "group-1") + public void consumer1(ConsumerRecord consumerRecord) { + trackConsumedPartitions("consumer-1", consumerRecord); + } + + private void trackConsumedPartitions(String key, ConsumerRecord record) { + consumedPartitions.computeIfAbsent(key, k -> new HashSet<>()); + consumedPartitions.computeIfPresent(key, (k, v) -> { + v.add(record.partition()); + return v; + }); + } +} diff --git a/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java new file mode 100644 index 0000000000..1620add9ca --- /dev/null +++ b/spring-kafka-2/src/test/java/com/baeldung/spring/kafka/managingkafkaconsumergroups/ManagingConsumerGroupsIntegrationTest.java @@ -0,0 +1,57 @@ +package com.baeldung.spring.kafka.managingkafkaconsumergroups; + +import org.apache.commons.lang3.RandomUtils; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.config.KafkaListenerEndpointRegistry; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.listener.MessageListenerContainer; +import org.springframework.kafka.test.context.EmbeddedKafka; + +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest(classes = ManagingConsumerGroupsApplicationKafkaApp.class) +@EmbeddedKafka(partitions = 2, brokerProperties = {"listeners=PLAINTEXT://localhost:9092", "port=9092"}) +public class ManagingConsumerGroupsIntegrationTest { + + private static final String CONSUMER_1_IDENTIFIER = "org.springframework.kafka.KafkaListenerEndpointContainer#1"; + private static final int TOTAL_PRODUCED_MESSAGES = 50000; + private static final int MESSAGE_WHERE_CONSUMER_1_LEAVES_GROUP = 10000; + + @Autowired + KafkaTemplate kafkaTemplate; + + @Autowired + KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry; + + @Autowired + MessageConsumerService consumerService; + + @Test + public void givenContinuousMessageFlow_whenAConsumerLeavesTheGroup_thenKafkaTriggersPartitionRebalance() throws InterruptedException { + int currentMessage = 0; + + do { + kafkaTemplate.send("topic-1", RandomUtils.nextDouble(10.0, 20.0)); + currentMessage++; + + if (currentMessage == MESSAGE_WHERE_CONSUMER_1_LEAVES_GROUP) { + String containerId = kafkaListenerEndpointRegistry.getListenerContainerIds() + .stream() + .filter(a -> a.equals(CONSUMER_1_IDENTIFIER)) + .findFirst() + .orElse(""); + MessageListenerContainer container = kafkaListenerEndpointRegistry.getListenerContainer(containerId); + Thread.sleep(2000); + Objects.requireNonNull(container).stop(); + kafkaListenerEndpointRegistry.unregisterListenerContainer(containerId); + } + } while (currentMessage != TOTAL_PRODUCED_MESSAGES); + Thread.sleep(2000); + assertEquals(1, consumerService.consumedPartitions.get("consumer-1").size()); + assertEquals(2, consumerService.consumedPartitions.get("consumer-0").size()); + } +} From 40315beb0df5754add38e8afaf8596ba8f620811 Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:44:00 +0200 Subject: [PATCH 57/71] JAVA-26733 Upgrade wiremock to the latest version (#15206) --- apache-httpclient/pom.xml | 10 ++++++++-- .../com/baeldung/httpclient/GetRequestMockServer.java | 2 +- .../baeldung/httpclient/HttpAsyncClientLiveTest.java | 6 ++---- .../java/com/baeldung/httpclient/ResponseUtil.java | 6 +++--- ...HttpClientAdvancedConfigurationIntegrationTest.java | 4 ++-- apache-httpclient4/pom.xml | 4 ++-- ...HttpClientAdvancedConfigurationIntegrationTest.java | 4 ++-- core-java-modules/core-java-httpclient/pom.xml | 4 ++-- core-java-modules/core-java-io-2/pom.xml | 5 ++--- httpclient-simple/pom.xml | 4 ++-- spring-jersey/pom.xml | 4 ++-- testing-modules/rest-testing/pom.xml | 4 ++-- 12 files changed, 30 insertions(+), 27 deletions(-) diff --git a/apache-httpclient/pom.xml b/apache-httpclient/pom.xml index 1b22d64799..3b178d4df8 100644 --- a/apache-httpclient/pom.xml +++ b/apache-httpclient/pom.xml @@ -58,11 +58,16 @@ - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test + + org.apache.httpcomponents + httpclient + ${httpclient.version} + @@ -77,11 +82,12 @@ 5.6.1 - 2.5.1 + 3.3.1 5.2 5.2 5.2 + 4.5.14 diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java index 92cb452dc8..1a4f4aebf3 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java @@ -8,7 +8,7 @@ import static org.mockserver.model.HttpResponse.response; import java.io.IOException; import java.net.ServerSocket; -import org.apache.http.HttpStatus; +import org.apache.hc.core5.http.HttpStatus; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.mockserver.client.MockServerClient; diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java index d421de1c7a..50cf1b7a64 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java @@ -38,8 +38,6 @@ import org.junit.jupiter.api.Test; class HttpAsyncClientLiveTest extends GetRequestMockServer { - - private static final String HOST = "http://www.google.com"; private static final String HOST_WITH_SSL = "https://mms.nw.ru/"; private static final String HOST_WITH_PROXY = "http://httpbin.org/"; private static final String URL_SECURED_BY_BASIC_AUTHENTICATION = "http://browserspy.dk/password-ok.php";// "http://localhost:8080/spring-security-rest-basic-auth/api/foos/1"; @@ -136,7 +134,7 @@ class HttpAsyncClientLiveTest extends GetRequestMockServer { client.start(); - final SimpleHttpRequest request = new SimpleHttpRequest("GET",HOST_WITH_SSL); + final SimpleHttpRequest request = new SimpleHttpRequest("GET", HOST_WITH_SSL); final Future future = client.execute(request, null); final HttpResponse response = future.get(); @@ -201,7 +199,7 @@ class HttpAsyncClientLiveTest extends GetRequestMockServer { @Override public void run() { try { - final Future future = client.execute(SimpleHttpRequest.copy(request), context, null); + final Future future = client.execute(SimpleRequestBuilder.copy(request).build(), context, null); final HttpResponse response = future.get(); assertThat(response.getCode(), equalTo(200)); } catch (final Exception ex) { diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java index e9ea08a723..537f501d93 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/ResponseUtil.java @@ -1,10 +1,10 @@ package com.baeldung.httpclient; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; - import java.io.IOException; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.core5.http.HttpEntity; + public final class ResponseUtil { private ResponseUtil() { } diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java index 3ac3ee88be..2a8665b624 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java @@ -103,7 +103,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { //given proxyMock.stubFor(get(urlMatching(".*")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); @@ -129,7 +129,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { public void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException { //given proxyMock.stubFor(get(urlMatching("/private")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); diff --git a/apache-httpclient4/pom.xml b/apache-httpclient4/pom.xml index 8b2fd76f0e..90890ef7b9 100644 --- a/apache-httpclient4/pom.xml +++ b/apache-httpclient4/pom.xml @@ -158,7 +158,7 @@ ${mockserver.version} - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -237,7 +237,7 @@ 1.16.0 4.1.5 - 2.5.1 + 3.3.1 4.4.16 4.5.14 5.11.2 diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java index 5ced756644..714c01192e 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/advancedconfig/HttpClientAdvancedConfigurationIntegrationTest.java @@ -102,7 +102,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { //given proxyMock.stubFor(get(urlMatching(".*")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); @@ -128,7 +128,7 @@ class HttpClientAdvancedConfigurationIntegrationTest { void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException { //given proxyMock.stubFor(get(urlMatching("/private")) - .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); + .willReturn(aResponse().proxiedFrom("http://localhost:8089"))); serviceMock.stubFor(get(urlEqualTo("/private")) .willReturn(aResponse().withStatus(200))); diff --git a/core-java-modules/core-java-httpclient/pom.xml b/core-java-modules/core-java-httpclient/pom.xml index f3730d1b45..fc95366392 100644 --- a/core-java-modules/core-java-httpclient/pom.xml +++ b/core-java-modules/core-java-httpclient/pom.xml @@ -32,7 +32,7 @@ test - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -58,7 +58,7 @@ 11 3.22.0 5.11.2 - 2.27.2 + 3.3.1 \ No newline at end of file diff --git a/core-java-modules/core-java-io-2/pom.xml b/core-java-modules/core-java-io-2/pom.xml index 8f4f2518fe..8632748baa 100644 --- a/core-java-modules/core-java-io-2/pom.xml +++ b/core-java-modules/core-java-io-2/pom.xml @@ -31,9 +31,8 @@ log4j-over-slf4j ${org.slf4j.version} - - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -63,7 +62,7 @@ 3.0.0-M1 - 2.26.3 + 3.3.1 \ No newline at end of file diff --git a/httpclient-simple/pom.xml b/httpclient-simple/pom.xml index 8cbc1237c2..a0f2dd6514 100644 --- a/httpclient-simple/pom.xml +++ b/httpclient-simple/pom.xml @@ -99,7 +99,7 @@ ${commons-codec.version} - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -207,7 +207,7 @@ 1.16.0 - 2.5.1 + 3.3.1 5.2 5.2 diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 32f75aa676..9ea5f62778 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -85,7 +85,7 @@ ${jersey.version} - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -219,7 +219,7 @@ 1.6.1 4.4.9 4.5.5 - 2.27.2 + 3.3.1 1.5.10.RELEASE diff --git a/testing-modules/rest-testing/pom.xml b/testing-modules/rest-testing/pom.xml index f8005092ae..975b6fb647 100644 --- a/testing-modules/rest-testing/pom.xml +++ b/testing-modules/rest-testing/pom.xml @@ -34,7 +34,7 @@ - com.github.tomakehurst + org.wiremock wiremock ${wiremock.version} test @@ -135,7 +135,7 @@ 2.9.0 6.8.0 - 2.21.0 + 3.3.1 1.3.1 4.1 From c10a404f57152bccaf50d097712f50700147e58f Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:58:10 +0000 Subject: [PATCH 58/71] [JAVA-26734] Upgraded aspectjrt, aspectjweaver to latest version (#15140) --- .../core-java-concurrency-advanced-3/pom.xml | 6 +++--- core-java-modules/core-java-os/pom.xml | 1 - .../core-java-time-measurements/pom.xml | 4 ++-- di-modules/cdi/pom.xml | 2 +- libraries-3/pom.xml | 6 +++--- parent-boot-2/pom.xml | 12 +++++++++++- spring-boot-modules/spring-boot-annotations/pom.xml | 1 - spring-boot-modules/spring-boot-mvc/pom.xml | 3 +-- spring-di/pom.xml | 2 +- spring-static-resources/pom.xml | 4 ++-- 10 files changed, 24 insertions(+), 17 deletions(-) diff --git a/core-java-modules/core-java-concurrency-advanced-3/pom.xml b/core-java-modules/core-java-concurrency-advanced-3/pom.xml index 7fa859c2d5..e3b399782e 100644 --- a/core-java-modules/core-java-concurrency-advanced-3/pom.xml +++ b/core-java-modules/core-java-concurrency-advanced-3/pom.xml @@ -85,12 +85,12 @@ 1.8 1.8 0.22.6 - 1.9.5 + 1.9.20.1 0.43 1.2.3 0.14.1 - 1.9.1 - 1.9.1 + 1.9.20.1 + 1.9.20.1 \ No newline at end of file diff --git a/core-java-modules/core-java-os/pom.xml b/core-java-modules/core-java-os/pom.xml index d4ee34b8b7..cd5b479974 100644 --- a/core-java-modules/core-java-os/pom.xml +++ b/core-java-modules/core-java-os/pom.xml @@ -75,7 +75,6 @@ 4.01 - 1.8.9 1.9 1.9 0.4 diff --git a/core-java-modules/core-java-time-measurements/pom.xml b/core-java-modules/core-java-time-measurements/pom.xml index 7b2bc31ebb..2dd713efe8 100644 --- a/core-java-modules/core-java-time-measurements/pom.xml +++ b/core-java-modules/core-java-time-measurements/pom.xml @@ -33,7 +33,7 @@ org.aspectj aspectjrt - ${asspectj.version} + ${aspectj.version} org.mockito @@ -74,7 +74,7 @@ 3.6.1 2.10 - 1.8.9 + 1.9.20.1 1.44 4.1.0 diff --git a/di-modules/cdi/pom.xml b/di-modules/cdi/pom.xml index fd920c8ce1..09f69f3dc3 100644 --- a/di-modules/cdi/pom.xml +++ b/di-modules/cdi/pom.xml @@ -59,7 +59,7 @@ 2.0.SP1 3.1.6.Final - 1.9.19 + 1.9.20.1 \ No newline at end of file diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index 8d45b95a7b..9923e46267 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -219,10 +219,10 @@ 2.7.2 1.2.3.Final 0.22.6 - 1.9.2 + 1.9.20.1 0.14.1 - 1.9.2 - 1.9.2 + 1.9.20.1 + 1.9.20.1 1.19 4.4.13 4.5.12 diff --git a/parent-boot-2/pom.xml b/parent-boot-2/pom.xml index 3f6ad8ef8a..b79be81a66 100644 --- a/parent-boot-2/pom.xml +++ b/parent-boot-2/pom.xml @@ -36,6 +36,16 @@ pom import + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + @@ -95,7 +105,7 @@ 1.0.22.RELEASE 2.7.11 - 1.9.1 + 1.9.20.1 8.0.31 diff --git a/spring-boot-modules/spring-boot-annotations/pom.xml b/spring-boot-modules/spring-boot-annotations/pom.xml index 91f2614de8..13a28cbd4e 100644 --- a/spring-boot-modules/spring-boot-annotations/pom.xml +++ b/spring-boot-modules/spring-boot-annotations/pom.xml @@ -17,7 +17,6 @@ org.aspectj aspectjweaver - ${aspectjweaver.version} org.springframework.boot diff --git a/spring-boot-modules/spring-boot-mvc/pom.xml b/spring-boot-modules/spring-boot-mvc/pom.xml index a251c5049b..963cda61b9 100644 --- a/spring-boot-modules/spring-boot-mvc/pom.xml +++ b/spring-boot-modules/spring-boot-mvc/pom.xml @@ -84,12 +84,10 @@ org.aspectj aspectjrt - ${aspectjweaver.version} org.aspectj aspectjweaver - ${aspectjweaver.version} org.projectlombok @@ -114,6 +112,7 @@ 1.10.0 2.3.7 + 1.9.20.1 com.baeldung.springbootmvc.SpringBootMvcApplication diff --git a/spring-di/pom.xml b/spring-di/pom.xml index bae7263ef9..d073f5359d 100644 --- a/spring-di/pom.xml +++ b/spring-di/pom.xml @@ -134,7 +134,7 @@ org.baeldung.org.baeldung.sample.App 3.1.2 - 1.9.5 + 1.9.20.1 \ No newline at end of file diff --git a/spring-static-resources/pom.xml b/spring-static-resources/pom.xml index 875b8de31b..2bf865ddbe 100644 --- a/spring-static-resources/pom.xml +++ b/spring-static-resources/pom.xml @@ -88,7 +88,7 @@ org.aspectj aspectjrt - ${org.aspectj-version} + ${aspectj.version} javax.inject @@ -186,7 +186,7 @@ - 1.8.9 + 1.9.20.1 8.0.1.Final 4.1.0 From 0847a0b8cee1daf773e152a7d4f051ec41633457 Mon Sep 17 00:00:00 2001 From: anuragkumawat Date: Mon, 20 Nov 2023 18:54:59 +0530 Subject: [PATCH 59/71] JAVA-26713 Upgrade spring-boot-starter-validation version --- javaxval-2/pom.xml | 23 +++++++++++-------- ...entDeserializerWithValidationUnitTest.java | 2 +- javaxval/pom.xml | 8 +++---- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/javaxval-2/pom.xml b/javaxval-2/pom.xml index f73f23bcb2..366fd9fdbf 100644 --- a/javaxval-2/pom.xml +++ b/javaxval-2/pom.xml @@ -9,26 +9,24 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-3 + 0.0.1-SNAPSHOT + ../parent-boot-3 org.springframework.boot spring-boot-starter-validation - ${spring.boot.version} org.springframework.boot spring-boot-starter-test - ${spring.boot.version} test com.fasterxml.jackson.core jackson-databind - ${jackson.databind.version} @@ -42,9 +40,16 @@ - - 3.0.4 - 2.14.0 - + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + \ No newline at end of file diff --git a/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java b/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java index 094236e963..8c3761ae09 100644 --- a/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java +++ b/javaxval-2/src/test/java/com/baeldung/javaxval/afterdeserialization/StudentDeserializerWithValidationUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.javaxval; +package com.baeldung.javaxval.afterdeserialization; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; diff --git a/javaxval/pom.xml b/javaxval/pom.xml index c4a30f915d..e1a3dc350c 100644 --- a/javaxval/pom.xml +++ b/javaxval/pom.xml @@ -8,20 +8,19 @@ com.baeldung - parent-modules - 1.0.0-SNAPSHOT + parent-boot-3 + 0.0.1-SNAPSHOT + ../parent-boot-3 org.springframework.boot spring-boot-starter-validation - ${spring.boot.version} org.springframework.boot spring-boot-starter-test - ${spring.boot.version} test @@ -38,7 +37,6 @@ 8.0.1.Final - 3.0.4 \ No newline at end of file From a3e0639a75506908027421d647c50704dd882edd Mon Sep 17 00:00:00 2001 From: MohamedHelmyKassab <137485958+MohamedHelmyKassab@users.noreply.github.com> Date: Mon, 20 Nov 2023 19:18:13 +0200 Subject: [PATCH 60/71] This commit is related to the article BAEL-7232 (#15252) This commit adds a new test class "TimeToLocalDateTimeUnitTest" that shows how to convert a long timestamp into a LocalDateTime object. --- .../TimeToLocalDateTimeUnitTest.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java diff --git a/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java new file mode 100644 index 0000000000..e8fb821c75 --- /dev/null +++ b/core-java-modules/core-java-datetime-conversion/src/test/java/com/baeldung/timestamptolocaldatetime/TimeToLocalDateTimeUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.timestamptolocaldatetime; + +import org.joda.time.DateTimeZone; +import org.junit.Test; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; + +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormat; + +import static org.junit.Assert.assertEquals; + +public class TimeToLocalDateTimeUnitTest { + private static final long timestampInMillis = 1700010123000L; + private static final String expectedTimestampString = "2023-11-15 01:02:03"; + + @Test + public void givenTimestamp_whenConvertingToLocalDateTime_thenConvertSuccessfully() { + Instant instant = Instant.ofEpochMilli(timestampInMillis); + LocalDateTime localDateTime = + LocalDateTime.ofInstant(instant, ZoneId.of("UTC")); + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + String formattedDateTime = localDateTime.format(formatter); + + assertEquals(expectedTimestampString, formattedDateTime); + } + + @Test + public void givenJodaTime_whenGettingTimestamp_thenConvertToLong() { + DateTime dateTime = new DateTime(timestampInMillis, DateTimeZone.UTC); + org.joda.time.LocalDateTime localDateTime = dateTime.toLocalDateTime(); + + org.joda.time.format.DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); + String actualTimestamp = formatter.print(localDateTime); + + assertEquals(expectedTimestampString, actualTimestamp); + } +} From ec1fde9dc1e03cf83678f194b29c4c6b437a0e84 Mon Sep 17 00:00:00 2001 From: Constantin Date: Mon, 20 Nov 2023 14:36:44 +0200 Subject: [PATCH 61/71] BAEL-6014: Check certificate name and alias in keystore file --- .../KeystoreCertificateNameAliasUnitTest.java | 50 ++++++++++++++++++ .../baeldung/keystorealias/my-keystore.jks | Bin 0 -> 2764 bytes 2 files changed, 50 insertions(+) create mode 100644 core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java create mode 100644 core-java-modules/core-java-security-4/src/test/resources/com/baeldung/keystorealias/my-keystore.jks diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java new file mode 100644 index 0000000000..47bc4c3425 --- /dev/null +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.keystorealias; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.security.KeyStore; +import java.security.cert.X509Certificate; + +import org.junit.jupiter.api.Test; + +public class KeystoreCertificateNameAliasUnitTest { + private static final String KEYSTORE_FILE = "my-keystore.jks"; + private static final String KEYSTORE_PWD = "storepw@1"; + private static final String KEYSTORE_ALIAS = "baeldung"; + + private KeyStore readKeyStore() throws Exception { + KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); + keystore.load(getClass().getResourceAsStream(KEYSTORE_FILE), KEYSTORE_PWD.toCharArray()); + return keystore; + } + + @Test + void whenCheckingAliasAndName_thenMatchIsFound() throws Exception { + KeyStore keystore = readKeyStore(); + + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String owner = x509Certificate.getSubjectX500Principal().getName(); + assertThat(owner.contains("my-cn.localhost")).isTrue(); + } + + @Test + void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); + + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String owner = x509Certificate.getSubjectX500Principal() + .getName(); + assertThat(owner.contains("commonName1")).isFalse(); + } + + @Test + void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); + + assertThat(keystore.containsAlias("alias1")).isFalse(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-security-4/src/test/resources/com/baeldung/keystorealias/my-keystore.jks b/core-java-modules/core-java-security-4/src/test/resources/com/baeldung/keystorealias/my-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..8f7709ee9656d443f21a53170449736898f0325b GIT binary patch literal 2764 zcma);S5y-W5`~kHMsGnRg0xViXoB?K1q?+g(wh*9G%3{r zC<2DAfb^zdp(#OBSoiE6|FciK4|C?soqOl;JA=kE4S;|QXgpIelu?RcM4+<*VL%d| z={gwCXlBRO&d=MMuWX=da_eb-q(?9bFV!6WW*!0{X_kG9svM) z?xUJzn&1b&{VUdNM9G;;Q(?tiGM+n+TxiEM{FlaCH94FY;BeXEqBcuh;X`KI!E!a~ z`dNv*29>23L_{zT3m*oW4slqpoS#DtCD;#d%*@x!M>@+HvQBJyIL$J^15#c#aER3lr{W{9H%Ms|L|B zIn-x~`K0MlRqK;7&MmoP__V$)XVZlJU_9N~StOx0e!SStk6c<#zYW=Y@uTscD{^bY zWVs$vq-hep-{`QoI(@gwBntI~W>j4DI(4waP>N8W5c8d8UgS)``u2qk`J7fzoZI!Cu!PMEqcZd#$zVwm0H-c^yXWAUpQlL4n9<8lfcFtbeJKe zVGl}wd~SRWOG2-EXeK|Dx$XmB`szEuf1ScQ?5;m(NUbvQ2(+8abHgULF+5^ZOEvdU zD3ml{^YDBq$e29yk%&5*l zpqpNA_OFEdbI5Gxxatp5YXTwiNh%h%*XQPsj=eI~<$RbtS`Z1JGKqU$jpo{lhi^aj zL_*8*r?NXo>@*4E?$uQp@EkS+26)uK;E~HrNE^5B zxO~oKn}r$|JJN2rgHxX2l43KKc9`AoT4^wsieIyglL}8H%J5h@h+=HBA7g^X3D#3c ztL)a5WJ0d>&d<6m&C5BQHjv2-oRs#&yPBWdLD3Xbk&sq)_Ell!+kQN=nsd>p5-Zcg z%pPORJaT>VNv@dw+cj8u=Tn`6CNlv&*;B4;(8IXlXE{6grl!#zhl}gH2jl~UxdG2a z2L-k))S#Xi2gUK89@;$1HdcGmIe9-iB_dIC5b5E@>~v$jY4iz~fzA#|*!I()`ngB< zD0Su;Pfj5g|oyK>?#eXR3%Zr1Q7O_%( z4;-CBa=OXE6zWF%(Bf;jYL_B^6~c+!YHB9@=A&d z3UZ2a%4j^e?2icsCE>wYzook%AmDdP{(A%bU#Nc1H(f)Iu-qPp4J0~RBJyyX8L{ENv;c9+K}{&!9EQc^z`jEhgwO_s%?5tW?et!Td)F<=kmZPue|)|XZpPwHhZl7UrE z5Bri;9?m}XwgCEbkJ5se14(Yzqsr$`kXJ`RvyE$Kd?nd>(T`4wBy|BUE~Q_RK3Dcc>t8{K3@>_B3moTdEejCRja_cK$r;B}L zXUP3m>&KX_$nT^M8w~tfN-oW>w)|(PqAXF$?kjfbOUn_>03)6FVM70$rR1A6!5gy1 zmH0Ba8QRUNXE?gGy6?1OGux?3$ONHY6jLZ>+BclMuChD2b6W{3pXZ9IMyv!&#Mvl3 zE-LMg@60T>AC0!U3txI#U5RZ^SJ}CJCY_FYe@oelsu8poYORX6qX+fs-B*p_6<{Yn zD1eY49`Nb?`3j-Kfd@kGw9_I!HmZQ;yn2*i<0q1N6|I4I7t!5x^~i0a1?A;{2o7WW zPSvL@iH-Vg5rvD{vK&@b-4}prL9>6gjX%R8machpgIoFcIsuQ8jn4PaYJmsm>xxi5 z>Nr&@ea6qKHhv(33i=@}3aJet8th$V3}APO7aZvtsLee^b>+V95-ah50cVuF?BMH0 zaP9Hh9TDZcQm8MR-#@Xh$-y6BGdWWwbrI@IyzJtjTI+9urXEbfNQR=#pKi8r4~ZYU zJR2iDnR&r4Vj03x-5gBw-E!G%$zu^wYIc$FS$cIW9laj*-YXLon)Q|k`MmuaKfgMu z*ZRxpQ_r;)+~Gu$l1ga+EHtCGZ*%3lSz_^>nr7AMpzUXnhCT1e5{1ucmO+5$zJG;^ zZ6`QtoD9CMqM;%c37+QE0Abd2{To5*`=#QJx{J^i=B?m^!1L9zdf1ANdwnh&DxI(5!zxJP;5901MR*oaT&uZ*eCJ>8i8%J%Pi& s4Oyc}^70n{XjUP7XTl7O;75 Date: Mon, 20 Nov 2023 20:12:51 +0200 Subject: [PATCH 62/71] BAEL-6014: Remove newline --- .../keystorealias/KeystoreCertificateNameAliasUnitTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java index 47bc4c3425..26bd937ca4 100644 --- a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java @@ -36,8 +36,7 @@ public class KeystoreCertificateNameAliasUnitTest { assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); - String owner = x509Certificate.getSubjectX500Principal() - .getName(); + String owner = x509Certificate.getSubjectX500Principal().getName(); assertThat(owner.contains("commonName1")).isFalse(); } From 34754e74ad17231b515fd8f25da96a8fd0f44858 Mon Sep 17 00:00:00 2001 From: Constantin Date: Mon, 20 Nov 2023 22:12:10 +0200 Subject: [PATCH 63/71] BAEL-6014: Address PR comments --- .../KeystoreCertificateNameAliasUnitTest.java | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java index 26bd937ca4..e53c1c57cb 100644 --- a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java @@ -25,25 +25,25 @@ public class KeystoreCertificateNameAliasUnitTest { assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); - String owner = x509Certificate.getSubjectX500Principal().getName(); - assertThat(owner.contains("my-cn.localhost")).isTrue(); + String ownerName = x509Certificate.getSubjectX500Principal().getName(); + assertThat(ownerName.contains("my-cn.localhost")).isTrue(); } - @Test - void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { - KeyStore keystore = readKeyStore(); +@Test +void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); - assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); - X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); - String owner = x509Certificate.getSubjectX500Principal().getName(); - assertThat(owner.contains("commonName1")).isFalse(); - } + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String ownerName = x509Certificate.getSubjectX500Principal().getName(); + assertThat(ownerName.contains("commonName1")).isFalse(); +} - @Test - void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { - KeyStore keystore = readKeyStore(); +@Test +void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); - assertThat(keystore.containsAlias("alias1")).isFalse(); - } + assertThat(keystore.containsAlias("alias1")).isFalse(); +} } \ No newline at end of file From 0bf89cfe37de372f25b378ca0aa02aa8a10e3ea6 Mon Sep 17 00:00:00 2001 From: Constantin Date: Mon, 20 Nov 2023 22:28:07 +0200 Subject: [PATCH 64/71] BAEL-6014: Fix formatting --- .../KeystoreCertificateNameAliasUnitTest.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java index e53c1c57cb..8f3ec35160 100644 --- a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/keystorealias/KeystoreCertificateNameAliasUnitTest.java @@ -29,21 +29,21 @@ public class KeystoreCertificateNameAliasUnitTest { assertThat(ownerName.contains("my-cn.localhost")).isTrue(); } -@Test -void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { - KeyStore keystore = readKeyStore(); + @Test + void whenCheckingAliasAndName_thenNameIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); - assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); + assertThat(keystore.containsAlias(KEYSTORE_ALIAS)).isTrue(); - X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); - String ownerName = x509Certificate.getSubjectX500Principal().getName(); - assertThat(ownerName.contains("commonName1")).isFalse(); -} + X509Certificate x509Certificate = (X509Certificate) keystore.getCertificate(KEYSTORE_ALIAS); + String ownerName = x509Certificate.getSubjectX500Principal().getName(); + assertThat(ownerName.contains("commonName1")).isFalse(); + } -@Test -void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { - KeyStore keystore = readKeyStore(); + @Test + void whenCheckingAliasAndName_thenAliasIsNotFound() throws Exception { + KeyStore keystore = readKeyStore(); - assertThat(keystore.containsAlias("alias1")).isFalse(); -} + assertThat(keystore.containsAlias("alias1")).isFalse(); + } } \ No newline at end of file From 111dcccb922f20b2fb7865a973d0ba7eac6a195e Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Mon, 20 Nov 2023 22:28:10 +0100 Subject: [PATCH 65/71] Bael 7060 (#15247) * BAEL-7060: Converting String to ByteBuffer * BAEL-7060: Converting String to ByteBuffer (format code) --- .../ByteArrayToStringUnitTest.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java index c498921d9a..c54bb1236e 100644 --- a/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java +++ b/core-java-modules/core-java-string-conversions-2/src/test/java/com/baeldung/bytebuffertostring/ByteArrayToStringUnitTest.java @@ -1,12 +1,12 @@ package com.baeldung.bytebuffertostring; -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.Test; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; public class ByteArrayToStringUnitTest { private static Charset charset = StandardCharsets.UTF_8; @@ -37,8 +37,17 @@ public class ByteArrayToStringUnitTest { // Allocate a ByteBuffer ByteBuffer byteBuffer = ByteBuffer.wrap(content.getBytes()); String newContent = charset.decode(byteBuffer) - .toString(); + .toString(); assertEquals(content, newContent); } + @Test + public void convertStringToByteBuffer_thenOk() { + byte[] expectedBytes = content.getBytes(Charset.forName(charset.toString())); + ByteBuffer byteBuffer = ByteBuffer.wrap(expectedBytes); + + // Test the conversion from string to ByteBuffer + assertEquals(expectedBytes, byteBuffer.array()); + } + } From 85c4c1450b68d7dbcc0bdf95daa210d3341be137 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Mon, 20 Nov 2023 19:43:54 -0300 Subject: [PATCH 66/71] BAEL-2499 - Write to CSV in Java Closes #15250 Adding a null check. --- .../src/main/java/com/baeldung/csv/WriteCsvFileExample.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java b/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java index f409d05b06..184ae6d3e3 100644 --- a/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java +++ b/core-java-modules/core-java-io-conversions-2/src/main/java/com/baeldung/csv/WriteCsvFileExample.java @@ -12,6 +12,10 @@ public class WriteCsvFileExample { } public String escapeSpecialCharacters(String data) { + if (data == null) { + throw new IllegalArgumentException("Input data cannot be null"); + } + String escapedData = data.replaceAll("\\R", " "); if (data.contains(",") || data.contains("\"") || data.contains("'")) { data = data.replace("\"", "\"\""); From 94595ea00060ca94784f60a94c523074aaecf8e7 Mon Sep 17 00:00:00 2001 From: Shahul Basha <32072554+shahulbasha@users.noreply.github.com> Date: Mon, 20 Nov 2023 21:50:44 -0500 Subject: [PATCH 67/71] BAEL-7016 (#15050) * initial commit * initial commit * code cleanup * code cleanup * code cleanup * code cleanup * code review comments addressed * pom version * code review comments * formatting updated * updated as per code review comments --- xml-2/pom.xml | 12 ++ .../com/baeldung/xml/tohashmap/Employee.java | 31 +++++ .../com/baeldung/xml/tohashmap/Employees.java | 21 +++ .../baeldung/xml/tohashmap/XmlToHashMap.java | 124 ++++++++++++++++++ .../main/resources/xml/xmltohashmap/test.xml | 12 ++ .../xml/tohashmap/XmlToHashMapUnitTest.java | 71 ++++++++++ 6 files changed, 271 insertions(+) create mode 100644 xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java create mode 100644 xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java create mode 100644 xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java create mode 100644 xml-2/src/main/resources/xml/xmltohashmap/test.xml create mode 100644 xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java diff --git a/xml-2/pom.xml b/xml-2/pom.xml index 0f94588ba0..ccb84e1687 100644 --- a/xml-2/pom.xml +++ b/xml-2/pom.xml @@ -46,6 +46,16 @@ underscore ${underscore.version} + + com.thoughtworks.xstream + xstream + ${xstream.version} + + + com.sun.xml.bind + jaxb-impl + ${jaxb.version} + org.apache.xmlbeans xmlbeans @@ -82,6 +92,8 @@ 2.1.3 20230227 1.89 + 1.4.18 + 2.3.3 diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java new file mode 100644 index 0000000000..c9c40e743a --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java @@ -0,0 +1,31 @@ +package com.baeldung.xml.tohashmap; + +public class Employee { + private String id; + private String firstName; + private String lastName; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java new file mode 100644 index 0000000000..d2f2276e5c --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java @@ -0,0 +1,21 @@ +package com.baeldung.xml.tohashmap; + +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "employees") +public class Employees { + + private List employeeList; + + @XmlElement(name = "employee") + public List getEmployeeList() { + return employeeList; + } + + public void setEmployeeList(List employeeList) { + this.employeeList = employeeList; + } +} \ No newline at end of file diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java new file mode 100644 index 0000000000..ec651486ac --- /dev/null +++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java @@ -0,0 +1,124 @@ +package com.baeldung.xml.tohashmap; + +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.github.underscore.U; +import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.security.AnyTypePermission; + +public class XmlToHashMap { + + public Map xmlToHashMapUsingXstream(String xml) { + XStream xStream = new XStream(); + xStream.alias("employees", List.class); + xStream.alias("employee", Employee.class); + xStream.addPermission(AnyTypePermission.ANY); + List employees = (List) xStream.fromXML(xml); + return employees.stream() + .collect(Collectors.toMap(Employee::getId, Function.identity())); + } + + public Map xmlToHashMapUsingUnderscore(String xml) { + Map employeeMap = new HashMap<>(); + Map employeeList = (Map) U.fromXmlMap(xml) + .get("employees"); + List> list = (List>) employeeList.get("employee"); + parseXmlToMap(employeeMap, list); + return employeeMap; + } + + public Map xmlToHashMapUsingJackson(String xml) throws JsonProcessingException { + XmlMapper xmlMapper = new XmlMapper(); + Map employeeMap = new HashMap<>(); + Map map = xmlMapper.readValue(xml, Map.class); + List> list = (List>) map.get("employee"); + parseXmlToMap(employeeMap, list); + return employeeMap; + } + + public Map xmlToHashMapUsingJAXB(String xmlData) throws JAXBException { + JAXBContext context = JAXBContext.newInstance(Employees.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + Employees employees = (Employees) unmarshaller.unmarshal(new StringReader(xmlData)); + return employees.getEmployeeList() + .stream() + .collect(Collectors.toMap(Employee::getId, Function.identity())); + } + + public Map xmlToHashMapUsingDOMParserXpath(String xmlData) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(new InputSource(new StringReader(xmlData))); + + XPathFactory xPathfactory = XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression xPathExpr = xpath.compile("/employees/employee"); + NodeList nodes = (NodeList) xPathExpr.evaluate(doc, XPathConstants.NODESET); + + HashMap map = new HashMap<>(); + for (int i = 0; i < nodes.getLength(); i++) { + Element node = (Element) nodes.item(i); + Employee employee = new Employee(); + employee.setId(node.getElementsByTagName("id") + .item(0) + .getTextContent()); + employee.setFirstName(node.getElementsByTagName("firstName") + .item(0) + .getTextContent()); + employee.setLastName(node.getElementsByTagName("lastName") + .item(0) + .getTextContent()); + map.put(employee.getId(), employee); + } + return map; + } + + private static void parseXmlToMap(Map employeeMap, List> list) { + list.forEach(empMap -> { + Employee employee = new Employee(); + for (Map.Entry key : empMap.entrySet()) { + switch (key.getKey()) { + case "id": + employee.setId(key.getValue()); + break; + case "firstName": + employee.setFirstName(key.getValue()); + break; + case "lastName": + employee.setLastName(key.getValue()); + break; + default: + break; + } + } + employeeMap.put(employee.getId(), employee); + }); + } +} diff --git a/xml-2/src/main/resources/xml/xmltohashmap/test.xml b/xml-2/src/main/resources/xml/xmltohashmap/test.xml new file mode 100644 index 0000000000..ef0d12e2af --- /dev/null +++ b/xml-2/src/main/resources/xml/xmltohashmap/test.xml @@ -0,0 +1,12 @@ + + + 654 + John + Doe + + + 776 + Steve + Smith + + \ No newline at end of file diff --git a/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java new file mode 100644 index 0000000000..5e05dd3ccb --- /dev/null +++ b/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung.xml.tohashmap; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Map; + +import javax.xml.bind.JAXBException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class XmlToHashMapUnitTest { + + private XmlToHashMap xmlToHashMap; + private static final String TEST_XML_PATH = "src/main/resources/xml/xmltohashmap/test.xml"; + + @BeforeEach + void setUp() { + xmlToHashMap = new XmlToHashMap(); + } + + @Test + void whenUsingXstream_thenHashMapShouldBeCreated() throws IOException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingXstream(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingUnderscore_thenHashMapShouldBeCreated() throws IOException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingUnderscore(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingJackson_thenHashMapShouldBeCreated() throws IOException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingJackson(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingJAXB_thenHashMapShouldBeCreated() throws IOException, JAXBException { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingJAXB(getXml()); + verify(employeeMap); + } + + @Test + void whenUsingDOMXpath_thenHashMapShouldBeCreated() throws Exception { + Map employeeMap = xmlToHashMap.xmlToHashMapUsingDOMParserXpath(getXml()); + verify(employeeMap); + } + + private void verify(Map employeeMap) { + Employee employee1 = employeeMap.get("654"); + Employee employee2 = employeeMap.get("776"); + Assertions.assertEquals("John", employee1 + .getFirstName()); + Assertions.assertEquals("Doe", employee1 + .getLastName()); + Assertions.assertEquals("Steve", employee2 + .getFirstName()); + Assertions.assertEquals("Smith", employee2 + .getLastName()); + } + + private String getXml() throws IOException { + return new String(Files.readAllBytes(Paths.get(TEST_XML_PATH))); + } +} From 9c995714f78f6715d0b99586c1f12e422ecca545 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Tue, 21 Nov 2023 04:47:17 +0100 Subject: [PATCH 68/71] JAVA-26732: Update the equalsverifier dependency --- core-java-modules/core-java-lang-oop-methods/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-lang-oop-methods/pom.xml b/core-java-modules/core-java-lang-oop-methods/pom.xml index 6f246d78ce..5e53004d62 100644 --- a/core-java-modules/core-java-lang-oop-methods/pom.xml +++ b/core-java-modules/core-java-lang-oop-methods/pom.xml @@ -35,7 +35,7 @@ 2.6 3.10.0 - 3.0.3 + 3.15.3 \ No newline at end of file From 923556ea274f141a02b9eca22b414961f9c94664 Mon Sep 17 00:00:00 2001 From: Bipin kumar Date: Tue, 21 Nov 2023 16:22:50 +0530 Subject: [PATCH 69/71] Java 27246 (#15255) --- core-java-modules/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index a237fe0ed6..27d84c742d 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -198,7 +198,8 @@ core-java-records core-java-9-jigsaw - + + core-java-collections-set core-java-date-operations-1 core-java-datetime-conversion From ea7466682bd16d35e126ab859662d1d0b3783782 Mon Sep 17 00:00:00 2001 From: Pedro Lopes Date: Tue, 21 Nov 2023 11:39:23 -0300 Subject: [PATCH 70/71] BAEL-7178: StringUtils.isBlank() vs String.isEmpty() (#15213) * adding first test cases * final code --- .../StringIsEmptyVsIsBlankUnitTest.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java diff --git a/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java new file mode 100644 index 0000000000..f6950237c5 --- /dev/null +++ b/core-java-modules/core-java-string-operations-7/src/test/java/com/baeldung/isemptyvsisblank/StringIsEmptyVsIsBlankUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.isemptyvsisblank; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class StringIsEmptyVsIsBlankUnitTest { + + @Test + public void givenString_whenCallIsEmpty_thenReturnCorrectValues() { + assertFalse("Example text".isEmpty()); + assertTrue("".isEmpty()); + assertFalse(" ".isEmpty()); + assertFalse("\t\n\r\f".isEmpty()); + } + + @Test + public void givenString_whenCallStringIsBlank_thenReturnCorrectValues() { + assertFalse("Example text".isBlank()); + assertTrue("".isBlank()); + assertTrue(" ".isBlank()); + assertTrue("\t\n\r\f ".isBlank()); + } +} From 76d261295986b4e31be99156f97d9b7039f4ac53 Mon Sep 17 00:00:00 2001 From: Kai Yuan Date: Wed, 22 Nov 2023 04:38:37 +0100 Subject: [PATCH 71/71] [if-class-is-enum] check class is enum (#15235) * [if-class-is-enum] check class is enum * [if-class-is-enum] move to new module --- .../classcheck/CheckClassIsEnumUnitTest.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/classcheck/CheckClassIsEnumUnitTest.java diff --git a/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/classcheck/CheckClassIsEnumUnitTest.java b/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/classcheck/CheckClassIsEnumUnitTest.java new file mode 100644 index 0000000000..a69df8739f --- /dev/null +++ b/core-java-modules/core-java-lang-oop-types-2/src/test/java/com/baeldung/enums/classcheck/CheckClassIsEnumUnitTest.java @@ -0,0 +1,75 @@ +package com.baeldung.enums.classcheck; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +enum Device { + Keyboard, Monitor, Mouse, Printer +} + +enum Weekday { + Monday, Tuesday, Wednesday, Thursday, Friday, + Saturday { + @Override + boolean isWeekend() { + return true; + } + }, + Sunday { + @Override + boolean isWeekend() { + return true; + } + }; + + boolean isWeekend() { + return false; + } +} + +public class CheckClassIsEnumUnitTest { + + @Test + void whenUsingInstanceOf_thenGetExpectedResult() { + Object obj = Device.Keyboard; + assertTrue(obj instanceof Enum); + } + + @Test + void whenUsingisInstance_thenGetExpectedResult() { + Object obj = Device.Keyboard; + assertTrue(Enum.class.isInstance(obj)); + } + + @Test + void whenUsingEnumClassisAssignableFrom_thenGetExpectedResult() { + Object obj = Device.Keyboard; + assertTrue(Enum.class.isAssignableFrom(obj.getClass())); + } + + @Test + void whenUsingGetClassIsEnum_thenGetExpectedResult() { + assertTrue(Device.class.isEnum()); + + Object obj = Device.Keyboard; + assertTrue(obj.getClass().isEnum()); + } + + + @Test + void whenEnum_thenGetExpectedResult() { + Object monday = Weekday.Monday; + assertTrue(monday instanceof Enum); + assertTrue(Enum.class.isInstance(monday)); + assertTrue(Enum.class.isAssignableFrom(monday.getClass())); + assertTrue(monday.getClass().isEnum()); + + Object sunday = Weekday.Sunday; + assertTrue(sunday instanceof Enum); + assertTrue(Enum.class.isInstance(sunday)); + assertTrue(Enum.class.isAssignableFrom(sunday.getClass())); + assertFalse(sunday.getClass().isEnum()); // <-- isEnum() check failed when Enum values with body + } +} \ No newline at end of file