From 009a99e340aff185da8eeeed16533b9114756595 Mon Sep 17 00:00:00 2001 From: macroscopic64 Date: Sun, 3 Feb 2019 00:33:17 +0530 Subject: [PATCH 01/11] example for multi-release jar --- .../com/baeldung/multireleaseapp/App.java | 11 +++++++++ .../baeldung/multireleaseapp/DateHelper.java | 24 +++++++++++++++++++ .../baeldung/multireleaseapp/DateHelper.java | 13 ++++++++++ 3 files changed, 48 insertions(+) create mode 100644 core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java create mode 100644 core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java create mode 100644 core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java diff --git a/core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java b/core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java new file mode 100644 index 0000000000..c2e738384a --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java @@ -0,0 +1,11 @@ +package com.baeldung.multireleaseapp; + +public class App { + + public static void main(String[] args) throws Exception { + String dateToCheck = args[0]; + boolean isLeapYear = DateHelper.checkIfLeapYear(dateToCheck); + System.out.println("Date given " + dateToCheck + " is leap year: " + isLeapYear); + } + +} diff --git a/core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java b/core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java new file mode 100644 index 0000000000..842ac00350 --- /dev/null +++ b/core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java @@ -0,0 +1,24 @@ +package com.baeldung.multireleaseapp; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +public class DateHelper { + + public static boolean checkIfLeapYear(String dateStr) throws Exception { + System.out.println("Checking for leap year using Java 1 calendar API "); + boolean isLeapYear = false; + Calendar cal = Calendar.getInstance(); + cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateStr)); + int year = cal.get(Calendar.YEAR); + if (year % 4 == 0) { + if (year % 100 == 0) { + isLeapYear = (year % 400 == 0) ? true : false; + } else { + isLeapYear = true; + } + } + return isLeapYear; + } + +} diff --git a/core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java b/core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java new file mode 100644 index 0000000000..1d8a10f145 --- /dev/null +++ b/core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java @@ -0,0 +1,13 @@ +package com.baeldung.multireleaseapp; + +import java.time.LocalDate; + +public class DateHelper { + + public static boolean checkIfLeapYear(String dateStr) throws Exception { + System.out.println("Checking for leap year using Java 9 Date Api"); + return LocalDate.parse(dateStr) + .isLeapYear(); + } + +} From 7e843727b971298db82909d142a80bf10c84bb66 Mon Sep 17 00:00:00 2001 From: macroscopic64 Date: Thu, 14 Feb 2019 08:36:11 +0530 Subject: [PATCH 02/11] simplified the leap year check logic --- .../java/com/baeldung/multireleaseapp/App.java | 7 ++++++- .../baeldung/multireleaseapp/DateHelper.java | 18 ++++++++---------- .../baeldung/multireleaseapp/DateHelper.java | 7 ++++++- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java b/core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java index c2e738384a..21bbcc01d4 100644 --- a/core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java +++ b/core-java-9/src/main/java/com/baeldung/multireleaseapp/App.java @@ -1,11 +1,16 @@ package com.baeldung.multireleaseapp; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class App { + private static final Logger logger = LoggerFactory.getLogger(App.class); + public static void main(String[] args) throws Exception { String dateToCheck = args[0]; boolean isLeapYear = DateHelper.checkIfLeapYear(dateToCheck); - System.out.println("Date given " + dateToCheck + " is leap year: " + isLeapYear); + logger.info("Date given " + dateToCheck + " is leap year: " + isLeapYear); } } diff --git a/core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java b/core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java index 842ac00350..4d943db30b 100644 --- a/core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java +++ b/core-java-9/src/main/java/com/baeldung/multireleaseapp/DateHelper.java @@ -2,23 +2,21 @@ package com.baeldung.multireleaseapp; import java.text.SimpleDateFormat; import java.util.Calendar; +import java.util.GregorianCalendar; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DateHelper { + private static final Logger logger = LoggerFactory.getLogger(DateHelper.class); + public static boolean checkIfLeapYear(String dateStr) throws Exception { - System.out.println("Checking for leap year using Java 1 calendar API "); - boolean isLeapYear = false; + logger.info("Checking for leap year using Java 1 calendar API"); Calendar cal = Calendar.getInstance(); cal.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(dateStr)); int year = cal.get(Calendar.YEAR); - if (year % 4 == 0) { - if (year % 100 == 0) { - isLeapYear = (year % 400 == 0) ? true : false; - } else { - isLeapYear = true; - } - } - return isLeapYear; + return (new GregorianCalendar()).isLeapYear(year); } } diff --git a/core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java b/core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java index 1d8a10f145..35fb0ada1e 100644 --- a/core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java +++ b/core-java-9/src/main/java9/com/baeldung/multireleaseapp/DateHelper.java @@ -2,10 +2,15 @@ package com.baeldung.multireleaseapp; import java.time.LocalDate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class DateHelper { + private static final Logger logger = LoggerFactory.getLogger(DateHelper.class); + public static boolean checkIfLeapYear(String dateStr) throws Exception { - System.out.println("Checking for leap year using Java 9 Date Api"); + logger.info("Checking for leap year using Java 9 Date Api"); return LocalDate.parse(dateStr) .isLeapYear(); } From 79becf29d5a37f79b2d50b061bec34dfeefc642d Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sun, 17 Feb 2019 16:32:35 +0530 Subject: [PATCH 03/11] [BAEL-12667] - Fixed the relative paths of parent --- spring-boot-crud/pom.xml | 21 ++++++++++--------- .../disabling-console-jul/pom.xml | 9 ++++---- .../disabling-console-log4j2/pom.xml | 9 ++++---- spring-boot-logging-log4j2/pom.xml | 7 ++++--- spring-soap/pom.xml | 8 ++++--- 5 files changed, 30 insertions(+), 24 deletions(-) diff --git a/spring-boot-crud/pom.xml b/spring-boot-crud/pom.xml index 749bf9cb5a..73635b0a1c 100644 --- a/spring-boot-crud/pom.xml +++ b/spring-boot-crud/pom.xml @@ -3,15 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 - com.baeldung.spring-boot-crud spring-boot-crud - 0.1.0 spring-boot-crud - org.springframework.boot - spring-boot-starter-parent - 2.0.6.RELEASE + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 @@ -41,11 +40,7 @@ h2 runtime - - - UTF-8 - 1.8 - + spring-boot-crud @@ -62,4 +57,10 @@ + + + UTF-8 + 1.8 + + \ No newline at end of file diff --git a/spring-boot-disable-console-logging/disabling-console-jul/pom.xml b/spring-boot-disable-console-logging/disabling-console-jul/pom.xml index 9ccbd56231..b95f610028 100644 --- a/spring-boot-disable-console-logging/disabling-console-jul/pom.xml +++ b/spring-boot-disable-console-logging/disabling-console-jul/pom.xml @@ -6,10 +6,11 @@ - org.springframework.boot - spring-boot-starter-parent - 2.1.1.RELEASE - + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-2 + diff --git a/spring-boot-disable-console-logging/disabling-console-log4j2/pom.xml b/spring-boot-disable-console-logging/disabling-console-log4j2/pom.xml index 0b360bb366..7db6c4ac1e 100644 --- a/spring-boot-disable-console-logging/disabling-console-log4j2/pom.xml +++ b/spring-boot-disable-console-logging/disabling-console-log4j2/pom.xml @@ -6,10 +6,11 @@ - org.springframework.boot - spring-boot-starter-parent - 2.1.1.RELEASE - + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-2 + diff --git a/spring-boot-logging-log4j2/pom.xml b/spring-boot-logging-log4j2/pom.xml index 6cc60da52c..b740585574 100644 --- a/spring-boot-logging-log4j2/pom.xml +++ b/spring-boot-logging-log4j2/pom.xml @@ -10,9 +10,10 @@ - spring-boot-starter-parent - org.springframework.boot - 2.0.5.RELEASE + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 diff --git a/spring-soap/pom.xml b/spring-soap/pom.xml index 2865a4c3bc..f5c3a1434d 100644 --- a/spring-soap/pom.xml +++ b/spring-soap/pom.xml @@ -8,13 +8,15 @@ 1.0.0 - org.springframework.boot - spring-boot-starter-parent - 2.1.2.RELEASE + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 1.8 + 2.1.2.RELEASE From 69ae99666ae1d2b8e1bab723c71a680d07e0fac4 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sun, 17 Feb 2019 23:58:47 +0530 Subject: [PATCH 04/11] Reverted spring-boot-logging modules parents --- .../disabling-console-jul/pom.xml | 7 +++---- .../disabling-console-log4j2/pom.xml | 7 +++---- spring-boot-logging-log4j2/pom.xml | 7 +++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/spring-boot-disable-console-logging/disabling-console-jul/pom.xml b/spring-boot-disable-console-logging/disabling-console-jul/pom.xml index b95f610028..f6f7890df1 100644 --- a/spring-boot-disable-console-logging/disabling-console-jul/pom.xml +++ b/spring-boot-disable-console-logging/disabling-console-jul/pom.xml @@ -6,10 +6,9 @@ - parent-boot-2 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-2 + org.springframework.boot + spring-boot-starter-parent + 2.1.1.RELEASE diff --git a/spring-boot-disable-console-logging/disabling-console-log4j2/pom.xml b/spring-boot-disable-console-logging/disabling-console-log4j2/pom.xml index 7db6c4ac1e..1cf3eb3e68 100644 --- a/spring-boot-disable-console-logging/disabling-console-log4j2/pom.xml +++ b/spring-boot-disable-console-logging/disabling-console-log4j2/pom.xml @@ -6,10 +6,9 @@ - parent-boot-2 - com.baeldung - 0.0.1-SNAPSHOT - ../../parent-boot-2 + org.springframework.boot + spring-boot-starter-parent + 2.1.1.RELEASE diff --git a/spring-boot-logging-log4j2/pom.xml b/spring-boot-logging-log4j2/pom.xml index b740585574..6cc60da52c 100644 --- a/spring-boot-logging-log4j2/pom.xml +++ b/spring-boot-logging-log4j2/pom.xml @@ -10,10 +10,9 @@ - parent-boot-2 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-2 + spring-boot-starter-parent + org.springframework.boot + 2.0.5.RELEASE From 91028e62b2bf63afbe15609cff89eaed7015cf2d Mon Sep 17 00:00:00 2001 From: Muhammad Asif Anwar Date: Sun, 17 Feb 2019 23:01:46 +0400 Subject: [PATCH 05/11] for Jenkins --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1c016a2ea9..b4bab0a389 100644 --- a/pom.xml +++ b/pom.xml @@ -1594,7 +1594,7 @@ UTF-8 UTF-8 - refs/heads/master + refs/remotes/origin/master true false false From cc1183cd8336baa28c67019bbdb4f30b4ecc162e Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sun, 17 Feb 2019 13:02:41 +0530 Subject: [PATCH 06/11] [BAEL-12668] - Make sure the tutorials build doesn't generate any un-committed or un-ignored artifacts --- .gitignore | 7 +++++++ .../java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java | 7 ++++--- core-java-io/src/test/resources/exampleOutput.csv | 2 -- persistence-modules/hibernate5/transaction.log | 0 4 files changed, 11 insertions(+), 5 deletions(-) delete mode 100644 core-java-io/src/test/resources/exampleOutput.csv delete mode 100644 persistence-modules/hibernate5/transaction.log diff --git a/.gitignore b/.gitignore index 0e71421ee7..21586748b7 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,10 @@ jmeter/src/main/resources/*-JMeter.csv **/nb-configuration.xml core-scala/.cache-main core-scala/.cache-tests + + +persistence-modules/hibernate5/transaction.log +apache-avro/src/main/java/com/baeldung/avro/model/ +jta/transaction-logs/ +software-security/sql-injection-samples/derby.log +spring-soap/src/main/java/com/baeldung/springsoap/gen/ \ No newline at end of file diff --git a/core-java-io/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java b/core-java-io/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java index 0658ec6101..5f4827bc21 100644 --- a/core-java-io/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java +++ b/core-java-io/src/test/java/com/baeldung/csv/WriteCsvFileExampleUnitTest.java @@ -5,6 +5,7 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileNotFoundException; +import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -17,7 +18,6 @@ import org.slf4j.LoggerFactory; public class WriteCsvFileExampleUnitTest { private static final Logger LOG = LoggerFactory.getLogger(WriteCsvFileExampleUnitTest.class); - private static final String CSV_FILE_NAME = "src/test/resources/exampleOutput.csv"; private WriteCsvFileExample csvExample; @Before @@ -65,12 +65,12 @@ public class WriteCsvFileExampleUnitTest { } @Test - public void givenDataArray_whenConvertToCSV_thenOutputCreated() { + public void givenDataArray_whenConvertToCSV_thenOutputCreated() throws IOException { List dataLines = new ArrayList(); dataLines.add(new String[] { "John", "Doe", "38", "Comment Data\nAnother line of comment data" }); dataLines.add(new String[] { "Jane", "Doe, Jr.", "19", "She said \"I'm being quoted\"" }); - File csvOutputFile = new File(CSV_FILE_NAME); + File csvOutputFile = File.createTempFile("exampleOutput", ".csv"); try (PrintWriter pw = new PrintWriter(csvOutputFile)) { dataLines.stream() .map(csvExample::convertToCSV) @@ -80,5 +80,6 @@ public class WriteCsvFileExampleUnitTest { } assertTrue(csvOutputFile.exists()); + csvOutputFile.deleteOnExit(); } } diff --git a/core-java-io/src/test/resources/exampleOutput.csv b/core-java-io/src/test/resources/exampleOutput.csv deleted file mode 100644 index 45c37f3a3b..0000000000 --- a/core-java-io/src/test/resources/exampleOutput.csv +++ /dev/null @@ -1,2 +0,0 @@ -John,Doe,38,Comment Data Another line of comment data -Jane,"Doe, Jr.",19,"She said ""I'm being quoted""" \ No newline at end of file diff --git a/persistence-modules/hibernate5/transaction.log b/persistence-modules/hibernate5/transaction.log deleted file mode 100644 index e69de29bb2..0000000000 From 6c237aaf3a009fc178aafb88967e2749bd2017b9 Mon Sep 17 00:00:00 2001 From: psevestre Date: Mon, 18 Feb 2019 02:39:25 -0300 Subject: [PATCH 07/11] [BAEL-1381] Add JPA Examples (#6369) * BAEL-1381 * [BAEL-1381] * [BAEL-1381] New module name * [BAEL-1381] software-security module * [BAEL-1381] Add JPA examples --- .../CustomBaeldungQueueUnitTest.java | 0 .../PriorityQueueUnitTest.java | 0 .../sql-injection-samples/pom.xml | 15 +- .../examples/security/sql/Account.java | 34 ++++ .../examples/security/sql/AccountDAO.java | 171 +++++++++++++++--- .../src/main/resources/application.properties | 1 + .../resources/db/changelog/create-tables.xml | 19 -- .../main/resources/db/master-changelog.xml | 8 - ...qlInjectionSamplesApplicationUnitTest.java | 34 +++- .../src/test/resources/application-test.yml | 14 +- .../src/test/resources/schema.sql | 1 + 11 files changed, 246 insertions(+), 51 deletions(-) rename core-java-collections/src/test/java/com/baeldung/{queueinterface => queueInterface}/CustomBaeldungQueueUnitTest.java (100%) rename core-java-collections/src/test/java/com/baeldung/{queueinterface => queueInterface}/PriorityQueueUnitTest.java (100%) create mode 100644 software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/Account.java delete mode 100644 software-security/sql-injection-samples/src/main/resources/db/changelog/create-tables.xml delete mode 100644 software-security/sql-injection-samples/src/main/resources/db/master-changelog.xml diff --git a/core-java-collections/src/test/java/com/baeldung/queueinterface/CustomBaeldungQueueUnitTest.java b/core-java-collections/src/test/java/com/baeldung/queueInterface/CustomBaeldungQueueUnitTest.java similarity index 100% rename from core-java-collections/src/test/java/com/baeldung/queueinterface/CustomBaeldungQueueUnitTest.java rename to core-java-collections/src/test/java/com/baeldung/queueInterface/CustomBaeldungQueueUnitTest.java diff --git a/core-java-collections/src/test/java/com/baeldung/queueinterface/PriorityQueueUnitTest.java b/core-java-collections/src/test/java/com/baeldung/queueInterface/PriorityQueueUnitTest.java similarity index 100% rename from core-java-collections/src/test/java/com/baeldung/queueinterface/PriorityQueueUnitTest.java rename to core-java-collections/src/test/java/com/baeldung/queueInterface/PriorityQueueUnitTest.java diff --git a/software-security/sql-injection-samples/pom.xml b/software-security/sql-injection-samples/pom.xml index e1590662b7..5b33c674d4 100644 --- a/software-security/sql-injection-samples/pom.xml +++ b/software-security/sql-injection-samples/pom.xml @@ -16,6 +16,8 @@ + + org.springframework.boot spring-boot-starter-jdbc @@ -42,6 +44,17 @@ provided + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.hibernate + hibernate-jpamodelgen + + + @@ -57,4 +70,4 @@ 1.8 - + \ No newline at end of file diff --git a/software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/Account.java b/software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/Account.java new file mode 100644 index 0000000000..3f077d5592 --- /dev/null +++ b/software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/Account.java @@ -0,0 +1,34 @@ +/** + * + */ +package com.baeldung.examples.security.sql; + +import java.math.BigDecimal; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import lombok.Data; + +/** + * @author Philippe + * + */ +@Entity +@Table(name="Accounts") +@Data +public class Account { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + private Long id; + + private String customerId; + private String accNumber; + private String branchId; + private BigDecimal balance; + +} diff --git a/software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java b/software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java index 447dcc456d..c7285e5fd3 100644 --- a/software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java +++ b/software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java @@ -7,14 +7,24 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Order; +import javax.persistence.criteria.Root; +import javax.persistence.metamodel.SingularAttribute; import javax.sql.DataSource; import org.springframework.stereotype.Component; @@ -27,9 +37,11 @@ import org.springframework.stereotype.Component; public class AccountDAO { private final DataSource dataSource; + private final EntityManager em; - public AccountDAO(DataSource dataSource) { + public AccountDAO(DataSource dataSource, EntityManager em) { this.dataSource = dataSource; + this.em = em; } /** @@ -63,6 +75,26 @@ public class AccountDAO { } } + /** + * Return all accounts owned by a given customer,given his/her external id - JPA version + * + * @param customerId + * @return + */ + public List unsafeJpaFindAccountsByCustomerId(String customerId) { + String jql = "from Account where customerId = '" + customerId + "'"; + TypedQuery q = em.createQuery(jql, Account.class); + return q.getResultList() + .stream() + .map(a -> AccountDTO.builder() + .accNumber(a.getAccNumber()) + .balance(a.getBalance()) + .branchId(a.getAccNumber()) + .customerId(a.getCustomerId()) + .build()) + .collect(Collectors.toList()); + } + /** * Return all accounts owned by a given customer,given his/her external id * @@ -71,7 +103,7 @@ public class AccountDAO { */ public List safeFindAccountsByCustomerId(String customerId) { - String sql = "select " + "customer_id,acc_number,branch_id,balance from Accounts where customer_id = ?"; + String sql = "select customer_id, branch_id,acc_number,balance from Accounts where customer_id = ?"; try (Connection c = dataSource.getConnection(); PreparedStatement p = c.prepareStatement(sql)) { p.setString(1, customerId); @@ -93,23 +125,73 @@ public class AccountDAO { } } + /** + * Return all accounts owned by a given customer,given his/her external id - JPA version + * + * @param customerId + * @return + */ + public List safeJpaFindAccountsByCustomerId(String customerId) { + + String jql = "from Account where customerId = :customerId"; + TypedQuery q = em.createQuery(jql, Account.class) + .setParameter("customerId", customerId); + + return q.getResultList() + .stream() + .map(a -> AccountDTO.builder() + .accNumber(a.getAccNumber()) + .balance(a.getBalance()) + .branchId(a.getAccNumber()) + .customerId(a.getCustomerId()) + .build()) + .collect(Collectors.toList()); + } + + /** + * Return all accounts owned by a given customer,given his/her external id - JPA version + * + * @param customerId + * @return + */ + public List safeJpaCriteriaFindAccountsByCustomerId(String customerId) { + + CriteriaBuilder cb = em.getCriteriaBuilder(); + CriteriaQuery cq = cb.createQuery(Account.class); + Root root = cq.from(Account.class); + cq.select(root) + .where(cb.equal(root.get(Account_.customerId), customerId)); + + TypedQuery q = em.createQuery(cq); + + return q.getResultList() + .stream() + .map(a -> AccountDTO.builder() + .accNumber(a.getAccNumber()) + .balance(a.getBalance()) + .branchId(a.getAccNumber()) + .customerId(a.getCustomerId()) + .build()) + .collect(Collectors.toList()); + } + private static final Set VALID_COLUMNS_FOR_ORDER_BY = Stream.of("acc_number", "branch_id", "balance") .collect(Collectors.toCollection(HashSet::new)); + /** * Return all accounts owned by a given customer,given his/her external id * * @param customerId * @return */ - public List safeFindAccountsByCustomerId(String customerId, String orderBy) { + public List safeFindAccountsByCustomerId(String customerId, String orderBy) { String sql = "select " + "customer_id,acc_number,branch_id,balance from Accounts where customer_id = ? "; if (VALID_COLUMNS_FOR_ORDER_BY.contains(orderBy)) { sql = sql + " order by " + orderBy; - } - else { + } else { throw new IllegalArgumentException("Nice try!"); } @@ -135,35 +217,82 @@ public class AccountDAO { } } + + private static final Map> VALID_JPA_COLUMNS_FOR_ORDER_BY = Stream.of( + new AbstractMap.SimpleEntry<>(Account_.ACC_NUMBER, Account_.accNumber), + new AbstractMap.SimpleEntry<>(Account_.BRANCH_ID, Account_.branchId), + new AbstractMap.SimpleEntry<>(Account_.BALANCE, Account_.balance) + ) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + /** + * Return all accounts owned by a given customer,given his/her external id + * + * @param customerId + * @return + */ + public List safeJpaFindAccountsByCustomerId(String customerId, String orderBy) { + +SingularAttribute orderByAttribute = VALID_JPA_COLUMNS_FOR_ORDER_BY.get(orderBy); +if ( orderByAttribute == null) { + throw new IllegalArgumentException("Nice try!"); +} + +CriteriaBuilder cb = em.getCriteriaBuilder(); +CriteriaQuery cq = cb.createQuery(Account.class); +Root root = cq.from(Account.class); +cq.select(root) + .where(cb.equal(root.get(Account_.customerId), customerId)) + .orderBy(cb.asc(root.get(orderByAttribute))); + +TypedQuery q = em.createQuery(cq); + + return q.getResultList() + .stream() + .map(a -> AccountDTO.builder() + .accNumber(a.getAccNumber()) + .balance(a.getBalance()) + .branchId(a.getAccNumber()) + .customerId(a.getCustomerId()) + .build()) + .collect(Collectors.toList()); + + } + /** * Invalid placeholder usage example * * @param tableName * @return */ - public List wrongCountRecordsByTableName(String tableName) { + public Long wrongCountRecordsByTableName(String tableName) { + + try (Connection c = dataSource.getConnection(); PreparedStatement p = c.prepareStatement("select count(*) from ?")) { - try (Connection c = dataSource.getConnection(); - PreparedStatement p = c.prepareStatement("select count(*) from ?")) { - p.setString(1, tableName); ResultSet rs = p.executeQuery(); - List accounts = new ArrayList<>(); - while (rs.next()) { - AccountDTO acc = AccountDTO.builder() - .customerId(rs.getString("customerId")) - .branchId(rs.getString("branch_id")) - .accNumber(rs.getString("acc_number")) - .balance(rs.getBigDecimal("balance")) - .build(); + rs.next(); + return rs.getLong(1); - accounts.add(acc); - } - - return accounts; } catch (SQLException ex) { throw new RuntimeException(ex); } } + /** + * Invalid placeholder usage example - JPA + * + * @param tableName + * @return + */ + public Long wrongJpaCountRecordsByTableName(String tableName) { + + String jql = "select count(*) from :tableName"; + TypedQuery q = em.createQuery(jql, Long.class) + .setParameter("tableName", tableName); + + return q.getSingleResult(); + + } + } diff --git a/software-security/sql-injection-samples/src/main/resources/application.properties b/software-security/sql-injection-samples/src/main/resources/application.properties index e69de29bb2..8b13789179 100644 --- a/software-security/sql-injection-samples/src/main/resources/application.properties +++ b/software-security/sql-injection-samples/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/software-security/sql-injection-samples/src/main/resources/db/changelog/create-tables.xml b/software-security/sql-injection-samples/src/main/resources/db/changelog/create-tables.xml deleted file mode 100644 index a405c02049..0000000000 --- a/software-security/sql-injection-samples/src/main/resources/db/changelog/create-tables.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/software-security/sql-injection-samples/src/main/resources/db/master-changelog.xml b/software-security/sql-injection-samples/src/main/resources/db/master-changelog.xml deleted file mode 100644 index 047ca2b314..0000000000 --- a/software-security/sql-injection-samples/src/main/resources/db/master-changelog.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/software-security/sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java b/software-security/sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java index 1f37ba04b6..f61b738abc 100644 --- a/software-security/sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java +++ b/software-security/sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java @@ -40,6 +40,15 @@ public class SqlInjectionSamplesApplicationUnitTest { assertThat(accounts).hasSize(3); } + @Test + public void givenAVulnerableJpaMethod_whenHackedCustomerId_thenReturnAllAccounts() { + + List accounts = target.unsafeJpaFindAccountsByCustomerId("C1' or '1'='1"); + assertThat(accounts).isNotNull(); + assertThat(accounts).isNotEmpty(); + assertThat(accounts).hasSize(3); + } + @Test public void givenASafeMethod_whenHackedCustomerId_thenReturnNoAccounts() { @@ -48,13 +57,36 @@ public class SqlInjectionSamplesApplicationUnitTest { assertThat(accounts).isEmpty(); } + @Test + public void givenASafeJpaMethod_whenHackedCustomerId_thenReturnNoAccounts() { + + List accounts = target.safeJpaFindAccountsByCustomerId("C1' or '1'='1"); + assertThat(accounts).isNotNull(); + assertThat(accounts).isEmpty(); + } + + + @Test + public void givenASafeJpaCriteriaMethod_whenHackedCustomerId_thenReturnNoAccounts() { + + List accounts = target.safeJpaCriteriaFindAccountsByCustomerId("C1' or '1'='1"); + assertThat(accounts).isNotNull(); + assertThat(accounts).isEmpty(); + } + @Test(expected = IllegalArgumentException.class) public void givenASafeMethod_whenInvalidOrderBy_thenThroweException() { target.safeFindAccountsByCustomerId("C1", "INVALID"); } - @Test(expected = RuntimeException.class) + @Test(expected = Exception.class) public void givenWrongPlaceholderUsageMethod_whenNormalCall_thenThrowsException() { target.wrongCountRecordsByTableName("Accounts"); } + + @Test(expected = Exception.class) + public void givenWrongJpaPlaceholderUsageMethod_whenNormalCall_thenThrowsException() { + target.wrongJpaCountRecordsByTableName("Accounts"); + } + } diff --git a/software-security/sql-injection-samples/src/test/resources/application-test.yml b/software-security/sql-injection-samples/src/test/resources/application-test.yml index d07ee10aee..3af3f58bff 100644 --- a/software-security/sql-injection-samples/src/test/resources/application-test.yml +++ b/software-security/sql-injection-samples/src/test/resources/application-test.yml @@ -2,5 +2,17 @@ # Test profile configuration # spring: + liquibase: + change-log: db/changelog/db.changelog-master.xml + + jpa: + hibernate: + ddl-auto: none + datasource: - initialization-mode: always + initialization-mode: embedded + +logging: + level: + sql: DEBUG + \ No newline at end of file diff --git a/software-security/sql-injection-samples/src/test/resources/schema.sql b/software-security/sql-injection-samples/src/test/resources/schema.sql index bfb0ae8059..cfc4c44f98 100644 --- a/software-security/sql-injection-samples/src/test/resources/schema.sql +++ b/software-security/sql-injection-samples/src/test/resources/schema.sql @@ -1,4 +1,5 @@ create table Accounts ( + id BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), customer_id varchar(16) not null, acc_number varchar(16) not null, branch_id decimal(8,0), From 96fbef6a14a945d23cb026bca75e219409c01530 Mon Sep 17 00:00:00 2001 From: anuraggoyal1 Date: Mon, 18 Feb 2019 21:14:38 +0530 Subject: [PATCH 08/11] changes as per review (#6341) * [BAEL-2471] Guide to Apache Commons MultiValuedMap * Update MultiValuedMapUnitTest.java * added empty lines * updated as per review comments * changes as per review --- .../baeldung/java/map/MultiValuedMapUnitTest.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/java-collections-maps/src/test/java/com/baeldung/java/map/MultiValuedMapUnitTest.java b/java-collections-maps/src/test/java/com/baeldung/java/map/MultiValuedMapUnitTest.java index b02b67f685..b3aaf8925f 100644 --- a/java-collections-maps/src/test/java/com/baeldung/java/map/MultiValuedMapUnitTest.java +++ b/java-collections-maps/src/test/java/com/baeldung/java/map/MultiValuedMapUnitTest.java @@ -9,8 +9,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import org.apache.commons.collections4.MultiMapUtils; +import org.apache.commons.collections4.MultiSet; import org.apache.commons.collections4.MultiValuedMap; import org.apache.commons.collections4.multimap.ArrayListValuedHashMap; import org.apache.commons.collections4.multimap.HashSetValuedHashMap; @@ -65,25 +67,28 @@ public class MultiValuedMapUnitTest { @Test public void givenMultiValuesMap_whenUsingKeysMethod_thenReturningAllKeys() { MultiValuedMap map = new ArrayListValuedHashMap<>(); - map.put("fruits", "apple"); map.put("fruits", "orange"); map.put("vehicles", "car"); map.put("vehicles", "bike"); - assertThat(((Collection) map.keys())).contains("fruits", "vehicles"); + MultiSet keys = map.keys(); + + assertThat((keys)).contains("fruits", "vehicles"); + } @Test public void givenMultiValuesMap_whenUsingKeySetMethod_thenReturningAllKeys() { MultiValuedMap map = new ArrayListValuedHashMap<>(); - map.put("fruits", "apple"); map.put("fruits", "orange"); map.put("vehicles", "car"); map.put("vehicles", "bike"); - assertThat((Collection) map.keySet()).contains("fruits", "vehicles"); + Set keys = map.keySet(); + + assertThat(keys).contains("fruits", "vehicles"); } From 243c671edbfc64c001ca3c25b9da6a9fddd85a0c Mon Sep 17 00:00:00 2001 From: FrancoCorleone Date: Mon, 18 Feb 2019 17:48:46 +0100 Subject: [PATCH 09/11] [BAEL-2566] Add example of Insert with Modifying Native Query (#6164) * [BAEL-2566] Add example of Insert with Modifying Native Query * [BAEL-2557] Fix MR conflicts * [BAEL-2557] Cleanup tests --- .../dao/repositories/user/UserRepository.java | 6 +++- .../repositories/UserRepositoryCommon.java | 30 +++++++++++++------ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java index 7d6b076517..fc6e72460a 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/dao/repositories/user/UserRepository.java @@ -67,10 +67,14 @@ public interface UserRepository extends JpaRepository , UserRepos @Query(value = "UPDATE Users u SET u.status = ? WHERE u.name = ?", nativeQuery = true) int updateUserSetStatusForNameNative(Integer status, String name); + @Query(value = "INSERT INTO Users (name, age, email, status) VALUES (:name, :age, :email, :status)", nativeQuery = true) + @Modifying + void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("status") Integer status, @Param("email") String email); + @Modifying @Query(value = "UPDATE Users u SET status = ? WHERE u.name = ?", nativeQuery = true) int updateUserSetStatusForNameNativePostgres(Integer status, String name); @Query(value = "SELECT u FROM User u WHERE u.name IN :names") - List findUserByNameList(@Param("names") Collection names); + List findUserByNameList(@Param("names") Collection names); } diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryCommon.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryCommon.java index 55a453e48f..03cb20a858 100644 --- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryCommon.java +++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/dao/repositories/UserRepositoryCommon.java @@ -12,11 +12,7 @@ import org.springframework.data.jpa.domain.JpaSort; import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.transaction.annotation.Transactional; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -29,10 +25,10 @@ class UserRepositoryCommon { final String USER_EMAIL4 = "email4@example.com"; final Integer INACTIVE_STATUS = 0; final Integer ACTIVE_STATUS = 1; - private final String USER_EMAIL5 = "email5@example.com"; - private final String USER_EMAIL6 = "email6@example.com"; - private final String USER_NAME_ADAM = "Adam"; - private final String USER_NAME_PETER = "Peter"; + final String USER_EMAIL5 = "email5@example.com"; + final String USER_EMAIL6 = "email6@example.com"; + final String USER_NAME_ADAM = "Adam"; + final String USER_NAME_PETER = "Peter"; @Autowired protected UserRepository userRepository; @@ -384,6 +380,22 @@ class UserRepositoryCommon { assertThat(usersWithNames.size()).isEqualTo(2); } + + + @Test + @Transactional + public void whenInsertedWithQuery_ThenUserIsPersisted() { + userRepository.insertUser(USER_NAME_ADAM, 1, ACTIVE_STATUS, USER_EMAIL); + userRepository.insertUser(USER_NAME_PETER, 1, ACTIVE_STATUS, USER_EMAIL2); + + User userAdam = userRepository.findUserByNameLike(USER_NAME_ADAM); + User userPeter = userRepository.findUserByNameLike(USER_NAME_PETER); + + assertThat(userAdam).isNotNull(); + assertThat(userAdam.getEmail()).isEqualTo(USER_EMAIL); + assertThat(userPeter).isNotNull(); + assertThat(userPeter.getEmail()).isEqualTo(USER_EMAIL2); + } @After public void cleanUp() { From fe289003faf09e7468882a5a11aed33d694c5cac Mon Sep 17 00:00:00 2001 From: Urvy Agrawal Date: Mon, 18 Feb 2019 23:00:58 +0530 Subject: [PATCH 10/11] Added files for BAEL-2494 (#6370) --- .../com/baeldung/jackson/dtos/Address.java | 40 ++++++++++++ .../com/baeldung/jackson/dtos/Person.java | 51 +++++++++++++++ .../xml/XMLSerializeDeserializeUnitTest.java | 64 +++++++++++++++++-- .../src/test/resources/PersonGenerated.xml | 18 ++++++ jackson/src/test/resources/person.xml | 19 ++++++ 5 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 jackson/src/test/java/com/baeldung/jackson/dtos/Address.java create mode 100644 jackson/src/test/java/com/baeldung/jackson/dtos/Person.java create mode 100644 jackson/src/test/resources/PersonGenerated.xml create mode 100644 jackson/src/test/resources/person.xml diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/Address.java b/jackson/src/test/java/com/baeldung/jackson/dtos/Address.java new file mode 100644 index 0000000000..19e7d4c53c --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/dtos/Address.java @@ -0,0 +1,40 @@ +package com.baeldung.jackson.dtos; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; + +public class Address { + + @JacksonXmlProperty(localName = "street_number") + String streetNumber; + + @JacksonXmlProperty(localName = "street_name") + String streetName; + + @JacksonXmlProperty(localName = "city") + String city; + + public String getStreetNumber() { + return streetNumber; + } + + public void setStreetNumber(String streetNumber) { + this.streetNumber = streetNumber; + } + + public String getStreetName() { + return streetName; + } + + public void setStreetName(String streetName) { + this.streetName = streetName; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + +} diff --git a/jackson/src/test/java/com/baeldung/jackson/dtos/Person.java b/jackson/src/test/java/com/baeldung/jackson/dtos/Person.java new file mode 100644 index 0000000000..7891595cc6 --- /dev/null +++ b/jackson/src/test/java/com/baeldung/jackson/dtos/Person.java @@ -0,0 +1,51 @@ +package com.baeldung.jackson.dtos; + +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; + +@JacksonXmlRootElement(localName = "person") +public final class Person { + private String firstName; + private String lastName; + @JacksonXmlElementWrapper(useWrapping = false) + private List phoneNumbers = new ArrayList<>(); + @JacksonXmlElementWrapper(localName = "addresses") + private List
address = new ArrayList<>(); + + public List
getAddress() { + return address; + } + + public void setAddress(List
address) { + this.address = address; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + public List getPhoneNumbers() { + return phoneNumbers; + } + + public void setPhoneNumbers(List phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + + + +} \ No newline at end of file diff --git a/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java index 0e2a52e75c..039edd45bc 100644 --- a/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java +++ b/jackson/src/test/java/com/baeldung/jackson/xml/XMLSerializeDeserializeUnitTest.java @@ -9,12 +9,16 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; import org.junit.Test; +import com.baeldung.jackson.dtos.Address; +import com.baeldung.jackson.dtos.Person; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.dataformat.xml.XmlMapper; -import com.fasterxml.jackson.annotation.JsonProperty; public class XMLSerializeDeserializeUnitTest { @@ -49,7 +53,7 @@ public class XMLSerializeDeserializeUnitTest { assertTrue(value.getX() == 1 && value.getY() == 2); } - @Test + @Test public void whenJavaGotFromXmlStrWithCapitalElem_thenCorrect() throws IOException { XmlMapper xmlMapper = new XmlMapper(); SimpleBeanForCapitalizedFields value = xmlMapper. @@ -67,6 +71,54 @@ public class XMLSerializeDeserializeUnitTest { assertNotNull(file); } + @Test + public void whenJavaDeserializedFromXmlFile_thenCorrect() throws IOException { + XmlMapper xmlMapper = new XmlMapper(); + Person value = xmlMapper.readValue(new File("src/test/resources/person.xml"), Person.class); + + assertTrue(value.getAddress() + .get(0) + .getCity() + .equalsIgnoreCase("city1") + && value.getAddress() + .get(1) + .getCity() + .equalsIgnoreCase("city2")); + } + + @Test + public void whenJavaSerializedToXmlFile_thenSuccess() throws IOException { + XmlMapper xmlMapper = new XmlMapper(); + + Person person = new Person(); + + person.setFirstName("Rohan"); + person.setLastName("Daye"); + + List ph = new ArrayList<>(); + ph.add("9911778981"); + ph.add("9991111111"); + person.setPhoneNumbers(ph); + + List
addresses = new ArrayList<>(); + + Address address1 = new Address(); + address1.setStreetNumber("1"); + address1.setStreetName("streetname1"); + address1.setCity("city1"); + + Address address2 = new Address(); + address2.setStreetNumber("2"); + address2.setStreetName("streetname2"); + address2.setCity("city2"); + + addresses.add(address1); + addresses.add(address2); + person.setAddress(addresses); + + xmlMapper.writeValue(new File("src/test/resources/PersonGenerated.xml"), person); + } + private static String inputStreamToString(InputStream is) throws IOException { BufferedReader br; StringBuilder sb = new StringBuilder(); @@ -103,10 +155,10 @@ class SimpleBean { } -class SimpleBeanForCapitalizedFields { - @JsonProperty("X") - private int x = 1; - private int y = 2; +class SimpleBeanForCapitalizedFields { + @JsonProperty("X") + private int x = 1; + private int y = 2; public int getX() { return x; diff --git a/jackson/src/test/resources/PersonGenerated.xml b/jackson/src/test/resources/PersonGenerated.xml new file mode 100644 index 0000000000..6ebadd971a --- /dev/null +++ b/jackson/src/test/resources/PersonGenerated.xml @@ -0,0 +1,18 @@ + + + + 9911778981 + 9991111111 + +
+ 1 + streetname1 + city1 +
+
+ 2 + streetname2 + city2 +
+
+
\ No newline at end of file diff --git a/jackson/src/test/resources/person.xml b/jackson/src/test/resources/person.xml new file mode 100644 index 0000000000..39a6e859c4 --- /dev/null +++ b/jackson/src/test/resources/person.xml @@ -0,0 +1,19 @@ + + + Rohan + Daye + 9911034731 + 9911033478 + +
+ 1 + Name1 + City1 +
+
+ 2 + Name2 + City2 +
+
+
\ No newline at end of file From 3a31350123af836518ec958c0484c9590fc5957c Mon Sep 17 00:00:00 2001 From: Amy DeGregorio Date: Mon, 18 Feb 2019 13:52:57 -0500 Subject: [PATCH 11/11] BAEL-2663 iterating a map (#6334) * Examples for BAEL-2663 iterating a map * Update for BAEL-2663 to use index in example --- .../com/baeldung/map/MapUnitTest.groovy | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 core-groovy/src/test/groovy/com/baeldung/map/MapUnitTest.groovy diff --git a/core-groovy/src/test/groovy/com/baeldung/map/MapUnitTest.groovy b/core-groovy/src/test/groovy/com/baeldung/map/MapUnitTest.groovy new file mode 100644 index 0000000000..97ffc50c76 --- /dev/null +++ b/core-groovy/src/test/groovy/com/baeldung/map/MapUnitTest.groovy @@ -0,0 +1,85 @@ +package com.baeldung.map + +import static org.junit.Assert.* +import org.junit.Test + +class MapUnitTest { + + @Test + void whenUsingEach_thenMapIsIterated() { + def map = [ + 'FF0000' : 'Red', + '00FF00' : 'Lime', + '0000FF' : 'Blue', + 'FFFF00' : 'Yellow' + ] + + map.each { println "Hex Code: $it.key = Color Name: $it.value" } + } + + @Test + void whenUsingEachWithEntry_thenMapIsIterated() { + def map = [ + 'E6E6FA' : 'Lavender', + 'D8BFD8' : 'Thistle', + 'DDA0DD' : 'Plum', + ] + + map.each { entry -> println "Hex Code: $entry.key = Color Name: $entry.value" } + } + + @Test + void whenUsingEachWithKeyAndValue_thenMapIsIterated() { + def map = [ + '000000' : 'Black', + 'FFFFFF' : 'White', + '808080' : 'Gray' + ] + + map.each { key, val -> + println "Hex Code: $key = Color Name $val" + } + } + + @Test + void whenUsingEachWithIndexAndEntry_thenMapIsIterated() { + def map = [ + '800080' : 'Purple', + '4B0082' : 'Indigo', + '6A5ACD' : 'Slate Blue' + ] + + map.eachWithIndex { entry, index -> + def indent = ((index == 0 || index % 2 == 0) ? " " : "") + println "$indent Hex Code: $entry.key = Color Name: $entry.value" + } + } + + @Test + void whenUsingEachWithIndexAndKeyAndValue_thenMapIsIterated() { + def map = [ + 'FFA07A' : 'Light Salmon', + 'FF7F50' : 'Coral', + 'FF6347' : 'Tomato', + 'FF4500' : 'Orange Red' + ] + + map.eachWithIndex { key, val, index -> + def indent = ((index == 0 || index % 2 == 0) ? " " : "") + println "$indent Hex Code: $key = Color Name: $val" + } + } + + @Test + void whenUsingForLoop_thenMapIsIterated() { + def map = [ + '2E8B57' : 'Seagreen', + '228B22' : 'Forest Green', + '008000' : 'Green' + ] + + for (entry in map) { + println "Hex Code: $entry.key = Color Name: $entry.value" + } + } +}