diff --git a/algorithms-modules/algorithms-miscellaneous-3/README.md b/algorithms-modules/algorithms-miscellaneous-3/README.md index dd5bbac162..8a606caa22 100644 --- a/algorithms-modules/algorithms-miscellaneous-3/README.md +++ b/algorithms-modules/algorithms-miscellaneous-3/README.md @@ -10,7 +10,7 @@ This module contains articles about algorithms. Some classes of algorithms, e.g. - [Converting Between Roman and Arabic Numerals in Java](https://www.baeldung.com/java-convert-roman-arabic) - [Practical Java Examples of the Big O Notation](https://www.baeldung.com/java-algorithm-complexity) - [Checking If a List Is Sorted in Java](https://www.baeldung.com/java-check-if-list-sorted) -- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle) +- [Checking if a Java Graph Has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle) - [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique) - [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle) - [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm) diff --git a/algorithms-modules/algorithms-miscellaneous-4/README.md b/algorithms-modules/algorithms-miscellaneous-4/README.md index e2ae542bf8..6f1b6a66b9 100644 --- a/algorithms-modules/algorithms-miscellaneous-4/README.md +++ b/algorithms-modules/algorithms-miscellaneous-4/README.md @@ -5,10 +5,10 @@ This module contains articles about algorithms. Some classes of algorithms, e.g. ### Relevant articles: - [Multi-Swarm Optimization Algorithm in Java](https://www.baeldung.com/java-multi-swarm-algorithm) -- [Check If a String Contains All The Letters of The Alphabet with Java](https://www.baeldung.com/java-string-contains-all-letters) +- [Check if a String Contains All the Letters of the Alphabet With Java](https://www.baeldung.com/java-string-contains-all-letters) - [Find the Middle Element of a Linked List in Java](https://www.baeldung.com/java-linked-list-middle-element) - [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings) -- [Find the Longest Substring without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters) +- [Find the Longest Substring Without Repeating Characters](https://www.baeldung.com/java-longest-substring-without-repeated-characters) - [Permutations of an Array in Java](https://www.baeldung.com/java-array-permutations) - [Find the Smallest Missing Integer in an Array](https://www.baeldung.com/java-smallest-missing-integer-in-array) - [Permutations of a String in Java](https://www.baeldung.com/java-string-permutations) diff --git a/algorithms-modules/algorithms-miscellaneous-5/README.md b/algorithms-modules/algorithms-miscellaneous-5/README.md index 54b936586f..72e9b45683 100644 --- a/algorithms-modules/algorithms-miscellaneous-5/README.md +++ b/algorithms-modules/algorithms-miscellaneous-5/README.md @@ -9,7 +9,7 @@ This module contains articles about algorithms. Some classes of algorithms, e.g. - [Reversing a Binary Tree in Java](https://www.baeldung.com/java-reversing-a-binary-tree) - [Find If Two Numbers Are Relatively Prime in Java](https://www.baeldung.com/java-two-relatively-prime-numbers) - [Knapsack Problem Implementation in Java](https://www.baeldung.com/java-knapsack) -- [How to Determine if a Binary Tree is Balanced in Java](https://www.baeldung.com/java-balanced-binary-tree) +- [How to Determine if a Binary Tree Is Balanced in Java](https://www.baeldung.com/java-balanced-binary-tree) - [Overview of Combinatorial Problems in Java](https://www.baeldung.com/java-combinatorial-algorithms) - [Prim’s Algorithm with a Java Implementation](https://www.baeldung.com/java-prim-algorithm) - [Maximum Subarray Problem in Java](https://www.baeldung.com/java-maximum-subarray) diff --git a/apache-cxf-modules/sse-jaxrs/README.md b/apache-cxf-modules/sse-jaxrs/README.md index 4d39560b46..ee85940b8a 100644 --- a/apache-cxf-modules/sse-jaxrs/README.md +++ b/apache-cxf-modules/sse-jaxrs/README.md @@ -1,3 +1,3 @@ ### Relevant Articles: -- [Server-Sent Events (SSE) In JAX-RS](https://www.baeldung.com/java-ee-jax-rs-sse) +- [Server-Sent Events (SSE) in JAX-RS](https://www.baeldung.com/java-ee-jax-rs-sse) diff --git a/apache-httpclient/pom.xml b/apache-httpclient/pom.xml index c371d1fc06..5c3ea5b3b3 100644 --- a/apache-httpclient/pom.xml +++ b/apache-httpclient/pom.xml @@ -90,6 +90,12 @@ + + org.mock-server + mockserver-netty + ${mockserver.version} + + com.github.tomakehurst wiremock @@ -112,6 +118,7 @@ 4.1.4 + 5.6.1 2.5.1 4.5.8 diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java new file mode 100644 index 0000000000..988a89e7af --- /dev/null +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java @@ -0,0 +1,79 @@ +package com.baeldung.httpclient; + +import static org.mockserver.integration.ClientAndServer.startClientAndServer; +import static org.mockserver.matchers.Times.exactly; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.URISyntaxException; + +import org.apache.http.HttpStatus; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.mockserver.client.MockServerClient; +import org.mockserver.integration.ClientAndServer; + +public class GetRequestMockServer { + + public static ClientAndServer mockServer; + public static String serviceOneUrl; + public static String serviceTwoUrl; + + public static int serverPort; + + public static final String SERVER_ADDRESS = "127.0.0.1"; + public static final String PATH_ONE = "/test1"; + public static final String PATH_TWO = "/test2"; + public static final String METHOD = "GET"; + + @BeforeAll + static void startServer() throws IOException { + serverPort = getFreePort(); + System.out.println("Free port "+serverPort); + serviceOneUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_ONE; + serviceTwoUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_TWO; + mockServer = startClientAndServer(serverPort); + mockGetRequest(); + } + + @AfterAll + static void stopServer() { + mockServer.stop(); + } + + private static void mockGetRequest() { + new MockServerClient(SERVER_ADDRESS, serverPort) + .when( + request() + .withPath(PATH_ONE) + .withMethod(METHOD), + exactly(5) + ) + .respond( + response() + .withStatusCode(HttpStatus.SC_OK) + .withBody("{\"status\":\"ok\"}") + ); + new MockServerClient(SERVER_ADDRESS, serverPort) + .when( + request() + .withPath(PATH_TWO) + .withMethod(METHOD), + exactly(1) + ) + .respond( + response() + .withStatusCode(HttpStatus.SC_OK) + .withBody("{\"status\":\"ok\"}") + ); + } + + private static int getFreePort () throws IOException { + try (ServerSocket serverSocket = new ServerSocket(0)) { + return serverSocket.getLocalPort(); + } + } + +} diff --git a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java index ab0e4e6308..123c51bb86 100644 --- a/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java +++ b/apache-httpclient/src/test/java/com/baeldung/httpclient/HttpAsyncClientLiveTest.java @@ -9,6 +9,7 @@ import java.util.concurrent.Future; import javax.net.ssl.SSLContext; +import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner; import org.junit.jupiter.api.Test; import org.apache.hc.client5.http.async.methods.SimpleHttpRequest; @@ -38,7 +39,7 @@ import org.apache.hc.core5.ssl.SSLContexts; import org.apache.hc.core5.ssl.TrustStrategy; -class HttpAsyncClientLiveTest { +class HttpAsyncClientLiveTest extends GetRequestMockServer { private static final String HOST = "http://www.google.com"; private static final String HOST_WITH_SSL = "https://mms.nw.ru/"; @@ -55,12 +56,12 @@ class HttpAsyncClientLiveTest { @Test void whenUseHttpAsyncClient_thenCorrect() throws InterruptedException, ExecutionException, IOException { - final HttpHost target = new HttpHost(HOST); + final HttpHost target = new HttpHost(HOST_WITH_COOKIE); final SimpleHttpRequest request = SimpleRequestBuilder.get() .setHttpHost(target) .build(); - final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault(); + final CloseableHttpAsyncClient client = HttpAsyncClients.custom().build(); client.start(); @@ -102,30 +103,15 @@ class HttpAsyncClientLiveTest { @Test void whenUseProxyWithHttpClient_thenCorrect() throws Exception { - final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault(); + final HttpHost proxy = new HttpHost("127.0.0.1", GetRequestMockServer.serverPort); + DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy); + final CloseableHttpAsyncClient client = HttpAsyncClients.custom() + .setRoutePlanner(routePlanner) + .build(); client.start(); - final HttpHost proxy = new HttpHost("127.0.0.1", 8080); - final RequestConfig config = RequestConfig.custom().setProxy(proxy).build(); + final SimpleHttpRequest request = new SimpleHttpRequest("GET" ,HOST_WITH_PROXY); - request.setConfig(config); - final Future future = client.execute(request, new FutureCallback<>(){ - @Override - public void completed(SimpleHttpResponse response) { - - System.out.println("responseData"); - } - - @Override - public void failed(Exception ex) { - System.out.println("Error executing HTTP request: " + ex.getMessage()); - } - - @Override - public void cancelled() { - System.out.println("HTTP request execution cancelled"); - } - }); - + final Future future = client.execute(request, null); final HttpResponse response = future.get(); assertThat(response.getCode(), equalTo(200)); client.close(); diff --git a/apache-httpclient4/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java b/apache-httpclient4/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java new file mode 100644 index 0000000000..ae432e68f0 --- /dev/null +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/GetRequestMockServer.java @@ -0,0 +1,77 @@ +package com.baeldung.httpclient; + +import static org.mockserver.integration.ClientAndServer.startClientAndServer; +import static org.mockserver.matchers.Times.exactly; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.URISyntaxException; + +import org.apache.http.HttpStatus; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.mockserver.client.MockServerClient; +import org.mockserver.integration.ClientAndServer; + +public class GetRequestMockServer { + + public static ClientAndServer mockServer; + public static String serviceOneUrl; + public static String serviceTwoUrl; + + public static int serverPort; + + public static final String SERVER_ADDRESS = "127.0.0.1"; + public static final String PATH_ONE = "/test1"; + public static final String PATH_TWO = "/test2"; + public static final String METHOD = "GET"; + + @BeforeAll + static void startServer() throws IOException, URISyntaxException { + serverPort = getFreePort(); + serviceOneUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_ONE; + serviceTwoUrl = "http://" + SERVER_ADDRESS + ":" + serverPort + PATH_TWO; + mockServer = startClientAndServer(serverPort); + mockGetRequest(); + } + + @AfterAll + static void stopServer() { + mockServer.stop(); + } + + private static void mockGetRequest() { + new MockServerClient(SERVER_ADDRESS, serverPort) + .when( + request() + .withPath(PATH_ONE) + .withMethod(METHOD), + exactly(5) + ) + .respond( + response() + .withStatusCode(HttpStatus.SC_OK) + .withBody("{\"status\":\"ok\"}") + ); + new MockServerClient(SERVER_ADDRESS, serverPort) + .when( + request() + .withPath(PATH_TWO) + .withMethod(METHOD), + exactly(1) + ) + .respond( + response() + .withStatusCode(HttpStatus.SC_OK) + .withBody("{\"status\":\"ok\"}") + ); + } + + private static int getFreePort () throws IOException { + try (ServerSocket serverSocket = new ServerSocket(0)) { + return serverSocket.getLocalPort(); + } + } +} 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 dc0055c5ae..e097f9f511 100644 --- a/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpAsyncClientV4LiveTest.java +++ b/apache-httpclient4/src/test/java/com/baeldung/httpclient/HttpAsyncClientV4LiveTest.java @@ -31,7 +31,8 @@ import org.apache.http.protocol.HttpContext; import org.apache.http.ssl.SSLContexts; import org.junit.jupiter.api.Test; -class HttpAsyncClientV4LiveTest { + +class HttpAsyncClientV4LiveTest extends GetRequestMockServer { private static final String HOST = "http://www.google.com"; private static final String HOST_WITH_SSL = "https://mms.nw.ru/"; @@ -87,7 +88,7 @@ class HttpAsyncClientV4LiveTest { void whenUseProxyWithHttpClient_thenCorrect() throws Exception { final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault(); client.start(); - final HttpHost proxy = new HttpHost("127.0.0.1", 8080); + final HttpHost proxy = new HttpHost("127.0.0.1", GetRequestMockServer.serverPort); final RequestConfig config = RequestConfig.custom().setProxy(proxy).build(); final HttpGet request = new HttpGet(HOST_WITH_PROXY); request.setConfig(config); diff --git a/apache-kafka-2/README.md b/apache-kafka-2/README.md index e86504d605..9a5f6e15ae 100644 --- a/apache-kafka-2/README.md +++ b/apache-kafka-2/README.md @@ -9,3 +9,5 @@ You can build the project from the command line using: *mvn clean install*, or i - [Guide to Check if Apache Kafka Server Is Running](https://www.baeldung.com/apache-kafka-check-server-is-running) - [Add Custom Headers to a Kafka Message](https://www.baeldung.com/java-kafka-custom-headers) - [Get Last N Messages in Apache Kafka Topic](https://www.baeldung.com/java-apache-kafka-get-last-n-messages) +- [Is a Key Required as Part of Sending Messages to Kafka?](https://www.baeldung.com/java-kafka-message-key) +- [Read Data From the Beginning Using Kafka Consumer API](https://www.baeldung.com/java-kafka-consumer-api-read) diff --git a/apache-poi-2/pom.xml b/apache-poi-2/pom.xml index af959292fa..9a01a76d73 100644 --- a/apache-poi-2/pom.xml +++ b/apache-poi-2/pom.xml @@ -1,7 +1,7 @@ - + 4.0.0 apache-poi-2 0.0.1-SNAPSHOT @@ -19,10 +19,15 @@ poi-ooxml ${poi.version} + + org.apache.poi + poi-scratchpad + ${poi.version} + - 5.2.0 + 5.2.3 \ No newline at end of file diff --git a/apache-poi-2/src/main/java/com/baeldung/poi/replacevariables/DocTextReplacer.java b/apache-poi-2/src/main/java/com/baeldung/poi/replacevariables/DocTextReplacer.java new file mode 100644 index 0000000000..f661551ce9 --- /dev/null +++ b/apache-poi-2/src/main/java/com/baeldung/poi/replacevariables/DocTextReplacer.java @@ -0,0 +1,38 @@ +package com.baeldung.poi.replacevariables; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.poi.hwpf.HWPFDocument; +import org.apache.poi.hwpf.usermodel.Range; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; + +public class DocTextReplacer { + + public void replaceText() throws IOException { + String filePath = getClass().getClassLoader() + .getResource("baeldung.doc") + .getPath(); + try (InputStream inputStream = new FileInputStream(filePath); POIFSFileSystem fileSystem = new POIFSFileSystem(inputStream)) { + HWPFDocument doc = new HWPFDocument(fileSystem); + doc = replaceText(doc, "Baeldung", "Hello"); + saveFile(filePath, doc); + doc.close(); + } + } + + private HWPFDocument replaceText(HWPFDocument doc, String originalText, String updatedText) { + Range range = doc.getRange(); + range.replaceText(originalText, updatedText); + return doc; + } + + private void saveFile(String filePath, HWPFDocument doc) throws IOException { + try (FileOutputStream out = new FileOutputStream(filePath)) { + doc.write(out); + } + } + +} diff --git a/apache-poi-2/src/main/java/com/baeldung/poi/replacevariables/DocxNaiveTextReplacer.java b/apache-poi-2/src/main/java/com/baeldung/poi/replacevariables/DocxNaiveTextReplacer.java new file mode 100644 index 0000000000..34c2bc43e5 --- /dev/null +++ b/apache-poi-2/src/main/java/com/baeldung/poi/replacevariables/DocxNaiveTextReplacer.java @@ -0,0 +1,63 @@ +package com.baeldung.poi.replacevariables; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFRun; +import org.apache.poi.xwpf.usermodel.XWPFTable; +import org.apache.poi.xwpf.usermodel.XWPFTableCell; +import org.apache.poi.xwpf.usermodel.XWPFTableRow; + +public class DocxNaiveTextReplacer { + + public void replaceText() throws IOException { + String filePath = getClass().getClassLoader() + .getResource("baeldung-copy.docx") + .getPath(); + try (InputStream inputStream = new FileInputStream(filePath)) { + XWPFDocument doc = new XWPFDocument(inputStream); + doc = replaceText(doc, "Baeldung", "Hello"); + saveFile(filePath, doc); + doc.close(); + } + } + + private XWPFDocument replaceText(XWPFDocument doc, String originalText, String updatedText) { + replaceTextInParagraphs(doc.getParagraphs(), originalText, updatedText); + for (XWPFTable tbl : doc.getTables()) { + for (XWPFTableRow row : tbl.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + replaceTextInParagraphs(cell.getParagraphs(), originalText, updatedText); + } + } + } + return doc; + } + + private void replaceTextInParagraphs(List paragraphs, String originalText, String updatedText) { + paragraphs.forEach(paragraph -> replaceTextInParagraph(paragraph, originalText, updatedText)); + } + + private void replaceTextInParagraph(XWPFParagraph paragraph, String originalText, String updatedText) { + List runs = paragraph.getRuns(); + for (XWPFRun run : runs) { + String text = run.getText(0); + if (text != null && text.contains(originalText)) { + String updatedRunText = text.replace(originalText, updatedText); + run.setText(updatedRunText, 0); + } + } + } + + private void saveFile(String filePath, XWPFDocument doc) throws IOException { + try (FileOutputStream out = new FileOutputStream(filePath)) { + doc.write(out); + } + } + +} diff --git a/apache-poi-2/src/main/java/com/baeldung/poi/replacevariables/DocxTextReplacer.java b/apache-poi-2/src/main/java/com/baeldung/poi/replacevariables/DocxTextReplacer.java new file mode 100644 index 0000000000..2d08d24a4e --- /dev/null +++ b/apache-poi-2/src/main/java/com/baeldung/poi/replacevariables/DocxTextReplacer.java @@ -0,0 +1,65 @@ +package com.baeldung.poi.replacevariables; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Objects; + +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFRun; +import org.apache.poi.xwpf.usermodel.XWPFTable; +import org.apache.poi.xwpf.usermodel.XWPFTableCell; +import org.apache.poi.xwpf.usermodel.XWPFTableRow; + +public class DocxTextReplacer { + + public void replaceText() throws IOException { + String filePath = getClass().getClassLoader() + .getResource("baeldung.docx") + .getPath(); + try (InputStream inputStream = new FileInputStream(filePath)) { + XWPFDocument doc = new XWPFDocument(inputStream); + doc = replaceText(doc, "Baeldung", "Hello"); + saveFile(filePath, doc); + doc.close(); + } + } + + private XWPFDocument replaceText(XWPFDocument doc, String originalText, String updatedText) { + replaceTextInParagraphs(doc.getParagraphs(), originalText, updatedText); + for (XWPFTable tbl : doc.getTables()) { + for (XWPFTableRow row : tbl.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + replaceTextInParagraphs(cell.getParagraphs(), originalText, updatedText); + } + } + } + return doc; + } + + private void replaceTextInParagraphs(List paragraphs, String originalText, String updatedText) { + paragraphs.forEach(paragraph -> replaceTextInParagraph(paragraph, originalText, updatedText)); + } + + private void replaceTextInParagraph(XWPFParagraph paragraph, String originalText, String updatedText) { + String paragraphText = paragraph.getParagraphText(); + if (paragraphText.contains(originalText)) { + String updatedParagraphText = paragraphText.replace(originalText, updatedText); + while (paragraph.getRuns().size() > 0) { + paragraph.removeRun(0); + } + XWPFRun newRun = paragraph.createRun(); + newRun.setText(updatedParagraphText); + } + } + + private void saveFile(String filePath, XWPFDocument doc) throws IOException { + try (FileOutputStream out = new FileOutputStream(filePath)) { + doc.write(out); + } + } + +} diff --git a/apache-poi-2/src/main/resources/baeldung-copy.docx b/apache-poi-2/src/main/resources/baeldung-copy.docx new file mode 100644 index 0000000000..2cb76e8ffd Binary files /dev/null and b/apache-poi-2/src/main/resources/baeldung-copy.docx differ diff --git a/apache-poi-2/src/main/resources/baeldung.doc b/apache-poi-2/src/main/resources/baeldung.doc new file mode 100644 index 0000000000..1b8474d65b Binary files /dev/null and b/apache-poi-2/src/main/resources/baeldung.doc differ diff --git a/apache-poi-2/src/main/resources/baeldung.docx b/apache-poi-2/src/main/resources/baeldung.docx new file mode 100644 index 0000000000..f0de4e057b Binary files /dev/null and b/apache-poi-2/src/main/resources/baeldung.docx differ diff --git a/apache-poi-2/src/test/java/com/baeldung/poi/replacevariables/DocTextReplacerUnitTest.java b/apache-poi-2/src/test/java/com/baeldung/poi/replacevariables/DocTextReplacerUnitTest.java new file mode 100644 index 0000000000..0c3d80a354 --- /dev/null +++ b/apache-poi-2/src/test/java/com/baeldung/poi/replacevariables/DocTextReplacerUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.poi.replacevariables; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Arrays; + +import org.apache.poi.hwpf.HWPFDocument; +import org.apache.poi.hwpf.extractor.WordExtractor; +import org.junit.jupiter.api.Test; + +class DocTextReplacerUnitTest { + + @Test + void whenReplaceText_ThenTextReplaced() throws IOException { + new DocTextReplacer().replaceText(); + + String filePath = getClass().getClassLoader() + .getResource("baeldung.doc") + .getPath(); + try (FileInputStream fis = new FileInputStream(filePath); HWPFDocument document = new HWPFDocument(fis); WordExtractor extractor = new WordExtractor(document)) { + long occurrencesOfHello = Arrays.stream(extractor.getText() + .split("\\s+")) + .filter(s -> s.contains("Hello")) + .count(); + assertEquals(5, occurrencesOfHello); + } + } + +} diff --git a/apache-poi-2/src/test/java/com/baeldung/poi/replacevariables/DocxNaiveTextReplacerUnitTest.java b/apache-poi-2/src/test/java/com/baeldung/poi/replacevariables/DocxNaiveTextReplacerUnitTest.java new file mode 100644 index 0000000000..324e63eb51 --- /dev/null +++ b/apache-poi-2/src/test/java/com/baeldung/poi/replacevariables/DocxNaiveTextReplacerUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.poi.replacevariables; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Arrays; + +import org.apache.poi.xwpf.extractor.XWPFWordExtractor; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.junit.jupiter.api.Test; + +class DocxNaiveTextReplacerUnitTest { + + @Test + void whenReplaceText_ThenTextReplaced() throws IOException { + new DocxNaiveTextReplacer().replaceText(); + + String filePath = getClass().getClassLoader() + .getResource("baeldung-copy.docx") + .getPath(); + try (FileInputStream fis = new FileInputStream(filePath); XWPFDocument document = new XWPFDocument(fis); XWPFWordExtractor extractor = new XWPFWordExtractor(document)) { + long occurrencesOfHello = Arrays.stream(extractor.getText() + .split("\\s+")) + .filter(s -> s.contains("Hello")) + .count(); + assertTrue(occurrencesOfHello < 5); + } + } + +} diff --git a/apache-poi-2/src/test/java/com/baeldung/poi/replacevariables/DocxTestReplacerUnitTest.java b/apache-poi-2/src/test/java/com/baeldung/poi/replacevariables/DocxTestReplacerUnitTest.java new file mode 100644 index 0000000000..d09f6b003d --- /dev/null +++ b/apache-poi-2/src/test/java/com/baeldung/poi/replacevariables/DocxTestReplacerUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.poi.replacevariables; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Arrays; + +import org.apache.poi.xwpf.extractor.XWPFWordExtractor; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.junit.jupiter.api.Test; + +class DocxTestReplacerUnitTest { + + @Test + void whenReplaceText_ThenTextReplaced() throws IOException { + new DocxTextReplacer().replaceText(); + + String filePath = getClass().getClassLoader() + .getResource("baeldung.docx") + .getPath(); + try (FileInputStream fis = new FileInputStream(filePath); XWPFDocument document = new XWPFDocument(fis); XWPFWordExtractor extractor = new XWPFWordExtractor(document)) { + long occurrencesOfHello = Arrays.stream(extractor.getText() + .split("\\s+")) + .filter(s -> s.contains("Hello")) + .count(); + assertEquals(5, occurrencesOfHello); + } + } + +} diff --git a/core-java-modules/core-java-arrays-guides/README.md b/core-java-modules/core-java-arrays-guides/README.md index ed10df5b00..0af77980af 100644 --- a/core-java-modules/core-java-arrays-guides/README.md +++ b/core-java-modules/core-java-arrays-guides/README.md @@ -5,7 +5,7 @@ This module contains complete guides about arrays in Java ### Relevant Articles: - [Arrays in Java: A Reference Guide](https://www.baeldung.com/java-arrays-guide) - [Guide to the java.util.Arrays Class](https://www.baeldung.com/java-util-arrays) -- [What is [Ljava.lang.Object;?](https://www.baeldung.com/java-tostring-array) +- [What Is [Ljava.lang.Object;?](https://www.baeldung.com/java-tostring-array) - [Guide to ArrayStoreException](https://www.baeldung.com/java-arraystoreexception) - [Creating a Generic Array in Java](https://www.baeldung.com/java-generic-array) - [Maximum Size of Java Arrays](https://www.baeldung.com/java-arrays-max-size) diff --git a/core-java-modules/core-java-arrays-multidimensional/README.md b/core-java-modules/core-java-arrays-multidimensional/README.md index d92747a4fb..d162eca24a 100644 --- a/core-java-modules/core-java-arrays-multidimensional/README.md +++ b/core-java-modules/core-java-arrays-multidimensional/README.md @@ -3,5 +3,5 @@ This module contains articles about multidimensional arrays in Java ### Relevant Articles: -- [Multi-Dimensional Arrays In Java](https://www.baeldung.com/java-jagged-arrays) -- [Looping Diagonally Through a 2d Java Array](https://www.baeldung.com/java-loop-diagonal-array) \ No newline at end of file +- [Multi-Dimensional Arrays in Java](https://www.baeldung.com/java-jagged-arrays) +- [Looping Diagonally Through a 2d Java Array](https://www.baeldung.com/java-loop-diagonal-array) 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 808696b580..1f55338644 100644 --- a/core-java-modules/core-java-arrays-operations-advanced/README.md +++ b/core-java-modules/core-java-arrays-operations-advanced/README.md @@ -7,7 +7,7 @@ This module contains articles about advanced operations on arrays in Java. They - [How to Copy an Array in Java](https://www.baeldung.com/java-array-copy) - [Arrays.deepEquals](https://www.baeldung.com/java-arrays-deepequals) - [Find Sum and Average in a Java Array](https://www.baeldung.com/java-array-sum-average) -- [Intersection Between two Integer Arrays](https://www.baeldung.com/java-array-intersection) +- [Intersection Between Two Integer Arrays](https://www.baeldung.com/java-array-intersection) - [Comparing Arrays in Java](https://www.baeldung.com/java-comparing-arrays) - [Concatenate Two Arrays in Java](https://www.baeldung.com/java-concatenate-arrays) - [Performance of System.arraycopy() vs. Arrays.copyOf()](https://www.baeldung.com/java-system-arraycopy-arrays-copyof-performance) diff --git a/core-java-modules/core-java-collections-2/README.md b/core-java-modules/core-java-collections-2/README.md index 5a9bae8f9f..fa4880bade 100644 --- a/core-java-modules/core-java-collections-2/README.md +++ b/core-java-modules/core-java-collections-2/README.md @@ -8,7 +8,7 @@ - [Join and Split Arrays and Collections in Java](https://www.baeldung.com/java-join-and-split) - [Java – Combine Multiple Collections](https://www.baeldung.com/java-combine-multiple-collections) - [Combining Different Types of Collections in Java](https://www.baeldung.com/java-combine-collections) -- [Shuffling Collections In Java](https://www.baeldung.com/java-shuffle-collection) +- [Shuffling Collections in Java](https://www.baeldung.com/java-shuffle-collection) - [Sorting in Java](https://www.baeldung.com/java-sorting) - [Getting the Size of an Iterable in Java](https://www.baeldung.com/java-iterable-size) - [Java Null-Safe Streams from Collections](https://www.baeldung.com/java-null-safe-streams-from-collections) diff --git a/core-java-modules/core-java-collections-conversions/README.md b/core-java-modules/core-java-collections-conversions/README.md index 5dd1848ce0..21fe45a8ec 100644 --- a/core-java-modules/core-java-collections-conversions/README.md +++ b/core-java-modules/core-java-collections-conversions/README.md @@ -3,7 +3,7 @@ This module contains articles about conversions among Collection types and arrays in Java. ### Relevant Articles: -- [Converting between an Array and a List in Java](https://www.baeldung.com/convert-array-to-list-and-list-to-array) +- [Converting Between an Array and a List in Java](https://www.baeldung.com/convert-array-to-list-and-list-to-array) - [Converting Between an Array and a Set in Java](https://www.baeldung.com/convert-array-to-set-and-set-to-array) - [Convert a Map to an Array, List or Set in Java](https://www.baeldung.com/convert-map-values-to-array-list-set) - [Converting a List to String in Java](https://www.baeldung.com/java-list-to-string) diff --git a/core-java-modules/core-java-collections-list-2/README.md b/core-java-modules/core-java-collections-list-2/README.md index 2e43f610a9..37e8ab0ee2 100644 --- a/core-java-modules/core-java-collections-list-2/README.md +++ b/core-java-modules/core-java-collections-list-2/README.md @@ -3,8 +3,8 @@ This module contains articles about the Java List collection ### Relevant Articles: -- [Check If Two Lists are Equal in Java](https://www.baeldung.com/java-test-a-list-for-ordinality-and-equality) -- [Java 8 Streams: Find Items From One List Based On Values From Another List](https://www.baeldung.com/java-streams-find-list-items) +- [Check if Two Lists Are Equal in Java](https://www.baeldung.com/java-test-a-list-for-ordinality-and-equality) +- [Java 8 Streams: Find Items From One List Based on Values From Another List](https://www.baeldung.com/java-streams-find-list-items) - [A Guide to the Java LinkedList](https://www.baeldung.com/java-linkedlist) - [Java List UnsupportedOperationException](https://www.baeldung.com/java-list-unsupported-operation-exception) - [Java List Initialization in One Line](https://www.baeldung.com/java-init-list-one-line) 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 31688bc9b1..ff40ae3725 100644 --- a/core-java-modules/core-java-collections-list-5/README.md +++ b/core-java-modules/core-java-collections-list-5/README.md @@ -7,3 +7,5 @@ This module contains articles about the Java List collection - [Finding All Duplicates in a List in Java](https://www.baeldung.com/java-list-find-duplicates) - [Moving Items Around in an Arraylist](https://www.baeldung.com/java-arraylist-move-items) - [Check if a List Contains an Element From Another List in Java](https://www.baeldung.com/java-check-elements-between-lists) +- [Array vs. List Performance in Java](https://www.baeldung.com/java-array-vs-list-performance) +- [Set Default Value for Elements in List](https://www.baeldung.com/java-list-set-default-values) diff --git a/core-java-modules/core-java-collections-list-5/src/test/java/com/baeldung/java/uniqueelements/UniqueElementsInListUnitTest.java b/core-java-modules/core-java-collections-list-5/src/test/java/com/baeldung/java/uniqueelements/UniqueElementsInListUnitTest.java new file mode 100644 index 0000000000..348a7d8807 --- /dev/null +++ b/core-java-modules/core-java-collections-list-5/src/test/java/com/baeldung/java/uniqueelements/UniqueElementsInListUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.java.uniqueelements; + +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; + +import org.junit.jupiter.api.Test; + +public class UniqueElementsInListUnitTest { + // @formatter:off + private static final List MY_LIST = Arrays.asList(new String[]{ + "Microsoft Windows", + "Mac OS", + "GNU Linux", + "Free BSD", + "GNU Linux", + "Mac OS"}); + // @formatter:on + + @Test + void whenConvertToSet_thenGetExpectedResult() { + List result = new ArrayList<>(new HashSet<>(MY_LIST)); + assertThat(result).containsExactlyInAnyOrder("Free BSD", "Microsoft Windows", "Mac OS", "GNU Linux"); + + result = new ArrayList<>(new LinkedHashSet<>(MY_LIST)); + assertThat(result).containsExactly("Microsoft Windows", "Mac OS", "GNU Linux", "Free BSD"); + } + + @Test + void whenUsingStream_thenGetExpectedResult() { + List result = MY_LIST.stream() + .distinct() + .collect(toList()); + assertThat(result).containsExactly("Microsoft Windows", "Mac OS", "GNU Linux", "Free BSD"); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-collections-list/README.md b/core-java-modules/core-java-collections-list/README.md index 5144757c80..919c64270b 100644 --- a/core-java-modules/core-java-collections-list/README.md +++ b/core-java-modules/core-java-collections-list/README.md @@ -4,8 +4,8 @@ This module contains articles about the Java List collection ### Relevant Articles: - [Java – Get Random Item/Element From a List](http://www.baeldung.com/java-random-list-element) -- [Removing all Nulls from a List in Java](http://www.baeldung.com/java-remove-nulls-from-list) -- [Removing all duplicates from a List in Java](http://www.baeldung.com/java-remove-duplicates-from-list) +- [Removing All Nulls From a List in Java](https://www.baeldung.com/java-remove-nulls-from-list) +- [Removing All Duplicates From a List in Java](https://www.baeldung.com/java-remove-duplicates-from-list) - [How to TDD a List Implementation in Java](http://www.baeldung.com/java-test-driven-list) - [Iterating Backward Through a List](http://www.baeldung.com/java-list-iterate-backwards) - [Remove the First Element from a List](http://www.baeldung.com/java-remove-first-element-from-list) diff --git a/core-java-modules/core-java-collections-maps-2/README.md b/core-java-modules/core-java-collections-maps-2/README.md index f49ba25c8c..befe6ab410 100644 --- a/core-java-modules/core-java-collections-maps-2/README.md +++ b/core-java-modules/core-java-collections-maps-2/README.md @@ -8,7 +8,7 @@ This module contains articles about Map data structures in Java. - [A Guide to Java HashMap](https://www.baeldung.com/java-hashmap) - [Guide to WeakHashMap in Java](https://www.baeldung.com/java-weakhashmap) - [Map to String Conversion in Java](https://www.baeldung.com/java-map-to-string-conversion) -- [Iterate over a Map in Java](https://www.baeldung.com/java-iterate-map) +- [Iterate Over a Map in Java](https://www.baeldung.com/java-iterate-map) - [Merging Two Maps with Java 8](https://www.baeldung.com/java-merge-maps) - [Sort a HashMap in Java](https://www.baeldung.com/java-hashmap-sort) - [Finding the Highest Value in a Java Map](https://www.baeldung.com/java-find-map-max) diff --git a/core-java-modules/core-java-collections-maps-6/README.md b/core-java-modules/core-java-collections-maps-6/README.md index fc12a1bb25..5b45752e74 100644 --- a/core-java-modules/core-java-collections-maps-6/README.md +++ b/core-java-modules/core-java-collections-maps-6/README.md @@ -1,2 +1,3 @@ ## Relevant Articles - [Copying All Keys and Values From One Hashmap Onto Another Without Replacing Existing Keys and Values](https://www.baeldung.com/java-copy-hashmap-no-changes) +- [Convert Hashmap to JSON Object in Java](https://www.baeldung.com/java-convert-hashmap-to-json-object) diff --git a/core-java-modules/core-java-collections-maps-6/src/test/com/baeldung/objecttomap/ObjectToMapUnitTest.java b/core-java-modules/core-java-collections-maps-6/src/test/com/baeldung/objecttomap/ObjectToMapUnitTest.java new file mode 100644 index 0000000000..52c2fb2bea --- /dev/null +++ b/core-java-modules/core-java-collections-maps-6/src/test/com/baeldung/objecttomap/ObjectToMapUnitTest.java @@ -0,0 +1,76 @@ +package java.com.baeldung.objecttomap; +import com.google.gson.Gson; +import org.junit.Assert; +import org.junit.Test; +import wiremock.com.fasterxml.jackson.core.type.TypeReference; +import wiremock.com.fasterxml.jackson.databind.ObjectMapper; +import wiremock.com.google.common.reflect.TypeToken; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +public class ObjectToMapUnitTest { + Employee employee = new Employee("John", 3000.0); + + @Test + public void givenJavaObject_whenUsingReflection_thenConvertToMap() throws IllegalAccessException { + Map map = convertUsingReflection(employee); + Assert.assertEquals(employee.getName(), map.get("name")); + Assert.assertEquals(employee.getSalary(), map.get("salary")); + } + + private Map convertUsingReflection(Object object) throws IllegalAccessException { + Map map = new HashMap<>(); + Field[] fields = object.getClass().getDeclaredFields(); + + for (Field field : fields) { + field.setAccessible(true); + map.put(field.getName(), field.get(object)); + } + + return map; + } + + @Test + public void givenJavaObject_whenUsingJackson_thenConvertToMap() { + ObjectMapper objectMapper = new ObjectMapper(); + Map map = objectMapper.convertValue(employee, new TypeReference>() {}); + Assert.assertEquals(employee.getName(), map.get("name")); + Assert.assertEquals(employee.getSalary(), map.get("salary")); + } + + @Test + public void givenJavaObject_whenUsingGson_thenConvertToMap() { + Gson gson = new Gson(); + String json = gson.toJson(employee); + Map map = gson.fromJson(json, new TypeToken>() {}.getType()); + Assert.assertEquals(employee.getName(), map.get("name")); + Assert.assertEquals(employee.getSalary(), map.get("salary")); + } + + private static class Employee { + private String name; + private Double salary; + + public Employee(String name, Double salary) { + this.name = name; + this.salary = salary; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Double getSalary() { + return salary; + } + + public void setSalary(Double age) { + this.salary = salary; + } + } +} diff --git a/core-java-modules/core-java-collections-maps-6/src/test/java/com/baeldung/map/generictypeconversion/ConvertMapWithTypeParamUnitTest.java b/core-java-modules/core-java-collections-maps-6/src/test/java/com/baeldung/map/generictypeconversion/ConvertMapWithTypeParamUnitTest.java new file mode 100644 index 0000000000..9548abd622 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-6/src/test/java/com/baeldung/map/generictypeconversion/ConvertMapWithTypeParamUnitTest.java @@ -0,0 +1,92 @@ +package com.baeldung.map.generictypeconversion; + +import static java.util.stream.Collectors.toMap; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import com.google.common.collect.Maps; + +public class ConvertMapWithTypeParamUnitTest { + private static final Map MAP1 = Maps.newHashMap(); + + static { + MAP1.put("K01", "GNU Linux"); + MAP1.put("K02", "Mac OS"); + MAP1.put("K03", "MS Windows"); + } + + private static final Map EXPECTED_MAP1 = Maps.newHashMap(); + + static { + EXPECTED_MAP1.put("K01", "GNU Linux"); + EXPECTED_MAP1.put("K02", "Mac OS"); + EXPECTED_MAP1.put("K03", "MS Windows"); + } + + private static final Map MAP2 = Maps.newHashMap(); + + static { + MAP2.put("K01", "GNU Linux"); + MAP2.put("K02", "Mac OS"); + MAP2.put("K03", BigDecimal.ONE); + } + + private static final Map EXPECTED_MAP2_STRING_VALUES = Maps.newHashMap(); + + static { + EXPECTED_MAP2_STRING_VALUES.put("K01", "GNU Linux"); + EXPECTED_MAP2_STRING_VALUES.put("K02", "Mac OS"); + EXPECTED_MAP2_STRING_VALUES.put("K03", "1"); + } + + @Test + void whenCastingToMap_shouldGetExpectedResult() { + Map result = (Map) MAP1; + assertEquals(EXPECTED_MAP1, result); + + Map result2 = (Map) MAP2; + assertFalse(result2.get("K03") instanceof String); + } + + Map checkAndTransform(Map inputMap) { + Map result = new HashMap<>(); + for (Map.Entry entry : inputMap.entrySet()) { + try { + result.put(entry.getKey(), (String) entry.getValue()); + } catch (ClassCastException e) { + throw e; + } + } + return result; + } + + @Test + void whenCheckAndTransform_shouldGetExpectedResult() { + Map result = checkAndTransform(MAP1); + assertEquals(EXPECTED_MAP1, result); + + assertThrows(ClassCastException.class, () -> checkAndTransform(MAP2)); + } + + @Test + void whenUsingStringValueOf_shouldGetExpectedResult() { + Map result = MAP1.entrySet() + .stream() + .collect(toMap(Map.Entry::getKey, e -> String.valueOf(e.getValue()))); + + assertEquals(EXPECTED_MAP1, result); + + Map result2 = MAP2.entrySet() + .stream() + .collect(toMap(Map.Entry::getKey, e -> String.valueOf(e.getValue()))); + + assertEquals(EXPECTED_MAP2_STRING_VALUES, result2); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-advanced-3/README.md b/core-java-modules/core-java-concurrency-advanced-3/README.md index 9495d5f479..ab541c73ae 100644 --- a/core-java-modules/core-java-concurrency-advanced-3/README.md +++ b/core-java-modules/core-java-concurrency-advanced-3/README.md @@ -15,5 +15,5 @@ This module contains articles about advanced topics about multithreading with co - [The ABA Problem in Concurrency](https://www.baeldung.com/cs/aba-concurrency) - [Introduction to Lock-Free Data Structures with Java Examples](https://www.baeldung.com/lock-free-programming) - [Introduction to Exchanger in Java](https://www.baeldung.com/java-exchanger) -- [Why Not To Start A Thread In The Constructor?](https://www.baeldung.com/java-thread-constructor) +- [Why Not to Start a Thread in the Constructor?](https://www.baeldung.com/java-thread-constructor) - [[<-- previous]](/core-java-modules/core-java-concurrency-advanced-2) diff --git a/core-java-modules/core-java-concurrency-basic-2/README.md b/core-java-modules/core-java-concurrency-basic-2/README.md index 455ff52081..91b84e3749 100644 --- a/core-java-modules/core-java-concurrency-basic-2/README.md +++ b/core-java-modules/core-java-concurrency-basic-2/README.md @@ -7,7 +7,7 @@ This module contains articles about basic Java concurrency - [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution) - [Difference Between Wait and Sleep in Java](https://www.baeldung.com/java-wait-and-sleep) - [Guide to AtomicMarkableReference](https://www.baeldung.com/java-atomicmarkablereference) -- [Why are Local Variables Thread-Safe in Java](https://www.baeldung.com/java-local-variables-thread-safe) +- [Why Are Local Variables Thread-Safe in Java](https://www.baeldung.com/java-local-variables-thread-safe) - [How to Stop Execution After a Certain Time in Java](https://www.baeldung.com/java-stop-execution-after-certain-time) - [How to Get the Number of Threads in a Java Process](https://www.baeldung.com/java-get-number-of-threads) - [Set the Name of a Thread in Java](https://www.baeldung.com/java-set-thread-name) diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/FactorialCalculator.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/FactorialCalculator.java new file mode 100644 index 0000000000..4d0c5ab69d --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/FactorialCalculator.java @@ -0,0 +1,29 @@ +package com.baeldung.concurrent.threadreturnvalue.task; + +import java.math.BigInteger; + +public class FactorialCalculator { + + public static BigInteger factorial(BigInteger end) { + BigInteger start = BigInteger.ONE; + BigInteger res = BigInteger.ONE; + + for (int i = start.add(BigInteger.ONE) + .intValue(); i <= end.intValue(); i++) { + res = res.multiply(BigInteger.valueOf(i)); + } + + return res; + } + + public static BigInteger factorial(BigInteger start, BigInteger end) { + BigInteger res = start; + + for (int i = start.add(BigInteger.ONE) + .intValue(); i <= end.intValue(); i++) { + res = res.multiply(BigInteger.valueOf(i)); + } + + return res; + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/callable/CallableExecutor.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/callable/CallableExecutor.java new file mode 100644 index 0000000000..260870d0a7 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/callable/CallableExecutor.java @@ -0,0 +1,38 @@ +package com.baeldung.concurrent.threadreturnvalue.task.callable; + +import java.math.BigInteger; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +public class CallableExecutor { + + public BigInteger execute(List tasks) { + + BigInteger result = BigInteger.ZERO; + + ExecutorService cachedPool = Executors.newCachedThreadPool(); + + List> futures; + + try { + futures = cachedPool.invokeAll(tasks); + } catch (InterruptedException e) { + // exception handling example + throw new RuntimeException(e); + } + + for (Future future : futures) { + try { + result = result.add(future.get()); + } catch (InterruptedException | ExecutionException e) { + // exception handling example + throw new RuntimeException(e); + } + } + + return result; + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/callable/CallableFactorialTask.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/callable/CallableFactorialTask.java new file mode 100644 index 0000000000..4c38d2fb19 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/callable/CallableFactorialTask.java @@ -0,0 +1,20 @@ +package com.baeldung.concurrent.threadreturnvalue.task.callable; + +import static com.baeldung.concurrent.threadreturnvalue.task.FactorialCalculator.factorial; + +import java.math.BigInteger; +import java.util.concurrent.Callable; + +public class CallableFactorialTask implements Callable { + + private final Integer value; + + public CallableFactorialTask(int value) { + this.value = value; + } + + @Override + public BigInteger call() { + return factorial(BigInteger.valueOf(value)); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/fork/ForkExecutor.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/fork/ForkExecutor.java new file mode 100644 index 0000000000..ed199973ce --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/fork/ForkExecutor.java @@ -0,0 +1,34 @@ +package com.baeldung.concurrent.threadreturnvalue.task.fork; + +import java.math.BigInteger; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.Future; + +public class ForkExecutor { + + private final ForkJoinPool forkJoinPool = ForkJoinPool.commonPool(); + + public BigInteger execute(ForkFactorialTask forkFactorial) { + return forkJoinPool.invoke(forkFactorial); + } + + public BigInteger execute(List> forkFactorials) { + List> futures = forkJoinPool.invokeAll(forkFactorials); + + BigInteger result = BigInteger.ZERO; + + for (Future future : futures) { + try { + result = result.add(future.get()); + } catch (InterruptedException | ExecutionException e) { + // exception handling example + throw new RuntimeException(e); + } + } + + return result; + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/fork/ForkFactorialTask.java b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/fork/ForkFactorialTask.java new file mode 100644 index 0000000000..b45a88655c --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/main/java/com/baeldung/concurrent/threadreturnvalue/task/fork/ForkFactorialTask.java @@ -0,0 +1,43 @@ +package com.baeldung.concurrent.threadreturnvalue.task.fork; + +import static com.baeldung.concurrent.threadreturnvalue.task.FactorialCalculator.factorial; + +import java.math.BigInteger; +import java.util.concurrent.RecursiveTask; + +public class ForkFactorialTask extends RecursiveTask { + + private final int start; + private final int end; + private final int threshold; + + public ForkFactorialTask(int end, int threshold) { + this.start = 1; + this.end = end; + this.threshold = threshold; + } + + public ForkFactorialTask(int start, int end, int threshold) { + this.start = start; + this.end = end; + this.threshold = threshold; + } + + @Override + protected BigInteger compute() { + + BigInteger sum = BigInteger.ONE; + + if (end - start > threshold) { + + int middle = (end + start) / 2; + + return sum.multiply(new ForkFactorialTask(start, middle, threshold).fork() + .join() + .multiply(new ForkFactorialTask(middle + 1, end, threshold).fork() + .join())); + } + + return sum.multiply(factorial(BigInteger.valueOf(start), BigInteger.valueOf(end))); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/threadreturnvalue/callable/CallableUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/threadreturnvalue/callable/CallableUnitTest.java new file mode 100644 index 0000000000..d9271b7603 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/threadreturnvalue/callable/CallableUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.concurrent.threadreturnvalue.callable; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigInteger; +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import com.baeldung.concurrent.threadreturnvalue.task.callable.CallableExecutor; +import com.baeldung.concurrent.threadreturnvalue.task.callable.CallableFactorialTask; + +public class CallableUnitTest { + + private final CallableExecutor callableExecutor = new CallableExecutor(); + + @Test + void givenCallableExecutor_whenExecuteFactorial_thenResultOk() { + BigInteger result = callableExecutor.execute(Arrays.asList(new CallableFactorialTask(5), new CallableFactorialTask(3))); + assertEquals(BigInteger.valueOf(126), result); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/threadreturnvalue/completableFuture/CompletableFutureUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/threadreturnvalue/completableFuture/CompletableFutureUnitTest.java new file mode 100644 index 0000000000..4322aa6847 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/threadreturnvalue/completableFuture/CompletableFutureUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.concurrent.threadreturnvalue.completableFuture; + +import static com.baeldung.concurrent.threadreturnvalue.task.FactorialCalculator.factorial; +import static java.util.concurrent.CompletableFuture.allOf; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigInteger; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; + +import org.junit.jupiter.api.Test; + +public class CompletableFutureUnitTest { + + @Test + void givenCompletableFuture_whenSupplyAsyncFactorial_thenResultOk() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> factorial(BigInteger.valueOf(10))); + assertEquals(BigInteger.valueOf(3628800), completableFuture.get()); + } + + @Test + void givenCompletableFuture_whenComposeTasks_thenResultOk() throws ExecutionException, InterruptedException { + CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> factorial(BigInteger.valueOf(3))) + .thenCompose(inputFromFirstTask -> CompletableFuture.supplyAsync(() -> factorial(inputFromFirstTask))); + assertEquals(BigInteger.valueOf(720), completableFuture.get()); + } + + @Test + void givenCompletableFuture_whenAllOfTasks_thenResultOk() { + CompletableFuture asyncTask1 = CompletableFuture.supplyAsync(() -> BigInteger.valueOf(5)); + CompletableFuture asyncTask2 = CompletableFuture.supplyAsync(() -> "3"); + + BigInteger result = allOf(asyncTask1, asyncTask2).thenApplyAsync(fn -> factorial(asyncTask1.join()).add(factorial(new BigInteger(asyncTask2.join()))), Executors.newFixedThreadPool(1)) + .join(); + + assertEquals(BigInteger.valueOf(126), result); + } +} diff --git a/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/threadreturnvalue/fork/ForkUnitTest.java b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/threadreturnvalue/fork/ForkUnitTest.java new file mode 100644 index 0000000000..5012fc3745 --- /dev/null +++ b/core-java-modules/core-java-concurrency-basic-3/src/test/java/com/baeldung/concurrent/threadreturnvalue/fork/ForkUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.concurrent.threadreturnvalue.fork; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.math.BigInteger; +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import com.baeldung.concurrent.threadreturnvalue.task.callable.CallableFactorialTask; +import com.baeldung.concurrent.threadreturnvalue.task.fork.ForkExecutor; +import com.baeldung.concurrent.threadreturnvalue.task.fork.ForkFactorialTask; + +public class ForkUnitTest { + + private final ForkExecutor forkExecutor = new ForkExecutor(); + + @Test + void givenForkExecutor_whenExecuteRecursiveTask_thenResultOk() { + assertEquals(BigInteger.valueOf(3628800), forkExecutor.execute(new ForkFactorialTask(10, 5))); + } + + @Test + void givenForkExecutor_whenExecuteCallable_thenResultOk() { + assertEquals(BigInteger.valueOf(126), forkExecutor.execute(Arrays.asList(new CallableFactorialTask(5), new CallableFactorialTask(3)))); + } +} diff --git a/core-java-modules/core-java-concurrency-basic/README.md b/core-java-modules/core-java-concurrency-basic/README.md index f1aa748c6b..137251b46a 100644 --- a/core-java-modules/core-java-concurrency-basic/README.md +++ b/core-java-modules/core-java-concurrency-basic/README.md @@ -9,5 +9,5 @@ This module contains articles about basic Java concurrency - [How to Kill a Java Thread](https://www.baeldung.com/java-thread-stop) - [ExecutorService – Waiting for Threads to Finish](https://www.baeldung.com/java-executor-wait-for-threads) - [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) +- [What Is Thread-Safety and How to Achieve It?](https://www.baeldung.com/java-thread-safety) - [[Next -->]](/core-java-modules/core-java-concurrency-basic-2) diff --git a/core-java-modules/core-java-concurrency-collections/README.md b/core-java-modules/core-java-concurrency-collections/README.md index 94f93d1bfd..1ae50531f0 100644 --- a/core-java-modules/core-java-concurrency-collections/README.md +++ b/core-java-modules/core-java-concurrency-collections/README.md @@ -7,7 +7,7 @@ This module contains articles about concurrent Java collections - [A Guide to ConcurrentMap](http://www.baeldung.com/java-concurrent-map) - [Guide to PriorityBlockingQueue in Java](http://www.baeldung.com/java-priority-blocking-queue) - [Avoiding the ConcurrentModificationException in Java](http://www.baeldung.com/java-concurrentmodificationexception) -- [Custom Thread Pools In Java 8 Parallel Streams](http://www.baeldung.com/java-8-parallel-streams-custom-threadpool) +- [Custom Thread Pools in Java 8 Parallel Streams](https://www.baeldung.com/java-8-parallel-streams-custom-threadpool) - [Guide to DelayQueue](http://www.baeldung.com/java-delay-queue) - [A Guide to Java SynchronousQueue](http://www.baeldung.com/java-synchronous-queue) - [Guide to the ConcurrentSkipListMap](http://www.baeldung.com/java-concurrent-skip-list-map) diff --git a/core-java-modules/core-java-date-operations-1/README.md b/core-java-modules/core-java-date-operations-1/README.md index b63fab63db..8c171177ee 100644 --- a/core-java-modules/core-java-date-operations-1/README.md +++ b/core-java-modules/core-java-date-operations-1/README.md @@ -10,6 +10,6 @@ This module contains articles about date operations in Java. - [Handling Daylight Savings Time in Java](http://www.baeldung.com/java-daylight-savings) - [Calculate Age in Java](http://www.baeldung.com/java-get-age) - [Increment Date in Java](http://www.baeldung.com/java-increment-date) -- [Add Hours To a Date In Java](http://www.baeldung.com/java-add-hours-date) +- [Add Hours to a Date in Java](https://www.baeldung.com/java-add-hours-date) - [Introduction to Joda-Time](http://www.baeldung.com/joda-time) -- [[Next -->]](/core-java-modules/core-java-date-operations-2) \ No newline at end of file +- [[Next -->]](/core-java-modules/core-java-date-operations-2) diff --git a/core-java-modules/core-java-date-operations-2/README.md b/core-java-modules/core-java-date-operations-2/README.md index 1555492bf6..da516b4641 100644 --- a/core-java-modules/core-java-date-operations-2/README.md +++ b/core-java-modules/core-java-date-operations-2/README.md @@ -5,10 +5,10 @@ This module contains articles about date operations in Java. - [Get the Current Date Prior to Java 8](https://www.baeldung.com/java-get-the-current-date-legacy) - [Skipping Weekends While Adding Days to LocalDate in Java 8](https://www.baeldung.com/java-localdate-add-days-skip-weekends) -- [Checking if Two Java Dates are On the Same Day](https://www.baeldung.com/java-check-two-dates-on-same-day) +- [Checking if Two Java Dates Are on the Same Day](https://www.baeldung.com/java-check-two-dates-on-same-day) - [Converting Java Date to OffsetDateTime](https://www.baeldung.com/java-convert-date-to-offsetdatetime) - [How to Set the JVM Time Zone](https://www.baeldung.com/java-jvm-time-zone) -- [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week) +- [How to Determine Day of Week by Passing Specific Date in Java?](https://www.baeldung.com/java-get-day-of-week) - [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year) - [Getting the Week Number From Any Date](https://www.baeldung.com/java-get-week-number) - [Subtract Days from a Date in Java](https://www.baeldung.com/java-subtract-days-from-date) diff --git a/core-java-modules/core-java-datetime-string/README.md b/core-java-modules/core-java-datetime-string/README.md index e22e807591..bd1a844654 100644 --- a/core-java-modules/core-java-datetime-string/README.md +++ b/core-java-modules/core-java-datetime-string/README.md @@ -4,12 +4,12 @@ This module contains articles about parsing and formatting Java date and time ob ### Relevant Articles: - [Check If a String Is a Valid Date in Java](https://www.baeldung.com/java-string-valid-date) -- [RegEx for matching Date Pattern in Java](http://www.baeldung.com/java-date-regular-expressions) +- [Regex for Matching Date Pattern in Java](https://www.baeldung.com/java-date-regular-expressions) - [Guide to DateTimeFormatter](https://www.baeldung.com/java-datetimeformatter) - [Format ZonedDateTime to String](https://www.baeldung.com/java-format-zoned-datetime-string) - [A Guide to SimpleDateFormat](https://www.baeldung.com/java-simple-date-format) -- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones) -- [Convert between String and Timestamp](https://www.baeldung.com/java-string-to-timestamp) +- [Display All Time Zones With GMT and UTC in Java](https://www.baeldung.com/java-time-zones) +- [Convert Between String and Timestamp](https://www.baeldung.com/java-string-to-timestamp) - [Convert String to Date in Java](http://www.baeldung.com/java-string-to-date) - [Format a Milliseconds Duration to HH:MM:SS](https://www.baeldung.com/java-ms-to-hhmmss) - [Format Instant to String in Java](https://www.baeldung.com/java-instant-to-string) diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md index 9bd55abac4..d62fd3dbd1 100644 --- a/core-java-modules/core-java-io-apis-2/README.md +++ b/core-java-modules/core-java-io-apis-2/README.md @@ -12,3 +12,5 @@ This module contains articles about core Java input/output(IO) APIs. - [Storing Java Scanner Input in an Array](https://www.baeldung.com/java-store-scanner-input-in-array) - [How to Take Input as String With Spaces in Java Using Scanner?](https://www.baeldung.com/java-scanner-input-with-spaces) - [Write Console Output to Text File in Java](https://www.baeldung.com/java-write-console-output-file) +- [What’s the difference between Scanner next() and nextLine() methods?](https://www.baeldung.com/java-scanner-next-vs-nextline) +- [Handle NoSuchElementException When Reading a File Through Scanner](https://www.baeldung.com/java-scanner-nosuchelementexception-reading-file) diff --git a/core-java-modules/core-java-lang-2/README.md b/core-java-modules/core-java-lang-2/README.md index c043d29811..2d69ef23c2 100644 --- a/core-java-modules/core-java-lang-2/README.md +++ b/core-java-modules/core-java-lang-2/README.md @@ -3,9 +3,9 @@ This module contains articles about core features in the Java language ### Relevant Articles: -- [Java Primitives versus Objects](https://www.baeldung.com/java-primitives-vs-objects) +- [Java Primitives Versus Objects](https://www.baeldung.com/java-primitives-vs-objects) - [Command-Line Arguments in Java](https://www.baeldung.com/java-command-line-arguments) -- [What is a POJO Class?](https://www.baeldung.com/java-pojo-class) +- [What Is a Pojo Class?](baeldung.com/java-pojo-class) - [Java Default Parameters Using Method Overloading](https://www.baeldung.com/java-default-parameters-method-overloading) - [How to Return Multiple Values From a Java Method](https://www.baeldung.com/java-method-return-multiple-values) - [Guide to the Java finally Keyword](https://www.baeldung.com/java-finally-keyword) diff --git a/core-java-modules/core-java-lang-3/README.md b/core-java-modules/core-java-lang-3/README.md index d0505dfee1..f0e7c8b7b4 100644 --- a/core-java-modules/core-java-lang-3/README.md +++ b/core-java-modules/core-java-lang-3/README.md @@ -4,7 +4,7 @@ This module contains articles about core features in the Java language - [Class.isInstance vs Class.isAssignableFrom and instanceof](https://www.baeldung.com/java-isinstance-isassignablefrom) - [Converting a Java String Into a Boolean](https://www.baeldung.com/java-string-to-boolean) -- [When are Static Variables Initialized in Java?](https://www.baeldung.com/java-static-variables-initialization) +- [When Are Static Variables Initialized in Java?](https://www.baeldung.com/java-static-variables-initialization) - [Checking if a Class Exists in Java](https://www.baeldung.com/java-check-class-exists) - [The Difference Between a.getClass() and A.class in Java](https://www.baeldung.com/java-getclass-vs-class) - [Constants in Java: Patterns and Anti-Patterns](https://www.baeldung.com/java-constants-good-practices) diff --git a/core-java-modules/core-java-lang-math-2/README.md b/core-java-modules/core-java-lang-math-2/README.md index 5e1dc5af0e..9567ea6fb6 100644 --- a/core-java-modules/core-java-lang-math-2/README.md +++ b/core-java-modules/core-java-lang-math-2/README.md @@ -6,7 +6,7 @@ - [Calculate Factorial in Java](https://www.baeldung.com/java-calculate-factorial) - [Generate Combinations in Java](https://www.baeldung.com/java-combinations-algorithm) -- [Check If Two Rectangles Overlap In Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap) +- [Check if Two Rectangles Overlap in Java](https://www.baeldung.com/java-check-if-two-rectangles-overlap) - [Calculate the Distance Between Two Points in Java](https://www.baeldung.com/java-distance-between-two-points) - [Find the Intersection of Two Lines in Java](https://www.baeldung.com/java-intersection-of-two-lines) - [Round Up to the Nearest Hundred in Java](https://www.baeldung.com/java-round-up-nearest-hundred) diff --git a/core-java-modules/core-java-lang-oop-types/README.md b/core-java-modules/core-java-lang-oop-types/README.md index 7978cb7730..ec2230f06a 100644 --- a/core-java-modules/core-java-lang-oop-types/README.md +++ b/core-java-modules/core-java-lang-oop-types/README.md @@ -8,7 +8,7 @@ This module contains articles about types in Java - [Guide to the this Java Keyword](https://www.baeldung.com/java-this) - [Nested Classes in Java](https://www.baeldung.com/java-nested-classes) - [Marker Interfaces in Java](https://www.baeldung.com/java-marker-interfaces) -- [Iterating over Enum Values in Java](https://www.baeldung.com/java-enum-iteration) +- [Iterating Over Enum Values in Java](https://www.baeldung.com/java-enum-iteration) - [Attaching Values to Java Enum](https://www.baeldung.com/java-enum-values) - [A Guide to Java Enums](https://www.baeldung.com/a-guide-to-java-enums) - [Determine if an Object Is of Primitive Type](https://www.baeldung.com/java-object-primitive-type) diff --git a/core-java-modules/core-java-lang-operators/README.md b/core-java-modules/core-java-lang-operators/README.md index 3e2afd1489..52906f292e 100644 --- a/core-java-modules/core-java-lang-operators/README.md +++ b/core-java-modules/core-java-lang-operators/README.md @@ -4,7 +4,7 @@ This module contains articles about Java operators ## Relevant Articles: - [Guide to the Diamond Operator in Java](https://www.baeldung.com/java-diamond-operator) -- [Ternary Operator In Java](https://www.baeldung.com/java-ternary-operator) +- [Ternary Operator in Java](https://www.baeldung.com/java-ternary-operator) - [The Modulo Operator in Java](https://www.baeldung.com/modulo-java) - [Java instanceof Operator](https://www.baeldung.com/java-instanceof) - [A Guide to Increment and Decrement Unary Operators in Java](https://www.baeldung.com/java-unary-operators) diff --git a/core-java-modules/core-java-lang/README.md b/core-java-modules/core-java-lang/README.md index 963a1e623e..93b4c25fd9 100644 --- a/core-java-modules/core-java-lang/README.md +++ b/core-java-modules/core-java-lang/README.md @@ -5,7 +5,7 @@ This module contains articles about core features in the Java language ### Relevant Articles: - [Generate equals() and hashCode() with Eclipse](https://www.baeldung.com/java-eclipse-equals-and-hashcode) - [Comparator and Comparable in Java](https://www.baeldung.com/java-comparator-comparable) -- [Recursion In Java](https://www.baeldung.com/java-recursion) +- [Recursion in Java](https://www.baeldung.com/java-recursion) - [A Guide to the finalize Method in Java](https://www.baeldung.com/java-finalize) - [Quick Guide to java.lang.System](https://www.baeldung.com/java-lang-system) - [Using Java Assertions](https://www.baeldung.com/java-assert) diff --git a/core-java-modules/core-java-networking-2/README.md b/core-java-modules/core-java-networking-2/README.md index c223e20a84..220ff8ad3d 100644 --- a/core-java-modules/core-java-networking-2/README.md +++ b/core-java-modules/core-java-networking-2/README.md @@ -12,6 +12,6 @@ This module contains articles about networking in Java - [Authentication with HttpUrlConnection](https://www.baeldung.com/java-http-url-connection) - [Download a File From an URL in Java](https://www.baeldung.com/java-download-file) - [Handling java.net.ConnectException](https://www.baeldung.com/java-net-connectexception) -- [Getting MAC addresses in Java](https://www.baeldung.com/java-mac-address) +- [Getting MAC Addresses in Java](https://www.baeldung.com/java-mac-address) - [Sending Emails with Attachments in Java](https://www.baeldung.com/java-send-emails-attachments) - [[<-- Prev]](/core-java-modules/core-java-networking) diff --git a/core-java-modules/core-java-networking/README.md b/core-java-modules/core-java-networking/README.md index 4038e9803a..893efa4c55 100644 --- a/core-java-modules/core-java-networking/README.md +++ b/core-java-modules/core-java-networking/README.md @@ -6,12 +6,12 @@ This module contains articles about networking in Java - [Connecting Through Proxy Servers in Core Java](https://www.baeldung.com/java-connect-via-proxy-server) - [Broadcasting and Multicasting in Java](http://www.baeldung.com/java-broadcast-multicast) -- [A Guide To UDP In Java](http://www.baeldung.com/udp-in-java) -- [A Guide To HTTP Cookies In Java](http://www.baeldung.com/cookies-java) +- [A Guide to UDP In Java](https://www.baeldung.com/udp-in-java) +- [A Guide to HTTP Cookies in Java](https://www.baeldung.com/cookies-java) - [A Guide to the Java URL](http://www.baeldung.com/java-url) - [Working with Network Interfaces in Java](http://www.baeldung.com/java-network-interfaces) - [A Guide to Java Sockets](http://www.baeldung.com/a-guide-to-java-sockets) - [Guide to Java URL Encoding/Decoding](http://www.baeldung.com/java-url-encoding-decoding) -- [Difference between URL and URI](http://www.baeldung.com/java-url-vs-uri) +- [Difference Between URL and URI](https://www.baeldung.com/java-url-vs-uri) - [Read an InputStream using the Java Server Socket](https://www.baeldung.com/java-inputstream-server-socket) - [[More -->]](/core-java-modules/core-java-networking-2) diff --git a/core-java-modules/core-java-reflection-private-constructor/README.md b/core-java-modules/core-java-reflection-private-constructor/README.md index a3c9d00b0a..7d843af9ea 100644 --- a/core-java-modules/core-java-reflection-private-constructor/README.md +++ b/core-java-modules/core-java-reflection-private-constructor/README.md @@ -1,10 +1 @@ ### Relevant Articles: - -- [Reading the Value of ‘private’ Fields from a Different Class in Java](https://www.baeldung.com/java-reflection-read-private-field-value) -- [Set Field Value With Reflection](https://www.baeldung.com/java-set-private-field-value) -- [Checking If a Method is Static Using Reflection in Java](https://www.baeldung.com/java-check-method-is-static) -- [Checking if a Java Class is ‘abstract’ Using Reflection](https://www.baeldung.com/java-reflection-is-class-abstract) -- [Invoking a Private Method in Java](https://www.baeldung.com/java-call-private-method) -- [Finding All Classes in a Java Package](https://www.baeldung.com/java-find-all-classes-in-package) -- [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) diff --git a/core-java-modules/core-java-reflection/README.md b/core-java-modules/core-java-reflection/README.md index b823f43606..e7c931575a 100644 --- a/core-java-modules/core-java-reflection/README.md +++ b/core-java-modules/core-java-reflection/README.md @@ -3,7 +3,7 @@ - [Void Type in Java](https://www.baeldung.com/java-void-type) - [Retrieve Fields from a Java Class Using Reflection](https://www.baeldung.com/java-reflection-class-fields) - [Method Parameter Reflection in Java](http://www.baeldung.com/java-parameter-reflection) -- [Changing Annotation Parameters At Runtime](http://www.baeldung.com/java-reflection-change-annotation-params) +- [Changing Annotation Parameters at Runtime](https://www.baeldung.com/java-reflection-change-annotation-params) - [Dynamic Proxies in Java](http://www.baeldung.com/java-dynamic-proxies) - [What Causes java.lang.reflect.InvocationTargetException?](https://www.baeldung.com/java-lang-reflect-invocationtargetexception) - [How to Get a Name of a Method Being Executed?](http://www.baeldung.com/java-name-of-executing-method) diff --git a/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/z_regexp/ZRegularExpressionUnitTest.java b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/z_regexp/ZRegularExpressionUnitTest.java index 90bbbb6540..a24682fc1a 100644 --- a/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/z_regexp/ZRegularExpressionUnitTest.java +++ b/core-java-modules/core-java-regex-2/src/test/java/com/baeldung/regex/z_regexp/ZRegularExpressionUnitTest.java @@ -3,33 +3,81 @@ package com.baeldung.regex.z_regexp; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.regex.Pattern; public class ZRegularExpressionUnitTest { @Test public void givenCreditCardNumber_thenReturnIfMatched() { String creditCardNumber = "1234567890123456"; + String creditCardNumber2 = "1234567890123456\n"; String pattern = "\\d{16}\\z"; - Assertions.assertTrue(creditCardNumber.matches(pattern)); + Assertions.assertTrue(Pattern.compile(pattern).matcher(creditCardNumber).find()); + Assertions.assertFalse(Pattern.compile(pattern).matcher(creditCardNumber2).find()); + } + + @Test + public void givenCreditCardNumber_thenReturnIfNotMatched() { + String creditCardNumber = "1234567890123456\n"; + String pattern = "\\d{16}\\z"; + Assertions.assertFalse(Pattern.compile(pattern).matcher(creditCardNumber).find()); } @Test public void givenLogOutput_thenReturnIfMatched() { String logLine = "2022-05-01 14:30:00,123 INFO Some log message"; String pattern = ".*message\\z"; - Assertions.assertTrue(logLine.matches(pattern)); + Assertions.assertTrue(Pattern.compile(pattern).matcher(logLine).find()); } + @Test + public void givenLogOutput_thenReturnIfNotMatched() { + String logLine = "2022-05-01 14:30:00,123 INFO Some log message\n"; + String pattern = ".*message\\z"; + Assertions.assertFalse(Pattern.compile(pattern).matcher(logLine).find()); + } @Test public void givenEmailMessage_thenReturnIfMatched() { String myMessage = "Hello HR, I hope i can write to Baeldung\n"; - String pattern = ".*Baeldung\\s*\\Z"; - Assertions.assertTrue(myMessage.matches(pattern)); + String myMessage2 = "Hello HR, I hope\n i can write to Baeldung"; + String pattern = ".*Baeldung\\Z"; + String pattern2 = ".*hope\\Z"; + Assertions.assertTrue(Pattern.compile(pattern).matcher(myMessage).find()); + Assertions.assertFalse(Pattern.compile(pattern2).matcher(myMessage2).find()); + } + + @Test + public void givenEmailMessage_thenReturnIfNotMatched() { + String myMessage = "Hello HR, I hope\n i can write to Baeldung"; + String pattern = ".*hope\\Z"; + Assertions.assertFalse(Pattern.compile(pattern).matcher(myMessage).find()); } @Test public void givenFileExtension_thenReturnIfMatched() { - String fileName = "image.jpeg"; + String fileName = "image.jpeg\n"; + String fileName2 = "image2.jpeg\n.png"; String pattern = ".*\\.jpeg\\Z"; - Assertions.assertTrue(fileName.matches(pattern)); + Assertions.assertTrue(Pattern.compile(pattern).matcher(fileName).find()); + Assertions.assertFalse(Pattern.compile(pattern).matcher(fileName2).find()); } -} + @Test + public void givenFileExtension_thenReturnIfNotMatched() { + String fileName = "image2.jpeg\n.png"; + String pattern = ".*\\.jpeg\\Z"; + Assertions.assertFalse(Pattern.compile(pattern).matcher(fileName).find()); + } + @Test + public void givenURL_thenReturnIfMatched() { + String url = "https://www.example.com/api/endpoint\n"; + String pattern = ".*/endpoint$"; + Assertions.assertTrue(Pattern.compile(pattern).matcher(url).find()); + } + + @Test + public void givenSentence_thenReturnIfMatched() { + String sentence = "Hello, how are you?"; + String pattern = ".*[.?!]$"; + Assertions.assertTrue(Pattern.compile(pattern).matcher(sentence).find()); + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-security-2/README.md b/core-java-modules/core-java-security-2/README.md index 7128c39713..1c6313b9dd 100644 --- a/core-java-modules/core-java-security-2/README.md +++ b/core-java-modules/core-java-security-2/README.md @@ -4,7 +4,7 @@ This module contains articles about core Java Security ### Relevant Articles: -- [Guide To The Java Authentication And Authorization Service (JAAS)](https://www.baeldung.com/java-authentication-authorization-service) +- [Guide to the Java Authentication And Authorization Service (JAAS)](https://www.baeldung.com/java-authentication-authorization-service) - [MD5 Hashing in Java](http://www.baeldung.com/java-md5) - [Hashing a Password in Java](https://www.baeldung.com/java-password-hashing) - [SHA-256 and SHA3-256 Hashing in Java](https://www.baeldung.com/sha-256-hashing-java) diff --git a/core-java-modules/core-java-serialization/README.md b/core-java-modules/core-java-serialization/README.md index fc6cfcf134..ed8f8dc1c6 100644 --- a/core-java-modules/core-java-serialization/README.md +++ b/core-java-modules/core-java-serialization/README.md @@ -6,4 +6,5 @@ - [Introduction to Java Serialization](http://www.baeldung.com/java-serialization) - [Deserialization Vulnerabilities in Java](https://www.baeldung.com/java-deserialization-vulnerabilities) - [Serialization Validation in Java](https://www.baeldung.com/java-validate-serializable) -- [What is the serialVersionUID?](http://www.baeldung.com/java-serial-version-uid) +- [What Is the serialVersionUID?](https://www.baeldung.com/java-serial-version-uid) +- [Java Serialization: readObject() vs. readResolve()](https://www.baeldung.com/java-serialization-readobject-vs-readresolve) diff --git a/core-java-modules/core-java-streams/README.md b/core-java-modules/core-java-streams/README.md index b950325e40..360f7190ea 100644 --- a/core-java-modules/core-java-streams/README.md +++ b/core-java-modules/core-java-streams/README.md @@ -12,5 +12,5 @@ This module contains articles about the Stream API in Java. - [Java Stream Filter with Lambda Expression](https://www.baeldung.com/java-stream-filter-lambda) - [Counting Matches on a Stream Filter](https://www.baeldung.com/java-stream-filter-count) - [Summing Numbers with Java Streams](https://www.baeldung.com/java-stream-sum) -- [How to Find all Getters Returning Null](https://www.baeldung.com/java-getters-returning-null) +- [How to Find All Getters Returning Null](https://www.baeldung.com/java-getters-returning-null) - More articles: [[next -->]](/../core-java-streams-2) diff --git a/core-java-modules/core-java-string-algorithms-2/README.md b/core-java-modules/core-java-string-algorithms-2/README.md index 5d39291cfb..dbfbb3ef3c 100644 --- a/core-java-modules/core-java-string-algorithms-2/README.md +++ b/core-java-modules/core-java-string-algorithms-2/README.md @@ -6,7 +6,7 @@ This module contains articles about string-related algorithms. - [How to Remove the Last Character of a String?](https://www.baeldung.com/java-remove-last-character-of-string) - [Add a Character to a String at a Given Position](https://www.baeldung.com/java-add-character-to-string) - [Java Check a String for Lowercase/Uppercase Letter, Special Character and Digit](https://www.baeldung.com/java-lowercase-uppercase-special-character-digit-regex) -- [Remove or Replace part of a String in Java](https://www.baeldung.com/java-remove-replace-string-part) +- [Remove or Replace Part of a String in Java](https://www.baeldung.com/java-remove-replace-string-part) - [Replace a Character at a Specific Index in a String in Java](https://www.baeldung.com/java-replace-character-at-index) - [Join Array of Primitives with Separator in Java](https://www.baeldung.com/java-join-primitive-array) - [Pad a String with Zeros or Spaces in Java](https://www.baeldung.com/java-pad-string) 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 bc6b6f2167..6af818b52d 100644 --- a/core-java-modules/core-java-string-algorithms-3/README.md +++ b/core-java-modules/core-java-string-algorithms-3/README.md @@ -5,7 +5,7 @@ This module contains articles about string-related algorithms. ### Relevant Articles: - [Generating a Java String of N Repeated Characters](https://www.baeldung.com/java-string-of-repeated-characters) -- [Check if Two Strings are Anagrams in Java](https://www.baeldung.com/java-strings-anagrams) +- [Check if Two Strings Are Anagrams in Java](https://www.baeldung.com/java-strings-anagrams) - [Email Validation in Java](https://www.baeldung.com/java-email-validation-regex) - [Check if the First Letter of a String Is Uppercase](https://www.baeldung.com/java-check-first-letter-uppercase) - [Find the First Non Repeating Character in a String in Java](https://www.baeldung.com/java-find-the-first-non-repeating-character) diff --git a/core-java-modules/core-java-string-algorithms/README.md b/core-java-modules/core-java-string-algorithms/README.md index e8c8e32da8..5a7abf074a 100644 --- a/core-java-modules/core-java-string-algorithms/README.md +++ b/core-java-modules/core-java-string-algorithms/README.md @@ -3,13 +3,13 @@ This module contains articles about string-related algorithms. ### Relevant Articles: -- [Check if a String is a Palindrome in Java](https://www.baeldung.com/java-palindrome) +- [Check if a String Is a Palindrome in Java](https://www.baeldung.com/java-palindrome) - [Count Occurrences of a Char in a String](https://www.baeldung.com/java-count-chars) - [Using indexOf to Find All Occurrences of a Word in a String](https://www.baeldung.com/java-indexof-find-string-occurrences) - [Removing Stopwords from a String in Java](https://www.baeldung.com/java-string-remove-stopwords) - [Removing Repeated Characters from a String](https://www.baeldung.com/java-remove-repeated-char) - [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 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) diff --git a/core-java-modules/core-java-string-operations-2/README.md b/core-java-modules/core-java-string-operations-2/README.md index f95b002906..871b5525cd 100644 --- a/core-java-modules/core-java-string-operations-2/README.md +++ b/core-java-modules/core-java-string-operations-2/README.md @@ -3,7 +3,7 @@ This module contains articles about string operations. ### Relevant Articles: -- [Concatenating Strings In Java](https://www.baeldung.com/java-strings-concatenation) +- [Concatenating Strings in Java](https://www.baeldung.com/java-strings-concatenation) - [Checking for Empty or Blank Strings in Java](https://www.baeldung.com/java-blank-empty-strings) - [String Initialization in Java](https://www.baeldung.com/java-string-initialization) - [String toLowerCase and toUpperCase Methods in Java](https://www.baeldung.com/java-string-convert-case) diff --git a/gradle-modules/gradle-customization/protobuf/README.md b/gradle-modules/gradle-customization/gradle-protobuf/README.md similarity index 100% rename from gradle-modules/gradle-customization/protobuf/README.md rename to gradle-modules/gradle-customization/gradle-protobuf/README.md diff --git a/gradle-modules/gradle-customization/protobuf/build.gradle b/gradle-modules/gradle-customization/gradle-protobuf/build.gradle similarity index 100% rename from gradle-modules/gradle-customization/protobuf/build.gradle rename to gradle-modules/gradle-customization/gradle-protobuf/build.gradle diff --git a/gradle-modules/gradle-customization/protobuf/gradle/wrapper/gradle-wrapper.properties b/gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from gradle-modules/gradle-customization/protobuf/gradle/wrapper/gradle-wrapper.properties rename to gradle-modules/gradle-customization/gradle-protobuf/gradle/wrapper/gradle-wrapper.properties diff --git a/gradle-modules/gradle-customization/protobuf/gradlew b/gradle-modules/gradle-customization/gradle-protobuf/gradlew similarity index 100% rename from gradle-modules/gradle-customization/protobuf/gradlew rename to gradle-modules/gradle-customization/gradle-protobuf/gradlew diff --git a/gradle-modules/gradle-customization/protobuf/gradlew.bat b/gradle-modules/gradle-customization/gradle-protobuf/gradlew.bat similarity index 100% rename from gradle-modules/gradle-customization/protobuf/gradlew.bat rename to gradle-modules/gradle-customization/gradle-protobuf/gradlew.bat diff --git a/gradle-modules/gradle-customization/gradle-protobuf/settings.gradle b/gradle-modules/gradle-customization/gradle-protobuf/settings.gradle new file mode 100644 index 0000000000..8f8b559eb6 --- /dev/null +++ b/gradle-modules/gradle-customization/gradle-protobuf/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'gradle-protobuf' diff --git a/gradle-modules/gradle-customization/protobuf/src/main/resources/application.properties b/gradle-modules/gradle-customization/gradle-protobuf/src/main/resources/application.properties similarity index 100% rename from gradle-modules/gradle-customization/protobuf/src/main/resources/application.properties rename to gradle-modules/gradle-customization/gradle-protobuf/src/main/resources/application.properties diff --git a/gradle-modules/gradle-customization/protobuf/src/sample_protofiles/user_message.proto b/gradle-modules/gradle-customization/gradle-protobuf/src/sample_protofiles/user_message.proto similarity index 100% rename from gradle-modules/gradle-customization/protobuf/src/sample_protofiles/user_message.proto rename to gradle-modules/gradle-customization/gradle-protobuf/src/sample_protofiles/user_message.proto diff --git a/gradle-modules/gradle-customization/protobuf/src/test/java/com/baeldung/protobuf/ProtobufCodeGenerationUnitTest.java b/gradle-modules/gradle-customization/gradle-protobuf/src/test/java/com/baeldung/protobuf/ProtobufCodeGenerationUnitTest.java similarity index 100% rename from gradle-modules/gradle-customization/protobuf/src/test/java/com/baeldung/protobuf/ProtobufCodeGenerationUnitTest.java rename to gradle-modules/gradle-customization/gradle-protobuf/src/test/java/com/baeldung/protobuf/ProtobufCodeGenerationUnitTest.java diff --git a/gradle-modules/gradle-customization/protobuf/settings.gradle b/gradle-modules/gradle-customization/protobuf/settings.gradle deleted file mode 100644 index 63483bae11..0000000000 --- a/gradle-modules/gradle-customization/protobuf/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'protobuf' diff --git a/jackson-modules/jackson-conversions/README.md b/jackson-modules/jackson-conversions/README.md index 5984ad399a..55dcb60c29 100644 --- a/jackson-modules/jackson-conversions/README.md +++ b/jackson-modules/jackson-conversions/README.md @@ -5,7 +5,7 @@ This module contains articles about Jackson conversions. ### Relevant Articles: - [Jackson – Unmarshall to Collection/Array](https://www.baeldung.com/jackson-collection-array) - [Jackson Date](https://www.baeldung.com/jackson-serialize-dates) -- [Jackson – Working with Maps and nulls](https://www.baeldung.com/jackson-map-null-values-or-null-key) +- [Jackson – Working With Maps and Nulls](https://www.baeldung.com/jackson-map-null-values-or-null-key) - [Jackson – Decide What Fields Get Serialized/Deserialized](https://www.baeldung.com/jackson-field-serializable-deserializable-or-not) - [XML Serialization and Deserialization with Jackson](https://www.baeldung.com/jackson-xml-serialization-and-deserialization) - [Map Serialization and Deserialization with Jackson](https://www.baeldung.com/jackson-map) diff --git a/jackson-modules/jackson-custom-conversions/README.md b/jackson-modules/jackson-custom-conversions/README.md index 2f45a2f43b..68a48511d9 100644 --- a/jackson-modules/jackson-custom-conversions/README.md +++ b/jackson-modules/jackson-custom-conversions/README.md @@ -5,6 +5,6 @@ This module contains articles about Jackson custom conversions. ### Relevant Articles: - [Jackson – Custom Serializer](https://www.baeldung.com/jackson-custom-serialization) - [Getting Started with Custom Deserialization in Jackson](https://www.baeldung.com/jackson-deserialization) -- [Serialize Only Fields that meet a Custom Criteria with Jackson](https://www.baeldung.com/jackson-serialize-field-custom-criteria) +- [Serialize Only Fields That Meet a Custom Criteria With Jackson](https://www.baeldung.com/jackson-serialize-field-custom-criteria) - [Calling Default Serializer from Custom Serializer in Jackson](https://www.baeldung.com/jackson-call-default-serializer-from-custom-serializer) - [OffsetDateTime Serialization With Jackson](https://www.baeldung.com/java-jackson-offsetdatetime) diff --git a/javaxval/README.md b/javaxval/README.md index b7e19d5794..7420580f8e 100644 --- a/javaxval/README.md +++ b/javaxval/README.md @@ -4,11 +4,11 @@ This module contains articles about Bean Validation. ### Relevant Articles: - [Java Bean Validation Basics](https://www.baeldung.com/javax-validation) -- [Validating Container Elements with Bean Validation 2.0](https://www.baeldung.com/bean-validation-container-elements) +- [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) - [Grouping Javax Validation Constraints](https://www.baeldung.com/javax-validation-groups) - [Constraint Composition with Bean Validation](https://www.baeldung.com/java-bean-validation-constraint-composition) - [Using @NotNull on a Method Parameter](https://www.baeldung.com/java-notnull-method-parameter) - [Difference Between @NotNull, @NotEmpty, and @NotBlank Constraints in Bean Validation](https://www.baeldung.com/java-bean-validation-not-null-empty-blank) -- More articles: [[next -->]](../javaxval-2) \ No newline at end of file +- More articles: [[next -->]](../javaxval-2) diff --git a/json-modules/gson-2/README.md b/json-modules/gson-2/README.md index 40d5515567..5580479753 100644 --- a/json-modules/gson-2/README.md +++ b/json-modules/gson-2/README.md @@ -3,5 +3,5 @@ This module contains articles about Gson ### Relevant Articles: - +- [Solving Gson Parsing Errors](https://www.baeldung.com/gson-parsing-errors) diff --git a/jsoup/README.md b/jsoup/README.md index 42b30d4d83..3a8a7f0ebb 100644 --- a/jsoup/README.md +++ b/jsoup/README.md @@ -4,7 +4,7 @@ This module contains articles about jsoup. ### Relevant Articles: - [Parsing HTML in Java with Jsoup](https://www.baeldung.com/java-with-jsoup) -- [How to add proxy support to Jsoup?](https://www.baeldung.com/java-jsoup-proxy) +- [How to Add Proxy Support to Jsoup?](https://www.baeldung.com/java-jsoup-proxy) - [Preserving Line Breaks When Using Jsoup](https://www.baeldung.com/jsoup-line-breaks) ### Build the Project diff --git a/kubernetes-modules/Deployment_Vs_StatefulSet/Deployment/Deployment.yaml b/kubernetes-modules/deployment-and-statefulset-configs/Deployment/Deployment.yaml similarity index 100% rename from kubernetes-modules/Deployment_Vs_StatefulSet/Deployment/Deployment.yaml rename to kubernetes-modules/deployment-and-statefulset-configs/Deployment/Deployment.yaml diff --git a/kubernetes-modules/Deployment_Vs_StatefulSet/Deployment/PersitantVoulumeClaim.yaml b/kubernetes-modules/deployment-and-statefulset-configs/Deployment/PersitantVoulumeClaim.yaml similarity index 100% rename from kubernetes-modules/Deployment_Vs_StatefulSet/Deployment/PersitantVoulumeClaim.yaml rename to kubernetes-modules/deployment-and-statefulset-configs/Deployment/PersitantVoulumeClaim.yaml diff --git a/kubernetes-modules/Deployment_Vs_StatefulSet/Deployment/Service.yaml b/kubernetes-modules/deployment-and-statefulset-configs/Deployment/Service.yaml similarity index 100% rename from kubernetes-modules/Deployment_Vs_StatefulSet/Deployment/Service.yaml rename to kubernetes-modules/deployment-and-statefulset-configs/Deployment/Service.yaml diff --git a/kubernetes-modules/Deployment_Vs_StatefulSet/StatefulSets/PersistantVolumeClaim.yaml b/kubernetes-modules/deployment-and-statefulset-configs/StatefulSets/PersistantVolumeClaim.yaml similarity index 100% rename from kubernetes-modules/Deployment_Vs_StatefulSet/StatefulSets/PersistantVolumeClaim.yaml rename to kubernetes-modules/deployment-and-statefulset-configs/StatefulSets/PersistantVolumeClaim.yaml diff --git a/kubernetes-modules/Deployment_Vs_StatefulSet/StatefulSets/Service.yaml b/kubernetes-modules/deployment-and-statefulset-configs/StatefulSets/Service.yaml similarity index 100% rename from kubernetes-modules/Deployment_Vs_StatefulSet/StatefulSets/Service.yaml rename to kubernetes-modules/deployment-and-statefulset-configs/StatefulSets/Service.yaml diff --git a/kubernetes-modules/Deployment_Vs_StatefulSet/StatefulSets/StatefulSet.yaml b/kubernetes-modules/deployment-and-statefulset-configs/StatefulSets/StatefulSet.yaml similarity index 100% rename from kubernetes-modules/Deployment_Vs_StatefulSet/StatefulSets/StatefulSet.yaml rename to kubernetes-modules/deployment-and-statefulset-configs/StatefulSets/StatefulSet.yaml diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index 5e06a5550e..8d45b95a7b 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -129,13 +129,6 @@ - - - jitpack.io - https://jitpack.io - - - libraries-3 diff --git a/libraries-data-db/README.md b/libraries-data-db/README.md index 1062449693..a3a126c7a5 100644 --- a/libraries-data-db/README.md +++ b/libraries-data-db/README.md @@ -7,7 +7,7 @@ This module contains articles about database-related data processing libraries. - [Introduction to Reladomo](https://www.baeldung.com/reladomo) - [Introduction to ORMLite](https://www.baeldung.com/ormlite) - [Guide to Java Data Objects](https://www.baeldung.com/jdo) -- [Intro to JDO Queries 2/2](https://www.baeldung.com/jdo-queries) +- [Intro to JDO Queries](https://www.baeldung.com/jdo-queries) - [Introduction to HikariCP](https://www.baeldung.com/hikaricp) - [Guide to Ebean ORM](https://www.baeldung.com/ebean-orm) - [Introduction to Debezium](https://www.baeldung.com/debezium-intro) diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml index d8479def3c..77498dd248 100644 --- a/libraries-http-2/pom.xml +++ b/libraries-http-2/pom.xml @@ -82,7 +82,31 @@ converter-gson ${retrofit.version} + + org.mockito + mockito-inline + ${mockito.version} + test + + + org.jmockit + jmockit + ${jmockit.version} + + + + + + maven-surefire-plugin + + + -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar + + + + + 4.9.1 @@ -95,6 +119,7 @@ 5.1.9.RELEASE 1.0.3 3.2.12.RELEASE + 1.49 \ No newline at end of file diff --git a/libraries-http-2/src/main/java/com/baeldung/mock/url/UrlFetcher.java b/libraries-http-2/src/main/java/com/baeldung/mock/url/UrlFetcher.java new file mode 100644 index 0000000000..bb9ba4a5f9 --- /dev/null +++ b/libraries-http-2/src/main/java/com/baeldung/mock/url/UrlFetcher.java @@ -0,0 +1,23 @@ +package com.baeldung.mock.url; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +public class UrlFetcher { + + private URL url; + + public UrlFetcher(URL url) throws IOException { + this.url = url; + } + + public boolean isUrlAvailable() throws IOException { + return getResponseCode() == HttpURLConnection.HTTP_OK; + } + + private int getResponseCode() throws IOException { + HttpURLConnection con = (HttpURLConnection) this.url.openConnection(); + return con.getResponseCode(); + } +} diff --git a/libraries-http-2/src/test/java/com/baeldung/mock/url/MockHttpURLConnection.java b/libraries-http-2/src/test/java/com/baeldung/mock/url/MockHttpURLConnection.java new file mode 100644 index 0000000000..9df05fe0d0 --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/mock/url/MockHttpURLConnection.java @@ -0,0 +1,35 @@ +package com.baeldung.mock.url; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +public class MockHttpURLConnection extends HttpURLConnection { + + protected MockHttpURLConnection(URL url) { + super(url); + } + + @Override + public int getResponseCode() { + return responseCode; + } + + public void setResponseCode(int responseCode) { + this.responseCode = responseCode; + } + + @Override + public void disconnect() { + } + + @Override + public boolean usingProxy() { + return false; + } + + @Override + public void connect() throws IOException { + } + +} diff --git a/libraries-http-2/src/test/java/com/baeldung/mock/url/MockURLStreamHandler.java b/libraries-http-2/src/test/java/com/baeldung/mock/url/MockURLStreamHandler.java new file mode 100644 index 0000000000..1cc09dc2e9 --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/mock/url/MockURLStreamHandler.java @@ -0,0 +1,21 @@ +package com.baeldung.mock.url; + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +public class MockURLStreamHandler extends URLStreamHandler { + + private MockHttpURLConnection mockHttpURLConnection; + + public MockURLStreamHandler(MockHttpURLConnection mockHttpURLConnection) { + this.mockHttpURLConnection = mockHttpURLConnection; + } + + @Override + protected URLConnection openConnection(URL url) throws IOException { + return this.mockHttpURLConnection; + } + +} diff --git a/libraries-http-2/src/test/java/com/baeldung/mock/url/MockURLStreamHandlerFactory.java b/libraries-http-2/src/test/java/com/baeldung/mock/url/MockURLStreamHandlerFactory.java new file mode 100644 index 0000000000..855c761b65 --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/mock/url/MockURLStreamHandlerFactory.java @@ -0,0 +1,19 @@ +package com.baeldung.mock.url; + +import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; + +public class MockURLStreamHandlerFactory implements URLStreamHandlerFactory { + + private MockHttpURLConnection mockHttpURLConnection; + + public MockURLStreamHandlerFactory(MockHttpURLConnection mockHttpURLConnection) { + this.mockHttpURLConnection = mockHttpURLConnection; + } + + @Override + public URLStreamHandler createURLStreamHandler(String protocol) { + return new MockURLStreamHandler(this.mockHttpURLConnection); + } + +} diff --git a/libraries-http-2/src/test/java/com/baeldung/mock/url/UrlFetcherJMockitUnitTest.java b/libraries-http-2/src/test/java/com/baeldung/mock/url/UrlFetcherJMockitUnitTest.java new file mode 100644 index 0000000000..b99dcd282d --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/mock/url/UrlFetcherJMockitUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung.mock.url; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import mockit.Expectations; +import mockit.Mocked; +import mockit.integration.junit5.JMockitExtension; + + +@ExtendWith(JMockitExtension.class) +class UrlFetcherJMockitUnitTest { + + @Test + void givenMockedUrl_whenRequestSent_thenIsUrlAvailableTrue(@Mocked URL anyURL, @Mocked HttpURLConnection mockConn) throws Exception { + new Expectations() {{ + mockConn.getResponseCode(); + result = HttpURLConnection.HTTP_OK; + }}; + + UrlFetcher fetcher = new UrlFetcher(new URL("https://www.baeldung.com/")); + assertTrue(fetcher.isUrlAvailable(), "Url should be available: "); + } + + @Test + void givenMockedUrl_whenRequestSent_thenIsUrlAvailableFalse(@Mocked URL anyURL, @Mocked HttpURLConnection mockConn) throws Exception { + new Expectations() {{ + mockConn.getResponseCode(); + result = HttpURLConnection.HTTP_INTERNAL_ERROR; + }}; + + UrlFetcher fetcher = new UrlFetcher(new URL("https://www.baeldung.com/")); + assertFalse(fetcher.isUrlAvailable(), "Url should NOT be available: "); + } + +} diff --git a/libraries-http-2/src/test/java/com/baeldung/mock/url/UrlFetcherMockitoUnitTest.java b/libraries-http-2/src/test/java/com/baeldung/mock/url/UrlFetcherMockitoUnitTest.java new file mode 100644 index 0000000000..bd998e83b4 --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/mock/url/UrlFetcherMockitoUnitTest.java @@ -0,0 +1,39 @@ +package com.baeldung.mock.url; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.jupiter.api.Test; + +class UrlFetcherMockitoUnitTest { + + @Test + void givenMockedUrl_whenRequestSent_thenIsUrlAvailableTrue() throws Exception { + HttpURLConnection mockHttpURLConnection = mock(HttpURLConnection.class); + when(mockHttpURLConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + + URL mockURL = mock(URL.class); + when(mockURL.openConnection()).thenReturn(mockHttpURLConnection); + + UrlFetcher fetcher = new UrlFetcher(mockURL); + assertTrue(fetcher.isUrlAvailable(), "Url should be available: "); + } + + @Test + void givenMockedUrl_whenRequestSent_thenIsUrlAvailableFalse() throws Exception { + HttpURLConnection mockHttpURLConnection = mock(HttpURLConnection.class); + when(mockHttpURLConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_NOT_FOUND); + + URL mockURL = mock(URL.class); + when(mockURL.openConnection()).thenReturn(mockHttpURLConnection); + + UrlFetcher fetcher = new UrlFetcher(mockURL); + assertFalse(fetcher.isUrlAvailable(), "Url should NOT be available: "); + } + +} diff --git a/libraries-http-2/src/test/java/com/baeldung/mock/url/UrlFetcherUnitTest.java b/libraries-http-2/src/test/java/com/baeldung/mock/url/UrlFetcherUnitTest.java new file mode 100644 index 0000000000..be3a784a99 --- /dev/null +++ b/libraries-http-2/src/test/java/com/baeldung/mock/url/UrlFetcherUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.mock.url; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class UrlFetcherUnitTest { + + private static MockHttpURLConnection mockHttpURLConnection; + + @BeforeAll + public static void setUp() { + mockHttpURLConnection = new MockHttpURLConnection(null); + URL.setURLStreamHandlerFactory(new MockURLStreamHandlerFactory(mockHttpURLConnection)); + } + + @Test + void givenMockedUrl_whenRequestSent_thenIsUrlAvailableTrue() throws Exception { + mockHttpURLConnection.setResponseCode(HttpURLConnection.HTTP_OK); + URL url = new URL("https://www.baeldung.com/"); + + UrlFetcher fetcher = new UrlFetcher(url); + assertTrue(fetcher.isUrlAvailable(), "Url should be available: "); + } + + @Test + void givenMockedUrl_whenRequestSent_thenIsUrlAvailableFalse() throws Exception { + mockHttpURLConnection.setResponseCode(HttpURLConnection.HTTP_FORBIDDEN); + URL url = new URL("https://www.baeldung.com/"); + + UrlFetcher fetcher = new UrlFetcher(url); + assertFalse(fetcher.isUrlAvailable(), "Url should NOT be available: "); + } + +} diff --git a/linux-bash-modules/json/README.md b/linux-bash-modules/linux-bash-json/README.md similarity index 100% rename from linux-bash-modules/json/README.md rename to linux-bash-modules/linux-bash-json/README.md diff --git a/linux-bash-modules/json/src/main/bash/fruit.json b/linux-bash-modules/linux-bash-json/src/main/bash/fruit.json similarity index 100% rename from linux-bash-modules/json/src/main/bash/fruit.json rename to linux-bash-modules/linux-bash-json/src/main/bash/fruit.json diff --git a/linux-bash-modules/json/src/main/bash/fruits.json b/linux-bash-modules/linux-bash-json/src/main/bash/fruits.json similarity index 100% rename from linux-bash-modules/json/src/main/bash/fruits.json rename to linux-bash-modules/linux-bash-json/src/main/bash/fruits.json diff --git a/linux-bash-modules/json/src/main/bash/jq.sh b/linux-bash-modules/linux-bash-json/src/main/bash/jq.sh similarity index 100% rename from linux-bash-modules/json/src/main/bash/jq.sh rename to linux-bash-modules/linux-bash-json/src/main/bash/jq.sh diff --git a/linux-bash-modules/json/src/main/bash/wikipedia.json b/linux-bash-modules/linux-bash-json/src/main/bash/wikipedia.json similarity index 100% rename from linux-bash-modules/json/src/main/bash/wikipedia.json rename to linux-bash-modules/linux-bash-json/src/main/bash/wikipedia.json diff --git a/linux-bash-modules/loops/README.md b/linux-bash-modules/linux-bash-loops/README.md similarity index 100% rename from linux-bash-modules/loops/README.md rename to linux-bash-modules/linux-bash-loops/README.md diff --git a/linux-bash-modules/loops/src/main/bash/find_directories.sh b/linux-bash-modules/linux-bash-loops/src/main/bash/find_directories.sh similarity index 100% rename from linux-bash-modules/loops/src/main/bash/find_directories.sh rename to linux-bash-modules/linux-bash-loops/src/main/bash/find_directories.sh diff --git a/linux-bash-modules/loops/src/main/bash/loop_directories.sh b/linux-bash-modules/linux-bash-loops/src/main/bash/loop_directories.sh similarity index 100% rename from linux-bash-modules/loops/src/main/bash/loop_directories.sh rename to linux-bash-modules/linux-bash-loops/src/main/bash/loop_directories.sh diff --git a/linux-bash-modules/read/README.md b/linux-bash-modules/linux-bash-read/README.md similarity index 100% rename from linux-bash-modules/read/README.md rename to linux-bash-modules/linux-bash-read/README.md diff --git a/linux-bash-modules/read/src/main/bash/file.csv b/linux-bash-modules/linux-bash-read/src/main/bash/file.csv similarity index 100% rename from linux-bash-modules/read/src/main/bash/file.csv rename to linux-bash-modules/linux-bash-read/src/main/bash/file.csv diff --git a/linux-bash-modules/read/src/main/bash/read_inputs.sh b/linux-bash-modules/linux-bash-read/src/main/bash/read_inputs.sh similarity index 100% rename from linux-bash-modules/read/src/main/bash/read_inputs.sh rename to linux-bash-modules/linux-bash-read/src/main/bash/read_inputs.sh diff --git a/linux-bash-modules/text/README.md b/linux-bash-modules/linux-bash-text/README.md similarity index 100% rename from linux-bash-modules/text/README.md rename to linux-bash-modules/linux-bash-text/README.md diff --git a/linux-bash-modules/text/src/main/bash/append_multiple_lines.sh b/linux-bash-modules/linux-bash-text/src/main/bash/append_multiple_lines.sh similarity index 100% rename from linux-bash-modules/text/src/main/bash/append_multiple_lines.sh rename to linux-bash-modules/linux-bash-text/src/main/bash/append_multiple_lines.sh diff --git a/linux-bash-modules/text/src/main/bash/remove_characters.sh b/linux-bash-modules/linux-bash-text/src/main/bash/remove_characters.sh similarity index 100% rename from linux-bash-modules/text/src/main/bash/remove_characters.sh rename to linux-bash-modules/linux-bash-text/src/main/bash/remove_characters.sh diff --git a/lombok-modules/lombok/pom.xml b/lombok-modules/lombok/pom.xml index 57b2a5a999..6ba90f33b5 100644 --- a/lombok-modules/lombok/pom.xml +++ b/lombok-modules/lombok/pom.xml @@ -49,10 +49,4 @@ 23.0.0 - - - projectlombok.org - https://projectlombok.org/edge-releases - - \ No newline at end of file diff --git a/messaging-modules/pom.xml b/messaging-modules/pom.xml index 71ff25d71b..6fd14f7c64 100644 --- a/messaging-modules/pom.xml +++ b/messaging-modules/pom.xml @@ -22,6 +22,7 @@ spring-amqp spring-apache-camel spring-jms + postgres-notify \ No newline at end of file diff --git a/messaging-modules/postgres-notify/.gitignore b/messaging-modules/postgres-notify/.gitignore new file mode 100644 index 0000000000..0776e6f133 --- /dev/null +++ b/messaging-modules/postgres-notify/.gitignore @@ -0,0 +1 @@ +/application-local.properties diff --git a/messaging-modules/postgres-notify/pom.xml b/messaging-modules/postgres-notify/pom.xml new file mode 100644 index 0000000000..174d66b7f5 --- /dev/null +++ b/messaging-modules/postgres-notify/pom.xml @@ -0,0 +1,78 @@ + + + 4.0.0 + postgres-notify + postgres-notify + PostgreSQL as a Message Broker + + + com.baeldung + messaging-modules + 0.0.1-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jdbc + + + org.postgresql + postgresql + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + org.projectlombok + lombok + true + + + + + + + 1.8 + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + instance1 + + + + org.springframework.boot + spring-boot-maven-plugin + + -Dserver.port=8081 + + + + + + + + \ No newline at end of file diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/Application.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/Application.java new file mode 100644 index 0000000000..b3b1f83d2f --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/Application.java @@ -0,0 +1,12 @@ +package com.baeldung.messaging.postgresql; + +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); + } +} \ No newline at end of file diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/config/CacheConfiguration.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/config/CacheConfiguration.java new file mode 100644 index 0000000000..73763316c3 --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/config/CacheConfiguration.java @@ -0,0 +1,34 @@ +package com.baeldung.messaging.postgresql.config; + +import java.util.Arrays; +import java.util.Collection; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.concurrent.ConcurrentMapCache; +import org.springframework.cache.support.SimpleCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.ConcurrentLruCache; + +import com.baeldung.messaging.postgresql.domain.Order; + +@Configuration +public class CacheConfiguration { + + @Bean + Cache ordersCache(CacheManager cm) { + return cm.getCache("orders"); + } + + @Bean + @ConditionalOnMissingBean + CacheManager defaultCacheManager() { + SimpleCacheManager cm = new SimpleCacheManager(); + Cache cache = new ConcurrentMapCache("orders",false); + cm.setCaches(Arrays.asList(cache)); + + return cm; + } +} diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/config/ListenerConfiguration.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/config/ListenerConfiguration.java new file mode 100644 index 0000000000..b053ba8bc2 --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/config/ListenerConfiguration.java @@ -0,0 +1,25 @@ +package com.baeldung.messaging.postgresql.config; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.messaging.postgresql.service.NotifierService; +import com.baeldung.messaging.postgresql.service.NotificationHandler; + +import lombok.extern.slf4j.Slf4j; + +@Configuration +@Slf4j +public class ListenerConfiguration { + + @Bean + CommandLineRunner startListener(NotifierService notifier, NotificationHandler handler) { + return (args) -> { + log.info("Starting order listener thread..."); + Runnable listener = notifier.createNotificationHandler(handler); + Thread t = new Thread(listener, "order-listener"); + t.start(); + }; + } +} diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/config/NotifierConfiguration.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/config/NotifierConfiguration.java new file mode 100644 index 0000000000..51d6016c57 --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/config/NotifierConfiguration.java @@ -0,0 +1,30 @@ +package com.baeldung.messaging.postgresql.config; + +import java.util.Properties; + +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; + +import com.baeldung.messaging.postgresql.service.NotifierService; +import com.zaxxer.hikari.util.DriverDataSource; + +@Configuration +public class NotifierConfiguration { + + @Bean + NotifierService notifier(DataSourceProperties props) { + + DriverDataSource ds = new DriverDataSource( + props.determineUrl(), + props.determineDriverClassName(), + new Properties(), + props.determineUsername(), + props.determinePassword()); + + JdbcTemplate tpl = new JdbcTemplate(ds); + + return new NotifierService(tpl); + } +} diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/controller/OrdersController.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/controller/OrdersController.java new file mode 100644 index 0000000000..70daa14abd --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/controller/OrdersController.java @@ -0,0 +1,53 @@ +package com.baeldung.messaging.postgresql.controller; + +import java.math.BigDecimal; +import java.util.Optional; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.messaging.postgresql.domain.Order; +import com.baeldung.messaging.postgresql.domain.OrderType; +import com.baeldung.messaging.postgresql.service.OrdersService; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@RestController +@RequiredArgsConstructor +@Slf4j +public class OrdersController { + + private final OrdersService orders; + + @PostMapping("/orders/sell") + public ResponseEntity postSellOrder(String symbol, BigDecimal quantity, BigDecimal price) { + log.info("postSellOrder: symbol={},quantity={},price={}", symbol,quantity,price); + Order order = orders.createOrder(OrderType.SELL, symbol, quantity, price); + return ResponseEntity.status(HttpStatus.CREATED).body(order); + } + + @PostMapping("/orders/buy") + public ResponseEntity postBuyOrder(String symbol, BigDecimal quantity, BigDecimal price) { + log.info("postBuyOrder: symbol={},quantity={},price={}", symbol,quantity,price); + Order order = orders.createOrder(OrderType.BUY, symbol, quantity, price); + return ResponseEntity.status(HttpStatus.CREATED).body(order); + } + + @GetMapping("/orders/{id}") + public ResponseEntity getOrderById(@PathVariable Long id) { + + Optional o = orders.findById(id); + if (o.isEmpty()) { + return ResponseEntity.notFound().build(); + } + + return ResponseEntity.ok(o.get()); + + } + +} diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/domain/Order.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/domain/Order.java new file mode 100644 index 0000000000..d7b19aa10d --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/domain/Order.java @@ -0,0 +1,21 @@ +package com.baeldung.messaging.postgresql.domain; + +import java.math.BigDecimal; + +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Table; + +import lombok.Data; +import lombok.ToString; + +@Data +@ToString +@Table(name = "orders") +public class Order { + @Id + private Long id; + private String symbol; + private OrderType orderType; + private BigDecimal price; + private BigDecimal quantity; +} diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/domain/OrderType.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/domain/OrderType.java new file mode 100644 index 0000000000..6c053bc25c --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/domain/OrderType.java @@ -0,0 +1,12 @@ +package com.baeldung.messaging.postgresql.domain; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Getter +public enum OrderType { + BUY('B'), + SELL('S'); + private final char c; +} diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/repository/OrdersRepository.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/repository/OrdersRepository.java new file mode 100644 index 0000000000..d131017930 --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/repository/OrdersRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.messaging.postgresql.repository; + +import org.springframework.data.repository.CrudRepository; + +import com.baeldung.messaging.postgresql.domain.Order; + +public interface OrdersRepository extends CrudRepository{ + +} diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/service/NotificationHandler.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/service/NotificationHandler.java new file mode 100644 index 0000000000..61b970f3a2 --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/service/NotificationHandler.java @@ -0,0 +1,31 @@ +package com.baeldung.messaging.postgresql.service; + +import java.util.Optional; +import java.util.function.Consumer; + +import org.postgresql.PGNotification; +import org.springframework.cache.Cache; +import org.springframework.stereotype.Component; + +import com.baeldung.messaging.postgresql.domain.Order; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Component +@Slf4j +@RequiredArgsConstructor +public class NotificationHandler implements Consumer{ + + private final OrdersService orders; + + @Override + public void accept(PGNotification t) { + log.info("Notification received: pid={}, name={}, param={}",t.getPID(),t.getName(),t.getParameter()); + Optional order = orders.findById(Long.valueOf(t.getParameter())); + if ( !order.isEmpty()) { + log.info("order details: {}", order.get()); + } + } + +} diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/service/NotifierService.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/service/NotifierService.java new file mode 100644 index 0000000000..bc8215c7b3 --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/service/NotifierService.java @@ -0,0 +1,55 @@ +package com.baeldung.messaging.postgresql.service; + +import java.sql.Connection; +import java.util.function.Consumer; + +import org.postgresql.PGConnection; +import org.postgresql.PGNotification; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.baeldung.messaging.postgresql.domain.Order; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RequiredArgsConstructor +public class NotifierService { + private static final String ORDERS_CHANNEL = "orders"; + private final JdbcTemplate tpl; + + + @Transactional + public void notifyOrderCreated(Order order) { + tpl.execute("NOTIFY " + ORDERS_CHANNEL + ", '" + order.getId() + "'"); + } + + public Runnable createNotificationHandler(Consumer consumer) { + + return () -> { + tpl.execute((Connection c) -> { + log.info("notificationHandler: sending LISTEN command..."); + c.createStatement().execute("LISTEN " + ORDERS_CHANNEL); + + PGConnection pgconn = c.unwrap(PGConnection.class); + + while(!Thread.currentThread().isInterrupted()) { + PGNotification[] nts = pgconn.getNotifications(10000); + if ( nts == null || nts.length == 0 ) { + continue; + } + + for( PGNotification nt : nts) { + consumer.accept(nt); + } + } + + return 0; + }); + + }; + } +} diff --git a/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/service/OrdersService.java b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/service/OrdersService.java new file mode 100644 index 0000000000..cc369c1f3e --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/java/com/baeldung/messaging/postgresql/service/OrdersService.java @@ -0,0 +1,61 @@ +package com.baeldung.messaging.postgresql.service; + +import java.math.BigDecimal; +import java.util.Optional; + +import javax.sql.DataSource; + +import org.springframework.cache.Cache; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.baeldung.messaging.postgresql.domain.Order; +import com.baeldung.messaging.postgresql.domain.OrderType; +import com.baeldung.messaging.postgresql.repository.OrdersRepository; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Service +@RequiredArgsConstructor +@Slf4j +public class OrdersService { + private final OrdersRepository repo; + private final NotifierService notifier; + private final Cache ordersCache; + + @Transactional + public Order createOrder(OrderType orderType, String symbol, BigDecimal quantity, BigDecimal price) { + + Order order = new Order(); + order.setOrderType(orderType); + order.setSymbol(symbol); + order.setQuantity(quantity); + order.setPrice(price); + order = repo.save(order); + + notifier.notifyOrderCreated(order); + + return order; + + } + + @Transactional(readOnly = true) + public Optional findById(Long id) { + Optional o = Optional.ofNullable(ordersCache.get(id, Order.class)); + if ( !o.isEmpty() ) { + log.info("findById: cache hit, id={}",id); + return o; + } + + log.info("findById: cache miss, id={}",id); + o = repo.findById(id); + if ( o.isEmpty()) { + return o; + } + + ordersCache.put(id, o.get()); + return o; + } + +} diff --git a/messaging-modules/postgres-notify/src/main/resources/application.properties b/messaging-modules/postgres-notify/src/main/resources/application.properties new file mode 100644 index 0000000000..836e01cdca --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/resources/application.properties @@ -0,0 +1,5 @@ +# Replace the properties below with proper values for your environment +spring.sql.init.mode=ALWAYS +#spring.datasource.url=jdbc:postgresql://some-postgresql-host/some-postgresql-database +#spring.datasource.username=your-postgresql-username +#spring.datasource.password=your-postgresql-password diff --git a/messaging-modules/postgres-notify/src/main/resources/schema.sql b/messaging-modules/postgres-notify/src/main/resources/schema.sql new file mode 100644 index 0000000000..fad33509bd --- /dev/null +++ b/messaging-modules/postgres-notify/src/main/resources/schema.sql @@ -0,0 +1,7 @@ +create table if not exists orders ( + id serial primary key, + symbol varchar(16) not null, + order_type varchar(8) not null, + price NUMERIC(10,2) not null, + quantity NUMERIC(10,2) not null +); diff --git a/messaging-modules/postgres-notify/src/test/java/com/baeldung/messaging/postgresql/ApplicationLiveTest.java b/messaging-modules/postgres-notify/src/test/java/com/baeldung/messaging/postgresql/ApplicationLiveTest.java new file mode 100644 index 0000000000..5311793fe7 --- /dev/null +++ b/messaging-modules/postgres-notify/src/test/java/com/baeldung/messaging/postgresql/ApplicationLiveTest.java @@ -0,0 +1,47 @@ +package com.baeldung.messaging.postgresql; + +import static org.junit.jupiter.api.Assertions.*; + +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.test.web.client.TestRestTemplate; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import com.baeldung.messaging.postgresql.domain.Order; + +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +@Sql("/schema.sql") +class ApplicationLiveTest { + + + @LocalServerPort + int localPort; + + @Autowired + TestRestTemplate client; + + @Test + void whenCreateBuyOrder_thenSuccess() { + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + MultiValueMap data= new LinkedMultiValueMap<>(); + data.add("symbol", "BAEL"); + data.add("price", "14.56"); + data.add("quantity", "100"); + HttpEntity> request = new HttpEntity>(data, headers); + + client.postForEntity("http://localhost:" + localPort + "/orders/buy", data, Order.class); + + } + +} diff --git a/messaging-modules/postgres-notify/src/test/resources/application.properties b/messaging-modules/postgres-notify/src/test/resources/application.properties new file mode 100644 index 0000000000..ebc3ef54e1 --- /dev/null +++ b/messaging-modules/postgres-notify/src/test/resources/application.properties @@ -0,0 +1,3 @@ +spring.datasource.url=jdbc:postgresql://localhost:5432/baeldung +spring.datasource.username=baeldung +spring.datasource.password=SqD64PtsGhDXjn9f \ No newline at end of file diff --git a/optaplanner/pom.xml b/optaplanner/pom.xml index e1653fd749..033e3a3718 100644 --- a/optaplanner/pom.xml +++ b/optaplanner/pom.xml @@ -27,7 +27,7 @@ - 8.24.0.Final + 9.38.0.Final \ No newline at end of file diff --git a/patterns-modules/design-patterns-architectural/pom.xml b/patterns-modules/design-patterns-architectural/pom.xml index 2d6117a406..4efcca0c6b 100644 --- a/patterns-modules/design-patterns-architectural/pom.xml +++ b/patterns-modules/design-patterns-architectural/pom.xml @@ -67,10 +67,10 @@ 5.2.16.Final 6.0.6 2.7.5 - 3.3.0 + 5.3.0 2.7.5 5.5.14 - 3.14.0 + 3.20.4 3.14.0 diff --git a/patterns-modules/design-patterns-cloud/pom.xml b/patterns-modules/design-patterns-cloud/pom.xml index acd3e64ed5..595e0cabcd 100644 --- a/patterns-modules/design-patterns-cloud/pom.xml +++ b/patterns-modules/design-patterns-cloud/pom.xml @@ -17,8 +17,13 @@ io.github.resilience4j resilience4j-retry - 1.7.1 + ${resilience4j-retry.version} + + + 2.0.2 + + \ No newline at end of file diff --git a/patterns-modules/design-patterns-cloud/src/test/java/com/baeldung/backoff/jitter/BackoffWithJitterUnitTest.java b/patterns-modules/design-patterns-cloud/src/test/java/com/baeldung/backoff/jitter/BackoffWithJitterUnitTest.java index abfcc71e66..5bd6b0fa23 100644 --- a/patterns-modules/design-patterns-cloud/src/test/java/com/baeldung/backoff/jitter/BackoffWithJitterUnitTest.java +++ b/patterns-modules/design-patterns-cloud/src/test/java/com/baeldung/backoff/jitter/BackoffWithJitterUnitTest.java @@ -1,6 +1,6 @@ package com.baeldung.backoff.jitter; -import io.github.resilience4j.retry.IntervalFunction; +import io.github.resilience4j.core.IntervalFunction; import io.github.resilience4j.retry.Retry; import io.github.resilience4j.retry.RetryConfig; import org.junit.Before; @@ -15,8 +15,8 @@ import java.util.concurrent.ExecutorService; import java.util.function.Function; import static com.baeldung.backoff.jitter.BackoffWithJitterUnitTest.RetryProperties.*; -import static io.github.resilience4j.retry.IntervalFunction.ofExponentialBackoff; -import static io.github.resilience4j.retry.IntervalFunction.ofExponentialRandomBackoff; +import static io.github.resilience4j.core.IntervalFunction.ofExponentialBackoff; +import static io.github.resilience4j.core.IntervalFunction.ofExponentialRandomBackoff; import static java.util.Collections.nCopies; import static java.util.concurrent.Executors.newFixedThreadPool; import static org.mockito.ArgumentMatchers.anyString; diff --git a/patterns-modules/design-patterns-structural/README.md b/patterns-modules/design-patterns-structural/README.md index 996b500842..7a9c7acf4d 100644 --- a/patterns-modules/design-patterns-structural/README.md +++ b/patterns-modules/design-patterns-structural/README.md @@ -1,7 +1,7 @@ ### Relevant Articles: - [Facade Design Pattern in Java](https://www.baeldung.com/java-facade-pattern) - [Proxy, Decorator, Adapter and Bridge Patterns](https://www.baeldung.com/java-structural-design-patterns) -- [Composite Design pattern in Java](https://www.baeldung.com/java-composite-pattern) +- [Composite Design Pattern in Java](https://www.baeldung.com/java-composite-pattern) - [The Decorator Pattern in Java](https://www.baeldung.com/java-decorator-pattern) - [The Adapter Pattern in Java](https://www.baeldung.com/java-adapter-pattern) - [The Proxy Pattern in Java](https://www.baeldung.com/java-proxy-pattern) diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Address.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Address.java index d559e5a6c2..b326363c60 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Address.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Address.java @@ -10,6 +10,16 @@ public class Address { private String country; private int zipCode; + public Address(String addressLine1, String addressLine2, String city, String country, int zipCode) { + this.addressLine1 = addressLine1; + this.addressLine2 = addressLine2; + this.city = city; + this.country = country; + this.zipCode = zipCode; + } + + public Address() {} + public String getAddressLine1() { return addressLine1; } diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java index f50d8fd7cc..ea92d516ae 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/AddressType.java @@ -2,19 +2,13 @@ package com.baeldung.hibernate.customtypes; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.spi.ValueAccess; import org.hibernate.usertype.CompositeUserType; -import org.hibernate.usertype.UserType; import java.io.Serializable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; import java.util.Objects; -public class AddressType implements CompositeUserType, UserType { +public class AddressType implements CompositeUserType { @Override public Object getPropertyValue(Address component, int property) throws HibernateException { @@ -39,7 +33,8 @@ public class AddressType implements CompositeUserType, UserType, UserType returnedClass() { return Address.class; @@ -73,36 +63,6 @@ public class AddressType implements CompositeUserType, UserType { +public class PhoneNumberType implements CompositeUserType { @Override - public int getSqlType() { - return Types.INTEGER; + public Object getPropertyValue(PhoneNumber component, int property) throws HibernateException { + switch (property) { + case 0: + return component.getCountryCode(); + case 1: + return component.getCityCode(); + case 2: + return component.getNumber(); + default: + throw new IllegalArgumentException(property + " is an invalid property index for class type " + component.getClass().getName()); + } + } + + @Override + public PhoneNumber instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) { + return new PhoneNumber(values.getValue(0, Integer.class), values.getValue(1, Integer.class), values.getValue(2,Integer.class)); + } + + @Override + public Class> embeddable() { + return PhoneNumber.class; } @Override @@ -37,32 +54,6 @@ public class PhoneNumberType implements UserType { return x.hashCode(); } - @Override - public PhoneNumber nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { - int countryCode = rs.getInt(position); - - if (rs.wasNull()) - return null; - - int cityCode = rs.getInt(position); - int number = rs.getInt(position); - - return new PhoneNumber(countryCode, cityCode, number); - } - - @Override - public void nullSafeSet(PreparedStatement st, PhoneNumber value, int index, SharedSessionContractImplementor session) throws SQLException { - if (Objects.isNull(value)) { - st.setNull(index, Types.INTEGER); - st.setNull(index+1, Types.INTEGER); - st.setNull(index+2, Types.INTEGER); - } else { - st.setInt(index, value.getCountryCode()); - st.setInt(index+1, value.getCityCode()); - st.setInt(index+2, value.getNumber()); - } - } - @Override public PhoneNumber deepCopy(PhoneNumber value) { if (Objects.isNull(value)) diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Salary.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Salary.java index f9a7ac5902..2402531869 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Salary.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/Salary.java @@ -1,8 +1,9 @@ package com.baeldung.hibernate.customtypes; +import java.io.Serializable; import java.util.Objects; -public class Salary { +public class Salary implements Serializable { private Long amount; private String currency; diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java index 69e34c1363..49294abe89 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/customtypes/SalaryType.java @@ -1,10 +1,6 @@ package com.baeldung.hibernate.customtypes; -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; -import org.hibernate.metamodel.spi.ValueAccess; -import org.hibernate.usertype.CompositeUserType; import org.hibernate.usertype.DynamicParameterizedType; import org.hibernate.usertype.UserType; @@ -16,38 +12,13 @@ import java.sql.Types; import java.util.Objects; import java.util.Properties; -public class SalaryType implements UserType, CompositeUserType, DynamicParameterizedType { +public class SalaryType implements UserType, DynamicParameterizedType { private String localCurrency; - @Override - public Object getPropertyValue(Salary component, int property) throws HibernateException { - - switch (property) { - case 0: - return component.getAmount(); - case 1: - return component.getCurrency(); - default: - throw new IllegalArgumentException(property + - " is an invalid property index for class type " + - component.getClass().getName()); - } - } - - @Override - public Salary instantiate(ValueAccess values, SessionFactoryImplementor sessionFactory) { - return null; - } - - @Override - public Class> embeddable() { - return Salary.class; - } - @Override public int getSqlType() { - return Types.BIGINT; + return Types.VARCHAR; } @Override @@ -74,12 +45,12 @@ public class SalaryType implements UserType, CompositeUserType, @Override public Salary nullSafeGet(ResultSet rs, int position, SharedSessionContractImplementor session, Object owner) throws SQLException { Salary salary = new Salary(); - salary.setAmount(rs.getLong(position)); - if (rs.wasNull()) - return null; + String salaryValue = rs.getString(position); - salary.setCurrency(rs.getString(position)); + salary.setAmount(Long.parseLong(salaryValue.split(" ")[1])); + + salary.setCurrency(salaryValue.split(" ")[0]); return salary; } @@ -87,13 +58,11 @@ public class SalaryType implements UserType, CompositeUserType, @Override public void nullSafeSet(PreparedStatement st, Salary value, int index, SharedSessionContractImplementor session) throws SQLException { if (Objects.isNull(value)) - st.setNull(index, Types.BIGINT); + st.setNull(index, Types.VARCHAR); else { - - st.setLong(index, SalaryCurrencyConvertor.convert( - value.getAmount(), - value.getCurrency(), localCurrency)); - st.setString(index + 1, value.getCurrency()); + Long salaryValue = SalaryCurrencyConvertor.convert(value.getAmount(), + value.getCurrency(), localCurrency); + st.setString(index, value.getCurrency() + " " + salaryValue); } } @@ -117,7 +86,7 @@ public class SalaryType implements UserType, CompositeUserType, @Override public Serializable disassemble(Salary value) { - return (Serializable) deepCopy(value); + return deepCopy(value); } @Override diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java index 9da3a90034..8e7a71c49b 100644 --- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java +++ b/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/customtypes/HibernateCustomTypesIntegrationTest.java @@ -11,10 +11,12 @@ import org.junit.Test; import jakarta.persistence.TypedQuery; import java.time.LocalDate; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; public class HibernateCustomTypesIntegrationTest { @@ -74,12 +76,18 @@ public class HibernateCustomTypesIntegrationTest { doInHibernate(this::sessionFactory, session -> { session.save(e); + session.flush(); + session.refresh(e); TypedQuery query = session.createQuery("FROM OfficeEmployee OE WHERE OE.empAddress.zipCode = :pinCode", OfficeEmployee.class); query.setParameter("pinCode",100); - int size = query.getResultList().size(); + final List resultList = query.getResultList(); + int size = resultList.size(); assertEquals(1, size); + assertNotNull(resultList.get(0).getEmployeeNumber()); + assertNotNull(resultList.get(0).getEmpAddress()); + assertNotNull(resultList.get(0).getSalary()); }); } diff --git a/persistence-modules/java-jpa/pom.xml b/persistence-modules/java-jpa/pom.xml index b70fd0daec..b96b24582e 100644 --- a/persistence-modules/java-jpa/pom.xml +++ b/persistence-modules/java-jpa/pom.xml @@ -69,6 +69,11 @@ javax.annotation-api ${javax.annotation.version} + + mysql + mysql-connector-java + ${mysql.version} + @@ -130,6 +135,7 @@ 2.1.214 4.0.0 1.3.2 + 8.0.33 \ No newline at end of file diff --git a/persistence-modules/querydsl/src/test/java/com/baeldung/dao/PersonDaoIntegrationTest.java b/persistence-modules/querydsl/src/test/java/com/baeldung/dao/PersonDaoIntegrationTest.java index e9cf679c43..879b4238db 100644 --- a/persistence-modules/querydsl/src/test/java/com/baeldung/dao/PersonDaoIntegrationTest.java +++ b/persistence-modules/querydsl/src/test/java/com/baeldung/dao/PersonDaoIntegrationTest.java @@ -25,7 +25,7 @@ public class PersonDaoIntegrationTest { // @Test - public void testCreation() { + public void givenExistingPersons_whenFindingPersonByFirstName_thenFound() { personDao.save(new Person("Erich", "Gamma")); final Person person = new Person("Kent", "Beck"); personDao.save(person); @@ -36,7 +36,7 @@ public class PersonDaoIntegrationTest { } @Test - public void testMultipleFilter() { + public void givenExistingPersons_whenFindingPersonByFirstNameAndSurName_thenFound() { personDao.save(new Person("Erich", "Gamma")); final Person person = personDao.save(new Person("Ralph", "Beck")); final Person person2 = personDao.save(new Person("Ralph", "Johnson")); @@ -47,7 +47,7 @@ public class PersonDaoIntegrationTest { } @Test - public void testOrdering() { + public void givenExistingPersons_whenFindingPersonByFirstNameInDescendingOrder_thenFound() { final Person person = personDao.save(new Person("Kent", "Gamma")); personDao.save(new Person("Ralph", "Johnson")); final Person person2 = personDao.save(new Person("Kent", "Zivago")); @@ -58,7 +58,7 @@ public class PersonDaoIntegrationTest { } @Test - public void testMaxAge() { + public void givenExistingPersons_whenFindingMaxAge_thenFound() { personDao.save(new Person("Kent", "Gamma", 20)); personDao.save(new Person("Ralph", "Johnson", 35)); personDao.save(new Person("Kent", "Zivago", 30)); @@ -68,7 +68,7 @@ public class PersonDaoIntegrationTest { } @Test - public void testMaxAgeByName() { + public void givenExistingPersons_whenFindingMaxAgeByName_thenFound() { personDao.save(new Person("Kent", "Gamma", 20)); personDao.save(new Person("Ralph", "Johnson", 35)); personDao.save(new Person("Kent", "Zivago", 30)); diff --git a/persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java index 664ed1d0c3..63f9f1c9e7 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/JedisIntegrationTest.java @@ -38,7 +38,7 @@ public class JedisIntegrationTest { redisServer = RedisServer.builder() .port(port) - .setting("maxheap 128M") + .setting("maxmemory 128M") .build(); redisServer.start(); diff --git a/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java index b80cae98d8..c4a24f5d05 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/RedissonConfigurationIntegrationTest.java @@ -34,7 +34,7 @@ public class RedissonConfigurationIntegrationTest { redisServer = RedisServer.builder() .port(port) - .setting("maxheap 128M") + .setting("maxmemory 128M") .build(); redisServer.start(); } diff --git a/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java index 79581df989..aeda20435b 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/RedissonIntegrationTest.java @@ -32,7 +32,7 @@ public class RedissonIntegrationTest { public static void setUp() { redisServer = RedisServer.builder() .port(6379) - .setting("maxheap 128M") + .setting("maxmemory 128M") .build(); redisServer.start(); client = Redisson.create(); diff --git a/persistence-modules/redis/src/test/java/com/baeldung/redis/deleteeverything/DeleteEverythingInRedisIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/redis/deleteeverything/DeleteEverythingInRedisIntegrationTest.java index 54123afdea..84fc060e2f 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/redis/deleteeverything/DeleteEverythingInRedisIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/redis/deleteeverything/DeleteEverythingInRedisIntegrationTest.java @@ -25,7 +25,7 @@ public class DeleteEverythingInRedisIntegrationTest { redisServer = RedisServer.builder() .port(port) - .setting("maxheap 128M") + .setting("maxmemory 128M") .build(); redisServer.start(); diff --git a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java index 5c325e8ea0..7ba7ff4310 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/NaiveApproachIntegrationTest.java @@ -27,7 +27,7 @@ public class NaiveApproachIntegrationTest { redisServer = RedisServer.builder() .port(port) - .setting("maxheap 128M") + .setting("maxmemory 128M") .build(); } diff --git a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java index 838d0144dc..ff00b6ddc6 100644 --- a/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java +++ b/persistence-modules/redis/src/test/java/com/baeldung/redis_scan/ScanStrategyIntegrationTest.java @@ -33,7 +33,7 @@ public class ScanStrategyIntegrationTest { redisServer = RedisServer.builder() .port(port) - .setting("maxheap 128M") + .setting("maxmemory 128M") .build(); } diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index 0e990c69f3..06425cceb7 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -169,14 +169,6 @@ - - - dynamodb-local - DynamoDB Local Release Repository - ${dynamodblocal.repository.url} - - - com.baeldung.Application @@ -186,9 +178,7 @@ 1.11.64 3.3.7-1 1.0.392 - 1.11.106 - 1.11.86 - https://s3-us-west-2.amazonaws.com/dynamodb-local/release + 1.21.1 3.1.1 2.4.7 2.17.1 diff --git a/persistence-modules/spring-data-jpa-annotations/README.md b/persistence-modules/spring-data-jpa-annotations/README.md index d7e6189ae5..2b2805b92b 100644 --- a/persistence-modules/spring-data-jpa-annotations/README.md +++ b/persistence-modules/spring-data-jpa-annotations/README.md @@ -5,7 +5,7 @@ This module contains articles about annotations used in Spring Data JPA ### Relevant articles - [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd) -- [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable) +- [Jpa @Embedded and @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable) - [Spring JPA @Embedded and @EmbeddedId](https://www.baeldung.com/spring-jpa-embedded-method-parameters) - [Programmatic Transaction Management in Spring](https://www.baeldung.com/spring-programmatic-transaction-management) - [JPA Entity Lifecycle Events](https://www.baeldung.com/jpa-entity-lifecycle-events) diff --git a/persistence-modules/spring-data-jpa-enterprise/README.md b/persistence-modules/spring-data-jpa-enterprise/README.md index 08fa55c14e..d1039dcc50 100644 --- a/persistence-modules/spring-data-jpa-enterprise/README.md +++ b/persistence-modules/spring-data-jpa-enterprise/README.md @@ -6,7 +6,7 @@ This module contains articles about Spring Data JPA used in enterprise applicati - [Spring Data Java 8 Support](https://www.baeldung.com/spring-data-java-8) - [DB Integration Tests with Spring Boot and Testcontainers](https://www.baeldung.com/spring-boot-testcontainers-integration-test) -- [A Guide to Spring’s Open Session In View](https://www.baeldung.com/spring-open-session-in-view) +- [A Guide to Spring’s Open Session in View](https://www.baeldung.com/spring-open-session-in-view) - [Working with Lazy Element Collections in JPA](https://www.baeldung.com/java-jpa-lazy-collections) - [Custom Naming Convention with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-custom-naming) - [Partial Data Update With Spring Data](https://www.baeldung.com/spring-data-partial-update) diff --git a/persistence-modules/spring-data-jpa-query-2/README.md b/persistence-modules/spring-data-jpa-query-2/README.md index 8005bc0e19..e091bc1d99 100644 --- a/persistence-modules/spring-data-jpa-query-2/README.md +++ b/persistence-modules/spring-data-jpa-query-2/README.md @@ -9,7 +9,7 @@ This module contains articles about querying data using Spring Data JPA . - [Hibernate Pagination](https://www.baeldung.com/hibernate-pagination) - [Sorting with Hibernate](https://www.baeldung.com/hibernate-sort) - [Stored Procedures with Hibernate](https://www.baeldung.com/stored-procedures-with-hibernate-tutorial) -- [Eager/Lazy Loading In Hibernate](https://www.baeldung.com/hibernate-lazy-eager-loading) +- [Eager/Lazy Loading in Hibernate](https://www.baeldung.com/hibernate-lazy-eager-loading) - [Auditing with JPA, Hibernate, and Spring Data JPA](https://www.baeldung.com/database-auditing-jpa) - More articles: [[<-- prev]](../spring-data-jpa-query)[[more -->]](../spring-data-jpa-query-3) diff --git a/persistence-modules/spring-data-jpa-repo-3/README.md b/persistence-modules/spring-data-jpa-repo-3/README.md index 2ed2dc8896..93cc9379f7 100644 --- a/persistence-modules/spring-data-jpa-repo-3/README.md +++ b/persistence-modules/spring-data-jpa-repo-3/README.md @@ -6,4 +6,5 @@ This module contains articles about Spring Data JPA. - [New CRUD Repository Interfaces in Spring Data 3](https://www.baeldung.com/spring-data-3-crud-repository-interfaces) - [How to Persist a List of String in JPA?](https://www.baeldung.com/java-jpa-persist-string-list) - [Hibernate Natural IDs in Spring Boot](https://www.baeldung.com/spring-boot-hibernate-natural-ids) +- [Correct Use of flush() in JPA](https://www.baeldung.com/spring-jpa-flush) - More articles: [[<-- prev]](../spring-data-jpa-repo-2) diff --git a/pom.xml b/pom.xml index 807df59289..16156c0d91 100644 --- a/pom.xml +++ b/pom.xml @@ -366,9 +366,11 @@ muleesb web-modules/java-lite web-modules/restx + web-modules/jee-7 persistence-modules/deltaspike persistence-modules/hibernate-ogm persistence-modules/java-cassandra + persistence-modules/spring-data-cassandra-reactive @@ -425,12 +427,10 @@ - spring-security-modules + spring-security-modules/spring-security-ldap spring-soap spring-static-resources spring-swagger-codegen - spring-web-modules - testing-modules video-tutorials @@ -547,9 +547,11 @@ muleesb web-modules/java-lite web-modules/restx + web-modules/jee-7 persistence-modules/deltaspike persistence-modules/hibernate-ogm persistence-modules/java-cassandra + persistence-modules/spring-data-cassandra-reactive @@ -598,12 +600,10 @@ - spring-security-modules + spring-security-modules/spring-security-ldap spring-soap spring-static-resources spring-swagger-codegen - spring-web-modules - testing-modules video-tutorials @@ -801,7 +801,7 @@ quarkus-modules spring-reactive-modules spring-swagger-codegen/custom-validations-opeanpi-codegen - testing-modules/testing-assertions + testing-modules testing-modules/mockito-simple rule-engines-modules @@ -914,7 +914,7 @@ spring-kafka spring-native - spring-security-modules/spring-security-oauth2-testing + spring-security-modules spring-protobuf spring-quartz @@ -926,6 +926,7 @@ spring-threads spring-vault spring-websockets + spring-web-modules static-analysis tensorflow-java vertx-modules @@ -1063,7 +1064,7 @@ quarkus-modules spring-reactive-modules spring-swagger-codegen/custom-validations-opeanpi-codegen - testing-modules/testing-assertions + testing-modules testing-modules/mockito-simple rule-engines-modules @@ -1177,6 +1178,7 @@ spring-kafka spring-native + spring-security-modules spring-protobuf spring-quartz @@ -1188,6 +1190,7 @@ spring-threads spring-vault spring-websockets + spring-web-modules static-analysis tensorflow-java vertx-modules diff --git a/quarkus-modules/quarkus-extension/quarkus-liquibase/deployment/pom.xml b/quarkus-modules/quarkus-extension/quarkus-liquibase/deployment/pom.xml index 9a9e4485cd..823b2f674a 100644 --- a/quarkus-modules/quarkus-extension/quarkus-liquibase/deployment/pom.xml +++ b/quarkus-modules/quarkus-extension/quarkus-liquibase/deployment/pom.xml @@ -41,7 +41,6 @@ org.apache.maven.plugins maven-compiler-plugin - ${compiler.plugin.version} @@ -55,8 +54,4 @@ - - 3.8.1 - - \ No newline at end of file diff --git a/quarkus-modules/quarkus-extension/quarkus-liquibase/runtime/pom.xml b/quarkus-modules/quarkus-extension/quarkus-liquibase/runtime/pom.xml index 6656556c4b..95916932a1 100644 --- a/quarkus-modules/quarkus-extension/quarkus-liquibase/runtime/pom.xml +++ b/quarkus-modules/quarkus-extension/quarkus-liquibase/runtime/pom.xml @@ -52,7 +52,6 @@ org.apache.maven.plugins maven-compiler-plugin - ${compiler.plugin.version} @@ -68,7 +67,6 @@ 3.8.1 - 3.8.1 3.8.1 diff --git a/quarkus-modules/quarkus-funqy/pom.xml b/quarkus-modules/quarkus-funqy/pom.xml index ae9c34e7e0..39a6151c69 100644 --- a/quarkus-modules/quarkus-funqy/pom.xml +++ b/quarkus-modules/quarkus-funqy/pom.xml @@ -6,17 +6,7 @@ com.baeldung.quarkus quarkus-funqy 1.0.0-SNAPSHOT - - 3.10.1 - false - 17 - UTF-8 - UTF-8 - quarkus-bom - io.quarkus.platform - 2.16.0.Final - 3.0.0-M7 - + com.baeldung quarkus-modules @@ -131,4 +121,16 @@ + + + 3.10.1 + false + 17 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 2.16.0.Final + 3.0.0-M7 + diff --git a/quarkus-modules/quarkus-jandex/hello-app/pom.xml b/quarkus-modules/quarkus-jandex/hello-app/pom.xml index 0255a6636b..fffa05d63e 100644 --- a/quarkus-modules/quarkus-jandex/hello-app/pom.xml +++ b/quarkus-modules/quarkus-jandex/hello-app/pom.xml @@ -76,7 +76,6 @@ maven-compiler-plugin - ${compiler-plugin.version} ${maven.compiler.parameters} diff --git a/quarkus-modules/quarkus-jandex/hello-sender-maven-plugin/pom.xml b/quarkus-modules/quarkus-jandex/hello-sender-maven-plugin/pom.xml index 215a00e479..8eb1b87707 100644 --- a/quarkus-modules/quarkus-jandex/hello-sender-maven-plugin/pom.xml +++ b/quarkus-modules/quarkus-jandex/hello-sender-maven-plugin/pom.xml @@ -29,7 +29,7 @@ org.jboss.jandex jandex-maven-plugin - 1.2.1 + ${jandex-maven-plugin.version} make-index @@ -43,4 +43,8 @@ + + 1.2.1 + + \ No newline at end of file diff --git a/quarkus-modules/quarkus-jandex/pom.xml b/quarkus-modules/quarkus-jandex/pom.xml index 25aeee0a46..f207854b55 100644 --- a/quarkus-modules/quarkus-jandex/pom.xml +++ b/quarkus-modules/quarkus-jandex/pom.xml @@ -38,7 +38,6 @@ - 3.8.1 true 11 11 diff --git a/quarkus-modules/quarkus-vs-springboot/spring-project/pom.xml b/quarkus-modules/quarkus-vs-springboot/spring-project/pom.xml index 13508d7086..df3eca8a4f 100644 --- a/quarkus-modules/quarkus-vs-springboot/spring-project/pom.xml +++ b/quarkus-modules/quarkus-vs-springboot/spring-project/pom.xml @@ -3,7 +3,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 - com.baeldung spring-project 0.1-SNAPSHOT @@ -19,7 +18,7 @@ org.testcontainers testcontainers-bom - 1.17.2 + ${testcontainers-bom.version} pom import @@ -43,7 +42,7 @@ com.github.jasync-sql jasync-r2dbc-mysql - 2.0.8 + ${jasync-r2dbc-mysql.version} org.springframework.boot @@ -104,7 +103,6 @@ org.apache.maven.plugins maven-compiler-plugin - ${maven-compiler-plugin.version} ${maven.compiler.source.version} ${maven.compiler.target.version} @@ -182,7 +180,7 @@ local-native exec - 0.9.11 + ${native-buildtools.version} @@ -241,7 +239,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.0.0-M6 + ${maven-surefire-plugin.version} -DspringAot=true -agentlib:native-image-agent=access-filter-file=src/test/resources/access-filter.json,config-merge-dir=target/classes/META-INF/native-image @@ -254,11 +252,15 @@ + 1.17.2 11 0.12.1 3.10.1 11 11 + 3.1.0 + 0.9.11 + 2.0.8 \ No newline at end of file diff --git a/saas-modules/sentry-servlet/pom.xml b/saas-modules/sentry-servlet/pom.xml index 11dd2ad0ff..4f9e37ebd5 100644 --- a/saas-modules/sentry-servlet/pom.xml +++ b/saas-modules/sentry-servlet/pom.xml @@ -3,20 +3,15 @@ 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 + sentry-servlet + sentry-servlet + war + com.baeldung saas-modules 1.0.0-SNAPSHOT - sentry-servlet - sentry-servlet - war - - - 6.11.0 - 1.10.4 - 3.3.2 - @@ -37,7 +32,7 @@ org.codehaus.cargo cargo-maven3-plugin - ${cargo.version} + ${cargo-maven3-plugin.version} tomcat9x @@ -47,4 +42,10 @@ + + + 6.11.0 + 1.10.4 + 3.3.2 + \ No newline at end of file diff --git a/security-modules/java-ee-8-security-api/pom.xml b/security-modules/java-ee-8-security-api/pom.xml index bcd15ed685..7d1a19cb88 100644 --- a/security-modules/java-ee-8-security-api/pom.xml +++ b/security-modules/java-ee-8-security-api/pom.xml @@ -34,7 +34,6 @@ maven-war-plugin - ${maven-war-plugin.version} false pom.xml diff --git a/security-modules/oauth2-framework-impl/README.md b/security-modules/oauth2-framework-impl/README.md index ae28c1b511..e3d9f0c4ee 100644 --- a/security-modules/oauth2-framework-impl/README.md +++ b/security-modules/oauth2-framework-impl/README.md @@ -4,4 +4,4 @@ This module contains articles about the implementation of OAuth2 with Java EE. ### Relevant Articles -- [Implementing The OAuth 2.0 Authorization Framework Using Jakarta EE](https://www.baeldung.com/java-ee-oauth2-implementation) +- [Implementing the Oauth 2.0 Authorization Framework Using Jakarta EE](https://www.baeldung.com/java-ee-oauth2-implementation) diff --git a/server-modules/undertow/pom.xml b/server-modules/undertow/pom.xml index 7d446c29d2..42a46d9508 100644 --- a/server-modules/undertow/pom.xml +++ b/server-modules/undertow/pom.xml @@ -32,7 +32,6 @@ org.apache.maven.plugins maven-jar-plugin - ${maven-jar-plugin.version} diff --git a/server-modules/wildfly/pom.xml b/server-modules/wildfly/pom.xml index af742c7bd3..fece3c9866 100644 --- a/server-modules/wildfly/pom.xml +++ b/server-modules/wildfly/pom.xml @@ -63,7 +63,6 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} @@ -75,8 +74,4 @@ - - 3.3.2 - - \ No newline at end of file diff --git a/spf4j/pom.xml b/spf4j/pom.xml index 6d325947cf..9d747f11dc 100644 --- a/spf4j/pom.xml +++ b/spf4j/pom.xml @@ -19,4 +19,9 @@ spf4j-aspects-app + + 1.10.2 + 8.9.0 + 3.1.1 + \ No newline at end of file diff --git a/spf4j/spf4j-aspects-app/pom.xml b/spf4j/spf4j-aspects-app/pom.xml index 3eccdd879a..9769ff77f3 100644 --- a/spf4j/spf4j-aspects-app/pom.xml +++ b/spf4j/spf4j-aspects-app/pom.xml @@ -45,7 +45,7 @@ org.apache.avro avro - 1.10.2 + ${avro.version} @@ -59,7 +59,6 @@ org.apache.maven.plugins maven-dependency-plugin - ${dependency.plugin.version} copy-dependencies @@ -91,9 +90,4 @@ - - 8.9.0 - 3.1.1 - - \ No newline at end of file diff --git a/spf4j/spf4j-core-app/pom.xml b/spf4j/spf4j-core-app/pom.xml index 20251860aa..ee82ea869a 100644 --- a/spf4j/spf4j-core-app/pom.xml +++ b/spf4j/spf4j-core-app/pom.xml @@ -51,7 +51,7 @@ org.apache.avro avro - 1.10.2 + ${avro.version} @@ -65,7 +65,6 @@ org.apache.maven.plugins maven-dependency-plugin - ${dependency.plugin.version} copy-dependencies @@ -97,9 +96,4 @@ - - 8.9.0 - 3.1.1 - - \ No newline at end of file diff --git a/spring-actuator/pom.xml b/spring-actuator/pom.xml index 48dae45940..20b80d9924 100644 --- a/spring-actuator/pom.xml +++ b/spring-actuator/pom.xml @@ -19,7 +19,7 @@ jakarta.servlet jakarta.servlet-api - 5.0.0 + ${jakarta.servlet-api.version} provided @@ -49,7 +49,6 @@ org.apache.maven.plugins maven-war-plugin - 3.3.2 @@ -68,6 +67,7 @@ + 5.0.0 3.0.6 11.0.15 diff --git a/spring-aop-2/pom.xml b/spring-aop-2/pom.xml index cb84ed4ca2..e4748cdcbf 100644 --- a/spring-aop-2/pom.xml +++ b/spring-aop-2/pom.xml @@ -44,7 +44,6 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} false @@ -54,7 +53,6 @@ 1.14.0 - 3.3.2 \ No newline at end of file diff --git a/spring-aop/pom.xml b/spring-aop/pom.xml index ae5ab5fce1..2b84e2a432 100644 --- a/spring-aop/pom.xml +++ b/spring-aop/pom.xml @@ -72,7 +72,6 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} false @@ -82,7 +81,6 @@ 1.14.0 - 3.3.2 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-actuator/README.md b/spring-boot-modules/spring-boot-actuator/README.md index ea43377ed2..3af4634e44 100644 --- a/spring-boot-modules/spring-boot-actuator/README.md +++ b/spring-boot-modules/spring-boot-actuator/README.md @@ -12,4 +12,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Health Indicators in Spring Boot](https://www.baeldung.com/spring-boot-health-indicators) - [How to Enable All Endpoints in Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuator-enable-endpoints) - [Spring Boot Startup Actuator Endpoint](https://www.baeldung.com/spring-boot-actuator-startup) -- [Metrics for your Spring REST API](https://www.baeldung.com/spring-rest-api-metrics) +- [Metrics for Your Spring REST API](https://www.baeldung.com/spring-rest-api-metrics) diff --git a/spring-boot-modules/spring-boot-gradle-2/README.md b/spring-boot-modules/spring-boot-gradle-2/README.md new file mode 100644 index 0000000000..ba6f30c000 --- /dev/null +++ b/spring-boot-modules/spring-boot-gradle-2/README.md @@ -0,0 +1,2 @@ +## Relevant Articles +- [Configuring Gradle Tasks in Spring Boot 3](https://www.baeldung.com/spring-boot-3-gradle-configure-tasks) diff --git a/spring-boot-modules/spring-boot-mvc-4/pom.xml b/spring-boot-modules/spring-boot-mvc-4/pom.xml index b1c079b715..800ca8e31e 100644 --- a/spring-boot-modules/spring-boot-mvc-4/pom.xml +++ b/spring-boot-modules/spring-boot-mvc-4/pom.xml @@ -32,11 +32,11 @@ spring-boot-devtools true - - io.springfox - springfox-boot-starter - ${spring.fox.version} - + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + com.fasterxml.jackson.core jackson-databind @@ -70,7 +70,7 @@ - 3.0.0 + 1.7.0 com.baeldung.springboot.swagger.ArticleApplication diff --git a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java index 8be380baa0..2b8388f914 100644 --- a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/ArticleApplication.java @@ -5,14 +5,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; @SpringBootApplication -@EnableSwagger2 @EnableWebMvc public class ArticleApplication { @@ -21,12 +17,10 @@ public class ArticleApplication { } @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build(); + public OpenAPI openAPI() { + return new OpenAPI().info(new Info().title("SpringDoc example") + .description("SpringDoc application") + .version("v0.0.1")); } } diff --git a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java index c4336a7cfe..96812e367a 100644 --- a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/controller/ArticlesController.java @@ -21,7 +21,7 @@ public class ArticlesController { } @PostMapping("") - public void addArticle(@ModelAttribute Article article) { + public void addArticle(@RequestBody Article article) { articleService.addArticle(article); } diff --git a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/model/Article.java b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/model/Article.java index f6318c04b3..8a54e54427 100644 --- a/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/model/Article.java +++ b/spring-boot-modules/spring-boot-mvc-4/src/main/java/com/baeldung/springboot/swagger/model/Article.java @@ -1,21 +1,16 @@ package com.baeldung.springboot.swagger.model; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonView; -import io.swagger.annotations.ApiModelProperty; -import io.swagger.annotations.ApiParam; - +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.media.Schema.AccessMode; public class Article { - //@JsonIgnore - //@JsonProperty(access = JsonProperty.Access.READ_ONLY) - //@ApiModelProperty(hidden = true) - //@ApiParam(hidden = true) - //@ApiModelProperty(readOnly = true) - @ApiParam(hidden = true) + // @JsonIgnore + // @JsonProperty(access = JsonProperty.Access.READ_ONLY) + // @Schema(accessMode = AccessMode.READ_ONLY) + @Hidden private int id; private String title; private int numOfWords; diff --git a/spring-boot-modules/spring-boot-properties-2/pom.xml b/spring-boot-modules/spring-boot-properties-2/pom.xml index 4b1daca34d..2c74f7f186 100644 --- a/spring-boot-modules/spring-boot-properties-2/pom.xml +++ b/spring-boot-modules/spring-boot-properties-2/pom.xml @@ -20,10 +20,12 @@ org.springframework.boot spring-boot-starter + ${spring-boot.version} org.springframework.boot spring-boot-starter-web + ${spring-boot.version} commons-lang @@ -34,6 +36,7 @@ com.baeldung.properties.yaml.YamlApplication + 3.1.0 \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/PriorityRecord.java b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/PriorityRecord.java new file mode 100644 index 0000000000..2d88da2f37 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-2/src/main/java/com/baeldung/properties/value/PriorityRecord.java @@ -0,0 +1,10 @@ +package com.baeldung.properties.value; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Component; + +@Component +@PropertySource("classpath:values.properties") +public record PriorityRecord(@Value("${priority:normal}") String priority) { +} diff --git a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/value/PriorityProviderIntegrationTest.java b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/value/PriorityProviderIntegrationTest.java index d7d1e7d78b..5d1ef825fc 100644 --- a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/value/PriorityProviderIntegrationTest.java +++ b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/value/PriorityProviderIntegrationTest.java @@ -1,13 +1,13 @@ package com.baeldung.properties.value; +import static org.assertj.core.api.Assertions.assertThat; + 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.test.context.junit4.SpringRunner; -import static org.assertj.core.api.Assertions.assertThat; - @RunWith(SpringRunner.class) @SpringBootTest(classes = PriorityProvider.class) public class PriorityProviderIntegrationTest { diff --git a/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/value/PriorityRecordIntegrationTest.java b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/value/PriorityRecordIntegrationTest.java new file mode 100644 index 0000000000..571e927bd5 --- /dev/null +++ b/spring-boot-modules/spring-boot-properties-2/src/test/java/com/baeldung/properties/value/PriorityRecordIntegrationTest.java @@ -0,0 +1,23 @@ +package com.baeldung.properties.value; + +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.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = PriorityRecord.class) +public class PriorityRecordIntegrationTest { + + @Autowired + private PriorityRecord priorityRecord; + + @Test + public void givenPropertyFile_WhenConstructorInjectionUsedInRecord_ThenValueInjected() { + assertThat(priorityRecord.priority()).isEqualTo("high"); + } + +} diff --git a/spring-boot-modules/spring-boot-properties-3/README.md b/spring-boot-modules/spring-boot-properties-3/README.md index cb09a0ab81..476797965a 100644 --- a/spring-boot-modules/spring-boot-properties-3/README.md +++ b/spring-boot-modules/spring-boot-properties-3/README.md @@ -13,4 +13,5 @@ - [Using Environment Variables in Spring Boot’s application.properties](https://www.baeldung.com/spring-boot-properties-env-variables) - [Loading Multiple YAML Configuration Files in Spring Boot](https://www.baeldung.com/spring-boot-load-multiple-yaml-configuration-files) - [Using Environment Variables in Spring Boot’s Properties Files](https://www.baeldung.com/spring-boot-properties-env-variables) +- [Spring Boot Properties Prefix Must Be in Canonical Form](https://www.baeldung.com/spring-boot-properties-canonical-form) - More articles: [[<-- prev]](../spring-boot-properties-2) diff --git a/spring-boot-modules/spring-boot-testing-2/README.md b/spring-boot-modules/spring-boot-testing-2/README.md index bb504aeee0..e6bc4c4590 100644 --- a/spring-boot-modules/spring-boot-testing-2/README.md +++ b/spring-boot-modules/spring-boot-testing-2/README.md @@ -8,7 +8,7 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles: -- [Setting the Log Level in Spring Boot when Testing](https://www.baeldung.com/spring-boot-testing-log-level) +- [Setting the Log Level in Spring Boot When Testing](https://www.baeldung.com/spring-boot-testing-log-level) - [Failed to Load ApplicationContext for JUnit Test of Spring Controller](https://www.baeldung.com/spring-junit-failed-to-load-applicationcontext) - [Spring Web Service Integration Tests with @WebServiceServerTest](https://www.baeldung.com/spring-webserviceservertest) - [Spring Boot – Testing Redis With Testcontainers](https://www.baeldung.com/spring-boot-redis-testcontainers) diff --git a/spring-core-3/README.md b/spring-core-3/README.md index ed88561e10..dcdbbd3a67 100644 --- a/spring-core-3/README.md +++ b/spring-core-3/README.md @@ -6,7 +6,7 @@ This module contains articles about core Spring functionality - [Understanding getBean() in Spring](https://www.baeldung.com/spring-getbean) - [Guide to the Spring BeanFactory](https://www.baeldung.com/spring-beanfactory) -- [How to use the Spring FactoryBean?](https://www.baeldung.com/spring-factorybean) +- [How to Use the Spring FactoryBean?](https://www.baeldung.com/spring-factorybean) - [Design Patterns in the Spring Framework](https://www.baeldung.com/spring-framework-design-patterns) - [Difference Between BeanFactory and ApplicationContext](https://www.baeldung.com/spring-beanfactory-vs-applicationcontext) - [Custom Scope in Spring](http://www.baeldung.com/spring-custom-scope) diff --git a/spring-core/README.md b/spring-core/README.md index ffcbf4757b..8e85ae44f3 100644 --- a/spring-core/README.md +++ b/spring-core/README.md @@ -8,7 +8,7 @@ This module contains articles about core Spring functionality. - [BeanNameAware and BeanFactoryAware Interfaces in Spring](https://www.baeldung.com/spring-bean-name-factory-aware) - [Access a File from the Classpath in a Spring Application](https://www.baeldung.com/spring-classpath-file-access) - [Spring Application Context Events](https://www.baeldung.com/spring-context-events) -- [What is a Spring Bean?](https://www.baeldung.com/spring-bean) +- [What Is a Spring Bean?](https://www.baeldung.com/spring-bean) - [Spring PostConstruct and PreDestroy Annotations](https://www.baeldung.com/spring-postconstruct-predestroy) - [Intro to the Spring ClassPathXmlApplicationContext](http://www.baeldung.com/spring-classpathxmlapplicationcontext) - More articles: [[next -->]](../spring-core-2) diff --git a/spring-di-3/README.md b/spring-di-3/README.md index ffb81fbe7d..64cf11eb6b 100644 --- a/spring-di-3/README.md +++ b/spring-di-3/README.md @@ -9,6 +9,6 @@ This module contains articles about dependency injection with Spring - [Finding All Beans with a Custom Annotation](https://www.baeldung.com/spring-injecting-all-annotated-beans) - [Guide to Spring @Autowired](http://www.baeldung.com/spring-autowire) - [@Order in Spring](http://www.baeldung.com/spring-order) -- [How to dynamically Autowire a Bean in Spring](https://www.baeldung.com/spring-dynamic-autowire) +- [How to Dynamically Autowire a Bean in Spring](https://www.baeldung.com/spring-dynamic-autowire) - [Spring @Import Annotation](https://www.baeldung.com/spring-import-annotation) - More articles: [[<-- prev]](../spring-di-2)[[more -->]](../spring-di-4) diff --git a/spring-di-4/src/main/java/com/baeldung/fieldinjection/EmailService.java b/spring-di-4/src/main/java/com/baeldung/fieldinjection/EmailService.java new file mode 100644 index 0000000000..2c28b5baf4 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/fieldinjection/EmailService.java @@ -0,0 +1,21 @@ +package com.baeldung.fieldinjection; + +import org.springframework.stereotype.Service; + +@Service +public class EmailService { + + public static final String INVALID_EMAIL = "Invalid email"; + private final EmailValidator emailValidator; + + public EmailService(final EmailValidator emailValidator) { + this.emailValidator = emailValidator; + } + + public void process(String email) { + if (!emailValidator.isValid(email)) { + throw new IllegalArgumentException(INVALID_EMAIL); + } + // ... + } +} \ No newline at end of file diff --git a/spring-di-4/src/main/java/com/baeldung/fieldinjection/EmailValidator.java b/spring-di-4/src/main/java/com/baeldung/fieldinjection/EmailValidator.java new file mode 100644 index 0000000000..884a139781 --- /dev/null +++ b/spring-di-4/src/main/java/com/baeldung/fieldinjection/EmailValidator.java @@ -0,0 +1,17 @@ +package com.baeldung.fieldinjection; + +import org.springframework.stereotype.Component; + +import java.util.regex.Pattern; + +@Component +public class EmailValidator { + + private static final String REGEX_PATTERN = "^(.+)@(\\S+)$"; + + public boolean isValid(final String email) { + return Pattern.compile(REGEX_PATTERN) + .matcher(email) + .matches(); + } +} diff --git a/spring-di-4/src/test/java/com/baeldung/fieldinjection/EmailServiceUnitTest.java b/spring-di-4/src/test/java/com/baeldung/fieldinjection/EmailServiceUnitTest.java new file mode 100644 index 0000000000..b2bcbad811 --- /dev/null +++ b/spring-di-4/src/test/java/com/baeldung/fieldinjection/EmailServiceUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.fieldinjection; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class EmailServiceUnitTest { + + private EmailValidator emailValidator; + + private EmailService emailService; + + @BeforeEach + public void setup() { + this.emailValidator = Mockito.mock(EmailValidator.class); + this.emailService = new EmailService(emailValidator); + } + + @Test + void givenInvalidEmail_whenProcess_thenThrowException() { + String email = "testbaeldung.com"; + + when(emailValidator.isValid(email)).thenReturn(false); + + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> emailService.process(email)); + + assertNotNull(exception); + assertEquals(EmailService.INVALID_EMAIL, exception.getMessage()); + } +} diff --git a/spring-ejb-modules/pom.xml b/spring-ejb-modules/pom.xml index 146d64c298..1ebfb66c32 100755 --- a/spring-ejb-modules/pom.xml +++ b/spring-ejb-modules/pom.xml @@ -55,23 +55,6 @@ - - - jboss-public-repository-group - JBoss Public Maven Repository Group - http://repository.jboss.org/nexus/content/groups/public/ - default - - true - never - - - true - never - - - - diff --git a/spring-integration/README.md b/spring-integration/README.md index ad46082a04..710af2a8c7 100644 --- a/spring-integration/README.md +++ b/spring-integration/README.md @@ -4,7 +4,7 @@ This module contains articles about Spring Integration ### Relevant Articles: - [Introduction to Spring Integration](https://www.baeldung.com/spring-integration) -- [Security In Spring Integration](https://www.baeldung.com/spring-integration-security) +- [Security in Spring Integration](https://www.baeldung.com/spring-integration-security) - [Spring Integration Java DSL](https://www.baeldung.com/spring-integration-java-dsl) - [Using Subflows in Spring Integration](https://www.baeldung.com/spring-integration-subflows) - [Transaction Support in Spring Integration](https://www.baeldung.com/spring-integration-transaction) diff --git a/spring-native/README.md b/spring-native/README.md index 72308cb9d5..0f193252d0 100644 --- a/spring-native/README.md +++ b/spring-native/README.md @@ -1,4 +1,3 @@ ## Relevant Articles: - [Introduction to Spring Native](https://www.baeldung.com/spring-native-intro) -- [Ahead of Time Optimizations in Spring 6](https://www.baeldung.com/aot-optimization-spring) \ No newline at end of file diff --git a/spring-reactive-modules/spring-5-reactive/README.md b/spring-reactive-modules/spring-5-reactive/README.md index aa8d2800e2..f3148fe696 100644 --- a/spring-reactive-modules/spring-5-reactive/README.md +++ b/spring-reactive-modules/spring-5-reactive/README.md @@ -9,7 +9,6 @@ The "REST With Spring" Classes: https://bit.ly/restwithspring - [Exploring the Spring 5 WebFlux URL Matching](https://www.baeldung.com/spring-5-mvc-url-matching) - [Reactive WebSockets with Spring 5](https://www.baeldung.com/spring-5-reactive-websockets) -- [Spring WebFlux Filters](https://www.baeldung.com/spring-webflux-filters) - [How to Set a Header on a Response with Spring 5](https://www.baeldung.com/spring-response-header) - [A Guide to Spring Session Reactive Support: WebSession](https://www.baeldung.com/spring-session-reactive) - More articles: [[next -->]](../spring-5-reactive-2) diff --git a/spring-security-modules/pom.xml b/spring-security-modules/pom.xml index 030f1ef876..2c9a8e3dfe 100644 --- a/spring-security-modules/pom.xml +++ b/spring-security-modules/pom.xml @@ -20,7 +20,7 @@ spring-security-cognito spring-security-core spring-security-core-2 - spring-security-ldap + spring-security-legacy-oidc spring-security-oauth2 spring-security-oauth2-sso diff --git a/spring-security-modules/spring-security-oauth2-sso/pom.xml b/spring-security-modules/spring-security-oauth2-sso/pom.xml index c9f9274c98..a87e4d7814 100644 --- a/spring-security-modules/spring-security-oauth2-sso/pom.xml +++ b/spring-security-modules/spring-security-oauth2-sso/pom.xml @@ -3,7 +3,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 - com.baeldung spring-security-oauth2-sso 1.0.0-SNAPSHOT spring-security-oauth2-sso diff --git a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-auth-server/pom.xml b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-auth-server/pom.xml index 1a8d1b580f..9ecea81ed3 100644 --- a/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-auth-server/pom.xml +++ b/spring-security-modules/spring-security-oauth2-sso/spring-security-sso-auth-server/pom.xml @@ -23,6 +23,27 @@ spring-security-oauth2 ${oauth.version} + + jakarta.annotation + jakarta.annotation-api + ${jakarta.annotation-api.version} + + + jakarta.xml.bind + jakarta.xml.bind-api + ${jakarta.xml.bind-api.version} + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + + + 1.3.5 + 2.3.3 + 2.3.5 + + \ No newline at end of file diff --git a/spring-security-modules/spring-security-saml2/README.md b/spring-security-modules/spring-security-saml2/README.md new file mode 100644 index 0000000000..6078ac2215 --- /dev/null +++ b/spring-security-modules/spring-security-saml2/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [SAML with Spring Boot and Spring Security](https://www.baeldung.com/spring-security-saml) diff --git a/spring-security-modules/spring-security-web-boot-4/README.md b/spring-security-modules/spring-security-web-boot-4/README.md index af8ed4e76a..8a7dbf3029 100644 --- a/spring-security-modules/spring-security-web-boot-4/README.md +++ b/spring-security-modules/spring-security-web-boot-4/README.md @@ -9,5 +9,5 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com - [Spring Security: Upgrading the Deprecated WebSecurityConfigurerAdapter](https://www.baeldung.com/spring-deprecated-websecurityconfigureradapter) - [Spring @EnableMethodSecurity Annotation](https://www.baeldung.com/spring-enablemethodsecurity) - +- [Securing Spring Boot API With API Key and Secret](https://www.baeldung.com/spring-boot-api-key-secret) More articles: [[<-- prev]](/spring-security-modules/spring-security-web-boot-3) diff --git a/spring-security-modules/spring-security-web-mvc-custom/README.md b/spring-security-modules/spring-security-web-mvc-custom/README.md index d8bd4cb3e0..6a38460b28 100644 --- a/spring-security-modules/spring-security-web-mvc-custom/README.md +++ b/spring-security-modules/spring-security-web-mvc-custom/README.md @@ -9,7 +9,7 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com ### Relevant Articles: - [Spring Security Remember Me](https://www.baeldung.com/spring-security-remember-me) -- [Redirect to Different Pages after Login with Spring Security](https://www.baeldung.com/spring-redirect-after-login) +- [Redirect to Different Pages After Login With Spring Security](https://www.baeldung.com/spring-redirect-after-login) - [Changing Spring Model Parameters with Handler Interceptor](https://www.baeldung.com/spring-model-parameters-with-handler-interceptor) - [Introduction to Spring MVC HandlerInterceptor](https://www.baeldung.com/spring-mvc-handlerinterceptor) - [Using a Custom Spring MVC’s Handler Interceptor to Manage Sessions](https://www.baeldung.com/spring-mvc-custom-handler-interceptor) 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 104b7025ad..f21c6dbe40 100644 --- a/spring-security-modules/spring-security-web-mvc-custom/pom.xml +++ b/spring-security-modules/spring-security-web-mvc-custom/pom.xml @@ -126,6 +126,11 @@ ${spring-security.version} test + + javax.annotation + javax.annotation-api + ${javax.annotation-api.version} + @@ -169,6 +174,7 @@ 3.2.2 1.6.1 + 1.3.2 \ No newline at end of file diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/README.md b/spring-security-modules/spring-security-web-rest-basic-auth/README.md index 097e89b138..9070179676 100644 --- a/spring-security-modules/spring-security-web-rest-basic-auth/README.md +++ b/spring-security-modules/spring-security-web-rest-basic-auth/README.md @@ -11,7 +11,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com - [Basic Authentication with the RestTemplate](https://www.baeldung.com/how-to-use-resttemplate-with-basic-authentication-in-spring) - [A Custom Filter in the Spring Security Filter Chain](https://www.baeldung.com/spring-security-custom-filter) - [Spring Security Basic Authentication](https://www.baeldung.com/spring-security-basic-authentication) -- [New Password Storage In Spring Security 5](https://www.baeldung.com/spring-security-5-password-storage) +- [New Password Storage in Spring Security 5](https://www.baeldung.com/spring-security-5-password-storage) - [Default Password Encoder in Spring Security 5](https://www.baeldung.com/spring-security-5-default-password-encoder) - [Basic Authentication With Postman](https://www.baeldung.com/java-postman-authentication) diff --git a/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml b/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml index 291d732049..3c842a8a54 100644 --- a/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml +++ b/spring-security-modules/spring-security-web-rest-basic-auth/pom.xml @@ -127,6 +127,11 @@ spring-test test + + javax.xml.bind + jaxb-api + ${jaxb-api.version} + @@ -220,6 +225,7 @@ + 2.3.1 4.4.11 4.5.8 diff --git a/spring-security-modules/spring-security-web-rest-custom/pom.xml b/spring-security-modules/spring-security-web-rest-custom/pom.xml index d420c45df2..dfd2f59aaf 100644 --- a/spring-security-modules/spring-security-web-rest-custom/pom.xml +++ b/spring-security-modules/spring-security-web-rest-custom/pom.xml @@ -115,6 +115,11 @@ commons-lang3 ${commons-lang3.version} + + javax.xml.bind + jaxb-api + ${jaxb-api.version} + @@ -165,6 +170,7 @@ 1.2 + 2.3.1 1.6.1 diff --git a/spring-security-modules/spring-security-web-sockets/pom.xml b/spring-security-modules/spring-security-web-sockets/pom.xml index 802c894612..513ee28c85 100644 --- a/spring-security-modules/spring-security-web-sockets/pom.xml +++ b/spring-security-modules/spring-security-web-sockets/pom.xml @@ -149,6 +149,12 @@ ${spring-boot-starter-test.version} test + + + javax.xml.bind + jaxb-api + ${jaxb-api.version} + @@ -168,12 +174,22 @@ org.apache.maven.plugins maven-war-plugin - 3.0.0 + ${maven-war-plugin.version} src/main/webapp false + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + --add-opens java.base/java.lang.invoke=ALL-UNNAMED + + + @@ -182,6 +198,7 @@ 1.11.3.RELEASE 1.5.10.RELEASE 1.7.6 + 2.3.1 \ No newline at end of file diff --git a/spring-web-modules/spring-freemarker/pom.xml b/spring-web-modules/spring-freemarker/pom.xml index 07d37736b6..9ac01fd106 100644 --- a/spring-web-modules/spring-freemarker/pom.xml +++ b/spring-web-modules/spring-freemarker/pom.xml @@ -55,9 +55,23 @@ + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + + + + 5.0.8.RELEASE - 2.3.28 + 2.3.32 false 1.5.10.RELEASE diff --git a/spring-web-modules/spring-mvc-basics-2/pom.xml b/spring-web-modules/spring-mvc-basics-2/pom.xml index 79d1531274..28eb3a16f2 100644 --- a/spring-web-modules/spring-mvc-basics-2/pom.xml +++ b/spring-web-modules/spring-mvc-basics-2/pom.xml @@ -136,7 +136,6 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} src/main/webapp springMvcSimple @@ -149,8 +148,6 @@ - 1.8 - 1.8 6.0.10.Final enter-location-of-server 3.0.11.RELEASE diff --git a/spring-web-modules/spring-mvc-basics-5/pom.xml b/spring-web-modules/spring-mvc-basics-5/pom.xml index 0f2b0bc7bd..c957d669bd 100644 --- a/spring-web-modules/spring-mvc-basics-5/pom.xml +++ b/spring-web-modules/spring-mvc-basics-5/pom.xml @@ -41,14 +41,18 @@ org.apache.commons commons-io - 1.3.2 + ${commons-io.version} com.jayway.jsonpath json-path - 2.7.0 + ${json-path.version} + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} - @@ -65,4 +69,10 @@ + + 1.3.2 + 2.7.0 + 2.3.5 + + \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-basics/pom.xml b/spring-web-modules/spring-mvc-basics/pom.xml index ccd6773e6f..0f1d423ca2 100644 --- a/spring-web-modules/spring-mvc-basics/pom.xml +++ b/spring-web-modules/spring-mvc-basics/pom.xml @@ -39,6 +39,11 @@ spring-boot-starter-test test + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + @@ -55,4 +60,8 @@ + + 2.3.5 + + \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-crash/pom.xml b/spring-web-modules/spring-mvc-crash/pom.xml index 2b7b79666d..f3faa18816 100644 --- a/spring-web-modules/spring-mvc-crash/pom.xml +++ b/spring-web-modules/spring-mvc-crash/pom.xml @@ -124,7 +124,15 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + diff --git a/spring-web-modules/spring-mvc-forms-jsp/pom.xml b/spring-web-modules/spring-mvc-forms-jsp/pom.xml index b0269e3344..3ad815e95f 100644 --- a/spring-web-modules/spring-mvc-forms-jsp/pom.xml +++ b/spring-web-modules/spring-mvc-forms-jsp/pom.xml @@ -68,6 +68,11 @@ ${spring-boot-starter-test.version} test + + javax.annotation + javax.annotation-api + ${javax.annotation-api.version} + @@ -83,7 +88,6 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} src/main/webapp spring-mvc-forms @@ -101,6 +105,7 @@ 6.0.10.Final 5.2.5.Final 6.0.6 + 1.3.2 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java-2/pom.xml b/spring-web-modules/spring-mvc-java-2/pom.xml index 1bbb066786..d88a9c320a 100644 --- a/spring-web-modules/spring-mvc-java-2/pom.xml +++ b/spring-web-modules/spring-mvc-java-2/pom.xml @@ -36,6 +36,11 @@ commons-io ${commons-io.version} + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + @@ -51,6 +56,7 @@ 4.0.1 5.2.2.RELEASE + 2.3.5 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-java/pom.xml b/spring-web-modules/spring-mvc-java/pom.xml index 208973eccb..8098f07282 100644 --- a/spring-web-modules/spring-mvc-java/pom.xml +++ b/spring-web-modules/spring-mvc-java/pom.xml @@ -126,7 +126,6 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} false @@ -227,7 +226,6 @@ 4.5.2 2.23 - 3.2.2 2.7 1.6.1 3.1.0 diff --git a/spring-web-modules/spring-mvc-velocity/pom.xml b/spring-web-modules/spring-mvc-velocity/pom.xml index 1b1e8b1ea4..676fa09dac 100644 --- a/spring-web-modules/spring-mvc-velocity/pom.xml +++ b/spring-web-modules/spring-mvc-velocity/pom.xml @@ -88,11 +88,19 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} false + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + diff --git a/spring-web-modules/spring-mvc-views/pom.xml b/spring-web-modules/spring-mvc-views/pom.xml index 79cf82bc0b..d2b5d45366 100644 --- a/spring-web-modules/spring-mvc-views/pom.xml +++ b/spring-web-modules/spring-mvc-views/pom.xml @@ -83,16 +83,10 @@ org.apache.maven.plugins maven-compiler-plugin - 2.0.2 - - ${java.version} - ${java.version} - org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} src/main/webapp spring-mvc-views diff --git a/spring-web-modules/spring-mvc-webflow/pom.xml b/spring-web-modules/spring-mvc-webflow/pom.xml index 69985a7b9d..a128103bac 100644 --- a/spring-web-modules/spring-mvc-webflow/pom.xml +++ b/spring-web-modules/spring-mvc-webflow/pom.xml @@ -71,7 +71,7 @@ org.apache.tomee.maven tomee-maven-plugin - 8.0.1 + ${tomee-maven-plugin.version} 8080 spring-mvc-webflow @@ -91,11 +91,19 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} false + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + @@ -110,6 +118,7 @@ 2.7 1.6.1 1.5.10.RELEASE + 8.0.1 \ No newline at end of file diff --git a/spring-web-modules/spring-mvc-xml-2/pom.xml b/spring-web-modules/spring-mvc-xml-2/pom.xml index 5910823e95..f4326ccf68 100644 --- a/spring-web-modules/spring-mvc-xml-2/pom.xml +++ b/spring-web-modules/spring-mvc-xml-2/pom.xml @@ -81,7 +81,15 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + diff --git a/spring-web-modules/spring-mvc-xml/pom.xml b/spring-web-modules/spring-mvc-xml/pom.xml index d8d4082219..bf0dc52b68 100644 --- a/spring-web-modules/spring-mvc-xml/pom.xml +++ b/spring-web-modules/spring-mvc-xml/pom.xml @@ -119,7 +119,15 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + diff --git a/spring-web-modules/spring-rest-http-2/pom.xml b/spring-web-modules/spring-rest-http-2/pom.xml index 10d904e302..d83a83c690 100644 --- a/spring-web-modules/spring-rest-http-2/pom.xml +++ b/spring-web-modules/spring-rest-http-2/pom.xml @@ -24,16 +24,6 @@ org.springframework.boot spring-boot-starter-webflux - - io.springfox - springfox-swagger2 - ${swagger2.version} - - - io.springfox - springfox-swagger-ui - ${swagger2.version} - com.h2database h2 @@ -47,11 +37,23 @@ resilience4j-timelimiter ${resilience4j.version} + + org.springdoc + springdoc-openapi-ui + ${springdoc.version} + + + com.google.guava + guava + ${guava.version} + 2.9.2 1.6.1 + 1.7.0 + 31.0.1-jre \ No newline at end of file diff --git a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringDocConfig.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringDocConfig.java new file mode 100644 index 0000000000..2df6cd118c --- /dev/null +++ b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringDocConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.endpoint.swagger; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; + +@Configuration +public class SpringDocConfig { + + @Bean + public OpenAPI openAPI() { + return new OpenAPI().info(new Info().title("SpringDoc example") + .description("SpringDoc application") + .version("v0.0.1")); + } +} diff --git a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java deleted file mode 100644 index bd258122cd..0000000000 --- a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/endpoint/swagger/SpringFoxConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.endpoint.swagger; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; - -@Configuration -public class SpringFoxConfig { - - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build(); - } -} diff --git a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/SwaggerUIDisableApplication.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/SwaggerUIDisableApplication.java new file mode 100644 index 0000000000..5aa4f219f0 --- /dev/null +++ b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/SwaggerUIDisableApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.swaggerui.disable; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SwaggerUIDisableApplication { + + public static void main(String[] args) { + SpringApplication.run(SwaggerUIDisableApplication.class, args); + } +} diff --git a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/config/SwaggerConfig.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/config/SwaggerConfig.java index e3c0237b06..d9981b7097 100644 --- a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/config/SwaggerConfig.java +++ b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/config/SwaggerConfig.java @@ -6,33 +6,21 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; @Profile("!prod && swagger") //@Profile("!prod") // @Profile("swagger") // @ConditionalOnExpression(value = "${useSwagger:false}") @Configuration -@EnableSwagger2 -public class SwaggerConfig implements WebMvcConfigurer { +public class SwaggerConfig { @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2).select() - .apis(RequestHandlerSelectors.basePackage("com.baeldung")) - .paths(PathSelectors.regex("/.*")) - .build(); - } - - @Override - public void addResourceHandlers(ResourceHandlerRegistry registry) { - registry.addResourceHandler("swagger-ui.html") - .addResourceLocations("classpath:/META-INF/resources/"); - registry.addResourceHandler("/webjars/**") - .addResourceLocations("classpath:/META-INF/resources/webjars/"); + public OpenAPI openAPI() { + return new OpenAPI().info(new Info().title("SpringDoc Disable SwaggerUI example") + .description("SpringDoc Disable SwaggerUI application") + .version("v0.0.1")); } } diff --git a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/controllers/VersionController.java b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/controllers/VersionController.java index 8f8115197e..403c7f6aa5 100644 --- a/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/controllers/VersionController.java +++ b/spring-web-modules/spring-rest-http-2/src/main/java/com/baeldung/swaggerui/disable/controllers/VersionController.java @@ -1,6 +1,6 @@ package com.baeldung.swaggerui.disable.controllers; -import io.swagger.annotations.ApiOperation; +import io.swagger.v3.oas.annotations.Operation; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -14,7 +14,7 @@ public class VersionController { this.environment = environment; } - @ApiOperation(value = "Get the currently deployed API version and active Spring profiles") + @Operation(summary = "Get the currently deployed API version and active Spring profiles") @GetMapping("/api/version") public Version getVersion() { return new Version("1.0", environment.getActiveProfiles()); diff --git a/spring-web-modules/spring-rest-testing/README.md b/spring-web-modules/spring-rest-testing/README.md index 806e67b7ec..e043667160 100644 --- a/spring-web-modules/spring-rest-testing/README.md +++ b/spring-web-modules/spring-rest-testing/README.md @@ -10,7 +10,7 @@ The "Learn Spring Security" Classes: http://github.learnspringsecurity.com ### Relevant Articles: -- [Integration Testing with the Maven Cargo plugin](https://www.baeldung.com/integration-testing-with-the-maven-cargo-plugin) +- [Integration Testing With the Maven Cargo Plugin](https://www.baeldung.com/integration-testing-with-the-maven-cargo-plugin) - [Testing Exceptions with Spring MockMvc](https://www.baeldung.com/spring-mvc-test-exceptions) ### Build the Project diff --git a/spring-web-modules/spring-thymeleaf-4/pom.xml b/spring-web-modules/spring-thymeleaf-4/pom.xml index 8063b14c39..163d590c9f 100644 --- a/spring-web-modules/spring-thymeleaf-4/pom.xml +++ b/spring-web-modules/spring-thymeleaf-4/pom.xml @@ -107,7 +107,6 @@ org.apache.maven.plugins maven-war-plugin - ${maven-war-plugin.version} false diff --git a/spring-web-modules/spring-thymeleaf-5/src/main/java/com/baeldung/thymeleaf/attribute/CheckedAttributeController.java b/spring-web-modules/spring-thymeleaf-5/src/main/java/com/baeldung/thymeleaf/attribute/CheckedAttributeController.java new file mode 100644 index 0000000000..165e98ac3a --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-5/src/main/java/com/baeldung/thymeleaf/attribute/CheckedAttributeController.java @@ -0,0 +1,29 @@ +package com.baeldung.thymeleaf.attribute; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; + +@Controller +public class CheckedAttributeController { + + @GetMapping("/checked") + public String displayCheckboxForm(Model model) { + Engine engine = new Engine(true); + model.addAttribute("engine", engine); + model.addAttribute("flag", true); + return "attribute/index"; + } + + private static class Engine { + private Boolean active; + + public Engine(Boolean active) { + this.active = active; + } + + public Boolean getActive() { + return active; + } + } +} diff --git a/spring-web-modules/spring-thymeleaf-5/src/main/resources/templates/attribute/index.html b/spring-web-modules/spring-thymeleaf-5/src/main/resources/templates/attribute/index.html new file mode 100644 index 0000000000..a7c5b90296 --- /dev/null +++ b/spring-web-modules/spring-thymeleaf-5/src/main/resources/templates/attribute/index.html @@ -0,0 +1,27 @@ + + + + + Spring Boot Thymeleaf Application - Checkbox Checked Conditionally + + + + + + + + + Flag activated + + + Customer activated + + + Flag deactivated + + + + + + + \ No newline at end of file diff --git a/testing-modules/gatling-java/pom.xml b/testing-modules/gatling-java/pom.xml index 54e18b3ac1..abe033f298 100644 --- a/testing-modules/gatling-java/pom.xml +++ b/testing-modules/gatling-java/pom.xml @@ -60,7 +60,12 @@ gatling-maven-plugin ${gatling-maven-plugin.version} - org.baeldung.EmployeeRegistrationSimulation + + org.baeldung.EmployeeRegistrationSimulation + org.baeldung.gatling.http.FetchSinglePostSimulation + org.baeldung.gatling.http.FetchSinglePostSimulationLog + + true @@ -70,8 +75,8 @@ 1.8 1.8 UTF-8 - 3.9.0 - 4.2.9 + 3.9.5 + 4.3.0 1.0.2 2.7.5 diff --git a/testing-modules/gatling-java/src/test/java/org/baeldung/gatling/http/FetchSinglePostSimulation.java b/testing-modules/gatling-java/src/test/java/org/baeldung/gatling/http/FetchSinglePostSimulation.java new file mode 100644 index 0000000000..16cf25faef --- /dev/null +++ b/testing-modules/gatling-java/src/test/java/org/baeldung/gatling/http/FetchSinglePostSimulation.java @@ -0,0 +1,23 @@ +package org.baeldung.gatling.http; + +import io.gatling.javaapi.core.*; +import io.gatling.javaapi.http.*; +import static io.gatling.javaapi.http.HttpDsl.*; +import static io.gatling.javaapi.core.CoreDsl.*; + +public class FetchSinglePostSimulation extends Simulation { + + public FetchSinglePostSimulation() { + HttpProtocolBuilder httpProtocolBuilder = http.baseUrl("https://jsonplaceholder.typicode.com"); + + ScenarioBuilder scn = scenario("Display Full HTTP Response Body").exec(http("GET Request").get("/posts/1") + .check(status().is(200)) + .check(bodyString().saveAs("responseBody"))) + .exec(session -> { + System.out.println("Response Body:"); + System.out.println(session.getString("responseBody")); + return session; + }); + setUp(scn.injectOpen(atOnceUsers(1))).protocols(httpProtocolBuilder); + } +} diff --git a/testing-modules/gatling-java/src/test/java/org/baeldung/gatling/http/FetchSinglePostSimulationLog.java b/testing-modules/gatling-java/src/test/java/org/baeldung/gatling/http/FetchSinglePostSimulationLog.java new file mode 100644 index 0000000000..9ad4d6edf6 --- /dev/null +++ b/testing-modules/gatling-java/src/test/java/org/baeldung/gatling/http/FetchSinglePostSimulationLog.java @@ -0,0 +1,42 @@ +package org.baeldung.gatling.http; + +import io.gatling.javaapi.core.ScenarioBuilder; +import io.gatling.javaapi.core.Simulation; +import io.gatling.javaapi.http.HttpProtocolBuilder; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; + +import static io.gatling.javaapi.core.CoreDsl.*; +import static io.gatling.javaapi.http.HttpDsl.http; +import static io.gatling.javaapi.http.HttpDsl.status; + +public class FetchSinglePostSimulationLog extends Simulation { + + public FetchSinglePostSimulationLog() { + HttpProtocolBuilder httpProtocolBuilder = http.baseUrl("https://jsonplaceholder.typicode.com"); + + ScenarioBuilder scn = scenario("Display Full HTTP Response Body").exec(http("GET Request").get("/posts/1") + .check(status().is(200)) + .check(bodyString().saveAs("responseBody"))) + .exec(session -> { + + String responseBody = session.getString("responseBody"); + try { + writeFile("response_body.log", responseBody); + } catch (IOException e) { + System.err.println("error writing file"); + } + return session; + }); + setUp(scn.injectOpen(atOnceUsers(1))).protocols(httpProtocolBuilder); + } + + private void writeFile(String fileName, String content) throws IOException { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, true))) { + writer.write(content); + writer.newLine(); + } + } +} diff --git a/testing-modules/junit-5-advanced/pom.xml b/testing-modules/junit-5-advanced/pom.xml index 998f6561ea..3ae62eac2e 100644 --- a/testing-modules/junit-5-advanced/pom.xml +++ b/testing-modules/junit-5-advanced/pom.xml @@ -53,6 +53,7 @@ org.apache.maven.plugins maven-surefire-plugin + ${maven-surefire-plugin.version} -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar @@ -70,6 +71,7 @@ 1.49 3.24.2 1.9.2 + 3.0.0 \ No newline at end of file diff --git a/testing-modules/junit-5-basics/README.md b/testing-modules/junit-5-basics/README.md index 31eb75a792..03b0d4269a 100644 --- a/testing-modules/junit-5-basics/README.md +++ b/testing-modules/junit-5-basics/README.md @@ -7,5 +7,5 @@ - [@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll](http://www.baeldung.com/junit-before-beforeclass-beforeeach-beforeall) - [JUnit 5 @Test Annotation](http://www.baeldung.com/junit-5-test-annotation) - [Migrating from JUnit 4 to JUnit 5](http://www.baeldung.com/junit-5-migration) -- [Assert an Exception is Thrown in JUnit 4 and 5](http://www.baeldung.com/junit-assert-exception) +- [Assert an Exception Is Thrown in JUnit 4 and 5](https://www.baeldung.com/junit-assert-exception) - [The Difference Between Failure and Error in JUnit](https://www.baeldung.com/junit-failure-vs-error) diff --git a/testing-modules/junit-5-basics/pom.xml b/testing-modules/junit-5-basics/pom.xml index a758d79069..9c3cf7a7e4 100644 --- a/testing-modules/junit-5-basics/pom.xml +++ b/testing-modules/junit-5-basics/pom.xml @@ -61,6 +61,17 @@ true + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + + diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index 047eddcbcb..8afaa085b1 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -121,8 +121,13 @@ org.apache.maven.plugins - maven-surefire-report-plugin - ${surefire.report.plugin} + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + --add-opens java.base/java.time=ALL-UNNAMED + + @@ -131,7 +136,6 @@ 2.17.1 2.0.9 5.0.1.RELEASE - 3.0.0-M3 3.3.0 diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectPackagesSuiteUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectPackagesSuiteUnitTest.java index ef8756a2bb..088fc00853 100644 --- a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectPackagesSuiteUnitTest.java +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5vstestng/SelectPackagesSuiteUnitTest.java @@ -4,7 +4,7 @@ import org.junit.platform.suite.api.SelectPackages; import org.junit.platform.suite.api.Suite; @Suite -@SelectPackages({ "com.baeldung.java.suite.childpackage1", "com.baeldung.java.suite.childpackage2" }) +@SelectPackages({ "com.baeldung.java.suite.junit4", "com.baeldung.java.suite.junit5" }) public class SelectPackagesSuiteUnitTest { } diff --git a/testing-modules/mocks-2/pom.xml b/testing-modules/mocks-2/pom.xml index e47649ca33..22a5198b8c 100644 --- a/testing-modules/mocks-2/pom.xml +++ b/testing-modules/mocks-2/pom.xml @@ -23,11 +23,18 @@ jackson-databind ${jackson.version} + + org.springframework + spring-test + ${spring-test.version} + test + 1.6.0 2.13.4 + 5.3.25 \ No newline at end of file diff --git a/testing-modules/mocks-2/src/main/java/com/baeldung/mockprivate/MockService.java b/testing-modules/mocks-2/src/main/java/com/baeldung/mockprivate/MockService.java new file mode 100644 index 0000000000..ab5624d973 --- /dev/null +++ b/testing-modules/mocks-2/src/main/java/com/baeldung/mockprivate/MockService.java @@ -0,0 +1,10 @@ +package com.baeldung.mockprivate; + +public class MockService { + + private final Person person = new Person("John Doe"); + + public String getName() { + return person.getName(); + } +} diff --git a/testing-modules/mocks-2/src/main/java/com/baeldung/mockprivate/Person.java b/testing-modules/mocks-2/src/main/java/com/baeldung/mockprivate/Person.java new file mode 100644 index 0000000000..405b9d58dd --- /dev/null +++ b/testing-modules/mocks-2/src/main/java/com/baeldung/mockprivate/Person.java @@ -0,0 +1,14 @@ +package com.baeldung.mockprivate; + +public class Person { + + private final String name; + + public Person(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/testing-modules/mocks-2/src/test/java/com/baeldung/mockprivate/MockServiceUnitTest.java b/testing-modules/mocks-2/src/test/java/com/baeldung/mockprivate/MockServiceUnitTest.java new file mode 100644 index 0000000000..64367a2290 --- /dev/null +++ b/testing-modules/mocks-2/src/test/java/com/baeldung/mockprivate/MockServiceUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.mockprivate; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.platform.commons.util.ReflectionUtils; +import org.springframework.test.util.ReflectionTestUtils; + +import java.lang.reflect.Field; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class MockServiceUnitTest { + + private Person mockedPerson; + + @BeforeEach + public void setUp(){ + mockedPerson = mock(Person.class); + } + + @Test + void givenNameChangedWithReflection_whenGetName_thenReturnName() throws Exception { + Class> mockServiceClass = Class.forName("com.baeldung.mockprivate.MockService"); + MockService mockService = (MockService) mockServiceClass.getDeclaredConstructor().newInstance(); + Field field = mockServiceClass.getDeclaredField("person"); + field.setAccessible(true); + field.set(mockService, mockedPerson); + + when(mockedPerson.getName()).thenReturn("Jane Doe"); + + Assertions.assertEquals("Jane Doe", mockService.getName()); + } + + @Test + void givenNameChangedWithReflectionUtils_whenGetName_thenReturnName() throws Exception { + MockService mockService = new MockService(); + Field field = ReflectionUtils + .findFields(MockService.class, f -> f.getName().equals("person"), + ReflectionUtils.HierarchyTraversalMode.TOP_DOWN) + .get(0); + + field.setAccessible(true); + field.set(mockService, mockedPerson); + + when(mockedPerson.getName()).thenReturn("Jane Doe"); + + Assertions.assertEquals("Jane Doe", mockService.getName()); + } + + @Test + void givenNameChangedWithReflectionTestUtils_whenGetName_thenReturnName() throws Exception { + MockService mockService = new MockService(); + + ReflectionTestUtils.setField(mockService, "person", mockedPerson); + + when(mockedPerson.getName()).thenReturn("Jane Doe"); + Assertions.assertEquals("Jane Doe", mockService.getName()); + } + +} \ No newline at end of file diff --git a/testing-modules/mocks/pom.xml b/testing-modules/mocks/pom.xml index e447639288..281fff38c2 100644 --- a/testing-modules/mocks/pom.xml +++ b/testing-modules/mocks/pom.xml @@ -43,6 +43,26 @@ + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar + -Djdk.attach.allowAttachSelf + + true + + **/testsuite/**/*UnitTest.java + + + + + + 0.15 1.5 diff --git a/testing-modules/pom.xml b/testing-modules/pom.xml index a6b5fba570..8040113a03 100644 --- a/testing-modules/pom.xml +++ b/testing-modules/pom.xml @@ -44,6 +44,7 @@ spring-mockito spring-testing-2 spring-testing + testing-assertions test-containers testing-libraries-2 testing-libraries @@ -52,6 +53,7 @@ xmlunit-2 zerocode mockito-2 + testing-techniques gatling-java diff --git a/testing-modules/powermock/pom.xml b/testing-modules/powermock/pom.xml index f3237ed4df..8eedc818af 100644 --- a/testing-modules/powermock/pom.xml +++ b/testing-modules/powermock/pom.xml @@ -26,9 +26,23 @@ + + + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + + + + 2.21.0 - 2.0.7 + 2.0.9 \ No newline at end of file diff --git a/testing-modules/testing-libraries-2/README.md b/testing-modules/testing-libraries-2/README.md index 7cc08a8140..d075c40919 100644 --- a/testing-modules/testing-libraries-2/README.md +++ b/testing-modules/testing-libraries-2/README.md @@ -4,3 +4,4 @@ - [Guide to the System Stubs Library](https://www.baeldung.com/java-system-stubs) - [Code Coverage with SonarQube and JaCoCo](https://www.baeldung.com/sonarqube-jacoco-code-coverage) - [Exclusions from Jacoco Report](https://www.baeldung.com/jacoco-report-exclude) +- [Gray Box Testing Using the OAT Technique](https://www.baeldung.com/java-gray-box-orthogonal-array-testing) diff --git a/testing-modules/testing-libraries-2/pom.xml b/testing-modules/testing-libraries-2/pom.xml index b0680c1e40..6e8ab599b4 100644 --- a/testing-modules/testing-libraries-2/pom.xml +++ b/testing-modules/testing-libraries-2/pom.xml @@ -93,6 +93,16 @@ + + org.apache.maven.plugins + maven-surefire-plugin + + + --add-opens java.base/java.util=ALL-UNNAMED + --add-opens java.base/java.lang=ALL-UNNAMED + + + diff --git a/testing-modules/testing-techniques/pom.xml b/testing-modules/testing-techniques/pom.xml new file mode 100644 index 0000000000..5902047aeb --- /dev/null +++ b/testing-modules/testing-techniques/pom.xml @@ -0,0 +1,14 @@ + + + + testing-techniques + 4.0.0 + + + testing-modules + com.baeldung + 1.0.0-SNAPSHOT + + \ No newline at end of file diff --git a/testing-modules/testing-techniques/src/main/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculator.java b/testing-modules/testing-techniques/src/main/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculator.java new file mode 100644 index 0000000000..d97b6687b3 --- /dev/null +++ b/testing-modules/testing-techniques/src/main/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculator.java @@ -0,0 +1,67 @@ +package com.baeldung.greyboxtesting; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.stream.DoubleStream; + +public class SalaryCommissionPercentageCalculator { + public BigDecimal calculate(Level level, Type type, Seniority seniority, SalesImpact impact) { + return BigDecimal.valueOf(DoubleStream.of(level.getBonus(), type.getBonus(), seniority.getBonus(), impact.getBonus(), type.getBonus()) + .average() + .orElse(0)) + .setScale(2, RoundingMode.CEILING); + } + + public enum Level { + L1(0.06), L2(0.12), L3(0.2); + private double bonus; + + Level(double bonus) { + this.bonus = bonus; + } + + public double getBonus() { + return bonus; + } + } + + public enum Type { + FULL_TIME_COMMISSIONED(0.18), CONTRACTOR(0.1), FREELANCER(0.06); + + private double bonus; + + Type(double bonus) { + this.bonus = bonus; + } + + public double getBonus() { + return bonus; + } + } + + public enum Seniority { + JR(0.8), MID(0.13), SR(0.19); + private double bonus; + + Seniority(double bonus) { + this.bonus = bonus; + } + + public double getBonus() { + return bonus; + } + } + + public enum SalesImpact { + LOW(0.06), MEDIUM(0.12), HIGH(0.2); + private double bonus; + + SalesImpact(double bonus) { + this.bonus = bonus; + } + + public double getBonus() { + return bonus; + } + } +} diff --git a/testing-modules/testing-techniques/src/test/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculatorUnitTest.java b/testing-modules/testing-techniques/src/test/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculatorUnitTest.java new file mode 100644 index 0000000000..e39a1e5445 --- /dev/null +++ b/testing-modules/testing-techniques/src/test/java/com/baeldung/greyboxtesting/SalaryCommissionPercentageCalculatorUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.greyboxtesting; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.math.BigDecimal; +import java.util.stream.Stream; + +import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.*; +import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.Level.*; +import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.SalesImpact.*; +import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.Seniority.*; +import static com.baeldung.greyboxtesting.SalaryCommissionPercentageCalculator.Type.*; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class SalaryCommissionPercentageCalculatorUnitTest { + + private SalaryCommissionPercentageCalculator testTarget = new SalaryCommissionPercentageCalculator(); + + @ParameterizedTest + @MethodSource("provideReferenceTestScenarioTable") + void givenReferenceTable_whenCalculateAverageCommission_thenReturnExpectedResult(Level level, Type type, Seniority seniority, SalesImpact impact, double expected) { + BigDecimal got = testTarget.calculate(level, type, seniority, impact); + assertEquals(BigDecimal.valueOf(expected), got); + } + + private static Stream provideReferenceTestScenarioTable() { + return Stream.of( + Arguments.of(L1, FULL_TIME_COMMISSIONED, JR, LOW, 0.26), + Arguments.of(L1, CONTRACTOR, SR, MEDIUM, 0.12), + Arguments.of(L1, FREELANCER, MID, HIGH, 0.11), + Arguments.of(L2, FULL_TIME_COMMISSIONED, SR, HIGH, 0.18), + Arguments.of(L2, CONTRACTOR, MID, LOW, 0.11), + Arguments.of(L2, FREELANCER, JR, MEDIUM, 0.24), + Arguments.of(L3, FULL_TIME_COMMISSIONED, MID, MEDIUM, 0.17), + Arguments.of(L3, CONTRACTOR, JR, HIGH, 0.28), + Arguments.of(L3, FREELANCER, SR, LOW, 0.12) + ); + } +} \ No newline at end of file diff --git a/testing-modules/testng/pom.xml b/testing-modules/testng/pom.xml index 72c220c118..62e2b2e578 100644 --- a/testing-modules/testng/pom.xml +++ b/testing-modules/testng/pom.xml @@ -79,7 +79,7 @@ - 7.1.0 + 7.8.0 \ No newline at end of file diff --git a/web-modules/play-modules/README.md b/web-modules/play-modules/README.md index a28c3f7ad7..d1ac7eb2d4 100644 --- a/web-modules/play-modules/README.md +++ b/web-modules/play-modules/README.md @@ -4,5 +4,5 @@ This module contains articles about the Play Framework. ### Relevant Articles: - [REST API with Play Framework in Java](https://www.baeldung.com/rest-api-with-play) -- [Routing In Play Applications in Java](https://www.baeldung.com/routing-in-play) -- [Introduction To Play In Java](https://www.baeldung.com/java-intro-to-the-play-framework) +- [Routing in Play Applications in Java](https://www.baeldung.com/routing-in-play) +- [Introduction to Play in Java](https://www.baeldung.com/java-intro-to-the-play-framework) diff --git a/web-modules/pom.xml b/web-modules/pom.xml index 97134ee31c..cdbc2db036 100644 --- a/web-modules/pom.xml +++ b/web-modules/pom.xml @@ -23,10 +23,10 @@ javax-servlets javax-servlets-2 - jee-7 + jooby linkrest - ninja + ratpack @@ -49,4 +49,4 @@ - \ No newline at end of file + diff --git a/web-modules/ratpack/src/main/java/com/baeldung/Application.java b/web-modules/ratpack/src/main/java/com/baeldung/Application.java index 235a6f0068..8035a1d0e3 100644 --- a/web-modules/ratpack/src/main/java/com/baeldung/Application.java +++ b/web-modules/ratpack/src/main/java/com/baeldung/Application.java @@ -8,6 +8,7 @@ import com.baeldung.repository.EmployeeRepository; import com.baeldung.repository.EmployeeRepositoryImpl; import com.zaxxer.hikari.HikariConfig; import io.netty.buffer.PooledByteBufAllocator; +import ratpack.exec.internal.DefaultExecController; import ratpack.func.Action; import ratpack.func.Function; import ratpack.guice.BindingsSpec; @@ -42,7 +43,7 @@ public class Application { .maxContentLength(ServerConfig.DEFAULT_MAX_CONTENT_LENGTH) .responseMaxChunkSize(16384) .readTimeout(Duration.of(60, ChronoUnit.SECONDS)) - .byteBufAllocator(PooledByteBufAllocator.DEFAULT); + .byteBufAllocator(PooledByteBufAllocator.DEFAULT).execController(new DefaultExecController(2)); }); final Function registryFunction = Guice.registry(bindingsSpecAction); diff --git a/xml-2/README.md b/xml-2/README.md index 383d0763d4..e91078dbf0 100644 --- a/xml-2/README.md +++ b/xml-2/README.md @@ -6,3 +6,4 @@ This module contains articles about eXtensible Markup Language (XML) - [Pretty-Print XML in Java](https://www.baeldung.com/java-pretty-print-xml) - [Validate an XML File Against an XSD File](https://www.baeldung.com/java-validate-xml-xsd) +- [Converting JSON to XML in Java](https://www.baeldung.com/java-convert-json-to-xml)