diff --git a/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java index 202912a1af..15e813f680 100644 --- a/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java +++ b/algorithms-modules/algorithms-miscellaneous-5/src/main/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithm.java @@ -5,7 +5,7 @@ import org.slf4j.LoggerFactory; public class KadaneAlgorithm { - private Logger logger = LoggerFactory.getLogger(BruteForceAlgorithm.class.getName()); + private Logger logger = LoggerFactory.getLogger(KadaneAlgorithm.class.getName()); public int maxSubArraySum(int[] arr) { @@ -14,15 +14,15 @@ public class KadaneAlgorithm { int end = 0; int maxSoFar = arr[0], maxEndingHere = arr[0]; + for (int i = 1; i < size; i++) { - - if (arr[i] > maxEndingHere + arr[i]) { - start = i; + maxEndingHere = maxEndingHere + arr[i]; + if (arr[i] > maxEndingHere) { maxEndingHere = arr[i]; - } else { - maxEndingHere = maxEndingHere + arr[i]; + if (maxSoFar < maxEndingHere) { + start = i; + } } - if (maxSoFar < maxEndingHere) { maxSoFar = maxEndingHere; end = i; diff --git a/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java index 8dcc81bc5b..b0ce689645 100644 --- a/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java +++ b/algorithms-modules/algorithms-miscellaneous-5/src/test/java/com/baeldung/algorithms/maximumsubarray/KadaneAlgorithmUnitTest.java @@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; class KadaneAlgorithmUnitTest { @Test - void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturns6() { + void givenArrayWithNegativeNumberWhenMaximumSubarrayThenReturnsExpectedResult() { //given int[] arr = new int[] { -3, 1, -8, 4, -1, 2, 1, -5, 5 }; //when @@ -27,7 +27,7 @@ class KadaneAlgorithmUnitTest { //then assertEquals(-1, maxSum); } - + @Test void givenArrayWithAllPosiitveNumbersWhenMaximumSubarrayThenReturnsExpectedResult() { //given @@ -39,4 +39,15 @@ class KadaneAlgorithmUnitTest { assertEquals(10, maxSum); } + @Test + void givenArrayToTestStartIndexWhenMaximumSubarrayThenReturnsExpectedResult() { + //given + int[] arr = new int[] { 1, 2, -1, 3, -6, -2 }; + //when + KadaneAlgorithm algorithm = new KadaneAlgorithm(); + int maxSum = algorithm.maxSubArraySum(arr); + //then + assertEquals(5, maxSum); + } + } \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-7/README.md b/algorithms-modules/algorithms-miscellaneous-7/README.md index ab07d655f9..82d9df9292 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/README.md +++ b/algorithms-modules/algorithms-miscellaneous-7/README.md @@ -3,4 +3,5 @@ - [Algorithm to Identify and Validate a Credit Card Number](https://www.baeldung.com/java-validate-cc-number) - [Find the N Most Frequent Elements in a Java Array](https://www.baeldung.com/java-n-most-frequent-elements-array) - [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image) +- [Calculate Distance Between Two Coordinates in Java](https://www.baeldung.com/java-find-distance-between-points) - More articles: [[<-- prev]](/algorithms-miscellaneous-6) diff --git a/annotations/README.md b/annotations/README.md deleted file mode 100644 index ec4005fc5e..0000000000 --- a/annotations/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## Annotations - -This module contains articles about Java annotations - -### Relevant Articles: - -- [Java Annotation Processing and Creating a Builder](https://www.baeldung.com/java-annotation-processing-builder) diff --git a/annotations/pom.xml b/annotations/pom.xml deleted file mode 100644 index b3fabb8637..0000000000 --- a/annotations/pom.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - 4.0.0 - annotations - annotations - pom - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - annotation-processing - annotation-user - - - \ No newline at end of file diff --git a/apache-cxf-modules/cxf-spring/pom.xml b/apache-cxf-modules/cxf-spring/pom.xml index 1c87ae4bfb..67a61e8200 100644 --- a/apache-cxf-modules/cxf-spring/pom.xml +++ b/apache-cxf-modules/cxf-spring/pom.xml @@ -43,19 +43,19 @@ com.sun.xml.ws jaxws-ri - 2.3.3 + ${jaxws-ri.version} pom javax.servlet javax.servlet-api - 4.0.1 + ${javax.servlet-api.version} provided javax.servlet jstl - 1.2 + ${jstl.version} @@ -117,7 +117,9 @@ 5.3.25 1.6.1 - 3.3.2 + 1.2 + 4.0.1 + 2.3.3 \ No newline at end of file diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/cookies/HttpClientGettingCookieValueUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/cookies/HttpClientGettingCookieValueUnitTest.java index ef57406705..6a8308483b 100644 --- a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/cookies/HttpClientGettingCookieValueUnitTest.java +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/cookies/HttpClientGettingCookieValueUnitTest.java @@ -14,6 +14,7 @@ import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.client5.http.impl.cookie.BasicClientCookie; import org.apache.hc.client5.http.protocol.HttpClientContext; +import org.apache.http.cookie.ClientCookie; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,8 +52,8 @@ class HttpClientGettingCookieValueUnitTest { private BasicCookieStore createCustomCookieStore() { BasicCookieStore cookieStore = new BasicCookieStore(); BasicClientCookie cookie = new BasicClientCookie("custom_cookie", "test_value"); - cookie.setDomain("baeldung.com"); - cookie.setAttribute("domain", "true"); + cookie.setDomain("github.com"); + cookie.setAttribute(ClientCookie.DOMAIN_ATTR, "github.com"); cookie.setPath("/"); cookieStore.addCookie(cookie); return cookieStore; diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClient5UnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClient5UnitTest.java index 9a79cbf491..8bf1278c3e 100644 --- a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClient5UnitTest.java +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClient5UnitTest.java @@ -16,7 +16,7 @@ public class ApacheHttpClient5UnitTest { public static final String DUMMY_URL = "https://postman-echo.com/get"; @Test - public void whenUseApacheHttpClient_thenCorrect() throws IOException { + void whenUseApacheHttpClient_thenCorrect() throws IOException { HttpGet request = new HttpGet(DUMMY_URL); try (CloseableHttpClient client = HttpClients.createDefault()) { diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpClientUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpClientUnitTest.java index 1dca1bf7c6..dcd3e38371 100644 --- a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpClientUnitTest.java +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpClientUnitTest.java @@ -1,6 +1,5 @@ package com.baeldung.httpclient.readresponsebodystring; -import org.junit.Test; import java.io.IOException; import java.net.URI; @@ -8,11 +7,13 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; -public class HttpClientUnitTest { +import org.junit.jupiter.api.Test; + +class HttpClientUnitTest { public static final String DUMMY_URL = "https://postman-echo.com/get"; @Test - public void whenUseHttpClient_thenCorrect() throws IOException, InterruptedException { + void whenUseHttpClient_thenCorrect() throws IOException, InterruptedException { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder().uri(URI.create(DUMMY_URL)).build(); diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpUrlConnectionUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpUrlConnectionUnitTest.java index 54ae887eb4..e19fbd6c53 100644 --- a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpUrlConnectionUnitTest.java +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/HttpUrlConnectionUnitTest.java @@ -1,7 +1,7 @@ package com.baeldung.httpclient.readresponsebodystring; -import org.junit.Assert; -import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.io.BufferedReader; import java.io.IOException; @@ -10,12 +10,14 @@ import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; +import org.junit.jupiter.api.Test; + public class HttpUrlConnectionUnitTest { public static final String DUMMY_URL = "https://postman-echo.com/get"; @Test - public void whenUseHttpUrlConnection_thenCorrect() throws IOException { + void whenUseHttpUrlConnection_thenCorrect() throws IOException { HttpURLConnection connection = (HttpURLConnection) new URL(DUMMY_URL).openConnection(); InputStream inputStream = connection.getInputStream(); @@ -28,7 +30,7 @@ public class HttpUrlConnectionUnitTest { response.append(currentLine); in.close(); - Assert.assertNotNull(response.toString()); + assertNotNull(response.toString()); System.out.println("Response -> " + response.toString()); } } diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringRestTemplateUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringRestTemplateUnitTest.java index c59d7662f1..e06cc165f0 100644 --- a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringRestTemplateUnitTest.java +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringRestTemplateUnitTest.java @@ -1,6 +1,6 @@ package com.baeldung.httpclient.readresponsebodystring; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.web.client.RestTemplate; public class SpringRestTemplateUnitTest { diff --git a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringWebClientUnitTest.java b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringWebClientUnitTest.java index 9bd2f825ad..df71bab983 100644 --- a/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringWebClientUnitTest.java +++ b/apache-httpclient-2/src/test/java/com/baeldung/httpclient/readresponsebodystring/SpringWebClientUnitTest.java @@ -1,6 +1,6 @@ package com.baeldung.httpclient.readresponsebodystring; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; @@ -8,7 +8,7 @@ public class SpringWebClientUnitTest { public static final String DUMMY_URL = "https://postman-echo.com/get"; @Test - public void whenUseWebClientRetrieve_thenCorrect() { + void whenUseWebClientRetrieve_thenCorrect() { WebClient webClient = WebClient.create(DUMMY_URL); Mono body = webClient.get().retrieve().bodyToMono(String.class); String s = body.block(); diff --git a/apache-httpclient-2/src/test/resources/logback.xml b/apache-httpclient-2/src/test/resources/logback.xml index 366a94e86e..dc1bbea439 100644 --- a/apache-httpclient-2/src/test/resources/logback.xml +++ b/apache-httpclient-2/src/test/resources/logback.xml @@ -4,6 +4,7 @@ %date [%level] %logger - %msg %n + diff --git a/apache-httpclient/pom.xml b/apache-httpclient/pom.xml index 5c3ea5b3b3..1b22d64799 100644 --- a/apache-httpclient/pom.xml +++ b/apache-httpclient/pom.xml @@ -15,45 +15,6 @@ - - - org.apache.httpcomponents - httpclient - ${httpclient.version} - - - commons-logging - commons-logging - - - - - org.apache.httpcomponents - fluent-hc - ${httpclient.version} - - - commons-logging - commons-logging - - - - - org.apache.httpcomponents - httpmime - ${httpclient.version} - - - org.apache.httpcomponents - httpasyncclient - ${httpasyncclient.version} - - - commons-logging - commons-logging - - - org.apache.httpcomponents.core5 httpcore5 @@ -115,12 +76,8 @@ - - 4.1.4 - 5.6.1 2.5.1 - 4.5.8 5.2 5.2 diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java index 69eedc8e48..627ac2bd31 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientMultipartLiveTest.java @@ -4,10 +4,10 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.apache.hc.core5.http.ParseException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.entity.mime.FileBody; import org.apache.hc.client5.http.entity.mime.HttpMultipartMode; @@ -19,6 +19,7 @@ import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.HttpStatus; +import org.apache.hc.core5.http.ParseException; import java.io.BufferedReader; import java.io.File; @@ -30,9 +31,6 @@ import java.net.URL; class HttpClientMultipartLiveTest extends GetRequestMockServer { - // No longer available - // private static final String SERVER = "http://echo.200please.com"; - private static final String SERVER = "http://localhost:8080/spring-mvc-java/stub/multipart"; private static final String TEXTFILENAME = "temp.txt"; private static final String IMAGEFILENAME = "image.jpg"; diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientRedirectLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientRedirectLiveTest.java index 04fad84333..560eb0c8ef 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientRedirectLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpClientRedirectLiveTest.java @@ -1,15 +1,16 @@ package com.baeldung.httpclient; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +import org.junit.jupiter.api.Test; + import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.impl.DefaultRedirectStrategy; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; import org.apache.hc.client5.http.impl.classic.HttpClients; -import org.junit.jupiter.api.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; import java.io.IOException; 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 3f2c1328e8..3ac3ee88be 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 @@ -8,7 +8,7 @@ import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.IOException; @@ -29,21 +29,34 @@ import org.apache.hc.core5.http.HttpHeaders; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.HttpResponse; import org.apache.hc.core5.http.io.entity.StringEntity; -import org.junit.Rule; -import org.junit.Test; -import com.github.tomakehurst.wiremock.junit.WireMockRule; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class HttpClientAdvancedConfigurationIntegrationTest { +import com.github.tomakehurst.wiremock.WireMockServer; - @Rule - public WireMockRule serviceMock = new WireMockRule(8089); +class HttpClientAdvancedConfigurationIntegrationTest { - @Rule - public WireMockRule proxyMock = new WireMockRule(8090); + public WireMockServer serviceMock; + public WireMockServer proxyMock; + + @BeforeEach + public void before () { + serviceMock = new WireMockServer(8089); + serviceMock.start(); + proxyMock = new WireMockServer(8090); + proxyMock.start(); + } + + @AfterEach + public void after () { + serviceMock.stop(); + proxyMock.stop(); + } @Test - public void givenClientWithCustomUserAgentHeader_whenExecuteRequest_shouldReturn200() throws IOException { + void givenClientWithCustomUserAgentHeader_whenExecuteRequest_shouldReturn200() throws IOException { //given String userAgent = "BaeldungAgent/1.0"; serviceMock.stubFor(get(urlEqualTo("/detail")) @@ -59,11 +72,11 @@ public class HttpClientAdvancedConfigurationIntegrationTest { HttpResponse response = httpClient.execute(httpGet); //then - assertEquals(response.getCode(), 200); + assertEquals(200, response.getCode()); } @Test - public void givenClientThatSendDataInBody_whenSendXmlInBody_shouldReturn200() throws IOException { + void givenClientThatSendDataInBody_whenSendXmlInBody_shouldReturn200() throws IOException { //given String xmlBody = "1"; serviceMock.stubFor(post(urlEqualTo("/person")) @@ -82,12 +95,12 @@ public class HttpClientAdvancedConfigurationIntegrationTest { HttpResponse response = httpClient.execute(httpPost); //then - assertEquals(response.getCode(), 200); + assertEquals(200, response.getCode()); } @Test - public void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { + void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { //given proxyMock.stubFor(get(urlMatching(".*")) .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); @@ -107,7 +120,7 @@ public class HttpClientAdvancedConfigurationIntegrationTest { HttpResponse response = httpclient.execute(httpGet); //then - assertEquals(response.getCode(), 200); + assertEquals(200, response.getCode()); proxyMock.verify(getRequestedFor(urlEqualTo("/private"))); serviceMock.verify(getRequestedFor(urlEqualTo("/private"))); } @@ -151,7 +164,7 @@ public class HttpClientAdvancedConfigurationIntegrationTest { HttpResponse response = httpclient.execute(httpGet, context); //then - assertEquals(response.getCode(), 200); + assertEquals(200, response.getCode()); proxyMock.verify(getRequestedFor(urlEqualTo("/private")).withHeader("Authorization", containing("Basic"))); serviceMock.verify(getRequestedFor(urlEqualTo("/private"))); } diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientBasicPostLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientBasicPostLiveTest.java deleted file mode 100644 index 9d4573084b..0000000000 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientBasicPostLiveTest.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.baeldung.httpclient.base; - -import com.baeldung.httpclient.ResponseUtil; -import org.apache.http.auth.AuthenticationException; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.auth.BasicScheme; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; - -public class HttpClientBasicPostLiveTest { - - private static final String SAMPLE_URL = "http://www.github.com"; - - private CloseableHttpClient instance; - - private CloseableHttpResponse response; - - @Before - public final void before() { - instance = HttpClientBuilder.create().build(); - } - - @After - public final void after() throws IllegalStateException, IOException { - ResponseUtil.closeResponse(response); - } - - // tests - non-GET - - @Test - public final void whenExecutingPostRequest_thenNoExceptions() throws IOException { - instance.execute(new HttpPost(SAMPLE_URL)); - } - - @Test - public final void whenExecutingPostRequestWithBody_thenNoExceptions() throws IOException { - final HttpPost request = new HttpPost(SAMPLE_URL); - request.setEntity(new StringEntity("in the body of the POST")); - instance.execute(request); - } - - @Test - public final void givenAuth_whenExecutingPostRequestWithBody_thenNoExceptions() throws IOException, AuthenticationException { - final HttpPost request = new HttpPost(SAMPLE_URL); - request.setEntity(new StringEntity("in the body of the POST")); - final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("username", "password"); - request.addHeader(new BasicScheme().authenticate(creds, request, null)); - instance.execute(request); - } - -} diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java deleted file mode 100644 index b8bc536918..0000000000 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientLiveTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.baeldung.httpclient.base; - -import com.baeldung.httpclient.ResponseUtil; - -import org.apache.http.Header; -import org.apache.http.HttpHeaders; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.conn.ConnectTimeoutException; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.BasicHttpClientConnectionManager; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; - -import static org.hamcrest.Matchers.emptyArray; -import static org.hamcrest.Matchers.not; -import static org.junit.Assert.assertThat; - -public class HttpClientLiveTest { - - private static final String SAMPLE_URL = "http://www.github.com"; - - private CloseableHttpClient instance; - - private CloseableHttpResponse response; - - @Before - public final void before() { - instance = HttpClientBuilder.create().build(); - } - - @After - public final void after() throws IllegalStateException, IOException { - ResponseUtil.closeResponse(response); - } - - // tests - - @Test(expected = ConnectTimeoutException.class) - public final void givenLowTimeout_whenExecutingRequestWithTimeout_thenException() throws IOException { - final RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(5).setConnectTimeout(5).setSocketTimeout(2).build(); - final HttpGet request = new HttpGet(SAMPLE_URL); - request.setConfig(requestConfig); - response = instance.execute(request); - } - - // tests - configs - - @Test - public final void givenHttpClientIsConfiguredWithCustomConnectionManager_whenExecutingRequest_thenNoExceptions() throws IOException { - instance = HttpClientBuilder.create().setConnectionManager(new BasicHttpClientConnectionManager()).build(); - response = instance.execute(new HttpGet(SAMPLE_URL)); - } - - @Test - public final void givenCustomHeaderIsSet_whenSendingRequest_thenNoExceptions() throws IOException { - final HttpGet request = new HttpGet(SAMPLE_URL); - request.addHeader(HttpHeaders.ACCEPT, "application/xml"); - response = instance.execute(request); - } - - @Test - public final void givenRequestWasSet_whenAnalyzingTheHeadersOfTheResponse_thenCorrect() throws IOException { - response = instance.execute(new HttpGet(SAMPLE_URL)); - - final Header[] headers = response.getHeaders(HttpHeaders.CONTENT_TYPE); - assertThat(headers, not(emptyArray())); - } - -} diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java index 9d5294aa7e..b0c60c0ab1 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/HttpClientConnectionManagementLiveTest.java @@ -1,5 +1,6 @@ package com.baeldung.httpclient.conn; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -34,14 +35,13 @@ import org.apache.hc.core5.pool.PoolStats; import org.apache.hc.core5.util.Args; import org.apache.hc.core5.util.TimeValue; import org.apache.hc.core5.util.Timeout; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class HttpClientConnectionManagementLiveTest { +class HttpClientConnectionManagementLiveTest { // Example 2.1. Getting a Connection Request for a Low Level Connection (HttpClientConnection) @Test - public final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws ExecutionException, InterruptedException, TimeoutException { + final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws ExecutionException, InterruptedException, TimeoutException { BasicHttpClientConnectionManager connMgr = new BasicHttpClientConnectionManager(); HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 443)); final LeaseRequest connRequest = connMgr.lease("some-id", route, null); @@ -51,7 +51,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 3.1. Setting the PoolingHttpClientConnectionManager on a HttpClient @Test - public final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws IOException { + final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws IOException { PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); CloseableHttpClient client = HttpClients.custom() .setConnectionManager(poolingConnManager) @@ -65,7 +65,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 3.2. Using Two HttpClients to Connect to One Target Host Each @Test - public final void whenTwoConnectionsForTwoRequests_thenNoExceptions() throws InterruptedException, IOException { + final void whenTwoConnectionsForTwoRequests_thenNoExceptions() throws InterruptedException, IOException { HttpGet get1 = new HttpGet("https://www.baeldung.com"); HttpGet get2 = new HttpGet("https://www.google.com"); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); @@ -83,8 +83,7 @@ public class HttpClientConnectionManagementLiveTest { thread1.join(); thread2.join(); - Assert.assertTrue(connManager.getTotalStats() - .getLeased() == 0); + assertEquals(0, connManager.getTotalStats().getLeased()); client1.close(); client2.close(); connManager.close(); @@ -92,7 +91,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 4.1. Increasing the Number of Connections that Can be Open and Managed Beyond the default Limits @Test - public final void whenIncreasingConnectionPool_thenNoExceptions() { + final void whenIncreasingConnectionPool_thenNoExceptions() { PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setMaxTotal(5); connManager.setDefaultMaxPerRoute(4); @@ -103,7 +102,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 4.2. Using Threads to Execute Connections @Test - public final void whenExecutingSameRequestsInDifferentThreads_thenExecuteRequest() throws InterruptedException, IOException { + final void whenExecutingSameRequestsInDifferentThreads_thenExecuteRequest() throws InterruptedException, IOException { HttpGet get = new HttpGet("http://www.baeldung.com"); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); CloseableHttpClient client = HttpClients.custom() @@ -133,7 +132,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 5.1. A Custom Keep Alive Strategy @Test - public final void whenCustomizingKeepAliveStrategy_thenNoExceptions() { + final void whenCustomizingKeepAliveStrategy_thenNoExceptions() { final ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() { @Override public TimeValue getKeepAliveDuration(HttpResponse response, HttpContext context) { @@ -162,7 +161,7 @@ public class HttpClientConnectionManagementLiveTest { //Example 6.1. BasicHttpClientConnectionManager Connection Reuse @Test - public final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws InterruptedException, ExecutionException, TimeoutException, IOException, URISyntaxException { + final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws InterruptedException, ExecutionException, TimeoutException, IOException, URISyntaxException { BasicHttpClientConnectionManager connMgr = new BasicHttpClientConnectionManager(); HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 443)); final HttpContext context = new BasicHttpContext(); @@ -184,7 +183,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 6.2. PoolingHttpClientConnectionManager: Re-Using Connections with Threads @Test - public final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException, IOException { + final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException, IOException { HttpGet get = new HttpGet("http://www.baeldung.com"); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setDefaultMaxPerRoute(6); @@ -208,7 +207,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 7.1. Setting Socket Timeout to 5 Seconds @Test - public final void whenConfiguringTimeOut_thenNoExceptions() throws ExecutionException, InterruptedException, TimeoutException, IOException { + final void whenConfiguringTimeOut_thenNoExceptions() throws ExecutionException, InterruptedException, TimeoutException, IOException { final HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80)); final HttpContext context = new BasicHttpContext(); final PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); @@ -227,7 +226,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 8.1. Setting the HttpClient to Check for Stale Connections @Test - public final void whenEvictIdealConn_thenNoExceptions() throws InterruptedException, IOException { + final void whenEvictIdealConn_thenNoExceptions() throws InterruptedException, IOException { final PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setMaxTotal(100); try (final CloseableHttpClient httpclient = HttpClients.custom() @@ -266,7 +265,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 9.1. Closing Connection and Releasing Resources @Test - public final void whenClosingConnectionsandManager_thenCloseWithNoExceptions1() throws IOException { + final void whenClosingConnectionsAndManager_thenCloseWithNoExceptions1() throws IOException { PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); CloseableHttpClient client = HttpClients.custom() .setConnectionManager(connManager) @@ -282,7 +281,7 @@ public class HttpClientConnectionManagementLiveTest { @Test // Example 3.2. TESTER VERSION - public final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException, IOException { + final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException, IOException { HttpGet get1 = new HttpGet("https://www.baeldung.com"); HttpGet get2 = new HttpGet("https://www.google.com"); @@ -300,8 +299,7 @@ public class HttpClientConnectionManagementLiveTest { thread2.start(); thread1.join(); thread2.join(1000); - Assert.assertTrue(poolingConnManager.getTotalStats() - .getLeased() == 2); + assertEquals(2, poolingConnManager.getTotalStats().getLeased()); client1.close(); client2.close(); diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/IdleConnectionMonitorThread.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/IdleConnectionMonitorThread.java deleted file mode 100644 index f1d7cbc427..0000000000 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/IdleConnectionMonitorThread.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.baeldung.httpclient.conn; - -import java.util.concurrent.TimeUnit; - -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; - -public class IdleConnectionMonitorThread extends Thread { - private final HttpClientConnectionManager connMgr; - private volatile boolean shutdown; - - IdleConnectionMonitorThread(final PoolingHttpClientConnectionManager connMgr) { - super(); - this.connMgr = connMgr; - } - - // API - - @Override - public final void run() { - try { - while (!shutdown) { - synchronized (this) { - wait(1000); - connMgr.closeExpiredConnections(); - connMgr.closeIdleConnections(30, TimeUnit.SECONDS); - } - } - } catch (final InterruptedException ex) { - shutdown(); - } - } - - private void shutdown() { - shutdown = true; - synchronized (this) { - notifyAll(); - } - } - -} diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/MultiHttpClientConnThread.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/MultiHttpClientConnThread.java index 16bb49123a..9e4b770828 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/MultiHttpClientConnThread.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/conn/MultiHttpClientConnThread.java @@ -6,7 +6,6 @@ import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.core5.http.HttpEntity; -import org.apache.hc.core5.http.HttpResponse; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/apache-httpclient4/pom.xml b/apache-httpclient4/pom.xml index 21c675db35..f4c213687e 100644 --- a/apache-httpclient4/pom.xml +++ b/apache-httpclient4/pom.xml @@ -241,8 +241,6 @@ 4.4.16 4.5.14 5.11.2 - - 3.3.2 \ No newline at end of file diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientSandboxLiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/client/HttpClientSandboxLiveTest.java similarity index 82% rename from apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientSandboxLiveTest.java rename to apache-httpclient4/src/test/java/com/baeldung/client/HttpClientSandboxLiveTest.java index f72aa0c878..c15d8953f2 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/base/HttpClientSandboxLiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/client/HttpClientSandboxLiveTest.java @@ -1,7 +1,7 @@ -package com.baeldung.httpclient.base; +package com.baeldung.client; + +import java.io.IOException; -import com.baeldung.httpclient.GetRequestMockServer; -import com.baeldung.httpclient.ResponseUtil; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; @@ -12,15 +12,16 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.junit.jupiter.api.Test; -import java.io.IOException; +import com.baeldung.GetRequestMockServer; +import com.baeldung.httpclient.ResponseUtil; /* * NOTE : Need module spring-security-rest-basic-auth to be running */ -public class HttpClientSandboxLiveTest extends GetRequestMockServer { +class HttpClientSandboxLiveTest extends GetRequestMockServer { @Test - public final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws IOException { + final void givenGetRequestExecuted_whenAnalyzingTheResponse_thenCorrectStatusCode() throws IOException { final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); final AuthScope authscp = new AuthScope("localhost", 8080); credentialsProvider.setCredentials(authscp, new UsernamePasswordCredentials("user1", "user1Pass")); diff --git a/apache-httpclient4/src/test/java/com/baeldung/client/RestClientV4LiveManualTest.java b/apache-httpclient4/src/test/java/com/baeldung/client/RestClientV4LiveManualTest.java index 3c0f5b7c63..98c6a0b4a7 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/client/RestClientV4LiveManualTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/client/RestClientV4LiveManualTest.java @@ -35,7 +35,7 @@ import org.springframework.web.client.RestTemplate; * This test requires a localhost server over HTTPS
* It should only be manually run, not part of the automated build * */ -public class RestClientV4LiveManualTest { +class RestClientV4LiveManualTest { final String urlOverHttps = "http://localhost:8082/httpclient-simple/api/bars/1"; @@ -81,7 +81,7 @@ public class RestClientV4LiveManualTest { } @Test - public void whenHttpsUrlIsConsumed_thenException() throws ClientProtocolException, IOException { + void whenHttpsUrlIsConsumed_thenException() throws ClientProtocolException, IOException { CloseableHttpClient httpClient = HttpClients.createDefault(); String urlOverHttps = "https://localhost:8082/httpclient-simple"; HttpGet getMethod = new HttpGet(urlOverHttps); diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/ClientUtil.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/ClientUtil.java index ce8a869e97..0b0d7104d7 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/ClientUtil.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/ClientUtil.java @@ -2,8 +2,6 @@ package com.baeldung.httpclient; import java.io.IOException; -import org.apache.http.HttpEntity; -import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.impl.client.CloseableHttpClient; public final class ClientUtil { diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpAsyncClientV4LiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpAsyncClientV4LiveTest.java index 80b16d7f07..90b64092e0 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpAsyncClientV4LiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpAsyncClientV4LiveTest.java @@ -1,4 +1,5 @@ package com.baeldung.httpclient; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestV4LiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestV4LiveTest.java index 446c47c200..6a8a66e87b 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestV4LiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCancelRequestV4LiveTest.java @@ -9,11 +9,11 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -public class HttpClientCancelRequestV4LiveTest { +class HttpClientCancelRequestV4LiveTest { private static final String SAMPLE_URL = "http://www.github.com"; @@ -21,18 +21,18 @@ public class HttpClientCancelRequestV4LiveTest { private CloseableHttpResponse response; - @Before + @BeforeEach public final void before() { instance = HttpClientBuilder.create().build(); } - @After + @AfterEach public final void after() throws IllegalStateException, IOException { ResponseUtil.closeResponse(response); } @Test - public final void whenRequestIsCanceled_thenCorrect() throws IOException { + final void whenRequestIsCanceled_thenCorrect() throws IOException { instance = HttpClients.custom().build(); final HttpGet request = new HttpGet(SAMPLE_URL); response = instance.execute(request); diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCookBookV4LiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCookBookV4LiveTest.java index 8b83419ba1..ba77a5c7dd 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCookBookV4LiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientCookBookV4LiveTest.java @@ -1,5 +1,9 @@ package com.baeldung.httpclient; +import org.apache.http.auth.AuthenticationException; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.auth.BasicScheme; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -181,4 +185,20 @@ class HttpClientCookBookV4LiveTest { } } + @Test + final void whenExecutingPostRequestWithBody_thenNoExceptions() throws IOException { + final HttpPost request = new HttpPost(SAMPLE_POST_URL); + request.setEntity(new StringEntity("in the body of the POST")); + client.execute(request); + } + + @Test + final void givenAuth_whenExecutingPostRequestWithBody_thenNoExceptions() throws IOException, AuthenticationException { + final HttpPost request = new HttpPost(SAMPLE_POST_URL); + request.setEntity(new StringEntity("in the body of the POST")); + final UsernamePasswordCredentials creds = new UsernamePasswordCredentials("username", "password"); + request.addHeader(new BasicScheme().authenticate(creds, request, null)); + client.execute(request); + } + } diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientRedirectV4LiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientRedirectV4LiveTest.java index f6d65a8d8f..a3f9f3eb47 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientRedirectV4LiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientRedirectV4LiveTest.java @@ -1,12 +1,12 @@ package com.baeldung.httpclient; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; - import java.io.IOException; import org.apache.http.client.methods.CloseableHttpResponse; diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientTimeoutV4LiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientTimeoutV4LiveTest.java index ed22913ddd..5b3ced8b98 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientTimeoutV4LiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpClientTimeoutV4LiveTest.java @@ -92,6 +92,26 @@ class HttpClientTimeoutV4LiveTest extends GetRequestMockServer { } + @Test + final void givenLowTimeout_whenExecutingRequestWithTimeout_thenException() { + final RequestConfig requestConfig = RequestConfig.custom() + .setConnectionRequestTimeout(5) + .setConnectTimeout(5) + .setSocketTimeout(2) + .build(); + + final CloseableHttpClient client = HttpClientBuilder.create() + .setDefaultRequestConfig(requestConfig) + .build(); + + final HttpGet request = new HttpGet("http://www.github.com"); + + assertThrows(ConnectTimeoutException.class, () -> { + response = client.execute(request); + }); + } + + @Test void whenSecuredRestApiIsConsumed_then200OK() throws IOException { CloseableHttpClient httpClient = HttpClientBuilder.create().build(); 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 2235d0e9d0..5ced756644 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 @@ -1,7 +1,7 @@ package com.baeldung.httpclient.advancedconfig; +import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.junit.WireMockRule; import org.apache.http.HttpHeaders; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; @@ -19,8 +19,10 @@ import org.apache.http.impl.client.BasicAuthCache; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.DefaultProxyRoutePlanner; -import org.junit.Rule; -import org.junit.Test; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.io.IOException; @@ -32,18 +34,29 @@ import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; -public class HttpClientAdvancedConfigurationIntegrationTest { +class HttpClientAdvancedConfigurationIntegrationTest { - @Rule - public WireMockRule serviceMock = new WireMockRule(8089); + public WireMockServer serviceMock; + public WireMockServer proxyMock; - @Rule - public WireMockRule proxyMock = new WireMockRule(8090); + @BeforeEach + public void before () { + serviceMock = new WireMockServer(8089); + serviceMock.start(); + proxyMock = new WireMockServer(8090); + proxyMock.start(); + } + + @AfterEach + public void after () { + serviceMock.stop(); + proxyMock.stop(); + } @Test - public void givenClientWithCustomUserAgentHeader_whenExecuteRequest_shouldReturn200() throws IOException { + void givenClientWithCustomUserAgentHeader_whenExecuteRequest_shouldReturn200() throws IOException { //given String userAgent = "BaeldungAgent/1.0"; serviceMock.stubFor(get(urlEqualTo("/detail")) @@ -59,11 +72,11 @@ public class HttpClientAdvancedConfigurationIntegrationTest { HttpResponse response = httpClient.execute(httpGet); //then - assertEquals(response.getStatusLine().getStatusCode(), 200); + assertEquals(200, response.getStatusLine().getStatusCode()); } @Test - public void givenClientThatSendDataInBody_whenSendXmlInBody_shouldReturn200() throws IOException { + void givenClientThatSendDataInBody_whenSendXmlInBody_shouldReturn200() throws IOException { //given String xmlBody = "1"; serviceMock.stubFor(post(urlEqualTo("/person")) @@ -82,12 +95,11 @@ public class HttpClientAdvancedConfigurationIntegrationTest { HttpResponse response = httpClient.execute(httpPost); //then - assertEquals(response.getStatusLine().getStatusCode(), 200); - + assertEquals(200, response.getStatusLine().getStatusCode()); } @Test - public void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { + void givenServerThatIsBehindProxy_whenClientIsConfiguredToSendRequestViaProxy_shouldReturn200() throws IOException { //given proxyMock.stubFor(get(urlMatching(".*")) .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); @@ -107,13 +119,13 @@ public class HttpClientAdvancedConfigurationIntegrationTest { HttpResponse response = httpclient.execute(httpGet); //then - assertEquals(response.getStatusLine().getStatusCode(), 200); + assertEquals(200, response.getStatusLine().getStatusCode()); proxyMock.verify(getRequestedFor(urlEqualTo("/private"))); serviceMock.verify(getRequestedFor(urlEqualTo("/private"))); } @Test - public void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException { + void givenServerThatIsBehindAuthorizationProxy_whenClientSendRequest_shouldAuthorizeProperly() throws IOException { //given proxyMock.stubFor(get(urlMatching("/private")) .willReturn(aResponse().proxiedFrom("http://localhost:8089/"))); @@ -152,7 +164,7 @@ public class HttpClientAdvancedConfigurationIntegrationTest { HttpResponse response = httpclient.execute(httpGet, context); //then - assertEquals(response.getStatusLine().getStatusCode(), 200); + assertEquals(200, response.getStatusLine().getStatusCode()); proxyMock.verify(getRequestedFor(urlEqualTo("/private")).withHeader("Authorization", containing("Basic"))); serviceMock.verify(getRequestedFor(urlEqualTo("/private"))); } diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/expandurl/HttpClientExpandUrlLiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/expandurl/HttpClientExpandUrlLiveTest.java index 5a8c87f4aa..c1b04c6728 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/expandurl/HttpClientExpandUrlLiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/expandurl/HttpClientExpandUrlLiveTest.java @@ -12,34 +12,35 @@ import org.apache.http.client.methods.HttpHead; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.util.EntityUtils; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertThat; -public class HttpClientExpandUrlLiveTest { + +class HttpClientExpandUrlLiveTest { private CloseableHttpClient client; - @Before - public final void before() { + @BeforeEach + public final void beforeEach() { client = HttpClientBuilder.create().disableRedirectHandling().build(); } @Test - public final void givenShortenedOnce_whenUrlIsExpanded_thenCorrectResult() throws IOException { + final void givenShortenedOnce_whenUrlIsExpanded_thenCorrectResult() throws IOException { final String expectedResult = "https://www.baeldung.com/rest-versioning"; final String actualResult = expandSingleLevel("http://bit.ly/3LScTri"); assertThat(actualResult, equalTo(expectedResult)); } @Test - public final void givenShortenedMultiple_whenUrlIsExpanded_thenCorrectResult() throws IOException { + final void givenShortenedMultiple_whenUrlIsExpanded_thenCorrectResult() throws IOException { final String expectedResult = "https://www.baeldung.com/rest-versioning"; final String actualResult = expand("http://t.co/e4rDDbnzmk"); assertThat(actualResult, equalTo(expectedResult)); diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/ApacheHttpClientUnitTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/ApacheHttpClientUnitTest.java index 9a7a734b65..a7948bcf64 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/ApacheHttpClientUnitTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/ApacheHttpClientUnitTest.java @@ -17,7 +17,6 @@ import com.baeldung.GetRequestMockServer; class ApacheHttpClientUnitTest extends GetRequestMockServer { - @Test void givenDeveloperUsedCloseableHttpResponse_whenExecutingGetRequest_thenStatusIsOk() throws IOException { try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) { diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/HttpClientConnectionManagementLiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/HttpClientConnectionManagementLiveTest.java index c894d72af0..c207aadd28 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/HttpClientConnectionManagementLiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/HttpClientConnectionManagementLiveTest.java @@ -1,7 +1,9 @@ package com.baeldung.httpclient.httpclient.conn; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; import java.util.concurrent.ExecutionException; @@ -24,6 +26,7 @@ import org.apache.http.conn.ConnectionPoolTimeoutException; import org.apache.http.conn.ConnectionRequest; import org.apache.http.conn.routing.HttpRoute; import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; @@ -33,14 +36,14 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpCoreContext; import org.apache.http.protocol.HttpRequestExecutor; import org.apache.http.util.EntityUtils; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; -public class HttpClientConnectionManagementLiveTest { +class HttpClientConnectionManagementLiveTest { // Example 2.1. Getting a Connection Request for a Low Level Connection (HttpClientConnection) @Test - public final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws ConnectionPoolTimeoutException, InterruptedException, ExecutionException { + final void whenLowLevelConnectionIsEstablished_thenNoExceptions() throws ConnectionPoolTimeoutException, InterruptedException, ExecutionException { try (BasicHttpClientConnectionManager connManager = new BasicHttpClientConnectionManager()) { HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80)); final ConnectionRequest connRequest = connManager.requestConnection(route, null); @@ -50,20 +53,20 @@ public class HttpClientConnectionManagementLiveTest { // Example 3.1. Setting the PoolingHttpClientConnectionManager on a HttpClient @Test - public final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws ClientProtocolException, IOException { + final void whenPollingConnectionManagerIsConfiguredOnHttpClient_thenNoExceptions() throws ClientProtocolException, IOException { PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); CloseableHttpClient client = HttpClients.custom() .setConnectionManager(poolingConnManager) .build(); client.execute(new HttpGet("https://www.baeldung.com")); - assertTrue(poolingConnManager.getTotalStats() - .getLeased() == 1); + assertEquals(1, poolingConnManager.getTotalStats() + .getLeased()); } // Example 3.2. Using Two HttpClients to Connect to One Target Host Each @Test - public final void whenTwoConnectionsForTwoRequests_thenNoExceptions() throws InterruptedException { + final void whenTwoConnectionsForTwoRequests_thenNoExceptions() throws InterruptedException { HttpGet get1 = new HttpGet("https://www.baeldung.com"); HttpGet get2 = new HttpGet("https://www.google.com"); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); @@ -81,13 +84,13 @@ public class HttpClientConnectionManagementLiveTest { thread1.join(); thread2.join(); - assertTrue(connManager.getTotalStats() - .getLeased() == 0); + assertEquals(0, connManager.getTotalStats() + .getLeased()); } // Example 4.1. Increasing the Number of Connections that Can be Open and Managed Beyond the default Limits @Test - public final void whenIncreasingConnectionPool_thenNoEceptions() { + final void whenIncreasingConnectionPool_thenNoEceptions() { try (PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager()) { connManager.setMaxTotal(5); connManager.setDefaultMaxPerRoute(4); @@ -98,7 +101,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 4.2. Using Threads to Execute Connections @Test - public final void whenExecutingSameRequestsInDifferentThreads_thenExecuteReuqest() throws InterruptedException { + final void whenExecutingSameRequestsInDifferentThreads_thenExecuteReuqest() throws InterruptedException { HttpGet get = new HttpGet("http://www.baeldung.com"); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); CloseableHttpClient client = HttpClients.custom() @@ -117,7 +120,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 5.1. A Custom Keep Alive Strategy @Test - public final void whenCustomizingKeepAliveStrategy_thenNoExceptions() { + final void whenCustomizingKeepAliveStrategy_thenNoExceptions() { final ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() { @Override public long getKeepAliveDuration(final HttpResponse myResponse, final HttpContext myContext) { @@ -148,7 +151,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 6.1. BasicHttpClientConnectionManager Connection Reuse @Test - public final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws IOException, HttpException, InterruptedException, ExecutionException { + final void givenBasicHttpClientConnManager_whenConnectionReuse_thenNoExceptions() throws IOException, HttpException, InterruptedException, ExecutionException { BasicHttpClientConnectionManager basicConnManager = new BasicHttpClientConnectionManager(); HttpClientContext context = HttpClientContext.create(); @@ -175,7 +178,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 6.2. PoolingHttpClientConnectionManager: Re-Using Connections with Threads @Test - public final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException { + final void whenConnectionsNeededGreaterThanMaxTotal_thenLeaseMasTotalandReuse() throws InterruptedException { HttpGet get = new HttpGet("http://echo.200please.com"); PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); connManager.setDefaultMaxPerRoute(5); @@ -197,20 +200,20 @@ public class HttpClientConnectionManagementLiveTest { // Example 7.1. Setting Socket Timeout to 5 Seconds @Test - public final void whenConfiguringTimeOut_thenNoExceptions() { + final void whenConfiguringTimeOut_thenNoExceptions() { HttpRoute route = new HttpRoute(new HttpHost("www.baeldung.com", 80)); try (PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager()) { connManager.setSocketConfig(route.getTargetHost(), SocketConfig.custom() .setSoTimeout(5000) .build()); - assertTrue(connManager.getSocketConfig(route.getTargetHost()) - .getSoTimeout() == 5000); + assertEquals(5000, connManager.getSocketConfig(route.getTargetHost()) + .getSoTimeout()); } } // Example 8.1. Setting the HttpClient to Check for Stale Connections @Test - public final void whenHttpClientChecksStaleConns_thenNoExceptions() { + final void whenHttpClientChecksStaleConns_thenNoExceptions() { PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); HttpClients.custom() .setDefaultRequestConfig(RequestConfig.custom() @@ -222,7 +225,7 @@ public class HttpClientConnectionManagementLiveTest { // Example 8.2. Using a Stale Connection Monitor Thread @Test - public final void whenCustomizedIdleConnMonitor_thenNoExceptions() throws InterruptedException { + final void whenCustomizedIdleConnMonitor_thenNoExceptions() throws InterruptedException { PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); HttpClients.custom() .setConnectionManager(connManager) @@ -233,8 +236,8 @@ public class HttpClientConnectionManagementLiveTest { } // Example 9.1. Closing Connection and Releasing Resources - @Test(expected = IllegalStateException.class) - public final void whenClosingConnectionsandManager_thenCloseWithNoExceptions1() throws InterruptedException, ExecutionException, IOException, HttpException { + @Test + final void whenClosingConnectionsAndManager_thenCloseWithNoExceptions1() throws IOException { PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(); CloseableHttpClient client = HttpClients.custom() .setConnectionManager(connManager) @@ -248,14 +251,14 @@ public class HttpClientConnectionManagementLiveTest { connManager.close(); connManager.shutdown(); - client.execute(get); - - assertTrue(response.getEntity() == null); + assertThrows(IllegalStateException.class, () -> { + client.execute(get); + }); } @Test // Example 3.2. TESTER VERSION - public final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException { + final void whenTwoConnectionsForTwoRequests_thenTwoConnectionsAreLeased() throws InterruptedException { HttpGet get1 = new HttpGet("https://www.baeldung.com"); HttpGet get2 = new HttpGet("https://www.google.com"); @@ -273,13 +276,13 @@ public class HttpClientConnectionManagementLiveTest { thread2.start(); thread1.join(); thread2.join(1000); - assertTrue(poolingConnManager.getTotalStats() - .getLeased() == 2); + assertEquals(2, poolingConnManager.getTotalStats() + .getLeased()); } @Test // Example 4.2 Tester Version - public final void whenExecutingSameRequestsInDifferentThreads_thenUseDefaultConnLimit() throws InterruptedException { + final void whenExecutingSameRequestsInDifferentThreads_thenUseDefaultConnLimit() throws InterruptedException { PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); CloseableHttpClient client = HttpClients.custom() .setConnectionManager(poolingConnManager) @@ -297,7 +300,7 @@ public class HttpClientConnectionManagementLiveTest { @Test // 6.2 TESTER VERSION - public final void whenConnectionsNeededGreaterThanMaxTotal_thenReuseConnections() throws InterruptedException { + final void whenConnectionsNeededGreaterThanMaxTotal_thenReuseConnections() throws InterruptedException { PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); poolingConnManager.setDefaultMaxPerRoute(5); poolingConnManager.setMaxTotal(5); @@ -316,15 +319,15 @@ public class HttpClientConnectionManagementLiveTest { thread.join(10000); countConnMade++; if (countConnMade == 0) { - assertTrue(thread.getLeasedConn() == 5); + assertEquals(5, thread.getLeasedConn()); } } } @Test - @Ignore("Very Long Running") + @Disabled("Very Long Running") // 8.2 TESTER VERSION - public final void whenCustomizedIdleConnMonitor_thenEliminateIdleConns() throws InterruptedException { + final void whenCustomizedIdleConnMonitor_thenEliminateIdleConns() throws InterruptedException { PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager(); CloseableHttpClient client = HttpClients.custom() .setConnectionManager(poolingConnManager) @@ -340,10 +343,10 @@ public class HttpClientConnectionManagementLiveTest { thread2.start(); thread2.join(); thread3.start(); - assertTrue(poolingConnManager.getTotalStats() - .getAvailable() == 1); + assertEquals(1, poolingConnManager.getTotalStats() + .getAvailable()); thread3.join(32000); - assertTrue(poolingConnManager.getTotalStats() - .getAvailable() == 0); + assertEquals(0, poolingConnManager.getTotalStats() + .getAvailable()); } } diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/MultiHttpClientConnThread.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/MultiHttpClientConnThread.java index 4183094621..b09a06050b 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/MultiHttpClientConnThread.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/MultiHttpClientConnThread.java @@ -3,7 +3,6 @@ package com.baeldung.httpclient.httpclient.conn; import java.io.IOException; import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/TesterVersion_MultiHttpClientConnThread.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/TesterVersion_MultiHttpClientConnThread.java index 5e2710342d..cd4979541e 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/TesterVersion_MultiHttpClientConnThread.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/httpclient/conn/TesterVersion_MultiHttpClientConnThread.java @@ -2,7 +2,6 @@ package com.baeldung.httpclient.httpclient.conn; import java.io.IOException; -import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClientUnitTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClientUnitTest.java index 4d88211d0d..a47a5cc743 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClientUnitTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/readresponsebodystring/ApacheHttpClientUnitTest.java @@ -6,18 +6,19 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; -import org.junit.Test; + +import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; -public class ApacheHttpClientUnitTest { +class ApacheHttpClientUnitTest { private final Logger logger = LoggerFactory.getLogger(this.getClass()); public static final String DUMMY_URL = "https://postman-echo.com/get"; @Test - public void whenUseApacheHttpClient_thenCorrect() throws IOException { + void whenUseApacheHttpClient_thenCorrect() throws IOException { HttpGet request = new HttpGet(DUMMY_URL); try (CloseableHttpClient client = HttpClients.createDefault(); CloseableHttpResponse response = client.execute(request)) { diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/retry/ApacheHttpClientRetryLiveTest.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/retry/ApacheHttpClientRetryLiveTest.java index 3a8ff252c2..f04ebff3f8 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/retry/ApacheHttpClientRetryLiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/retry/ApacheHttpClientRetryLiveTest.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class ApacheHttpClientRetryLiveTest { +class ApacheHttpClientRetryLiveTest { private Integer requestCounter; private CloseableHttpClient httpClient; @@ -93,14 +93,14 @@ public class ApacheHttpClientRetryLiveTest { } @Test - public void givenDefaultConfiguration_whenReceivedIOException_thenRetriesPerformed() { + void givenDefaultConfiguration_whenReceivedIOException_thenRetriesPerformed() { createFailingHttpClient(); assertThrows(IOException.class, () -> httpClient.execute(new HttpGet("https://httpstat.us/200"))); assertThat(requestCounter).isEqualTo(4); } @Test - public void givenDefaultConfiguration_whenDomainNameNotResolved_thenNoRetryApplied() { + void givenDefaultConfiguration_whenDomainNameNotResolved_thenNoRetryApplied() { createDefaultApacheHttpClient(); HttpGet request = new HttpGet(URI.create("http://domain.that.does.not.exist:80/api/v1")); @@ -109,7 +109,7 @@ public class ApacheHttpClientRetryLiveTest { } @Test - public void givenDefaultConfiguration_whenGotInternalServerError_thenNoRetryLogicApplied() throws IOException { + void givenDefaultConfiguration_whenGotInternalServerError_thenNoRetryLogicApplied() throws IOException { createDefaultApacheHttpClient(); HttpGet request = new HttpGet(URI.create("https://httpstat.us/500")); @@ -120,7 +120,7 @@ public class ApacheHttpClientRetryLiveTest { } @Test - public void givenDefaultConfiguration_whenHttpPatchRequest_thenRetryIsNotApplied() { + void givenDefaultConfiguration_whenHttpPatchRequest_thenRetryIsNotApplied() { createFailingHttpClient(); HttpPatch request = new HttpPatch(URI.create("https://httpstat.us/500")); @@ -129,7 +129,7 @@ public class ApacheHttpClientRetryLiveTest { } @Test - public void givenDefaultConfiguration_whenHttpPutRequest_thenRetryIsNotApplied() { + void givenDefaultConfiguration_whenHttpPutRequest_thenRetryIsNotApplied() { createFailingHttpClient(); HttpPut request = new HttpPut(URI.create("https://httpstat.us/500")); @@ -138,7 +138,7 @@ public class ApacheHttpClientRetryLiveTest { } @Test - public void givenConfiguredRetryHandler_whenHttpPostRequest_thenRetriesPerformed() { + void givenConfiguredRetryHandler_whenHttpPostRequest_thenRetriesPerformed() { createHttpClientWithRetryHandler(); HttpPost request = new HttpPost(URI.create("https://httpstat.us/200")); @@ -148,7 +148,7 @@ public class ApacheHttpClientRetryLiveTest { } @Test - public void givenCustomRetryHandler_whenUnknownHostException_thenRetryAnyway() { + void givenCustomRetryHandler_whenUnknownHostException_thenRetryAnyway() { createHttpClientWithCustomRetryHandler(); HttpGet request = new HttpGet(URI.create("https://domain.that.does.not.exist/200")); @@ -158,7 +158,7 @@ public class ApacheHttpClientRetryLiveTest { } @Test - public void givenDisabledRetries_whenExecutedHttpRequestEndUpWithIOException_thenRetryIsNotApplied() { + void givenDisabledRetries_whenExecutedHttpRequestEndUpWithIOException_thenRetryIsNotApplied() { createHttpClientWithRetriesDisabled(); HttpGet request = new HttpGet(URI.create("https://httpstat.us/200")); diff --git a/apache-libraries-2/README.md b/apache-libraries-2/README.md index e69de29bb2..cc910c5c2c 100644 --- a/apache-libraries-2/README.md +++ b/apache-libraries-2/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Understanding XSLT Processing in Java](https://www.baeldung.com/java-extensible-stylesheet-language-transformations) diff --git a/apache-libraries-2/pom.xml b/apache-libraries-2/pom.xml index 618ff4a188..d188204208 100644 --- a/apache-libraries-2/pom.xml +++ b/apache-libraries-2/pom.xml @@ -21,7 +21,6 @@
- 2.0.1.Final diff --git a/apache-libraries-2/src/main/java/com/baeldung/xsltProcessing/XSLTProcessorWithParametersAndOption.java b/apache-libraries-2/src/main/java/com/baeldung/xsltProcessing/XSLTProcessorWithParametersAndOption.java new file mode 100644 index 0000000000..07efab080d --- /dev/null +++ b/apache-libraries-2/src/main/java/com/baeldung/xsltProcessing/XSLTProcessorWithParametersAndOption.java @@ -0,0 +1,31 @@ +package com.baeldung.xsltProcessing; + +import javax.xml.transform.*; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.File; + +public class XSLTProcessorWithParametersAndOption { + public static void transformXMLWithParametersAndOption( + String inputXMLPath, + String xsltPath, + String outputHTMLPath, + String companyName, + boolean enableIndentation + ) throws TransformerException { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Source xsltSource = new StreamSource(new File(xsltPath)); + Transformer transformer = transformerFactory.newTransformer(xsltSource); + + transformer.setParameter("companyName", companyName); + + if (enableIndentation) { + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + } + + Source xmlSource = new StreamSource(new File(inputXMLPath)); + Result outputResult = new StreamResult(new File(outputHTMLPath)); + + transformer.transform(xmlSource, outputResult); + } +} diff --git a/apache-libraries-2/src/main/java/com/baeldung/xsltProcessing/XSLTProcessorWithTemplate.java b/apache-libraries-2/src/main/java/com/baeldung/xsltProcessing/XSLTProcessorWithTemplate.java new file mode 100644 index 0000000000..017fc0db8b --- /dev/null +++ b/apache-libraries-2/src/main/java/com/baeldung/xsltProcessing/XSLTProcessorWithTemplate.java @@ -0,0 +1,21 @@ +package com.baeldung.xsltProcessing; + +import javax.xml.transform.*; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.File; + +public class XSLTProcessorWithTemplate { + public static void transformXMLUsingTemplate(String inputXMLPath, String xsltPath, String outputHTMLPath) throws TransformerException { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Source xsltSource = new StreamSource(new File(xsltPath)); + Templates templates = transformerFactory.newTemplates(xsltSource); + + Transformer transformer = templates.newTransformer(); + + Source xmlSource = new StreamSource(new File(inputXMLPath)); + Result outputResult = new StreamResult(new File(outputHTMLPath)); + + transformer.transform(xmlSource, outputResult); + } +} diff --git a/apache-velocity/pom.xml b/apache-velocity/pom.xml index a562ebeec0..f4b6de8872 100644 --- a/apache-velocity/pom.xml +++ b/apache-velocity/pom.xml @@ -63,7 +63,6 @@ 4.5.2 1.7 2.0 - 3.3.2 \ No newline at end of file diff --git a/asm/pom.xml b/asm/pom.xml index f1e60d2560..4edfe86ae5 100644 --- a/asm/pom.xml +++ b/asm/pom.xml @@ -49,7 +49,6 @@ 5.2 - 2.4 \ No newline at end of file diff --git a/aws-modules/aws-s3-update-object/pom.xml b/aws-modules/aws-s3-update-object/pom.xml index 574a63977b..3cf7b657b0 100644 --- a/aws-modules/aws-s3-update-object/pom.xml +++ b/aws-modules/aws-s3-update-object/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 aws-s3-update-object 0.0.1-SNAPSHOT diff --git a/aws-modules/aws-s3/README.md b/aws-modules/aws-s3/README.md index 3389fdf454..cb039b7c61 100644 --- a/aws-modules/aws-s3/README.md +++ b/aws-modules/aws-s3/README.md @@ -8,4 +8,6 @@ This module contains articles about Simple Storage Service (S3) on AWS - [Multipart Uploads in Amazon S3 with Java](https://www.baeldung.com/aws-s3-multipart-upload) - [Using the JetS3t Java Client With Amazon S3](https://www.baeldung.com/jets3t-amazon-s3) - [Check if a Specified Key Exists in a Given S3 Bucket Using Java](https://www.baeldung.com/java-aws-s3-check-specified-key-exists) -- [Listing All AWS S3 Objects in a Bucket Using Java](https://www.baeldung.com/java-aws-s3-list-bucket-objects) \ No newline at end of file +- [Listing All AWS S3 Objects in a Bucket Using Java](https://www.baeldung.com/java-aws-s3-list-bucket-objects) +- [Update an Existing Amazon S3 Object Using Java](https://www.baeldung.com/java-update-amazon-s3-object) +- [How To Rename Files and Folders in Amazon S3](https://www.baeldung.com/java-amazon-s3-rename-files-folders) diff --git a/aws-modules/aws-s3/pom.xml b/aws-modules/aws-s3/pom.xml index 157aeb671d..e2bc04964a 100644 --- a/aws-modules/aws-s3/pom.xml +++ b/aws-modules/aws-s3/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 aws-s3 0.1.0-SNAPSHOT diff --git a/aws-modules/aws-s3/src/main/java/com/baeldung/s3/RenameObjectService.java b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/RenameObjectService.java new file mode 100644 index 0000000000..0ca586c73b --- /dev/null +++ b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/RenameObjectService.java @@ -0,0 +1,79 @@ +package com.baeldung.s3; + +import java.util.List; + +import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.CopyObjectRequest; +import software.amazon.awssdk.services.s3.model.DeleteObjectRequest; +import software.amazon.awssdk.services.s3.model.ListObjectsV2Request; +import software.amazon.awssdk.services.s3.model.ListObjectsV2Response; +import software.amazon.awssdk.services.s3.model.S3Object; + +public class RenameObjectService { + + private S3Client s3Client; + + public RenameObjectService(S3Client s3Client) { + this.s3Client = s3Client; + } + + public RenameObjectService() { + init(); + } + + public void init() { + this.s3Client = S3Client.builder() + .region(Region.US_EAST_1) + .credentialsProvider(ProfileCredentialsProvider.create("default")) + .build(); + } + + public void renameFile(String bucketName, String keyName, String destinationKeyName) { + CopyObjectRequest copyObjRequest = CopyObjectRequest.builder() + .sourceBucket(bucketName) + .sourceKey(keyName) + .destinationBucket(destinationKeyName) + .destinationKey(bucketName) + .build(); + s3Client.copyObject(copyObjRequest); + DeleteObjectRequest deleteRequest = DeleteObjectRequest.builder() + .bucket(bucketName) + .key(keyName) + .build(); + s3Client.deleteObject(deleteRequest); + } + + public void renameFolder(String bucketName, String sourceFolderKey, String destinationFolderKey) { + ListObjectsV2Request listRequest = ListObjectsV2Request.builder() + .bucket(bucketName) + .prefix(sourceFolderKey) + .build(); + + ListObjectsV2Response listResponse = s3Client.listObjectsV2(listRequest); + List objects = listResponse.contents(); + + for (S3Object s3Object : objects) { + String newKey = destinationFolderKey + s3Object.key() + .substring(sourceFolderKey.length()); + + // Copy object to destination folder + CopyObjectRequest copyRequest = CopyObjectRequest.builder() + .sourceBucket(bucketName) + .sourceKey(s3Object.key()) + .destinationBucket(bucketName) + .destinationKey(newKey) + .build(); + s3Client.copyObject(copyRequest); + + // Delete object from source folder + DeleteObjectRequest deleteRequest = DeleteObjectRequest.builder() + .bucket(bucketName) + .key(s3Object.key()) + .build(); + s3Client.deleteObject(deleteRequest); + } + } + +} diff --git a/azure/pom.xml b/azure/pom.xml index aae84db0c6..6a06282a71 100644 --- a/azure/pom.xml +++ b/azure/pom.xml @@ -122,7 +122,6 @@ ${azure.containerRegistry}.azurecr.io 1.1.0 1.1.0 - 3.3.2 \ No newline at end of file diff --git a/core-groovy-modules/pom.xml b/core-groovy-modules/pom.xml index 6faa7f94c8..4fdaf3ee7a 100644 --- a/core-groovy-modules/pom.xml +++ b/core-groovy-modules/pom.xml @@ -27,6 +27,7 @@ 2.7.1 2.3-groovy-3.0 2.1.0 + 2.21.0 diff --git a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/ConstraintsBuilder.java b/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/ConstraintsBuilder.java deleted file mode 100644 index ce437fac6d..0000000000 --- a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/ConstraintsBuilder.java +++ /dev/null @@ -1,15 +0,0 @@ -package reminderapplication; - -import java.awt.GridBagConstraints; -import java.awt.Insets; - -public class ConstraintsBuilder { - - static GridBagConstraints constraint(int x, int y) { - final GridBagConstraints gridBagConstraints = new GridBagConstraints(); - gridBagConstraints.gridx = x; - gridBagConstraints.gridy = y; - gridBagConstraints.insets = new Insets(5, 5, 5, 5); - return gridBagConstraints; - } -} diff --git a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/EditReminderFrame.java b/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/EditReminderFrame.java deleted file mode 100644 index 818cea403e..0000000000 --- a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/EditReminderFrame.java +++ /dev/null @@ -1,194 +0,0 @@ -package reminderapplication; - -import static reminderapplication.ConstraintsBuilder.*; - -import java.awt.GridBagLayout; -import java.awt.HeadlessException; -import java.lang.reflect.InvocationTargetException; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.TimeUnit; -import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JTextField; -import javax.swing.SwingUtilities; - -public class EditReminderFrame extends JFrame { - - private static Timer TIMER = new Timer(); - - private final TimeReminderApplication reminderApplication; - private final JLabel reminderTextLabel; - private final JLabel repeatPeriodLabel; - private final JLabel setDelayLabel; - private final JComboBox delay; - private final JComboBox period; - private final JButton cancelButton; - private final JButton okButton; - private final JTextField textField; - private final JLabel delaysLabel; - private final JLabel periodLabel; - - private final int reminderIndex; - - public EditReminderFrame(TimeReminderApplication reminderApp, String reminderText, int delayInSeconds, int periodInSeconds, int index) throws HeadlessException { - this.reminderApplication = reminderApp; - reminderIndex = index; - textField = createTextField(reminderText); - delay = createDelayComboBox(delayInSeconds); - period = createPeriodComboBox(periodInSeconds); - cancelButton = createCancelButton(); - okButton = createOkButton(); - reminderTextLabel = createReminderTextLabel(); - repeatPeriodLabel = createRepeatPeriodLabel(); - setDelayLabel = createSetDelayLabel(); - delaysLabel = createDelaysLabel(); - periodLabel = createPeriodLabel(); - configureVisualRepresentation(); - configureActions(); - } - - private void configureActions() { - updateReminder(); - } - - private void configureVisualRepresentation() { - configureFrame(); - setLocationRelativeTo(null); - setLayout(new GridBagLayout()); - add(reminderTextLabel, constraint(0,0)); - add(repeatPeriodLabel, constraint(1,0)); - add(setDelayLabel, constraint(2,0)); - add(textField, constraint(0, 1)); - add(delay, constraint(1, 1)); - add(period, constraint(2, 1)); - add(delaysLabel, constraint(1,3)); - add(periodLabel, constraint(2,3)); - add(okButton, constraint(1, 4)); - add(cancelButton, constraint(2, 4)); - pack(); - setVisible(true); - } - - private void configureFrame() { - setTitle("Set Reminder"); - setName("Set Reminder"); - setDefaultCloseOperation(DISPOSE_ON_CLOSE); - } - - private static JLabel createSetDelayLabel() { - return createLabel("Set Delay", "Set Delay Label"); - } - - private static JLabel createRepeatPeriodLabel() { - return createLabel("Set Period", "Set Repeat Period Label"); - } - - private static JLabel createReminderTextLabel() { - return createLabel("Reminder Text", "Reminder Text Label"); - } - - private JLabel createPeriodLabel() { - return createLabel("0", "Period label"); - } - - private JLabel createDelaysLabel() { - return createLabel("30", "Delays Label"); - } - - private JComboBox createPeriodComboBox(final int periodInSeconds) { - final JComboBox comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{0, 5, 10, 20})); - comboBox.setSelectedItem(periodInSeconds); - comboBox.setName("set Period"); - comboBox.addActionListener(e -> periodLabel.setText(comboBox.getSelectedItem().toString())); - return comboBox; - } - - private JComboBox createDelayComboBox(final int delayInSeconds) { - final JComboBox comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{30, 25, 15, 5})); - comboBox.setSelectedItem(delayInSeconds); - comboBox.setName("set Delay"); - comboBox.addActionListener(e -> delaysLabel.setText(comboBox.getSelectedItem().toString())); - return comboBox; - } - - private JTextField createTextField(final String reminderText) { - final JTextField textField = new JTextField(20); - textField.setName("Field"); - textField.setText(reminderText); - return textField; - } - - private JButton createOkButton() { - final JButton button = new JButton("ok"); - button.setName("OK"); - return button; - } - - private void updateReminder() { - okButton.addActionListener(e -> this.dispose()); - okButton.addActionListener(e -> { - final int periodInSeconds = getTimeInSeconds(period); - final int delayInSeconds = getTimeInSeconds(delay); - final Reminder reminder = new Reminder(textField.getText(), delayInSeconds, periodInSeconds); - ((DefaultListModel) reminderApplication.getReminders()).set(reminderIndex, reminder); - }); - okButton.addActionListener(e -> scheduleReminder(textField, delay, period)); - } - - private void scheduleReminder(final JTextField textField, final JComboBox delay, final JComboBox period) { - final int periodInSeconds = getTimeInSeconds(period); - if (periodInSeconds == 0) - scheduleNonRepeatedReminder(textField, delay); - else - scheduleRepeatedReminder(textField, delay, period); - } - - private void scheduleRepeatedReminder(final JTextField textField, final JComboBox delay, final JComboBox period) { - final int delayInSeconds = getTimeInSeconds(delay); - final int periodInSeconds = getTimeInSeconds(period); - final TimerTask timerTask = getTimerTask(textField.getText(), delayInSeconds, periodInSeconds); - TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(delayInSeconds), TimeUnit.SECONDS.toMillis(periodInSeconds)); - } - - private void scheduleNonRepeatedReminder(final JTextField textField, final JComboBox delay) { - final int delayInSeconds = getTimeInSeconds(delay); - final int periodInSeconds = 0; - final TimerTask timerTask = getTimerTask(textField.getText(), delayInSeconds, periodInSeconds); - TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(delayInSeconds)); - - } - - private int getTimeInSeconds(final JComboBox comboBox) { - if (comboBox != null && comboBox.getSelectedItem() != null) - return ((Integer) comboBox.getSelectedItem()); - else - return 0; - } - - private TimerTask getTimerTask(final String reminderText, final Integer delayInSeconds, final Integer periodInSeconds) { - return new TimerTask() { - @Override - public void run() { - new ReminderPopupFrame(reminderApplication, reminderText, delayInSeconds, periodInSeconds); - } - }; - } - - private JButton createCancelButton() { - final JButton button = new JButton("cancel"); - button.setName("Cancel"); - button.addActionListener(e -> this.dispose()); - return button; - } - - private static JLabel createLabel(final String text, final String name) { - JLabel label = new JLabel(text); - label.setName(name); - return label; - } -} diff --git a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/Reminder.java b/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/Reminder.java deleted file mode 100644 index 8f6ff336ed..0000000000 --- a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/Reminder.java +++ /dev/null @@ -1,33 +0,0 @@ -package reminderapplication; - -public class Reminder { - - private static String REMINDER_FORMAT = "Reminder Text: %s; Delay: %d; Period: %d;"; - - private final String name; - private final int delay; - private final int period; - - public Reminder(final String name, final int delay, final int period) { - this.name = name; - this.delay = delay; - this.period = period; - } - - public String getName() { - return name; - } - - public int getDelay() { - return delay; - } - - public int getPeriod() { - return period; - } - - @Override - public String toString() { - return REMINDER_FORMAT.formatted(name, delay, period); - } -} diff --git a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/ReminderFrame.java b/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/ReminderFrame.java deleted file mode 100644 index 3a1623219c..0000000000 --- a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/ReminderFrame.java +++ /dev/null @@ -1,186 +0,0 @@ -package reminderapplication; - -import static reminderapplication.ConstraintsBuilder.*; - -import java.awt.GridBagLayout; -import java.awt.HeadlessException; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.TimeUnit; -import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JTextField; - -public class ReminderFrame extends JFrame { - - private static Timer TIMER = new Timer(); - private final TimeReminderApplication reminderApplication; - private final JLabel reminderTextLabel; - private final JLabel repeatPeriodLabel; - private final JLabel setDelayLabel; - private final JComboBox delay; - private final JComboBox period; - private final JButton cancelButton; - private final JButton okButton; - private final JTextField textField; - private final JLabel delaysLabel; - private final JLabel periodLabel; - - public ReminderFrame(TimeReminderApplication reminderApp) throws HeadlessException { - this.reminderApplication = reminderApp; - textField = createTextField(); - delay = createDelayComboBox(); - period = createPeriodComboBox(); - cancelButton = createCancelButton(); - okButton = createOkButton(); - reminderTextLabel = createReminderTextLabel(); - repeatPeriodLabel = createRepeatPeriodLabel(); - setDelayLabel = createSetDelayLabel(); - delaysLabel = createDelaysLabel(); - periodLabel = createPeriodLabel(); - configureVisualRepresentation(); - configureActions(); - } - - private void configureActions() { - createNewReminder(); - } - - private void configureVisualRepresentation() { - configureFrame(); - setLocationRelativeTo(null); - setLayout(new GridBagLayout()); - add(reminderTextLabel, constraint(0,0)); - add(repeatPeriodLabel, constraint(1,0)); - add(setDelayLabel, constraint(2,0)); - add(textField, constraint(0, 1)); - add(delay, constraint(1, 1)); - add(period, constraint(2, 1)); - add(delaysLabel, constraint(1,3)); - add(periodLabel, constraint(2,3)); - add(okButton, constraint(1, 4)); - add(cancelButton, constraint(2, 4)); - pack(); - setVisible(true); - } - - private void configureFrame() { - setTitle("Set Reminder"); - setName("Set Reminder"); - setDefaultCloseOperation(DISPOSE_ON_CLOSE); - } - - private static JLabel createSetDelayLabel() { - return createLabel("Set Delay", "Set Delay Label"); - } - - private static JLabel createRepeatPeriodLabel() { - return createLabel("Set Period", "Set Repeat Period Label"); - } - - private static JLabel createReminderTextLabel() { - return createLabel("Reminder Text", "Reminder Text Label"); - } - - private JLabel createPeriodLabel() { - return createLabel("0", "Period label"); - } - - private JLabel createDelaysLabel() { - return createLabel("30", "Delays Label"); - } - - private JComboBox createPeriodComboBox() { - final JComboBox comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{0, 5, 10, 20})); - comboBox.setName("set Period"); - comboBox.addActionListener(e -> periodLabel.setText(comboBox.getSelectedItem().toString())); - return comboBox; - } - - private JComboBox createDelayComboBox() { - final JComboBox comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{30, 25, 15, 5})); - comboBox.setName("set Delay"); - comboBox.addActionListener(e -> delaysLabel.setText(comboBox.getSelectedItem().toString())); - return comboBox; - } - - private JTextField createTextField() { - final JTextField textField = new JTextField(20); - textField.setName("Field"); - return textField; - } - - private JButton createOkButton() { - final JButton button = new JButton("ok"); - button.setName("OK"); - return button; - } - - private void createNewReminder() { - - okButton.addActionListener(e -> this.dispose()); - okButton.addActionListener(e -> { - final int periodInSeconds = getTimeInSeconds(period); - final int delayInSeconds = getTimeInSeconds(delay); - final Reminder reminder = new Reminder(textField.getText(), delayInSeconds, periodInSeconds); - ((DefaultListModel) reminderApplication.getReminders()).addElement(reminder); - }); - okButton.addActionListener(e -> scheduleReminder(textField, delay, period)); - } - - private void scheduleReminder(final JTextField textField, final JComboBox delay, final JComboBox period) { - final int periodInSeconds = getTimeInSeconds(period); - if (periodInSeconds == 0) - scheduleNonRepeatedReminder(textField, delay); - else - scheduleRepeatedReminder(textField, delay, period); - } - - private void scheduleRepeatedReminder(final JTextField textField, final JComboBox delay, final JComboBox period) { - final int delayInSeconds = getTimeInSeconds(delay) + 200; - final int periodInSeconds = getTimeInSeconds(period); - final TimerTask timerTask = getTimerTask(textField.getText(), delayInSeconds, periodInSeconds); - TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(delayInSeconds), TimeUnit.SECONDS.toMillis(periodInSeconds)); - } - - private void scheduleNonRepeatedReminder(final JTextField textField, final JComboBox delay) { - final int delayInSeconds = getTimeInSeconds(delay); - final int periodInSeconds = 0; - final TimerTask timerTask = getTimerTask(textField.getText(), delayInSeconds, periodInSeconds); - TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(delayInSeconds)); - - } - - private int getTimeInSeconds(final JComboBox comboBox) { - if (comboBox != null && comboBox.getSelectedItem() != null) - return ((Integer) comboBox.getSelectedItem()); - else - return 0; - } - - private TimerTask getTimerTask(final String reminderText, final Integer delayInSeconds, final Integer periodInSeconds) { - return new TimerTask() { - @Override - public void run() { - new ReminderPopupFrame(reminderApplication, reminderText, delayInSeconds, periodInSeconds); - } - }; - } - - private JButton createCancelButton() { - final JButton button = new JButton("cancel"); - button.setName("Cancel"); - button.addActionListener(e -> this.dispose()); - return button; - } - - private static JLabel createLabel(final String text, final String name) { - JLabel label = new JLabel(text); - label.setName(name); - return label; - } -} diff --git a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/ReminderPopupFrame.java b/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/ReminderPopupFrame.java deleted file mode 100644 index d41343cb6d..0000000000 --- a/core-java-modules/Reminder Application/Reminder Application/task/src/reminderapplication/ReminderPopupFrame.java +++ /dev/null @@ -1,151 +0,0 @@ -package reminderapplication; - -import static reminderapplication.ConstraintsBuilder.*; - -import java.awt.GridBagLayout; -import java.awt.HeadlessException; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.TimeUnit; -import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListModel; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JTextField; - -public class ReminderPopupFrame extends JFrame { - - private static final Timer TIMER = new Timer(); - private final int AUTOMATIC_CLOSE_TIME_IN_SECONDS = 10; - private final TimeReminderApplication reminderApplication; - private final JLabel reminderTextLabel; - private final JLabel repeatPeriodLabel; - private final JLabel setDelayLabel; - private final JComboBox delay; - private final JComboBox period; - private final JButton cancelButton; - private final JButton okButton; - private final JTextField textField; - private final JLabel delaysLabel; - private final JLabel periodLabel; - - public ReminderPopupFrame(TimeReminderApplication reminderApp, final String text, final Integer delayInSeconds, final Integer periodInSeconds) throws HeadlessException { - this.reminderApplication = reminderApp; - textField = createTextField(text); - delay = createDelayComboBox(delayInSeconds); - period = createPeriodComboBox(periodInSeconds); - cancelButton = createCancelButton(); - okButton = createDisabledOkButton(); - reminderTextLabel = createReminderTextLabel(); - repeatPeriodLabel = createRepeatPeriodLabel(); - setDelayLabel = createSetDelayLabel(); - delaysLabel = createDelaysLabel(); - periodLabel = createPeriodLabel(); - configureVisualRepresentation(); - configureActions(); - } - - private void configureActions() { - scheduleClosing(); - } - - private void scheduleClosing() { - final TimerTask timerTask = new TimerTask() { - @Override - public void run() { - ReminderPopupFrame.this.dispose(); - } - }; - TIMER.schedule(timerTask, TimeUnit.SECONDS.toMillis(AUTOMATIC_CLOSE_TIME_IN_SECONDS)); - } - - private void configureVisualRepresentation() { - configureFrame(); - setLocationRelativeTo(null); - setLayout(new GridBagLayout()); - add(reminderTextLabel, constraint(0,0)); - add(repeatPeriodLabel, constraint(1,0)); - add(setDelayLabel, constraint(2,0)); - add(textField, constraint(0, 1)); - add(delay, constraint(1, 1)); - add(period, constraint(2, 1)); - add(delaysLabel, constraint(1,3)); - add(periodLabel, constraint(2,3)); - add(okButton, constraint(1, 4)); - add(cancelButton, constraint(2, 4)); - pack(); - setVisible(true); - } - - private void configureFrame() { - setTitle("Set Reminder"); - setName("Set Reminder"); - setDefaultCloseOperation(DISPOSE_ON_CLOSE); - } - - private static JLabel createSetDelayLabel() { - return createLabel("Set Delay", "Set Delay Label"); - } - - private static JLabel createRepeatPeriodLabel() { - return createLabel("Set Period", "Set Repeat Period Label"); - } - - private static JLabel createReminderTextLabel() { - return createLabel("Reminder Text", "Reminder Text Label"); - } - - private JLabel createPeriodLabel() { - return createLabel("0", "Period label"); - } - - private JLabel createDelaysLabel() { - return createLabel("30", "Delays Label"); - } - - private JComboBox createPeriodComboBox(final Integer periodInSeconds) { - final JComboBox comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{0, 5, 10, 20})); - comboBox.setName("set Period"); - comboBox.setSelectedItem(periodInSeconds); - comboBox.addActionListener(e -> periodLabel.setText(comboBox.getSelectedItem().toString())); - return comboBox; - } - - private JComboBox createDelayComboBox(Integer delay) { - final JComboBox comboBox = new JComboBox<>(new DefaultComboBoxModel<>(new Integer[]{30, 25, 15, 5})); - comboBox.setSelectedItem(delay); - comboBox.setName("set Delay"); - comboBox.addActionListener(e -> delaysLabel.setText(comboBox.getSelectedItem().toString())); - return comboBox; - } - - private JTextField createTextField(final String text) { - final JTextField textField = new JTextField(20); - textField.setName("Field"); - textField.setText(text); - return textField; - } - - private JButton createDisabledOkButton() { - final JButton button = new JButton("ok"); - button.setName("OK"); - button.setEnabled(false); - return button; - } - - private JButton createCancelButton() { - final JButton button = new JButton("cancel"); - button.setName("Cancel"); - button.addActionListener(e -> this.dispose()); - return button; - } - - private static JLabel createLabel(final String text, final String name) { - JLabel label = new JLabel(text); - label.setName(name); - return label; - } - -} diff --git a/core-java-modules/core-java-14/pom.xml b/core-java-modules/core-java-14/pom.xml index 9f48c0b8b2..55c50b2a5c 100644 --- a/core-java-modules/core-java-14/pom.xml +++ b/core-java-modules/core-java-14/pom.xml @@ -48,7 +48,6 @@ 14 - 3.8.1 3.0.0-M3 diff --git a/core-java-modules/core-java-15/pom.xml b/core-java-modules/core-java-15/pom.xml index 059e2cc8f3..3ac45d26ba 100644 --- a/core-java-modules/core-java-15/pom.xml +++ b/core-java-modules/core-java-15/pom.xml @@ -53,7 +53,6 @@ 15 - 3.8.1 3.0.0-M3 diff --git a/core-java-modules/core-java-17/README.md b/core-java-modules/core-java-17/README.md index 1af860b7c4..2d4a2e0382 100644 --- a/core-java-modules/core-java-17/README.md +++ b/core-java-modules/core-java-17/README.md @@ -7,3 +7,4 @@ - [Random Number Generators in Java 17](https://www.baeldung.com/java-17-random-number-generators) - [Sealed Classes and Interfaces in Java](https://www.baeldung.com/java-sealed-classes-interfaces) - [Migrate From Java 8 to Java 17](https://www.baeldung.com/java-migrate-8-to-17) +- [Format Multiple ‘or’ Conditions in an If Statement in Java](https://www.baeldung.com/java-multiple-or-conditions-if-statement) diff --git a/core-java-modules/core-java-17/src/test/java/com/baeldung/multipleorwithif/MultipleOrWithIfUnitTest.java b/core-java-modules/core-java-17/src/test/java/com/baeldung/multipleorwithif/MultipleOrWithIfUnitTest.java new file mode 100644 index 0000000000..09b8d3c2b1 --- /dev/null +++ b/core-java-modules/core-java-17/src/test/java/com/baeldung/multipleorwithif/MultipleOrWithIfUnitTest.java @@ -0,0 +1,126 @@ +package com.baeldung.multipleorwithif; + +import static java.time.Month.DECEMBER; +import static java.time.Month.NOVEMBER; +import static java.time.Month.OCTOBER; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.in; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.Month; +import java.util.List; +import java.util.Random; +import java.util.Set; +import java.util.function.Predicate; + +import org.junit.jupiter.api.Test; + +class MultipleOrWithIfUnitTest { + + private final Random rand = new Random(); + + final Set months = Set.of(OCTOBER, NOVEMBER, DECEMBER); + + @Test + public void givenIfStatement_whenMultipleOrOperator_thenAssert() { + assertTrue(multipleOrOperatorIf(monthIn())); + assertFalse(multipleOrOperatorIf(monthNotIn())); + } + + boolean multipleOrOperatorIf(Month month) { + if (month == OCTOBER || month == NOVEMBER || month == DECEMBER) { + return true; + } + return false; + } + + @Test + public void givenSwitch_whenMultipleCase_thenBreakAndAssert() { + assertTrue(switchMonth(monthIn())); + assertFalse(switchMonth(monthNotIn())); + } + + boolean switchMonth(Month month) { + return switch (month) { + case OCTOBER, NOVEMBER, DECEMBER -> true; + default -> false; + }; + } + + @Test + public void givenAllowedValuesList_whenContains_thenAssert() { + assertTrue(contains(monthIn())); + assertFalse(contains(monthNotIn())); + } + + @Test + public void givenPredicates_whenTestMultipleOr_thenAssert() { + assertTrue(predicateWithIf(monthIn())); + assertFalse(predicateWithIf(monthNotIn())); + } + + @Test + public void givenInputList_whenFilterWithPredicate_thenAssert() { + + List list = List.of(monthIn(), monthIn(), monthNotIn()); + + list.stream() + .filter(this::predicateWithIf) + .forEach(m -> assertThat(m, is(in(months)))); + } + + Predicate orPredicate() { + Predicate predicate = x -> x == OCTOBER; + Predicate predicate1 = x -> x == NOVEMBER; + Predicate predicate2 = x -> x == DECEMBER; + + return predicate.or(predicate1) + .or(predicate2); + } + + boolean predicateWithIf(Month month) { + if (orPredicate().test(month)) { + return true; + } + return false; + } + + @Test + public void givenContainsInSetPredicate_whenTestPredicate_thenAssert() { + Predicate collectionPredicate = this::contains; + + assertTrue(collectionPredicate.test(monthIn())); + assertFalse(collectionPredicate.test(monthNotIn())); + } + + @Test + public void givenInputList_whenFilterWithContains_thenAssert() { + + List monthList = List.of(monthIn(), monthIn(), monthNotIn()); + + monthList.stream() + .filter(this::contains) + .forEach(m -> assertThat(m, is(in(months)))); + } + + private boolean contains(Month month) { + if (months.contains(month)) { + return true; + } + return false; + } + + private Month monthIn() { + return Month.of(rand.ints(10, 13) + .findFirst() + .orElse(10)); + } + + private Month monthNotIn() { + return Month.of(rand.ints(1, 10) + .findFirst() + .orElse(1)); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-21/README.md b/core-java-modules/core-java-21/README.md new file mode 100644 index 0000000000..c63f3b360b --- /dev/null +++ b/core-java-modules/core-java-21/README.md @@ -0,0 +1 @@ +## Relevant Articles \ No newline at end of file diff --git a/core-java-modules/core-java-21/pom.xml b/core-java-modules/core-java-21/pom.xml new file mode 100644 index 0000000000..83b2b1c858 --- /dev/null +++ b/core-java-modules/core-java-21/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + core-java-21 + core-java-21 + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-21/src/main/java/com/baeldung/sequenced/collections/SequencedCollection.java b/core-java-modules/core-java-21/src/main/java/com/baeldung/sequenced/collections/SequencedCollection.java new file mode 100644 index 0000000000..58f5dbd014 --- /dev/null +++ b/core-java-modules/core-java-21/src/main/java/com/baeldung/sequenced/collections/SequencedCollection.java @@ -0,0 +1,15 @@ +package com.baeldung.sequenced.collections; + +/* +interface SequencedCollection extends Collection { + // new method + SequencedCollection reversed(); + // methods promoted from Deque + void addFirst(E); + void addLast(E); + E getFirst(); + E getLast(); + E removeFirst(); + E removeLast(); +} + */ diff --git a/core-java-modules/core-java-21/src/main/java/com/baeldung/sequenced/collections/SequencedMap.java b/core-java-modules/core-java-21/src/main/java/com/baeldung/sequenced/collections/SequencedMap.java new file mode 100644 index 0000000000..925449a090 --- /dev/null +++ b/core-java-modules/core-java-21/src/main/java/com/baeldung/sequenced/collections/SequencedMap.java @@ -0,0 +1,18 @@ +package com.baeldung.sequenced.collections; + +/* +interface SequencedMap extends Map { + // new methods + SequencedMap reversed(); + SequencedSet sequencedKeySet(); + SequencedCollection sequencedValues(); + SequencedSet> sequencedEntrySet(); + V putFirst(K, V); + V putLast(K, V); + // methods promoted from NavigableMap + Entry firstEntry(); + Entry lastEntry(); + Entry pollFirstEntry(); + Entry pollLastEntry(); +} + */ \ No newline at end of file diff --git a/core-java-modules/core-java-21/src/main/java/com/baeldung/sequenced/collections/SequencedSet.java b/core-java-modules/core-java-21/src/main/java/com/baeldung/sequenced/collections/SequencedSet.java new file mode 100644 index 0000000000..a8fb4caa1f --- /dev/null +++ b/core-java-modules/core-java-21/src/main/java/com/baeldung/sequenced/collections/SequencedSet.java @@ -0,0 +1,7 @@ +package com.baeldung.sequenced.collections; + +/* +interface SequencedSet extends Set, SequencedCollection { + SequencedSet reversed(); // covariant override +} + */ diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/stringtime/AddMinuteStringTimeUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/stringtime/AddMinuteStringTimeUnitTest.java new file mode 100644 index 0000000000..15b430cc6a --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/stringtime/AddMinuteStringTimeUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.stringtime; + +import static org.junit.jupiter.api.Assertions.*; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalTime; +import java.util.Calendar; +import java.util.Date; +import org.junit.jupiter.api.Test; + +public class AddMinuteStringTimeUnitTest { + + @Test + public void givenTimeStringUsingSimpleDateFormat_whenIncrementedWith10Minutes_thenResultShouldBeCorrect() throws ParseException { + String timeString = "23:45"; + SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); + Date date = timeFormat.parse(timeString); + + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.add(Calendar.MINUTE, 10); + String result = timeFormat.format(cal.getTime()); + assertEquals("23:55", result); + + } + + @Test + public void givenTimeStringUsingLocalTime_whenIncrementedWith10Minutes_thenResultShouldBeCorrect() { + String timeString = "23:45"; + LocalTime time = LocalTime.parse(timeString); + LocalTime newTime = time.plusMinutes(10); + String result = newTime.toString(); + assertEquals("23:55", result); + } + +} diff --git a/core-java-modules/core-java-9-improvements/pom.xml b/core-java-modules/core-java-9-improvements/pom.xml index f6f13ff409..ce40a4acb8 100644 --- a/core-java-modules/core-java-9-improvements/pom.xml +++ b/core-java-modules/core-java-9-improvements/pom.xml @@ -10,7 +10,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../../ + ../../pom.xml diff --git a/core-java-modules/core-java-9-jigsaw/library-core/pom.xml b/core-java-modules/core-java-9-jigsaw/library-core/pom.xml index 80638367cf..415c7fb053 100644 --- a/core-java-modules/core-java-9-jigsaw/library-core/pom.xml +++ b/core-java-modules/core-java-9-jigsaw/library-core/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung + com.baeldung.core-java-modules core-java-9-jigsaw - 0.2-SNAPSHOT + 0.0.1-SNAPSHOT library-core diff --git a/core-java-modules/core-java-9-jigsaw/pom.xml b/core-java-modules/core-java-9-jigsaw/pom.xml index 288254b9cf..4afe2ae31a 100644 --- a/core-java-modules/core-java-9-jigsaw/pom.xml +++ b/core-java-modules/core-java-9-jigsaw/pom.xml @@ -11,10 +11,9 @@ - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - ../../ + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT diff --git a/core-java-modules/core-java-9-new-features/pom.xml b/core-java-modules/core-java-9-new-features/pom.xml index 6821c9c340..9c897f1cea 100644 --- a/core-java-modules/core-java-9-new-features/pom.xml +++ b/core-java-modules/core-java-9-new-features/pom.xml @@ -152,7 +152,6 @@ 4.0.2 1.9 1.9 - 3.2.0 \ No newline at end of file diff --git a/core-java-modules/core-java-9-streams/src/main/java/com/baeldung/streams/regexmatches/StreamFromRegexUtil.java b/core-java-modules/core-java-9-streams/src/main/java/com/baeldung/streams/regexmatches/StreamFromRegexUtil.java new file mode 100644 index 0000000000..f7187c79de --- /dev/null +++ b/core-java-modules/core-java-9-streams/src/main/java/com/baeldung/streams/regexmatches/StreamFromRegexUtil.java @@ -0,0 +1,16 @@ +package com.baeldung.streams.regexmatches; + +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +public class StreamFromRegexUtil { + + public static Stream getStream(String input, String regex) { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(input); + return matcher.results().map(MatchResult::group); + } + +} diff --git a/core-java-modules/core-java-9-streams/src/test/java/com/baeldung/streams/regexmatches/StreamFromRegexUnitTest.java b/core-java-modules/core-java-9-streams/src/test/java/com/baeldung/streams/regexmatches/StreamFromRegexUnitTest.java new file mode 100644 index 0000000000..9d8b840e0e --- /dev/null +++ b/core-java-modules/core-java-9-streams/src/test/java/com/baeldung/streams/regexmatches/StreamFromRegexUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.streams.regexmatches; + +import org.junit.Test; + +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; + +public class StreamFromRegexUnitTest { + + @Test + public void whenInputStringIncludeLettersAndNumbersAndRegex_ThenReturnStreamOfNumbers() { + List result = StreamFromRegexUtil.getStream("There are 3 apples and 2 bananas on the table.", "\\d+") + .collect(Collectors.toList()); + assertEquals(asList("3", "2"), result); + } + + @Test + public void whenInputStringsAndRegex_ThenReturnStreamOfJavaWords() { + List result = StreamFromRegexUtil.getStream("sample sentence with some words Java Java", "\\bJava\\b") + .collect(Collectors.toList()); + assertEquals(asList("Java", "Java"), result); + } + +} diff --git a/core-java-modules/core-java-arrays-operations-advanced/README.md b/core-java-modules/core-java-arrays-operations-advanced/README.md index e3465c9fa3..0647d89d16 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/README.md +++ b/core-java-modules/core-java-arrays-operations-advanced/README.md @@ -13,3 +13,5 @@ This module contains articles about advanced operations on arrays in Java. They - [Performance of System.arraycopy() vs. Arrays.copyOf()](https://www.baeldung.com/java-system-arraycopy-arrays-copyof-performance) - [Slicing Arrays in Java](https://www.baeldung.com/java-slicing-arrays) - [Combining Two or More Byte Arrays](https://www.baeldung.com/java-concatenate-byte-arrays) +- [Calculating the Sum of Two Arrays in Java](https://www.baeldung.com/java-sum-arrays-element-wise) +- [Find the Middle Element of an Array in Java](https://www.baeldung.com/java-array-middle-item) diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/arraymiddle/MiddleOfArray.java b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/arraymiddle/MiddleOfArray.java new file mode 100644 index 0000000000..f389893209 --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-advanced/src/main/java/com/baeldung/arraymiddle/MiddleOfArray.java @@ -0,0 +1,65 @@ +package com.baeldung.arraymiddle; + +import java.util.Arrays; + +import org.apache.commons.lang3.ObjectUtils; + +public class MiddleOfArray { + int[] middleOfArray(int[] array) { + if (ObjectUtils.isEmpty(array) || array.length < 3) + return array; + int n = array.length; + int mid = n / 2; + if (n % 2 == 0) { + int mid2 = mid - 1; + return new int[] { array[mid2], array[mid] }; + } else { + return new int[] { array[mid] }; + } + } + + int[] middleOfArrayWithStartEndNaive(int[] array, int start, int end) { + int mid = (start + end) / 2; + int n = end - start; + if (n % 2 == 0) { + int mid2 = mid - 1; + return new int[] { array[mid2], array[mid] }; + } else { + return new int[] { array[mid] }; + } + } + + int[] middleOfArrayWithStartEnd(int[] array, int start, int end) { + int mid = start + (end - start) / 2; + int n = end - start; + if (n % 2 == 0) { + int mid2 = mid - 1; + return new int[] { array[mid2], array[mid] }; + } else { + return new int[] { array[mid] }; + } + } + + int[] middleOfArrayWithStartEndBitwise(int[] array, int start, int end) { + int mid = (start + end) >>> 1; + int n = end - start; + if (n % 2 == 0) { + int mid2 = mid - 1; + return new int[] { array[mid2], array[mid] }; + } else { + return new int[] { array[mid] }; + } + } + + int medianOfArray(int[] array, int start, int end) { + Arrays.sort(array); // for safety. This can be ignored + int mid = (start + end) >>> 1; + int n = end - start; + if (n % 2 == 0) { + int mid2 = mid - 1; + return (array[mid2] + array[mid]) / 2; + } else { + return array[mid]; + } + } +} diff --git a/core-java-modules/core-java-arrays-operations-advanced/src/test/java/com/baeldung/arraymiddle/MiddleOfArrayUnitTest.java b/core-java-modules/core-java-arrays-operations-advanced/src/test/java/com/baeldung/arraymiddle/MiddleOfArrayUnitTest.java new file mode 100644 index 0000000000..706412d83e --- /dev/null +++ b/core-java-modules/core-java-arrays-operations-advanced/src/test/java/com/baeldung/arraymiddle/MiddleOfArrayUnitTest.java @@ -0,0 +1,89 @@ +package com.baeldung.arraymiddle; + +import org.junit.Assert; +import org.junit.Test; + +public class MiddleOfArrayUnitTest { + + @Test + public void givenArrayOfEvenLength_whenMiddleOfArray_thenReturn2Values() { + int[] array = new int[100]; + for (int i = 0; i < array.length; i++) { + array[i] = i + 1; + } + int[] expectedMidArray = { 50, 51 }; + MiddleOfArray middleOfArray = new MiddleOfArray(); + Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArray(array)); + } + + @Test + public void givenArrayOfEdgeCaseLength_whenMiddleOfArray_thenReturn2Values() { + int[] array = new int[0]; + int[] expectedMidArray = new int[0]; + MiddleOfArray middleOfArray = new MiddleOfArray(); + Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArray(array)); + + array = new int[] { 1, 2 }; + expectedMidArray = new int[] { 1, 2 }; + + Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArray(array)); + } + + @Test + public void givenArrayOfOddLength_whenMiddleOfArray_thenReturnMid() { + int[] array = new int[99]; + for (int i = 0; i < array.length; i++) { + array[i] = i + 1; + } + int[] expectedMidArray = { 50 }; + MiddleOfArray middleOfArray = new MiddleOfArray(); + Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArray(array)); + } + + @Test + public void givenArrayWithStartAndEnd_whenMiddleOfArray_thenReturnMid() { + int[] array = new int[100]; + for (int i = 0; i < array.length; i++) { + array[i] = i + 1; + } + int[] expectedMidArray = { 58 }; + MiddleOfArray middleOfArray = new MiddleOfArray(); + Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArrayWithStartEndNaive(array, 55, 60)); + + expectedMidArray = new int[] { 58, 59 }; + Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArrayWithStartEndNaive(array, 56, 60)); + } + + @Test + public void givenArrayWithStartAndEndOptimized_whenMiddleOfArray_thenReturnMid() { + int[] array = new int[100]; + for (int i = 0; i < array.length; i++) { + array[i] = i + 1; + } + int[] expectedMidArray = { 78 }; + MiddleOfArray middleOfArray = new MiddleOfArray(); + Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArrayWithStartEnd(array, 55, 100)); + } + + @Test + public void givenArrayWithStartAndEndBitwise_whenMiddleOfArray_thenReturnMid() { + int[] array = new int[100]; + for (int i = 0; i < array.length; i++) { + array[i] = i + 1; + } + int[] expectedMidArray = { 78 }; + MiddleOfArray middleOfArray = new MiddleOfArray(); + Assert.assertArrayEquals(expectedMidArray, middleOfArray.middleOfArrayWithStartEndBitwise(array, 55, 100)); + } + + @Test + public void givenArrayWithStartAndEnd_whenMedianOfArray_thenReturnMid() { + int[] array = new int[100]; + for (int i = 0; i < array.length; i++) { + array[i] = i + 1; + } + int expectMedian = 50; + MiddleOfArray middleOfArray = new MiddleOfArray(); + Assert.assertEquals(expectMedian, middleOfArray.medianOfArray(array, 0, 100)); + } +} diff --git a/core-java-modules/core-java-collections-conversions-2/README.md b/core-java-modules/core-java-collections-conversions-2/README.md index efd01c46ee..e8d008104c 100644 --- a/core-java-modules/core-java-collections-conversions-2/README.md +++ b/core-java-modules/core-java-collections-conversions-2/README.md @@ -13,4 +13,5 @@ This module contains articles about conversions among Collection types and array - [Combining Two Lists Into a Map in Java](https://www.baeldung.com/java-combine-two-lists-into-map) - [Convert a List of Strings to a List of Integers](https://www.baeldung.com/java-convert-list-strings-to-integers) - [Convert List to Long[] Array in Java](https://www.baeldung.com/java-convert-list-object-to-long-array) +- [Get the First n Elements of a List Into an Array](https://www.baeldung.com/java-take-start-elements-list-array) - More articles: [[<-- prev]](../core-java-collections-conversions) diff --git a/core-java-modules/core-java-collections-list-5/README.md b/core-java-modules/core-java-collections-list-5/README.md index d734cf7364..42f878ad70 100644 --- a/core-java-modules/core-java-collections-list-5/README.md +++ b/core-java-modules/core-java-collections-list-5/README.md @@ -12,3 +12,4 @@ This module contains articles about the Java List collection - [Get Unique Values From an ArrayList in Java](https://www.baeldung.com/java-unique-values-arraylist) - [Converting a Java List to a Json Array](https://www.baeldung.com/java-converting-list-to-json-array) - [What’s the Difference Between Iterator and ListIterator?](https://www.baeldung.com/java-iterator-vs-listiterator) +- [Create List of Object From Another Type Using Java 8](https://www.baeldung.com/java-generate-list-different-type) 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 bcdb6824ed..2b4b0041b3 100644 --- a/core-java-modules/core-java-collections-list-5/pom.xml +++ b/core-java-modules/core-java-collections-list-5/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-collections-list-5 core-java-collections-list-5 diff --git a/core-java-modules/core-java-collections-list-5/src/test/java/com/baeldung/java/streamtoanotherlist/CreateListOfDifferentTypeUsingStreamUnitTest.java b/core-java-modules/core-java-collections-list-5/src/test/java/com/baeldung/java/streamtoanotherlist/CreateListOfDifferentTypeUsingStreamUnitTest.java new file mode 100644 index 0000000000..c2d74dd726 --- /dev/null +++ b/core-java-modules/core-java-collections-list-5/src/test/java/com/baeldung/java/streamtoanotherlist/CreateListOfDifferentTypeUsingStreamUnitTest.java @@ -0,0 +1,114 @@ +package com.baeldung.java.streamtoanotherlist; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.Test; + +import lombok.Getter; + +@Getter +class Employee { + private final String name; + private final Set hobbies = new HashSet<>(); + private final String email; + private String department; + + public Employee(String name, String email, Collection hobbies) { + this.name = name; + this.email = email; + this.hobbies.addAll(hobbies); + } +} + +class TennisPlayerCandidate { + private final String name; + private final String email; + private final Boolean confirmed = Boolean.FALSE; + + public TennisPlayerCandidate(String name, String email) { + this.name = name; + this.email = email; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof TennisPlayerCandidate)) + return false; + + TennisPlayerCandidate that = (TennisPlayerCandidate) o; + + if (!Objects.equals(name, that.name)) + return false; + return Objects.equals(email, that.email); + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (email != null ? email.hashCode() : 0); + return result; + } +} + +public class CreateListOfDifferentTypeUsingStreamUnitTest { + private final static List EMPLOYEES = Lists.newArrayList( + // @formatter:off + new Employee("Kai", "kai@company.com", Lists.newArrayList("Football", "Reading", "Chess")), + new Employee("Eric", "eric@company.com", Lists.newArrayList("Tennis", "Baseball", "Singing")), + new Employee("Saajan", "saajan@company.com", Lists.newArrayList("Tennis", "Baseball", "Singing")), + new Employee("Kevin", "kevin@company.com", Lists.newArrayList("Dancing", "Computer Games", "Tennis")), + new Employee("Amanda", "amanda@company.com", Lists.newArrayList("Painting", "Yoga", "Dancing")) + //@formatter:on + ); + + private final static List EXPECTED = Lists.newArrayList( + // @formatter:off + new TennisPlayerCandidate("Eric", "eric@company.com"), + new TennisPlayerCandidate("Saajan", "saajan@company.com"), + new TennisPlayerCandidate("Kevin", "kevin@company.com") + //@formatter:on + ); + + @Test + void whenUsingStreamForEachFillingAnotherList_thenGetExpectedResult() { + List result = new ArrayList<>(); + EMPLOYEES.forEach(e -> { + if (e.getHobbies() + .contains("Tennis")) { + result.add(new TennisPlayerCandidate(e.getName(), e.getEmail())); + } + }); + + assertEquals(EXPECTED, result); + } + + @Test + void whenUsingStreamMap_thenGetExpectedResult() { + List result = EMPLOYEES.stream() + .filter(e -> e.getHobbies() + .contains("Tennis")) + .map(e -> new TennisPlayerCandidate(e.getName(), e.getEmail())) + .collect(Collectors.toList()); + assertEquals(EXPECTED, result); + } + + @Test + void whenUsingCollectorMapping_thenGetExpectedResult() { + List result = EMPLOYEES.stream() + .filter(e -> e.getHobbies() + .contains("Tennis")) + .collect(Collectors.mapping(e -> new TennisPlayerCandidate(e.getName(), e.getEmail()), Collectors.toList())); + assertEquals(EXPECTED, result); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps-3/README.md b/core-java-modules/core-java-collections-maps-3/README.md index 68df2b9556..0d07bde8c1 100644 --- a/core-java-modules/core-java-collections-maps-3/README.md +++ b/core-java-modules/core-java-collections-maps-3/README.md @@ -9,4 +9,5 @@ This module contains articles about Map data structures in Java. - [Collections.synchronizedMap vs. ConcurrentHashMap](https://www.baeldung.com/java-synchronizedmap-vs-concurrenthashmap) - [Java HashMap Load Factor](https://www.baeldung.com/java-hashmap-load-factor) - [Converting Java Properties to HashMap](https://www.baeldung.com/java-convert-properties-to-hashmap) +- [Get Values and Keys as ArrayList From a HashMap](https://www.baeldung.com/java-values-keys-arraylists-hashmap) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-maps-2) diff --git a/core-java-modules/core-java-collections-maps/src/main/java/com/baeldung/map/MapClear.java b/core-java-modules/core-java-collections-maps/src/main/java/com/baeldung/map/MapClear.java new file mode 100644 index 0000000000..9e16b742cf --- /dev/null +++ b/core-java-modules/core-java-collections-maps/src/main/java/com/baeldung/map/MapClear.java @@ -0,0 +1,49 @@ +package com.baeldung.map; + +import java.util.HashMap; +import java.util.Map; + +public class MapClear { + public static Map returnCopyAndClearMap() { + // Create a HashMap + Map scores = new HashMap<>(); + Map scores_copy; + + // Add some key-value pairs + scores.put("Alice", 90); + scores.put("Bob", 85); + scores.put("Charlie", 95); + + scores_copy = scores; + + System.out.println("Before clearing: " + scores); + + // Clear the map + scores.clear(); + + System.out.println("After clearing: " + scores); + return scores_copy; + } + + public static Map returnCopyAndRewriteMap() { + // Create a HashMap + Map scores = new HashMap<>(); + Map scores_copy; + + // Add some key-value pairs + scores.put("Alice", 90); + scores.put("Bob", 85); + scores.put("Charlie", 95); + + scores_copy = scores; + + System.out.println("Before clearing: " + scores); + + // Create a new map + scores = new HashMap<>(); + + System.out.println("After clearing: " + scores); + + return scores_copy; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/MapClearUnitTest.java b/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/MapClearUnitTest.java new file mode 100644 index 0000000000..a6d10f2707 --- /dev/null +++ b/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/MapClearUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.map; + +import java.util.Map; + +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class MapClearUnitTest { + @Test + public void givenMap_returnEntryAndClearContent() { + Map entry = MapClear.returnCopyAndClearMap(); + assertTrue(entry.isEmpty()); + } + + @Test public void givenMap_returnEntryAndRewriteContent() { + Map entry = MapClear.returnCopyAndRewriteMap(); + assertTrue(!entry.isEmpty()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/UsingtoStringUnitTest.java b/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/UsingtoStringUnitTest.java new file mode 100644 index 0000000000..4af6b72a4e --- /dev/null +++ b/core-java-modules/core-java-collections-maps/src/test/java/com/baeldung/map/UsingtoStringUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.map; + +import org.junit.Test; + +import java.util.HashMap; + +import static org.junit.Assert.assertEquals; + +public class UsingtoStringUnitTest { + + @Test + public void given_HashMapString_whenUsingtoString_thenConvertToHashMapObject() { + // Example string representation of a HashMap + String hashMapString = "{key1=value1, key2=value2, key3=value3}"; + + // Remove unnecessary characters + String keyValuePairs = hashMapString.replaceAll("[{}\\s]", ""); + + // Split into individual key-value pairs + String[] pairs = keyValuePairs.split(","); + + // Create a new HashMap + HashMap expectedHashMap = new HashMap<>(); + expectedHashMap.put("key1", "value1"); + expectedHashMap.put("key2", "value2"); + expectedHashMap.put("key3", "value3"); + + HashMap actualHashMap = new HashMap<>(); + + // Parse and populate the HashMap + for (String pair : pairs) { + String[] keyValue = pair.split("="); + if (keyValue.length == 2) { + actualHashMap.put(keyValue[0], keyValue[1]); + } + } + + // Assert that the converted HashMap matches the expected one + assertEquals(expectedHashMap, actualHashMap); + } + +} diff --git a/core-java-modules/core-java-collections-set-2/README.md b/core-java-modules/core-java-collections-set-2/README.md index 33f20d60af..feeffed1c4 100644 --- a/core-java-modules/core-java-collections-set-2/README.md +++ b/core-java-modules/core-java-collections-set-2/README.md @@ -4,4 +4,5 @@ - [A Guide to LinkedHashSet in Java](https://www.baeldung.com/java-linkedhashset) - [Sorting a HashSet in Java](https://www.baeldung.com/java-sort-hashset) - [How to Get First Item From a Java Set](https://www.baeldung.com/first-item-set) +- [Cartesian Product of Any Number of Sets in Java](https://www.baeldung.com/java-cartesian-product-sets) - More articles: [[<-- prev]](/core-java-modules/core-java-collections-set) diff --git a/core-java-modules/core-java-collections-set-2/pom.xml b/core-java-modules/core-java-collections-set-2/pom.xml index 680c01d8ca..7274f1861b 100644 --- a/core-java-modules/core-java-collections-set-2/pom.xml +++ b/core-java-modules/core-java-collections-set-2/pom.xml @@ -20,6 +20,23 @@ ${junit-platform.version} test + + org.apache.commons + commons-collections4 + 4.4 + + + + org.testng + testng + 7.7.0 + test + + + com.google.guava + guava + 32.1.1-jre + diff --git a/core-java-modules/core-java-collections-set-2/src/main/java/com/baeldung/cartesianproduct/CartesianProduct.java b/core-java-modules/core-java-collections-set-2/src/main/java/com/baeldung/cartesianproduct/CartesianProduct.java new file mode 100644 index 0000000000..d4725d74f1 --- /dev/null +++ b/core-java-modules/core-java-collections-set-2/src/main/java/com/baeldung/cartesianproduct/CartesianProduct.java @@ -0,0 +1,75 @@ +package com.baeldung.cartesianproduct; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.google.common.collect.Sets; + +public class CartesianProduct { + public List> getCartesianProductIterative(List> sets) { + List> result = new ArrayList<>(); + if(sets == null || sets.isEmpty()) { + return result; + } + int totalSets = sets.size(); + int totalCombinations = 1 << totalSets; + for(int i = 0; i < totalCombinations; i++) { + List combination = new ArrayList<>(); + for(int j = 0; j < totalSets; j++) { + if (((i >> j) & 1) == 1) { + combination.add(sets.get(j).get(0)); + } else { + combination.add(sets.get(j).get(1)); + } + } + result.add(combination); + } + return result; + } + + public List> getCartesianProductRecursive(List> sets) { + List> result = new ArrayList<>(); + getCartesianProductRecursiveHelper(sets, 0, new ArrayList<>(), result); + return result; + } + + private void getCartesianProductRecursiveHelper(List> sets, int index, List current, List> result) { + if(index == sets.size()) { + result.add(new ArrayList<>(current)); + return; + } + List currentSet = sets.get(index); + for(Object element: currentSet) { + current.add(element); + getCartesianProductRecursiveHelper(sets, index+1, current, result); + current.remove(current.size() - 1); + } + } + + public List> getCartesianProductUsingStreams(List> sets) { + return cartesianProduct(sets,0).collect(Collectors.toList()); + } + + public Stream> cartesianProduct(List> sets, int index) { + if(index == sets.size()) { + List emptyList = new ArrayList<>(); + return Stream.of(emptyList); + } + List currentSet = sets.get(index); + return currentSet.stream().flatMap(element -> cartesianProduct(sets, index+1) + .map(list -> { + List newList = new ArrayList<>(list); + newList.add(0, element); return newList; + })); + } + + public List> getCartesianProductUsingGuava(List> sets) { + Set> cartesianProduct = Sets.cartesianProduct(sets); + List> cartesianList = new ArrayList<>(cartesianProduct); + return cartesianList; + } + +} diff --git a/core-java-modules/core-java-collections-set-2/src/main/java/com/baeldung/indexawareset/IndexOfElementsInSet.java b/core-java-modules/core-java-collections-set-2/src/main/java/com/baeldung/indexawareset/IndexOfElementsInSet.java new file mode 100644 index 0000000000..abedf147a3 --- /dev/null +++ b/core-java-modules/core-java-collections-set-2/src/main/java/com/baeldung/indexawareset/IndexOfElementsInSet.java @@ -0,0 +1,29 @@ +package com.baeldung.indexawareset; + +import java.util.Iterator; +import java.util.Set; + +public class IndexOfElementsInSet { + public int getIndexUsingIterator(Set set, E element) { + Iterator iterator = set.iterator(); + int index = 0; + while (iterator.hasNext()) { + if (element.equals(iterator.next())) { + return index; + } + index++; + } + return -1; + } + + public int getIndexUsingForEach(Set set, E element) { + int index = 0; + for (E current : set) { + if (element.equals(current)) { + return index; + } + index++; + } + return -1; + } +} diff --git a/core-java-modules/core-java-collections-set-2/src/main/java/com/baeldung/indexawareset/InsertionIndexAwareSet.java b/core-java-modules/core-java-collections-set-2/src/main/java/com/baeldung/indexawareset/InsertionIndexAwareSet.java new file mode 100644 index 0000000000..de2a739186 --- /dev/null +++ b/core-java-modules/core-java-collections-set-2/src/main/java/com/baeldung/indexawareset/InsertionIndexAwareSet.java @@ -0,0 +1,20 @@ +package com.baeldung.indexawareset; + +import java.util.LinkedHashSet; + +public class InsertionIndexAwareSet extends LinkedHashSet { + public InsertionIndexAwareSet() { + super(); + } + + public int getIndexOf(E element) { + int index = 0; + for (E current : this) { + if (current.equals(element)) { + return index; + } + index++; + } + return -1; + } +} diff --git a/core-java-modules/core-java-collections-set-2/src/test/java/com/baeldung/cartesianproduct/CartesianProductUnitTest.java b/core-java-modules/core-java-collections-set-2/src/test/java/com/baeldung/cartesianproduct/CartesianProductUnitTest.java new file mode 100644 index 0000000000..cc9c01fb5f --- /dev/null +++ b/core-java-modules/core-java-collections-set-2/src/test/java/com/baeldung/cartesianproduct/CartesianProductUnitTest.java @@ -0,0 +1,93 @@ +package com.baeldung.cartesianproduct; + +import static org.testng.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.testng.annotations.Test; + +public class CartesianProductUnitTest { + private CartesianProduct cp = new CartesianProduct(); + List> sets = Arrays.asList( + Arrays.asList(10, 20), + Arrays.asList("John", "Jack"), + Arrays.asList('I', 'J') + ); + + @Test + public void whenUsingStreams_thenCalculateCartesianProduct() { + List> expected = Arrays.asList( + Arrays.asList(10, "John", 'I'), + Arrays.asList(10, "John", 'J'), + Arrays.asList(10, "Jack", 'I'), + Arrays.asList(10, "Jack", 'J'), + Arrays.asList(20, "John", 'I'), + Arrays.asList(20, "John", 'J'), + Arrays.asList(20, "Jack", 'I'), + Arrays.asList(20, "Jack", 'J') + ); + List> cartesianProduct = cp.getCartesianProductUsingStreams(sets); + + assertEquals(expected, cartesianProduct); + } + + @Test + public void whenUsingRecursion_thenCalculateCartesianProduct() { + List> expected = Arrays.asList( + Arrays.asList(10, "John", 'I'), + Arrays.asList(10, "John", 'J'), + Arrays.asList(10, "Jack", 'I'), + Arrays.asList(10, "Jack", 'J'), + Arrays.asList(20, "John", 'I'), + Arrays.asList(20, "John", 'J'), + Arrays.asList(20, "Jack", 'I'), + Arrays.asList(20, "Jack", 'J') + ); + List> cartesianProduct = cp.getCartesianProductRecursive(sets); + + assertEquals(expected, cartesianProduct); + } + + @Test + public void whenUsingIterativeApproach_thenCalculateCartesianProduct() { + List> expected = Arrays.asList( + Arrays.asList(20, "Jack", 'J'), + Arrays.asList(10, "Jack", 'J'), + Arrays.asList(20, "John", 'J'), + Arrays.asList(10, "John", 'J'), + Arrays.asList(20, "Jack", 'I'), + Arrays.asList(10, "Jack", 'I'), + Arrays.asList(20, "John", 'I'), + Arrays.asList(10, "John", 'I') + ); + List> cartesianProduct = cp.getCartesianProductIterative(sets); + + assertEquals(expected, cartesianProduct); + } + + @Test + public void whenUsingGuava_thenCalculateCartesianProduct() { + List> sets = new ArrayList<>(); + sets.add(new HashSet<>(Arrays.asList(10, 20))); + sets.add(new HashSet<>(Arrays.asList("John", "Jack"))); + sets.add(new HashSet<>(Arrays.asList('I', 'J'))); + + List> expected = Arrays.asList( + Arrays.asList(20, "John", 'I'), + Arrays.asList(20, "John", 'J'), + Arrays.asList(20, "Jack", 'I'), + Arrays.asList(20, "Jack", 'J'), + Arrays.asList(10, "John", 'I'), + Arrays.asList(10, "John", 'J'), + Arrays.asList(10, "Jack", 'I'), + Arrays.asList(10, "Jack", 'J') + ); + List> cartesianProduct = cp.getCartesianProductUsingGuava(sets); + + assertEquals(expected, cartesianProduct); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-set-2/src/test/java/com/baeldung/indexawareset/IndexOfSetElementsUsingListUnitTest.java b/core-java-modules/core-java-collections-set-2/src/test/java/com/baeldung/indexawareset/IndexOfSetElementsUsingListUnitTest.java new file mode 100644 index 0000000000..a1f961a5a4 --- /dev/null +++ b/core-java-modules/core-java-collections-set-2/src/test/java/com/baeldung/indexawareset/IndexOfSetElementsUsingListUnitTest.java @@ -0,0 +1,108 @@ +package com.baeldung.indexawareset; + +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.TreeSet; + +import org.apache.commons.collections4.set.ListOrderedSet; +import org.junit.Assert; +import org.junit.Test; + +public class IndexOfSetElementsUsingListUnitTest { + @Test + public void givenHashSet_whenIndexOfElement_thenGivesIndex() { + Set set = new HashSet<>(); + set.add(100); + set.add(20); + set.add(300); + set.add(0); + set.add(-1); + set.add(300); + + IndexOfElementsInSet integerIndexOfElementsInSet = new IndexOfElementsInSet<>(); + int index100 = integerIndexOfElementsInSet.getIndexUsingIterator(set, 100); + Assert.assertEquals(index100, integerIndexOfElementsInSet.getIndexUsingIterator(set, 100)); + + Assert.assertEquals(-1, integerIndexOfElementsInSet.getIndexUsingIterator(set, 12)); + } + + @Test + public void givenLinkedHashSet_whenIndexOfElement_thenGivesIndex() { + Set set = new LinkedHashSet<>(); + set.add(100); + set.add(20); + set.add(300); + set.add(0); + set.add(-1); + set.add(300); + + IndexOfElementsInSet integerIndexOfElementsInSet = new IndexOfElementsInSet<>(); + Assert.assertEquals(0, integerIndexOfElementsInSet.getIndexUsingIterator(set, 100)); + } + + @Test + public void givenTreeSet_whenIndexOfElement_thenGivesIndex() { + Set set = new TreeSet<>(); + set.add(100); + set.add(20); + set.add(300); + set.add(0); + set.add(-1); + set.add(300); + + IndexOfElementsInSet integerIndexOfElementsInSet = new IndexOfElementsInSet<>(); + Assert.assertEquals(0, integerIndexOfElementsInSet.getIndexUsingIterator(set, -1)); + Assert.assertEquals(3, integerIndexOfElementsInSet.getIndexUsingIterator(set, 100)); + } + + @Test + public void givenIndexAwareSet_whenIndexOfElement_thenGivesIndex() { + InsertionIndexAwareSet set = new InsertionIndexAwareSet<>(); + set.add(100); + set.add(20); + set.add(300); + Assert.assertEquals(0, set.getIndexOf(100)); + Assert.assertEquals(2, set.getIndexOf(300)); + Assert.assertEquals(-1, set.getIndexOf(0)); + } + + @Test + public void givenIndexAwareSetWithStrings_whenIndexOfElement_thenGivesIndex() { + InsertionIndexAwareSet set = new InsertionIndexAwareSet<>(); + set.add("Go"); + set.add("Java"); + set.add("Scala"); + set.add("Python"); + Assert.assertEquals(0, set.getIndexOf("Go")); + Assert.assertEquals(2, set.getIndexOf("Scala")); + Assert.assertEquals(-1, set.getIndexOf("C++")); + } + + @Test + public void givenListOrderedSet_whenIndexOfElement_thenGivesIndex() { + ListOrderedSet set = new ListOrderedSet<>(); + set.add(12); + set.add(0); + set.add(-1); + set.add(50); + + Assert.assertEquals(0, set.indexOf(12)); + Assert.assertEquals(2, set.indexOf(-1)); + Assert.assertEquals(-1, set.indexOf(100)); + } + + @Test + public void givenLinkedHashSet_whenIndexUsingUtilityMethod_thenReturnsIndex() { + Set set = new LinkedHashSet<>(); + set.add(100); + set.add(20); + set.add(300); + set.add(0); + set.add(-1); + set.add(300); + + IndexOfElementsInSet integerIndexOfElementsInSet = new IndexOfElementsInSet<>(); + Assert.assertEquals(-1, integerIndexOfElementsInSet.getIndexUsingForEach(set, 150)); + } +} diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java index 9c880025f7..de350a40c4 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Consumer.java @@ -4,6 +4,7 @@ import java.util.logging.Logger; public class Consumer implements Runnable { private static final Logger log = Logger.getLogger(Consumer.class.getCanonicalName()); + private boolean running = false; private final DataQueue dataQueue; public Consumer(DataQueue dataQueue) { @@ -12,26 +13,36 @@ public class Consumer implements Runnable { @Override public void run() { + running = true; consume(); } + public void stop() { + running = false; + } + public void consume() { - while (dataQueue.runFlag) { - while (dataQueue.isEmpty() && dataQueue.runFlag) { + while (running) { + + if (dataQueue.isEmpty()) { try { - dataQueue.waitOnEmpty(); + dataQueue.waitIsNotEmpty(); } catch (InterruptedException e) { - e.printStackTrace(); + log.severe("Error while waiting to Consume messages."); break; } } - if (!dataQueue.runFlag) { + + // avoid spurious wake-up + if (!running) { break; } - Message message = dataQueue.remove(); - dataQueue.notifyAllForFull(); + + Message message = dataQueue.poll(); useMessage(message); + //Sleeping on random time to make it realistic + ThreadUtil.sleep((long) (Math.random() * 100)); } log.info("Consumer Stopped"); } @@ -40,14 +51,7 @@ public class Consumer implements Runnable { if (message != null) { log.info(String.format("[%s] Consuming Message. Id: %d, Data: %f%n", Thread.currentThread().getName(), message.getId(), message.getData())); - - //Sleeping on random time to make it realistic - ThreadUtil.sleep((long) (message.getData() * 100)); } } - public void stop() { - dataQueue.runFlag = false; - dataQueue.notifyAllForEmpty(); - } } diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/DataQueue.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/DataQueue.java index 8867ddeb63..7286ed8af8 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/DataQueue.java +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/DataQueue.java @@ -6,10 +6,8 @@ import java.util.Queue; public class DataQueue { private final Queue queue = new LinkedList<>(); private final int maxSize; - private final Object FULL_QUEUE = new Object(); - private final Object EMPTY_QUEUE = new Object(); - - public boolean runFlag = true; + private final Object IS_NOT_FULL = new Object(); + private final Object IS_NOT_EMPTY = new Object(); DataQueue(int maxSize) { this.maxSize = maxSize; @@ -23,39 +21,42 @@ public class DataQueue { return queue.isEmpty(); } - public void waitOnFull() throws InterruptedException { - synchronized (FULL_QUEUE) { - FULL_QUEUE.wait(); + public void waitIsNotFull() throws InterruptedException { + synchronized (IS_NOT_FULL) { + IS_NOT_FULL.wait(); } } - public void waitOnEmpty() throws InterruptedException { - synchronized (EMPTY_QUEUE) { - EMPTY_QUEUE.wait(); - } - } - - public void notifyAllForFull() { - synchronized (FULL_QUEUE) { - FULL_QUEUE.notifyAll(); - } - } - - public void notifyAllForEmpty() { - synchronized (EMPTY_QUEUE) { - EMPTY_QUEUE.notifyAll(); + public void waitIsNotEmpty() throws InterruptedException { + synchronized (IS_NOT_EMPTY) { + IS_NOT_EMPTY.wait(); } } public void add(Message message) { - synchronized (queue) { - queue.add(message); + queue.add(message); + notifyIsNotEmpty(); + } + + public Message poll() { + Message mess = queue.poll(); + notifyIsNotFull(); + return mess; + } + + public Integer getSize() { + return queue.size(); + } + + private void notifyIsNotFull() { + synchronized (IS_NOT_FULL) { + IS_NOT_FULL.notify(); } } - public Message remove() { - synchronized (queue) { - return queue.poll(); + private void notifyIsNotEmpty() { + synchronized (IS_NOT_EMPTY) { + IS_NOT_EMPTY.notify(); } } } diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java index 5ca60a29e4..4bd0e9e6d1 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/Producer.java @@ -1,60 +1,63 @@ package com.baeldung.producerconsumer; +import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; public class Producer implements Runnable { private static final Logger log = Logger.getLogger(Producer.class.getCanonicalName()); + private static final AtomicInteger idSequence = new AtomicInteger(0); + private boolean running = false; private final DataQueue dataQueue; - private static int idSequence = 0; - public Producer(DataQueue dataQueue) { this.dataQueue = dataQueue; } @Override public void run() { + running = true; produce(); } + public void stop() { + running = false; + } + public void produce() { - while (dataQueue.runFlag) { - while (dataQueue.isFull() && dataQueue.runFlag) { + + while (running) { + + if (dataQueue.isFull()) { try { - dataQueue.waitOnFull(); + dataQueue.waitIsNotFull(); } catch (InterruptedException e) { - e.printStackTrace(); + log.severe("Error while waiting to Produce messages."); break; } } - if (!dataQueue.runFlag) { + + // avoid spurious wake-up + if (!running) { break; } - Message message = generateMessage(); - dataQueue.add(message); - dataQueue.notifyAllForEmpty(); + dataQueue.add(generateMessage()); + + log.info("Size of the queue is: " + dataQueue.getSize()); + + //Sleeping on random time to make it realistic + ThreadUtil.sleep((long) (Math.random() * 100)); } + log.info("Producer Stopped"); } private Message generateMessage() { - Message message = new Message(incrementAndGetId(), Math.random()); + Message message = new Message(idSequence.incrementAndGet(), Math.random()); log.info(String.format("[%s] Generated Message. Id: %d, Data: %f%n", Thread.currentThread().getName(), message.getId(), message.getData())); - //Sleeping on random time to make it realistic - ThreadUtil.sleep((long) (message.getData() * 100)); - return message; } - private static int incrementAndGetId() { - return ++idSequence; - } - - public void stop() { - dataQueue.runFlag = false; - dataQueue.notifyAllForFull(); - } } diff --git a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ProducerConsumerDemonstrator.java b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ProducerConsumerDemonstrator.java index 96d7b9f865..5e8c99fce3 100644 --- a/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ProducerConsumerDemonstrator.java +++ b/core-java-modules/core-java-concurrency-advanced-4/src/main/java/com/baeldung/producerconsumer/ProducerConsumerDemonstrator.java @@ -27,7 +27,7 @@ public class ProducerConsumerDemonstrator { // let threads run for two seconds sleep(2000); - // Stop threads + // stop threads producer.stop(); consumer.stop(); @@ -36,28 +36,34 @@ public class ProducerConsumerDemonstrator { public static void demoMultipleProducersAndMultipleConsumers() { DataQueue dataQueue = new DataQueue(MAX_QUEUE_CAPACITY); - int producerCount = 3; - int consumerCount = 3; + int producerCount = 5; + int consumerCount = 5; List threads = new ArrayList<>(); - Producer producer = new Producer(dataQueue); + List producers = new ArrayList<>(); + List consumers = new ArrayList<>(); + for(int i = 0; i < producerCount; i++) { + Producer producer = new Producer(dataQueue); Thread producerThread = new Thread(producer); producerThread.start(); threads.add(producerThread); + producers.add(producer); } - Consumer consumer = new Consumer(dataQueue); + for(int i = 0; i < consumerCount; i++) { + Consumer consumer = new Consumer(dataQueue); Thread consumerThread = new Thread(consumer); consumerThread.start(); threads.add(consumerThread); + consumers.add(consumer); } - // let threads run for two seconds - sleep(2000); + // let threads run for ten seconds + sleep(10000); - // Stop threads - producer.stop(); - consumer.stop(); + // stop threads + consumers.forEach(Consumer::stop); + producers.forEach(Producer::stop); waitForAllThreadsToComplete(threads); } diff --git a/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/phaser/LongRunningAction.java b/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/phaser/LongRunningAction.java index 44f84ad77c..093cfdbc81 100644 --- a/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/phaser/LongRunningAction.java +++ b/core-java-modules/core-java-concurrency-advanced/src/main/java/com/baeldung/concurrent/phaser/LongRunningAction.java @@ -7,31 +7,37 @@ import java.util.concurrent.Phaser; class LongRunningAction implements Runnable { - private static Logger log = LoggerFactory.getLogger(LongRunningAction.class); - private String threadName; - private Phaser ph; + private static final Logger log = LoggerFactory.getLogger(LongRunningAction.class); + private final String threadName; + private final Phaser ph; LongRunningAction(String threadName, Phaser ph) { this.threadName = threadName; this.ph = ph; + + this.randomWait(); + ph.register(); + log.info("Thread {} registered during phase {}", threadName, ph.getPhase()); } @Override public void run() { - log.info("This is phase {}", ph.getPhase()); - log.info("Thread {} before long running action", threadName); - + log.info("Thread {} BEFORE long running action in phase {}", threadName, ph.getPhase()); + ph.arriveAndAwaitAdvance(); + + randomWait(); + + log.info("Thread {} AFTER long running action in phase {}", threadName, ph.getPhase()); + ph.arriveAndDeregister(); + } + + // Simulating real work + private void randomWait() { try { - Thread.sleep(2000); + Thread.sleep((long) (Math.random() * 100)); } catch (InterruptedException e) { e.printStackTrace(); } - - log.debug("Thread {} action completed and waiting for others", threadName); - ph.arriveAndAwaitAdvance(); - log.debug("Thread {} proceeding in phase {}", threadName, ph.getPhase()); - - ph.arriveAndDeregister(); } } \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/phaser/PhaserUnitTest.java b/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/phaser/PhaserUnitTest.java index 384a1837c1..9cb863073e 100644 --- a/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/phaser/PhaserUnitTest.java +++ b/core-java-modules/core-java-concurrency-advanced/src/test/java/com/baeldung/concurrent/phaser/PhaserUnitTest.java @@ -7,8 +7,6 @@ import org.junit.runners.MethodSorters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.Phaser; import static junit.framework.TestCase.assertEquals; @@ -16,38 +14,32 @@ import static junit.framework.TestCase.assertEquals; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class PhaserUnitTest { - private static Logger log = LoggerFactory.getLogger(PhaserUnitTest.class); + private static final Logger log = LoggerFactory.getLogger(PhaserUnitTest.class); @Test - public void givenPhaser_whenCoordinateWorksBetweenThreads_thenShouldCoordinateBetweenMultiplePhases() { - //given - ExecutorService executorService = Executors.newCachedThreadPool(); + public void givenPhaser_whenCoordinateWorksBetweenThreads_thenShouldCoordinateBetweenMultiplePhases() throws InterruptedException { Phaser ph = new Phaser(1); assertEquals(0, ph.getPhase()); - //when - executorService.submit(new LongRunningAction("thread-1", ph)); - executorService.submit(new LongRunningAction("thread-2", ph)); - executorService.submit(new LongRunningAction("thread-3", ph)); + new Thread(new LongRunningAction("thread-1", ph)).start(); + new Thread(new LongRunningAction("thread-2", ph)).start(); + new Thread(new LongRunningAction("thread-3", ph)).start(); - //then - log.debug("Thread {} waiting for others", Thread.currentThread().getName()); + log.info("Thread {} waiting for others", Thread.currentThread().getName()); ph.arriveAndAwaitAdvance(); - log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase()); - + log.info("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase()); assertEquals(1, ph.getPhase()); - //and - executorService.submit(new LongRunningAction("thread-4", ph)); - executorService.submit(new LongRunningAction("thread-5", ph)); + new Thread(new LongRunningAction("thread-4", ph)).start(); + new Thread(new LongRunningAction("thread-5", ph)).start(); - log.debug("Thread {} waiting for others", Thread.currentThread().getName()); + log.info("Thread {} waiting for new phase", Thread.currentThread().getName()); ph.arriveAndAwaitAdvance(); - log.debug("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase()); - + log.info("Thread {} proceeding in phase {}", Thread.currentThread().getName(), ph.getPhase()); assertEquals(2, ph.getPhase()); - ph.arriveAndDeregister(); + Thread.sleep(1000); + assertEquals(true, ph.isTerminated()); } } diff --git a/core-java-modules/core-java-concurrency-basic/README.md b/core-java-modules/core-java-concurrency-basic/README.md index e5c061710c..a133beb1fe 100644 --- a/core-java-modules/core-java-concurrency-basic/README.md +++ b/core-java-modules/core-java-concurrency-basic/README.md @@ -11,4 +11,5 @@ This module contains articles about basic Java concurrency - [Runnable vs. Callable in Java](https://www.baeldung.com/java-runnable-callable) - [What Is Thread-Safety and How to Achieve It?](https://www.baeldung.com/java-thread-safety) - [How to Get Notified When a Task Completes in Java Executors](https://www.baeldung.com/java-executors-task-completed-notification) +- [Difference Between Future, CompletableFuture, and Rxjava’s Observable](https://www.baeldung.com/java-future-completablefuture-rxjavas-observable) - [[Next -->]](/core-java-modules/core-java-concurrency-basic-2) diff --git a/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/hashtableandconcurrenthashmap/BenchMarkRunner.java b/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/hashtableandconcurrenthashmap/BenchMarkRunner.java new file mode 100644 index 0000000000..3c7132ffcd --- /dev/null +++ b/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/hashtableandconcurrenthashmap/BenchMarkRunner.java @@ -0,0 +1,73 @@ +package com.baeldung.hashtableandconcurrenthashmap; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.Blackhole; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.Hashtable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +@Fork(value = 1) +@Warmup(iterations = 3) +@Measurement(iterations = 5) +@Threads(10) // 10 threads for the test +public class BenchMarkRunner { + private Hashtable hashTable; + private ConcurrentHashMap concurrentHashMap; + + @Setup(Level.Trial) + public void setup() { + hashTable = new Hashtable<>(); + concurrentHashMap = new ConcurrentHashMap<>(); + } + + @Benchmark + @Group("hashtable") + public void benchmarkHashtablePut() { + for (int i = 0; i < 10000; i++) { + hashTable.put(String.valueOf(i), i); + } + } + + @Benchmark + @Group("hashtable") + public void benchmarkHashtableGet(Blackhole blackhole) { + for (int i = 0; i < 10000; i++) { + Integer value = hashTable.get(String.valueOf(i)); + blackhole.consume(value); + } + } + + @Benchmark + @Group("concurrentHashMap") + public void benchmarkConcurrentHashMapPut() { + for (int i = 0; i < 10000; i++) { + concurrentHashMap.put(String.valueOf(i), i); + } + } + + @Benchmark + @Group("concurrentHashMap") + public void benchmarkConcurrentHashMapGet(Blackhole blackhole) { + for (int i = 0; i < 10000; i++) { + Integer value = concurrentHashMap.get(String.valueOf(i)); + blackhole.consume(value); + } + } + + public static void main(String[] args) throws Exception { + Options options = new OptionsBuilder() + .include(BenchMarkRunner.class.getSimpleName()) + .shouldFailOnError(true) + .shouldDoGC(true) + .jvmArgs("-server") + .build(); + new Runner(options).run(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/hashtableandconcurrenthashmap/ConcurrentHashMapUnitTest.java b/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/hashtableandconcurrenthashmap/ConcurrentHashMapUnitTest.java new file mode 100644 index 0000000000..c936583abb --- /dev/null +++ b/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/hashtableandconcurrenthashmap/ConcurrentHashMapUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.hashtableandconcurrenthashmap; + +import org.junit.Test; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +public class ConcurrentHashMapUnitTest { + @Test + public void givenEmptyConcurrentHashMap_whenValuesAreAdded_thenValuesCanBeRetrieved() { + ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap<>(); + concurrentHashMap.put("Key1", "1"); + concurrentHashMap.put("Key2", "2"); + concurrentHashMap.putIfAbsent("Key3", "3"); + String value = concurrentHashMap.get("Key2"); + + assertEquals("1", concurrentHashMap.get("Key1")); + assertEquals("2", value); + assertEquals("3", concurrentHashMap.get("Key3")); + } + @Test + public void givenPopulatedConcurrentHashMap_whenModifiedDuringIteration_thenShouldNotThrowConcurrentModificationException() throws InterruptedException { + ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap<>(); + concurrentHashMap.put("Key1", 1); + concurrentHashMap.put("Key2", 2); + concurrentHashMap.put("Key3", 3); + AtomicBoolean exceptionCaught = new AtomicBoolean(false); + + Thread iteratorThread = new Thread(() -> { + Iterator it = concurrentHashMap.keySet().iterator(); + try { + while (it.hasNext()) { + it.next(); + Thread.sleep(100); + } + } catch (ConcurrentModificationException e) { + exceptionCaught.set(true); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + Thread modifierThread = new Thread(() -> { + try { + Thread.sleep(50); + concurrentHashMap.put("Key4", 4); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + iteratorThread.start(); + modifierThread.start(); + + iteratorThread.join(); + modifierThread.join(); + + assertFalse(exceptionCaught.get()); + } +} diff --git a/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/hashtableandconcurrenthashmap/HashtableUnitTest.java b/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/hashtableandconcurrenthashmap/HashtableUnitTest.java new file mode 100644 index 0000000000..8f8195fdef --- /dev/null +++ b/core-java-modules/core-java-concurrency-collections-2/src/test/java/com/baeldung/hashtableandconcurrenthashmap/HashtableUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.hashtableandconcurrenthashmap; + +import org.junit.Test; +import java.util.ConcurrentModificationException; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +public class HashtableUnitTest { + @Test + public void givenEmptyHashtable_whenValuesAreAdded_thenValuesCanBeRetrieved() { + Hashtable hashtable = new Hashtable<>(); + hashtable.put("Key1", "1"); + hashtable.put("Key2", "2"); + hashtable.putIfAbsent("Key3", "3"); + String value = hashtable.get("Key2"); + + assertEquals("1", hashtable.get("Key1")); + assertEquals("2", value); + assertEquals("3", hashtable.get("Key3")); + } + @Test + public void givenPopulatedHashtable_whenModifiedDuringIteration_thenShouldThrowConcurrentModificationException() throws InterruptedException { + Hashtable hashtable = new Hashtable<>(); + hashtable.put("Key1", 1); + hashtable.put("Key2", 2); + hashtable.put("Key3", 3); + AtomicBoolean exceptionCaught = new AtomicBoolean(false); + + Thread iteratorThread = new Thread(() -> { + Iterator it = hashtable.keySet().iterator(); + try { + while (it.hasNext()) { + it.next(); + Thread.sleep(100); + } + } catch (ConcurrentModificationException e) { + exceptionCaught.set(true); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + Thread modifierThread = new Thread(() -> { + try { + Thread.sleep(50); + hashtable.put("Key4", 4); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + iteratorThread.start(); + modifierThread.start(); + + iteratorThread.join(); + modifierThread.join(); + + assertTrue(exceptionCaught.get()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-conditionals/pom.xml b/core-java-modules/core-java-conditionals/pom.xml index 2a1290c98e..811f183e99 100644 --- a/core-java-modules/core-java-conditionals/pom.xml +++ b/core-java-modules/core-java-conditionals/pom.xml @@ -37,20 +37,19 @@ --enable-preview - - org.apache.maven.plugins - maven-surefire-plugin - ${surefire.plugin.version} - - --enable-preview - - + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.plugin.version} + + --enable-preview + + 14 - 3.8.1 14 3.0.0-M3 diff --git a/core-java-modules/core-java-date-operations-3/README.md b/core-java-modules/core-java-date-operations-3/README.md index e3f0cfa3dc..9d16d1f71c 100644 --- a/core-java-modules/core-java-date-operations-3/README.md +++ b/core-java-modules/core-java-date-operations-3/README.md @@ -10,4 +10,5 @@ This module contains articles about date operations in Java. - [How to Get Last Day of a Month in Java](https://www.baeldung.com/java-last-day-month) - [Getting Yesterday’s Date in Java](https://www.baeldung.com/java-find-yesterdays-date) - [How to Get the Start and End Dates of a Year Using Java](https://www.baeldung.com/java-date-year-start-end) +- [Convert Between Java LocalDate and Epoch](https://www.baeldung.com/java-localdate-epoch) - [[<-- Prev]](/core-java-modules/core-java-date-operations-2) 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 19760ca357..9b7be18b85 100644 --- a/core-java-modules/core-java-date-operations-3/pom.xml +++ b/core-java-modules/core-java-date-operations-3/pom.xml @@ -12,7 +12,7 @@ core-java-modules 0.0.1-SNAPSHOT - + joda-time @@ -25,7 +25,7 @@ ${commons-lang3.version} - + 2.12.5 3.12.0 diff --git a/core-java-modules/core-java-date-operations-3/src/main/java/com/baeldung/epochconversion/EpochToLocalDate.java b/core-java-modules/core-java-date-operations-3/src/main/java/com/baeldung/epochconversion/EpochToLocalDate.java new file mode 100644 index 0000000000..574693355d --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/main/java/com/baeldung/epochconversion/EpochToLocalDate.java @@ -0,0 +1,24 @@ +package com.baeldung.epochconversion; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; + +public class EpochToLocalDate { + + public static void main(String[] args) { + long millisSinceEpoch = 2131242L; + ZoneId zoneId = ZoneId.of("Europe/Amsterdam"); // or: ZoneId.systemDefault(); + // to get All Zone Ids available, we can use the function below + // Set allZoneIds = ZoneId.getAvailableZoneIds(); + LocalDate date = + Instant.ofEpochMilli(millisSinceEpoch) + .atZone(zoneId) + .toLocalDate(); + LocalDateTime time = + Instant.ofEpochMilli(millisSinceEpoch) + .atZone(zoneId) + .toLocalDateTime(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations-3/src/main/java/com/baeldung/epochconversion/LocalDateToEpoch.java b/core-java-modules/core-java-date-operations-3/src/main/java/com/baeldung/epochconversion/LocalDateToEpoch.java new file mode 100644 index 0000000000..b84cd5c1a7 --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/main/java/com/baeldung/epochconversion/LocalDateToEpoch.java @@ -0,0 +1,18 @@ +package com.baeldung.epochconversion; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; + +public class LocalDateToEpoch { + + public static void main(String[] args) { + ZoneId zoneId = ZoneId.of("Europe/Amsterdam"); // or: ZoneId.systemDefault() + LocalDate date = LocalDate.now(); + long epochMilliSecondsAtDate = date.atStartOfDay(zoneId).toInstant().toEpochMilli(); + + // epoch for time + LocalDateTime time = LocalDateTime.parse("2019-11-15T13:15:30"); + long epochMilliSecondsAtTime = time.atZone(zoneId).toInstant().toEpochMilli(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/epochconversion/EpochToLocalDateUnitTest.java b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/epochconversion/EpochToLocalDateUnitTest.java new file mode 100644 index 0000000000..90ab056511 --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/epochconversion/EpochToLocalDateUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.epochconversion; + +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class EpochToLocalDateUnitTest { + + @Test + void givenEpoch_thenComputeLocalDateCorrectly() { + ZoneId zoneId = ZoneId.systemDefault(); + LocalDate expectedDate = LocalDate.of(1995, 4, 15); + long date = expectedDate.atStartOfDay(zoneId).toInstant().toEpochMilli(); + + LocalDate actualDate = + Instant.ofEpochMilli(date) + .atZone(zoneId) + .toLocalDate(); + assertEquals(expectedDate, actualDate); + } + + @Test + void givenEpoch_thenComputeLocalDateTimeCorrectly() { + ZoneId zoneId = ZoneId.systemDefault(); + LocalDateTime expectedTime = LocalDateTime.parse("2019-11-15T13:15:30"); + long time = expectedTime.atZone(zoneId).toInstant().toEpochMilli(); + + LocalDateTime actualTime = + Instant.ofEpochMilli(time) + .atZone(zoneId) + .toLocalDateTime(); + assertEquals(expectedTime, actualTime); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/epochconversion/LocalDateTimeToEpochUnitTest.java b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/epochconversion/LocalDateTimeToEpochUnitTest.java new file mode 100644 index 0000000000..8e9a4b01d0 --- /dev/null +++ b/core-java-modules/core-java-date-operations-3/src/test/java/com/baeldung/epochconversion/LocalDateTimeToEpochUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.epochconversion; + +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class LocalDateTimeToEpochUnitTest { + + @Test + void givenDate_thenComputeEpochCorrectly() { + ZoneId zoneId = ZoneId.of("Europe/Tallinn"); + long expectedEpoch = LocalDate.now().toEpochDay(); + LocalDateTime givenDate = Instant.ofEpochMilli(expectedEpoch) + .atZone(zoneId) + .toLocalDateTime(); + + long actualEpoch = givenDate.atZone(zoneId).toInstant().toEpochMilli(); + assertEquals(expectedEpoch, actualEpoch); + } + + @Test + void givenTime_thenComputeEpochCorrectly() { + ZoneId zoneId = ZoneId.of("Europe/Amsterdam"); + long expectedEpoch = Instant.now().toEpochMilli(); + LocalDateTime givenTime = Instant.ofEpochMilli(expectedEpoch) + .atZone(zoneId) + .toLocalDateTime(); + + long actualEpoch = givenTime.atZone(zoneId).toInstant().toEpochMilli(); + assertEquals(expectedEpoch, actualEpoch); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-datetime-conversion/README.md b/core-java-modules/core-java-datetime-conversion/README.md index 98c2d6694b..d3a3dae728 100644 --- a/core-java-modules/core-java-datetime-conversion/README.md +++ b/core-java-modules/core-java-datetime-conversion/README.md @@ -9,3 +9,4 @@ This module contains articles about converting between Java date and time object - [Convert Between java.time.Instant and java.sql.Timestamp](https://www.baeldung.com/java-time-instant-to-java-sql-timestamp) - [Convert Between LocalDateTime and ZonedDateTime](https://www.baeldung.com/java-localdatetime-zoneddatetime) - [Conversion From 12-Hour Time to 24-Hour Time in Java](https://www.baeldung.com/java-convert-time-format) +- [Convert Epoch Time to LocalDate and LocalDateTime](https://www.baeldung.com/java-convert-epoch-localdate) diff --git a/core-java-modules/core-java-io/README.md b/core-java-modules/core-java-io/README.md index f6b7787960..aed0ff41c2 100644 --- a/core-java-modules/core-java-io/README.md +++ b/core-java-modules/core-java-io/README.md @@ -12,4 +12,5 @@ This module contains articles about core Java input and output (IO) - [Getting a File’s Mime Type in Java](https://www.baeldung.com/java-file-mime-type) - [How to Avoid the Java FileNotFoundException When Loading Resources](https://www.baeldung.com/java-classpath-resource-cannot-be-opened) - [Java – Rename or Move a File](https://www.baeldung.com/java-how-to-rename-or-move-a-file) +- [Closing Java IO Streams](https://www.baeldung.com/java-io-streams-closing) - [[More -->]](/core-java-modules/core-java-io-2) diff --git a/core-java-modules/core-java-io/pom.xml b/core-java-modules/core-java-io/pom.xml index a59ac619bd..12e957a3ba 100644 --- a/core-java-modules/core-java-io/pom.xml +++ b/core-java-modules/core-java-io/pom.xml @@ -38,11 +38,22 @@ ${fscontext.version} - javax.activation - activation - 1.1 + org.eclipse.angus + angus-activation + ${angus-activation.version} test + + org.jodd + jodd-util + ${jodd-util.version} + + + com.j256.simplemagic + simplemagic + ${simplemagic.version} + + @@ -54,6 +65,13 @@ + + maven-compiler-plugin + + 11 + 11 + + org.codehaus.mojo exec-maven-plugin @@ -73,10 +91,6 @@ org.apache.maven.plugins maven-javadoc-plugin ${maven-javadoc-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - @@ -131,13 +145,16 @@ - 3.0.0-M1 - 2.4.0 + 3.5.0 + 2.7.1 - 1.18 + 2.8.0 0.1.5 - 3.1.0 4.4.2 + 2.1.2 + 2.0.1 + 6.2.1 + 1.17 \ No newline at end of file diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/close/StreamCloseUnitTest.java b/core-java-modules/core-java-io/src/test/java/com/baeldung/close/StreamCloseUnitTest.java new file mode 100644 index 0000000000..aa462ba984 --- /dev/null +++ b/core-java-modules/core-java-io/src/test/java/com/baeldung/close/StreamCloseUnitTest.java @@ -0,0 +1,118 @@ +package com.baeldung.close; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.*; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.AutoCloseInputStream; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@RunWith(MockitoJUnitRunner.class) +public class StreamCloseUnitTest { + + private static final Logger log = LoggerFactory.getLogger(StreamCloseUnitTest.class); + + @Mock + private OutputStream wrappedOutputStream; + + @Mock + private InputStream wrappedInputStream; + + @Test + public void whenStreamClosedByFinally_thenIOStreamsCloseCalled() throws IOException { + + InputStream inputStream = null; + OutputStream outputStream = null; + + try { + inputStream = new BufferedInputStream(wrappedInputStream); + outputStream = new BufferedOutputStream(wrappedOutputStream); + } + finally { + try { + if (inputStream != null) + inputStream.close(); + } + catch (IOException ioe1) { + log.error("Cannot close InputStream"); + } + try { + if (outputStream != null) + outputStream.close(); + } + catch (IOException ioe2) { + log.error("Cannot close OutputStream"); + } + } + + verify(wrappedInputStream).close(); + verify(wrappedOutputStream).close(); + } + + @Test + public void whenStreamClosedByCloseQuietly_thenIOStreamsCloseCalled() throws IOException { + + InputStream inputStream = null; + OutputStream outputStream = null; + + try { + inputStream = new BufferedInputStream(wrappedInputStream); + outputStream = new BufferedOutputStream(wrappedOutputStream); + } + finally { + IOUtils.closeQuietly(inputStream); + IOUtils.closeQuietly(outputStream); + } + + verify(wrappedInputStream).close(); + verify(wrappedOutputStream).close(); + } + + @Test + public void whenFinishReadOnAutoCloseInputStream_thenInputStreamsCloseCalled() throws IOException { + + // Mimic no more data in the InputStream + when(wrappedInputStream.read(any(byte[].class))).thenReturn(-1); + + InputStream inputStream = AutoCloseInputStream.builder().setInputStream(wrappedInputStream).get(); + + byte[] buffer = new byte[256]; + while (inputStream.read(buffer) != -1) { + } + + verify(wrappedInputStream).close(); + } + + @Test + public void whenStreamClosedByWithResources_thenIOStreamsCloseCalled() throws IOException { + + try (BufferedInputStream inputStream = new BufferedInputStream(wrappedInputStream); + BufferedOutputStream outputStream = new BufferedOutputStream(wrappedOutputStream)) { + } + + verify(wrappedInputStream).close(); + verify(wrappedOutputStream).close(); + } + + @Test + public void whenStreamClosedByWithResourcesJava9_thenIOStreamsCloseCalled() throws IOException { + + InputStream inputStream = new BufferedInputStream(wrappedInputStream); + OutputStream outputStream = new BufferedOutputStream(wrappedOutputStream); + + try (inputStream; outputStream) { + } + + verify(wrappedInputStream).close(); + verify(wrappedOutputStream).close(); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/extension/ExtensionFromMimeTypeUnitTest.java b/core-java-modules/core-java-io/src/test/java/com/baeldung/extension/ExtensionFromMimeTypeUnitTest.java new file mode 100644 index 0000000000..f8f42861cc --- /dev/null +++ b/core-java-modules/core-java-io/src/test/java/com/baeldung/extension/ExtensionFromMimeTypeUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.extension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.tika.mime.MimeTypeException; + +import org.junit.Test; + +import com.j256.simplemagic.ContentInfo; + +public class ExtensionFromMimeTypeUnitTest { + private static final String IMAGE_JPEG_MIME_TYPE = "image/jpeg"; + @Test + public void whenUsingTika_thenGetFileExtension() throws MimeTypeException { + List expectedExtensions = Arrays.asList(".jpg", ".jpeg", ".jpe", ".jif", ".jfif", ".jfi"); + org.apache.tika.mime.MimeTypes allTypes = org.apache.tika.mime.MimeTypes.getDefaultMimeTypes(); + org.apache.tika.mime.MimeType type = allTypes.forName(IMAGE_JPEG_MIME_TYPE); + String primaryExtension = type.getExtension(); + assertEquals(".jpg", primaryExtension); + List detectedExtensions = type.getExtensions(); + assertThat(detectedExtensions).containsExactlyElementsOf(expectedExtensions); + } + + @Test + public void whenUsingJodd_thenGetFileExtension() { + List expectedExtensions = Arrays.asList("jpeg", "jpg", "jpe"); + String[] detectedExtensions = jodd.net.MimeTypes.findExtensionsByMimeTypes(IMAGE_JPEG_MIME_TYPE, false); + assertThat(detectedExtensions).containsExactlyElementsOf(expectedExtensions); + } + + @Test + public void whenUsingMimetypesFileTypeMap_thenGetFileExtension() { + List expectedExtensions = Arrays.asList("jpeg", "jpg", "jpe"); + ContentInfo contentInfo = new ContentInfo("", IMAGE_JPEG_MIME_TYPE, "", true); + String[] detectedExtensions = contentInfo.getFileExtensions(); + assertThat(detectedExtensions).containsExactlyElementsOf(expectedExtensions); + } + + @Test + public void whenUsingCustomLogic_thenGetFileExtension() { + Map> mimeExtensionsMap = new HashMap<>(); + List expectedExtensions = Arrays.asList(".jpg", ".jpe", ".jpeg"); + addMimeExtensions(mimeExtensionsMap, "image/jpeg", ".jpg"); + addMimeExtensions(mimeExtensionsMap, "image/jpeg", ".jpe"); + addMimeExtensions(mimeExtensionsMap, "image/jpeg", ".jpeg"); + + Set detectedExtensions = mimeExtensionsMap.get(IMAGE_JPEG_MIME_TYPE); + assertThat(detectedExtensions).containsExactlyElementsOf(expectedExtensions); + } + + private void addMimeExtensions(Map> map, String mimeType, String extension) { + map.computeIfAbsent(mimeType, k -> new HashSet<>()).add(extension); + } +} diff --git a/core-java-modules/core-java-io/src/test/java/com/baeldung/mimetype/MimeTypeUnitTest.java b/core-java-modules/core-java-io/src/test/java/com/baeldung/mimetype/MimeTypeUnitTest.java index bf916e39e7..4c382d07a6 100644 --- a/core-java-modules/core-java-io/src/test/java/com/baeldung/mimetype/MimeTypeUnitTest.java +++ b/core-java-modules/core-java-io/src/test/java/com/baeldung/mimetype/MimeTypeUnitTest.java @@ -10,7 +10,7 @@ import java.net.URLConnection; import java.nio.file.Files; import java.nio.file.Path; -import javax.activation.MimetypesFileTypeMap; +import jakarta.activation.MimetypesFileTypeMap; import org.apache.tika.Tika; import org.junit.Test; diff --git a/core-java-modules/core-java-jar/pom.xml b/core-java-modules/core-java-jar/pom.xml index ec88abe444..a46299c669 100644 --- a/core-java-modules/core-java-jar/pom.xml +++ b/core-java-modules/core-java-jar/pom.xml @@ -275,7 +275,6 @@ 1.1 3.0.0-M1 - 3.0.2 1.4.4 3.1.1 3.3.0 diff --git a/core-java-modules/core-java-lang-6/README.md b/core-java-modules/core-java-lang-6/README.md index 515e29bedd..9ddd08d9ba 100644 --- a/core-java-modules/core-java-lang-6/README.md +++ b/core-java-modules/core-java-lang-6/README.md @@ -6,3 +6,5 @@ This module contains articles about core features in the Java language - [Convert One Enum to Another Enum in Java](https://www.baeldung.com/java-convert-enums) - [What Is the Maximum Depth of the Java Call Stack?](https://www.baeldung.com/java-call-stack-max-depth) +- [Get a Random Element From a Set in Java](https://www.baeldung.com/java-set-draw-sample) +- [Stop Executing Further Code in Java](https://www.baeldung.com/java-stop-running-code) diff --git a/core-java-modules/core-java-lang-6/pom.xml b/core-java-modules/core-java-lang-6/pom.xml index 86121e0a7f..53ef36a898 100644 --- a/core-java-modules/core-java-lang-6/pom.xml +++ b/core-java-modules/core-java-lang-6/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.core-java-modules diff --git a/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java new file mode 100644 index 0000000000..7964ad9f52 --- /dev/null +++ b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/InterruptThread.java @@ -0,0 +1,13 @@ +package com.baeldung.stopexecution; + +public class InterruptThread extends Thread { + @Override + public void run() { + while (!isInterrupted()) { + if (isInterrupted()) { + break; + } + // business logic + } + } +} diff --git a/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/StopExecutionFurtherCode.java b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/StopExecutionFurtherCode.java new file mode 100644 index 0000000000..81abe15b5c --- /dev/null +++ b/core-java-modules/core-java-lang-6/src/main/java/com/baeldung/stopexecution/StopExecutionFurtherCode.java @@ -0,0 +1,87 @@ +package com.baeldung.stopexecution; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Locale; + +public class StopExecutionFurtherCode { + + boolean shouldContinue = true; + + int performTask(int a, int b) { + if (!shouldContinue) { + System.exit(0); + } + return a + b; + } + + void stop() { + this.shouldContinue = false; + } + + int calculateFactorial(int n) { + if (n <= 1) { + return 1; // base case + } + + return n * calculateFactorial(n - 1); + } + + int calculateSum(int[] x) { + int sum = 0; + for (int i = 0; i < 10; i++) { + if (x[i] < 0) { + break; + } + sum += x[i]; + } + return sum; + } + + T stopExecutionUsingException(T object) { + if (object instanceof Number) { + throw new IllegalArgumentException("Parameter can not be number."); + } + T upperCase = (T) String.valueOf(object) + .toUpperCase(Locale.ENGLISH); + return upperCase; + } + + int processLines(String[] lines) { + int statusCode = 0; + parser: + for (String line : lines) { + System.out.println("Processing line: " + line); + if (line.equals("stop")) { + System.out.println("Stopping parsing..."); + statusCode = -1; + break parser; // Stop parsing and exit the loop + } + System.out.println("Line processed."); + } + return statusCode; + } + + void download(String fileUrl, String destinationPath) throws MalformedURLException { + if (fileUrl == null || fileUrl.isEmpty() || destinationPath == null || destinationPath.isEmpty()) { + return; + } + // execute downloading + URL url = new URL(fileUrl); + try (InputStream in = url.openStream(); FileOutputStream out = new FileOutputStream(destinationPath)) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + + +} diff --git a/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/stopexecution/StopExecutionFurtherCodeUnitTest.java b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/stopexecution/StopExecutionFurtherCodeUnitTest.java new file mode 100644 index 0000000000..9cdb1e71aa --- /dev/null +++ b/core-java-modules/core-java-lang-6/src/test/java/com/baeldung/stopexecution/StopExecutionFurtherCodeUnitTest.java @@ -0,0 +1,90 @@ +package com.baeldung.stopexecution; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import java.net.MalformedURLException; + +import org.junit.Assert; +import org.junit.FixMethodOrder; +import org.junit.jupiter.api.Test; +import org.junit.runners.MethodSorters; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class StopExecutionFurtherCodeUnitTest { + + + @Test + void givenExecution_whenStopIsNotCalled_thenTaskIsPerformed() { + StopExecutionFurtherCode stopExecution = new StopExecutionFurtherCode(); + int performedTask = stopExecution.performTask(10, 20); + Assert.assertEquals(30, performedTask); + } + + // This test case have been commented because, otherwise, the program will exit since System.exit(statusCode) is being used. + /*@Test + void givenExecution_whenStopIsCalled_thenTaskNotPerformed() { + StopExecutionFurtherCode stopExecution = new StopExecutionFurtherCode(); + stopExecution.stop(); + int performedTask = stopExecution.performTask(10, 20); + Assert.assertEquals(30, performedTask); + }*/ + + @Test + void givenWrongUrlAndPath_whenDownloadCalled_thenExecutionIsStopped() throws MalformedURLException { + StopExecutionFurtherCode stopExecutionFurtherCode = new StopExecutionFurtherCode(); + stopExecutionFurtherCode.download("", ""); + } + + @Test + void givenName_whenStopExecutionUsingExceptionCalled_thenNameIsConvertedToUpper() { + StopExecutionFurtherCode stopExecutionFurtherCode = new StopExecutionFurtherCode(); + String name = "John"; + String result1 = stopExecutionFurtherCode.stopExecutionUsingException(name); + Assert.assertEquals("JOHN", result1); + try { + Integer number1 = 10; + Assert.assertThrows(IllegalArgumentException.class, () -> { + int result = stopExecutionFurtherCode.stopExecutionUsingException(number1); + }); + } catch (Exception e) { + Assert.fail("Unexpected exception thrown: " + e.getMessage()); + } + } + + @Test + void givenBaseCase_whenStopExecutionWhenBaseCaseKnownCalled_thenFactorialIsCalculated() throws MalformedURLException { + StopExecutionFurtherCode stopExecutionFurtherCode = new StopExecutionFurtherCode(); + int factorial = stopExecutionFurtherCode.calculateFactorial(1); + Assert.assertEquals(1, factorial); + } + + @Test + void givenArrayWithNegative_whenStopExecutionInLoopCalled_thenSumIsCalculatedIgnoringNegatives() { + StopExecutionFurtherCode stopExecutionFurtherCode = new StopExecutionFurtherCode(); + int[] nums = { 1, 2, 3, -1, 1, 2, 3 }; + int sum = stopExecutionFurtherCode.calculateSum(nums); + Assert.assertEquals(6, sum); + } + + @Test + void givenThreadRunning_whenInterrupted_thenThreadExecutionIsStopped() throws InterruptedException { + InterruptThread stopExecution = new InterruptThread(); + stopExecution.start(); + Thread.sleep(2000); + stopExecution.interrupt(); + stopExecution.join(); + Assert.assertTrue(!stopExecution.isAlive()); + } + + @Test + void givenLinesWithStopLabel_whenStopExecutionLabeledLoopCalled_thenLoopExecutionIsStopped() { + StopExecutionFurtherCode furtherCode = new StopExecutionFurtherCode(); + final String[] lines = { "Line 1", "Line 2", "Line 3", "stop", "Line 4", "Line 5" }; + int statusCode = furtherCode.processLines(lines); + Assert.assertEquals(-1, statusCode); + } + +} diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md index 847bd314a7..ef9c2ee4c4 100644 --- a/core-java-modules/core-java-lang-math-3/README.md +++ b/core-java-modules/core-java-lang-math-3/README.md @@ -11,4 +11,5 @@ - [Java Program to Calculate the Standard Deviation](https://www.baeldung.com/java-calculate-standard-deviation) - [Java Program to Print Pascal’s Triangle](https://www.baeldung.com/java-pascal-triangle) - [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency) +- [Clamp Function in Java](https://www.baeldung.com/java-clamp-function) - More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2) diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/clampfunction/Clamp.java b/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/clampfunction/Clamp.java new file mode 100644 index 0000000000..4c62c0560e --- /dev/null +++ b/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/clampfunction/Clamp.java @@ -0,0 +1,23 @@ +package com.baeldung.clampfunction; + +public class Clamp { + + public int clamp(int value, int min, int max) { + return Math.max(min, Math.min(max, value)); + } + + public double clamp(double value, double min, double max) { + return Math.max(min, Math.min(max, value)); + } + + public static > T clamp(T value, T min, T max) { + if (value.compareTo(min) < 0) { + return min; + } else if (value.compareTo(max) > 0) { + return max; + } else { + return value; + } + } + +} diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/clampfunction/ClampFunctionUnitTest.java b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/clampfunction/ClampFunctionUnitTest.java new file mode 100644 index 0000000000..a8d40caee0 --- /dev/null +++ b/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/clampfunction/ClampFunctionUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.clampfunction; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class ClampFunctionUnitTest { + + Clamp clampValue = new Clamp(); + + @Test + public void givenValueOutsideRange_whenClamp_thenReturnLowerValue() { + assertEquals(15, clampValue.clamp(10, 15, 35)); + } + + @Test + public void givenValueWithinRange_whenClamp_thenReturnValue() { + assertEquals(20, clampValue.clamp(20, 15, 35)); + } + + @Test + public void givenValueOutsideRange_whenClamp_thenReturnMaximumValue() { + assertEquals(35, clampValue.clamp(50, 15, 35)); + } + + @Test + public void givenDoubleValueOutsideRange_whenClamp_thenReturnMaximumValue() { + assertEquals(60.5, clampValue.clamp(75.6, 25.5, 60.5)); + } + + /* + * This method uses the clamp() method introduced in Java 21 + @Test + public void givenValueWithinRange_whenClamp_thenReturnValue() { + assertEquals(20, Math.clamp(20, 17, 98)); + } + */ + +} diff --git a/core-java-modules/core-java-lang-oop-inheritance/README.md b/core-java-modules/core-java-lang-oop-inheritance/README.md index c87bdf13d7..430f88e717 100644 --- a/core-java-modules/core-java-lang-oop-inheritance/README.md +++ b/core-java-modules/core-java-lang-oop-inheritance/README.md @@ -12,3 +12,4 @@ This module contains articles about inheritance in Java - [Guide to Inheritance in Java](https://www.baeldung.com/java-inheritance) - [Object Type Casting in Java](https://www.baeldung.com/java-type-casting) - [Variable and Method Hiding in Java](https://www.baeldung.com/java-variable-method-hiding) +- [Inner Classes Vs. Subclasses in Java](https://www.baeldung.com/java-inner-classes-vs-subclasses) diff --git a/core-java-modules/core-java-lang-oop-others/README.md b/core-java-modules/core-java-lang-oop-others/README.md index 09c1dadb8b..4adfec86ef 100644 --- a/core-java-modules/core-java-lang-oop-others/README.md +++ b/core-java-modules/core-java-lang-oop-others/README.md @@ -8,3 +8,4 @@ This module contains articles about Object Oriented Programming (OOP) in Java - [Pass-By-Value as a Parameter Passing Mechanism in Java](https://www.baeldung.com/java-pass-by-value-or-pass-by-reference) - [Check If All the Variables of an Object Are Null](https://www.baeldung.com/java-check-all-variables-object-null) - [Law of Demeter in Java](https://www.baeldung.com/java-demeter-law) +- [Java Interface Naming Conventions](https://www.baeldung.com/java-interface-naming-conventions) diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/Identifiable.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/Identifiable.java new file mode 100644 index 0000000000..080f63b295 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/Identifiable.java @@ -0,0 +1,5 @@ +package com.baeldung.interfaces.namingconventions; + +public interface Identifiable { + void identify(); +} diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/RegularUser.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/RegularUser.java new file mode 100644 index 0000000000..e75d01e365 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/RegularUser.java @@ -0,0 +1,13 @@ +package com.baeldung.interfaces.namingconventions; + +public class RegularUser implements User { + @Override + public void identify() { + // some implementation + } + + @Override + public void authorize() { + // some implementation + } +} diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/RootUser.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/RootUser.java new file mode 100644 index 0000000000..a02804d0b3 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/RootUser.java @@ -0,0 +1,13 @@ +package com.baeldung.interfaces.namingconventions; + +public class RootUser implements User { + @Override + public void identify() { + // some implementation + } + + @Override + public void authorize() { + // some implementation + } +} diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/User.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/User.java new file mode 100644 index 0000000000..2891126ddd --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/interfaces/namingconventions/User.java @@ -0,0 +1,5 @@ +package com.baeldung.interfaces.namingconventions; + +public interface User extends Identifiable { + void authorize(); +} diff --git a/core-java-modules/core-java-lang-operators-2/README.md b/core-java-modules/core-java-lang-operators-2/README.md index 86e17a678f..e8b792e634 100644 --- a/core-java-modules/core-java-lang-operators-2/README.md +++ b/core-java-modules/core-java-lang-operators-2/README.md @@ -9,3 +9,4 @@ This module contains articles about Java operators - [Getting a Bit at a Certain Position from Integral Values](https://www.baeldung.com/java-get-bit-at-position) - [Check if at Least Two Out of Three Booleans Are True in Java](https://www.baeldung.com/java-check-two-of-three-booleans) - [Alternatives for instanceof Operator in Java](https://www.baeldung.com/java-instanceof-alternatives) +- [What Does “––>” Mean in Java?](https://www.baeldung.com/java-minus-minus-greaterthan) diff --git a/core-java-modules/core-java-lang-operators-2/src/test/java/com/baeldung/doubleminusgreaterthan/DoubleMinusAndGreaterThanUnitTest.java b/core-java-modules/core-java-lang-operators-2/src/test/java/com/baeldung/doubleminusgreaterthan/DoubleMinusAndGreaterThanUnitTest.java new file mode 100644 index 0000000000..bf3934b2de --- /dev/null +++ b/core-java-modules/core-java-lang-operators-2/src/test/java/com/baeldung/doubleminusgreaterthan/DoubleMinusAndGreaterThanUnitTest.java @@ -0,0 +1,66 @@ +package com.baeldung.doubleminusgreaterthan; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import com.google.common.collect.Lists; + +public class DoubleMinusAndGreaterThanUnitTest { + + @Test + void whenUsingDoubleMinusAndGreaterThan_thenGetTheExpectedResult() { + List resultWhile = new ArrayList<>(); + int i = 6; + while (i-- > 0) { + resultWhile.add(i); + } + assertEquals(Lists.newArrayList(5, 4, 3, 2, 1, 0), resultWhile); + + List resultFor = new ArrayList<>(); + for (int j = 6; j-- > 0; ) { + resultFor.add(j); + } + + assertEquals(Lists.newArrayList(5, 4, 3, 2, 1, 0), resultFor); + } + + @Test + void whenUsingOtherOperatorsSimilarly_thenGetTheExpectedResult() { + // <++ + List result = new ArrayList<>(); + int i = -1; + while (i++ < 5) { + result.add(i); + } + assertEquals(Lists.newArrayList(0, 1, 2, 3, 4, 5), result); + + // <-- + result.clear(); + int j = 10; + while (0 < --j) { + result.add(j); + } + assertEquals(Lists.newArrayList(9, 8, 7, 6, 5, 4, 3, 2, 1), result); + + // >++ + result.clear(); + int n = 0; + while (6 > ++n) { + result.add(n); + } + assertEquals(Lists.newArrayList(1, 2, 3, 4, 5), result); + + // >>>= + result.clear(); + int x = 32; + while ((x >>>= 1) > 1) { + result.add(x); + } + assertEquals(Lists.newArrayList(16, 8, 4, 2), result); + + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java index 8b3685adf3..0a9418cb17 100644 --- a/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java +++ b/core-java-modules/core-java-lang-operators/src/test/java/com/baeldung/modulo/ModuloUnitTest.java @@ -1,54 +1,77 @@ package com.baeldung.modulo; +import static org.junit.Assert.assertEquals; + import org.junit.Test; import static org.assertj.core.api.Java6Assertions.*; public class ModuloUnitTest { - @Test - public void whenIntegerDivision_thenLosesRemainder(){ - assertThat(11 / 4).isEqualTo(2); - } - - @Test - public void whenDoubleDivision_thenKeepsRemainder(){ - assertThat(11 / 4.0).isEqualTo(2.75); - } - - @Test - public void whenModulo_thenReturnsRemainder(){ - assertThat(11 % 4).isEqualTo(3); - } - - @Test(expected = ArithmeticException.class) - public void whenDivisionByZero_thenArithmeticException(){ - double result = 1 / 0; - } - - @Test(expected = ArithmeticException.class) - public void whenModuloByZero_thenArithmeticException(){ - double result = 1 % 0; - } - - @Test - public void whenDivisorIsOddAndModulusIs2_thenResultIs1(){ - assertThat(3 % 2).isEqualTo(1); - } - - @Test - public void whenDivisorIsEvenAndModulusIs2_thenResultIs0(){ - assertThat(4 % 2).isEqualTo(0); - } - - @Test - public void whenItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds(){ - int QUEUE_CAPACITY= 10; - int[] circularQueue = new int[QUEUE_CAPACITY]; - int itemsInserted = 0; - for (int value = 0; value < 1000; value++) { - int writeIndex = ++itemsInserted % QUEUE_CAPACITY; - circularQueue[writeIndex] = value; + @Test + public void whenIntegerDivision_thenLosesRemainder() { + assertThat(11 / 4).isEqualTo(2); + } + + @Test + public void whenDoubleDivision_thenKeepsRemainder() { + assertThat(11 / 4.0).isEqualTo(2.75); + } + + @Test + public void whenModulo_thenReturnsRemainder() { + assertThat(11 % 4).isEqualTo(3); + } + + @Test(expected = ArithmeticException.class) + public void whenDivisionByZero_thenArithmeticException() { + double result = 1 / 0; + } + + @Test(expected = ArithmeticException.class) + public void whenModuloByZero_thenArithmeticException() { + double result = 1 % 0; + } + + @Test + public void whenDivisorIsOddAndModulusIs2_thenResultIs1() { + assertThat(3 % 2).isEqualTo(1); + } + + @Test + public void whenDivisorIsEvenAndModulusIs2_thenResultIs0() { + assertThat(4 % 2).isEqualTo(0); + } + + @Test + public void whenDividendIsNegativeAndModulusIs2_thenResultIsNegative() { + assertEquals(-1, -9 % 2); + } + + @Test + public void whenDividendIsNegativeAndRemainderIsCheckedForNegativeValue_thenResultIsPositive() { + int remainder = -9 % 2; + + if (remainder < 0) { + remainder += 2; + } + assertEquals(1, remainder); + } + + @Test + public void whenDividendIsNegativeAndUsesMathClass_thenResultIsPositive() { + int remainder = Math.floorMod(-9, 2); + assertEquals(1, remainder); + } + + @Test + public void whenItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds() { + int QUEUE_CAPACITY = 10; + int[] circularQueue = new int[QUEUE_CAPACITY]; + int itemsInserted = 0; + for (int value = 0; value < 1000; value++) { + int writeIndex = ++itemsInserted % QUEUE_CAPACITY; + circularQueue[writeIndex] = value; + } } - } } diff --git a/core-java-modules/core-java-nio-2/pom.xml b/core-java-modules/core-java-nio-2/pom.xml index e35b70cfc7..dde708c10d 100644 --- a/core-java-modules/core-java-nio-2/pom.xml +++ b/core-java-modules/core-java-nio-2/pom.xml @@ -13,4 +13,18 @@ 0.0.1-SNAPSHOT + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.nio=ALL-UNNAMED + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-6/README.md b/core-java-modules/core-java-numbers-6/README.md index 67f574652c..254b2b58d7 100644 --- a/core-java-modules/core-java-numbers-6/README.md +++ b/core-java-modules/core-java-numbers-6/README.md @@ -3,4 +3,5 @@ - [Convert Integer to Hexadecimal in Java](https://www.baeldung.com/java-convert-int-to-hex) - [Integer.class vs Integer.TYPE vs int.class](https://www.baeldung.com/java-integer-class-vs-type-vs-int) - [Does Java Read Integers in Little Endian or Big Endian?](https://www.baeldung.com/java-integers-little-big-endian) +- [How to Split an Integer Number Into Digits in Java](https://www.baeldung.com/java-integer-individual-digits) - More articles: [[<-- prev]](../core-java-numbers-5) diff --git a/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/integertodigits/IntegerToDigitsUnitTest.java b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/integertodigits/IntegerToDigitsUnitTest.java new file mode 100644 index 0000000000..3162fba814 --- /dev/null +++ b/core-java-modules/core-java-numbers-6/src/test/java/com/baeldung/integertodigits/IntegerToDigitsUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.integertodigits; + +import com.google.common.collect.Lists; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class IntegerToDigitsUnitTest { + private final static int THE_NUMBER = 1230456; + private final static List EXPECTED_INT_LIST = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6); + private final static String[] EXPECTED_STR_ARRAY = new String[] { "1", "2", "3", "0", "4", "5", "6" }; + private final static List EXPECTED_STR_LIST = Lists.newArrayList("1", "2", "3", "0", "4", "5", "6"); + private final static char[] EXPECTED_CHAR_ARRAY = new char[] { '1', '2', '3', '0', '4', '5', '6' }; + + @Test + void whenUsingModOperator_thenGetExpectedResult() { + int number = THE_NUMBER; + LinkedList result = new LinkedList<>(); + while (number > 0) { + result.push(number % 10); + number /= 10; + } + assertEquals(EXPECTED_INT_LIST, result); + } + + + private void collectDigits(int num, List digitList) { + if (num / 10 > 0) { + collectDigits(num / 10, digitList); + } + digitList.add(num % 10); + } + + @Test + void whenUsingModOperatorAndRecursion_thenGetExpectedResult() { + List result = new ArrayList<>(); + collectDigits(THE_NUMBER, result); + assertEquals(EXPECTED_INT_LIST, result); + } + + @Test + void whenUsingIntStream_thenGetExpectedResult() { + String numStr = String.valueOf(THE_NUMBER); + List result = numStr.chars().map(Character::getNumericValue).boxed().collect(Collectors.toList()); + assertEquals(EXPECTED_INT_LIST, result); + } + + @Test + void whenUsingToCharArray_thenGetExpectedResult() { + String numStr = String.valueOf(THE_NUMBER); + char[] result = numStr.toCharArray(); + assertArrayEquals(EXPECTED_CHAR_ARRAY, result); + } + + @Test + void whenUsingSplit_thenGetExpectedResult() { + String numStr = String.valueOf(THE_NUMBER); + String[] result = numStr.split("(?<=.)"); + assertArrayEquals(EXPECTED_STR_ARRAY, result); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-numbers-conversions/README.md b/core-java-modules/core-java-numbers-conversions/README.md index b4c593c494..27a07a5f8b 100644 --- a/core-java-modules/core-java-numbers-conversions/README.md +++ b/core-java-modules/core-java-numbers-conversions/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Convert a Number to a Letter in Java](https://www.baeldung.com/java-convert-number-to-letter) - [Convert Long to BigDecimal in Java](https://www.baeldung.com/java-convert-long-bigdecimal) +- [Convert int to Long in Java](https://www.baeldung.com/java-convert-int-long) diff --git a/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/inttolong/IntToLongUnitTest.java b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/inttolong/IntToLongUnitTest.java new file mode 100644 index 0000000000..bc4109b42a --- /dev/null +++ b/core-java-modules/core-java-numbers-conversions/src/test/java/com/baeldung/inttolong/IntToLongUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.inttolong; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class IntToLongUnitTest { + + @Test + void whenUsingTheAutoboxing_thenGetTheExpectedLong() { + int intTen = 10; + Long longTen = (long) intTen; + assertEquals(intTen, longTen); + } + + @Test + void whenUsingTheValueOf_thenGetTheExpectedLong() { + int intTen = 10; + Long longTen = Long.valueOf(intTen); + assertEquals(intTen, longTen); + } + + @Test + void whenUsingTheConstructor_thenGetTheExpectedLong() { + int intTen = 10; + Long longTen = new Long(intTen); + assertEquals(intTen, longTen); + } + + @Test + void whenUsingTheParseLong_thenGetTheExpectedLong() { + int intTen = 10; + Long longTen = Long.parseLong(String.valueOf(intTen)); + assertEquals(intTen, longTen); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-perf-2/README.md b/core-java-modules/core-java-perf-2/README.md index 8718060645..aea10fa69c 100644 --- a/core-java-modules/core-java-perf-2/README.md +++ b/core-java-modules/core-java-perf-2/README.md @@ -5,3 +5,4 @@ This module contains articles about performance of Java applications ### Relevant Articles: - [External Debugging With JMXTerm](https://www.baeldung.com/java-jmxterm-external-debugging) - [Create and Detect Memory Leaks in Java](https://www.baeldung.com/java-create-detect-memory-leaks) +- [Differences Between Heap Dump, Thread Dump and Core Dump](https://www.baeldung.com/java-heap-thread-core-dumps) diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/CoreDump.c b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/CoreDump.c new file mode 100644 index 0000000000..4a8b2c2b83 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/CoreDump.c @@ -0,0 +1,15 @@ +#include +#include "CoreDump.h" + +void core() { + int *p = NULL; + *p = 0; +} + +JNIEXPORT void JNICALL Java_CoreDump_core (JNIEnv *env, jobject obj) { + core(); +}; + +void main() { +} + diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/CoreDump.h b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/CoreDump.h new file mode 100644 index 0000000000..3b0e34b77d --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/CoreDump.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class CoreDump */ + +#ifndef _Included_CoreDump +#define _Included_CoreDump +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: CoreDump + * Method: core + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_CoreDump_core + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/CoreDump.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/CoreDump.java new file mode 100644 index 0000000000..17725ee567 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/CoreDump.java @@ -0,0 +1,13 @@ +package com.baeldung.dumps; + +public class CoreDump { + static { + System.loadLibrary("nativelib"); + } + + public static void main(String[] args) { + new CoreDump().core(); + } + + private native void core(); +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/HeapDump.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/HeapDump.java new file mode 100644 index 0000000000..c117c4f9a9 --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/HeapDump.java @@ -0,0 +1,19 @@ +package com.baeldung.dumps; + +import java.util.ArrayList; +import java.util.List; + +public class HeapDump { + public static void main(String[] args) { + List numbers = new ArrayList<>(); + + try { + while (true) { + numbers.add(10); + } + } catch (OutOfMemoryError e) { + System.out.println("Out of memory error occurred!"); + } + } + +} diff --git a/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/ThreadDump.java b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/ThreadDump.java new file mode 100644 index 0000000000..1d76c911de --- /dev/null +++ b/core-java-modules/core-java-perf-2/src/main/java/com/baeldung/dumps/ThreadDump.java @@ -0,0 +1,18 @@ +package com.baeldung.dumps; + +public class ThreadDump { + public static void main(String[] args) { + longRunningTask(); + } + + private static void longRunningTask() { + for (int i = 0; i < Integer.MAX_VALUE; i++) { + if (Thread.currentThread().isInterrupted()) { + System.out.println("Interrupted!"); + break; + } + System.out.println(i); + } + } + +} diff --git a/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceTest.java b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceUnitTest.java similarity index 95% rename from core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceTest.java rename to core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceUnitTest.java index 90c96cba1b..ca288560a1 100644 --- a/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceTest.java +++ b/core-java-modules/core-java-perf-2/src/test/java/com/baeldung/lapsedlistener/MovieQuoteServiceUnitTest.java @@ -4,7 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -class MovieQuoteServiceTest { +class MovieQuoteServiceUnitTest { @Test void whenSubscribeToService_thenServiceHasOneSubscriber() { diff --git a/core-java-modules/core-java-reflection-2/README.md b/core-java-modules/core-java-reflection-2/README.md index 4918b1fe98..dfd6bf28e6 100644 --- a/core-java-modules/core-java-reflection-2/README.md +++ b/core-java-modules/core-java-reflection-2/README.md @@ -9,3 +9,4 @@ - [Invoke a Static Method Using Java Reflection API](https://www.baeldung.com/java-invoke-static-method-reflection) - [What Is the JDK com.sun.proxy.$Proxy Class?](https://www.baeldung.com/jdk-com-sun-proxy) - [Unit Test Private Methods in Java](https://www.baeldung.com/java-unit-test-private-methods) +- [Constructing Java Objects From Only the Class Name](https://www.baeldung.com/java-objects-make-using-class-name) diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/BronzeJobCard.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/BronzeJobCard.java new file mode 100644 index 0000000000..cb8d7e8422 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/BronzeJobCard.java @@ -0,0 +1,21 @@ +package com.baeldung.reflection.createobject.basic; + +import java.lang.reflect.InvocationTargetException; + +public class BronzeJobCard { + private Object jobType; + public void setJobType(String jobType) throws ClassNotFoundException, + NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Class jobTypeClass = Class.forName(jobType); + this.jobType = jobTypeClass.getDeclaredConstructor().newInstance(); + } + public String startJob() { + if(this.jobType instanceof RepairJob) { + return "Start Bronze " + ((RepairJob) this.jobType).getJobType(); + } + if(this.jobType instanceof MaintenanceJob) { + return "Start Bronze " + ((MaintenanceJob) this.jobType).getJobType(); + } + return "Bronze Job Failed"; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/GoldJobCard.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/GoldJobCard.java new file mode 100644 index 0000000000..f6b14b9355 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/GoldJobCard.java @@ -0,0 +1,17 @@ +package com.baeldung.reflection.createobject.basic; + +import java.lang.reflect.InvocationTargetException; + +public class GoldJobCard { + private T jobType; + + public void setJobType(Class jobTypeClass) throws + NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + this.jobType = jobTypeClass.getDeclaredConstructor().newInstance(); + } + + public String startJob() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + return "Start Gold " + this.jobType.getClass().getMethod("getJobType") + .invoke(this.jobType).toString(); + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/MaintenanceJob.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/MaintenanceJob.java new file mode 100644 index 0000000000..8c268f0491 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/MaintenanceJob.java @@ -0,0 +1,7 @@ +package com.baeldung.reflection.createobject.basic; + +public class MaintenanceJob { + public String getJobType() { + return "Maintenance Job"; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/PaintJob.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/PaintJob.java new file mode 100644 index 0000000000..74e6e2ccd2 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/PaintJob.java @@ -0,0 +1,7 @@ +package com.baeldung.reflection.createobject.basic; + +public class PaintJob { + public String getJobType() { + return "Paint Job"; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/RepairJob.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/RepairJob.java new file mode 100644 index 0000000000..22fe8e3742 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/RepairJob.java @@ -0,0 +1,7 @@ +package com.baeldung.reflection.createobject.basic; + +public class RepairJob { + public String getJobType() { + return "Repair Job"; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/SilverJobCard.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/SilverJobCard.java new file mode 100644 index 0000000000..231924bbaa --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/basic/SilverJobCard.java @@ -0,0 +1,22 @@ +package com.baeldung.reflection.createobject.basic; + +import java.lang.reflect.InvocationTargetException; + +public class SilverJobCard { + private Object jobType; + + public void setJobType(Class jobTypeClass) throws + NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + this.jobType = jobTypeClass.getDeclaredConstructor().newInstance(); + } + + public String startJob() { + if (this.jobType instanceof RepairJob) { + return "Start Silver " + ((RepairJob) this.jobType).getJobType(); + } + if (this.jobType instanceof MaintenanceJob) { + return "Start Silver " + ((MaintenanceJob) this.jobType).getJobType(); + } + return "Silver Job Failed"; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/Job.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/Job.java new file mode 100644 index 0000000000..4fbf00e775 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/Job.java @@ -0,0 +1,5 @@ +package com.baeldung.reflection.createobject.special; + +public interface Job { + String getJobType(); +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/MaintenanceJob.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/MaintenanceJob.java new file mode 100644 index 0000000000..d93c20a09a --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/MaintenanceJob.java @@ -0,0 +1,7 @@ +package com.baeldung.reflection.createobject.special; + +public class MaintenanceJob implements Job { + public String getJobType() { + return "Maintenance Job"; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/PaintJob.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/PaintJob.java new file mode 100644 index 0000000000..3eae7cb0c6 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/PaintJob.java @@ -0,0 +1,8 @@ +package com.baeldung.reflection.createobject.special; + +public class PaintJob implements Job { + @Override + public String getJobType() { + return "Paint Job"; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/PlatinumJobCard.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/PlatinumJobCard.java new file mode 100644 index 0000000000..4dd71e7fea --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/PlatinumJobCard.java @@ -0,0 +1,16 @@ +package com.baeldung.reflection.createobject.special; + +import java.lang.reflect.InvocationTargetException; + +public class PlatinumJobCard { + private T jobType; + + public void setJobType(Class jobTypeClass) throws + NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + this.jobType = jobTypeClass.getDeclaredConstructor().newInstance(); + } + + public String startJob() { + return "Start Platinum " + this.jobType.getJobType(); + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/RepairJob.java b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/RepairJob.java new file mode 100644 index 0000000000..985160fe48 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/java/com/baeldung/reflection/createobject/special/RepairJob.java @@ -0,0 +1,7 @@ +package com.baeldung.reflection.createobject.special; + +public class RepairJob implements Job { + public String getJobType() { + return "Repair Job"; + } +} diff --git a/core-java-modules/core-java-reflection-2/src/main/resources/Bronze.puml b/core-java-modules/core-java-reflection-2/src/main/resources/Bronze.puml new file mode 100644 index 0000000000..21f05fe52b --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/resources/Bronze.puml @@ -0,0 +1,20 @@ +@startuml +'https://plantuml.com/class-diagram + +class BronzeJobCard { + -Object jobType + +setJobType(String jobType) + +startJob() +} + +class MaintenanceJob { + +getJobType() +} +class RepairJob { + +getJobType() +} +BronzeJobCard -left-> MaintenanceJob:creates +BronzeJobCard -right-> RepairJob:creates + + +@enduml \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-2/src/main/resources/Gold.puml b/core-java-modules/core-java-reflection-2/src/main/resources/Gold.puml new file mode 100644 index 0000000000..2055154c21 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/resources/Gold.puml @@ -0,0 +1,20 @@ +@startuml +'https://plantuml.com/class-diagram + +class GoldJobCard { + -T jobType + +setJobType(Class jobTypeClass) + +startJob() +} + +class MaintenanceJob { + +getJobType() +} +class RepairJob { + +getJobType() +} +GoldJobCard -left-> MaintenanceJob:creates +GoldJobCard -right-> RepairJob:creates + + +@enduml \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-2/src/main/resources/Platinum.puml b/core-java-modules/core-java-reflection-2/src/main/resources/Platinum.puml new file mode 100644 index 0000000000..d9dc9b028d --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/resources/Platinum.puml @@ -0,0 +1,25 @@ +@startuml +'https://plantuml.com/class-diagram +interface Job { ++getJobType +} +class PlatinumJobCard { + +setJobType(Class jobTypeClass) + +startJob() +} + +class MaintenanceJob implements Job { + +getJobType() +} +class RepairJob implements Job { + +getJobType() +} +class PaintJob implements Job { + +getJobType() +} +PlatinumJobCard -up-> MaintenanceJob:creates +PlatinumJobCard -up-> RepairJob:creates +PlatinumJobCard -up-> PaintJob:creates + + +@enduml \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-2/src/main/resources/Silver.puml b/core-java-modules/core-java-reflection-2/src/main/resources/Silver.puml new file mode 100644 index 0000000000..46a9c88295 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/main/resources/Silver.puml @@ -0,0 +1,20 @@ +@startuml +'https://plantuml.com/class-diagram + +class SilverJobCard { + -Object jobType + +setJobType(Class jobTypeClass); + +startJob(); +} + +class MaintenanceJob { + +getJobType(); +} +class RepairJob { + +getJobType(); +} +SilverJobCard -left-> MaintenanceJob:creates +SilverJobCard -right-> RepairJob:creates + + +@enduml \ No newline at end of file diff --git a/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/createobject/CreateObjectBasicUnitTest.java b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/createobject/CreateObjectBasicUnitTest.java new file mode 100644 index 0000000000..c8dcabf190 --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/createobject/CreateObjectBasicUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.reflection.createobject; + +import com.baeldung.reflection.createobject.basic.*; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.InvocationTargetException; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class CreateObjectBasicUnitTest { + @Test + public void givenBronzeJobCard_whenJobTypeRepairAndMaintenance_thenStartJob() throws ClassNotFoundException, + InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + + BronzeJobCard bronzeJobCard1 = new BronzeJobCard(); + bronzeJobCard1.setJobType("com.baeldung.reflection.createobject.basic.RepairJob"); + assertEquals("Start Bronze Repair Job", bronzeJobCard1.startJob()); + + BronzeJobCard bronzeJobCard2 = new BronzeJobCard(); + bronzeJobCard2.setJobType("com.baeldung.reflection.createobject.basic.MaintenanceJob"); + assertEquals("Start Bronze Maintenance Job", bronzeJobCard2.startJob()); + } + @Test + public void givenBronzeJobCard_whenJobTypePaint_thenFailJob() throws ClassNotFoundException, + InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + + BronzeJobCard bronzeJobCard = new BronzeJobCard(); + bronzeJobCard.setJobType("com.baeldung.reflection.createobject.basic.PaintJob"); + assertEquals("Bronze Job Failed", bronzeJobCard.startJob()); + } + @Test + public void givenSilverJobCard_whenJobTypeRepairAndMaintenance_thenStartJob() throws InvocationTargetException, + NoSuchMethodException, InstantiationException, IllegalAccessException { + + SilverJobCard silverJobCard1 = new SilverJobCard(); + silverJobCard1.setJobType(RepairJob.class); + assertEquals("Start Silver Repair Job", silverJobCard1.startJob()); + + SilverJobCard silverJobCard2 = new SilverJobCard(); + silverJobCard2.setJobType(MaintenanceJob.class); + assertEquals("Start Silver Maintenance Job", silverJobCard2.startJob()); + } + @Test + public void givenSilverJobCard_whenJobTypePaint_thenFailJob() throws ClassNotFoundException, + InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + + SilverJobCard silverJobCard = new SilverJobCard(); + silverJobCard.setJobType(PaintJob.class); + assertEquals("Silver Job Failed", silverJobCard.startJob()); + } + @Test + public void givenGoldJobCard_whenJobTypeRepairMaintenanceAndPaint_thenStartJob() throws InvocationTargetException, + NoSuchMethodException, InstantiationException, IllegalAccessException { + + GoldJobCard goldJobCard1 = new GoldJobCard(); + goldJobCard1.setJobType(RepairJob.class); + assertEquals("Start Gold Repair Job", goldJobCard1.startJob()); + + GoldJobCard goldJobCard2 = new GoldJobCard(); + goldJobCard2.setJobType(MaintenanceJob.class); + assertEquals("Start Gold Maintenance Job", goldJobCard2.startJob()); + + GoldJobCard goldJobCard3 = new GoldJobCard(); + goldJobCard3.setJobType(PaintJob.class); + assertEquals("Start Gold Paint Job", goldJobCard3.startJob()); + } +} diff --git a/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/createobject/CreateObjectSpecialUnitTest.java b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/createobject/CreateObjectSpecialUnitTest.java new file mode 100644 index 0000000000..99fdf7be2d --- /dev/null +++ b/core-java-modules/core-java-reflection-2/src/test/java/com/baeldung/reflection/createobject/CreateObjectSpecialUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.reflection.createobject; + +import com.baeldung.reflection.createobject.special.MaintenanceJob; +import com.baeldung.reflection.createobject.special.PaintJob; +import com.baeldung.reflection.createobject.special.PlatinumJobCard; +import com.baeldung.reflection.createobject.special.RepairJob; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.InvocationTargetException; + +public class CreateObjectSpecialUnitTest { + @Test + public void givenPlatinumJobCard_whenJobTypeRepairMaintenanceAndPaint_thenStartJob() throws InvocationTargetException, + NoSuchMethodException, InstantiationException, IllegalAccessException { + + PlatinumJobCard platinumJobCard1 = new PlatinumJobCard(); + platinumJobCard1.setJobType(RepairJob.class); + assertEquals("Start Platinum Repair Job", platinumJobCard1.startJob()); + + PlatinumJobCard platinumJobCard2 = new PlatinumJobCard(); + platinumJobCard2.setJobType(MaintenanceJob.class); + assertEquals("Start Platinum Maintenance Job", platinumJobCard2.startJob()); + + PlatinumJobCard platinumJobCard3 = new PlatinumJobCard(); + platinumJobCard3.setJobType(PaintJob.class); + assertEquals("Start Platinum Paint Job", platinumJobCard3.startJob()); + } +} diff --git a/core-java-modules/core-java-reflection/src/main/java/com/baeldung/reflection/Employee.java b/core-java-modules/core-java-reflection/src/main/java/com/baeldung/reflection/Employee.java index 833cf26b14..43229b3d0e 100644 --- a/core-java-modules/core-java-reflection/src/main/java/com/baeldung/reflection/Employee.java +++ b/core-java-modules/core-java-reflection/src/main/java/com/baeldung/reflection/Employee.java @@ -2,6 +2,7 @@ package com.baeldung.reflection; public class Employee extends Person { + public static final String LABEL = "employee"; public int employeeId; } diff --git a/core-java-modules/core-java-reflection/src/test/java/com/baeldung/reflection/PersonAndEmployeeReflectionUnitTest.java b/core-java-modules/core-java-reflection/src/test/java/com/baeldung/reflection/PersonAndEmployeeReflectionUnitTest.java index cb1b5e926a..0a5764171b 100644 --- a/core-java-modules/core-java-reflection/src/test/java/com/baeldung/reflection/PersonAndEmployeeReflectionUnitTest.java +++ b/core-java-modules/core-java-reflection/src/test/java/com/baeldung/reflection/PersonAndEmployeeReflectionUnitTest.java @@ -1,6 +1,7 @@ package com.baeldung.reflection; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -9,128 +10,170 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; -import static org.junit.Assert.*; +import org.junit.Test; public class PersonAndEmployeeReflectionUnitTest { - // Fields names private static final String LAST_NAME_FIELD = "lastName"; private static final String FIRST_NAME_FIELD = "firstName"; private static final String EMPLOYEE_ID_FIELD = "employeeId"; + private static final String EMPLOYEE_TYPE_FIELD = "LABEL"; private static final String MONTH_EMPLOYEE_REWARD_FIELD = "reward"; @Test public void givenPersonClass_whenGetDeclaredFields_thenTwoFields() { - // When - Field[] allFields = Person.class.getDeclaredFields(); + List allFields = Arrays.asList(Person.class.getDeclaredFields()); - // Then - assertEquals(2, allFields.length); - - assertTrue(Arrays.stream(allFields).anyMatch(field -> - field.getName().equals(LAST_NAME_FIELD) - && field.getType().equals(String.class)) - ); - assertTrue(Arrays.stream(allFields).anyMatch(field -> - field.getName().equals(FIRST_NAME_FIELD) - && field.getType().equals(String.class)) - ); + assertEquals(2, allFields.size()); + Field lastName = allFields.stream() + .filter(field -> field.getName() + .equals(LAST_NAME_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(String.class, lastName.getType()); + Field firstName = allFields.stream() + .filter(field -> field.getName() + .equals(FIRST_NAME_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(String.class, firstName.getType()); } @Test - public void givenEmployeeClass_whenGetDeclaredFields_thenOneField() { - // When - Field[] allFields = Employee.class.getDeclaredFields(); + public void givenEmployeeClass_whenGetDeclaredFields_thenFilterAndReturnStaticField() { + List publicStaticField = Arrays.stream(Employee.class.getDeclaredFields()) + .filter(field -> Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) + .collect(Collectors.toList()); - // Then - assertEquals(1, allFields.length); - - assertTrue(Arrays.stream(allFields).anyMatch(field -> - field.getName().equals(EMPLOYEE_ID_FIELD) - && field.getType().equals(int.class)) - ); + assertEquals(1, publicStaticField.size()); + Field employeeTypeField = publicStaticField.get(0); + assertEquals(EMPLOYEE_TYPE_FIELD, employeeTypeField.getName()); } @Test - public void givenEmployeeClass_whenSuperClassGetDeclaredFields_thenOneField() { - // When - Field[] allFields = Employee.class.getSuperclass().getDeclaredFields(); + public void givenEmployeeClass_whenGetDeclaredFields_thenTwoField() { + List allFields = Arrays.asList(Employee.class.getDeclaredFields()); - // Then - assertEquals(2, allFields.length); - - assertTrue(Arrays.stream(allFields).anyMatch(field -> - field.getName().equals(LAST_NAME_FIELD) - && field.getType().equals(String.class)) - ); - assertTrue(Arrays.stream(allFields).anyMatch(field -> - field.getName().equals(FIRST_NAME_FIELD) - && field.getType().equals(String.class)) - ); + assertEquals(2, allFields.size()); + Field employeeIdField = allFields.stream() + .filter(field -> field.getName() + .equals(EMPLOYEE_ID_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(int.class, employeeIdField.getType()); + Field employeeTypeField = allFields.stream() + .filter(field -> field.getName() + .equals(EMPLOYEE_TYPE_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(String.class, employeeTypeField.getType()); } @Test - public void givenEmployeeClass_whenGetDeclaredFieldsOnBothClasses_thenThreeFields() { - // When - Field[] personFields = Employee.class.getSuperclass().getDeclaredFields(); - Field[] employeeFields = Employee.class.getDeclaredFields(); - Field[] allFields = new Field[employeeFields.length + personFields.length]; - Arrays.setAll(allFields, i -> (i < personFields.length ? personFields[i] : employeeFields[i - personFields.length])); + public void givenEmployeeClass_whenSuperClassGetDeclaredFields_thenTwoField() { + List allFields = Arrays.asList(Employee.class.getSuperclass() + .getDeclaredFields()); - // Then - assertEquals(3, allFields.length); + assertEquals(2, allFields.size()); + Field lastNameField = allFields.stream() + .filter(field -> field.getName() + .equals(LAST_NAME_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(String.class, lastNameField.getType()); + Field firstNameField = allFields.stream() + .filter(field -> field.getName() + .equals(FIRST_NAME_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(String.class, firstNameField.getType()); + } - assertTrue(Arrays.stream(allFields).anyMatch(field -> - field.getName().equals(LAST_NAME_FIELD) - && field.getType().equals(String.class)) - ); - assertTrue(Arrays.stream(allFields).anyMatch(field -> - field.getName().equals(FIRST_NAME_FIELD) - && field.getType().equals(String.class)) - ); - assertTrue(Arrays.stream(allFields).anyMatch(field -> - field.getName().equals(EMPLOYEE_ID_FIELD) - && field.getType().equals(int.class)) - ); + @Test + public void givenEmployeeClass_whenGetDeclaredFieldsOnBothClasses_thenFourFields() { + List personFields = Arrays.asList(Employee.class.getSuperclass() + .getDeclaredFields()); + List employeeFields = Arrays.asList(Employee.class.getDeclaredFields()); + List allFields = Stream.concat(personFields.stream(), employeeFields.stream()) + .collect(Collectors.toList()); + + assertEquals(4, allFields.size()); + Field lastNameField = allFields.stream() + .filter(field -> field.getName() + .equals(LAST_NAME_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(String.class, lastNameField.getType()); + Field firstNameField = allFields.stream() + .filter(field -> field.getName() + .equals(FIRST_NAME_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(String.class, firstNameField.getType()); + Field employeeIdField = allFields.stream() + .filter(field -> field.getName() + .equals(EMPLOYEE_ID_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(int.class, employeeIdField.getType()); + Field employeeTypeField = allFields.stream() + .filter(field -> field.getName() + .equals(EMPLOYEE_TYPE_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(String.class, employeeTypeField.getType()); } @Test public void givenEmployeeClass_whenGetDeclaredFieldsOnEmployeeSuperclassWithModifiersFilter_thenOneFields() { - // When - List personFields = Arrays.stream(Employee.class.getSuperclass().getDeclaredFields()) - .filter(f -> Modifier.isPublic(f.getModifiers()) || Modifier.isProtected(f.getModifiers())) - .collect(Collectors.toList()); + List personFields = Arrays.stream(Employee.class.getSuperclass() + .getDeclaredFields()) + .filter(f -> Modifier.isPublic(f.getModifiers()) || Modifier.isProtected(f.getModifiers())) + .collect(Collectors.toList()); - // Then assertEquals(1, personFields.size()); - - assertTrue(personFields.stream().anyMatch(field -> - field.getName().equals(LAST_NAME_FIELD) - && field.getType().equals(String.class)) - ); + Field personField = personFields.stream() + .filter(field -> field.getName() + .equals(LAST_NAME_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")); + assertEquals(String.class, personField.getType()); } @Test - public void givenMonthEmployeeClass_whenGetAllFields_thenThreeFields() { - // When + public void givenMonthEmployeeClass_whenGetAllFields_thenFourFields() { List allFields = getAllFields(MonthEmployee.class); - // Then - assertEquals(3, allFields.size()); - - assertTrue(allFields.stream().anyMatch(field -> - field.getName().equals(LAST_NAME_FIELD) - && field.getType().equals(String.class)) - ); - assertTrue(allFields.stream().anyMatch(field -> - field.getName().equals(EMPLOYEE_ID_FIELD) - && field.getType().equals(int.class)) - ); - assertTrue(allFields.stream().anyMatch(field -> - field.getName().equals(MONTH_EMPLOYEE_REWARD_FIELD) - && field.getType().equals(double.class)) - ); + assertEquals(4, allFields.size()); + assertFalse(allFields.stream() + .anyMatch(field -> field.getName() + .equals(FIRST_NAME_FIELD))); + assertEquals(String.class, allFields.stream() + .filter(field -> field.getName() + .equals(LAST_NAME_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")) + .getType()); + assertEquals(int.class, allFields.stream() + .filter(field -> field.getName() + .equals(EMPLOYEE_ID_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")) + .getType()); + assertEquals(double.class, allFields.stream() + .filter(field -> field.getName() + .equals(MONTH_EMPLOYEE_REWARD_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")) + .getType()); + assertEquals(String.class, allFields.stream() + .filter(field -> field.getName() + .equals(EMPLOYEE_TYPE_FIELD)) + .findFirst() + .orElseThrow(() -> new RuntimeException("Field not found")) + .getType()); } public List getAllFields(Class clazz) { @@ -140,8 +183,8 @@ public class PersonAndEmployeeReflectionUnitTest { List result = new ArrayList<>(getAllFields(clazz.getSuperclass())); List filteredFields = Arrays.stream(clazz.getDeclaredFields()) - .filter(f -> Modifier.isPublic(f.getModifiers()) || Modifier.isProtected(f.getModifiers())) - .collect(Collectors.toList()); + .filter(f -> Modifier.isPublic(f.getModifiers()) || Modifier.isProtected(f.getModifiers())) + .collect(Collectors.toList()); result.addAll(filteredFields); return result; } diff --git a/core-java-modules/core-java-regex-2/README.md b/core-java-modules/core-java-regex-2/README.md index ccf60f56d9..02e470cce5 100644 --- a/core-java-modules/core-java-regex-2/README.md +++ b/core-java-modules/core-java-regex-2/README.md @@ -7,4 +7,6 @@ - [Creating a Java Array from Regular Expression Matches](https://www.baeldung.com/java-array-regex-matches) - [Getting the Text That Follows After the Regex Match in Java](https://www.baeldung.com/java-regex-text-after-match) - [Regular Expression: \z vs \Z Anchors in Java](https://www.baeldung.com/java-regular-expression-z-vs-z-anchors) +- [Extract Text Between Square Brackets](https://www.baeldung.com/java-get-content-between-square-brackets) +- [Get the Indexes of Regex Pattern Matches in Java](https://www.baeldung.com/java-indexes-regex-pattern-matches) - More articles: [[<-- prev]](/core-java-modules/core-java-regex) diff --git a/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/indexesofmatches/IndexesOfMatchesUnitTest.java b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/indexesofmatches/IndexesOfMatchesUnitTest.java new file mode 100644 index 0000000000..7fb2afcdea --- /dev/null +++ b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/indexesofmatches/IndexesOfMatchesUnitTest.java @@ -0,0 +1,75 @@ +package com.baeldung.regex.indexesofmatches; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +public class IndexesOfMatchesUnitTest { + private static final String INPUT = "This line contains , , and ."; + + @Test + void whenUsingNorCharClass_thenGetExpectedTexts() { + Pattern pattern = Pattern.compile("<[^>]*>"); + Matcher matcher = pattern.matcher(INPUT); + List result = new ArrayList<>(); + while (matcher.find()) { + result.add(matcher.group()); + } + assertThat(result).containsExactly("", "", ""); + } + + @Test + void whenCallingMatcherEnd_thenGetIndexesAfterTheMatchSequence() { + Pattern pattern = Pattern.compile("456"); + Matcher matcher = pattern.matcher("0123456789"); + String result = null; + int startIdx = -1; + int endIdx = -1; + if (matcher.find()) { + result = matcher.group(); + startIdx = matcher.start(); + endIdx = matcher.end(); + } + assertThat(result).isEqualTo("456"); + assertThat(startIdx).isEqualTo(4); + assertThat(endIdx).isEqualTo(7); + } + + @Test + void whenUsingMatcherStartAndEnd_thenGetIndexesOfMatches() { + Pattern pattern = Pattern.compile("<[^>]*>"); + Matcher matcher = pattern.matcher(INPUT); + List result = new ArrayList<>(); + Map indexesOfMatches = new LinkedHashMap<>(); + while (matcher.find()) { + result.add(matcher.group()); + indexesOfMatches.put(matcher.start(), matcher.end()); + } + assertThat(result).containsExactly("", "", ""); + assertThat(indexesOfMatches.entrySet()).map(entry -> INPUT.substring(entry.getKey(), entry.getValue())) + .containsExactly("", "", ""); + } + + @Test + void whenUsingMatcherStartAndEndWithGroupIdx_thenGetIndexesOfMatches() { + Pattern pattern = Pattern.compile("<([^>]*)>"); + Matcher matcher = pattern.matcher(INPUT); + List result = new ArrayList<>(); + Map indexesOfMatches = new LinkedHashMap<>(); + while (matcher.find()) { + result.add(matcher.group(1)); + indexesOfMatches.put(matcher.start(1), matcher.end(1)); + } + assertThat(result).containsExactly("the first value", "the second value", "the third value"); + + assertThat(indexesOfMatches.entrySet()).map(entry -> INPUT.substring(entry.getKey(), entry.getValue())) + .containsExactly("the first value", "the second value", "the third value"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/squarebrackets/ExtractTextBetweenSquareBracketsUnitTest.java b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/squarebrackets/ExtractTextBetweenSquareBracketsUnitTest.java new file mode 100644 index 0000000000..2ea80a1f69 --- /dev/null +++ b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/squarebrackets/ExtractTextBetweenSquareBracketsUnitTest.java @@ -0,0 +1,98 @@ +package com.baeldung.regex.squarebrackets; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.jupiter.api.Test; + +import com.google.common.collect.Lists; + +public class ExtractTextBetweenSquareBracketsUnitTest { + static final String INPUT1 = "some text [THE IMPORTANT MESSAGE] something else"; + static final String EXPECTED1 = "THE IMPORTANT MESSAGE"; + + static final String INPUT2 = "[La La Land], [The last Emperor], and [Life of Pi] are all great movies."; + static final List EXPECTED2 = Lists.newArrayList("La La Land", "The last Emperor", "Life of Pi"); + + @Test + void whenUsingDotStarOnInput1_thenGetExpectedResult() { + String result = null; + String rePattern = "\\[(.*)]"; + Pattern p = Pattern.compile(rePattern); + Matcher m = p.matcher(INPUT1); + if (m.find()) { + result = m.group(1); + } + assertThat(result).isEqualTo(EXPECTED1); + } + + @Test + void whenUsingCharClassOnInput1_thenGetExpectedResult() { + String result = null; + String rePattern = "\\[([^]]*)"; + Pattern p = Pattern.compile(rePattern); + Matcher m = p.matcher(INPUT1); + if (m.find()) { + result = m.group(1); + } + assertThat(result).isEqualTo(EXPECTED1); + } + + @Test + void whenUsingSplitOnInput1_thenGetExpectedResult() { + String[] strArray = INPUT1.split("[\\[\\]]", -1); + String result = strArray.length == 3 ? strArray[1] : null; + + assertThat(result).isEqualTo(EXPECTED1); + } + + @Test + void whenUsingSplitWithLimit_thenGetExpectedResult() { + String[] strArray = "[THE IMPORTANT MESSAGE]".split("[\\[\\]]"); + assertThat(strArray).hasSize(2) + .containsExactly("", "THE IMPORTANT MESSAGE"); + + strArray = "[THE IMPORTANT MESSAGE]".split("[\\[\\]]", -1); + assertThat(strArray).hasSize(3) + .containsExactly("", "THE IMPORTANT MESSAGE", ""); + } + + @Test + void whenUsingNonGreedyOnInput2_thenGetExpectedResult() { + List result = new ArrayList<>(); + String rePattern = "\\[(.*?)]"; + Pattern p = Pattern.compile(rePattern); + Matcher m = p.matcher(INPUT2); + while (m.find()) { + result.add(m.group(1)); + } + assertThat(result).isEqualTo(EXPECTED2); + } + + @Test + void whenUsingCharClassOnInput2_thenGetExpectedResult() { + List result = new ArrayList<>(); + String rePattern = "\\[([^]]*)"; + Pattern p = Pattern.compile(rePattern); + Matcher m = p.matcher(INPUT2); + while (m.find()) { + result.add(m.group(1)); + } + assertThat(result).isEqualTo(EXPECTED2); + } + + @Test + void whenUsingSplitInput2_thenGetExpectedResult() { + List result = new ArrayList<>(); + String[] strArray = INPUT2.split("[\\[\\]]", -1); + for (int i = 1; i < strArray.length; i += 2) { + result.add(strArray[i]); + } + assertThat(result).isEqualTo(EXPECTED2); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-scanner/pom.xml b/core-java-modules/core-java-scanner/pom.xml index f149f51955..bb5c7dca78 100644 --- a/core-java-modules/core-java-scanner/pom.xml +++ b/core-java-modules/core-java-scanner/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-scanner core-java-scanner diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml index ad9feeb36a..b979b56658 100644 --- a/core-java-modules/core-java-security-3/pom.xml +++ b/core-java-modules/core-java-security-3/pom.xml @@ -33,7 +33,7 @@ com.google.guava guava - ${google-guava.version} + ${guava.version} org.springframework.security @@ -47,7 +47,6 @@ 1.15 2.3.1 6.0.3 - 31.0.1-jre \ No newline at end of file diff --git a/core-java-modules/core-java-security-4/README.md b/core-java-modules/core-java-security-4/README.md new file mode 100644 index 0000000000..236715713b --- /dev/null +++ b/core-java-modules/core-java-security-4/README.md @@ -0,0 +1,8 @@ +## Core Java Security + +This module contains articles about core Java Security + +### Relevant Articles: +- [Check if Certificate Is Self-Signed or CA-Signed With Java](https://www.baeldung.com/java-check-certificate-sign) +- [Extract CN From X509 Certificate in Java](https://www.baeldung.com/java-extract-common-name-x509-certificate) +- More articles: [[<-- prev]](/core-java-modules/core-java-security-3) diff --git a/core-java-modules/core-java-security-4/pom.xml b/core-java-modules/core-java-security-4/pom.xml new file mode 100644 index 0000000000..aae33f87d4 --- /dev/null +++ b/core-java-modules/core-java-security-4/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + core-java-security-4 + core-java-security-4 + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + org.bouncycastle + bcpkix-jdk15on + ${bouncycastle.version} + + + org.cryptacular + cryptacular + ${cryptacular.version} + + + + + 1.70 + 1.2.6 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-security-4/src/main/java/com/baeldung/certificate/RootCertificateUtil.java b/core-java-modules/core-java-security-4/src/main/java/com/baeldung/certificate/RootCertificateUtil.java new file mode 100644 index 0000000000..3e8445971f --- /dev/null +++ b/core-java-modules/core-java-security-4/src/main/java/com/baeldung/certificate/RootCertificateUtil.java @@ -0,0 +1,51 @@ +package com.baeldung.certificate; + +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.Enumeration; + +public class RootCertificateUtil { + + private RootCertificateUtil() { + } + + public static X509Certificate getRootCertificate(X509Certificate endEntityCertificate, KeyStore trustStore) + throws Exception { + X509Certificate issuerCertificate = findIssuerCertificate(endEntityCertificate, trustStore); + if (issuerCertificate != null) { + if (isRoot(issuerCertificate)) { + return issuerCertificate; + } else { + return getRootCertificate(issuerCertificate, trustStore); + } + } + return null; + } + + private static X509Certificate findIssuerCertificate(X509Certificate certificate, KeyStore trustStore) + throws KeyStoreException { + Enumeration aliases = trustStore.aliases(); + while (aliases.hasMoreElements()) { + String alias = aliases.nextElement(); + Certificate cert = trustStore.getCertificate(alias); + if (cert instanceof X509Certificate) { + X509Certificate x509Cert = (X509Certificate) cert; + if (x509Cert.getSubjectX500Principal().equals(certificate.getIssuerX500Principal())) { + return x509Cert; + } + } + } + return null; + } + + private static boolean isRoot(X509Certificate certificate) { + try { + certificate.verify(certificate.getPublicKey()); + return certificate.getKeyUsage() != null && certificate.getKeyUsage()[5]; + } catch (Exception e) { + return false; + } + } +} diff --git a/core-java-modules/core-java-security-4/src/main/resources/Baeldung.cer b/core-java-modules/core-java-security-4/src/main/resources/Baeldung.cer new file mode 100644 index 0000000000..72d0918424 --- /dev/null +++ b/core-java-modules/core-java-security-4/src/main/resources/Baeldung.cer @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIJAPvd1gx14C3CMA0GCSqGSIb3DQEBBQUAMEcxCzAJBgNV +BAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNhYmxhbmNhMREw +DwYDVQQDEwhCYWVsZHVuZzAeFw0xNzEwMTIxMDQzMTRaFw0yNzEwMTMxMDQzMTRa +MEcxCzAJBgNVBAYTAk1BMRAwDgYDVQQIEwdNb3JvY2NvMRMwEQYDVQQHEwpDYXNh +YmxhbmNhMREwDwYDVQQDEwhCYWVsZHVuZzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMyi5GmOeN4QaH/CP5gSOyHX8znb5TDHWV8wc+ZT7kNU8zt5tGMh +jozK6hax155/6tOsBDR0rSYBhL+Dm/+uCVS7qOlRHhf6cNGtzGF1gnNJB2WjI8oM +AYm24xpLj1WphKUwKrn3nTMPnQup5OoNAMYl99flANrRYVjjxrLQvDZDUio6Iujr +CZ2TtXGM0g/gP++28KT7g1KlUui3xtB0u33wx7UN8Fix3JmjOaPHGwxGpwP3VGSj +fs8cuhqVwRQaZpCOoHU/P8wpXKw80sSdhz+SRueMPtVYqK0CiLL5/O0h0Y3le4IV +whgg3KG1iTGOWn60UMFn1EYmQ18k5Nsma6UCAwEAAaMtMCswCQYDVR0TBAIwADAR +BglghkgBhvhCAQEEBAMCBPAwCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBBQUAA4IB +AQC8DDBmJ3p4xytxBiE0s4p1715WT6Dm/QJHp0XC0hkSoyZKDh+XVmrzm+J3SiW1 +vpswb5hLgPo040YX9jnDmgOD+TpleTuKHxZRYj92UYWmdjkWLVtFMcvOh+gxBiAP +pHIqZsqo8lfcyAuh8Jx834IXbknfCUtERDLG/rU9P/3XJhrM2GC5qPQznrW4EYhU +CGPyIJXmvATMVvXMWCtfogAL+n42vjYXQXZoAWomHhLHoNbSJUErnNdWDOh4WoJt +XJCxA6U5LSBplqb3wB2hUTqw+0admKltvmy+KA1PD7OxoGiY7V544zeGqJam1qxU +ia7y5BL6uOa/4ShSV8pcJDYz +-----END CERTIFICATE----- diff --git a/core-java-modules/core-java-security-4/src/main/resources/keystore.jks b/core-java-modules/core-java-security-4/src/main/resources/keystore.jks new file mode 100644 index 0000000000..656c6c17d3 Binary files /dev/null and b/core-java-modules/core-java-security-4/src/main/resources/keystore.jks differ diff --git a/core-java-modules/core-java-security-4/src/main/resources/truststore.jks b/core-java-modules/core-java-security-4/src/main/resources/truststore.jks new file mode 100644 index 0000000000..5e1a9b4ce1 Binary files /dev/null and b/core-java-modules/core-java-security-4/src/main/resources/truststore.jks differ diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/certificate/ExtractCommonNameUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/certificate/ExtractCommonNameUnitTest.java new file mode 100644 index 0000000000..91e40453ea --- /dev/null +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/certificate/ExtractCommonNameUnitTest.java @@ -0,0 +1,94 @@ +package com.baeldung.certificate; + +import org.bouncycastle.asn1.x500.RDN; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.asn1.x500.style.IETFUtils; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.cryptacular.util.CertUtil; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; +import javax.security.auth.x500.X500Principal; +import java.io.FileInputStream; +import java.security.Security; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ExtractCommonNameUnitTest { + + private static final String EXPECTED_CN = "Baeldung"; + + private String certificatePath = "src/main/resources/Baeldung.cer"; + + private X509Certificate certificate; + + @BeforeEach + public void setUp() throws Exception { + Security.addProvider(new BouncyCastleProvider()); + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC"); + certificate = (X509Certificate) certificateFactory.generateCertificate(new FileInputStream(certificatePath)); + } + + @Test + void whenUsingBouncyCastle_thenExtractCommonName() { + X500Principal principal = certificate.getSubjectX500Principal(); + X500Name x500Name = new X500Name(principal.getName()); + RDN[] rdns = x500Name.getRDNs(BCStyle.CN); + List names = new ArrayList<>(); + for (RDN rdn : rdns) { + String name = IETFUtils.valueToString(rdn.getFirst().getValue()); + names.add(name); + } + + for (String commonName : names) { + assertEquals(EXPECTED_CN, commonName); + } + } + + @Test + void whenUsingLDAPAPI_thenExtractCommonName() throws Exception { + X500Principal principal = certificate.getSubjectX500Principal(); + LdapName ldapDN = new LdapName(principal.getName()); + List names = new ArrayList<>(); + for (Rdn rdn : ldapDN.getRdns()) { + if (rdn.getType().equalsIgnoreCase("cn")) { + String name = rdn.getValue().toString(); + names.add(name); + } + } + + for (String commonName : names) { + assertEquals(EXPECTED_CN, commonName); + } + } + + @Test + void whenUsingCryptacular_thenExtractCommonName() { + String commonName = CertUtil.subjectCN(certificate); + assertEquals(EXPECTED_CN, commonName); + } + + @Test + void whenUsingRegex_thenExtractCommonName() { + X500Principal principal = certificate.getSubjectX500Principal(); + List names = new ArrayList<>(); + Pattern pattern = Pattern.compile("CN=([^,]+)"); + Matcher matcher = pattern.matcher(principal.getName()); + while (matcher.find()) { + names.add(matcher.group(1)); + } + + for (String commonName : names) { + assertEquals(EXPECTED_CN, commonName); + } + } +} diff --git a/core-java-modules/core-java-security-4/src/test/java/com/baeldung/certificate/SignedCertificateUnitTest.java b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/certificate/SignedCertificateUnitTest.java new file mode 100644 index 0000000000..f5ea3c1b87 --- /dev/null +++ b/core-java-modules/core-java-security-4/src/test/java/com/baeldung/certificate/SignedCertificateUnitTest.java @@ -0,0 +1,76 @@ +package com.baeldung.certificate; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.security.KeyStore; +import java.security.SignatureException; +import java.security.cert.X509Certificate; + +import static com.baeldung.certificate.RootCertificateUtil.getRootCertificate; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SignedCertificateUnitTest { + + private KeyStore keyStore; + + private KeyStore trustStore; + + @BeforeEach + public void setUp() throws Exception { + char[] passwd = "changeit".toCharArray(); + keyStore = KeyStore.getInstance("JKS"); + keyStore.load(this.getClass().getClassLoader().getResourceAsStream("keystore.jks"), passwd); + trustStore = KeyStore.getInstance("JKS"); + trustStore.load(this.getClass().getClassLoader().getResourceAsStream("truststore.jks"), passwd); + } + + @Test + void whenCertificateIsSelfSigned_thenSubjectIsEqualToIssuer() throws Exception { + X509Certificate certificate = (X509Certificate) keyStore.getCertificate("selfsigned"); + assertEquals(certificate.getSubjectDN(), certificate.getIssuerDN()); + } + + @Test + void whenCertificateIsSelfSigned_thenItCanBeVerifiedWithItsOwnPublicKey() throws Exception { + X509Certificate certificate = (X509Certificate) keyStore.getCertificate("selfsigned"); + assertDoesNotThrow(() -> certificate.verify(certificate.getPublicKey())); + } + + @Test + void whenCertificateIsCASigned_thenItCantBeVerifiedWithItsOwnPublicKey() throws Exception { + X509Certificate certificate = (X509Certificate) keyStore.getCertificate("baeldung"); + assertThrows(SignatureException.class, () -> certificate.verify(certificate.getPublicKey())); + } + + @Test + void whenCertificateIsCASigned_thenRootCanBeFoundInTruststore() throws Exception { + X509Certificate endEntityCertificate = (X509Certificate) keyStore.getCertificate("baeldung"); + X509Certificate rootCertificate = getRootCertificate(endEntityCertificate, trustStore); + assertNotNull(rootCertificate); + } + + @Test + void whenCertificateIsCA_thenItCanBeUsedToSignOtherCertificates() throws Exception { + X509Certificate certificate = (X509Certificate) keyStore.getCertificate("cloudflare"); + assertTrue(certificate.getKeyUsage()[5]); + } + + @Test + void whenCertificateIsCA_thenBasicConstrainsReturnsZeroOrGreaterThanZero() throws Exception { + X509Certificate certificate = (X509Certificate) keyStore.getCertificate("cloudflare"); + assertNotEquals(-1, certificate.getBasicConstraints()); + } + + @Test + void whenCertificateIsSelfSigned_thenItCantBeUsedToSignOtherCertificates() throws Exception { + X509Certificate certificate = (X509Certificate) keyStore.getCertificate("selfsigned"); + assertNull(certificate.getKeyUsage()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-serialization/pom.xml b/core-java-modules/core-java-serialization/pom.xml index 5a6f256687..63771d2da0 100644 --- a/core-java-modules/core-java-serialization/pom.xml +++ b/core-java-modules/core-java-serialization/pom.xml @@ -53,6 +53,12 @@ ${spring.core.version} test + + org.projectlombok + lombok + ${lombok.version} + provided + diff --git a/core-java-modules/core-java-streams-4/pom.xml b/core-java-modules/core-java-streams-4/pom.xml index fe791ebd42..e832cc1616 100644 --- a/core-java-modules/core-java-streams-4/pom.xml +++ b/core-java-modules/core-java-streams-4/pom.xml @@ -39,7 +39,7 @@ org.assertj assertj-core - 3.23.1 + ${assertj.version} test @@ -55,7 +55,7 @@ org.apache.commons commons-lang3 - 3.12.0 + ${commons-lang3.version} test @@ -81,7 +81,7 @@ com.google.guava guava - ${google.guava.version} + ${guava.version} com.oath.cyclops @@ -114,7 +114,7 @@ - 3.1 + 3.23.1 12 12 1.2.5 @@ -123,7 +123,6 @@ 1.0.0-alpha-4 3.5.1 4.4 - 31.1-jre 10.4.1 diff --git a/core-java-modules/core-java-streams-5/README.md b/core-java-modules/core-java-streams-5/README.md index c0df5990c4..885949d937 100644 --- a/core-java-modules/core-java-streams-5/README.md +++ b/core-java-modules/core-java-streams-5/README.md @@ -1,3 +1,4 @@ ## Relevant Articles - [Difference Between parallelStream() and stream().parallel() in Java](https://www.baeldung.com/java-parallelstream-vs-stream-parallel) - [Working With Empty Stream in Java](https://www.baeldung.com/java-empty-stream) +- [Aggregate Runtime Exceptions in Java Streams](https://www.baeldung.com/java-streams-aggregate-exceptions) diff --git a/core-java-modules/core-java-streams-5/pom.xml b/core-java-modules/core-java-streams-5/pom.xml index d1f8af6461..dc97d81b3d 100644 --- a/core-java-modules/core-java-streams-5/pom.xml +++ b/core-java-modules/core-java-streams-5/pom.xml @@ -38,6 +38,11 @@ 3.12.0 test + + io.vavr + vavr + ${vavr.version} + @@ -64,9 +69,9 @@ - 3.1 12 12 + 0.10.2 \ No newline at end of file diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/aggregateexception/CustomCollector.java b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/aggregateexception/CustomCollector.java new file mode 100644 index 0000000000..dea3d3f44c --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/aggregateexception/CustomCollector.java @@ -0,0 +1,38 @@ +package com.baeldung.aggregateexception; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collector; + +public class CustomCollector { + private final List results = new ArrayList<>(); + private final List exceptions = new ArrayList<>(); + + public static Collector> of(Function mapper) { + return Collector.of( + CustomCollector::new, + (collector, item) -> { + try { + R result = mapper.apply(item); + collector.results.add(result); + } catch (Exception e) { + collector.exceptions.add(e); + } + }, + (left, right) -> { + left.results.addAll(right.results); + left.exceptions.addAll(right.exceptions); + return left; + } + ); + } + + public List getResults() { + return results; + } + + public List getExceptions() { + return exceptions; + } +} diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/aggregateexception/CustomMapper.java b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/aggregateexception/CustomMapper.java new file mode 100644 index 0000000000..920c963337 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/aggregateexception/CustomMapper.java @@ -0,0 +1,17 @@ +package com.baeldung.aggregateexception; + +import com.baeldung.aggregateexception.entity.Result; + +import java.util.function.Function; + +public class CustomMapper { + public static Function> mapper(Function func) { + return arg -> { + try { + return new Result(func.apply(arg)); + } catch (Exception e) { + return new Result(e); + } + }; + } +} diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/aggregateexception/entity/Result.java b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/aggregateexception/entity/Result.java new file mode 100644 index 0000000000..b723c3e510 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/aggregateexception/entity/Result.java @@ -0,0 +1,26 @@ +package com.baeldung.aggregateexception.entity; + +import java.util.Optional; + +public class Result { + private Optional result; + private Optional exception; + + public Result(R result) { + this.result = Optional.of(result); + this.exception = Optional.empty(); + } + + public Result(E exception) { + this.exception = Optional.of(exception); + this.result = Optional.empty(); + } + + public Optional getResult() { + return result; + } + + public Optional getException() { + return exception; + } +} diff --git a/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/streamsvsloops/PerformanceBenchmark.java b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/streamsvsloops/PerformanceBenchmark.java new file mode 100644 index 0000000000..6c1ee9b2dd --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/main/java/com/baeldung/streams/streamsvsloops/PerformanceBenchmark.java @@ -0,0 +1,111 @@ +package com.baeldung.streams.streamsvsloops; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(1) +public class PerformanceBenchmark { + + @State(Scope.Thread) + public static class MyState { + List numbers; + + @Setup(Level.Trial) + public void setUp() { + numbers = new ArrayList<>(); + for (int i = 0; i < 1_000_000; i++) { + numbers.add(i); + } + } + } + + @Benchmark + public int forLoopBenchmark(MyState state) { + int sum = 0; + for (int number : state.numbers) { + if (number % 2 == 0) { + sum = sum + (number * number); + } + } + return sum; + } + + @Benchmark + public int parallelStreamBenchMark(MyState state) { + return state.numbers.parallelStream() + .filter(number -> number % 2 == 0) + .map(number -> number * number) + .reduce(0, Integer::sum); + } + + @Benchmark + public int concurrentForLoopBenchmark(MyState state) throws InterruptedException, ExecutionException { + int numThreads = Runtime.getRuntime().availableProcessors(); + ExecutorService executorService = Executors.newFixedThreadPool(numThreads); + List> tasks = new ArrayList<>(); + int chunkSize = state.numbers.size() / numThreads; + + for (int i = 0; i < numThreads; i++) { + final int start = i * chunkSize; + final int end = (i == numThreads - 1) ? state.numbers.size() : (i + 1) * chunkSize; + tasks.add(() -> { + int sum = 0; + for (int j = start; j < end; j++) { + int number = state.numbers.get(j); + if (number % 2 == 0) { + sum = sum + (number * number); + } + } + return sum; + }); + } + + int totalSum = 0; + for (Future result : executorService.invokeAll(tasks)) { + totalSum += result.get(); + } + + executorService.shutdown(); + return totalSum; + } + + @Benchmark + public int streamBenchMark(MyState state) { + return state.numbers.stream() + .filter(number -> number % 2 == 0) + .map(number -> number * number) + .reduce(0, Integer::sum); + } + + public static void main(String[] args) throws RunnerException { + Options options = new OptionsBuilder().include(PerformanceBenchmark.class.getSimpleName()) + .build(); + new Runner(options).run(); + } +} diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/aggregateexception/AggregateExceptionHandlerUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/aggregateexception/AggregateExceptionHandlerUnitTest.java new file mode 100644 index 0000000000..6410645d2a --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/aggregateexception/AggregateExceptionHandlerUnitTest.java @@ -0,0 +1,150 @@ +package com.baeldung.aggregateexception; + +import com.baeldung.aggregateexception.entity.Result; +import io.vavr.control.Either; +import io.vavr.control.Try; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertEquals; + + +public class AggregateExceptionHandlerUnitTest { + private static final Logger logger = LoggerFactory.getLogger(AggregateExceptionHandlerUnitTest.class); + + @Test + public void givenExtractedMethod_whenFoundEx_thenSuppressExIntoRuntimeEx() { + String[] strings = {"1", "2", "3", "a", "b", "c"}; + RuntimeException runEx = Arrays.stream(strings) + .map(str -> callProcessThrowsExAndNoOutput(str)) + .filter(Objects::nonNull) + .reduce(new RuntimeException("Errors Occurred"), (o1, o2) -> { + o1.addSuppressed(o2); + return o1; + }); + processExceptions(runEx); + assertEquals("Errors Occurred", runEx.getMessage()); + assertEquals(3, runEx.getSuppressed().length); + } + @Test + public void givenTryCatchInPipeline_whenFoundEx_thenSuppressExIntoRuntimeEx() { + String[] strings = {"1", "2", "3", "a", "b", "c"}; + RuntimeException runEx = Arrays.stream(strings).map(str -> { + try { + processThrowsExAndNoOutput(str); + return null; + } catch (RuntimeException e) { + return e; + } + }).filter(Objects::nonNull) + .collect(Collectors.collectingAndThen(Collectors.toList(), list -> { + RuntimeException runtimeException = new RuntimeException("Errors Occurred"); + list.forEach(runtimeException::addSuppressed); + return runtimeException; + })); + processExceptions(runEx); + assertEquals("Errors Occurred", runEx.getMessage()); + assertEquals(3, runEx.getSuppressed().length); + } + + @Test + public void givenProcessMethod_whenStreamResultHasExAndOutput_thenHandleExceptionListAndOutputList() { + List strings = List.of("1", "2", "3", "a", "b", "c"); + Map map = strings.stream() + .map(s -> processReturnsExAndOutput(s)) + .collect(Collectors.partitioningBy(o -> o instanceof RuntimeException, Collectors.toList())); + + List exceptions = (List)map.getOrDefault(Boolean.TRUE, List.of()); + List results = (List)map.getOrDefault(Boolean.FALSE, List.of()); + handleExceptionsAndOutputs(exceptions, results); + } + + @Test + public void givenCustomMapper_whenStreamResultHasExAndSuccess_thenHandleExceptionListAndOutputList() { + List strings = List.of("1", "2", "3", "a", "b", "c"); + strings.stream() + .map(CustomMapper.mapper(Integer::parseInt)) + .collect(Collectors.collectingAndThen(Collectors.toList(), list -> handleErrorsAndOutputForResult(list))); + } + + @Test + public void givenCustomCollector_whenStreamResultHasExAndSuccess_thenHandleAggrExceptionAndResults() { + String[] strings = {"1", "2", "3", "a", "b", "c"}; + Arrays.stream(strings) + .collect(Collectors.collectingAndThen(CustomCollector.of(Integer::parseInt), + col -> handleExAndResults(col.getExceptions(), col.getResults()))); + } + + @Test + public void givenVavrEitherAndTry_whenStreamResultHasExAndSuccess_thenHandleExceptionListAndOutputList() { + List strings = List.of("1", "2", "3", "a", "b", "c"); + strings.stream() + .map(str -> Try.of(() -> Integer.parseInt(str)).toEither()) + .collect(Collectors.collectingAndThen(Collectors.partitioningBy(Either::isLeft, Collectors.toList()), + map -> handleErrorsAndOutputForEither(map))); + } + + private static void processThrowsExAndNoOutput(String input) { + //throw exception when input is "a", "b", "c" + if (input.matches("[a-c]")) { + throw new RuntimeException("Downstream method throws exception for " + input); + } + } + private static RuntimeException callProcessThrowsExAndNoOutput(String input) { + try { + processThrowsExAndNoOutput(input); + return null; + } catch (RuntimeException e) { + return e; + } + } + + private static Object processReturnsExAndOutput(String input) { + logger.info("call a downstream method that returns an Integer"); + try { + return Integer.parseInt(input); + } catch (Exception e) { + return new RuntimeException("Exception in processWithReturnOutput for " + input, e); + } + } + + private static void processExceptions(Throwable throwable) { + logger.error("Process Exception" + throwable.getMessage()); + } + + private static void handleExceptionsAndOutputs(List exs, List output) { + logger.info("number of exceptions " + exs.size() + " number of outputs " + output.size()); + } + + private static String handleExAndResults(List ex, List results ) { + logger.info("handle aggregated exceptions and results" + ex.size() + " " + results.size()); + return "Exceptions and Results Handled"; + } + + private static String handleErrorsAndOutputForEither(Map>> map) { + logger.info("handle errors and output"); + map.getOrDefault(Boolean.TRUE, List.of()).forEach(either -> logger.error("Process Exception " + either.getLeft())); + + map.getOrDefault(Boolean.FALSE, List.of()).forEach(either -> logger.info("Process Result " + either.get())); + return "Errors and Output Handled"; + } + + private static String handleErrorsAndOutputForResult(List> successAndErrors) { + logger.info("handle errors and output"); + successAndErrors.forEach(result -> { + if (result.getException().isPresent()) { + logger.error("Process Exception " + result.getException().get()); + } else { + logger.info("Process Result" + result.getResult().get()); + } + }); + return "Errors and Output Handled"; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamsvsloops/StreamsVsLoopsUnitTest.java b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamsvsloops/StreamsVsLoopsUnitTest.java new file mode 100644 index 0000000000..e84fbc3da3 --- /dev/null +++ b/core-java-modules/core-java-streams-5/src/test/java/com/baeldung/streamsvsloops/StreamsVsLoopsUnitTest.java @@ -0,0 +1,55 @@ +package com.baeldung.streamsvsloops; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.Test; + +public class StreamsVsLoopsUnitTest { + + @Test + public void givenListWithFruits_whenFilterUsingStream_thenReturnedCount() { + List fruits = Arrays.asList("apple", "banana", "orange", "grape"); + long count = fruits.stream() + .filter(fruit -> fruit.length() > 5) + .count(); + assertEquals(2, count); + } + + @Test + public void givenListWithFruits_whenFilterUsingForLoop_thenReturnedCount() { + List fruits = Arrays.asList("apple", "banana", "orange", "grape"); + long count = 0; for (String fruit : fruits) { + if (fruit.length() > 5) { + count++; + } + } + assertEquals(2, count); + } + + @Test + public void givenListWithFruits_whenApplyUppercase_thenNewListGenerated() { + List desiredArray = new ArrayList<>(Arrays.asList("APPLE", "BANANA", "ORANGE")); + List fruits = new ArrayList<>(Arrays.asList("apple", "banana", "orange")); + List upperCaseFruits = fruits.stream() + .map(fruit -> fruit.toUpperCase()) + .collect(Collectors.toList()); + assertThat(desiredArray, is(upperCaseFruits)); + } + + @Test + public void givenListWithFruits_whenApplyUppercase_elementsAreUpdated() { + List desiredArray = new ArrayList<>(Arrays.asList("APPLE", "BANANA", "ORANGE")); + List fruits = new ArrayList<>(Arrays.asList("apple", "banana", "orange")); + for (int i = 0; i < fruits.size(); i++) { + fruits.set(i, fruits.get(i).toUpperCase()); + } + assertThat(desiredArray, is(fruits)); + } +} diff --git a/core-java-modules/core-java-streams-maps/pom.xml b/core-java-modules/core-java-streams-maps/pom.xml index 66e1fedd87..6b04897a29 100644 --- a/core-java-modules/core-java-streams-maps/pom.xml +++ b/core-java-modules/core-java-streams-maps/pom.xml @@ -58,7 +58,6 @@ - 3.1 1.8 1.8 diff --git a/core-java-modules/core-java-streams/pom.xml b/core-java-modules/core-java-streams/pom.xml index b0794829c2..c7282dda21 100644 --- a/core-java-modules/core-java-streams/pom.xml +++ b/core-java-modules/core-java-streams/pom.xml @@ -14,33 +14,6 @@ - - org.openjdk.jmh - jmh-core - ${jmh-core.version} - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh-generator.version} - provided - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - log4j - log4j - ${log4j.version} - - - org.projectlombok - lombok - ${lombok.version} - provided - com.codepoetics protonpack @@ -57,17 +30,7 @@ ${streamex.version} - org.aspectj - aspectjrt - ${asspectj.version} - - - org.aspectj - aspectjweaver - ${asspectj.version} - - - pl.touk + com.pivovarit throwing-function ${throwing-function.version} @@ -96,15 +59,13 @@ - 0.9.0 - 1.15 - 0.6.5 - 2.10 - 1.3 - 1.8.9 - 3.1 - 1.8 - 1.8 + 0.10.4 + 1.16 + 0.8.1 + 1.5.1 + + 17 + 17 \ No newline at end of file diff --git a/core-java-modules/core-java-streams/src/test/java/com/baeldung/stream/filter/StreamFilterUnitTest.java b/core-java-modules/core-java-streams/src/test/java/com/baeldung/stream/filter/StreamFilterUnitTest.java index 5ad875f61e..3f3922e015 100644 --- a/core-java-modules/core-java-streams/src/test/java/com/baeldung/stream/filter/StreamFilterUnitTest.java +++ b/core-java-modules/core-java-streams/src/test/java/com/baeldung/stream/filter/StreamFilterUnitTest.java @@ -1,8 +1,8 @@ package com.baeldung.stream.filter; import org.junit.jupiter.api.Test; -import pl.touk.throwing.ThrowingPredicate; -import pl.touk.throwing.exception.WrappedException; +import com.pivovarit.function.ThrowingPredicate; +import com.pivovarit.function.exception.WrappedException; import java.io.IOException; import java.util.Arrays; @@ -156,5 +156,4 @@ public class StreamFilterUnitTest { }) .collect(Collectors.toList())).isInstanceOf(RuntimeException.class); } - -} +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-algorithms-3/README.md b/core-java-modules/core-java-string-algorithms-3/README.md index 6af818b52d..2bb70f5c97 100644 --- a/core-java-modules/core-java-string-algorithms-3/README.md +++ b/core-java-modules/core-java-string-algorithms-3/README.md @@ -11,3 +11,4 @@ This module contains articles about string-related algorithms. - [Find the First Non Repeating Character in a String in Java](https://www.baeldung.com/java-find-the-first-non-repeating-character) - [Find the First Embedded Occurrence of an Integer in a Java String](https://www.baeldung.com/java-string-find-embedded-integer) - [Find the Most Frequent Characters in a String](https://www.baeldung.com/java-string-find-most-frequent-characters) +- [Checking If a String Is a Repeated Substring](https://www.baeldung.com/java-repeated-substring) \ No newline at end of file diff --git a/core-java-modules/core-java-string-algorithms/src/main/java/com/baeldung/repetition/SubstringRepetition.java b/core-java-modules/core-java-string-algorithms-3/src/main/java/com/baeldung/repetition/SubstringRepetition.java similarity index 100% rename from core-java-modules/core-java-string-algorithms/src/main/java/com/baeldung/repetition/SubstringRepetition.java rename to core-java-modules/core-java-string-algorithms-3/src/main/java/com/baeldung/repetition/SubstringRepetition.java diff --git a/core-java-modules/core-java-string-algorithms/src/test/java/com/baeldung/repetition/SubstringRepetitionUnitTest.java b/core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/repetition/SubstringRepetitionUnitTest.java similarity index 100% rename from core-java-modules/core-java-string-algorithms/src/test/java/com/baeldung/repetition/SubstringRepetitionUnitTest.java rename to core-java-modules/core-java-string-algorithms-3/src/test/java/com/baeldung/repetition/SubstringRepetitionUnitTest.java diff --git a/core-java-modules/core-java-string-algorithms/README.md b/core-java-modules/core-java-string-algorithms/README.md index 5a7abf074a..e2f909ed38 100644 --- a/core-java-modules/core-java-string-algorithms/README.md +++ b/core-java-modules/core-java-string-algorithms/README.md @@ -11,6 +11,5 @@ This module contains articles about string-related algorithms. - [How to Reverse a String in Java](https://www.baeldung.com/java-reverse-string) - [Check if a String Is a Pangram in Java](https://www.baeldung.com/java-string-pangram) - [Check If a String Contains Multiple Keywords in Java](https://www.baeldung.com/string-contains-multiple-words) -- [Checking If a String Is a Repeated Substring](https://www.baeldung.com/java-repeated-substring) - [Remove Emojis from a Java String](https://www.baeldung.com/java-string-remove-emojis) - More articles: [[next -->]](../core-java-string-algorithms-2) diff --git a/core-java-modules/core-java-string-apis-2/pom.xml b/core-java-modules/core-java-string-apis-2/pom.xml index 51ab3bc1f8..814d301532 100644 --- a/core-java-modules/core-java-string-apis-2/pom.xml +++ b/core-java-modules/core-java-string-apis-2/pom.xml @@ -22,7 +22,7 @@ org.apache.commons commons-lang3 - ${commons.lang3.version} + ${commons-lang3.version} com.ibm.icu @@ -42,8 +42,6 @@ - 3.12.0 - 31.1-jre 61.1 diff --git a/core-java-modules/core-java-string-conversions-3/src/java.com.baeldung.multivluehashmap/MultiValueHashMapTest.java b/core-java-modules/core-java-string-conversions-3/src/java.com.baeldung.multivluehashmap/MultiValueHashMapTest.java deleted file mode 100644 index a3d0bc35de..0000000000 --- a/core-java-modules/core-java-string-conversions-3/src/java.com.baeldung.multivluehashmap/MultiValueHashMapTest.java +++ /dev/null @@ -1,79 +0,0 @@ -import org.junit.jupiter.api.Test; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -public class MultiValueHashMapTest { - @Test - public void given_MultiValueHashMap_whenPuttingAndGettingSingleValue_thenValueIsRetrieved() { - MultiValueHashMap map = new MultiValueHashMap<>(); - map.put("key1", 10); - assertEquals(List.of(10), map.get("key1")); - } - - @Test - public void given_MultiValueHashMap_whenPuttingAndGettingMultipleValues_thenAllValuesAreRetrieved() { - MultiValueHashMap map = new MultiValueHashMap<>(); - map.put("key2", "value1"); - map.put("key2", "value2"); - map.put("key2", "value3"); - - assertEquals(List.of("value1", "value2", "value3"), map.get("key2")); - } - - @Test - public void given_MultiValueHashMap_whenGettingNonExistentKey_thenEmptyListIsReturned() { - MultiValueHashMap map = new MultiValueHashMap<>(); - assertTrue(map.get("nonexistent").isEmpty()); - } - - @Test - public void given_MultiValueHashMap_whenRemovingValue_thenValueIsSuccessfullyRemoved() { - MultiValueHashMap map = new MultiValueHashMap<>(); - map.put(1, "one"); - map.put(1, "uno"); - map.put(1, "eins"); - - map.remove(1, "uno"); - assertEquals(List.of("one", "eins"), map.get(1)); - } - - @Test - public void testRemoveNonExistentValue() { - MultiValueHashMap map = new MultiValueHashMap<>(); - map.put(1, "one"); - map.remove(1, "nonexistent"); - assertEquals(List.of("one"), map.get(1)); - } - - public class MultiValueHashMap { - private HashMap> map; - - // Constructor - public MultiValueHashMap() { - map = new HashMap<>(); - } - - public void put(K key, V value) { - if (!map.containsKey(key)) { - map.put(key, new ArrayList<>()); - } - map.get(key).add(value); - } - - public List get(K key) { - return map.getOrDefault(key, new ArrayList<>()); - } - - public void remove(K key, V value) { - if (map.containsKey(key)) { - map.get(key).remove(value); - } - } - - - } -} diff --git a/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/replace/ReplaceStringUnitTest.java b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/replace/ReplaceStringUnitTest.java new file mode 100644 index 0000000000..081ffabab1 --- /dev/null +++ b/core-java-modules/core-java-string-operations-5/src/test/java/com/baeldung/replace/ReplaceStringUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.replace; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class ReplaceStringUnitTest { + private final String ORIGINAL_STRING = "This is 'Baeldung' tutorial."; + private final String EXPECTED_STRING = "This is \\'Baeldung\\' tutorial."; + + @Test + public void givenString_thenReplaceUsinReplaceAllMethod() { + String modifiedString = ORIGINAL_STRING.replaceAll("'", "\\\\'"); + assertEquals(EXPECTED_STRING, modifiedString); + } + + @Test + public void givenString_thenReplaceUsinReplaceMethod() { + String modifiedString = ORIGINAL_STRING.replace("'", "\\'"); + assertEquals(EXPECTED_STRING, modifiedString); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations-6/pom.xml b/core-java-modules/core-java-string-operations-6/pom.xml index 0ec32d91b1..ca9a7a9297 100644 --- a/core-java-modules/core-java-string-operations-6/pom.xml +++ b/core-java-modules/core-java-string-operations-6/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 core-java-string-operations-6 core-java-string-operations-6 diff --git a/core-java-modules/core-java-string-operations/pom.xml b/core-java-modules/core-java-string-operations/pom.xml index 577736a324..601d0341a3 100644 --- a/core-java-modules/core-java-string-operations/pom.xml +++ b/core-java-modules/core-java-string-operations/pom.xml @@ -15,30 +15,20 @@ - javax.xml.bind - jaxb-api - 2.4.0-b180725.0427 + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.xml.bind-api.version} org.apache.commons commons-lang3 ${commons-lang3.version} - - org.openjdk.jmh - jmh-core - ${jmh-core.version} - log4j log4j ${log4j.version} - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh-generator.version} - commons-codec commons-codec @@ -57,7 +47,8 @@ - 1.15 + 1.16.0 + 4.0.0 \ No newline at end of file diff --git a/core-java-modules/core-java-string-operations/src/test/java/com/baeldung/base64encodinganddecoding/StringToByteArrayUnitTest.java b/core-java-modules/core-java-string-operations/src/test/java/com/baeldung/base64encodinganddecoding/StringToByteArrayUnitTest.java index 6f8a17e316..491574f0f1 100644 --- a/core-java-modules/core-java-string-operations/src/test/java/com/baeldung/base64encodinganddecoding/StringToByteArrayUnitTest.java +++ b/core-java-modules/core-java-string-operations/src/test/java/com/baeldung/base64encodinganddecoding/StringToByteArrayUnitTest.java @@ -2,7 +2,7 @@ package com.baeldung.base64encodinganddecoding; import org.junit.Test; -import javax.xml.bind.DatatypeConverter; +import jakarta.xml.bind.DatatypeConverter; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.Arrays; diff --git a/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringtoolong/StringTooLongUnitTest.java b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringtoolong/StringTooLongUnitTest.java index 4035cadb83..185c2809c1 100644 --- a/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringtoolong/StringTooLongUnitTest.java +++ b/core-java-modules/core-java-strings/src/test/java/com/baeldung/stringtoolong/StringTooLongUnitTest.java @@ -27,7 +27,7 @@ public class StringTooLongUnitTest { @Test public void whenStoringInPropertiesString_thenNoCompilationError() throws IOException { String sValue = null; - try (InputStream input = new FileInputStream("src/main/resources/config.properties")) { + try (InputStream input = new FileInputStream("src/test/resources/config.properties")) { Properties prop = new Properties(); prop.load(input); sValue = prop.getProperty("string.too.long"); diff --git a/core-java-modules/core-java-strings/src/test/resources/config.properties b/core-java-modules/core-java-strings/src/test/resources/config.properties new file mode 100644 index 0000000000..86ae17679f --- /dev/null +++ b/core-java-modules/core-java-strings/src/test/resources/config.properties @@ -0,0 +1 @@ +string.too.long="a long string example" \ No newline at end of file diff --git a/core-java-modules/core-java-strings/src/test/resources/stringtoolong.txt b/core-java-modules/core-java-strings/src/test/resources/stringtoolong.txt new file mode 100644 index 0000000000..f31b4a28bd --- /dev/null +++ b/core-java-modules/core-java-strings/src/test/resources/stringtoolong.txt @@ -0,0 +1,4 @@ +Get busy living +or +get busy dying. +--Stephen King \ No newline at end of file diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index e9bb86e500..7fbd6cf657 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -24,12 +24,40 @@ - - - + core-java-9-improvements + core-java-collections-array-list + core-java-9-streams + core-java-9 + core-java-10 + core-java-11 + core-java-11-2 + core-java-11-3 + core-java-collections-list-4 + core-java-collections-list-5 + core-java-collections-maps-4 + core-java-collections-maps-5 + core-java-concurrency-simple + core-java-datetime-string + core-java-io-conversions-2 + core-java-jpms + core-java-lang-oop-constructors-2 + core-java-methods + core-java-networking-3 + core-java-os + core-java-perf-2 + core-java-streams-4 + core-java-streams-5 + core-java-streams-collect + core-java-streams-maps + core-java-string-algorithms-3 + core-java-string-operations-3 + core-java-string-operations-4 + core-java-string-operations-5 + + core-java-time-measurements core-java-annotations core-java-arrays-sorting core-java-arrays-guides @@ -113,6 +141,7 @@ core-java-networking-2 core-java-networking-4 core-java-nio + core-java-nio-2 core-java-numbers core-java-numbers-2 core-java-numbers-3 @@ -127,7 +156,9 @@ core-java-scanner core-java-security-2 core-java-security-3 + core-java-security-4 core-java-security-algorithms + core-java-serialization core-java-streams core-java-streams-3 core-java-string-algorithms @@ -145,6 +176,7 @@ core-java-uuid core-java-collections-maps-6 core-java-records + core-java-9-jigsaw diff --git a/di-modules/avaje/pom.xml b/di-modules/avaje/pom.xml index 7ffe14bd72..49162c518e 100644 --- a/di-modules/avaje/pom.xml +++ b/di-modules/avaje/pom.xml @@ -1,37 +1,37 @@ - 4.0.0 - com.baeldung - inject-intro - 0.0.1-SNAPSHOT - avaje-inject-intro - - 11 - 11 - 9.5 - - - - io.avaje - avaje-inject - ${avaje.inject.version} - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + com.baeldung + inject-intro + 0.0.1-SNAPSHOT + avaje-inject-intro + + 11 + 11 + 9.5 + + + + io.avaje + avaje-inject + ${avaje.inject.version} + - - io.avaje - avaje-inject-test - ${avaje.inject.version} - test - + + io.avaje + avaje-inject-test + ${avaje.inject.version} + test + - - - io.avaje - avaje-inject-generator - ${avaje.inject.version} - provided - true - - + + + io.avaje + avaje-inject-generator + ${avaje.inject.version} + provided + true + + \ No newline at end of file diff --git a/disruptor/pom.xml b/disruptor/pom.xml index 75e783e935..b3b065d67e 100644 --- a/disruptor/pom.xml +++ b/disruptor/pom.xml @@ -119,7 +119,6 @@ 3.3.6 2.4.3 - 3.0.2 1.4.4 diff --git a/docker-modules/docker-caching/multi-module-caching/pom.xml b/docker-modules/docker-caching/multi-module-caching/pom.xml index b64cf1a8b8..60f14a17e5 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 - 31.1-jre + 32.1.2-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 a388c7563f..0e5174b7ca 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 - 31.1-jre + 32.1.2-jre \ No newline at end of file diff --git a/docker-modules/dockerfile/git-strategies/.gitmodules b/docker-modules/dockerfile-git-strategies/.gitmodules similarity index 100% rename from docker-modules/dockerfile/git-strategies/.gitmodules rename to docker-modules/dockerfile-git-strategies/.gitmodules diff --git a/docker-modules/dockerfile/git-strategies/Dockerfile b/docker-modules/dockerfile-git-strategies/Dockerfile similarity index 91% rename from docker-modules/dockerfile/git-strategies/Dockerfile rename to docker-modules/dockerfile-git-strategies/Dockerfile index 91dfee3bc6..98911bdcbd 100644 --- a/docker-modules/dockerfile/git-strategies/Dockerfile +++ b/docker-modules/dockerfile-git-strategies/Dockerfile @@ -1,4 +1,4 @@ -ADD . /project/ +ADD git-strategies /project/ ADD /build/ /project/ ADD /output/project.jar /project/ diff --git a/docker-modules/dockerfile/README.md b/docker-modules/dockerfile-git-strategies/README.md similarity index 100% rename from docker-modules/dockerfile/README.md rename to docker-modules/dockerfile-git-strategies/README.md diff --git a/google-auto-project/README.md b/google-auto-project/README.md index d45a113a8f..44dd6c5d61 100644 --- a/google-auto-project/README.md +++ b/google-auto-project/README.md @@ -8,3 +8,5 @@ This module contains articles about automatic code generation - [Introduction to AutoFactory](https://www.baeldung.com/autofactory) - [Google AutoService](https://www.baeldung.com/google-autoservice) - [Defensive Copies for Collections Using AutoValue](https://www.baeldung.com/autovalue-defensive-copies) +- [Java Annotation Processing and Creating a Builder](https://www.baeldung.com/java-annotation-processing-builder) + diff --git a/annotations/annotation-processing/pom.xml b/google-auto-project/annotation-processing/pom.xml similarity index 90% rename from annotations/annotation-processing/pom.xml rename to google-auto-project/annotation-processing/pom.xml index 14bbc409e5..5c872c2059 100644 --- a/annotations/annotation-processing/pom.xml +++ b/google-auto-project/annotation-processing/pom.xml @@ -8,8 +8,8 @@ com.baeldung - 1.0.0-SNAPSHOT - annotations + google-auto-project + 1.0 diff --git a/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java b/google-auto-project/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java similarity index 100% rename from annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java rename to google-auto-project/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProcessor.java diff --git a/annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java b/google-auto-project/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java similarity index 100% rename from annotations/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java rename to google-auto-project/annotation-processing/src/main/java/com/baeldung/annotation/processor/BuilderProperty.java diff --git a/annotations/annotation-processing/src/main/resources/logback.xml b/google-auto-project/annotation-processing/src/main/resources/logback.xml similarity index 100% rename from annotations/annotation-processing/src/main/resources/logback.xml rename to google-auto-project/annotation-processing/src/main/resources/logback.xml diff --git a/annotations/annotation-user/pom.xml b/google-auto-project/annotation-user/pom.xml similarity index 88% rename from annotations/annotation-user/pom.xml rename to google-auto-project/annotation-user/pom.xml index 37a2e36f61..c21a4ca03d 100644 --- a/annotations/annotation-user/pom.xml +++ b/google-auto-project/annotation-user/pom.xml @@ -8,8 +8,8 @@ com.baeldung - annotations - 1.0.0-SNAPSHOT + google-auto-project + 1.0 diff --git a/annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java b/google-auto-project/annotation-user/src/main/java/com/baeldung/annotation/Person.java similarity index 100% rename from annotations/annotation-user/src/main/java/com/baeldung/annotation/Person.java rename to google-auto-project/annotation-user/src/main/java/com/baeldung/annotation/Person.java diff --git a/annotations/annotation-user/src/main/resources/logback.xml b/google-auto-project/annotation-user/src/main/resources/logback.xml similarity index 100% rename from annotations/annotation-user/src/main/resources/logback.xml rename to google-auto-project/annotation-user/src/main/resources/logback.xml diff --git a/annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderUnitTest.java b/google-auto-project/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderUnitTest.java similarity index 100% rename from annotations/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderUnitTest.java rename to google-auto-project/annotation-user/src/test/java/com/baeldung/annotation/PersonBuilderUnitTest.java diff --git a/google-auto-project/pom.xml b/google-auto-project/pom.xml index 839ccabc5f..034fea5aad 100644 --- a/google-auto-project/pom.xml +++ b/google-auto-project/pom.xml @@ -6,6 +6,8 @@ google-auto-project 1.0 google-auto-project + pom + com.baeldung @@ -13,6 +15,11 @@ 1.0.0-SNAPSHOT + + annotation-processing + annotation-user + + com.google.auto.value diff --git a/guest/README.md b/guest/README.md deleted file mode 100644 index ff12555376..0000000000 --- a/guest/README.md +++ /dev/null @@ -1 +0,0 @@ -## Relevant articles: diff --git a/guest/memory-leaks/pom.xml b/guest/memory-leaks/pom.xml deleted file mode 100644 index 42bb71617d..0000000000 --- a/guest/memory-leaks/pom.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - 4.0.0 - memory-leaks - 0.0.1-SNAPSHOT - memory-leaks - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - ../../ - - - - - - src/main/resources/ - - **/*.java - - - - src/test/resources/ - - - - \ No newline at end of file diff --git a/guest/memory-leaks/src/test/java/com/baeldung/Key.java b/guest/memory-leaks/src/test/java/com/baeldung/Key.java deleted file mode 100644 index 6ae2fe7fcf..0000000000 --- a/guest/memory-leaks/src/test/java/com/baeldung/Key.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.baeldung; - -public class Key { - - public static String key; - - public Key(String key) { - Key.key = key; - } - -} diff --git a/guest/memory-leaks/src/test/java/com/baeldung/MemoryLeaksTest.java b/guest/memory-leaks/src/test/java/com/baeldung/MemoryLeaksTest.java deleted file mode 100644 index a8a094b4db..0000000000 --- a/guest/memory-leaks/src/test/java/com/baeldung/MemoryLeaksTest.java +++ /dev/null @@ -1,98 +0,0 @@ -//package com.baeldung; -// -//import java.io.BufferedReader; -//import java.io.File; -//import java.io.IOException; -//import java.io.InputStream; -//import java.io.InputStreamReader; -//import java.net.URISyntaxException; -//import java.net.URL; -//import java.net.URLConnection; -//import java.nio.charset.StandardCharsets; -//import java.nio.file.Files; -//import java.nio.file.Paths; -//import java.nio.file.StandardOpenOption; -//import java.util.ArrayList; -//import java.util.Map; -//import java.util.Random; -//import java.util.Scanner; -// -//import org.junit.FixMethodOrder; -//import org.junit.Test; -//import org.junit.runner.RunWith; -//import org.junit.runners.JUnit4; -//import org.junit.runners.MethodSorters; -// -//@FixMethodOrder(MethodSorters.NAME_ASCENDING) -//@RunWith(JUnit4.class) -//public class MemoryLeaksTest { -// private Random random = new Random(); -// public static final ArrayList list = new ArrayList(1000000); -// -// @Test -// public void givenStaticField_whenLotsOfOperations_thenMemoryLeak() throws InterruptedException { -// for (int i = 0; i < 1000000; i++) { -// list.add(random.nextDouble()); -// } -// System.gc(); -// Thread.sleep(10000); //to allow GC do its job -// } -// -// -// @Test -// public void givenNormalField_whenLotsOfOperations_thenGCWorksFine() throws InterruptedException { -// addElementsToTheList(); -// System.gc(); -// Thread.sleep(10000); //to allow GC do its job -// } -// -// private void addElementsToTheList(){ -// ArrayList list = new ArrayList(1000000); -// for (int i = 0; i < 1000000; i++) { -// list.add(random.nextDouble()); -// } -// } -// -// @SuppressWarnings({ "resource" }) -// @Test(expected = OutOfMemoryError.class) -// public void givenLengthString_whenIntern_thenOutOfMemory() throws IOException, InterruptedException { -// Thread.sleep(15000); -// String str = new Scanner(new File("src/test/resources/large.txt"), "UTF-8").useDelimiter("\\A") -// .next(); -// System.gc(); -// str.intern(); -// Thread.sleep(10000); -// } -// -// @Test(expected = OutOfMemoryError.class) -// public void givenURL_whenUnclosedStream_thenOutOfMemory() throws IOException, URISyntaxException { -// String str = ""; -// URLConnection conn = new URL("http:norvig.com/big.txt").openConnection(); -// BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); -// while (br.readLine() != null) { -// str += br.readLine(); -// } -// Files.write(Paths.get("src/main/resources/"), str.getBytes(), StandardOpenOption.CREATE); -// } -// -// @SuppressWarnings("unused") -// @Test(expected = OutOfMemoryError.class) -// public void givenConnection_whenUnclosed_thenOutOfMemory() throws IOException, URISyntaxException { -// URL url = new URL("ftp:speedtest.tele2.net"); -// URLConnection urlc = url.openConnection(); -// InputStream is = urlc.getInputStream(); -// String str = ""; -// while (true) { -// str += is.toString() -// .intern(); -// } -// } -// -// @Test(expected = OutOfMemoryError.class) -// public void givenMap_whenNoEqualsNoHashCodeMethods_thenOutOfMemory() throws IOException, URISyntaxException { -// Map map = System.getProperties(); -// while (true) { -// map.put(new Key("key"), "value"); -// } -// } -//} diff --git a/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java b/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java index 047d53ab62..4dc9e40292 100644 --- a/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java +++ b/jackson-modules/jackson-conversions/src/test/java/com/baeldung/jackson/date/JacksonDateUnitTest.java @@ -20,6 +20,7 @@ import org.joda.time.DateTimeZone; import org.junit.Test; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.util.StdDateFormat; @@ -67,6 +68,8 @@ public class JacksonDateUnitTest { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.findAndRegisterModules(); objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + objectMapper.enable(SerializationFeature.WRITE_DATES_WITH_ZONE_ID); + objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE); ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")); String converted = objectMapper.writeValueAsString(now); diff --git a/jackson-modules/jackson-polymorphic-deserialization/README.md b/jackson-modules/jackson-polymorphic-deserialization/README.md index feb40da5c4..a8468ab829 100644 --- a/jackson-modules/jackson-polymorphic-deserialization/README.md +++ b/jackson-modules/jackson-polymorphic-deserialization/README.md @@ -1,2 +1,2 @@ ## Relevant Articles -- [@JsonSubTypes Vs. Reflections for Polymorphic Deserialization in Jackson](https://www.baeldung.com/java-jackson-polymorphic-deserialization) +- [@JsonSubTypes vs. Reflections for Polymorphic Deserialization in Jackson](https://www.baeldung.com/java-jackson-polymorphic-deserialization) diff --git a/jackson-modules/jackson-polymorphic-deserialization/pom.xml b/jackson-modules/jackson-polymorphic-deserialization/pom.xml index afa9cab82f..0d88c19500 100644 --- a/jackson-modules/jackson-polymorphic-deserialization/pom.xml +++ b/jackson-modules/jackson-polymorphic-deserialization/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 jackson-polymorphic-deserialization jackson-polymorphic-deserialization diff --git a/java-jdi/pom.xml b/java-jdi/pom.xml index aad2f7cfff..e7b2326e21 100644 --- a/java-jdi/pom.xml +++ b/java-jdi/pom.xml @@ -14,10 +14,6 @@ ../parent-java - - - - java-jdi @@ -33,9 +29,6 @@ ${maven.compiler.source.version} ${maven.compiler.target.version} - - --add-exports=jdk.jdi/com.sun.jdi=ALL-UNNAMED - diff --git a/java-panama/pom.xml b/java-panama/pom.xml index 7c6b420eeb..18dffaec73 100644 --- a/java-panama/pom.xml +++ b/java-panama/pom.xml @@ -1,10 +1,10 @@ - ${project.model.version} + 4.0.0 com.baeldung.java.panama java-panama - ${project.version} + 1.0 java-panama jar diff --git a/java-spi/exchange-rate-api/src/main/java/com/baeldung/rate/ExchangeRate.java b/java-spi/exchange-rate-api/src/main/java/com/baeldung/rate/ExchangeRate.java index afc7ef92ce..026f5a23c5 100644 --- a/java-spi/exchange-rate-api/src/main/java/com/baeldung/rate/ExchangeRate.java +++ b/java-spi/exchange-rate-api/src/main/java/com/baeldung/rate/ExchangeRate.java @@ -16,9 +16,7 @@ public final class ExchangeRate { public static List providers() { List services = new ArrayList<>(); ServiceLoader loader = ServiceLoader.load(ExchangeRateProvider.class); - loader.forEach(exchangeRateProvider -> { - services.add(exchangeRateProvider); - }); + loader.forEach(services::add); return services; } diff --git a/java-spi/exchange-rate-api/src/main/java/com/baeldung/rate/api/Quote.java b/java-spi/exchange-rate-api/src/main/java/com/baeldung/rate/api/Quote.java index 577af3b618..b5c2bf23fb 100644 --- a/java-spi/exchange-rate-api/src/main/java/com/baeldung/rate/api/Quote.java +++ b/java-spi/exchange-rate-api/src/main/java/com/baeldung/rate/api/Quote.java @@ -8,7 +8,12 @@ public class Quote { private BigDecimal ask; private BigDecimal bid; private LocalDate date; - //... + + public Quote(String currency, BigDecimal ask, BigDecimal bid) { + this.currency = currency; + this.ask = ask; + this.bid = bid; + } public String getCurrency() { return currency; diff --git a/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/QuoteResponse.java b/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/QuoteResponse.java deleted file mode 100644 index 9ba4fb26b0..0000000000 --- a/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/QuoteResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.baeldung.rate.impl; - -import com.baeldung.rate.api.Quote; - -import java.util.List; - -public class QuoteResponse { - private List result; - private String error; - - public List getResult() { - return result; - } - - public void setResult(List result) { - this.result = result; - } - - public String getError() { - return error; - } - - public void setError(String error) { - this.error = error; - } -} diff --git a/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/QuoteResponseWrapper.java b/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/QuoteResponseWrapper.java deleted file mode 100644 index 6d7be086f0..0000000000 --- a/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/QuoteResponseWrapper.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.rate.impl; - -public class QuoteResponseWrapper { - private QuoteResponse quoteResponse; - - public QuoteResponse getQuoteResponse() { - return quoteResponse; - } - - public void setQuoteResponse(QuoteResponse quoteResponse) { - this.quoteResponse = quoteResponse; - } -} diff --git a/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/YahooQuoteManagerImpl.java b/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/YahooQuoteManagerImpl.java index f5c60699c7..ff507d4c9f 100644 --- a/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/YahooQuoteManagerImpl.java +++ b/java-spi/exchange-rate-impl/src/main/java/com/baeldung/rate/impl/YahooQuoteManagerImpl.java @@ -2,64 +2,102 @@ package com.baeldung.rate.impl; import com.baeldung.rate.api.Quote; import com.baeldung.rate.api.QuoteManager; + import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; +import javax.json.bind.Jsonb; import javax.json.bind.JsonbBuilder; import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; +import java.math.BigDecimal; import java.time.LocalDate; +import java.util.ArrayList; import java.util.Currency; import java.util.List; +import java.util.Map; public class YahooQuoteManagerImpl implements QuoteManager { - static final String URL_PROVIDER = "https://query1.finance.yahoo.com/v7/finance/quote"; + static final String URL_PROVIDER = "https://query2.finance.yahoo.com/v6/finance/quoteSummary/%s=X?modules=summaryDetail"; OkHttpClient client = new OkHttpClient(); @Override public List getQuotes(String baseCurrency, LocalDate date) { - StringBuilder sb = new StringBuilder(); + List currencyQuery = new ArrayList<>(); Currency.getAvailableCurrencies().forEach(currency -> { if (!baseCurrency.equals(currency.getCurrencyCode())) { - sb.append(baseCurrency).append(currency.getCurrencyCode()).append("=X").append(","); + currencyQuery.add(String.format(URL_PROVIDER, baseCurrency + currency.getCurrencyCode())); } }); - - String value = ""; - try { - value = URLEncoder.encode(sb.toString().substring(0, sb.toString().length() - 1), "UTF-8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); + final List quotes = new ArrayList<>(); + for (String url: currencyQuery) { + String response = doGetRequest(url); + if (response != null) { + final Quote map = map(response); + if (map != null) { + quotes.add(map); + } + } } - String queryString = String.format("%s=%s", "symbols", value); - String response = doGetRequest(queryString); - System.out.println(response); - return map(response); + return quotes; } - private List map(String response) { - QuoteResponseWrapper qrw = JsonbBuilder.create().fromJson(response, QuoteResponseWrapper.class); - return qrw.getQuoteResponse().getResult(); + private Quote map(String response) { + try (final Jsonb jsonb = JsonbBuilder.create()) { + final Map qrw = jsonb.fromJson(response, Map.class); + return parseResult(qrw); + } catch (Exception e) { + System.out.println("Error while trying to read response"); + return null; + } } - String doGetRequest(String queryString) { - String fullUrl = URL_PROVIDER + "?" + queryString; + private static Quote parseResult(Map qrw) { + Quote quote = null; + if (qrw != null) { + final Map quoteSummary = (Map) qrw.get("quoteSummary"); + if (quoteSummary != null) { + final List result = (List) quoteSummary.get("result"); + if (result != null) { + final Map resultArray = result.get(0); + if (resultArray != null) { + final Map summaryDetail = (Map) resultArray.get("summaryDetail"); + if (summaryDetail != null) { + quote = constructQuote(summaryDetail); + } + } + } + } + } + return quote; + } - System.out.println(fullUrl); + private static Quote constructQuote(Map summaryDetail) { + final String currency = (String) summaryDetail.get("currency"); + final Map ask = (Map) summaryDetail.get("ask"); + final Map bid = (Map) summaryDetail.get("bid"); + final BigDecimal askPrice = (BigDecimal) ask.get("raw"); + final BigDecimal bidPrice = (BigDecimal) bid.get("raw"); + if (askPrice != null && bidPrice != null) { + return new Quote(currency, askPrice, bidPrice); + } + return null; + } + + String doGetRequest(String url) { + + System.out.println(url); Request request = new Request.Builder() - .url(fullUrl) + .url(url) .build(); - Response response = null; + Response response; try { response = client.newCall(request).execute(); return response.body().string(); } catch (IOException e) { - e.printStackTrace(); + return null; } - return null; } } diff --git a/java-websocket/pom.xml b/java-websocket/pom.xml index 7c5c006aa9..d529b32022 100644 --- a/java-websocket/pom.xml +++ b/java-websocket/pom.xml @@ -30,7 +30,6 @@ 1.1 2.8.0 - 3.3.2 \ No newline at end of file diff --git a/javaxval/README.md b/javaxval/README.md index 7420580f8e..be8c3b51b7 100644 --- a/javaxval/README.md +++ b/javaxval/README.md @@ -3,7 +3,7 @@ This module contains articles about Bean Validation. ### Relevant Articles: -- [Java Bean Validation Basics](https://www.baeldung.com/javax-validation) +- [Java Bean Validation Basics](https://www.baeldung.com/java-validation) - [Validating Container Elements with Jakarta Bean Validation 3.0](https://www.baeldung.com/bean-validation-container-elements) - [Validations for Enum Types](https://www.baeldung.com/javax-validations-enums) - [Javax BigDecimal Validation](https://www.baeldung.com/javax-bigdecimal-validation) diff --git a/jersey/pom.xml b/jersey/pom.xml index 005fa85077..c2b37f7118 100644 --- a/jersey/pom.xml +++ b/jersey/pom.xml @@ -100,7 +100,6 @@ 3.1.1 - 3.3.2 \ No newline at end of file diff --git a/jhipster-6/README.md b/jhipster-6/README.md index 9db409a032..6ddf33e8cf 100644 --- a/jhipster-6/README.md +++ b/jhipster-6/README.md @@ -1,3 +1,3 @@ ## JHipster 6 -This module contains articles about JHipster 5. This is an aggregator module, articles are in the relevant submodules. +This module contains articles about JHipster 6. This is an aggregator module, articles are in the relevant submodules. diff --git a/jhipster-6/bookstore-monolith/pom.xml b/jhipster-6/bookstore-monolith/pom.xml index f719baab8b..a35abb9c19 100644 --- a/jhipster-6/bookstore-monolith/pom.xml +++ b/jhipster-6/bookstore-monolith/pom.xml @@ -1,7 +1,6 @@ 4.0.0 - com.baeldung.jhipster6 bookstore-monolith 0.0.1-SNAPSHOT @@ -56,10 +55,6 @@ jaxb-runtime 4.0.0 - - - - com.fasterxml.jackson.datatype jackson-datatype-hibernate5 @@ -649,6 +644,76 @@ + + default-jdk9-and-above + + + + com.github.eirslett + frontend-maven-plugin + + + install node and npm + + true + + + + npm install + + true + + + + webpack build dev + + true + + + + webpack build test + none + + + + + + + + integration-jdk9-and-above + + + + com.github.eirslett + frontend-maven-plugin + + + install node and npm + + true + + + + npm install + + true + + + + webpack build dev + + true + + + + webpack build test + none + + + + + + no-liquibase @@ -1098,7 +1163,7 @@ 3.1.0 - 3.8.0 + 3.11.0 2.10 3.0.0-M1 2.2.1 diff --git a/jmh/pom.xml b/jmh/pom.xml index e5e0f46044..e8a88bf301 100644 --- a/jmh/pom.xml +++ b/jmh/pom.xml @@ -83,10 +83,8 @@ - 3.3.0 0.17 3.5.0 - 3.11.0 \ No newline at end of file diff --git a/jsf/pom.xml b/jsf/pom.xml index 81030537fb..09dea98f65 100644 --- a/jsf/pom.xml +++ b/jsf/pom.xml @@ -76,8 +76,6 @@ 2.2.14 3.0.0 - - 3.3.1 1.3.1 diff --git a/json-modules/json-2/README.md b/json-modules/json-2/README.md index a29484d9fc..f41a7047fa 100644 --- a/json-modules/json-2/README.md +++ b/json-modules/json-2/README.md @@ -13,5 +13,6 @@ This module contains articles about JSON. - [Getting a Value in JSONObject](https://www.baeldung.com/java-jsonobject-get-value) - [Pretty-Print a JSON in Java](https://www.baeldung.com/java-json-pretty-print) - [Remove Whitespaces From a JSON in Java](https://www.baeldung.com/java-json-minify-remove-whitespaces) +- [Programmatic Generation of JSON Schemas in Java](https://www.baeldung.com/java-json-schema-create-automatically) - More Articles: [[<-- prev]](/json-modules/json) diff --git a/json-modules/json-arrays/README.md b/json-modules/json-arrays/README.md new file mode 100644 index 0000000000..f119467046 --- /dev/null +++ b/json-modules/json-arrays/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [How to Check if a Value Exists in a JSON Array for a Particular Key](https://www.baeldung.com/java-json-array-check-key-value-pair) diff --git a/json-modules/json-conversion/README.md b/json-modules/json-conversion/README.md index 86e8365c70..a0cf0f6246 100644 --- a/json-modules/json-conversion/README.md +++ b/json-modules/json-conversion/README.md @@ -4,3 +4,4 @@ This module contains articles about JSON Conversions ### Relevant Articles: - [Convert JSON Array to Java List](https://www.baeldung.com/java-convert-json-array-to-list) +- [Reading JSON Documents as Maps and Comparing Them](https://www.baeldung.com/java-json-maps-comparison) diff --git a/json-modules/json-conversion/pom.xml b/json-modules/json-conversion/pom.xml index 1af13cbbcb..680f27fa38 100644 --- a/json-modules/json-conversion/pom.xml +++ b/json-modules/json-conversion/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.baeldung json-conversion @@ -29,11 +29,17 @@ jackson-databind ${jackson.version} + + com.google.guava + guava + ${guava.version} + 20211205 2.10.1 + 32.1.2-jre diff --git a/json-modules/json-conversion/src/main/java/com/baeldung/jsontomap/FlattenUtils.java b/json-modules/json-conversion/src/main/java/com/baeldung/jsontomap/FlattenUtils.java new file mode 100644 index 0000000000..2fd49d99ad --- /dev/null +++ b/json-modules/json-conversion/src/main/java/com/baeldung/jsontomap/FlattenUtils.java @@ -0,0 +1,36 @@ +package com.baeldung.jsontomap; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FlattenUtils { + public static Map flatten(Map map) { + return flatten(map, null); + } + + private static Map flatten(Map map, String prefix) { + Map flatMap = new HashMap<>(); + map.forEach((key, value) -> { + String newKey = prefix != null ? prefix + "." + key : key; + if (value instanceof Map) { + flatMap.putAll(flatten((Map) value, newKey)); + } else if (value instanceof List) { + // check for list of primitives + Object element = ((List) value).get(0); + if (element instanceof String || element instanceof Number || element instanceof Boolean) { + flatMap.put(newKey, value); + } else { + // check for list of objects + List> list = (List>) value; + for (int i = 0; i < list.size(); i++) { + flatMap.putAll(flatten(list.get(i), newKey + "[" + i + "]")); + } + } + } else { + flatMap.put(newKey, value); + } + }); + return flatMap; + } +} \ No newline at end of file diff --git a/json-modules/json-conversion/src/main/java/com/baeldung/jsontomap/JsonUtils.java b/json-modules/json-conversion/src/main/java/com/baeldung/jsontomap/JsonUtils.java new file mode 100644 index 0000000000..35339494fb --- /dev/null +++ b/json-modules/json-conversion/src/main/java/com/baeldung/jsontomap/JsonUtils.java @@ -0,0 +1,23 @@ +package com.baeldung.jsontomap; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Map; + +public class JsonUtils { + public static Map jsonFileToMap(String path) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(new File(path), new TypeReference>() {}); + } + + public static Map jsonFileToMapGson(String path) throws IOException { + Gson gson = new Gson(); + return gson.fromJson(new FileReader(path), new TypeToken>() {}.getType()); + } +} diff --git a/json-modules/json-conversion/src/test/java/com/baeldung/jsontomap/JSONComparisonUnitTest.java b/json-modules/json-conversion/src/test/java/com/baeldung/jsontomap/JSONComparisonUnitTest.java new file mode 100644 index 0000000000..908161c258 --- /dev/null +++ b/json-modules/json-conversion/src/test/java/com/baeldung/jsontomap/JSONComparisonUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.jsontomap; + +import com.google.common.collect.MapDifference; +import com.google.common.collect.Maps; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; + +public class JSONComparisonUnitTest { + + @Test + void givenTwoJsonFiles_whenCompared_thenTheyAreDifferent() throws IOException { + Map firstMap = JsonUtils.jsonFileToMap("src/test/resources/first.json"); + Map secondMap = JsonUtils.jsonFileToMap("src/test/resources/second.json"); + + MapDifference difference = Maps.difference(firstMap, secondMap); + difference.entriesDiffering().forEach((key, value) -> { + System.out.println(key + ": " + value.leftValue() + " - " + value.rightValue()); + }); + assertThat(difference.areEqual()).isFalse(); + } + + @Test + void givenTwoJsonFiles_whenFlattenedAndCompared_thenTheyAreDifferent() throws IOException { + Map firstFlatMap = FlattenUtils.flatten(JsonUtils.jsonFileToMap("src/test/resources/first.json")); + Map secondFlatMap = FlattenUtils.flatten(JsonUtils.jsonFileToMap("src/test/resources/second.json")); + + MapDifference difference = Maps.difference(firstFlatMap, secondFlatMap); + difference.entriesDiffering().forEach((key, value) -> { + System.out.println(key + ": " + value.leftValue() + " - " + value.rightValue()); + }); + assertThat(difference.areEqual()).isFalse(); + } +} diff --git a/json-modules/json-conversion/src/test/resources/first.json b/json-modules/json-conversion/src/test/resources/first.json new file mode 100644 index 0000000000..905859c59f --- /dev/null +++ b/json-modules/json-conversion/src/test/resources/first.json @@ -0,0 +1,22 @@ +{ + "name": "John", + "age": 30, + "cars": [ + "Ford", + "BMW" + ], + "address": { + "street": "Second Street", + "city": "New York" + }, + "children": [ + { + "name": "Sara", + "age": 5 + }, + { + "name": "Alex", + "age": 3 + } + ] +} \ No newline at end of file diff --git a/json-modules/json-conversion/src/test/resources/second.json b/json-modules/json-conversion/src/test/resources/second.json new file mode 100644 index 0000000000..503228519f --- /dev/null +++ b/json-modules/json-conversion/src/test/resources/second.json @@ -0,0 +1,22 @@ +{ + "name": "John", + "age": 30, + "cars": [ + "Ford", + "Audi" + ], + "address": { + "street": "Main Street", + "city": "New York" + }, + "children": [ + { + "name": "Peter", + "age": 5 + }, + { + "name": "Cathy", + "age": 10 + } + ] +} \ No newline at end of file diff --git a/jws/pom.xml b/jws/pom.xml index 2f01f90721..12aa76127c 100644 --- a/jws/pom.xml +++ b/jws/pom.xml @@ -61,8 +61,4 @@ - - 3.0.2 - - diff --git a/kubernetes-modules/jkube-demo/pom.xml b/kubernetes-modules/jkube-demo/pom.xml index 7bb662c4a3..6fedc0f24a 100644 --- a/kubernetes-modules/jkube-demo/pom.xml +++ b/kubernetes-modules/jkube-demo/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 com.baeldung diff --git a/kubernetes-modules/pom.xml b/kubernetes-modules/pom.xml index ffe9c42472..9bd623b4f4 100644 --- a/kubernetes-modules/pom.xml +++ b/kubernetes-modules/pom.xml @@ -17,6 +17,7 @@ k8s-intro k8s-admission-controller kubernetes-spring + k8s-java-heap-dump diff --git a/libraries-data-2/pom.xml b/libraries-data-2/pom.xml index e19067daa3..0d0ba2dc82 100644 --- a/libraries-data-2/pom.xml +++ b/libraries-data-2/pom.xml @@ -86,13 +86,11 @@ spring-web ${spring.version} - org.derive4j derive4j @@ -162,17 +160,6 @@ - - 1.16.1 @@ -181,7 +168,7 @@ 1.0.3 14.0.6.Final 5.3.25 - 4.0.0 + 0.1.0 1.1.0 3.0.0 2.8.4 diff --git a/libraries-data-2/src/main/java/com/baeldung/suanshu/SuanShuMath.java b/libraries-data-2/src/main/java/com/baeldung/suanshu/SuanShuMath.java index a5365871c6..faf254ee97 100644 --- a/libraries-data-2/src/main/java/com/baeldung/suanshu/SuanShuMath.java +++ b/libraries-data-2/src/main/java/com/baeldung/suanshu/SuanShuMath.java @@ -1,23 +1,22 @@ package com.baeldung.suanshu; -/* -import com.numericalmethod.suanshu.algebra.linear.matrix.doubles.Matrix; -import com.numericalmethod.suanshu.algebra.linear.matrix.doubles.matrixtype.dense.DenseMatrix; -import com.numericalmethod.suanshu.algebra.linear.matrix.doubles.operation.Inverse; -import com.numericalmethod.suanshu.algebra.linear.vector.doubles.Vector; -import com.numericalmethod.suanshu.algebra.linear.vector.doubles.dense.DenseVector; +import com.numericalmethod.suanshu.matrix.doubles.Matrix; +import com.numericalmethod.suanshu.matrix.doubles.matrixtype.dense.DenseMatrix; +import com.numericalmethod.suanshu.matrix.doubles.operation.Inverse; +import com.numericalmethod.suanshu.vector.doubles.Vector; +import com.numericalmethod.suanshu.vector.doubles.dense.DenseVector; import com.numericalmethod.suanshu.analysis.function.polynomial.Polynomial; import com.numericalmethod.suanshu.analysis.function.polynomial.root.PolyRoot; import com.numericalmethod.suanshu.analysis.function.polynomial.root.PolyRootSolver; import com.numericalmethod.suanshu.number.complex.Complex; -*/ + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; class SuanShuMath { -/** fixing in JAVA-24004 + private static final Logger log = LoggerFactory.getLogger(SuanShuMath.class); public static void main(String[] args) throws Exception { @@ -139,5 +138,5 @@ class SuanShuMath { List roots = solver.solve(p); log.info("Finding polynomial roots: {}", roots); } -*/ + } diff --git a/libraries-server-2/pom.xml b/libraries-server-2/pom.xml index cf5d016d9f..7377fa3fa9 100644 --- a/libraries-server-2/pom.xml +++ b/libraries-server-2/pom.xml @@ -73,7 +73,6 @@ 9.4.27.v20200227 8.1.11.v20170118 - 3.2.2 \ No newline at end of file diff --git a/libraries/pom.xml b/libraries/pom.xml index 2ab345c469..07a4853728 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -291,7 +291,6 @@ 2.3.0 3.29.2-GA 0.9.12 - 3.0.2 3.6 2.6 diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml index cddc2e72ea..8df95c18bb 100644 --- a/logging-modules/logback/pom.xml +++ b/logging-modules/logback/pom.xml @@ -71,11 +71,11 @@ runtime - org.projectlombok - lombok - provided + org.projectlombok + lombok + provided ${lombok.version} - + diff --git a/lombok-modules/lombok-2/README.md b/lombok-modules/lombok-2/README.md index 6d3482d800..83fdb382ee 100644 --- a/lombok-modules/lombok-2/README.md +++ b/lombok-modules/lombok-2/README.md @@ -13,4 +13,5 @@ This module contains articles about Project Lombok. - [@StandardException Annotation in Lombok](https://www.baeldung.com/lombok-standardexception-annotation) - [Lombok EqualsAndHashCode Annotation](https://www.baeldung.com/java-lombok-equalsandhashcode) - [Lombok’s @RequiredArgsConstructor Annotation](https://www.baeldung.com/java-lombok-constructor-annotation) +- [Generate Models Using OpenAPI With Lombok Annotations](https://www.baeldung.com/java-openapi-lombok-create-models) - More articles: [[<-- prev]](../lombok) diff --git a/mapstruct/README.md b/mapstruct/README.md index 790b4b1a93..dd2a3bddd8 100644 --- a/mapstruct/README.md +++ b/mapstruct/README.md @@ -11,3 +11,4 @@ This module contains articles about MapStruct. - [Mapping Collections with MapStruct](https://www.baeldung.com/java-mapstruct-mapping-collections) - [Use Mapper in Another Mapper with Mapstruct and Java](https://www.baeldung.com/java-mapstruct-nested-mapping) - [Throw Exception for Unexpected Input for Enum With MapStruct](https://www.baeldung.com/java-mapstruct-enum-unexpected-input-exception) +- [How to Use Conditional Mapping With MapStruct](https://www.baeldung.com/java-mapstruct-bean-types-conditional) diff --git a/mapstruct/src/main/java/com/baeldung/expression/dto/LicenseDto.java b/mapstruct/src/main/java/com/baeldung/expression/dto/LicenseDto.java new file mode 100644 index 0000000000..025df1a4f6 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/expression/dto/LicenseDto.java @@ -0,0 +1,38 @@ +package com.baeldung.expression.dto; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class LicenseDto { + + private UUID id; + + private LocalDateTime startDate; + + private LocalDateTime endDate; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public LocalDateTime getStartDate() { + return startDate; + } + + public void setStartDate(LocalDateTime startDate) { + this.startDate = startDate; + } + + public LocalDateTime getEndDate() { + return endDate; + } + + public void setEndDate(LocalDateTime endDate) { + this.endDate = endDate; + } + +} diff --git a/mapstruct/src/main/java/com/baeldung/expression/mapper/LicenseMapper.java b/mapstruct/src/main/java/com/baeldung/expression/mapper/LicenseMapper.java new file mode 100644 index 0000000000..100588b45d --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/expression/mapper/LicenseMapper.java @@ -0,0 +1,43 @@ +package com.baeldung.expression.mapper; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; + +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; + +import com.baeldung.expression.dto.LicenseDto; +import com.baeldung.expression.model.License; + +@Mapper +public interface LicenseMapper { + + @Mapping(target = "startDate", expression = "java(mapStartDate(licenseDto))") + @Mapping(target = "endDate", ignore = true) + @Mapping(target = "active", constant = "true") + @Mapping(target = "renewalRequired", conditionExpression = "java(isEndDateInTwoWeeks(licenseDto))", source = ".") + License toLicense(LicenseDto licenseDto); + + @AfterMapping + default void afterMapping(LicenseDto licenseDto, @MappingTarget License license) { + OffsetDateTime endDate = licenseDto.getEndDate() != null ? licenseDto.getEndDate() + .atOffset(ZoneOffset.UTC) : OffsetDateTime.now() + .plusYears(1); + license.setEndDate(endDate); + } + + default OffsetDateTime mapStartDate(LicenseDto licenseDto) { + return licenseDto.getStartDate() != null ? licenseDto.getStartDate() + .atOffset(ZoneOffset.UTC) : OffsetDateTime.now(); + } + + default boolean isEndDateInTwoWeeks(LicenseDto licenseDto) { + return licenseDto.getEndDate() != null && Duration.between(licenseDto.getEndDate(), LocalDateTime.now()) + .toDays() <= 14; + } + +} diff --git a/mapstruct/src/main/java/com/baeldung/expression/model/License.java b/mapstruct/src/main/java/com/baeldung/expression/model/License.java new file mode 100644 index 0000000000..71e4f086c0 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/expression/model/License.java @@ -0,0 +1,58 @@ +package com.baeldung.expression.model; + +import java.time.OffsetDateTime; +import java.util.UUID; + + +public class License { + + private UUID id; + + private OffsetDateTime startDate; + + private OffsetDateTime endDate; + + private boolean active; + + private boolean renewalRequired; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public OffsetDateTime getStartDate() { + return startDate; + } + + public void setStartDate(OffsetDateTime startDate) { + this.startDate = startDate; + } + + public OffsetDateTime getEndDate() { + return endDate; + } + + public void setEndDate(OffsetDateTime endDate) { + this.endDate = endDate; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public boolean isRenewalRequired() { + return renewalRequired; + } + + public void setRenewalRequired(boolean renewalRequired) { + this.renewalRequired = renewalRequired; + } +} diff --git a/mapstruct/src/test/java/com/baeldung/expression/mapper/LicenseMapperUnitTest.java b/mapstruct/src/test/java/com/baeldung/expression/mapper/LicenseMapperUnitTest.java new file mode 100644 index 0000000000..dcdda5c1ac --- /dev/null +++ b/mapstruct/src/test/java/com/baeldung/expression/mapper/LicenseMapperUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.expression.mapper; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.UUID; + +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +import com.baeldung.expression.dto.LicenseDto; +import com.baeldung.expression.model.License; + +class LicenseMapperUnitTest { + + LicenseMapper licenseMapper = Mappers.getMapper(LicenseMapper.class); + + @Test + void givenLicenseDtoWithStartDateAndWithoutEndDate_WhenMapperMethodIsInvoked_ThenLicenseShouldBePopulatedWithDefaultEndDate() { + LicenseDto licenseDto = new LicenseDto(); + licenseDto.setStartDate(LocalDateTime.now()); + License license = licenseMapper.toLicense(licenseDto); + assertThat(license).isNotNull(); + assertThat(license.getEndDate() + .toLocalDate()).isEqualTo(LocalDate.now() + .plusYears(1)); + } + + @Test + void givenLicenseDtoWithEndDateAndWithoutStartDate_WhenMapperMethodIsInvoked_ThenLicenseShouldBePopulatedWithDefaultStartDate() { + LicenseDto licenseDto = new LicenseDto(); + licenseDto.setEndDate(LocalDateTime.now() + .plusYears(2)); + License license = licenseMapper.toLicense(licenseDto); + assertThat(license).isNotNull(); + assertThat(license.getStartDate() + .toLocalDate()).isEqualTo(LocalDate.now()); + } + + @Test + void givenLicenseDtoWithoutStartDateAndEndDate_WhenMapperMethodIsInvoked_ThenLicenseShouldBePopulatedWithDefaultDetails() { + LicenseDto licenseDto = new LicenseDto(); + License license = licenseMapper.toLicense(licenseDto); + assertThat(license).isNotNull(); + assertThat(license.getStartDate() + .toLocalDate()).isEqualTo(LocalDate.now()); + assertThat(license.getEndDate() + .toLocalDate()).isEqualTo(LocalDate.now() + .plusYears(1)); + assertThat(license.isActive()).isTrue(); + assertThat(license.isRenewalRequired()).isFalse(); + } + + @Test + void givenLicenseDtoWithEndDateInTwoWeeks_WhenMapperMethodIsInvoked_ThenLicenseShouldBePopulatedWithRenewalRequiredSetToTrue() { + LicenseDto licenseDto = new LicenseDto(); + licenseDto.setEndDate(LocalDateTime.now() + .plusDays(10)); + License license = licenseMapper.toLicense(licenseDto); + assertThat(license).isNotNull(); + assertThat(license.isRenewalRequired()).isTrue(); + } + + @Test + void givenLicenseDtoWithoutId_WhenMapperMethodIsInvoked_ThenLicenseShouldBePopulatedWithValidId() { + LicenseDto licenseDto = new LicenseDto(); + UUID id = UUID.randomUUID(); + licenseDto.setId(id); + licenseDto.setEndDate(LocalDateTime.now() + .plusDays(10)); + License license = licenseMapper.toLicense(licenseDto); + assertThat(license).isNotNull(); + assertThat(license.getId()).isSameAs(id); + } + +} \ No newline at end of file diff --git a/maven-modules/compiler-plugin-java-9/pom.xml b/maven-modules/compiler-plugin-java-9/pom.xml index 1063ee2e8f..54ec811374 100644 --- a/maven-modules/compiler-plugin-java-9/pom.xml +++ b/maven-modules/compiler-plugin-java-9/pom.xml @@ -22,7 +22,7 @@ - 3.8.0 + 3.11.0 9 9 diff --git a/maven-modules/host-maven-repo-example/pom.xml b/maven-modules/host-maven-repo-example/pom.xml index d5f36713d0..3bb1d721a8 100644 --- a/maven-modules/host-maven-repo-example/pom.xml +++ b/maven-modules/host-maven-repo-example/pom.xml @@ -18,7 +18,7 @@ org.apache.maven.plugins maven-source-plugin - 3.1.0 + ${maven-source-plugin.version} attach-sources @@ -31,7 +31,7 @@ com.github.github site-maven-plugin - 0.12 + ${site-maven-plugin.version} Maven artifacts for ${project.version} true @@ -56,7 +56,7 @@ maven-deploy-plugin - 2.8.2 + ${maven-deploy-plugin.version} internal.repo::default::file://${project.build.directory}/mvn-artifact @@ -66,7 +66,7 @@ org.apache.maven.plugins maven-source-plugin - 3.1.0 + ${maven-source-plugin.version} attach-sources @@ -106,6 +106,10 @@ github 8 8 + 3.1.0 + 2.8.2 + 3.1.0 + 0.12 \ No newline at end of file diff --git a/maven-modules/jacoco-coverage-aggregation/README.md b/maven-modules/jacoco-coverage-aggregation/README.md new file mode 100644 index 0000000000..98c3748330 --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Maven Multi-Module Project Coverage With Jacoco](https://www.baeldung.com/maven-jacoco-multi-module-project) diff --git a/maven-modules/jacoco-coverage-aggregation/aggregate-report/pom.xml b/maven-modules/jacoco-coverage-aggregation/aggregate-report/pom.xml new file mode 100644 index 0000000000..1a076cacae --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/aggregate-report/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + com.baeldung.jacoco-coverage-aggregation + aggregate-report + aggregate-report + pom + + + com.baeldung + jacoco-coverage-aggregation + 1.0 + + + + + com.baeldung.jacoco-coverage-aggregation + services + ${project.parent.version} + + + com.baeldung.jacoco-coverage-aggregation + controllers + ${project.parent.version} + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + verify + + report-aggregate + + + + **/jacoco.exec + + + ${project.reporting.outputDirectory}/jacoco-aggregate + + + + + + + + + + 0.8.8 + + + \ No newline at end of file diff --git a/maven-modules/jacoco-coverage-aggregation/controllers/pom.xml b/maven-modules/jacoco-coverage-aggregation/controllers/pom.xml new file mode 100644 index 0000000000..5aa54f042f --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/controllers/pom.xml @@ -0,0 +1,64 @@ + + + 4.0.0 + com.baeldung.jacoco-coverage-aggregation + controllers + controllers + jar + + + com.baeldung + jacoco-coverage-aggregation + 1.0 + + + + + com.baeldung.jacoco-coverage-aggregation + services + ${project.parent.version} + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + + integration-test + verify + + + + + + **/*IntegrationTest.java + + + + + + + + 3.0.9 + 3.1.2 + + + \ No newline at end of file diff --git a/maven-modules/jacoco-coverage-aggregation/controllers/src/main/java/com/baeldung/coverageaggregation/MyApplication.java b/maven-modules/jacoco-coverage-aggregation/controllers/src/main/java/com/baeldung/coverageaggregation/MyApplication.java new file mode 100644 index 0000000000..03b8cb6b87 --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/controllers/src/main/java/com/baeldung/coverageaggregation/MyApplication.java @@ -0,0 +1,11 @@ +package com.baeldung.coverageaggregation; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MyApplication { + public static void main(String[] args) { + SpringApplication.run(MyApplication.class, args); + } +} \ No newline at end of file diff --git a/maven-modules/jacoco-coverage-aggregation/controllers/src/main/java/com/baeldung/coverageaggregation/MyController.java b/maven-modules/jacoco-coverage-aggregation/controllers/src/main/java/com/baeldung/coverageaggregation/MyController.java new file mode 100644 index 0000000000..59217a5b94 --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/controllers/src/main/java/com/baeldung/coverageaggregation/MyController.java @@ -0,0 +1,30 @@ +package com.baeldung.coverageaggregation; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +class MyController { + + private final MyService myService; + + public MyController(MyService myService) { + this.myService = myService; + } + + @GetMapping("/tested") + String fullyTested() { + return myService.coveredByUnitAndIntegrationTests(); + } + + @GetMapping("/indirecttest") + String indirectlyTestingServiceMethod() { + return myService.coveredByIntegrationTest(); + } + + @GetMapping("/nottested") + String notTested() { + return myService.notTested(); + } + +} \ No newline at end of file diff --git a/maven-modules/jacoco-coverage-aggregation/controllers/src/test/java/com/baeldung/coverageaggregation/MyControllerIntegrationTest.java b/maven-modules/jacoco-coverage-aggregation/controllers/src/test/java/com/baeldung/coverageaggregation/MyControllerIntegrationTest.java new file mode 100644 index 0000000000..3811f7e150 --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/controllers/src/test/java/com/baeldung/coverageaggregation/MyControllerIntegrationTest.java @@ -0,0 +1,40 @@ +package com.baeldung.coverageaggregation; + +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.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +@SpringBootTest(classes = MyApplication.class) +@AutoConfigureMockMvc +class MyControllerIntegrationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void whenFullyTested_ThenCorrectText() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/tested")) + .andExpect(MockMvcResultMatchers.status() + .isOk()) + .andExpect(MockMvcResultMatchers.content() + .string("covered by unit and integration tests")); + } + + @Test + void whenIndirectlyTestingServiceMethod_ThenCorrectText() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/indirecttest")) + .andExpect(MockMvcResultMatchers.status() + .isOk()) + .andExpect(MockMvcResultMatchers.content() + .string("covered by integration test")); + } + +} diff --git a/maven-modules/jacoco-coverage-aggregation/pom.xml b/maven-modules/jacoco-coverage-aggregation/pom.xml new file mode 100644 index 0000000000..d85f41968d --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + com.baeldung + jacoco-coverage-aggregation + 1.0 + jacoco-coverage-aggregation + pom + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + services + controllers + aggregate-report + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + + prepare-agent + + + + + + + + + 0.8.8 + + + \ No newline at end of file diff --git a/maven-modules/jacoco-coverage-aggregation/services/pom.xml b/maven-modules/jacoco-coverage-aggregation/services/pom.xml new file mode 100644 index 0000000000..50c8c87f54 --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/services/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + com.baeldung.jacoco-coverage-aggregation + services + services + jar + + + com.baeldung + jacoco-coverage-aggregation + 1.0 + + + + + + org.springframework + spring-context + ${spring-context.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter-engine.version} + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.2 + + + **/*Test.java + + + + + + + + 5.9.2 + 6.0.11 + + + \ No newline at end of file diff --git a/maven-modules/jacoco-coverage-aggregation/services/src/main/java/com/baeldung/coverageaggregation/MyService.java b/maven-modules/jacoco-coverage-aggregation/services/src/main/java/com/baeldung/coverageaggregation/MyService.java new file mode 100644 index 0000000000..1c19b8d3cd --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/services/src/main/java/com/baeldung/coverageaggregation/MyService.java @@ -0,0 +1,25 @@ +package com.baeldung.coverageaggregation; + +import java.lang.String; +import org.springframework.stereotype.Service; + +@Service +class MyService { + + String unitTestedOnly() { + return "unit tested only"; + } + + String coveredByUnitAndIntegrationTests() { + return "covered by unit and integration tests"; + } + + String coveredByIntegrationTest() { + return "covered by integration test"; + } + + String notTested() { + return "not tested"; + } + +} \ No newline at end of file diff --git a/maven-modules/jacoco-coverage-aggregation/services/src/test/java/com/baeldung/coverageaggregation/MyServiceUnitTest.java b/maven-modules/jacoco-coverage-aggregation/services/src/test/java/com/baeldung/coverageaggregation/MyServiceUnitTest.java new file mode 100644 index 0000000000..017de771bf --- /dev/null +++ b/maven-modules/jacoco-coverage-aggregation/services/src/test/java/com/baeldung/coverageaggregation/MyServiceUnitTest.java @@ -0,0 +1,21 @@ +package com.baeldung.coverageaggregation; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class MyServiceUnitTest { + + MyService myService = new MyService(); + + @Test + void whenUnitTestedOnly_thenCorrectText() { + assertEquals("unit tested only", myService.unitTestedOnly()); + } + + @Test + void whenTestedMethod_thenCorrectText() { + assertEquals("covered by unit and integration tests", myService.coveredByUnitAndIntegrationTests()); + } + +} \ No newline at end of file diff --git a/maven-modules/maven-build-optimization/pom.xml b/maven-modules/maven-build-optimization/pom.xml index f0da31ceda..86d3b2d34f 100644 --- a/maven-modules/maven-build-optimization/pom.xml +++ b/maven-modules/maven-build-optimization/pom.xml @@ -7,8 +7,8 @@ 0.0.1-SNAPSHOT maven-build-optimization pom - - + + com.baeldung maven-modules 0.0.1-SNAPSHOT @@ -19,12 +19,12 @@ org.apache.maven.plugins maven-profiler-plugin - ${profiler.version} + ${maven-profiler-plugin.version} org.apache.maven.plugins maven-failsafe-plugin - ${failsafe.version} + ${maven-failsafe-plugin.version} @@ -53,10 +53,10 @@ - + - 3.1.2 - 1.7 - + 3.1.2 + 1.7 + \ No newline at end of file diff --git a/maven-modules/maven-builder-plugin/pom.xml b/maven-modules/maven-builder-plugin/pom.xml index f7d6a4e69b..338aafe85d 100644 --- a/maven-modules/maven-builder-plugin/pom.xml +++ b/maven-modules/maven-builder-plugin/pom.xml @@ -12,7 +12,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.2.0 + ${build-helper-maven-plugin.version} add-source @@ -32,6 +32,7 @@ + 3.2.0 1.8 1.8 UTF-8 diff --git a/maven-modules/maven-exec-plugin/pom.xml b/maven-modules/maven-exec-plugin/pom.xml index f0d4706455..1bac52ae2c 100644 --- a/maven-modules/maven-exec-plugin/pom.xml +++ b/maven-modules/maven-exec-plugin/pom.xml @@ -30,7 +30,7 @@ org.codehaus.mojo exec-maven-plugin - 3.0.0 + ${exec-maven-plugin.version} com.baeldung.main.Exec @@ -45,7 +45,8 @@ 1.2.6 - 3.8.1 + 3.11.0 + 3.1.0 1.8 diff --git a/maven-modules/maven-generate-war/pom.xml b/maven-modules/maven-generate-war/pom.xml index cf8952e72f..7de3f15298 100644 --- a/maven-modules/maven-generate-war/pom.xml +++ b/maven-modules/maven-generate-war/pom.xml @@ -43,7 +43,7 @@ maven-war-plugin - 3.3.1 + ${maven-war-plugin.version} @@ -72,7 +72,6 @@ 11 2.17.1 - 3.10.1 11 11 diff --git a/maven-modules/maven-integration-test/pom.xml b/maven-modules/maven-integration-test/pom.xml index 4483bb2d55..ae2eddb40f 100644 --- a/maven-modules/maven-integration-test/pom.xml +++ b/maven-modules/maven-integration-test/pom.xml @@ -76,7 +76,7 @@ maven-compiler-plugin - ${maven.compiler.version} + ${maven-compiler-plugin.version} ${java.version} ${java.version} @@ -103,7 +103,7 @@ maven-failsafe-plugin - ${maven.failsafe.version} + ${maven-failsafe-plugin.version} @@ -267,10 +267,10 @@ - 3.3.2 + 3.4.0 3.0.2 - 3.8.0 - 2.22.0 + 3.11.0 + 3.1.2 1.1 3.0.0 3.0.0 diff --git a/maven-modules/maven-multi-source/pom.xml b/maven-modules/maven-multi-source/pom.xml index d9863b31a9..96b390d75a 100644 --- a/maven-modules/maven-multi-source/pom.xml +++ b/maven-modules/maven-multi-source/pom.xml @@ -18,7 +18,7 @@ maven-compiler-plugin - ${maven.compiler.version} + ${maven-compiler-plugin.version} ${java.version} ${java.version} @@ -30,7 +30,7 @@ org.codehaus.mojo build-helper-maven-plugin - ${maven.build.helper.version} + ${build-helper-maven-plugin.version} generate-sources @@ -80,11 +80,9 @@ 3.0.2 - 3.8.0 - 2.22.0 1.1 3.0.0 - 3.0.0 + 3.0.0 9.4.11.v20180605 2.27 diff --git a/maven-modules/maven-parent-pom-resolution/pom.xml b/maven-modules/maven-parent-pom-resolution/pom.xml index 8506f1c5fa..288bf5f780 100644 --- a/maven-modules/maven-parent-pom-resolution/pom.xml +++ b/maven-modules/maven-parent-pom-resolution/pom.xml @@ -20,10 +20,13 @@ org.apache.maven.plugins maven-dependency-plugin - 3.2.0 + ${maven-dependency-plugin.version} + + 3.2.0 + \ No newline at end of file diff --git a/maven-modules/maven-simple/parent-project/webapp/pom.xml b/maven-modules/maven-simple/parent-project/webapp/pom.xml index ce964c222f..d0596a4503 100644 --- a/maven-modules/maven-simple/parent-project/webapp/pom.xml +++ b/maven-modules/maven-simple/parent-project/webapp/pom.xml @@ -26,8 +26,4 @@ - - 3.3.2 - - \ No newline at end of file diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml index e139a4b921..913421d496 100644 --- a/maven-modules/pom.xml +++ b/maven-modules/pom.xml @@ -19,6 +19,7 @@ compiler-plugin-java-9 dependency-exclusion host-maven-repo-example + jacoco-coverage-aggregation maven-archetype maven-build-optimization maven-builder-plugin @@ -46,6 +47,9 @@ version-collision version-overriding-plugins versions-maven-plugin + maven-pom-types + multimodulemavenproject + resume-from diff --git a/maven-modules/resume-from/business/pom.xml b/maven-modules/resume-from/business/pom.xml index 189be12a0f..6c5db6cbe1 100644 --- a/maven-modules/resume-from/business/pom.xml +++ b/maven-modules/resume-from/business/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 business 1.0-SNAPSHOT @@ -24,5 +24,4 @@ 11 - \ No newline at end of file diff --git a/maven-modules/resume-from/pom.xml b/maven-modules/resume-from/pom.xml index 972395cbf2..d653d00d3b 100644 --- a/maven-modules/resume-from/pom.xml +++ b/maven-modules/resume-from/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung resume-from diff --git a/maven-modules/version-overriding-plugins/pom.xml b/maven-modules/version-overriding-plugins/pom.xml index b98a444bd4..d38541d797 100644 --- a/maven-modules/version-overriding-plugins/pom.xml +++ b/maven-modules/version-overriding-plugins/pom.xml @@ -51,7 +51,7 @@ - 3.8.0 + 3.11.0 \ No newline at end of file diff --git a/messaging-modules/pom.xml b/messaging-modules/pom.xml index 6fd14f7c64..27524637ab 100644 --- a/messaging-modules/pom.xml +++ b/messaging-modules/pom.xml @@ -22,7 +22,7 @@ spring-amqp spring-apache-camel spring-jms - postgres-notify + postgres-notify \ No newline at end of file diff --git a/messaging-modules/postgres-notify/pom.xml b/messaging-modules/postgres-notify/pom.xml index 174d66b7f5..876519f40c 100644 --- a/messaging-modules/postgres-notify/pom.xml +++ b/messaging-modules/postgres-notify/pom.xml @@ -42,37 +42,36 @@ lombok true - + + + 1.8 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + - - 1.8 - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - - - instance1 - - - - org.springframework.boot - spring-boot-maven-plugin - - -Dserver.port=8081 - - - - - - - + + + instance1 + + + + org.springframework.boot + spring-boot-maven-plugin + + -Dserver.port=8081 + + + + + + + \ No newline at end of file diff --git a/microservices-modules/pom.xml b/microservices-modules/pom.xml index 2111390481..a9cd8d2cd9 100644 --- a/microservices-modules/pom.xml +++ b/microservices-modules/pom.xml @@ -22,8 +22,4 @@ rest-express - - 3.3.2 - - \ No newline at end of file diff --git a/microservices-modules/rest-express/pom.xml b/microservices-modules/rest-express/pom.xml index da697fdc56..182d14cfbf 100644 --- a/microservices-modules/rest-express/pom.xml +++ b/microservices-modules/rest-express/pom.xml @@ -144,7 +144,6 @@ 1.0 0.4.8 4.11 - 1.2.1 2.4.1 2.0 diff --git a/muleesb/pom.xml b/muleesb/pom.xml index a2204c15b7..8cdd3400e9 100644 --- a/muleesb/pom.xml +++ b/muleesb/pom.xml @@ -217,6 +217,8 @@ 1.3.6 1.10 2.2.1 + 3.3.2 + 2.5.2 \ No newline at end of file diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AbstractFactoryRunner.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AbstractFactoryRunner.java new file mode 100644 index 0000000000..59aa3f8040 --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AbstractFactoryRunner.java @@ -0,0 +1,8 @@ +package com.baeldung.creational.abstractfactory2; + +public class AbstractFactoryRunner { + + public static void main(String[] args) { + new AnimalAbstractFactory().createAnimal(AnimalType.LAND); + } +} diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/Animal.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/Animal.java new file mode 100644 index 0000000000..97b444c3e0 --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/Animal.java @@ -0,0 +1,13 @@ +package com.baeldung.creational.abstractfactory2; + +public abstract class Animal { + AnimalType type; + AnimalEra era; + String name; + Animal(AnimalType type, AnimalEra era, String name) { + this.type = type; + this.era = era; + this.name = name; + } + abstract void create(); +} diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AnimalAbstractFactory.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AnimalAbstractFactory.java new file mode 100644 index 0000000000..6d09e1661a --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AnimalAbstractFactory.java @@ -0,0 +1,22 @@ +package com.baeldung.creational.abstractfactory2; + +public class AnimalAbstractFactory { + + Animal animal; + Animal createAnimal(AnimalType type) { + AnimalEra era = getFromConfiguration(); + switch (era) { + case MESOZOIC: + animal = new MesozoicAnimalFactory().createAnimal(type); + break; + case CENOZOIC: + animal = new CenozoicAnimalFactory().createAnimal(type); + break; + } + return null; + } + + AnimalEra getFromConfiguration() { + return AnimalEra.MESOZOIC; + } +} diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AnimalEra.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AnimalEra.java new file mode 100644 index 0000000000..0ee4deda65 --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AnimalEra.java @@ -0,0 +1,6 @@ +package com.baeldung.creational.abstractfactory2; + +public enum AnimalEra { + MESOZOIC, + CENOZOIC +} \ No newline at end of file diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AnimalType.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AnimalType.java new file mode 100644 index 0000000000..be2f5e2361 --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/AnimalType.java @@ -0,0 +1,6 @@ +package com.baeldung.creational.abstractfactory2; + +public enum AnimalType { + LAND, + SKY +} \ No newline at end of file diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/CenozoicAnimalFactory.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/CenozoicAnimalFactory.java new file mode 100644 index 0000000000..cf28acdd25 --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/CenozoicAnimalFactory.java @@ -0,0 +1,23 @@ +package com.baeldung.creational.abstractfactory2; + +public class CenozoicAnimalFactory implements EraAnimalFactory{ + @Override + public LandAnimal makeLandAnimal() { + return new LandAnimal(AnimalEra.CENOZOIC, "Mammoth"); + } + + @Override + public SkyAnimal makeSkyAnimal() { + return new SkyAnimal(AnimalEra.CENOZOIC, "Terror bird"); + } + + Animal createAnimal(AnimalType type) { + switch (type) { + case LAND: + return makeLandAnimal(); + case SKY: + return makeSkyAnimal(); + } + return null; + } +} diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/EraAnimalFactory.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/EraAnimalFactory.java new file mode 100644 index 0000000000..30c69b4598 --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/EraAnimalFactory.java @@ -0,0 +1,7 @@ +package com.baeldung.creational.abstractfactory2; + +public interface EraAnimalFactory { + + LandAnimal makeLandAnimal(); + SkyAnimal makeSkyAnimal(); +} diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/LandAnimal.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/LandAnimal.java new file mode 100644 index 0000000000..963cd96969 --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/LandAnimal.java @@ -0,0 +1,13 @@ +package com.baeldung.creational.abstractfactory2; + +public class LandAnimal extends Animal{ + + LandAnimal(AnimalEra era, String name) { + super(AnimalType.LAND, era, name); + create(); + } + @Override + void create() { + System.out.println("Creating a " + type + " animal: " + name); + } +} diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/MesozoicAnimalFactory.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/MesozoicAnimalFactory.java new file mode 100644 index 0000000000..dd56669242 --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/MesozoicAnimalFactory.java @@ -0,0 +1,24 @@ +package com.baeldung.creational.abstractfactory2; + +public class MesozoicAnimalFactory implements EraAnimalFactory{ + @Override + public LandAnimal makeLandAnimal() { + return new LandAnimal(AnimalEra.MESOZOIC, "Tyrannosaurus Rex"); + } + + @Override + public SkyAnimal makeSkyAnimal() { + return new SkyAnimal(AnimalEra.MESOZOIC, "Pterodactylus"); + } + + Animal createAnimal(AnimalType type) { + switch (type) { + case LAND: + return makeLandAnimal(); + case SKY: + return makeSkyAnimal(); + } + return null; + } + +} diff --git a/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/SkyAnimal.java b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/SkyAnimal.java new file mode 100644 index 0000000000..ce27236d7c --- /dev/null +++ b/patterns-modules/design-patterns-creational/src/main/java/com/baeldung/creational/abstractfactory2/SkyAnimal.java @@ -0,0 +1,13 @@ +package com.baeldung.creational.abstractfactory2; + +public class SkyAnimal extends Animal{ + + SkyAnimal(AnimalEra era, String name) { + super(AnimalType.SKY, era, name); + create(); + } + @Override + void create() { + System.out.println("Creating a " + type + " animal: " + name); + } +} diff --git a/persistence-modules/core-java-persistence-2/README.md b/persistence-modules/core-java-persistence-2/README.md index afabf9ecb3..f9da4947a7 100644 --- a/persistence-modules/core-java-persistence-2/README.md +++ b/persistence-modules/core-java-persistence-2/README.md @@ -9,3 +9,4 @@ - [Get the Number of Rows in a ResultSet](https://www.baeldung.com/java-resultset-number-of-rows) - [Converting a JDBC ResultSet to JSON in Java](https://www.baeldung.com/java-jdbc-convert-resultset-to-json) - [Guide to MicroStream](https://www.baeldung.com/microstream-intro) +- [Executing SQL Script File in Java](https://www.baeldung.com/java-run-sql-script) diff --git a/persistence-modules/hibernate-libraries/pom.xml b/persistence-modules/hibernate-libraries/pom.xml index 031d55c17d..3f4da28296 100644 --- a/persistence-modules/hibernate-libraries/pom.xml +++ b/persistence-modules/hibernate-libraries/pom.xml @@ -166,7 +166,6 @@ 3.27.0-GA 2.3.1 2.0.0 - 3.0.2 3.8.1 3.8.1 8.0.19 diff --git a/persistence-modules/java-cassandra/pom.xml b/persistence-modules/java-cassandra/pom.xml index 0dd148e528..6479ae3312 100644 --- a/persistence-modules/java-cassandra/pom.xml +++ b/persistence-modules/java-cassandra/pom.xml @@ -13,26 +13,11 @@ - com.datastax.cassandra cassandra-driver-core ${cassandra-driver-core.version} - true - - - com.google.guava - guava - - - - - org.cassandraunit - cassandra-unit - ${cassandra-unit.version} - - com.datastax.oss java-driver-core @@ -48,32 +33,28 @@ netty-transport ${netty-transport-version} + + org.testcontainers + cassandra + ${cassandra-testcontainer.version} + test + - - - integration-lite-first - - - - - org.apache.maven.plugins - maven-surefire-plugin - - 1 - true - - - - - - + + + + org.apache.maven.plugins + maven-compiler-plugin + + + 3.1.2 - 3.1.1.0 4.1.0 + 1.15.3 4.1.71.Final diff --git a/persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/batch/CassandraConnector.java b/persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/batch/CassandraConnector.java index 02d63c62f6..7c9a00f088 100644 --- a/persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/batch/CassandraConnector.java +++ b/persistence-modules/java-cassandra/src/main/java/com/baeldung/cassandra/batch/CassandraConnector.java @@ -5,8 +5,6 @@ import com.datastax.oss.driver.api.core.CqlSessionBuilder; import java.net.InetSocketAddress; -import org.apache.commons.lang3.StringUtils; - public class CassandraConnector { private CqlSession session; @@ -14,11 +12,11 @@ public class CassandraConnector { public void connect(final String node, final Integer port, final String dataCenter) { CqlSessionBuilder builder = CqlSession.builder(); builder.addContactPoint(new InetSocketAddress(node, port)); - if (StringUtils.isNotBlank(dataCenter)) { + if (dataCenter != null && !dataCenter.isEmpty()) { builder.withLocalDatacenter(dataCenter); } - session = builder.build(); + session = builder.build(); } public CqlSession getSession() { diff --git a/persistence-modules/java-cassandra/src/main/java/com/baeldung/datastax/cassandra/Application.java b/persistence-modules/java-cassandra/src/main/java/com/baeldung/datastax/cassandra/Application.java index f067ee8b73..57f5d8cf0e 100644 --- a/persistence-modules/java-cassandra/src/main/java/com/baeldung/datastax/cassandra/Application.java +++ b/persistence-modules/java-cassandra/src/main/java/com/baeldung/datastax/cassandra/Application.java @@ -1,5 +1,6 @@ package com.baeldung.datastax.cassandra; +import com.baeldung.cassandra.batch.repository.ProductRepository; import com.baeldung.datastax.cassandra.domain.Video; import com.baeldung.datastax.cassandra.repository.KeyspaceRepository; import com.baeldung.datastax.cassandra.repository.VideoRepository; @@ -30,9 +31,11 @@ public class Application { keyspaceRepository.useKeyspace("testKeyspace"); VideoRepository videoRepository = new VideoRepository(session); + ProductRepository productRepository = new ProductRepository(session); videoRepository.createTable(); + productRepository.createProductTableByName("testKeyspace"); videoRepository.insertVideo(new Video("Video Title 1", Instant.now())); videoRepository.insertVideo(new Video("Video Title 2", Instant.now().minus(1, ChronoUnit.DAYS))); diff --git a/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/batch/epository/ProductRepositoryIntegrationTest.java b/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/batch/epository/ProductRepositoryLiveTest.java similarity index 80% rename from persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/batch/epository/ProductRepositoryIntegrationTest.java rename to persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/batch/epository/ProductRepositoryLiveTest.java index 55dc3dad9f..9e6839b2b4 100644 --- a/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/batch/epository/ProductRepositoryIntegrationTest.java +++ b/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/batch/epository/ProductRepositoryLiveTest.java @@ -1,24 +1,5 @@ package com.baeldung.cassandra.batch.epository; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.cassandra.exceptions.ConfigurationException; -import org.apache.thrift.transport.TTransportException; -import org.cassandraunit.utils.EmbeddedCassandraServerHelper; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import com.baeldung.cassandra.batch.CassandraConnector; import com.baeldung.cassandra.batch.domain.Product; import com.baeldung.cassandra.batch.repository.KeyspaceRepository; import com.baeldung.cassandra.batch.repository.ProductRepository; @@ -26,10 +7,25 @@ import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.CqlSession; import com.datastax.oss.driver.api.core.cql.ColumnDefinition; import com.datastax.oss.driver.api.core.cql.ResultSet; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.testcontainers.containers.CassandraContainer; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class ProductRepositoryIntegrationTest { - +public class ProductRepositoryLiveTest { + @Rule + public CassandraContainer cassandra = new CassandraContainer<>("cassandra:3.11.2"); private KeyspaceRepository schemaRepository; private ProductRepository productRepository; @@ -39,21 +35,20 @@ public class ProductRepositoryIntegrationTest { private final String KEYSPACE_NAME = "testBaeldungKeyspace"; private final String PRODUCT = "product"; - @BeforeClass - public static void init() throws ConfigurationException, TTransportException, IOException, InterruptedException { - // Start an embedded Cassandra Server - EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L); - } - @Before public void connect() { - CassandraConnector client = new CassandraConnector(); - client.connect("127.0.0.1", 9142,"datacenter1"); - session = client.getSession(); - schemaRepository = new KeyspaceRepository(client.getSession()); + cassandra.start(); + + this.session = CqlSession + .builder() + .addContactPoint(new InetSocketAddress(cassandra.getHost(),cassandra.getFirstMappedPort())) + .withLocalDatacenter("datacenter1") + .build(); + + schemaRepository = new KeyspaceRepository(this.session); schemaRepository.createKeyspace(KEYSPACE_NAME, 1); schemaRepository.useKeyspace(KEYSPACE_NAME); - productRepository = new ProductRepository(client.getSession()); + productRepository = new ProductRepository(this.session); } @Test @@ -114,14 +109,7 @@ public class ProductRepositoryIntegrationTest { assertEquals(productList.get(0).getPrice(), 12f,0f); assertEquals(productList.get(1).getPrice(), 12f,0f); } - - - @AfterClass - public static void cleanup() { - EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); - } - private Product getTestProduct() { Product product = new Product(); product.setProductName("Banana"); diff --git a/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java b/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryLiveTest.java similarity index 82% rename from persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java rename to persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryLiveTest.java index 62eae94c7c..2fa39113c6 100644 --- a/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryIntegrationTest.java +++ b/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/BookRepositoryLiveTest.java @@ -1,31 +1,24 @@ package com.baeldung.cassandra.java.client.repository; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.cassandra.exceptions.ConfigurationException; -import org.apache.thrift.transport.TTransportException; -import org.cassandraunit.utils.EmbeddedCassandraServerHelper; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.baeldung.cassandra.java.client.CassandraConnector; import com.baeldung.cassandra.java.client.domain.Book; +import com.datastax.driver.core.Cluster; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.Session; import com.datastax.driver.core.exceptions.InvalidQueryException; import com.datastax.driver.core.utils.UUIDs; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.testcontainers.containers.CassandraContainer; -public class BookRepositoryIntegrationTest { +import java.util.List; +import java.util.stream.Collectors; - private KeyspaceRepository schemaRepository; +import static org.junit.Assert.*; + +public class BookRepositoryLiveTest { + @Rule + public CassandraContainer cassandra = new CassandraContainer<>("cassandra:3.11.2"); private BookRepository bookRepository; @@ -35,18 +28,18 @@ public class BookRepositoryIntegrationTest { final String BOOKS = "books"; final String BOOKS_BY_TITLE = "booksByTitle"; - @BeforeClass - public static void init() throws ConfigurationException, TTransportException, IOException, InterruptedException { - // Start an embedded Cassandra Server - EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L); - } - @Before public void connect() { - CassandraConnector client = new CassandraConnector(); - client.connect("127.0.0.1", 9142); - this.session = client.getSession(); - schemaRepository = new KeyspaceRepository(session); + cassandra.start(); + + this.session = Cluster + .builder() + .addContactPoint(cassandra.getHost()) + .withPort(cassandra.getMappedPort(CassandraContainer.CQL_PORT)) + .build() + .newSession(); + + KeyspaceRepository schemaRepository = new KeyspaceRepository(session); schemaRepository.createKeyspace(KEYSPACE_NAME, "SimpleStrategy", 1); schemaRepository.useKeyspace(KEYSPACE_NAME); bookRepository = new BookRepository(session); @@ -166,9 +159,4 @@ public class BookRepositoryIntegrationTest { session.execute("SELECT * FROM " + KEYSPACE_NAME + "." + BOOKS + ";"); } - - @AfterClass - public static void cleanup() { - EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); - } } diff --git a/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java b/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryLiveTest.java similarity index 61% rename from persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java rename to persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryLiveTest.java index 9df46b3176..3a8411ddce 100644 --- a/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryIntegrationTest.java +++ b/persistence-modules/java-cassandra/src/test/java/com/baeldung/cassandra/java/client/repository/KeyspaceRepositoryLiveTest.java @@ -1,45 +1,38 @@ package com.baeldung.cassandra.java.client.repository; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertEquals; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Session; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import org.testcontainers.containers.CassandraContainer; -import java.io.IOException; import java.util.List; import java.util.stream.Collectors; -import org.apache.cassandra.exceptions.ConfigurationException; -import org.apache.thrift.transport.TTransportException; -import org.cassandraunit.utils.EmbeddedCassandraServerHelper; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runners.MethodSorters; - -import com.baeldung.cassandra.java.client.CassandraConnector; -import com.datastax.driver.core.ResultSet; -import com.datastax.driver.core.Session; +import static org.junit.Assert.*; @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class KeyspaceRepositoryIntegrationTest { - +public class KeyspaceRepositoryLiveTest { + @Rule + public CassandraContainer cassandra = new CassandraContainer<>("cassandra:3.11.2"); private KeyspaceRepository schemaRepository; - private Session session; - @BeforeClass - public static void init() throws ConfigurationException, TTransportException, IOException, InterruptedException { - // Start an embedded Cassandra Server - EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L); - } - @Before public void connect() { - CassandraConnector client = new CassandraConnector(); - client.connect("127.0.0.1", 9142); - this.session = client.getSession(); + cassandra.start(); + + this.session = Cluster + .builder() + .addContactPoint(cassandra.getHost()) + .withPort(cassandra.getMappedPort(CassandraContainer.CQL_PORT)) + .build() + .newSession(); + schemaRepository = new KeyspaceRepository(session); } @@ -62,16 +55,11 @@ public class KeyspaceRepositoryIntegrationTest { public void whenDeletingAKeyspace_thenDoesNotExist() { String keyspaceName = "testBaeldungKeyspace"; - // schemaRepository.createKeyspace(keyspaceName, "SimpleStrategy", 1); + schemaRepository.createKeyspace(keyspaceName, "SimpleStrategy", 1); schemaRepository.deleteKeyspace(keyspaceName); ResultSet result = session.execute("SELECT * FROM system_schema.keyspaces;"); boolean isKeyspaceCreated = result.all().stream().anyMatch(r -> r.getString(0).equals(keyspaceName.toLowerCase())); assertFalse(isKeyspaceCreated); } - - @AfterClass - public static void cleanup() { - EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); - } } diff --git a/persistence-modules/java-jpa-2/pom.xml b/persistence-modules/java-jpa-2/pom.xml index 34e7f9f349..77d9590d65 100644 --- a/persistence-modules/java-jpa-2/pom.xml +++ b/persistence-modules/java-jpa-2/pom.xml @@ -156,7 +156,6 @@ 4.0.1 2.2 - 3.5.1 3.3.3 3.0.0 5.0.0 diff --git a/persistence-modules/java-jpa-3/pom.xml b/persistence-modules/java-jpa-3/pom.xml index 20143af9f0..0237da7ece 100644 --- a/persistence-modules/java-jpa-3/pom.xml +++ b/persistence-modules/java-jpa-3/pom.xml @@ -88,7 +88,6 @@ 2.7.4 8.0.21 2.2 - 3.5.1 3.3.3 3.0.0 2.1.214 diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index 24a55491d3..ec02b0f37c 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -35,6 +35,7 @@ hibernate-queries hibernate-enterprise influxdb + java-cassandra java-cockroachdb java-jdbi java-jpa @@ -85,7 +86,7 @@ spring-data-jpa-query-3 spring-data-jpa-repo spring-data-jpa-repo-2 - spring-data-jpa-repo-4 + spring-data-jpa-repo-4 spring-data-jdbc spring-data-keyvalue spring-data-mongodb @@ -113,6 +114,10 @@ java-mongodb questdb neo4j + rethinkdb + scylladb + spring-data-cassandra-2 + spring-data-jpa-repo-3 diff --git a/persistence-modules/spring-boot-persistence-4/pom.xml b/persistence-modules/spring-boot-persistence-4/pom.xml index 99c39e205d..7a6c2d2b17 100644 --- a/persistence-modules/spring-boot-persistence-4/pom.xml +++ b/persistence-modules/spring-boot-persistence-4/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.baeldung.boot.persistence spring-boot-persistence-4 diff --git a/persistence-modules/spring-data-cassandra-2/pom.xml b/persistence-modules/spring-data-cassandra-2/pom.xml index 740c04d2a0..01b5ce5ed6 100644 --- a/persistence-modules/spring-data-cassandra-2/pom.xml +++ b/persistence-modules/spring-data-cassandra-2/pom.xml @@ -65,6 +65,18 @@ java-driver-mapper-runtime 4.15.0 + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test + @@ -88,10 +100,10 @@ 11 - 3.1.11 - 1.15.3 + 3.4.15 + 1.19.0 1.1.0 - 5.6.2 + 5.9.3 \ No newline at end of file diff --git a/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/CassandraApplication.java b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/CassandraApplication.java new file mode 100644 index 0000000000..ecc50cbf40 --- /dev/null +++ b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/CassandraApplication.java @@ -0,0 +1,12 @@ +package org.baeldung.cassandra.inquery; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CassandraApplication { + + public static void main(String[] args) { + SpringApplication.run(CassandraApplication.class, args); + } +} diff --git a/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/model/Product.java b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/model/Product.java new file mode 100644 index 0000000000..c9007e8405 --- /dev/null +++ b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/model/Product.java @@ -0,0 +1,49 @@ +package org.baeldung.cassandra.inquery.model; + +import org.springframework.data.cassandra.core.cql.PrimaryKeyType; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn; +import org.springframework.data.cassandra.core.mapping.Table; + +import java.util.Objects; +import java.util.UUID; + +@Table +public class Product { + + @PrimaryKeyColumn(name = "product_id", ordinal = 0, type = PrimaryKeyType.PARTITIONED) + private UUID productId; + + @PrimaryKeyColumn(name = "product_name", ordinal = 1, type = PrimaryKeyType.CLUSTERED) + private String productName; + + @Column("description") + private String description; + + @Column("price") + private double price; + + public Product(UUID productId, String productName, String description, double price) { + this.productId = productId; + this.productName = productName; + this.description = description; + this.price = price; + } + + public String getProductName() { + return productName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Product product = (Product) o; + return productId.equals(product.productId) && productName.equals(product.productName); + } + + @Override + public int hashCode() { + return Objects.hash(productId, productName); + } +} diff --git a/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/repository/ProductRepository.java b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/repository/ProductRepository.java new file mode 100644 index 0000000000..176ca4d786 --- /dev/null +++ b/persistence-modules/spring-data-cassandra-2/src/main/java/org/baeldung/cassandra/inquery/repository/ProductRepository.java @@ -0,0 +1,20 @@ +package org.baeldung.cassandra.inquery.repository; + +import org.baeldung.cassandra.inquery.model.Product; +import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.data.cassandra.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.UUID; + +@Repository +public interface ProductRepository extends CassandraRepository { + + @Query("select * from product where product_id in :productIds") + List findByProductIds(@Param("productIds") List productIds); + + @Query("select * from product where product_id = :productId and product_name in :productNames") + List findByProductIdAndNames(@Param("productId") UUID productId, @Param("productNames") List productNames); +} diff --git a/persistence-modules/spring-data-cassandra-2/src/test/java/org/baeldung/cassandra/inquery/ProductRepositoryNestedLiveTest.java b/persistence-modules/spring-data-cassandra-2/src/test/java/org/baeldung/cassandra/inquery/ProductRepositoryNestedLiveTest.java new file mode 100644 index 0000000000..3d2433814e --- /dev/null +++ b/persistence-modules/spring-data-cassandra-2/src/test/java/org/baeldung/cassandra/inquery/ProductRepositoryNestedLiveTest.java @@ -0,0 +1,115 @@ +package org.baeldung.cassandra.inquery; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.utils.UUIDs; +import org.baeldung.cassandra.inquery.model.Product; +import org.baeldung.cassandra.inquery.repository.ProductRepository; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.testcontainers.containers.CassandraContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + + +@Testcontainers +@SpringBootTest +class ProductRepositoryIntegrationTest { + + private static final String KEYSPACE_NAME = "mynamespace"; + + @Container + private static final CassandraContainer cassandra = (CassandraContainer) new CassandraContainer("cassandra:3.11.2") + .withExposedPorts(9042); + + @BeforeAll + static void setupCassandraConnectionProperties() { + System.setProperty("spring.data.cassandra.keyspace-name", KEYSPACE_NAME); + System.setProperty("spring.data.cassandra.contact-points", cassandra.getHost()); + System.setProperty("spring.data.cassandra.port", String.valueOf(cassandra.getMappedPort(9042))); + createKeyspace(cassandra.getCluster()); + } + + static void createKeyspace(Cluster cluster) { + try (Session session = cluster.connect()) { + session.execute("CREATE KEYSPACE IF NOT EXISTS " + KEYSPACE_NAME + " WITH replication = \n" + + "{'class':'SimpleStrategy','replication_factor':'1'};"); + } + } + + @Nested + class ApplicationContextLiveTest { + @Test + void givenCassandraContainer_whenSpringContextIsBootstrapped_thenContainerIsRunningWithNoExceptions() { + assertThat(cassandra.isRunning()).isTrue(); + } + } + + @Nested + class ProductRepositoryLiveTest { + + @Autowired + private ProductRepository productRepository; + + @Test + void givenValidProductsIsFetched_whenFindByProductIdsIsCalled_thenProductIsReturned() { + UUID productId1 = UUIDs.timeBased(); + UUID productId2 = UUIDs.timeBased(); + UUID productId3 = UUIDs.timeBased(); + Product product1 = new Product(productId1, "Apple", "Apple v1", 12.5); + Product product2 = new Product(productId2, "Apple v2", "Apple v2", 15.5); + Product product3 = new Product(productId3, "Banana", "Banana v1", 5.5); + Product product4 = new Product(productId3, "Banana v2", "Banana v2", 15.5); + + productRepository.saveAll(List.of(product1, product2, product3, product4)); + + List existingProducts = productRepository.findByProductIds(List.of(productId1, productId2)); + assertEquals(2, existingProducts.size()); + assertTrue(existingProducts.contains(product1)); + assertTrue(existingProducts.contains(product2)); + } + + @Test + void givenExistingProducts_whenFindByIdAndNamesIsCalled_thenProductIsReturned() { + UUID productId1 = UUIDs.timeBased(); + UUID productId2 = UUIDs.timeBased(); + Product product1 = new Product(productId1, "Apple", "Apple v1", 12.5); + Product product2 = new Product(productId1, "Apple v2", "Apple v2", 15.5); + Product product3 = new Product(productId2, "Banana", "Banana v1", 5.5); + Product product4 = new Product(productId2, "Banana v2", "Banana v2", 15.5); + + productRepository.saveAll(List.of(product1, product2, product3, product4)); + + List existingProducts = productRepository.findByProductIdAndNames(productId1, + List.of(product1.getProductName(), product2.getProductName())); + assertEquals(2, existingProducts.size()); + assertTrue(existingProducts.contains(product1)); + assertTrue(existingProducts.contains(product2)); + } + + @Test + void givenNonExistingProductName_whenFindByIdAndNamesIsCalled_thenProductIsReturned() { + UUID productId1 = UUIDs.timeBased(); + UUID productId2 = UUIDs.timeBased(); + Product product1 = new Product(productId1, "Apple", "Apple v1", 12.5); + Product product2 = new Product(productId1, "Apple v2", "Apple v2", 15.5); + Product product3 = new Product(productId2, "Banana", "Banana v1", 5.5); + Product product4 = new Product(productId2, "Banana v2", "Banana v2", 15.5); + + productRepository.saveAll(List.of(product1, product2, product4)); + + List existingProducts = productRepository.findByProductIdAndNames(productId1, + List.of(product3.getProductName())); + assertEquals(0, existingProducts.size()); + } + } +} diff --git a/persistence-modules/spring-data-elasticsearch/pom.xml b/persistence-modules/spring-data-elasticsearch/pom.xml index 8e5e8ab7c7..a353f60ad2 100644 --- a/persistence-modules/spring-data-elasticsearch/pom.xml +++ b/persistence-modules/spring-data-elasticsearch/pom.xml @@ -8,77 +8,56 @@ com.baeldung - parent-spring-5 + parent-boot-3 0.0.1-SNAPSHOT - ../../parent-spring-5 + ../../parent-boot-3 - - org.springframework - spring-web - ${spring.version} - org.springframework.data spring-data-elasticsearch ${spring-data-elasticsearch.version} - - org.elasticsearch - elasticsearch - ${elasticsearch.version} - - - com.alibaba - fastjson - ${fastjson.version} - + + + + + + + + + + + + org.elasticsearch.client elasticsearch-rest-high-level-client 7.17.11 - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - org.projectlombok lombok 1.18.28 - org.locationtech.spatial4j - spatial4j - ${spatial4j.version} - - - org.locationtech.jts - jts-core - ${jts.version} - - - xerces - xercesImpl - - - - - org.springframework - spring-test - ${spring.version} - test + org.springframework.boot + spring-boot-autoconfigure - + + + + org.springframework.boot + spring-boot-maven-plugin + + + 5.1.2 8.9.0 - 2.0.37 - 0.8 - 1.18.2 2.15.2 diff --git a/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/Application.java b/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/Application.java new file mode 100644 index 0000000000..c95b7cb5cb --- /dev/null +++ b/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/Application.java @@ -0,0 +1,12 @@ +package com.baeldung; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Location.java b/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Location.java new file mode 100644 index 0000000000..cdc8f8b255 --- /dev/null +++ b/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Location.java @@ -0,0 +1,16 @@ +package com.baeldung.elasticsearch; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class Location { + + private String name; + private List location; +} diff --git a/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Person.java b/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Person.java index d51d1a0576..9a01af84e7 100644 --- a/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Person.java +++ b/persistence-modules/spring-data-elasticsearch/src/main/java/com/baeldung/elasticsearch/Person.java @@ -12,8 +12,6 @@ import java.util.Date; public class Person { private int age; - private String fullName; - private Date dateOfBirth; } diff --git a/persistence-modules/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java b/persistence-modules/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java index 0d4117c75e..e0656db04e 100644 --- a/persistence-modules/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java +++ b/persistence-modules/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/ElasticSearchManualTest.java @@ -15,18 +15,18 @@ import co.elastic.clients.json.jackson.JacksonJsonpMapper; import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.rest_client.RestClientTransport; import lombok.extern.slf4j.Slf4j; + import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; -import org.junit.Before; -import org.junit.Test; -import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.io.IOException; import java.io.StringReader; import java.util.Date; import java.util.List; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * This Manual test requires: Elasticsearch instance running on localhost:9200. @@ -35,41 +35,35 @@ import static org.junit.Assert.assertEquals; * docker run -d --name elastic-test -p 9200:9200 -e "discovery.type=single-node" -e "xpack.security.enabled=false" docker.elastic.co/elasticsearch/elasticsearch:8.9.0 */ @Slf4j -@Disabled("Manual test") public class ElasticSearchManualTest { private ElasticsearchClient client = null; - @Before + @BeforeEach public void setUp() throws IOException { - RestClient restClient = RestClient - .builder(HttpHost.create("http://localhost:9200")) - .build(); + RestClient restClient = RestClient.builder(HttpHost.create("http://localhost:9200")) + .build(); ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper()); client = new ElasticsearchClient(transport); Person person1 = new Person(10, "John Doe", new Date()); Person person2 = new Person(25, "Janette Doe", new Date()); Person person3 = new Person(8, "Mark Doe", new Date()); - client.index(builder -> builder - .index("person") - .id(person1.getFullName()) - .document(person1)); - client.index(builder -> builder - .index("person") - .id(person2.getFullName()) - .document(person2)); - client.index(builder -> builder - .index("person") - .id(person3.getFullName()) - .document(person3)); + client.index(builder -> builder.index("person") + .id(person1.getFullName()) + .document(person1)); + client.index(builder -> builder.index("person") + .id(person2.getFullName()) + .document(person2)); + client.index(builder -> builder.index("person") + .id(person3.getFullName()) + .document(person3)); } @Test public void givenJsonDocument_whenJavaObject_thenIndexDocument() throws Exception { Person person = new Person(20, "Mark Doe", new Date(1471466076564L)); - IndexResponse response = client.index(i -> i - .index("person") - .id(person.getFullName()) - .document(person)); + IndexResponse response = client.index(i -> i.index("person") + .id(person.getFullName()) + .document(person)); log.info("Indexed with version: {}", response.version()); assertEquals(Result.Created, response.result()); @@ -81,10 +75,9 @@ public class ElasticSearchManualTest { public void givenJsonString_whenJavaObject_thenIndexDocument() throws Exception { String jsonString = "{\"age\":10,\"dateOfBirth\":1471466076564,\"fullName\":\"John Doe\"}"; StringReader stringReader = new StringReader(jsonString); - IndexResponse response = client.index(i -> i - .index("person") - .id("John Doe") - .withJson(stringReader)); + IndexResponse response = client.index(i -> i.index("person") + .id("John Doe") + .withJson(stringReader)); log.info("Indexed with version: {}", response.version()); assertEquals("person", response.index()); assertEquals("John Doe", response.id()); @@ -93,9 +86,8 @@ public class ElasticSearchManualTest { @Test public void givenDocumentId_whenJavaObject_thenDeleteDocument() throws Exception { String documentId = "Mark Doe"; - DeleteResponse response = client.delete(i -> i - .index("person") - .id(documentId)); + DeleteResponse response = client.delete(i -> i.index("person") + .id(documentId)); assertEquals(Result.Deleted, response.result()); assertEquals("Mark Doe", response.id()); } @@ -103,24 +95,23 @@ public class ElasticSearchManualTest { @Test public void givenSearchRequest_whenMatch_thenReturnAllResults() throws Exception { String searchText = "John"; - SearchResponse searchResponse = client.search(s -> s - .index("person") - .query(q -> q - .match(t -> t - .field("fullName") - .query(searchText))), Person.class); + SearchResponse searchResponse = client.search(s -> s.index("person") + .query(q -> q.match(t -> t.field("fullName") + .query(searchText))), Person.class); - List> hits = searchResponse.hits().hits(); + List> hits = searchResponse.hits() + .hits(); assertEquals(1, hits.size()); - assertEquals("John Doe", hits.get(0).source().getFullName()); + assertEquals("John Doe", hits.get(0) + .source() + .getFullName()); } @Test public void givenGetRequest_whenMatch_thenReturnAllResults() throws IOException { String documentId = "John Doe"; - GetResponse getResponse = client.get(s -> s - .index("person") - .id(documentId), Person.class); + GetResponse getResponse = client.get(s -> s.index("person") + .id(documentId), Person.class); Person source = getResponse.source(); assertEquals("John Doe", source.getFullName()); } @@ -128,47 +119,58 @@ public class ElasticSearchManualTest { @Test public void givenSearchRequest_whenMatchAndRange_thenReturnAllResults() throws Exception { String searchText = "John"; - SearchResponse searchResponse = client.search(s -> s - .index("person") - .query(q -> q - .match(t -> t - .field("fullName").query(searchText))) - .query(q -> q - .range(range -> range - .field("age").from("1").to("10"))), - Person.class); + SearchResponse searchResponse = client.search(s -> s.index("person") + .query(q -> q.match(t -> t.field("fullName") + .query(searchText))) + .query(q -> q.range(range -> range.field("age") + .from("1") + .to("10"))), Person.class); - List> hits = searchResponse.hits().hits(); + List> hits = searchResponse.hits() + .hits(); assertEquals(1, hits.size()); - assertEquals("John Doe", hits.get(0).source().getFullName()); + assertEquals("John Doe", hits.get(0) + .source() + .getFullName()); } - @Test public void givenMultipleQueries_thenReturnResults() throws Exception { - Query ageQuery = RangeQuery.of(r -> r.field("age").from("5").to("15"))._toQuery(); - SearchResponse response1 = client.search(s -> s.query(q -> q.bool(b -> b - .must(ageQuery))), Person.class); - response1.hits().hits().forEach(hit -> log.info("Response 1: {}", hit.source())); + Query ageQuery = RangeQuery.of(r -> r.field("age") + .from("5") + .to("15")) + ._toQuery(); + SearchResponse response1 = client.search(s -> s.query(q -> q.bool(b -> b.must(ageQuery))), Person.class); + response1.hits() + .hits() + .forEach(hit -> log.info("Response 1: {}", hit.source())); - Query fullNameQuery = MatchQuery.of(m -> m.field("fullName").query("John"))._toQuery(); - SearchResponse response2 = client.search(s -> s.query(q -> q.bool(b -> b - .must(fullNameQuery))), Person.class); - response2.hits().hits().forEach(hit -> log.info("Response 2: {}", hit.source())); - Query doeContainsQuery = SimpleQueryStringQuery.of(q -> q.query("*Doe"))._toQuery(); - SearchResponse response3 = client.search(s -> s.query(q -> q.bool(b -> b - .must(doeContainsQuery))), Person.class); - response3.hits().hits().forEach(hit -> log.info("Response 3: {}", hit.source())); + Query fullNameQuery = MatchQuery.of(m -> m.field("fullName") + .query("John")) + ._toQuery(); + SearchResponse response2 = client.search(s -> s.query(q -> q.bool(b -> b.must(fullNameQuery))), Person.class); + response2.hits() + .hits() + .forEach(hit -> log.info("Response 2: {}", hit.source())); + Query doeContainsQuery = SimpleQueryStringQuery.of(q -> q.query("*Doe")) + ._toQuery(); + SearchResponse response3 = client.search(s -> s.query(q -> q.bool(b -> b.must(doeContainsQuery))), Person.class); + response3.hits() + .hits() + .forEach(hit -> log.info("Response 3: {}", hit.source())); - Query simpleStringQuery = SimpleQueryStringQuery.of(q -> q.query("+John -Doe OR Janette"))._toQuery(); - SearchResponse response4 = client.search(s -> s.query(q -> q.bool(b -> b - .must(simpleStringQuery))), Person.class); - response4.hits().hits().forEach(hit -> log.info("Response 4: {}", hit.source())); + Query simpleStringQuery = SimpleQueryStringQuery.of(q -> q.query("+John -Doe OR Janette")) + ._toQuery(); + SearchResponse response4 = client.search(s -> s.query(q -> q.bool(b -> b.must(simpleStringQuery))), Person.class); + response4.hits() + .hits() + .forEach(hit -> log.info("Response 4: {}", hit.source())); - SearchResponse response5 = client.search(s -> s.query(q -> q.bool(b -> b - .must(ageQuery) - .must(fullNameQuery) - .must(simpleStringQuery))), Person.class); - response5.hits().hits().forEach(hit -> log.info("Response 5: {}", hit.source())); + SearchResponse response5 = client.search(s -> s.query(q -> q.bool(b -> b.must(ageQuery) + .must(fullNameQuery) + .must(simpleStringQuery))), Person.class); + response5.hits() + .hits() + .forEach(hit -> log.info("Response 5: {}", hit.source())); } } diff --git a/persistence-modules/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesManualTest.java b/persistence-modules/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesManualTest.java index abe10f4607..51e6ebca70 100644 --- a/persistence-modules/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesManualTest.java +++ b/persistence-modules/spring-data-elasticsearch/src/test/java/com/baeldung/elasticsearch/GeoQueriesManualTest.java @@ -1,199 +1,198 @@ package com.baeldung.elasticsearch; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import co.elastic.clients.elasticsearch.ElasticsearchClient; +import co.elastic.clients.elasticsearch._types.GeoShapeRelation; +import co.elastic.clients.elasticsearch.core.IndexResponse; +import co.elastic.clients.elasticsearch.core.SearchRequest; +import co.elastic.clients.elasticsearch.core.SearchResponse; +import co.elastic.clients.elasticsearch.core.search.Hit; +import co.elastic.clients.json.JsonData; +import co.elastic.clients.json.jackson.JacksonJsonpMapper; +import co.elastic.clients.transport.ElasticsearchTransport; +import co.elastic.clients.transport.rest_client.RestClientTransport; import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; +import java.io.StringReader; import java.util.List; -import java.util.stream.Collectors; -import com.baeldung.spring.data.es.config.Config; +import lombok.extern.slf4j.Slf4j; -import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; -import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.index.IndexResponse; -import org.elasticsearch.action.search.SearchRequest; -import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.RestHighLevelClient; -import org.elasticsearch.client.indices.CreateIndexRequest; -import org.elasticsearch.common.geo.GeoPoint; -import org.elasticsearch.common.geo.ShapeRelation; -import org.elasticsearch.common.unit.DistanceUnit; -import org.elasticsearch.index.query.GeoShapeQueryBuilder; -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.builder.SearchSourceBuilder; -import org.elasticsearch.xcontent.XContentType; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.locationtech.jts.geom.Coordinate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.apache.http.HttpHost; +import org.elasticsearch.client.RestClient; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; /** * This Manual test requires: Elasticsearch instance running on localhost:9200. - * - * The following docker command can be used: docker run -d --name es762 -p - * 9200:9200 -e "discovery.type=single-node" elasticsearch:7.6.2 + *

+ * The following docker command can be used: docker run -d --name elastic-test -p 9200:9200 -e + * "discovery.type=single-node" -e "xpack.security.enabled=false" + * docker.elastic.co/elasticsearch/elasticsearch:8.9.0 */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = Config.class) -public class GeoQueriesManualTest { + +@Slf4j +class GeoQueriesManualTest { private static final String WONDERS_OF_WORLD = "wonders-of-world"; - @Autowired - private RestHighLevelClient client; + private ElasticsearchClient client; - @Before + @BeforeEach public void setUp() throws Exception { - String jsonObject = "{\"properties\":{\"name\":{\"type\":\"text\",\"index\":false},\"region\":{\"type\":\"geo_shape\"},\"location\":{\"type\":\"geo_point\"}}}"; - - CreateIndexRequest req = new CreateIndexRequest(WONDERS_OF_WORLD); - req.mapping(jsonObject, XContentType.JSON); - + RestClient restClient = RestClient.builder(HttpHost.create("http://localhost:9200")) + .build(); + ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper()); + client = new ElasticsearchClient(transport); + log.info("Creating index: {}", WONDERS_OF_WORLD); client.indices() - .create(req, RequestOptions.DEFAULT); - } - -// @Test -// public void givenGeoShapeData_whenExecutedGeoShapeQuery_thenResultNonEmpty() throws IOException { -// String jsonObject = "{\"name\":\"Agra\",\"region\":{\"type\":\"envelope\",\"coordinates\":[[75,30.2],[80.1, 25]]}}"; -// IndexRequest indexRequest = new IndexRequest(WONDERS_OF_WORLD); -// indexRequest.source(jsonObject, XContentType.JSON); -// IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT); -// -// String tajMahalId = response.getId(); -// -// RefreshRequest refreshRequest = new RefreshRequest(WONDERS_OF_WORLD); -// client.indices() -// .refresh(refreshRequest, RequestOptions.DEFAULT); -// -// Coordinate topLeft = new Coordinate(74, 31.2); -// Coordinate bottomRight = new Coordinate(81.1, 24); -// -// GeoShapeQueryBuilder qb = QueryBuilders.geoShapeQuery("region", new EnvelopeBuilder(topLeft, bottomRight).buildGeometry()); -// qb.relation(ShapeRelation.INTERSECTS); -// -// SearchSourceBuilder source = new SearchSourceBuilder().query(qb); -// SearchRequest searchRequest = new SearchRequest(WONDERS_OF_WORLD); -// searchRequest.source(source); -// -// SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); -// -// List ids = Arrays.stream(searchResponse.getHits() -// .getHits()) -// .map(SearchHit::getId) -// .collect(Collectors.toList()); -// -// assertTrue(ids.contains(tajMahalId)); -// } - - @Test - public void givenGeoPointData_whenExecutedGeoBoundingBoxQuery_thenResultNonEmpty() throws Exception { - String jsonObject = "{\"name\":\"Pyramids of Giza\",\"location\":[31.131302,29.976480]}"; - - IndexRequest indexRequest = new IndexRequest(WONDERS_OF_WORLD); - indexRequest.source(jsonObject, XContentType.JSON); - IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT); - - String pyramidsOfGizaId = response.getId(); - - RefreshRequest refreshRequest = new RefreshRequest(WONDERS_OF_WORLD); - client.indices() - .refresh(refreshRequest, RequestOptions.DEFAULT); - - QueryBuilder qb = QueryBuilders.geoBoundingBoxQuery("location") - .setCorners(31, 30, 28, 32); - - SearchSourceBuilder source = new SearchSourceBuilder().query(qb); - SearchRequest searchRequest = new SearchRequest(WONDERS_OF_WORLD); - searchRequest.source(source); - - SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); - - List ids = Arrays.stream(searchResponse.getHits() - .getHits()) - .map(SearchHit::getId) - .collect(Collectors.toList()); - assertTrue(ids.contains(pyramidsOfGizaId)); + .create(builder -> builder.index(WONDERS_OF_WORLD) + .mappings(typeMapping -> typeMapping.properties("region", region -> region.geoShape(gs -> gs)) + .properties("location", location -> location.geoPoint(gp -> gp)))); } @Test - public void givenGeoPointData_whenExecutedGeoDistanceQuery_thenResultNonEmpty() throws Exception { - String jsonObject = "{\"name\":\"Lighthouse of alexandria\",\"location\":[31.131302,29.976480]}"; + void givenGeoShapeData_whenExecutedGeoShapeQuery_thenResultNonEmpty() throws IOException { + String jsonObject = """ + { + "name":"Agra", + "region":{ + "type":"envelope", + "coordinates":[[75,30.2],[80.1,25]] + } + } + """; + IndexResponse response = client.index(idx -> idx.index(WONDERS_OF_WORLD) + .withJson(new StringReader(jsonObject))); - IndexRequest indexRequest = new IndexRequest(WONDERS_OF_WORLD); - indexRequest.source(jsonObject, XContentType.JSON); - IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT); - - String lighthouseOfAlexandriaId = response.getId(); - - RefreshRequest refreshRequest = new RefreshRequest(WONDERS_OF_WORLD); + String tajMahalId = response.id(); client.indices() - .refresh(refreshRequest, RequestOptions.DEFAULT); + .refresh(); - QueryBuilder qb = QueryBuilders.geoDistanceQuery("location") - .point(29.976, 31.131) - .distance(10, DistanceUnit.MILES); + StringReader jsonData = new StringReader(""" + { + "type":"envelope", + "coordinates": [[74.0, 31.2], [81.1, 24.0 ] ] + } + """); - SearchSourceBuilder source = new SearchSourceBuilder().query(qb); - SearchRequest searchRequest = new SearchRequest(WONDERS_OF_WORLD); - searchRequest.source(source); - - SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); - - List ids = Arrays.stream(searchResponse.getHits() - .getHits()) - .map(SearchHit::getId) - .collect(Collectors.toList()); - assertTrue(ids.contains(lighthouseOfAlexandriaId)); + SearchRequest searchRequest = new SearchRequest.Builder().query(query -> query.bool(boolQuery -> boolQuery.filter(query1 -> query1.geoShape(geoShapeQuery -> geoShapeQuery.field("region") + .shape(geoShapeFieldQuery -> geoShapeFieldQuery.relation(GeoShapeRelation.Within) + .shape(JsonData.from(jsonData))))))) + .build(); + log.info("Search request: {}", searchRequest); + SearchResponse search = client.search(searchRequest, Object.class); + log.info("Search response: {}", search); + List searchResults = search.hits() + .hits() + .stream() + .map(Hit::id) + .toList(); + assertTrue(searchResults.contains(tajMahalId)); } @Test - public void givenGeoPointData_whenExecutedGeoPolygonQuery_thenResultNonEmpty() throws Exception { - String jsonObject = "{\"name\":\"The Great Rann of Kutch\",\"location\":[69.859741,23.733732]}"; + void givenGeoPointData_whenExecutedGeoBoundingBoxQuery_thenResultNonEmpty() throws Exception { + Location pyramidsOfGiza = new Location("Pyramids of Giza", List.of(31.1328, 29.9761)); + IndexResponse response = client.index(builder -> builder.index(WONDERS_OF_WORLD) + .document(pyramidsOfGiza)); - IndexRequest indexRequest = new IndexRequest(WONDERS_OF_WORLD); - indexRequest.source(jsonObject, XContentType.JSON); - IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT); + String pyramidsOfGizaId = response.id(); - String greatRannOfKutchid = response.getId(); - - RefreshRequest refreshRequest = new RefreshRequest(WONDERS_OF_WORLD); + log.info("Indexed pyramid of Giza: {}", pyramidsOfGizaId); client.indices() - .refresh(refreshRequest, RequestOptions.DEFAULT); + .refresh(); - List allPoints = new ArrayList(); - allPoints.add(new GeoPoint(22.733, 68.859)); - allPoints.add(new GeoPoint(24.733, 68.859)); - allPoints.add(new GeoPoint(23, 70.859)); - QueryBuilder qb = QueryBuilders.geoPolygonQuery("location", allPoints); - - SearchSourceBuilder source = new SearchSourceBuilder().query(qb); - SearchRequest searchRequest = new SearchRequest(WONDERS_OF_WORLD); - searchRequest.source(source); - - SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); - - List ids = Arrays.stream(searchResponse.getHits() - .getHits()) - .map(SearchHit::getId) - .collect(Collectors.toList()); - assertTrue(ids.contains(greatRannOfKutchid)); + SearchRequest.Builder builder = new SearchRequest.Builder().index(WONDERS_OF_WORLD); + builder.query(query -> query.geoBoundingBox(geoBoundingBoxQuery -> geoBoundingBoxQuery.field("location") + .boundingBox(geoBounds -> geoBounds.tlbr(bl4 -> bl4.topLeft(geoLocation -> geoLocation.coords(List.of(30.0, 31.0))) + .bottomRight(geoLocation -> geoLocation.coords(List.of(32.0, 28.0))))))); + SearchRequest build = builder.build(); + log.info("Search request: {}", build); + SearchResponse searchResponse = client.search(build, Location.class); + log.info("Search response: {}", searchResponse); + List returnedLocations = searchResponse.hits() + .hits() + .stream() + .map(Hit::source) + .toList(); + assertEquals(pyramidsOfGiza, returnedLocations.get(0)); } - @After + @Test + void givenGeoPointData_whenExecutedGeoDistanceQuery_thenResultNonEmpty() throws Exception { + String jsonObject = """ + { + "name":"Lighthouse of alexandria", + "location":{ "lat": 31.2139, "lon": 29.8856 } + } + """; + IndexResponse response = client.index(idx -> idx.index(WONDERS_OF_WORLD) + .withJson(new StringReader(jsonObject))); + + String lightHouseOfAlexandriaId = response.id(); + client.indices() + .refresh(); + SearchRequest searchRequest = new SearchRequest.Builder().index(WONDERS_OF_WORLD) + .query(query -> query.geoDistance(geoDistanceQuery -> geoDistanceQuery.field("location") + .distance("10 miles") + .location(geoLocation -> geoLocation.latlon(latLonGeoLocation -> latLonGeoLocation.lon(29.88) + .lat(31.21))))) + .build(); + log.info("Search request: {}", searchRequest); + SearchResponse search = client.search(searchRequest, Object.class); + log.info("Search response: {}", search); + List ids = search.hits() + .hits() + .stream() + .map(Hit::id) + .toList(); + assertTrue(ids.contains(lightHouseOfAlexandriaId)); + } + + @Test + void givenGeoPointData_whenExecutedGeoPolygonQuery_thenResultNonEmpty() throws Exception { + String jsonObject = """ + { + "name":"The Great Rann polygonPoints Kutch", + "location":{"lon": 69.859741, "lat": 23.733732} + } + """; + IndexResponse response = client.index(idx -> idx.index(WONDERS_OF_WORLD) + .withJson(new StringReader(jsonObject))); + String greatRannOfKutchid = response.id(); + client.indices() + .refresh(); + log.info("Indexed greatRannOfKutchid: {}", greatRannOfKutchid); + + JsonData jsonData = JsonData.fromJson(""" + { + "type":"polygon", + "coordinates":[[[68.859,22.733],[68.859,24.733],[70.859,23]]] + } + """); + + SearchRequest build = new SearchRequest.Builder().query(query -> query.bool(boolQuery -> boolQuery.filter(query1 -> query1.geoShape(geoShapeQuery -> geoShapeQuery.field("location") + .shape(geoShapeFieldQuery -> geoShapeFieldQuery.relation(GeoShapeRelation.Within) + .shape(jsonData)))))) + .build(); + log.info("Search request: {}", build); + SearchResponse search = client.search(build, Object.class); + log.info("Search response: {}", search); + List searchResults = search.hits() + .hits() + .stream() + .map(Hit::id) + .toList(); + assertTrue(searchResults.contains(greatRannOfKutchid)); + } + + @AfterEach public void destroy() throws Exception { - DeleteIndexRequest deleteIndex = new DeleteIndexRequest(WONDERS_OF_WORLD); client.indices() - .delete(deleteIndex, RequestOptions.DEFAULT); + .delete(builder -> builder.index(WONDERS_OF_WORLD)); } } diff --git a/persistence-modules/spring-data-jpa-repo-3/pom.xml b/persistence-modules/spring-data-jpa-repo-3/pom.xml index 207e753ecd..211e8a2d96 100644 --- a/persistence-modules/spring-data-jpa-repo-3/pom.xml +++ b/persistence-modules/spring-data-jpa-repo-3/pom.xml @@ -32,5 +32,8 @@ test + + com.baeldung.spring.data.jpa.naturalid.Application + diff --git a/persistence-modules/spring-data-shardingsphere/pom.xml b/persistence-modules/spring-data-shardingsphere/pom.xml index 1f37bed4cc..c1ca313038 100644 --- a/persistence-modules/spring-data-shardingsphere/pom.xml +++ b/persistence-modules/spring-data-shardingsphere/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-data-shardingsphere 1.0 diff --git a/persistence-modules/spring-data-yugabytedb/pom.xml b/persistence-modules/spring-data-yugabytedb/pom.xml index cf85988ac3..d7f7576cfe 100644 --- a/persistence-modules/spring-data-yugabytedb/pom.xml +++ b/persistence-modules/spring-data-yugabytedb/pom.xml @@ -1,7 +1,7 @@ + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-data-yugabytedb 1.0 diff --git a/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/ReplaceDeprecatedApplication.java b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/ReplaceDeprecatedApplication.java new file mode 100644 index 0000000000..f1f50dfbf9 --- /dev/null +++ b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/ReplaceDeprecatedApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.spring.jdbc.replacedeprecated; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan(basePackages = "com.baeldung.spring.jdbc.replacedeprecated") +public class ReplaceDeprecatedApplication { + + public static void main(String[] args) { + SpringApplication.run(ReplaceDeprecatedApplication.class, args); + } +} diff --git a/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/StudentDaoWithDeprecatedJdbcTemplateMethods.java b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/StudentDaoWithDeprecatedJdbcTemplateMethods.java new file mode 100644 index 0000000000..74e1ea6a0a --- /dev/null +++ b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/StudentDaoWithDeprecatedJdbcTemplateMethods.java @@ -0,0 +1,54 @@ +package com.baeldung.spring.jdbc.replacedeprecated; + +import com.baeldung.spring.jdbc.replacedeprecated.model.Student; +import com.baeldung.spring.jdbc.replacedeprecated.model.StudentResultExtractor; +import com.baeldung.spring.jdbc.replacedeprecated.model.StudentRowMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowCountCallbackHandler; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class StudentDaoWithDeprecatedJdbcTemplateMethods { + JdbcTemplate jdbcTemplate; + + @Autowired + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public List getStudentsOfAgeAndGender(Integer age, String gender) { + String sql = "select student_id, student_name, age, gender, grade, state from student where age= ? and gender = ?"; + Object[] args = {age, gender}; + return jdbcTemplate.query(sql, args, new StudentRowMapper()); + } + + public List getStudentsOfAgeGenderAndGrade(Integer age, String gender, Integer grade) { + String sql = "select student_id, student_name, age, gender, grade, state from student where age= ? and gender = ? and grade = ?"; + Object[] args = {age, gender, grade}; + return jdbcTemplate.query(sql, args, new StudentRowMapper()); + } + + public List getStudentsOfGradeAndState(Integer grade, String state) { + String sql = "select student_id, student_name, age, gender, grade, state from student where grade = ? and state = ?"; + Object[] args = {grade, state}; + return jdbcTemplate.query(sql, args, new StudentResultExtractor()); + } + + public Student getStudentOfStudentIDAndGrade(Integer studentID, Integer grade) { + String sql = "select student_id, student_name, age, gender, grade, state from student where student_id = ? and grade = ?"; + Object[] args = {studentID, grade}; + + return jdbcTemplate.queryForObject(sql, args, new StudentRowMapper()); + } + + public Integer getCountOfStudentsInAGradeFromAState(Integer grade, String state) { + String sql = "select student_id, student_name, age, gender, grade, state from student where grade = ? and state = ?"; + Object[] args = {grade, state}; + RowCountCallbackHandler countCallbackHandler = new RowCountCallbackHandler(); + jdbcTemplate.query(sql, args, countCallbackHandler); + return countCallbackHandler.getRowCount(); + } +} diff --git a/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/StudentDaoWithPreferredJdbcTemplateMethods.java b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/StudentDaoWithPreferredJdbcTemplateMethods.java new file mode 100644 index 0000000000..afe8a8f2bd --- /dev/null +++ b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/StudentDaoWithPreferredJdbcTemplateMethods.java @@ -0,0 +1,56 @@ +package com.baeldung.spring.jdbc.replacedeprecated; + +import com.baeldung.spring.jdbc.replacedeprecated.model.Student; +import com.baeldung.spring.jdbc.replacedeprecated.model.StudentResultExtractor; +import com.baeldung.spring.jdbc.replacedeprecated.model.StudentRowMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowCountCallbackHandler; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class StudentDaoWithPreferredJdbcTemplateMethods { + JdbcTemplate jdbcTemplate; + + @Autowired + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public List getStudentsOfAgeAndGender(Integer age, String gender) { + String sql = "select student_id, student_name, age, gender, grade, state from student where age= ? and gender = ?"; + return jdbcTemplate.query(sql, new StudentRowMapper(), age, gender); + } + + public List getStudentsOfAgeGenderAndGrade(Integer age, String gender, Integer grade) { + String sql = "select student_id, student_name, age, gender, grade, state from student where age= ? and gender = ? and grade = ?"; + return jdbcTemplate.query(sql, new StudentRowMapper(), age, gender, grade); + } + + public List getStudentsOfGradeAndState(Integer grade, String state) { + String sql = "select student_id, student_name, age, gender, grade, state from student where grade = ? and state = ?"; + return jdbcTemplate.query(sql, new StudentResultExtractor(), grade, state); + } + + public Student getStudentOfStudentIDAndGrade(Integer studentID, Integer grade) { + String sql = "select student_id, student_name, age, gender, grade, state from student where student_id = ? and grade = ?"; + + return jdbcTemplate.queryForObject(sql, new StudentRowMapper(), studentID, grade); + } + + public Integer getCountOfGenderInAGrade(String gender, Integer grade) { + String sql = "select count(1) as total from student where gender = ? and grade = ?"; + + return jdbcTemplate.queryForObject(sql, Integer.class, gender, grade); + } + + public Integer getCountOfStudentsInAGradeFromAState(Integer grade, String state) { + String sql = "select student_id, student_name, age, gender, grade, state from student where grade = ? and state = ?"; + + RowCountCallbackHandler countCallbackHandler = new RowCountCallbackHandler(); + jdbcTemplate.query(sql, countCallbackHandler, grade, state); + return countCallbackHandler.getRowCount(); + } +} diff --git a/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/model/Student.java b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/model/Student.java new file mode 100644 index 0000000000..001089d830 --- /dev/null +++ b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/model/Student.java @@ -0,0 +1,60 @@ +package com.baeldung.spring.jdbc.replacedeprecated.model; + +public class Student { + private Integer studentId; + private String studentName; + private String studentGender; + private Integer age; + private Integer grade; + + public Integer getStudentId() { + return studentId; + } + + public void setStudentId(Integer studentId) { + this.studentId = studentId; + } + + public String getStudentName() { + return studentName; + } + + public void setStudentName(String studentName) { + this.studentName = studentName; + } + + public String getStudentGender() { + return studentGender; + } + + public void setStudentGender(String studentGender) { + this.studentGender = studentGender; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Integer getGrade() { + return grade; + } + + public void setGrade(Integer grade) { + this.grade = grade; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + private String state; + +} diff --git a/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/model/StudentResultExtractor.java b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/model/StudentResultExtractor.java new file mode 100644 index 0000000000..d2da59e5f9 --- /dev/null +++ b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/model/StudentResultExtractor.java @@ -0,0 +1,26 @@ +package com.baeldung.spring.jdbc.replacedeprecated.model; + +import org.springframework.jdbc.core.ResultSetExtractor; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class StudentResultExtractor implements ResultSetExtractor> { + @Override + public List extractData(ResultSet rs) throws SQLException { + List students = new ArrayList(); + while(rs.next()) { + Student student = new Student(); + student.setStudentId(rs.getInt("student_id")); + student.setStudentName(rs.getString("student_name")); + student.setAge(rs.getInt("age")); + student.setStudentGender(rs.getString("gender")); + student.setGrade(rs.getInt("grade")); + student.setState(rs.getString("state")); + students.add(student); + } + return students; + } +} diff --git a/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/model/StudentRowMapper.java b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/model/StudentRowMapper.java new file mode 100644 index 0000000000..bf2419e663 --- /dev/null +++ b/persistence-modules/spring-jdbc/src/main/java/com/baeldung/spring/jdbc/replacedeprecated/model/StudentRowMapper.java @@ -0,0 +1,20 @@ +package com.baeldung.spring.jdbc.replacedeprecated.model; + +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class StudentRowMapper implements RowMapper { + @Override + public Student mapRow(ResultSet rs, int rowNum) throws SQLException { + Student student = new Student(); + student.setStudentId(rs.getInt("student_id")); + student.setStudentName(rs.getString("student_name")); + student.setAge(rs.getInt("age")); + student.setStudentGender(rs.getString("gender")); + student.setGrade(rs.getInt("grade")); + student.setState(rs.getString("state")); + return student; + } +} diff --git a/persistence-modules/spring-jdbc/src/main/resources/com/baeldung/spring/jdbc/replacedeprecated/application.properties b/persistence-modules/spring-jdbc/src/main/resources/com/baeldung/spring/jdbc/replacedeprecated/application.properties new file mode 100644 index 0000000000..04c963ebf4 --- /dev/null +++ b/persistence-modules/spring-jdbc/src/main/resources/com/baeldung/spring/jdbc/replacedeprecated/application.properties @@ -0,0 +1,5 @@ +# DataSource Configuration +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=user +spring.datasource.password= # Leave this empty \ No newline at end of file diff --git a/persistence-modules/spring-jdbc/src/main/resources/com/baeldung/spring/jdbc/replacedeprecated/drop_student.sql b/persistence-modules/spring-jdbc/src/main/resources/com/baeldung/spring/jdbc/replacedeprecated/drop_student.sql new file mode 100644 index 0000000000..954545a862 --- /dev/null +++ b/persistence-modules/spring-jdbc/src/main/resources/com/baeldung/spring/jdbc/replacedeprecated/drop_student.sql @@ -0,0 +1 @@ +DROP TABLE student; \ No newline at end of file diff --git a/persistence-modules/spring-jdbc/src/main/resources/com/baeldung/spring/jdbc/replacedeprecated/student.sql b/persistence-modules/spring-jdbc/src/main/resources/com/baeldung/spring/jdbc/replacedeprecated/student.sql new file mode 100644 index 0000000000..0e137f5445 --- /dev/null +++ b/persistence-modules/spring-jdbc/src/main/resources/com/baeldung/spring/jdbc/replacedeprecated/student.sql @@ -0,0 +1,98 @@ + +CREATE TABLE student ( + student_id INT AUTO_INCREMENT PRIMARY KEY, + student_name VARCHAR(255) NOT NULL, + age INT, + grade INT NOT NULL, + gender VARCHAR(10) NOT NULL, + state VARCHAR(100) NOT NULL +); +-- Student 1 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('John Smith', 18, 3, 'Male', 'California'); + +-- Student 2 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emily Johnson', 17, 2, 'Female', 'New York'); + +-- Student 3 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Michael Davis', 4, 1, 'Male', 'Texas'); + +-- Student 4 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Sophia Martinez', 2, 1, 'Female', 'Florida'); + +-- Student 5 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('William Brown', 5, 5, 'Male', 'California'); + +-- Student 6 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Garcia', 4, 2, 'Female', 'Texas'); + +-- Student 7 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ethan Rodriguez', 3, 1, 'Male', 'New York'); + +-- Student 8 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ava Hernandez', 2, 1, 'Female', 'Florida'); + +-- Student 9 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('James Wilson', 5, 4, 'Male', 'Texas'); + +-- Student 10 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emma Miller', 3, 1, 'Female', 'California'); + +-- Student 11 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Benjamin Brown', 4, 1, 'Male', 'New York'); + +-- Student 12 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Mia Smith', 2, 1, 'Female', 'Florida'); + +-- Student 13 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Daniel Johnson', 5, 4, 'Male', 'California'); + +-- Student 14 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ava Davis', 4, 2, 'Female', 'Texas'); + +-- Student 15 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Matthew Martinez', 3, 1, 'Male', 'New York'); + +-- Student 16 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Sophia Taylor', 2, 1, 'Female', 'Florida'); + +-- Student 17 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Alexander White', 5, 4, 'Male', 'California'); + +-- Student 18 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Johnson', 4, 2, 'Female', 'Texas'); + +-- Student 19 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Christopher Lee', 3, 1, 'Male', 'New York'); + +-- Student 20 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emma Wilson', 2, 1, 'Female', 'Florida'); + +-- Student 21 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Elijah Smith', 5, 3, 'Male', 'Texas'); + +-- Student 22 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Isabella Davis', 4, 2, 'Female', 'California'); + +-- Student 23 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Liam Johnson', 3, 1, 'Male', 'New York'); + +-- Student 24 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Garcia', 2, 1, 'Female', 'Florida'); + +-- Student 25 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Noah Rodriguez', 5, 3, 'Male', 'Texas'); + +-- Student 26 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Sophia Hernandez', 4, 2, 'Female', 'California'); + +-- Student 27 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Mason Smith', 3, 1, 'Male', 'New York'); + +-- Student 28 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Ava Taylor', 2, 1, 'Female', 'Florida'); + +-- Student 29 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('William Brown', 5, 5, 'Male', 'Texas'); + +-- Student 30 +INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Olivia Martinez', 4, 4, 'Female', 'California'); diff --git a/persistence-modules/spring-jdbc/src/test/java/com/baeldung/spring/jdbc/replacedeprecated/StudentDaoWithJdbcTemplateMethodsUnitTest.java b/persistence-modules/spring-jdbc/src/test/java/com/baeldung/spring/jdbc/replacedeprecated/StudentDaoWithJdbcTemplateMethodsUnitTest.java new file mode 100644 index 0000000000..ea1a4a8659 --- /dev/null +++ b/persistence-modules/spring-jdbc/src/test/java/com/baeldung/spring/jdbc/replacedeprecated/StudentDaoWithJdbcTemplateMethodsUnitTest.java @@ -0,0 +1,131 @@ +package com.baeldung.spring.jdbc.replacedeprecated; + +import com.baeldung.spring.jdbc.replacedeprecated.model.Student; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest; +import org.springframework.test.context.jdbc.Sql; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@JdbcTest +@Sql(value = "student.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) +@Sql(value = "drop_student.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) +public class StudentDaoWithJdbcTemplateMethodsUnitTest { + private static final Logger logger = LoggerFactory.getLogger(StudentDaoWithJdbcTemplateMethodsUnitTest.class); + @Autowired + StudentDaoWithDeprecatedJdbcTemplateMethods studentDaoWithDeprecatedJdbcTemplateMethods; + @Autowired + StudentDaoWithPreferredJdbcTemplateMethods studentDaoWithPreferredJdbcTemplateMethods; + + @Test + public void givenPreferredMethodQuery_whenArgsAgeAndGender_thenReturnStudents() { + List students = studentDaoWithPreferredJdbcTemplateMethods.getStudentsOfAgeAndGender(4, "Female"); + + for (Student student: students) { + logger.info("Student Name: " + student.getStudentName() + " Student gender: " + student.getStudentGender()); + } + assertEquals(6, students.size()); + } + + @Test + public void givenPreferredMethodQuery_whenArgsAgeGenderAndGrade_thenReturnStudents() { + List students = studentDaoWithPreferredJdbcTemplateMethods.getStudentsOfAgeGenderAndGrade(4, "Female", 2); + + for (Student student: students) { + logger.info("Student Name: " + student.getStudentName() + " Student gender: " + student.getStudentGender() + + " Student grade: " + student.getGrade()); + } + assertEquals(5, students.size()); + } + + @Test + public void givenDeprecatedMethodQuery_whenArgsAgeGenderAndGrade_thenReturnStudents() { + List students = studentDaoWithDeprecatedJdbcTemplateMethods.getStudentsOfAgeGenderAndGrade(4, "Female", 2); + + for (Student student: students) { + logger.info("Student Name: " + student.getStudentName() + " Student gender: " + student.getStudentGender() + + " Student grade: " + student.getGrade()); + } + assertEquals(5, students.size()); + } + + @Test + public void givenDeprecatedMethodQuery_whenArgsAgeAndGender_thenReturnStudents() { + List students = studentDaoWithDeprecatedJdbcTemplateMethods.getStudentsOfAgeAndGender(4, "Female"); + for (Student student: students) { + logger.info("Student Name: " + student.getStudentName() + " Student gender: " + student.getStudentGender()); + } + assertEquals(6, students.size()); + } + + @Test + public void givenDeprecatedMethodQuery_whenArgsGradeAndState_thenReturnStudents() { + List students = studentDaoWithDeprecatedJdbcTemplateMethods.getStudentsOfGradeAndState(1, "New York"); + for (Student student: students) { + logger.info("Student Name: " + student.getStudentName() + + " Student grade: " + student.getStudentGender() + + " Student State: " + student.getState()); + } + assertEquals(6, students.size()); + } + + @Test + public void givenPreferredMethodQuery_whenArgsGradeAndState_thenReturnStudents() { + List students = studentDaoWithPreferredJdbcTemplateMethods.getStudentsOfGradeAndState(1, "New York"); + for (Student student: students) { + logger.info("Student Name: " + student.getStudentName() + + " Student grade: " + student.getStudentGender() + + " Student State: " + student.getState()); + } + assertEquals(6, students.size()); + } + + @Test + public void givenDeprecatedMethodQuery_whenArgsGradeAndState_thenReturnCount() { + Integer count = studentDaoWithDeprecatedJdbcTemplateMethods.getCountOfStudentsInAGradeFromAState(1, "New York"); + logger.info("Total students of grade 1 from New York: " + count); + assertEquals(6, count); + } + @Test + public void givenPreferredMethodQuery_whenArgsGradeAndState_thenReturnCount() { + Integer count = studentDaoWithPreferredJdbcTemplateMethods.getCountOfStudentsInAGradeFromAState(1, "New York"); + logger.info("Total students of grade 1 from New York: " + count); + assertEquals(6, count); + } + @Test + public void givenDeprecatedMethodQueryForObject_whenArgsStudentIDAndGrade_thenReturnStudent() { + Student student = studentDaoWithDeprecatedJdbcTemplateMethods.getStudentOfStudentIDAndGrade(4, 1); + assertEquals(1, student.getGrade()); + assertEquals(4, student.getStudentId()); + logger.info("Student ID: " + student.getStudentId() + + " Student Name: " + student.getStudentName() + " Student grade: " + student.getGrade()); + } + + @Test + public void givenPreferredMethodQueryForObject_whenArgsStudentIDAndGrade_thenReturnStudent() { + Student student = studentDaoWithPreferredJdbcTemplateMethods.getStudentOfStudentIDAndGrade(4, 1); + assertEquals(1, student.getGrade()); + assertEquals(4, student.getStudentId()); + logger.info("Student ID: " + student.getStudentId() + + " Student Name: " + student.getStudentName() + " Student grade: " + student.getGrade()); + } + + @Test + public void givenPreferredMethodQueryForObject_whenArgsGenderAndGrade_thenReturnCount() { + Integer count = studentDaoWithPreferredJdbcTemplateMethods.getCountOfGenderInAGrade("Female", 2); + assertEquals(6, count); + logger.info("Total number of Female Students: " + count); + } + + @Test + public void givenDeprecatedMethodQueryForObject_whenArgsGenderAndGrade_thenReturnCount() { + Integer count = studentDaoWithPreferredJdbcTemplateMethods.getCountOfGenderInAGrade("Female", 2); + assertEquals(6, count); + logger.info("Total number of Female Students: " + count); + } +} diff --git a/pom.xml b/pom.xml index f06cd438f8..c65f6ce62d 100644 --- a/pom.xml +++ b/pom.xml @@ -342,8 +342,6 @@ core-java-modules/core-java-8-datetime-2 core-java-modules/core-java-sun core-java-modules/core-java-security - core-java-modules/core-java-nio-2 - core-java-modules/core-java-serialization core-java-modules/core-java-lang core-java-modules/core-java-lang-math-3 @@ -366,10 +364,10 @@ web-modules/restx persistence-modules/deltaspike persistence-modules/hibernate-ogm - persistence-modules/java-cassandra persistence-modules/spring-data-cassandra-reactive java-nashorn jeromq + spring-ejb-modules/ejb-beans @@ -519,8 +517,6 @@ core-java-modules/core-java-8-datetime-2 core-java-modules/core-java-sun core-java-modules/core-java-security - core-java-modules/core-java-nio-2 - core-java-modules/core-java-serialization core-java-modules/core-java-lang core-java-modules/core-java-lang-math-3 @@ -541,9 +537,10 @@ web-modules/restx persistence-modules/deltaspike persistence-modules/hibernate-ogm - persistence-modules/java-cassandra persistence-modules/spring-data-cassandra-reactive java-nashorn + jeromq + spring-ejb-modules/ejb-beans @@ -812,7 +809,6 @@ akka-modules - annotations httpclient-simple antlr apache-kafka @@ -868,7 +864,7 @@ libraries-apache-commons-2 libraries-apache-commons-collections libraries-apache-commons-io - + libraries-data-2 libraries-data-io libraries-files libraries-http @@ -938,6 +934,8 @@ language-interop gradle-modules/gradle/maven-to-gradle persistence-modules/spring-data-neo4j + parent-boot-3 + @@ -1036,6 +1034,7 @@ core-groovy-modules core-java-modules + gcp-firebase @@ -1084,7 +1083,6 @@ akka-modules - annotations antlr apache-kafka apache-kafka-2 @@ -1140,7 +1138,7 @@ libraries-apache-commons-2 libraries-apache-commons-collections libraries-apache-commons-io - + libraries-data-2 libraries-data-io libraries-files libraries-http @@ -1211,6 +1209,8 @@ language-interop gradle-modules/gradle/maven-to-gradle persistence-modules/spring-data-neo4j + spring-actuator + spring-cloud-modules/spring-cloud-contract @@ -1226,6 +1226,7 @@ parent-boot-1 parent-boot-2 + parent-boot-3 parent-spring-4 parent-spring-5 parent-spring-6 @@ -1270,19 +1271,19 @@ 2.22.2 - 3.8.1 - 3.0.0 + 3.11.0 + 3.1.0 1.8 1.2.17 1.36 1.36 - 2.21.0 + 3.1.2 4.4 2.13.0 2.6 3.13.0 1.5.0 - 3.3.2 + 3.4.0 4.0.1 1.2 2.3.3 @@ -1292,16 +1293,16 @@ 1.9.2 5.9.2 1.3.2 - 0.3.1 - 2.5.2 + 1.0 + 3.1.1 0.0.1 3.12.2 - 3.0.0 - 3.19.0 + 3.3.0 + 3.21.0 1.18.28 2.1.214 - 31.1-jre - 3.2.2 + 32.1.2-jre + 3.3.0 diff --git a/quarkus-modules/quarkus-vs-springboot/spring-project/pom.xml b/quarkus-modules/quarkus-vs-springboot/spring-project/pom.xml index df3eca8a4f..74deab3558 100644 --- a/quarkus-modules/quarkus-vs-springboot/spring-project/pom.xml +++ b/quarkus-modules/quarkus-vs-springboot/spring-project/pom.xml @@ -255,7 +255,6 @@ 1.17.2 11 0.12.1 - 3.10.1 11 11 3.1.0 diff --git a/saas-modules/sentry-servlet/pom.xml b/saas-modules/sentry-servlet/pom.xml index 4f9e37ebd5..70f6876dee 100644 --- a/saas-modules/sentry-servlet/pom.xml +++ b/saas-modules/sentry-servlet/pom.xml @@ -46,6 +46,5 @@ 6.11.0 1.10.4 - 3.3.2 \ No newline at end of file diff --git a/saas-modules/slack/pom.xml b/saas-modules/slack/pom.xml index 326167c055..d9e7abb4a2 100644 --- a/saas-modules/slack/pom.xml +++ b/saas-modules/slack/pom.xml @@ -55,7 +55,6 @@ 1.4 - 2.4 \ No newline at end of file diff --git a/security-modules/jwt/src/test/java/com/baeldung/jwt/auth0/Auth0JsonWebTokenUnitTest.java b/security-modules/jwt/src/test/java/com/baeldung/jwt/auth0/Auth0JsonWebTokenUnitTest.java index a9c3b4185d..29fb832bd9 100644 --- a/security-modules/jwt/src/test/java/com/baeldung/jwt/auth0/Auth0JsonWebTokenUnitTest.java +++ b/security-modules/jwt/src/test/java/com/baeldung/jwt/auth0/Auth0JsonWebTokenUnitTest.java @@ -7,6 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.Date; +import org.junit.Ignore; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -97,13 +98,14 @@ public class Auth0JsonWebTokenUnitTest { assertEquals(DATA, claim.asString()); } - @Test + //Need to fix with JAVA-24552 + @Ignore public void givenJWT_whenCreatedWithNotBefore_thenThrowException() { jwtToken = JWT.create() .withIssuer(ISSUER) .withClaim(DATA_CLAIM, DATA) - .withNotBefore(new Date(System.currentTimeMillis() + 1000L)) + .withNotBefore(new Date(System.currentTimeMillis() + 10000L)) .sign(algorithm); assertThrows(IncorrectClaimException.class, () -> { diff --git a/security-modules/pom.xml b/security-modules/pom.xml index b779c0d46d..864b1a7fcc 100644 --- a/security-modules/pom.xml +++ b/security-modules/pom.xml @@ -25,8 +25,4 @@ sql-injection-samples - - 3.3.2 - - diff --git a/server-modules/undertow/pom.xml b/server-modules/undertow/pom.xml index 42a46d9508..a73771485c 100644 --- a/server-modules/undertow/pom.xml +++ b/server-modules/undertow/pom.xml @@ -46,7 +46,6 @@ 1.4.18.Final - 3.0.2 \ No newline at end of file diff --git a/spring-aop-2/pom.xml b/spring-aop-2/pom.xml index 056e248a3c..206e1d7d7c 100644 --- a/spring-aop-2/pom.xml +++ b/spring-aop-2/pom.xml @@ -51,4 +51,119 @@ + + + no-weaving + + true + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest + com.baeldung.selfinvocation.LoadTimeWeavingIntegrationTest + + + + + + + + + compile-time-weaving + + + + org.springframework + spring-aspects + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + com.baeldung.selfinvocation.CompileTimeWeavingIntegrationTest + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj-plugin.version} + + ${java.version} + ${java.version} + ${java.version} + ignore + UTF-8 + + + org.springframework + spring-aspects + + + + + + + compile + + + + + + + + + + load-time-weaving + + + + org.springframework + spring-aspects + + + org.springframework + spring-tx + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${maven-surefire-plugin.version} + + + --add-opens java.base/java.lang=ALL-UNNAMED + --add-opens java.base/java.util=ALL-UNNAMED + -javaagent:"${settings.localRepository}"/org/aspectj/aspectjweaver/${aspectjweaver.version}/aspectjweaver-${aspectjweaver.version}.jar + -javaagent:"${settings.localRepository}"/org/springframework/spring-instrument/${spring.version}/spring-instrument-${spring.version}.jar + + true + always + + com.baeldung.selfinvocation.LoadTimeWeavingIntegrationTest + + + + + + + + + + 1.14.0 + 5.3.27 + + \ No newline at end of file diff --git a/spring-aop-2/src/main/java/com/baeldung/Application.java b/spring-aop-2/src/main/java/com/baeldung/Application.java index c0490d50c6..cc64447264 100644 --- a/spring-aop-2/src/main/java/com/baeldung/Application.java +++ b/spring-aop-2/src/main/java/com/baeldung/Application.java @@ -2,8 +2,16 @@ package com.baeldung; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; @SpringBootApplication +@ComponentScan(basePackages = { "com.baeldung" }, excludeFilters = { + @ComponentScan.Filter(type = FilterType.ANNOTATION, + value = { SpringBootApplication.class}) +}) +@EnableCaching public class Application { public static void main(String[] args) { diff --git a/spring-aop-2/src/main/java/com/baeldung/selfinvocation/CompileTimeWeavingApplication.java b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/CompileTimeWeavingApplication.java new file mode 100644 index 0000000000..03995dd53b --- /dev/null +++ b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/CompileTimeWeavingApplication.java @@ -0,0 +1,20 @@ +package com.baeldung.selfinvocation; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.AdviceMode; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; + +@SpringBootApplication +@EnableCaching(mode = AdviceMode.ASPECTJ) +@ComponentScan(basePackages = { "com.baeldung" }, excludeFilters = { + @ComponentScan.Filter(type = FilterType.ANNOTATION, + value = { SpringBootApplication.class}) +}) +public class CompileTimeWeavingApplication { + public static void main(String[] args) { + SpringApplication.run(CompileTimeWeavingApplication.class, args); + } +} \ No newline at end of file diff --git a/spring-aop-2/src/main/java/com/baeldung/selfinvocation/LoadTimeWeavingApplication.java b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/LoadTimeWeavingApplication.java new file mode 100644 index 0000000000..a3dcc161b3 --- /dev/null +++ b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/LoadTimeWeavingApplication.java @@ -0,0 +1,16 @@ +package com.baeldung.selfinvocation; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.AdviceMode; +import org.springframework.context.annotation.EnableLoadTimeWeaving; + +@SpringBootApplication +@EnableCaching(mode = AdviceMode.ASPECTJ) +@EnableLoadTimeWeaving +public class LoadTimeWeavingApplication { + public static void main(String[] args) { + SpringApplication.run(LoadTimeWeavingApplication.class, args); + } +} \ No newline at end of file diff --git a/spring-aop-2/src/main/java/com/baeldung/selfinvocation/MathService.java b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/MathService.java new file mode 100644 index 0000000000..993b73295f --- /dev/null +++ b/spring-aop-2/src/main/java/com/baeldung/selfinvocation/MathService.java @@ -0,0 +1,43 @@ +package com.baeldung.selfinvocation; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.stereotype.Service; + +import java.util.concurrent.atomic.AtomicInteger; + +@Service +@CacheConfig(cacheNames = "square") +@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) +public class MathService { + + @Autowired + private MathService self; + private final AtomicInteger counter = new AtomicInteger(); + + @CacheEvict(allEntries = true) + public AtomicInteger resetCounter() { + counter.set(0); + return counter; + } + + @Cacheable(key = "#n") + public double square(double n) { + counter.incrementAndGet(); + return n * n; + } + + public double sumOfSquareOf2() { + return this.square(2) + this.square(2); + } + + public double sumOfSquareOf3() { + return self.square(3) + self.square(3); + } + +} + diff --git a/spring-aop-2/src/main/resources/logback.xml b/spring-aop-2/src/main/resources/logback.xml index 4eaa556705..d63707a9da 100644 --- a/spring-aop-2/src/main/resources/logback.xml +++ b/spring-aop-2/src/main/resources/logback.xml @@ -17,6 +17,8 @@ + + diff --git a/spring-aop-2/src/test/java/com/baeldung/selfinvocation/CompileTimeWeavingIntegrationTest.java b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/CompileTimeWeavingIntegrationTest.java new file mode 100644 index 0000000000..d0522f67e5 --- /dev/null +++ b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/CompileTimeWeavingIntegrationTest.java @@ -0,0 +1,24 @@ +package com.baeldung.selfinvocation; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.annotation.Resource; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = CompileTimeWeavingApplication.class) +class CompileTimeWeavingIntegrationTest { + + @Resource + private MathService mathService; + + @Test + void givenCacheableMethod_whenInvokingByInternalCall_thenCacheIsTriggered() { + AtomicInteger counter = mathService.resetCounter(); + + assertThat(mathService.sumOfSquareOf2()).isEqualTo(8); + assertThat(counter.get()).isEqualTo(1); + } +} \ No newline at end of file diff --git a/spring-aop-2/src/test/java/com/baeldung/selfinvocation/LoadTimeWeavingIntegrationTest.java b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/LoadTimeWeavingIntegrationTest.java new file mode 100644 index 0000000000..93c57699d6 --- /dev/null +++ b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/LoadTimeWeavingIntegrationTest.java @@ -0,0 +1,25 @@ +package com.baeldung.selfinvocation; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.annotation.Resource; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = LoadTimeWeavingApplication.class) +class LoadTimeWeavingIntegrationTest { + + @Resource + private MathService mathService; + + @Test + void givenCacheableMethod_whenInvokingByInternalCall_thenCacheIsTriggered() { + AtomicInteger counter = mathService.resetCounter(); + + assertThat(mathService.sumOfSquareOf2()).isEqualTo(8); + assertThat(counter.get()).isEqualTo(1); + } + +} \ No newline at end of file diff --git a/spring-aop-2/src/test/java/com/baeldung/selfinvocation/MathServiceIntegrationTest.java b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/MathServiceIntegrationTest.java new file mode 100644 index 0000000000..24b829fa07 --- /dev/null +++ b/spring-aop-2/src/test/java/com/baeldung/selfinvocation/MathServiceIntegrationTest.java @@ -0,0 +1,47 @@ +package com.baeldung.selfinvocation; + +import com.baeldung.Application; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.annotation.Resource; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +class MathServiceIntegrationTest { + + @Resource + private MathService mathService; + + @Test + void givenCacheableMethod_whenInvokedForSecondTime_thenCounterShouldNotIncrease() { + AtomicInteger counter = mathService.resetCounter(); + assertThat(mathService.square(2)).isEqualTo(4); + assertThat(counter.get()).isEqualTo(1); + + mathService.square(2); + assertThat(counter.get()).isEqualTo(1); + + mathService.square(3); + assertThat(counter.get()).isEqualTo(2); + } + + @Test + void givenCacheableMethod_whenInvokingByInternalCall_thenCacheIsNotTriggered() { + AtomicInteger counter = mathService.resetCounter(); + + assertThat(mathService.sumOfSquareOf2()).isEqualTo(8); + assertThat(counter.get()).isEqualTo(2); + } + + @Test + void givenCacheableMethod_whenInvokingByExternalCall_thenCacheIsTriggered() { + AtomicInteger counter = mathService.resetCounter(); + + assertThat(mathService.sumOfSquareOf3()).isEqualTo(18); + assertThat(counter.get()).isEqualTo(1); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index a2febc8156..1c4b2bb38f 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -44,7 +44,7 @@ spring-boot-graphql spring-boot-groovy - + spring-boot-jasypt spring-boot-jsp spring-boot-keycloak spring-boot-keycloak-2 @@ -91,13 +91,19 @@ spring-boot-3-native spring-boot-3-observation spring-boot-3-test-pitfalls + spring-boot-3-testcontainers spring-boot-resilience4j spring-boot-properties spring-boot-properties-2 spring-boot-properties-3 spring-boot-properties-4 spring-boot-properties-migrator-demo + spring-boot-aws + spring-boot-keycloak-adapters + spring-boot-mvc-legacy + spring-boot-springdoc-2 spring-boot-documentation + spring-boot-3-url-matching @@ -119,8 +125,4 @@ - - 3.3.2 - - diff --git a/spring-boot-modules/spring-boot-3-testcontainers/README.md b/spring-boot-modules/spring-boot-3-testcontainers/README.md new file mode 100644 index 0000000000..183c64faae --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Built-in Testcontainers Support in Spring Boot](https://www.baeldung.com/spring-boot-built-in-testcontainers) diff --git a/spring-boot-modules/spring-boot-3-testcontainers/pom.xml b/spring-boot-modules/spring-boot-3-testcontainers/pom.xml new file mode 100644 index 0000000000..173fb8795c --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + spring-boot-3-testcontainers + 0.0.1-SNAPSHOT + spring-boot-3-testcontainers + Testcontainer Improvements in Spring Boot 3 + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 + + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.springframework.boot + spring-boot-starter-test + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + + org.springframework.boot + spring-boot-testcontainers + + + + org.testcontainers + mongodb + ${testcontainers.version} + test + + + org.testcontainers + testcontainers + ${testcontainers.version} + test + + + org.testcontainers + junit-jupiter + ${testcontainers.version} + test + + + + io.rest-assured + rest-assured + ${rest-assured.version} + test + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + 3.0.0-M7 + 1.18.3 + 5.3.1 + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/Application.java b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/Application.java new file mode 100644 index 0000000000..afe987a313 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/Application.java @@ -0,0 +1,13 @@ +package com.baeldung.testcontainers; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharacter.java b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharacter.java new file mode 100644 index 0000000000..4780a2f66a --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharacter.java @@ -0,0 +1,13 @@ +package com.baeldung.testcontainers.support; + +import java.util.UUID; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Document("characters") +public record MiddleEarthCharacter(@Id String id, String name, String race) { + public MiddleEarthCharacter(String name, String race) { + this(UUID.randomUUID().toString(), name, race); + } +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersController.java b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersController.java new file mode 100644 index 0000000000..3b7bfddbef --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersController.java @@ -0,0 +1,30 @@ +package com.baeldung.testcontainers.support; + +import java.util.List; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("characters") +public class MiddleEarthCharactersController { + private final MiddleEarthCharactersRepository repository; + + public MiddleEarthCharactersController(MiddleEarthCharactersRepository repository) { + this.repository = repository; + } + + @GetMapping + public List findByRace(@RequestParam String race) { + return repository.findAllByRace(race); + } + + @PostMapping + public MiddleEarthCharacter save(@RequestBody MiddleEarthCharacter character) { + return repository.save(character); + } +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersRepository.java b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersRepository.java new file mode 100644 index 0000000000..a668650670 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/main/java/com/baeldung/testcontainers/support/MiddleEarthCharactersRepository.java @@ -0,0 +1,11 @@ +package com.baeldung.testcontainers.support; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface MiddleEarthCharactersRepository extends MongoRepository { + List findAllByRace(String race); +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/DynamicPropertiesLiveTest.java b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/DynamicPropertiesLiveTest.java new file mode 100644 index 0000000000..e8818c1019 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/DynamicPropertiesLiveTest.java @@ -0,0 +1,59 @@ +package com.baeldung.testcontainers; + +import static io.restassured.RestAssured.when; +import static org.hamcrest.Matchers.hasItems; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; +import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_CLASS; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import com.baeldung.testcontainers.support.MiddleEarthCharacter; +import com.baeldung.testcontainers.support.MiddleEarthCharactersRepository; + +@Testcontainers +@SpringBootTest(webEnvironment = DEFINED_PORT) +@DirtiesContext(classMode = AFTER_CLASS) +class DynamicPropertiesLiveTest { + @Container + static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")); + + @DynamicPropertySource + static void setProperties(DynamicPropertyRegistry registry) { + registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); + } + + @Autowired + private MiddleEarthCharactersRepository repository; + + @BeforeEach + void beforeEach() { + repository.deleteAll(); + } + + @Test + void whenRequestingHobbits_thenReturnFrodoAndSam() { + repository.saveAll(List.of( + new MiddleEarthCharacter("Frodo", "hobbit"), + new MiddleEarthCharacter("Samwise", "hobbit"), + new MiddleEarthCharacter("Aragon", "human"), + new MiddleEarthCharacter("Gandalf", "wizard") + )); + + when().get("/characters?race=hobbit") + .then().statusCode(200) + .and().body("name", hasItems("Frodo", "Samwise")); + } + +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/LocalDevApplication.java b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/LocalDevApplication.java new file mode 100644 index 0000000000..a94c0f772a --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/LocalDevApplication.java @@ -0,0 +1,29 @@ +package com.baeldung.testcontainers; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.devtools.restart.RestartScope; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.context.annotation.Bean; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.utility.DockerImageName; + +class LocalDevApplication { + + public static void main(String[] args) { + SpringApplication.from(Application::main) + .with(LocalDevTestcontainersConfig.class) + .run(args); + } + + @TestConfiguration(proxyBeanMethods = false) + static class LocalDevTestcontainersConfig { + @Bean + @RestartScope + @ServiceConnection + public MongoDBContainer mongoDBContainer() { + return new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")); + } + } + +} diff --git a/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/ServiceConnectionLiveTest.java b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/ServiceConnectionLiveTest.java new file mode 100644 index 0000000000..838ee127f6 --- /dev/null +++ b/spring-boot-modules/spring-boot-3-testcontainers/src/test/java/com/baeldung/testcontainers/ServiceConnectionLiveTest.java @@ -0,0 +1,55 @@ +package com.baeldung.testcontainers; + +import static io.restassured.RestAssured.when; +import static org.hamcrest.Matchers.hasItems; +import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.DEFINED_PORT; +import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_CLASS; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.testcontainers.service.connection.ServiceConnection; +import org.springframework.test.annotation.DirtiesContext; +import org.testcontainers.containers.MongoDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import com.baeldung.testcontainers.support.MiddleEarthCharacter; +import com.baeldung.testcontainers.support.MiddleEarthCharactersRepository; + +@Testcontainers +@SpringBootTest(webEnvironment = DEFINED_PORT) +@DirtiesContext(classMode = AFTER_CLASS) +class ServiceConnectionLiveTest { + + @Container + @ServiceConnection + static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10")); + + @Autowired + private MiddleEarthCharactersRepository repository; + + @BeforeEach + void beforeEach() { + repository.deleteAll(); + } + + @Test + void whenRequestingHobbits_thenReturnFrodoAndSam() { + repository.saveAll(List.of( + new MiddleEarthCharacter("Frodo", "hobbit"), + new MiddleEarthCharacter("Samwise", "hobbit"), + new MiddleEarthCharacter("Aragon", "human"), + new MiddleEarthCharacter("Gandalf", "wizard") + )); + + when().get("/characters?race=hobbit") + .then().statusCode(200) + .and().body("name", hasItems("Frodo", "Samwise")); + } + +} diff --git a/spring-boot-modules/spring-boot-3-url-matching/pom.xml b/spring-boot-modules/spring-boot-3-url-matching/pom.xml index aa83a676d7..43f89eab47 100644 --- a/spring-boot-modules/spring-boot-3-url-matching/pom.xml +++ b/spring-boot-modules/spring-boot-3-url-matching/pom.xml @@ -67,7 +67,7 @@ io.projectreactor reactor-test - ${reactor-test.version} + ${reactor-core.version} test diff --git a/spring-boot-modules/spring-boot-3/pom.xml b/spring-boot-modules/spring-boot-3/pom.xml index 32c69801ca..7e61ca18af 100644 --- a/spring-boot-modules/spring-boot-3/pom.xml +++ b/spring-boot-modules/spring-boot-3/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-boot-3 0.0.1-SNAPSHOT @@ -49,7 +49,6 @@ com.h2database h2 - runtime diff --git a/spring-boot-modules/spring-boot-artifacts/pom.xml b/spring-boot-modules/spring-boot-artifacts/pom.xml index dedeb0ab2a..e39ddb5af1 100644 --- a/spring-boot-modules/spring-boot-artifacts/pom.xml +++ b/spring-boot-modules/spring-boot-artifacts/pom.xml @@ -193,7 +193,6 @@ 2.2.4 3.1.7 4.5.8 - 2.18 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-aws/pom.xml b/spring-boot-modules/spring-boot-aws/pom.xml index 12a65908af..815766a846 100644 --- a/spring-boot-modules/spring-boot-aws/pom.xml +++ b/spring-boot-modules/spring-boot-aws/pom.xml @@ -23,7 +23,7 @@ com.amazonaws.serverless aws-serverless-java-container-springboot2 - ${springboot2.aws.version} + ${aws-serverless-java-container-springboot2.version} org.springframework.boot @@ -64,16 +64,18 @@ org.apache.maven.plugins maven-compiler-plugin - 11 - 11 + ${maven.compiler.source.version} + ${maven.compiler.target.version} - 1.9.1 + 1.9.1 3.2.4 + 11 + 11 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/pom.xml b/spring-boot-modules/spring-boot-basic-customization/pom.xml index 4b1009d38a..581a7fec06 100644 --- a/spring-boot-modules/spring-boot-basic-customization/pom.xml +++ b/spring-boot-modules/spring-boot-basic-customization/pom.xml @@ -86,5 +86,4 @@ com.baeldung.changeport.CustomApplication - \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-ci-cd/pom.xml b/spring-boot-modules/spring-boot-ci-cd/pom.xml index 8c12c98236..6e58f1162d 100644 --- a/spring-boot-modules/spring-boot-ci-cd/pom.xml +++ b/spring-boot-modules/spring-boot-ci-cd/pom.xml @@ -34,7 +34,7 @@ org.jacoco jacoco-maven-plugin - 0.8.5 + ${jacoco-maven-plugin.version} default-prepare-agent @@ -65,7 +65,7 @@ com.heroku.sdk heroku-maven-plugin - 3.0.2 + ${heroku-maven-plugin.version} spring-boot-ci-cd @@ -88,7 +88,7 @@ com.google.cloud.tools jib-maven-plugin - 2.2.0 + ${jib-maven-plugin.version} registry.hub.docker.com/baeldungjib/baeldung-ci-cd-process @@ -104,4 +104,10 @@ + + 0.8.5 + 3.0.2 + 2.2.0 + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-cli/pom.xml b/spring-boot-modules/spring-boot-cli/pom.xml index 76b14b2103..19607ac21c 100644 --- a/spring-boot-modules/spring-boot-cli/pom.xml +++ b/spring-boot-modules/spring-boot-cli/pom.xml @@ -6,7 +6,6 @@ spring-boot-cli spring-boot-cli jar - com.baeldung.spring-boot-modules diff --git a/spring-boot-modules/spring-boot-crud/pom.xml b/spring-boot-modules/spring-boot-crud/pom.xml index 7acaa49e87..35f3ec114d 100644 --- a/spring-boot-modules/spring-boot-crud/pom.xml +++ b/spring-boot-modules/spring-boot-crud/pom.xml @@ -59,7 +59,7 @@ org.apache.maven.plugins maven-assembly-plugin - 3.3.0 + ${maven-assembly-plugin.version} jar-with-dependencies @@ -78,4 +78,8 @@ + + 3.3.0 + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-data-3/pom.xml b/spring-boot-modules/spring-boot-data-3/pom.xml index 4903d2ea26..6c2edbb864 100644 --- a/spring-boot-modules/spring-boot-data-3/pom.xml +++ b/spring-boot-modules/spring-boot-data-3/pom.xml @@ -27,7 +27,7 @@ com.amazonaws.secretsmanager aws-secretsmanager-jdbc - ${aws.secrets.manager.jdbc} + ${aws-secretsmanager-jdbc.version} mysql @@ -46,7 +46,7 @@ io.awspring.cloud spring-cloud-starter-aws-secrets-manager-config - ${aws.secrets.manager.config} + ${spring-cloud-starter-aws-secrets-manager-config.version} @@ -60,8 +60,8 @@ - 2.4.4 - 1.0.11 + 2.4.4 + 1.0.11 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-deployment/pom.xml b/spring-boot-modules/spring-boot-deployment/pom.xml index a1819c4f38..890a5be58f 100644 --- a/spring-boot-modules/spring-boot-deployment/pom.xml +++ b/spring-boot-modules/spring-boot-deployment/pom.xml @@ -113,7 +113,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.18 + ${maven-failsafe-plugin.version} @@ -181,6 +181,7 @@ 2.2 3.1.7 4.5.8 + 2.18 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-documentation/pom.xml b/spring-boot-modules/spring-boot-documentation/pom.xml index 587ad8473b..f0806b3c75 100644 --- a/spring-boot-modules/spring-boot-documentation/pom.xml +++ b/spring-boot-modules/spring-boot-documentation/pom.xml @@ -48,7 +48,7 @@ io.swagger.core.v3 swagger-core-jakarta - ${swagger-core.version} + ${swagger-core-jakarta.version} io.github.springwolf @@ -92,8 +92,7 @@ - 3.3.2 - 2.2.11 + 2.2.11 0.12.1 0.8.0 1.18.3 diff --git a/spring-boot-modules/spring-boot-graphql/pom.xml b/spring-boot-modules/spring-boot-graphql/pom.xml index 628babbd3f..d3c122709d 100644 --- a/spring-boot-modules/spring-boot-graphql/pom.xml +++ b/spring-boot-modules/spring-boot-graphql/pom.xml @@ -18,7 +18,7 @@ kr.motd.maven os-maven-plugin - 1.7.0 + ${os-maven-plugin.version} @@ -43,17 +43,6 @@ - - 3.19.2 - 0.6.1 - 1.43.2 - 2.13.1.RELEASE - 1.5.1 - 1.3.5 - 1.6.2 - 3.3.2 - - org.springframework.boot @@ -88,7 +77,7 @@ jakarta.annotation jakarta.annotation-api - ${jakarta.annotation.version} + ${jakarta.annotation-api.version} true @@ -119,4 +108,16 @@ + + 3.19.2 + 0.6.1 + 1.43.2 + 2.13.1.RELEASE + 1.5.1 + 1.3.5 + 1.6.2 + 3.3.2 + 1.7.0 + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-groovy/pom.xml b/spring-boot-modules/spring-boot-groovy/pom.xml index ab1fef6865..151160bde5 100644 --- a/spring-boot-modules/spring-boot-groovy/pom.xml +++ b/spring-boot-modules/spring-boot-groovy/pom.xml @@ -50,7 +50,7 @@ org.codehaus.gmavenplus gmavenplus-plugin - 1.9.0 + ${gmavenplus-plugin.version} @@ -72,6 +72,7 @@ com.baeldung.springwithgroovy.SpringBootGroovyApplication 3.0.13 + 1.9.0 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-jasypt/pom.xml b/spring-boot-modules/spring-boot-jasypt/pom.xml index 8595b9c639..f48cd78595 100644 --- a/spring-boot-modules/spring-boot-jasypt/pom.xml +++ b/spring-boot-modules/spring-boot-jasypt/pom.xml @@ -46,8 +46,15 @@ + + + spring-milestone + Spring Milestone + https://repo.spring.io/milestone + + + 2.0.0 - \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak-2/pom.xml b/spring-boot-modules/spring-boot-keycloak-2/pom.xml index 4c4f403776..39a7283328 100644 --- a/spring-boot-modules/spring-boot-keycloak-2/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak-2/pom.xml @@ -17,10 +17,6 @@ ../../parent-boot-2 - - 21.0.1 - - org.springframework.boot @@ -88,4 +84,8 @@ + + 21.0.1 + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-keycloak/pom.xml b/spring-boot-modules/spring-boot-keycloak/pom.xml index a4d6e18fd5..64fb39d085 100644 --- a/spring-boot-modules/spring-boot-keycloak/pom.xml +++ b/spring-boot-modules/spring-boot-keycloak/pom.xml @@ -55,7 +55,7 @@ wsdl4j wsdl4j - 1.6.3 + ${wsdl4j.version} org.springframework.boot @@ -105,6 +105,7 @@ com.baeldung.keycloak.SpringBoot 4.0.0 + 1.6.3 2.5.0 diff --git a/spring-boot-modules/spring-boot-mvc-5/pom.xml b/spring-boot-modules/spring-boot-mvc-5/pom.xml index 5a4f8a6cce..a516cab049 100644 --- a/spring-boot-modules/spring-boot-mvc-5/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-5/pom.xml @@ -47,7 +47,7 @@ commons-configuration commons-configuration - 1.10 + ${commons-configuration.version} @@ -68,6 +68,7 @@ 3.0.0 com.baeldung.springboot.swagger.ArticleApplication 2021.0.5 + 1.10 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-performance/pom.xml b/spring-boot-modules/spring-boot-performance/pom.xml index 38f5758c1f..d63bb450b5 100644 --- a/spring-boot-modules/spring-boot-performance/pom.xml +++ b/spring-boot-modules/spring-boot-performance/pom.xml @@ -25,7 +25,7 @@ de.codecentric chaos-monkey-spring-boot - ${chaos.monkey.version} + ${chaos-monkey-spring-boot.version} @@ -48,7 +48,7 @@ com.baeldung.lazyinitialization.Application - 2.0.0 + 2.0.0 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-2/pom.xml b/spring-boot-modules/spring-boot-properties-2/pom.xml index 2c74f7f186..60ee9538c1 100644 --- a/spring-boot-modules/spring-boot-properties-2/pom.xml +++ b/spring-boot-modules/spring-boot-properties-2/pom.xml @@ -30,7 +30,7 @@ commons-lang commons-lang - 2.6 + ${commons-lang.version} diff --git a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java index 72c45afbb2..d7e948ca9a 100644 --- a/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java +++ b/spring-boot-modules/spring-boot-properties/src/main/java/com/baeldung/configurationproperties/ImmutableCredentials.java @@ -1,6 +1,7 @@ package com.baeldung.configurationproperties; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.bind.ConstructorBinding; @ConfigurationProperties(prefix = "mail.credentials") public class ImmutableCredentials { @@ -9,12 +10,19 @@ public class ImmutableCredentials { private final String username; private final String password; + @ConstructorBinding public ImmutableCredentials(String authMethod, String username, String password) { this.authMethod = authMethod; this.username = username; this.password = password; } + public ImmutableCredentials(String username, String password) { + this.username = username; + this.password = password; + this.authMethod = "Default"; + } + public String getAuthMethod() { return authMethod; } diff --git a/spring-boot-modules/spring-boot-react/pom.xml b/spring-boot-modules/spring-boot-react/pom.xml index dc0c6914c9..05ff6811c4 100644 --- a/spring-boot-modules/spring-boot-react/pom.xml +++ b/spring-boot-modules/spring-boot-react/pom.xml @@ -52,11 +52,128 @@ + + + default-jdk9-and-above + + + + com.github.eirslett + frontend-maven-plugin + + + install node + + install-node-and-yarn + + + true + ${node.version} + ${yarn.version} + + + + yarn install + + yarn + + none + + true + + + + yarn test + + yarn + + none + + test + + true + + + + + yarn build + + yarn + + compile + + true + + + + + + + + + integration-jdk9-and-above + + + + com.github.eirslett + frontend-maven-plugin + + + install node + + install-node-and-yarn + + + true + ${node.version} + ${yarn.version} + + + + yarn install + + yarn + + none + + true + + + + yarn test + + yarn + + none + + test + + true + + + + + yarn build + + yarn + + compile + + true + + + + + + + + + maven-resources-plugin - 3.1.0 + ${maven-resources-plugin.version} copy-resources @@ -135,6 +252,7 @@ 11 11 + 3.1.0 1.6 v14.18.0 v1.12.1 diff --git a/spring-boot-modules/spring-boot-redis/pom.xml b/spring-boot-modules/spring-boot-redis/pom.xml index e0ae5d388f..fa6b5a59c1 100644 --- a/spring-boot-modules/spring-boot-redis/pom.xml +++ b/spring-boot-modules/spring-boot-redis/pom.xml @@ -44,13 +44,13 @@ slf4j-simple - 0.7.3 + ${embedded-redis.version} test org.springframework spring-webflux - 6.0.3 + ${spring-webflux.version} test @@ -74,6 +74,8 @@ 15 + 6.0.3 + 0.7.3 diff --git a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/ResilientAppControllerIntegrationTest.java b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/ResilientAppControllerIntegrationTest.java index b4378a9248..a1173f40ae 100644 --- a/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/ResilientAppControllerIntegrationTest.java +++ b/spring-boot-modules/spring-boot-resilience4j/src/test/java/com/baeldung/resilience4j/eventendpoints/ResilientAppControllerIntegrationTest.java @@ -31,9 +31,13 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.annotation.DirtiesContext; +/** + * This was failing as a unit test in integrated environment + * probably due to parallel execution of tests. + */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) -class ResilientAppControllerIntegrationTest { +class ResilientAppControllerManualTest { private final Logger LOGGER = LoggerFactory.getLogger(getClass()); diff --git a/spring-boot-modules/spring-boot-telegram/README.md b/spring-boot-modules/spring-boot-telegram/README.md new file mode 100644 index 0000000000..4cd6560bc0 --- /dev/null +++ b/spring-boot-modules/spring-boot-telegram/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Creating a Telegram Bot with Spring Boot](https://www.baeldung.com/spring-boot-telegram-bot) diff --git a/spring-boot-modules/spring-boot-telegram/pom.xml b/spring-boot-modules/spring-boot-telegram/pom.xml index b960137449..67fdf197f8 100644 --- a/spring-boot-modules/spring-boot-telegram/pom.xml +++ b/spring-boot-modules/spring-boot-telegram/pom.xml @@ -20,12 +20,12 @@ org.telegram telegrambots-spring-boot-starter - 6.7.0 + ${telegrambots.version} org.telegram telegrambots-abilities - 6.7.0 + ${telegrambots.version} @@ -40,6 +40,7 @@ 17 + 6.7.0 diff --git a/spring-boot-modules/spring-boot-testing-2/pom.xml b/spring-boot-modules/spring-boot-testing-2/pom.xml index be8beaf700..f684d7ce97 100644 --- a/spring-boot-modules/spring-boot-testing-2/pom.xml +++ b/spring-boot-modules/spring-boot-testing-2/pom.xml @@ -43,7 +43,7 @@ org.springframework.ws spring-ws-test - 3.1.3 + ${spring-ws-test.version} test @@ -75,7 +75,7 @@ com.redis.testcontainers testcontainers-redis-junit-jupiter - 1.4.6 + ${testcontainers-redis-junit-jupiter.version} test @@ -85,7 +85,7 @@ org.jvnet.jaxb2.maven2 maven-jaxb2-plugin - 0.15.1 + ${maven-jaxb2-plugin.version} xjc @@ -107,8 +107,11 @@ com.baeldung.boot.Application + 3.1.3 1.17.2 1.10.0 + 1.4.6 + 0.15.1 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-spock/pom.xml b/spring-boot-modules/spring-boot-testing-spock/pom.xml index c82d88ccfb..db78143cb8 100644 --- a/spring-boot-modules/spring-boot-testing-spock/pom.xml +++ b/spring-boot-modules/spring-boot-testing-spock/pom.xml @@ -96,7 +96,6 @@ com.baeldung.boot.Application 2.4-M1-groovy-4.0 3.0.0 - 3.10.1 2.17.1 diff --git a/spring-boot-modules/spring-boot-testing/pom.xml b/spring-boot-modules/spring-boot-testing/pom.xml index 2098ac767d..257260fc3f 100644 --- a/spring-boot-modules/spring-boot-testing/pom.xml +++ b/spring-boot-modules/spring-boot-testing/pom.xml @@ -64,7 +64,7 @@ it.ozimov embedded-redis - ${redis.version} + ${embedded-redis.version} test @@ -121,8 +121,7 @@ 2.2.4 2.4-M1-groovy-4.0 3.0.0 - 3.10.1 - 0.7.2 + 0.7.2 2.5.0 2.17.1 diff --git a/spring-boot-modules/spring-caching/pom.xml b/spring-boot-modules/spring-caching/pom.xml index 7f68dbf3ec..c27ccf3348 100644 --- a/spring-boot-modules/spring-caching/pom.xml +++ b/spring-boot-modules/spring-caching/pom.xml @@ -78,7 +78,6 @@ 3.5.2 - 1.18.26 \ No newline at end of file diff --git a/spring-boot-rest/pom.xml b/spring-boot-rest/pom.xml index 74d46f0651..db646899ad 100644 --- a/spring-boot-rest/pom.xml +++ b/spring-boot-rest/pom.xml @@ -134,7 +134,7 @@ io.rest-assured rest-assured - 3.3.0 + ${rest-assured.version} provided @@ -163,7 +163,7 @@ com.baeldung.SpringBootRestApplication 1.4.11.1 3.1.0 - 3.3.2 + 3.3.0 2.3.7 diff --git a/spring-cloud-modules/spring-cloud-zuul-fallback/pom.xml b/spring-cloud-modules/spring-cloud-zuul-fallback/pom.xml index ff62a99a00..fcf216cd6e 100644 --- a/spring-cloud-modules/spring-cloud-zuul-fallback/pom.xml +++ b/spring-cloud-modules/spring-cloud-zuul-fallback/pom.xml @@ -22,7 +22,6 @@ 2020.0.3 2.2.7.RELEASE - 3.1.1 \ No newline at end of file diff --git a/spring-core-4/pom.xml b/spring-core-4/pom.xml index 492a2ec5a2..2d11cc701b 100644 --- a/spring-core-4/pom.xml +++ b/spring-core-4/pom.xml @@ -84,7 +84,6 @@ 4.0.2 4.0.0 1.3.2 - 3.3.2 1.10.0 diff --git a/spring-core/pom.xml b/spring-core/pom.xml index d1c155b92a..e369bc24d0 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -88,7 +88,6 @@ 1.5.2.RELEASE 1.10.19 1.3.2 - 3.3.2 \ No newline at end of file diff --git a/spring-di/pom.xml b/spring-di/pom.xml index cf3703096c..af0601deb6 100644 --- a/spring-di/pom.xml +++ b/spring-di/pom.xml @@ -149,7 +149,6 @@ 1.5.2.RELEASE 1.10.19 1.9.5 - 3.3.2 \ No newline at end of file diff --git a/spring-ejb-modules/pom.xml b/spring-ejb-modules/pom.xml index c5d04dab25..bb4fe87a6d 100755 --- a/spring-ejb-modules/pom.xml +++ b/spring-ejb-modules/pom.xml @@ -17,10 +17,10 @@ - + spring-ejb-remote spring-ejb-client - wildfly + wildfly-mdb @@ -76,6 +76,7 @@ 12.0.0.Final 2.4 3.2 + 7.0 \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-mdb/README.md b/spring-ejb-modules/wildfly-mdb/README.md similarity index 100% rename from spring-ejb-modules/wildfly/wildfly-mdb/README.md rename to spring-ejb-modules/wildfly-mdb/README.md diff --git a/spring-ejb-modules/wildfly/wildfly-mdb/pom.xml b/spring-ejb-modules/wildfly-mdb/pom.xml similarity index 82% rename from spring-ejb-modules/wildfly/wildfly-mdb/pom.xml rename to spring-ejb-modules/wildfly-mdb/pom.xml index 0784725cde..7498379ef9 100644 --- a/spring-ejb-modules/wildfly/wildfly-mdb/pom.xml +++ b/spring-ejb-modules/wildfly-mdb/pom.xml @@ -7,9 +7,9 @@ wildfly-mdb - com.baeldung.wildfly - wildfly - 0.0.1-SNAPSHOT + com.baeldung.spring.ejb + spring-ejb-modules + 1.0.0-SNAPSHOT diff --git a/spring-ejb-modules/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java b/spring-ejb-modules/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java similarity index 100% rename from spring-ejb-modules/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java rename to spring-ejb-modules/wildfly-mdb/src/com/baeldung/wildfly/mdb/ReadMessageMDB.java diff --git a/spring-ejb-modules/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java b/spring-ejb-modules/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java similarity index 100% rename from spring-ejb-modules/wildfly/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java rename to spring-ejb-modules/wildfly-mdb/src/com/baeldung/wildfly/mdb/SendMessageServlet.java diff --git a/spring-ejb-modules/wildfly/pom.xml b/spring-ejb-modules/wildfly/pom.xml deleted file mode 100644 index f122e99001..0000000000 --- a/spring-ejb-modules/wildfly/pom.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - 4.0.0 - com.baeldung.wildfly - wildfly - 0.0.1-SNAPSHOT - wildfly - pom - - - com.baeldung.spring.ejb - spring-ejb-modules - 1.0.0-SNAPSHOT - - - - widlfly-web - wildfly-ear - wildfly-jpa - wildfly-ejb-interfaces - wildfly-ejb - wildfly-mdb - - - - - - - - javax - javaee-api - ${javaee-api.version} - provided - - - - org.wildfly.bom - wildfly-javaee7 - ${wildfly-javaee7.version} - import - pom - - - - org.hibernate - hibernate-core - ${hibernate-core.version} - provided - - - - com.baeldung.wildfly - wildlfy-ear - ${wildlfy.version} - ear - - - - com.baeldung.wildfly - wildlfy-web - ${wildlfy.version} - war - - - - com.baeldung.wildfly - wildlfy-jpa - ${wildlfy.version} - - - - com.baeldung.wildfly - wildfly-ejb - ${wildlfy.version} - - - - com.baeldung.wildfly - wildfly-ejb-interfaces - ${wildlfy.version} - - - - - - 7.0 - 10.1.0.Final - 5.2.3.Final - 0.0.1-SNAPSHOT - - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/widlfly-web/pom.xml b/spring-ejb-modules/wildfly/widlfly-web/pom.xml deleted file mode 100644 index 46c3f7d0bc..0000000000 --- a/spring-ejb-modules/wildfly/widlfly-web/pom.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - 4.0.0 - widlfly-web - widlfly-web - war - - - com.baeldung.wildfly - wildfly - 0.0.1-SNAPSHOT - - - - - - javax - javaee-api - ${javaee-api.version} - provided - - - - com.baeldung.wildfly - wildfly-jpa - ${wildlfy.version} - - - - com.baeldung.wildfly - wildfly-ejb-interfaces - ${wildlfy.version} - - - - com.baeldung.wildfly - wildfly-ejb - ${wildlfy.version} - - - - - 3.3.2 - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/widlfly-web/src/main/java/TestEJBServlet.java b/spring-ejb-modules/wildfly/widlfly-web/src/main/java/TestEJBServlet.java deleted file mode 100644 index 57376e9c4a..0000000000 --- a/spring-ejb-modules/wildfly/widlfly-web/src/main/java/TestEJBServlet.java +++ /dev/null @@ -1,41 +0,0 @@ - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.List; - -import javax.ejb.EJB; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import model.User; -import wildfly.beans.UserBeanLocal; - -/** - * Servlet implementation class TestEJBServlet - */ -public class TestEJBServlet extends HttpServlet { - - @EJB - private UserBeanLocal userBean; - - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - List users = userBean.getUsers(); - - PrintWriter out = response.getWriter(); - - out.println(""); - out.println(""); - for (User user : users) { - out.print(user.getUsername()); - out.print(" " + user.getEmail() + "
"); - } - out.println(""); - out.println(""); - } - - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - doGet(request, response); - } -} diff --git a/spring-ejb-modules/wildfly/widlfly-web/src/main/java/TestJPAServlet.java b/spring-ejb-modules/wildfly/widlfly-web/src/main/java/TestJPAServlet.java deleted file mode 100644 index 609366c53a..0000000000 --- a/spring-ejb-modules/wildfly/widlfly-web/src/main/java/TestJPAServlet.java +++ /dev/null @@ -1,54 +0,0 @@ - -import java.io.IOException; -import java.util.List; - -import javax.annotation.Resource; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.Query; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.transaction.UserTransaction; - -import model.User; - -/** - * Servlet implementation class TestJPAServlet - */ -public class TestJPAServlet extends HttpServlet { - private static final long serialVersionUID = 1L; - @PersistenceContext(unitName = "wildfly-jpa") - EntityManager em; - - @Resource - UserTransaction tx; - - /** - * @see HttpServlet#HttpServlet() - */ - public TestJPAServlet() { - super(); - // TODO Auto-generated constructor stub - } - - /** - * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) - */ - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - Query q = em.createNamedQuery("User.findAll"); - List users = q.getResultList(); - response.getWriter() - .append("JPA users returned: " + users.size()); - } - - /** - * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) - */ - protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - // TODO Auto-generated method stub - doGet(request, response); - } - -} diff --git a/spring-ejb-modules/wildfly/widlfly-web/src/main/resources/logback.xml b/spring-ejb-modules/wildfly/widlfly-web/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-ejb-modules/wildfly/widlfly-web/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/widlfly-web/src/main/webapp/WEB-INF/web.xml b/spring-ejb-modules/wildfly/widlfly-web/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 5b3f664443..0000000000 --- a/spring-ejb-modules/wildfly/widlfly-web/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - widlfly-web - - index.html - index.htm - index.jsp - default.html - default.htm - default.jsp - - - - TestJPAServlet - TestJPAServlet - TestJPAServlet - - - TestJPAServlet - /TestJPAServlet - - - - TestEJBServlet - TestEJBServlet - TestEJBServlet - - - TestEJBServlet - /TestEJBServlet - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-ear/pom.xml b/spring-ejb-modules/wildfly/wildfly-ear/pom.xml deleted file mode 100644 index da321cb9eb..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-ear/pom.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - 4.0.0 - wildfly-ear - wildfly-ear - ear - - - com.baeldung.wildfly - wildfly - 0.0.1-SNAPSHOT - - - - - - com.baeldung.wildfly - widlfly-web - ${wildlfy.version} - war - - - - com.baeldung.wildfly - wildfly-jpa - ${wildlfy.version} - - - - com.baeldung.wildfly - wildfly-ejb - - - - com.baeldung.wildfly - wildfly-ejb-interfaces - - - - - - - maven-ear-plugin - ${maven-ear-plugin.version} - - lib/ - ${defaultLibBundleDir.version} - - - com.baeldung.wildfly - widlfly-web - /wildfly - - - - - - org.wildfly.plugins - wildfly-maven-plugin - ${wildfly-maven-plugin.version} - - - - - - 2.10.1 - 1.2.0.Final - 7 - - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/pom.xml b/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/pom.xml deleted file mode 100644 index bc9159b667..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/pom.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - 4.0.0 - wildfly-ejb-interfaces - wildfly-ejb-interfaces - - - com.baeldung.wildfly - wildfly - 0.0.1-SNAPSHOT - - - - - - javax.ejb - javax.ejb-api - ${javax.ejb-api.version} - provided - - - - com.baeldung.wildfly - wildfly-jpa - ${wildlfy.version} - - - - - 3.2 - - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanLocal.java b/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanLocal.java deleted file mode 100644 index 16930cb5b9..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanLocal.java +++ /dev/null @@ -1,13 +0,0 @@ -package wildfly.beans; - -import java.util.List; - -import javax.ejb.Local; - -import model.User; - -@Local -public interface UserBeanLocal { - - List getUsers(); -} diff --git a/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanRemote.java b/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanRemote.java deleted file mode 100644 index 5b57d4283f..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/src/main/java/wildfly/beans/UserBeanRemote.java +++ /dev/null @@ -1,13 +0,0 @@ -package wildfly.beans; - -import java.util.List; - -import javax.ejb.Remote; - -import model.User; - -@Remote -public interface UserBeanRemote { - - List getUsers(); -} diff --git a/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/src/main/resources/logback.xml b/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-ejb-interfaces/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-ejb/pom.xml b/spring-ejb-modules/wildfly/wildfly-ejb/pom.xml deleted file mode 100644 index 36574bf984..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-ejb/pom.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - 4.0.0 - wildfly-ejb - wildfly-ejb - ejb - - - com.baeldung.wildfly - wildfly - 0.0.1-SNAPSHOT - - - - - - javax.ejb - javax.ejb-api - ${ejb.version} - provided - - - - javax - javaee-api - provided - - - - org.hibernate - hibernate-core - - - - com.baeldung.wildfly - wildfly-ejb-interfaces - - - - - - - org.apache.maven.plugins - maven-ejb-plugin - - ${ejb.version} - - - - - - - 3.2 - - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-ejb/src/main/java/wildfly/beans/UserBean.java b/spring-ejb-modules/wildfly/wildfly-ejb/src/main/java/wildfly/beans/UserBean.java deleted file mode 100644 index 07e3cbcb32..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-ejb/src/main/java/wildfly/beans/UserBean.java +++ /dev/null @@ -1,24 +0,0 @@ -package wildfly.beans; - -import java.util.List; - -import javax.ejb.Stateless; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; - -import model.User; - -/** - * Session Bean implementation class UserBean - */ -@Stateless -public class UserBean implements UserBeanRemote, UserBeanLocal { - @PersistenceContext(unitName = "wildfly-jpa") - private EntityManager em; - - @Override - public List getUsers() { - return em.createNamedQuery("User.findAll") - .getResultList(); - } -} diff --git a/spring-ejb-modules/wildfly/wildfly-ejb/src/main/resources/logback.xml b/spring-ejb-modules/wildfly/wildfly-ejb/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-ejb/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-jpa/pom.xml b/spring-ejb-modules/wildfly/wildfly-jpa/pom.xml deleted file mode 100644 index 603e337510..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-jpa/pom.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - 4.0.0 - wildfly-jpa - wildfly-jpa - - - com.baeldung.wildfly - wildfly - 0.0.1-SNAPSHOT - - - - - - - org.hibernate - hibernate-core - provided - - - - \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-jpa/src/main/java/model/User.java b/spring-ejb-modules/wildfly/wildfly-jpa/src/main/java/model/User.java deleted file mode 100644 index 3a3f95bf8c..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-jpa/src/main/java/model/User.java +++ /dev/null @@ -1,51 +0,0 @@ -package model; - -import java.io.Serializable; -import javax.persistence.*; - -/** - * The persistent class for the users database table. - * - */ -@Entity -@Table(name = "users") -@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u") -public class User implements Serializable { - private static final long serialVersionUID = 1L; - - @Id - private String username; - - private String email; - - @Column(name = "postal_number") - private Integer postalNumber; - - public User() { - } - - public String getUsername() { - return this.username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getEmail() { - return this.email; - } - - public void setEmail(String email) { - this.email = email; - } - - public Integer getPostalNumber() { - return this.postalNumber; - } - - public void setPostalNumber(Integer postalNumber) { - this.postalNumber = postalNumber; - } - -} \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-jpa/src/main/resources/META-INF/persistence.xml b/spring-ejb-modules/wildfly/wildfly-jpa/src/main/resources/META-INF/persistence.xml deleted file mode 100644 index 2aa6bc2cd7..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-jpa/src/main/resources/META-INF/persistence.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - java:/H2DS - model.User - - - - - - - - diff --git a/spring-ejb-modules/wildfly/wildfly-jpa/src/main/resources/data.sql b/spring-ejb-modules/wildfly/wildfly-jpa/src/main/resources/data.sql deleted file mode 100644 index 03eafa534e..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-jpa/src/main/resources/data.sql +++ /dev/null @@ -1 +0,0 @@ -INSERT INTO users (username, email, postal_number) VALUES ('user1', 'user1@baeldung.com', 1000), ('user2', 'user2@baeldung.com', 2); \ No newline at end of file diff --git a/spring-ejb-modules/wildfly/wildfly-jpa/src/main/resources/logback.xml b/spring-ejb-modules/wildfly/wildfly-jpa/src/main/resources/logback.xml deleted file mode 100644 index 7d900d8ea8..0000000000 --- a/spring-ejb-modules/wildfly/wildfly-jpa/src/main/resources/logback.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - \ No newline at end of file diff --git a/spring-exceptions/pom.xml b/spring-exceptions/pom.xml index 8912cad674..49c44f88f2 100644 --- a/spring-exceptions/pom.xml +++ b/spring-exceptions/pom.xml @@ -181,7 +181,6 @@ 2.7 1.6.1 - 3.3.2 \ No newline at end of file diff --git a/spring-jersey/pom.xml b/spring-jersey/pom.xml index 17d527ca6a..32f75aa676 100644 --- a/spring-jersey/pom.xml +++ b/spring-jersey/pom.xml @@ -221,7 +221,6 @@ 4.5.5 2.27.2 1.5.10.RELEASE - 3.3.2 \ No newline at end of file diff --git a/spring-katharsis/pom.xml b/spring-katharsis/pom.xml index 82be0555c3..b836a42bca 100644 --- a/spring-katharsis/pom.xml +++ b/spring-katharsis/pom.xml @@ -135,7 +135,6 @@ 3.0.2 0.9.10 1.6.1 - 3.3.2 \ No newline at end of file diff --git a/spring-mobile/pom.xml b/spring-mobile/pom.xml index 0c279c0d62..f810159eb7 100644 --- a/spring-mobile/pom.xml +++ b/spring-mobile/pom.xml @@ -46,9 +46,6 @@ ${maven.compiler.source} ${maven.compiler.target} - - --add-exports=java.base/jdk.internal.vm.annotation=ALL-UNNAMED -
@@ -58,7 +55,6 @@ 1.1.5.RELEASE 11 11 - 3.3.2 \ No newline at end of file diff --git a/spring-pulsar/pom.xml b/spring-pulsar/pom.xml index 4c2fc0d9b4..df1959c84e 100644 --- a/spring-pulsar/pom.xml +++ b/spring-pulsar/pom.xml @@ -1,6 +1,7 @@ - + 4.0.0 spring-pulsar 0.0.1-SNAPSHOT diff --git a/spring-reactive-modules/spring-5-data-reactive-2/pom.xml b/spring-reactive-modules/spring-5-data-reactive-2/pom.xml index e5447ac038..3d88e672eb 100644 --- a/spring-reactive-modules/spring-5-data-reactive-2/pom.xml +++ b/spring-reactive-modules/spring-5-data-reactive-2/pom.xml @@ -1,7 +1,7 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-5-data-reactive-2 spring-5-data-reactive-2 @@ -13,7 +13,6 @@ 1.0.0-SNAPSHOT - 8 8 diff --git a/spring-reactive-modules/spring-reactive/pom.xml b/spring-reactive-modules/spring-reactive/pom.xml index 2281e6b0b4..f19809e302 100644 --- a/spring-reactive-modules/spring-reactive/pom.xml +++ b/spring-reactive-modules/spring-reactive/pom.xml @@ -6,9 +6,10 @@ spring-reactive - com.baeldung.spring.reactive - spring-reactive-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -90,6 +91,18 @@ + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + 3.4.16 1.3.10 diff --git a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/ConsumerDebuggingApplication.java b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/ConsumerDebuggingApplication.java index fa10383c95..9cb8cdf003 100644 --- a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/ConsumerDebuggingApplication.java +++ b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/debugging/consumer/ConsumerDebuggingApplication.java @@ -24,10 +24,10 @@ public class ConsumerDebuggingApplication { @Bean public SecurityWebFilterChain debuggingConsumerSpringSecurityFilterChain(ServerHttpSecurity http) { - http.authorizeExchange() - .anyExchange() - .permitAll(); - http.csrf().disable(); + http.authorizeExchange(exchanges -> exchanges + .anyExchange() + .permitAll()); + http.csrf(csrf -> csrf.disable()); return http.build(); } } diff --git a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/debugging/server/ServerDebuggingApplication.java b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/debugging/server/ServerDebuggingApplication.java index ddf97ee5a8..d836a892aa 100644 --- a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/debugging/server/ServerDebuggingApplication.java +++ b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/debugging/server/ServerDebuggingApplication.java @@ -22,9 +22,9 @@ public class ServerDebuggingApplication { @Bean public SecurityWebFilterChain debuggingServerSpringSecurityFilterChain(ServerHttpSecurity http) { - http.authorizeExchange() - .anyExchange() - .permitAll(); + http.authorizeExchange(exchanges -> exchanges + .anyExchange() + .permitAll()); return http.build(); } } diff --git a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SecurityConfig.java b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SecurityConfig.java index 67e54ad26a..69683452cd 100644 --- a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SecurityConfig.java +++ b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SecurityConfig.java @@ -1,6 +1,7 @@ package com.baeldung.reactive.security; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; @@ -12,18 +13,19 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.server.SecurityWebFilterChain; @EnableWebFluxSecurity +@Configuration @EnableReactiveMethodSecurity public class SecurityConfig { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { - return http.authorizeExchange() - .pathMatchers("/admin").hasAuthority("ROLE_ADMIN") - .anyExchange().authenticated() - .and() - .formLogin() - .and() - .csrf().disable() + return http + .authorizeExchange(exchanges -> exchanges + .pathMatchers("/admin").hasAuthority("ROLE_ADMIN") + .anyExchange().authenticated()) + .formLogin(formLogin -> formLogin + .loginPage("/login")) + .csrf(csrf -> csrf.disable()) .build(); } diff --git a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SpringSecurity5Application.java b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SpringSecurity6Application.java similarity index 94% rename from spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SpringSecurity5Application.java rename to spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SpringSecurity6Application.java index bc0895a38b..4b20c678b5 100644 --- a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SpringSecurity5Application.java +++ b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/security/SpringSecurity6Application.java @@ -13,11 +13,11 @@ import reactor.netty.http.server.HttpServer; @ComponentScan(basePackages = {"com.baeldung.reactive.security"}) @EnableWebFlux -public class SpringSecurity5Application { +public class SpringSecurity6Application { public static void main(String[] args) { try (AnnotationConfigApplicationContext context = - new AnnotationConfigApplicationContext(SpringSecurity5Application.class)) { + new AnnotationConfigApplicationContext(SpringSecurity6Application.class)) { context.getBean(DisposableServer.class).onDispose().block(); } } diff --git a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientApplication.java b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientApplication.java index 3a62e7b8a5..c756f43893 100644 --- a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientApplication.java +++ b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webclient/WebClientApplication.java @@ -16,9 +16,8 @@ public class WebClientApplication { @Bean public SecurityWebFilterChain filterChain(ServerHttpSecurity http) { - http.csrf().disable() - .authorizeExchange() - .anyExchange().permitAll(); + http.csrf(csrf -> csrf.disable()) + .authorizeExchange(exchanges -> exchanges.anyExchange().permitAll()); return http.build(); } } diff --git a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebSecurityConfig.java b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebSecurityConfig.java index fc98b70c0f..67c10e12a2 100644 --- a/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebSecurityConfig.java +++ b/spring-reactive-modules/spring-reactive/src/main/java/com/baeldung/reactive/webflux/annotation/EmployeeWebSecurityConfig.java @@ -1,7 +1,9 @@ package com.baeldung.reactive.webflux.annotation; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; @@ -12,6 +14,7 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.server.SecurityWebFilterChain; @EnableWebFluxSecurity +@Configuration public class EmployeeWebSecurityConfig { @Bean @@ -27,12 +30,11 @@ public class EmployeeWebSecurityConfig { @Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { http - .csrf().disable() - .authorizeExchange() + .csrf(csrf -> csrf.disable()) + .authorizeExchange(exchanges -> exchanges .pathMatchers(HttpMethod.POST, "/employees/update").hasRole("ADMIN") - .pathMatchers("/**").permitAll() - .and() - .httpBasic(); + .pathMatchers("/**").permitAll()) + .httpBasic(Customizer.withDefaults()); return http.build(); } diff --git a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/security/SecurityIntegrationTest.java b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/security/SecurityIntegrationTest.java index 6bf39e4791..161c739ffb 100644 --- a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/security/SecurityIntegrationTest.java +++ b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/security/SecurityIntegrationTest.java @@ -8,7 +8,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.reactive.server.WebTestClient; -@SpringBootTest(classes = SpringSecurity5Application.class) +@SpringBootTest(classes = SpringSecurity6Application.class) class SecurityIntegrationTest { @Autowired diff --git a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java index aaecb6498c..f109ab4887 100644 --- a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java +++ b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebClientIntegrationTest.java @@ -7,7 +7,7 @@ import io.netty.handler.timeout.WriteTimeoutHandler; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.codec.CodecException; import org.springframework.http.HttpHeaders; diff --git a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebControllerIntegrationTest.java b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebControllerIntegrationTest.java index f4d2f4384f..9274f836e6 100644 --- a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebControllerIntegrationTest.java +++ b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebControllerIntegrationTest.java @@ -5,7 +5,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebTestClientIntegrationTest.java b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebTestClientIntegrationTest.java index 6c7433dfe3..d476fb1e9a 100644 --- a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebTestClientIntegrationTest.java +++ b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclient/WebTestClientIntegrationTest.java @@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.ApplicationContext; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java index 3e09521e04..bf407dbbf7 100644 --- a/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java +++ b/spring-reactive-modules/spring-reactive/src/test/java/com/baeldung/reactive/webclientrequests/WebClientRequestsWithParametersUnitTest.java @@ -14,10 +14,7 @@ import org.springframework.web.util.DefaultUriBuilderFactory; import reactor.core.publisher.Mono; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @WebFluxTest class WebClientRequestsWithParametersUnitTest { @@ -51,6 +48,7 @@ class WebClientRequestsWithParametersUnitTest { .uri("/products") .retrieve() .bodyToMono(String.class) + .onErrorResume(e -> Mono.empty()) .block(); verifyCalledUrl("/products"); @@ -64,6 +62,7 @@ class WebClientRequestsWithParametersUnitTest { .build(2)) .retrieve() .bodyToMono(String.class) + .onErrorResume(e -> Mono.empty()) .block(); verifyCalledUrl("/products/2"); @@ -77,6 +76,7 @@ class WebClientRequestsWithParametersUnitTest { .build(2, 13)) .retrieve() .bodyToMono(String.class) + .onErrorResume(e -> Mono.empty()) .block(); verifyCalledUrl("/products/2/attributes/13"); @@ -93,6 +93,7 @@ class WebClientRequestsWithParametersUnitTest { .build()) .retrieve() .bodyToMono(String.class) + .onErrorResume(e -> Mono.empty()) .block(); verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019"); @@ -109,6 +110,7 @@ class WebClientRequestsWithParametersUnitTest { .build("AndroidPhone", "black", "13/04/2019")) .retrieve() .bodyToMono(String.class) + .onErrorResume(e -> Mono.empty()) .block(); verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13%2F04%2F2019"); @@ -123,6 +125,7 @@ class WebClientRequestsWithParametersUnitTest { .build()) .retrieve() .bodyToMono(String.class) + .onErrorResume(e -> Mono.empty()) .block(); verifyCalledUrl("/products/?tag%5B%5D=Snapdragon&tag%5B%5D=NFC"); @@ -137,6 +140,7 @@ class WebClientRequestsWithParametersUnitTest { .build()) .retrieve() .bodyToMono(String.class) + .onErrorResume(e -> Mono.empty()) .block(); verifyCalledUrl("/products/?category=Phones&category=Tablets"); @@ -151,6 +155,7 @@ class WebClientRequestsWithParametersUnitTest { .build()) .retrieve() .bodyToMono(String.class) + .onErrorResume(e -> Mono.empty()) .block(); verifyCalledUrl("/products/?category=Phones,Tablets"); @@ -176,6 +181,7 @@ class WebClientRequestsWithParametersUnitTest { .build()) .retrieve() .bodyToMono(String.class) + .onErrorResume(e -> Mono.empty()) .block(); verifyCalledUrl("/products/?name=AndroidPhone&color=black&deliveryDate=13/04/2019"); diff --git a/spring-security-modules/spring-security-web-mvc-custom/pom.xml b/spring-security-modules/spring-security-web-mvc-custom/pom.xml index f21c6dbe40..41f24050b2 100644 --- a/spring-security-modules/spring-security-web-mvc-custom/pom.xml +++ b/spring-security-modules/spring-security-web-mvc-custom/pom.xml @@ -172,7 +172,6 @@ - 3.2.2 1.6.1 1.3.2 diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController3.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationController.java similarity index 89% rename from spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController3.java rename to spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationController.java index 2dcb98286b..4f9b24cf36 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController3.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationController.java @@ -8,9 +8,9 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller -public class SecurityController3 { +public class GetUserWithAuthenticationController { - public SecurityController3() { + public GetUserWithAuthenticationController() { super(); } diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController4.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationPrincipalAnnotationController.java similarity index 87% rename from spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController4.java rename to spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationPrincipalAnnotationController.java index 93a2bfcacd..912b4c178c 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController4.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithAuthenticationPrincipalAnnotationController.java @@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController -public class SecurityController4 { +public class GetUserWithAuthenticationPrincipalAnnotationController { @GetMapping("/user") public String getUser(@AuthenticationPrincipal UserDetails userDetails) { diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithPrincipalController.java similarity index 85% rename from spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController.java rename to spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithPrincipalController.java index ece442430f..ed3ea5b25d 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithPrincipalController.java @@ -8,9 +8,9 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller -public class SecurityController { +public class GetUserWithPrincipalController { - public SecurityController() { + public GetUserWithPrincipalController() { super(); } diff --git a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController1.java b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithSecurityContextHolderController.java similarity index 92% rename from spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController1.java rename to spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithSecurityContextHolderController.java index 1951e04dcb..c63271ef77 100644 --- a/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/SecurityController1.java +++ b/spring-security-modules/spring-security-web-rest-custom/src/main/java/com/baeldung/web/controller/GetUserWithSecurityContextHolderController.java @@ -11,12 +11,12 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller -public class SecurityController1 { +public class GetUserWithSecurityContextHolderController { @Autowired private ApplicationEventPublisher eventPublisher; - public SecurityController1() { + public GetUserWithSecurityContextHolderController() { super(); } diff --git a/spring-shell/pom.xml b/spring-shell/pom.xml index 506884b413..952920fd1e 100644 --- a/spring-shell/pom.xml +++ b/spring-shell/pom.xml @@ -39,7 +39,6 @@ 1.2.0.RELEASE - 3.3.2 \ No newline at end of file diff --git a/spring-vault/pom.xml b/spring-vault/pom.xml index 7b89db2302..60a5ee18f2 100644 --- a/spring-vault/pom.xml +++ b/spring-vault/pom.xml @@ -51,10 +51,36 @@ spring-boot-starter-test test + + + ch.qos.logback + logback-classic + + + ch.qos.logback + logback-core + + + + org.slf4j + slf4j-api + + + + software.amazon.awssdk + auth + 2.20.140 + + + + org.springframework.cloud + spring-cloud-starter-vault-config + 3.1.3 + - 3.0.2 + 2.3.4 17 diff --git a/spring-vault/src/main/java/com/baeldung/springcloudvault/SpringCloudVaultTestApplication.java b/spring-vault/src/main/java/com/baeldung/springcloudvault/SpringCloudVaultTestApplication.java new file mode 100644 index 0000000000..cea416005d --- /dev/null +++ b/spring-vault/src/main/java/com/baeldung/springcloudvault/SpringCloudVaultTestApplication.java @@ -0,0 +1,25 @@ +package com.baeldung.springcloudvault; + + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; +import org.springframework.util.Assert; + +@SpringBootApplication +public class SpringCloudVaultTestApplication { + public static void main(String... args) { + SpringApplication.run(SpringCloudVaultTestApplication.class, args); + } + + @Bean + CommandLineRunner listSecrets(Environment env) { + return args -> { + var foo = env.getProperty("foo"); + Assert.notNull(foo, "foo must have a value"); + System.out.println("foo=" + foo); + }; + } +} diff --git a/spring-vault/src/main/java/com/baeldung/springvaultk8s/VaultConfig.java b/spring-vault/src/main/java/com/baeldung/springvaultk8s/VaultConfig.java new file mode 100644 index 0000000000..407e324a87 --- /dev/null +++ b/spring-vault/src/main/java/com/baeldung/springvaultk8s/VaultConfig.java @@ -0,0 +1,25 @@ +package com.baeldung.springvaultk8s; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.vault.authentication.ClientAuthentication; +import org.springframework.vault.authentication.KubernetesAuthentication; +import org.springframework.vault.authentication.KubernetesAuthenticationOptions; +import org.springframework.vault.client.VaultEndpoint; +import org.springframework.vault.config.AbstractVaultConfiguration; +import org.springframework.vault.config.EnvironmentVaultConfiguration; +import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestTemplate; + +import java.net.URI; +import java.net.URISyntaxException; + +@Configuration +@PropertySource("vault-config-k8s.properties") +@Import(EnvironmentVaultConfiguration.class) +public class VaultConfig { + +} diff --git a/spring-vault/src/main/java/com/baeldung/springvaultk8s/VaultK8SApplication.java b/spring-vault/src/main/java/com/baeldung/springvaultk8s/VaultK8SApplication.java new file mode 100644 index 0000000000..a61b67bf6e --- /dev/null +++ b/spring-vault/src/main/java/com/baeldung/springvaultk8s/VaultK8SApplication.java @@ -0,0 +1,45 @@ +package com.baeldung.springvaultk8s; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; +import org.springframework.vault.core.VaultKeyValueOperations; +import org.springframework.vault.core.VaultKeyValueOperationsSupport; +import org.springframework.vault.core.VaultTemplate; + +import java.util.List; +import java.util.Map; + +@SpringBootApplication +public class VaultK8SApplication { + + public static void main(String... args) { + SpringApplication.run(VaultK8SApplication.class, args); + } + + @Bean + CommandLineRunner listSecrets(VaultTemplate vault) { + + return args -> { + VaultKeyValueOperations ops = vault.opsForKeyValue("secrets", VaultKeyValueOperationsSupport.KeyValueBackend.KV_2); + List secrets = ops.list(""); + if (secrets == null) { + System.out.println("No secrets found"); + return; + } + + secrets.forEach(s -> { + System.out.println("secret=" + s); + var response = ops.get(s); + var data = response.getRequiredData(); + + data.entrySet() + .forEach(e -> { + System.out.println("- key=" + e.getKey() + " => " + e.getValue()); + }); + }); + }; + } +} diff --git a/spring-vault/src/main/k8s/vault-csi-example.yaml b/spring-vault/src/main/k8s/vault-csi-example.yaml new file mode 100644 index 0000000000..8136554033 --- /dev/null +++ b/spring-vault/src/main/k8s/vault-csi-example.yaml @@ -0,0 +1,51 @@ +--- +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: baeldung-csi-secrets + namespace: baeldung +spec: + # Vault CSI Provider + provider: vault + parameters: + # Vault role name to use during login + roleName: 'baeldung-test-role' + objects: | + - objectName: 'baeldung.properties' + secretPath: "secrets/data/baeldung-test" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-csi + namespace: baeldung +spec: + selector: + matchLabels: + app: nginx-csi + replicas: 1 # tells deployment to run 2 pods matching the template + template: + metadata: + labels: + app: nginx-csi + spec: + serviceAccountName: vault-test-sa + automountServiceAccountToken: true + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 + volumeMounts: + - name: vault-secrets + mountPath: /vault/secrets + readOnly: true + volumes: + - name: vault-secrets + csi: + driver: 'secrets-store.csi.k8s.io' + readOnly: true + volumeAttributes: + secretProviderClass: baeldung-csi-secrets + + diff --git a/spring-vault/src/main/k8s/vault-injector-example.yaml b/spring-vault/src/main/k8s/vault-injector-example.yaml new file mode 100644 index 0000000000..4d0aad70a1 --- /dev/null +++ b/spring-vault/src/main/k8s/vault-injector-example.yaml @@ -0,0 +1,32 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + namespace: baeldung +spec: + selector: + matchLabels: + app: nginx + replicas: 1 # tells deployment to run 2 pods matching the template + template: + metadata: + labels: + app: nginx + annotations: + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/agent-inject-secret-baeldung.properties: "secrets/baeldung-test" + vault.hashicorp.com/role: "baeldung-test-role" + vault.hashicorp.com/agent-inject-template-baeldung.properties: | + {{- with secret "secrets/baeldung-test" -}} + {{- range $k, $v := .Data.data }} + {{$k}}={{$v}} + {{- end -}} + {{ end }} + spec: + serviceAccountName: vault-test-sa + automountServiceAccountToken: true + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 diff --git a/spring-vault/src/main/k8s/vault-operator-example.yaml b/spring-vault/src/main/k8s/vault-operator-example.yaml new file mode 100644 index 0000000000..a77888905d --- /dev/null +++ b/spring-vault/src/main/k8s/vault-operator-example.yaml @@ -0,0 +1,58 @@ +--- +## +## Vault Connection +## +apiVersion: secrets.hashicorp.com/v1beta1 +kind: VaultConnection +metadata: + namespace: baeldung + name: vault-local +spec: + # required configuration + # address to the Vault server. + address: http://vault.vault.svc.cluster.local:8200 +--- +## +## Vault Auth +## +apiVersion: secrets.hashicorp.com/v1beta1 +kind: VaultAuth +metadata: + namespace: baeldung + name: baeldung-test +spec: + # required configuration + # VaultConnectionRef of the corresponding VaultConnection CustomResource. + # If no value is specified the Operator will default to the `default` VaultConnection, + # configured in its own Kubernetes namespace. + vaultConnectionRef: vault-local + # Method to use when authenticating to Vault. + method: kubernetes + # Mount to use when authenticating to auth method. + mount: kubernetes + # Kubernetes specific auth configuration, requires that the Method be set to kubernetes. + kubernetes: + # role to use when authenticating to Vault + role: baeldung-test-role + # ServiceAccount to use when authenticating to Vault + # it is recommended to always provide a unique serviceAccount per Pod/application + serviceAccount: vault-test-sa +--- +## +## Vault-backed secret +## +apiVersion: secrets.hashicorp.com/v1beta1 +kind: VaultStaticSecret +metadata: + namespace: baeldung + name: baeldung-test +spec: + vaultAuthRef: baeldung-test + mount: secrets + type: kv-v2 + path: baeldung-test + refreshAfter: 60s + hmacSecretData: true + destination: + create: true + name: baeldung-test diff --git a/spring-vault/src/main/resources/vault-config-k8s.properties b/spring-vault/src/main/resources/vault-config-k8s.properties new file mode 100644 index 0000000000..276d735fcb --- /dev/null +++ b/spring-vault/src/main/resources/vault-config-k8s.properties @@ -0,0 +1,4 @@ +vault.uri=http://localhost:8200 +vault.authentication=KUBERNETES +vault.kubernetes.role=baeldung-test-role +vault.kubernetes.service-account-token-file=sa-token.txt \ No newline at end of file diff --git a/spring-vault/src/test/java/com/baeldung/springcloudvault/SpringCloudVaultApplicationLiveTest.java b/spring-vault/src/test/java/com/baeldung/springcloudvault/SpringCloudVaultApplicationLiveTest.java new file mode 100644 index 0000000000..b4ece472a6 --- /dev/null +++ b/spring-vault/src/test/java/com/baeldung/springcloudvault/SpringCloudVaultApplicationLiveTest.java @@ -0,0 +1,26 @@ +package com.baeldung.springcloudvault; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.env.Environment; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ActiveProfiles("vault") +@SpringBootTest(classes = SpringCloudVaultTestApplication.class) +public class SpringCloudVaultApplicationLiveTest { + + @Autowired + Environment env; + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + assertNotNull(env.getProperty("foo")); + } + +} diff --git a/spring-vault/src/test/resources/application-vault.properties b/spring-vault/src/test/resources/application-vault.properties new file mode 100644 index 0000000000..7226a3a6e4 --- /dev/null +++ b/spring-vault/src/test/resources/application-vault.properties @@ -0,0 +1,15 @@ +# Vault Properties +spring.config.import: vault:// +spring.cloud.vault.uri=http://localhost:8200 +spring.cloud.vault.authentication=KUBERNETES +spring.cloud.vault.kubernetes.role=baeldung-test-role + +# +spring.cloud.vault.kv.backend=secrets +spring.cloud.vault.kv.application-name=baeldung-test +# + +# NOTICE: the following property is only necessary when running the application +# outside Kubernetes +# Please refer to the article for instructions on how to create this file +spring.cloud.vault.kubernetes.service-account-token-file=sa-token.txt \ No newline at end of file diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml index 38d019c683..d4fff21605 100644 --- a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml @@ -1,84 +1,84 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd"> - 4.0.0 + 4.0.0 - com.baeldung.spring-thymeleaf-attributes.module - accessing-session-attributes - 0.0.1-SNAPSHOT - war - - - com.baeldung.spring-thymeleaf-attributes - spring-thymeleaf-attributes + com.baeldung.spring-thymeleaf-attributes.module + accessing-session-attributes 0.0.1-SNAPSHOT - ../pom.xml - + war - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-thymeleaf - ${spring.boot.starter.thymeleaf} - - - - org.junit.jupiter - junit-jupiter-engine - ${junit.jupiter.engine.version} - test - - - org.mockito - mockito-core - ${mockito.version} - test - - - org.mockito - mockito-junit-jupiter - ${mockito.version} - test - - - org.junit.jupiter - junit-jupiter-api - ${junit.jupiter.engine.version} - test - - + + com.baeldung.spring-thymeleaf-attributes + spring-thymeleaf-attributes + 0.0.1-SNAPSHOT + ../pom.xml + - - - - org.springframework.boot - spring-boot-maven-plugin - - - -Dfile.encoding="UTF-8" -Xdebug - -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 - - - - - + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + ${spring.boot.starter.thymeleaf} + + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.engine.version} + test + + + org.mockito + mockito-core + ${mockito.version} + test + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.engine.version} + test + + - - com.baeldung.accesing_session_attributes.SpringWebApplicationInitializer - UTF-8 - UTF-8 - UTF-8 - true - true - 5.9.3 - 5.3.1 - 3.1.1.RELEASE - 3.1.1 - + + + + org.springframework.boot + spring-boot-maven-plugin + + + -Dfile.encoding="UTF-8" -Xdebug + -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 + + + + + + + + com.baeldung.accesing_session_attributes.SpringWebApplicationInitializer + UTF-8 + UTF-8 + UTF-8 + true + true + 5.9.3 + 5.3.1 + 3.1.1.RELEASE + 3.1.1 + \ No newline at end of file diff --git a/spring-websockets/pom.xml b/spring-websockets/pom.xml index c13d1cff33..a28ef8749a 100644 --- a/spring-websockets/pom.xml +++ b/spring-websockets/pom.xml @@ -44,8 +44,4 @@
- - 3.3.2 - - \ No newline at end of file diff --git a/testing-modules/cucumber/pom.xml b/testing-modules/cucumber/pom.xml index ffa5c0d250..6d178b86a3 100644 --- a/testing-modules/cucumber/pom.xml +++ b/testing-modules/cucumber/pom.xml @@ -124,7 +124,6 @@ 14 6.10.3 5.4.0 - 2.22.2 3.141.59 4.3.1 0.40 diff --git a/testing-modules/junit-5-basics-2/README.md b/testing-modules/junit-5-basics-2/README.md new file mode 100644 index 0000000000..f5e2558332 --- /dev/null +++ b/testing-modules/junit-5-basics-2/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Test Main Method with JUnit](http://www.baeldung.com/junit-5) diff --git a/testing-modules/junit-5-basics-2/pom.xml b/testing-modules/junit-5-basics-2/pom.xml new file mode 100644 index 0000000000..85b6c707fb --- /dev/null +++ b/testing-modules/junit-5-basics-2/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + junit-5-basics-2 + + + + commons-cli + commons-cli + ${commons-cli.version} + + + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter-api.version} + test + + + org.mockito + mockito-core + ${mockito-core.version} + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + + + 11 + 11 + UTF-8 + 1.5.0 + 5.10.0 + 5.5.0 + + + \ No newline at end of file diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Bootstrapper.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Bootstrapper.java new file mode 100644 index 0000000000..3dcdb93bd5 --- /dev/null +++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Bootstrapper.java @@ -0,0 +1,62 @@ +package com.baeldung.junit.main.test; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +public class Bootstrapper { + private final InputReader inputReader; + private final Calculator calculator; + + public Bootstrapper(InputReader inputReader, Calculator calculator) { + this.inputReader = inputReader; + this.calculator = calculator; + } + + public void processRequest(String[] args) { + try { + Options options = getOptions(); + CommandLineParser parser = new DefaultParser(); + CommandLine commandLine = parser.parse(options, args); + + if (commandLine.hasOption("i")) { + System.out.print("Option i is present. The value is: " + commandLine.getOptionValue("i") + " \n"); + String optionValue = commandLine.getOptionValue("i"); + InputType inputType = InputType.valueOf(optionValue); + + String fileName = null; + if (commandLine.hasOption("f")) { + fileName = commandLine.getOptionValue("f"); + } + String inputString = inputReader.read(inputType, fileName); + int calculatedSum = calculator.calculateSum(inputString); + } + + } catch (ParseException exception) { + System.out.print("Parse error: " + exception.getMessage()); + } + } + + public static Options getOptions() { + Option fileNameOption = Option.builder("f") + .required(false) + .desc("The file name option") + .type(String.class) + .build(); + Option inputTypeOption = Option.builder("i") + .longOpt("input") + .required(true) + .desc("The input type") + .type(InputType.class) + .hasArg() + .build(); + + Options options = new Options(); + options.addOption(inputTypeOption); + options.addOption(fileNameOption); + return options; + } +} \ No newline at end of file diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Calculator.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Calculator.java new file mode 100644 index 0000000000..a741a0b03a --- /dev/null +++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/Calculator.java @@ -0,0 +1,17 @@ +package com.baeldung.junit.main.test; + +import java.util.Arrays; + +public class Calculator { + + public int calculateSum(String input) { + String[] array = input.split(" "); + int sum = Arrays.stream(array) + .map(Integer::valueOf) + .mapToInt(Integer::intValue) + .sum(); + System.out.println("Calculated sum: " + sum); + return sum; + } + +} \ No newline at end of file diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputReader.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputReader.java new file mode 100644 index 0000000000..86f558df92 --- /dev/null +++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputReader.java @@ -0,0 +1,38 @@ +package com.baeldung.junit.main.test; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Scanner; + +public class InputReader { + + public String read(InputType inputType, String fileName) { + switch (inputType) { + case FILE: + return readFromFile(fileName); + case CONSOLE: + return readFromConsole(); + default: + return null; + } + } + + private String readFromConsole() { + System.out.println("Enter values for calculation: \n"); + return new Scanner(System.in).nextLine(); + } + + private String readFromFile(String fileName) { + String readString = null; + try { + readString = Files.readString(Path.of(URI.create(fileName))); + System.out.println(readString); + } catch (IOException e) { + throw new RuntimeException(e); + } + return null; + } + +} \ No newline at end of file diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputType.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputType.java new file mode 100644 index 0000000000..fbf26b7df3 --- /dev/null +++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/InputType.java @@ -0,0 +1,5 @@ +package com.baeldung.junit.main.test; + +public enum InputType { + FILE, CONSOLE +} diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/SimpleMain.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/SimpleMain.java new file mode 100644 index 0000000000..346162bbae --- /dev/null +++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/SimpleMain.java @@ -0,0 +1,16 @@ +package com.baeldung.junit.main.test; + +import java.util.Arrays; + +public class SimpleMain { + + public static void main(String[] args) { + + System.out.println("Received input parameters: " + Arrays.asList(args)); + + Bootstrapper bootstrapper = new Bootstrapper(new InputReader(), new Calculator()); + + bootstrapper.processRequest(args); + } + +} \ No newline at end of file diff --git a/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/StaticMain.java b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/StaticMain.java new file mode 100644 index 0000000000..8c610f57ad --- /dev/null +++ b/testing-modules/junit-5-basics-2/src/main/java/com/baeldung/junit/main/test/StaticMain.java @@ -0,0 +1,115 @@ +package com.baeldung.junit.main.test; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Scanner; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +public class StaticMain { + + public static void main(String[] args) { + System.out.println("Received input parameters: " + Arrays.asList(args)); + + processRequest(args); + } + + public static void processRequest(String[] args) { + try { + Options options = getOptions(); + CommandLineParser parser = new DefaultParser(); + CommandLine commandLine = parser.parse(options, args); + + if (commandLine.hasOption("V")) { + System.out.print("Option V is present. The value is: "); + System.out.println(commandLine.getOptionValue("V")); + } + + if (commandLine.hasOption("i")) { + System.out.print("Option i is present. The value is: " + commandLine.getOptionValue("i") + " \n"); + String optionValue = commandLine.getOptionValue("i"); + InputType inputType = InputType.valueOf(optionValue); + + String fileName = null; + if (commandLine.hasOption("f")) { + fileName = commandLine.getOptionValue("f"); + } + String inputString = read(inputType, fileName); + int calculatedSum = calculateSum(inputString); + } + + } catch (ParseException exception) { + System.out.print("Parse error: "); + System.out.println(exception.getMessage()); + } + } + + public static Options getOptions() { + Option inputTypeOption = Option.builder("i") + .longOpt("input") + .required(true) + .desc("The input type") + .type(InputType.class) + .hasArg() + .build(); + Option fileNameOption = Option.builder("f") + .required(false) + .desc("The file name option") + .type(String.class) + .hasArg() + .build(); + + Options options = new Options(); + options.addOption(inputTypeOption); + options.addOption(fileNameOption); + return options; + } + + public static int calculateSum(String input) { + if (input == null) { + return 0; + } + String[] array = input.split(" "); + int sum = Arrays.stream(array) + .map(Integer::valueOf) + .mapToInt(Integer::intValue) + .sum(); + System.out.println("Calculated sum: " + sum); + return sum; + } + + private static String readFromConsole() { + System.out.println("Enter values for calculation: \n"); + return new Scanner(System.in).nextLine(); + } + + private static String readFromFile(String fileName) { + String readString = null; + try { + readString = Files.readString(Path.of(URI.create(fileName))); + System.out.println(readString); + } catch (IOException e) { + throw new RuntimeException(e); + } + return null; + } + + public static String read(InputType inputType, String fileName) { + switch (inputType) { + case FILE: + return readFromFile(fileName); + case CONSOLE: + return readFromConsole(); + default: + return null; + } + } +} \ No newline at end of file diff --git a/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestSimpleMain.java b/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestSimpleMain.java new file mode 100644 index 0000000000..37ef516bff --- /dev/null +++ b/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestSimpleMain.java @@ -0,0 +1,94 @@ +package com.baeldung.junit.main.test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.nio.charset.Charset; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class TestSimpleMain { + private InputStream defaultIn; + private PrintStream defaultOut; + + @BeforeEach + public void setUp() { + defaultIn = System.in; + defaultOut = System.out; + } + + @AfterEach + public void tearDown() { + System.setIn(defaultIn); + System.setOut(defaultOut); + } + + @Test + public void givenArgumentAsConsoleInput_WhenReadFromSubstitutedByteStream_ThenSuccessfullyCalculate() throws IOException { + String[] arguments = new String[] { "-i", "CONSOLE" }; + + final InputStream fips = new ByteArrayInputStream("1 2 3".getBytes()); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + final PrintStream out = new PrintStream(byteArrayOutputStream); + + System.setIn(fips); + System.setOut(out); + + SimpleMain.main(arguments); + + String consoleOutput = byteArrayOutputStream.toString(Charset.defaultCharset()); + assertTrue(consoleOutput.contains("Calculated sum: 6")); + + fips.close(); + out.close(); + } + + @Test + public void givenArgumentAsConsoleInput_WhenReadFromSubstitutedFileStream_ThenSuccessfullyCalculate() throws IOException { + String[] arguments = new String[] { "-i", "CONSOLE" }; + + final InputStream fips = getClass().getClassLoader() + .getResourceAsStream("test-input.txt"); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + final PrintStream out = new PrintStream(byteArrayOutputStream); + + System.setIn(fips); + System.setOut(out); + + SimpleMain.main(arguments); + + String consoleOutput = byteArrayOutputStream.toString(Charset.defaultCharset()); + assertTrue(consoleOutput.contains("Calculated sum: 10")); + + fips.close(); + out.close(); + } + + @Test + public void givenLongArgumentAsConsoleInput_WhenReadFromSubstitutedFileStream_ThenSuccessfullyCalculate() throws IOException { + String[] arguments = new String[] { "--input", "CONSOLE" }; + + final InputStream fips = getClass().getClassLoader() + .getResourceAsStream("test-input.txt"); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + final PrintStream out = new PrintStream(byteArrayOutputStream); + + System.setIn(fips); + System.setOut(out); + + SimpleMain.main(arguments); + + String consoleOutput = byteArrayOutputStream.toString(Charset.defaultCharset()); + assertTrue(consoleOutput.contains("Calculated sum: 10")); + + fips.close(); + out.close(); + } + +} diff --git a/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestStaticMain.java b/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestStaticMain.java new file mode 100644 index 0000000000..267b101f94 --- /dev/null +++ b/testing-modules/junit-5-basics-2/src/test/java/com/baeldung/junit/main/test/TestStaticMain.java @@ -0,0 +1,35 @@ +package com.baeldung.junit.main.test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +public class TestStaticMain { + + @Test + public void givenArgumentAsConsoleInput_WhenReadFromSubstitutedByteArrayInputStream_ThenSuccessfullyCalculate() throws IOException { + String[] arguments = new String[] { "-i", "CONSOLE" }; + try (MockedStatic mockedStatic = Mockito.mockStatic(StaticMain.class, Mockito.CALLS_REAL_METHODS); + InputStream fips = new ByteArrayInputStream("1 2 3".getBytes())) { + + final InputStream original = System.in; + + //Reassigns the "standard" input stream + System.setIn(fips); + + ArgumentCaptor stringArgumentCaptor = ArgumentCaptor.forClass(String.class); + + StaticMain.main(arguments); + + mockedStatic.verify(() -> StaticMain.calculateSum(stringArgumentCaptor.capture())); + + System.setIn(original); + } + } + +} diff --git a/testing-modules/junit-5-basics-2/src/test/resources/test-input.txt b/testing-modules/junit-5-basics-2/src/test/resources/test-input.txt new file mode 100644 index 0000000000..6163c9426b --- /dev/null +++ b/testing-modules/junit-5-basics-2/src/test/resources/test-input.txt @@ -0,0 +1 @@ +4 5 1 \ No newline at end of file diff --git a/testing-modules/mockito-2/README.md b/testing-modules/mockito-2/README.md index ac931a108f..82c97305f6 100644 --- a/testing-modules/mockito-2/README.md +++ b/testing-modules/mockito-2/README.md @@ -6,3 +6,4 @@ This module contains articles about Mockito - [Mocking a Singleton With Mockito](https://www.baeldung.com/java-mockito-singleton) - [Resolving Mockito Exception: Wanted But Not Invoked](https://www.baeldung.com/mockito-exception-wanted-but-not-invoked) - [Matching Null With Mockito](https://www.baeldung.com/mockito-match-null) +- [Mock Same Method with Different Parameters](https://www.baeldung.com/java-mock-same-method-other-parameters) diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentProcessor.java b/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentProcessor.java new file mode 100644 index 0000000000..39b2b74bd0 --- /dev/null +++ b/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentProcessor.java @@ -0,0 +1,22 @@ +package com.baeldung.constructor; + +public class PaymentProcessor { + + private final PaymentService paymentService; + + public PaymentProcessor(PaymentService paymentService) { + this.paymentService = paymentService; + } + + public PaymentProcessor() { + this.paymentService = new PaymentService(); + } + + public PaymentProcessor(String paymentMode) { + this.paymentService = new PaymentService(paymentMode); + } + + public String processPayment(){ + return paymentService.processPayment(); + } +} diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentService.java b/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentService.java new file mode 100644 index 0000000000..5194ed7e21 --- /dev/null +++ b/testing-modules/mockito-2/src/main/java/com/baeldung/constructor/PaymentService.java @@ -0,0 +1,19 @@ +package com.baeldung.constructor; + +public class PaymentService { + + private final String paymentMode; + + public PaymentService(String paymentMode) { + this.paymentMode = paymentMode; + } + + public PaymentService() { + this.paymentMode = "Cash"; + } + + public String processPayment(){ + // simulate processing payment and returns the payment mode + return this.paymentMode; + } +} diff --git a/testing-modules/mockito-2/src/main/java/com/baeldung/onemethodmultipleparams/ExampleService.java b/testing-modules/mockito-2/src/main/java/com/baeldung/onemethodmultipleparams/ExampleService.java new file mode 100644 index 0000000000..7177013721 --- /dev/null +++ b/testing-modules/mockito-2/src/main/java/com/baeldung/onemethodmultipleparams/ExampleService.java @@ -0,0 +1,7 @@ +package com.baeldung.onemethodmultipleparams; + +public class ExampleService { + public int getValue(int arg) { + return 1; + } +} diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/constructor/PaymentServiceUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/constructor/PaymentServiceUnitTest.java new file mode 100644 index 0000000000..16be4a728b --- /dev/null +++ b/testing-modules/mockito-2/src/test/java/com/baeldung/constructor/PaymentServiceUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.constructor; + +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.MockedConstruction; +import org.mockito.Mockito; + +class PaymentServiceUnitTest { + + @Test + void whenConstructorInvokedWithInitializer_ThenMockObjectShouldBeCreated(){ + try(MockedConstruction mockPaymentService = Mockito.mockConstruction(PaymentService.class,(mock,context)-> when(mock.processPayment()).thenReturn("Credit"))){ + PaymentProcessor paymentProcessor = new PaymentProcessor(); + Assertions.assertEquals(1,mockPaymentService.constructed().size()); + Assertions.assertEquals("Credit", paymentProcessor.processPayment()); + } + } + + @Test + void whenConstructorInvokedWithoutInitializer_ThenMockObjectShouldBeCreatedWithNullFields(){ + try(MockedConstruction mockPaymentService = Mockito.mockConstruction(PaymentService.class)){ + PaymentProcessor paymentProcessor = new PaymentProcessor(); + Assertions.assertEquals(1,mockPaymentService.constructed().size()); + Assertions.assertNull(paymentProcessor.processPayment()); + } + } + + @Test + void whenConstructorInvokedWithParameters_ThenMockObjectShouldBeCreated(){ + try(MockedConstruction mockPaymentService = Mockito.mockConstruction(PaymentService.class,(mock, context) -> when(mock.processPayment()).thenReturn("Credit"))){ + PaymentProcessor paymentProcessor = new PaymentProcessor("Debit"); + Assertions.assertEquals(1,mockPaymentService.constructed().size()); + Assertions.assertEquals("Credit", paymentProcessor.processPayment()); + } + } + + @Test + void whenMultipleConstructorsInvoked_ThenMultipleMockObjectsShouldBeCreated(){ + try(MockedConstruction mockPaymentService = Mockito.mockConstruction(PaymentService.class)){ + PaymentProcessor paymentProcessor = new PaymentProcessor(); + PaymentProcessor secondPaymentProcessor = new PaymentProcessor(); + PaymentProcessor thirdPaymentProcessor = new PaymentProcessor("Debit"); + + when(mockPaymentService.constructed().get(0).processPayment()).thenReturn("Credit"); + when(mockPaymentService.constructed().get(1).processPayment()).thenReturn("Online Banking"); + + Assertions.assertEquals(3,mockPaymentService.constructed().size()); + Assertions.assertEquals("Credit", paymentProcessor.processPayment()); + Assertions.assertEquals("Online Banking", secondPaymentProcessor.processPayment()); + Assertions.assertNull(thirdPaymentProcessor.processPayment()); + } + } + + @Test + void whenDependencyInjectionIsUsed_ThenMockObjectShouldBeCreated(){ + PaymentService mockPaymentService = Mockito.mock(PaymentService.class); + PaymentProcessor paymentProcessor = new PaymentProcessor(mockPaymentService); + when(mockPaymentService.processPayment()).thenReturn("Online Banking"); + Assertions.assertEquals("Online Banking", paymentProcessor.processPayment()); + } +} diff --git a/testing-modules/mockito-2/src/test/java/com/baeldung/onemethodmultipleparams/OneMethodMultipleParamsUnitTest.java b/testing-modules/mockito-2/src/test/java/com/baeldung/onemethodmultipleparams/OneMethodMultipleParamsUnitTest.java new file mode 100644 index 0000000000..0633a5a2f0 --- /dev/null +++ b/testing-modules/mockito-2/src/test/java/com/baeldung/onemethodmultipleparams/OneMethodMultipleParamsUnitTest.java @@ -0,0 +1,63 @@ +package com.baeldung.onemethodmultipleparams; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class OneMethodMultipleParamsUnitTest { + + @Mock + ExampleService exampleService; + + @Test + public void givenAMethod_whenStubbingForMultipleArguments_thenExpectDifferentResults() { + when(exampleService.getValue(10)).thenReturn(100); + when(exampleService.getValue(20)).thenReturn(200); + when(exampleService.getValue(30)).thenReturn(300); + + assertEquals(100, exampleService.getValue(10)); + assertEquals(200, exampleService.getValue(20)); + assertEquals(300, exampleService.getValue(30)); + } + + @Test + public void givenAMethod_whenUsingThenAnswer_thenExpectDifferentReults() { + when(exampleService.getValue(anyInt())).thenAnswer(invocation -> { + int argument = (int) invocation.getArguments()[0]; + int result; + switch (argument) { + case 25: + result = 125; + break; + case 50: + result = 150; + break; + case 75: + result = 175; + break; + default: + result = 0; + } + return result; + }); + assertEquals(125, exampleService.getValue(25)); + assertEquals(150, exampleService.getValue(50)); + assertEquals(175, exampleService.getValue(75)); + } + + @Test + public void givenAMethod_whenUsingConsecutiveStubbing_thenExpectResultsInOrder() { + when(exampleService.getValue(anyInt())).thenReturn(9, 18, 27); + assertEquals(9, exampleService.getValue(1)); + assertEquals(18, exampleService.getValue(1)); + assertEquals(27, exampleService.getValue(1)); + assertEquals(27, exampleService.getValue(1)); + } + +} diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index 108ce29b86..fa72b1e696 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -27,6 +27,7 @@ junit-4 junit-5-advanced junit-5-basics + junit-5-basics-2 junit-5 junit5-annotations junit5-migration diff --git a/testing-modules/testing-assertions/src/test/java/com/baeldung/assertregexmatch/AssetRegexMatchUnitTest.java b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertregexmatch/AssetRegexMatchUnitTest.java new file mode 100644 index 0000000000..e5456130e9 --- /dev/null +++ b/testing-modules/testing-assertions/src/test/java/com/baeldung/assertregexmatch/AssetRegexMatchUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.assertregexmatch; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.hamcrest.Matchers.matchesPattern; +import static org.hamcrest.Matchers.not; +import static org.junit.jupiter.api.Assertions.*; + +public class AssetRegexMatchUnitTest { + + @Test + void whenUsingJunit5assertTrue_thenGetExpectedResult() { + assertTrue("Java at Baeldung".matches(".* at Baeldung$")); + assertFalse("something else".matches(".* at Baeldung$")); + } + + @Test + void whenUsingJunit5assertLinesMatch_thenGetExpectedResult() { + assertLinesMatch(List.of(".* at Baeldung$"), List.of("Kotlin at Baeldung")); + } + + @Test + void whenUsingJunit5assertLinesMatch_thenEqualsIsCheckedFirst() { + assertFalse(".* at Baeldung$".matches(".* at Baeldung$")); + assertLinesMatch(List.of(".* at Baeldung$"), List.of(".* at Baeldung$")); + } + + @Test + void whenUsingAssertJMatches_thenGetExpectedResult() { + org.assertj.core.api.Assertions.assertThat("Linux at Baeldung").matches(".* at Baeldung$"); + org.assertj.core.api.Assertions.assertThat("something unrelated").doesNotMatch(".* at Baeldung$"); + } + + @Test + void whenUsingHamcrestMatches_thenGetExpectedResult() { + org.hamcrest.MatcherAssert.assertThat("Computer science at Baeldung", matchesPattern(".* at Baeldung$")); + org.hamcrest.MatcherAssert.assertThat("something unrelated", not(matchesPattern(".* at Baeldung$"))); + } + +} \ No newline at end of file diff --git a/testing-modules/testing-libraries-2/pom.xml b/testing-modules/testing-libraries-2/pom.xml index d74ede07db..4cc3ea8428 100644 --- a/testing-modules/testing-libraries-2/pom.xml +++ b/testing-modules/testing-libraries-2/pom.xml @@ -1,6 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 testing-libraries-2 testing-libraries-2 diff --git a/testing-modules/testng/pom.xml b/testing-modules/testng/pom.xml index 62e2b2e578..b0a10b131c 100644 --- a/testing-modules/testng/pom.xml +++ b/testing-modules/testng/pom.xml @@ -25,15 +25,9 @@ testng - - - src/main/resources - true - - - src/main/resources + src/test/resources true diff --git a/testing-modules/zerocode/pom.xml b/testing-modules/zerocode/pom.xml index 15ef45be63..c0aa370096 100644 --- a/testing-modules/zerocode/pom.xml +++ b/testing-modules/zerocode/pom.xml @@ -91,7 +91,6 @@ - 3.0.0-M5 3.0.0-M5 8 8 diff --git a/vaadin/pom.xml b/vaadin/pom.xml index 777ab2551c..aa37a2392a 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -187,7 +187,6 @@ local mytheme 3.0.0 - 3.3.2 \ No newline at end of file diff --git a/web-modules/blade/pom.xml b/web-modules/blade/pom.xml index 0733556c20..2748c05663 100644 --- a/web-modules/blade/pom.xml +++ b/web-modules/blade/pom.xml @@ -112,7 +112,6 @@ 4.5.6 4.5.6 4.4.10 - 3.0.0-M3 0.7 3.1.0 diff --git a/web-modules/javax-servlets-2/README.md b/web-modules/javax-servlets-2/README.md index cd599890ad..179264f90a 100644 --- a/web-modules/javax-servlets-2/README.md +++ b/web-modules/javax-servlets-2/README.md @@ -5,3 +5,4 @@ This module contains articles about Servlets. ### Relevant Articles: - [Check if a User Is Logged-in With Servlets and JSP](https://www.baeldung.com/servlets-jsp-check-user-login) - [How to Mock HttpServletRequest](https://www.baeldung.com/java-httpservletrequest-mock) +- [Set a Parameter in an HttpServletRequest in Java](https://www.baeldung.com/java-servlet-request-set-parameter) diff --git a/web-modules/javax-servlets-2/pom.xml b/web-modules/javax-servlets-2/pom.xml index 81616e0055..9ba12352fd 100644 --- a/web-modules/javax-servlets-2/pom.xml +++ b/web-modules/javax-servlets-2/pom.xml @@ -22,6 +22,11 @@ commons-fileupload ${commons-fileupload.version} + + org.apache.commons + commons-text + ${commons-text.version} + javax.servlet @@ -76,6 +81,16 @@ + + org.eclipse.jetty + jetty-maven-plugin + ${jetty-maven-plugin.version} + + + / + + + @@ -84,6 +99,8 @@ 1.49 5.3.20 2.22.2 + 10.0.4 + 1.10.0 \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/LanguageServlet.java b/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/LanguageServlet.java new file mode 100644 index 0000000000..983066ec51 --- /dev/null +++ b/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/LanguageServlet.java @@ -0,0 +1,21 @@ +package com.baeldung.setparam; + +import java.io.IOException; +import java.util.Locale; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.*; + +@WebServlet(name = "LanguageServlet", urlPatterns = "/setparam/lang") +public class LanguageServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + + SetParameterRequestWrapper requestWrapper = new SetParameterRequestWrapper(request); + requestWrapper.setParameter("locale", Locale.getDefault().getLanguage()); + request.getRequestDispatcher("/setparam/3rd_party_module.jsp").forward(requestWrapper, response); + } + +} \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/SanitizeParametersFilter.java b/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/SanitizeParametersFilter.java new file mode 100644 index 0000000000..3f93591bd9 --- /dev/null +++ b/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/SanitizeParametersFilter.java @@ -0,0 +1,17 @@ +package com.baeldung.setparam; + +import java.io.IOException; +import javax.servlet.*; +import javax.servlet.annotation.WebFilter; +import javax.servlet.http.HttpServletRequest; + +@WebFilter(urlPatterns = { "/setparam/with-sanitize.jsp" }) +public class SanitizeParametersFilter implements Filter { + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpReq = (HttpServletRequest) request; + chain.doFilter(new SanitizeParametersRequestWrapper(httpReq), response); + } + +} \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/SanitizeParametersRequestWrapper.java b/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/SanitizeParametersRequestWrapper.java new file mode 100644 index 0000000000..e4c2870ca6 --- /dev/null +++ b/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/SanitizeParametersRequestWrapper.java @@ -0,0 +1,46 @@ +package com.baeldung.setparam; + +import java.util.*; +import java.util.stream.Collectors; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import org.apache.commons.text.StringEscapeUtils; + +public class SanitizeParametersRequestWrapper extends HttpServletRequestWrapper { + + private final Map sanitizedMap; + + public SanitizeParametersRequestWrapper(HttpServletRequest request) { + super(request); + sanitizedMap = Collections.unmodifiableMap( + request.getParameterMap().entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + entry -> Arrays.stream(entry.getValue()) + .map(StringEscapeUtils::escapeHtml4) + .toArray(String[]::new) + ))); + } + + @Override + public Map getParameterMap() { + return sanitizedMap; + } + + @Override + public String[] getParameterValues(String name) { + return Optional.ofNullable(getParameterMap().get(name)) + .map(values -> Arrays.copyOf(values, values.length)) + .orElse(null); + } + + @Override + public String getParameter(String name) { + return Optional.ofNullable(getParameterValues(name)) + .map(values -> values[0]) + .orElse(null); + } + +} \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/SetParameterRequestWrapper.java b/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/SetParameterRequestWrapper.java new file mode 100644 index 0000000000..7b2ab4597c --- /dev/null +++ b/web-modules/javax-servlets-2/src/main/java/com/baeldung/setparam/SetParameterRequestWrapper.java @@ -0,0 +1,40 @@ +package com.baeldung.setparam; + +import java.util.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +public class SetParameterRequestWrapper extends HttpServletRequestWrapper { + + private final Map paramMap; + + public SetParameterRequestWrapper(HttpServletRequest request) { + super(request); + paramMap = new HashMap<>(request.getParameterMap()); + } + + @Override + public Map getParameterMap() { + return Collections.unmodifiableMap(paramMap); + } + + @Override + public String[] getParameterValues(String name) { + return Optional.ofNullable(getParameterMap().get(name)) + .map(values -> Arrays.copyOf(values, values.length)) + .orElse(null); + } + + @Override + public String getParameter(String name) { + return Optional.ofNullable(getParameterValues(name)) + .map(values -> values[0]) + .orElse(null); + } + + public void setParameter(String name, String value) { + paramMap.put(name, new String[] {value}); + } + +} \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/main/webapp/setparam/3rd_party_module.jsp b/web-modules/javax-servlets-2/src/main/webapp/setparam/3rd_party_module.jsp new file mode 100644 index 0000000000..9ab4fd2c00 --- /dev/null +++ b/web-modules/javax-servlets-2/src/main/webapp/setparam/3rd_party_module.jsp @@ -0,0 +1,13 @@ +<%@ page import="java.util.*"%> + + + 3rd party Module + + + <% + String localeStr = request.getParameter("locale"); + Locale currentLocale = (localeStr != null ? new Locale(localeStr) : null); + %> + The language you have selected: <%=currentLocale != null ? currentLocale.getDisplayLanguage(currentLocale) : " None"%> + + \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/main/webapp/setparam/with-sanitize.jsp b/web-modules/javax-servlets-2/src/main/webapp/setparam/with-sanitize.jsp new file mode 100644 index 0000000000..68704d6133 --- /dev/null +++ b/web-modules/javax-servlets-2/src/main/webapp/setparam/with-sanitize.jsp @@ -0,0 +1,10 @@ + + + Sanitized request parameter + + + The text below comes from request parameter "input": +
+ <%=request.getParameter("input")%> + + \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/main/webapp/setparam/without-sanitize.jsp b/web-modules/javax-servlets-2/src/main/webapp/setparam/without-sanitize.jsp new file mode 100644 index 0000000000..f5437164ef --- /dev/null +++ b/web-modules/javax-servlets-2/src/main/webapp/setparam/without-sanitize.jsp @@ -0,0 +1,10 @@ + + + Non sanitized request parameter + + + The text below comes from request parameter "input": +
+ <%=request.getParameter("input")%> + + \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/LanguageServletLiveTest.java b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/LanguageServletLiveTest.java new file mode 100644 index 0000000000..c539ce63b9 --- /dev/null +++ b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/LanguageServletLiveTest.java @@ -0,0 +1,34 @@ +package com.baeldung.setparam; + +import static org.junit.Assert.assertTrue; + +import java.util.Locale; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; +import org.junit.Test; + +public class LanguageServletLiveTest { + + @Test + public void whenGetRequestUsingHttpClient_thenResponseBodyContainsDefaultLanguage() throws Exception { + + // When + HttpClient client = HttpClientBuilder.create().build(); + HttpGet method = new HttpGet("http://localhost:8080/setparam/lang"); + HttpResponse httpResponse = client.execute(method); + + // Then + Locale defaultLocale = Locale.getDefault(); + String expectedLanguage = defaultLocale.getDisplayLanguage(defaultLocale); + + HttpEntity entity = httpResponse.getEntity(); + String responseBody = EntityUtils.toString(entity, "UTF-8"); + assertTrue(responseBody.contains("The language you have selected: " + expectedLanguage)); + } + +} diff --git a/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/SanitizeParametersRequestLiveTest.java b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/SanitizeParametersRequestLiveTest.java new file mode 100644 index 0000000000..5fffea1824 --- /dev/null +++ b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/SanitizeParametersRequestLiveTest.java @@ -0,0 +1,40 @@ +package com.baeldung.setparam; + +import static org.junit.Assert.assertTrue; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; +import org.junit.BeforeClass; +import org.junit.Test; + +public class SanitizeParametersRequestLiveTest { + + private static String PARAM_INPUT; + + @BeforeClass + public static void init() throws UnsupportedEncodingException { + PARAM_INPUT = URLEncoder.encode("", "UTF-8"); + } + + @Test + public void whenInputParameterContainsXss_thenResponseBodyContainsSanitizedValue() throws Exception { + + // When + HttpClient client = HttpClientBuilder.create().build(); + HttpGet method = new HttpGet(String.format("http://localhost:8080/setparam/with-sanitize.jsp?input=%s", PARAM_INPUT)); + HttpResponse httpResponse = client.execute(method); + + // Then + HttpEntity entity = httpResponse.getEntity(); + String responseBody = EntityUtils.toString(entity, "UTF-8"); + assertTrue(responseBody.contains("<script>alert('Hello');</script>")); + } + +} \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/SanitizeParametersRequestWrapperUnitTest.java b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/SanitizeParametersRequestWrapperUnitTest.java new file mode 100644 index 0000000000..029cf41d1c --- /dev/null +++ b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/SanitizeParametersRequestWrapperUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.setparam; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class SanitizeParametersRequestWrapperUnitTest { + + private static final String NEW_VALUE = "NEW VALUE"; + + private Map parameterMap; + + @Mock + private HttpServletRequest request; + + @Before + public void initBeforeEachTest() { + parameterMap = new HashMap<>(); + parameterMap.put("input", new String[] {""}); + when(request.getParameterMap()).thenReturn(parameterMap); + } + + @Test + public void whenGetParameterViaWrapper_thenParameterReturnedIsSanitized() { + SanitizeParametersRequestWrapper wrapper = new SanitizeParametersRequestWrapper(request); + String actualValue = wrapper.getParameter("input"); + + assertEquals("<script>alert('Hello');</script>", actualValue); + } + + @Test(expected = UnsupportedOperationException.class) + public void whenPutValueToWrapperParameterMap_thenThrowsUnsupportedOperationException() { + SanitizeParametersRequestWrapper wrapper = new SanitizeParametersRequestWrapper(request); + Map wrapperParamMap = wrapper.getParameterMap(); + wrapperParamMap.put("input", new String[] {NEW_VALUE}); + } + + @Test + public void whenSetValueToWrapperParametersStringArray_thenThe2ndCallShouldNotEqualToNewValue() { + SanitizeParametersRequestWrapper wrapper = new SanitizeParametersRequestWrapper(request); + String[] firstCallValues = wrapper.getParameterValues("input"); + + firstCallValues[0] = NEW_VALUE; + String[] secondCallValues = wrapper.getParameterValues("input"); + assertThat(secondCallValues).doesNotContain(NEW_VALUE); + } + +} \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/SetParameterRequestWrapperUnitTest.java b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/SetParameterRequestWrapperUnitTest.java new file mode 100644 index 0000000000..8ef5307d44 --- /dev/null +++ b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/SetParameterRequestWrapperUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.setparam; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class SetParameterRequestWrapperUnitTest { + + private static final String NEW_VALUE = "NEW VALUE"; + + private Map parameterMap; + + @Mock + private HttpServletRequest request; + + @Before + public void initBeforeEachTest() { + parameterMap = new HashMap<>(); + parameterMap.put("input", new String[] {"inputValue"}); + when(request.getParameterMap()).thenReturn(parameterMap); + } + + @Test + public void whenSetParameterViaWrapper_thenGetParameterShouldReturnTheSameValue() { + SetParameterRequestWrapper wrapper = new SetParameterRequestWrapper(request); + wrapper.setParameter("newInput", "newInputValue"); + String actualValue = wrapper.getParameter("newInput"); + + assertEquals("newInputValue", actualValue); + } + + @Test(expected = UnsupportedOperationException.class) + public void whenPutValueToWrapperParameterMap_thenThrowsUnsupportedOperationException() { + SetParameterRequestWrapper wrapper = new SetParameterRequestWrapper(request); + Map wrapperParamMap = wrapper.getParameterMap(); + wrapperParamMap.put("input", new String[] {NEW_VALUE}); + } + + @Test + public void whenSetValueToWrapperParametersStringArray_thenThe2ndCallShouldNotEqualToNewValue() { + SetParameterRequestWrapper wrapper = new SetParameterRequestWrapper(request); + String[] firstCallValues = wrapper.getParameterValues("input"); + + firstCallValues[0] = NEW_VALUE; + String[] secondCallValues = wrapper.getParameterValues("input"); + assertThat(secondCallValues).doesNotContain(NEW_VALUE); + } + +} \ No newline at end of file diff --git a/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/UnsanitizedParametersRequestLiveTest.java b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/UnsanitizedParametersRequestLiveTest.java new file mode 100644 index 0000000000..f6cc566bfc --- /dev/null +++ b/web-modules/javax-servlets-2/src/test/java/com/baeldung/setparam/UnsanitizedParametersRequestLiveTest.java @@ -0,0 +1,42 @@ +package com.baeldung.setparam; + +import static org.junit.Assert.assertTrue; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; +import org.junit.BeforeClass; +import org.junit.Test; + +public class UnsanitizedParametersRequestLiveTest { + + private static final String TAG_SCRIPT = ""; + + private static String PARAM_INPUT; + + @BeforeClass + public static void init() throws UnsupportedEncodingException { + PARAM_INPUT = URLEncoder.encode(TAG_SCRIPT, "UTF-8"); + } + + @Test + public void whenInputParameterContainsXss_thenResponseBodyContainsUnsanitizedValue() throws Exception { + + // When + HttpClient client = HttpClientBuilder.create().build(); + HttpGet method = new HttpGet(String.format("http://localhost:8080/setparam/without-sanitize.jsp?input=%s", PARAM_INPUT)); + HttpResponse httpResponse = client.execute(method); + + // Then + HttpEntity entity = httpResponse.getEntity(); + String responseBody = EntityUtils.toString(entity, "UTF-8"); + assertTrue(responseBody.contains(TAG_SCRIPT)); + } + +} \ No newline at end of file diff --git a/web-modules/pom.xml b/web-modules/pom.xml index c009837186..2dcec681ad 100644 --- a/web-modules/pom.xml +++ b/web-modules/pom.xml @@ -26,7 +26,7 @@ jee-7 jooby linkrest - + ratpack diff --git a/web-modules/wicket/pom.xml b/web-modules/wicket/pom.xml index 9348e15cdb..244d176e25 100644 --- a/web-modules/wicket/pom.xml +++ b/web-modules/wicket/pom.xml @@ -84,7 +84,6 @@ 7.5.0 9.2.13.v20150730 - 3.3.1 \ No newline at end of file diff --git a/xml-2/src/main/java/com/baeldung/xml/validation/XmlValidator.java b/xml-2/src/main/java/com/baeldung/xml/validation/XmlValidator.java index 7d8f531bfa..57eccab193 100644 --- a/xml-2/src/main/java/com/baeldung/xml/validation/XmlValidator.java +++ b/xml-2/src/main/java/com/baeldung/xml/validation/XmlValidator.java @@ -44,7 +44,7 @@ public class XmlValidator { try { validator.validate(new StreamSource(getFile(xmlPath))); } catch (SAXParseException e) {} - xsdErrorHandler.getExceptions().forEach(e -> LOGGER.info(e.getMessage())); + xsdErrorHandler.getExceptions().forEach(e -> LOGGER.info(String.format("Line number: %s, Column number: %s. %s", e.getLineNumber(), e.getColumnNumber(), e.getMessage()))); return xsdErrorHandler.getExceptions(); }