From e3bada67dd6bcabcdeb4c61304360aa78054abf7 Mon Sep 17 00:00:00 2001 From: Philippe Date: Thu, 24 Jan 2019 23:35:44 -0200 Subject: [PATCH 001/185] BAEL-1381 --- sql-injection-samples/.gitignore | 25 +++ sql-injection-samples/pom.xml | 61 +++++++ .../examples/security/sql/AccountDAO.java | 169 ++++++++++++++++++ .../examples/security/sql/AccountDTO.java | 16 ++ .../sql/SqlInjectionSamplesApplication.java | 14 ++ .../src/main/resources/application.properties | 0 .../resources/db/changelog/create-tables.xml | 19 ++ .../main/resources/db/master-changelog.xml | 8 + ...qlInjectionSamplesApplicationUnitTest.java | 60 +++++++ .../src/test/resources/application-test.yml | 6 + .../src/test/resources/data.sql | 4 + .../src/test/resources/schema.sql | 6 + 12 files changed, 388 insertions(+) create mode 100644 sql-injection-samples/.gitignore create mode 100644 sql-injection-samples/pom.xml create mode 100644 sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java create mode 100644 sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDTO.java create mode 100644 sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplication.java create mode 100644 sql-injection-samples/src/main/resources/application.properties create mode 100644 sql-injection-samples/src/main/resources/db/changelog/create-tables.xml create mode 100644 sql-injection-samples/src/main/resources/db/master-changelog.xml create mode 100644 sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java create mode 100644 sql-injection-samples/src/test/resources/application-test.yml create mode 100644 sql-injection-samples/src/test/resources/data.sql create mode 100644 sql-injection-samples/src/test/resources/schema.sql diff --git a/sql-injection-samples/.gitignore b/sql-injection-samples/.gitignore new file mode 100644 index 0000000000..82eca336e3 --- /dev/null +++ b/sql-injection-samples/.gitignore @@ -0,0 +1,25 @@ +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ \ No newline at end of file diff --git a/sql-injection-samples/pom.xml b/sql-injection-samples/pom.xml new file mode 100644 index 0000000000..b6390ad387 --- /dev/null +++ b/sql-injection-samples/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + com.baeldung + sql-injection-samples + 0.0.1-SNAPSHOT + sql-injection-samples + Sample SQL Injection tests + + + 1.8 + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + org.apache.derby + derby + runtime + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + provided + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java b/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java new file mode 100644 index 0000000000..447dcc456d --- /dev/null +++ b/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java @@ -0,0 +1,169 @@ +/** + * + */ +package com.baeldung.examples.security.sql; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.sql.DataSource; + +import org.springframework.stereotype.Component; + +/** + * @author Philippe + * + */ +@Component +public class AccountDAO { + + private final DataSource dataSource; + + public AccountDAO(DataSource dataSource) { + this.dataSource = dataSource; + } + + /** + * Return all accounts owned by a given customer,given his/her external id + * + * @param customerId + * @return + */ + public List unsafeFindAccountsByCustomerId(String customerId) { + + String sql = "select " + "customer_id,acc_number,branch_id,balance from Accounts where customer_id = '" + customerId + "'"; + + try (Connection c = dataSource.getConnection(); + ResultSet rs = c.createStatement() + .executeQuery(sql)) { + List accounts = new ArrayList<>(); + while (rs.next()) { + AccountDTO acc = AccountDTO.builder() + .customerId(rs.getString("customer_id")) + .branchId(rs.getString("branch_id")) + .accNumber(rs.getString("acc_number")) + .balance(rs.getBigDecimal("balance")) + .build(); + + accounts.add(acc); + } + + return accounts; + } catch (SQLException ex) { + throw new RuntimeException(ex); + } + } + + /** + * Return all accounts owned by a given customer,given his/her external id + * + * @param customerId + * @return + */ + public List safeFindAccountsByCustomerId(String customerId) { + + String sql = "select " + "customer_id,acc_number,branch_id,balance from Accounts where customer_id = ?"; + + try (Connection c = dataSource.getConnection(); PreparedStatement p = c.prepareStatement(sql)) { + p.setString(1, customerId); + 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(); + + accounts.add(acc); + } + return accounts; + } catch (SQLException ex) { + throw new RuntimeException(ex); + } + } + + 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) { + + 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 { + throw new IllegalArgumentException("Nice try!"); + } + + try (Connection c = dataSource.getConnection(); PreparedStatement p = c.prepareStatement(sql)) { + + p.setString(1, customerId); + 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(); + + accounts.add(acc); + } + + return accounts; + } catch (SQLException ex) { + throw new RuntimeException(ex); + } + } + + /** + * Invalid placeholder usage example + * + * @param tableName + * @return + */ + public List wrongCountRecordsByTableName(String tableName) { + + 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(); + + accounts.add(acc); + } + + return accounts; + } catch (SQLException ex) { + throw new RuntimeException(ex); + } + } + +} diff --git a/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDTO.java b/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDTO.java new file mode 100644 index 0000000000..2e6fa04af4 --- /dev/null +++ b/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDTO.java @@ -0,0 +1,16 @@ +package com.baeldung.examples.security.sql; + +import java.math.BigDecimal; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class AccountDTO { + + private String customerId; + private String accNumber; + private String branchId; + private BigDecimal balance; +} diff --git a/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplication.java b/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplication.java new file mode 100644 index 0000000000..c1083ae3de --- /dev/null +++ b/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.examples.security.sql; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SqlInjectionSamplesApplication { + + public static void main(String[] args) { + SpringApplication.run(SqlInjectionSamplesApplication.class, args); + } + +} + diff --git a/sql-injection-samples/src/main/resources/application.properties b/sql-injection-samples/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sql-injection-samples/src/main/resources/db/changelog/create-tables.xml b/sql-injection-samples/src/main/resources/db/changelog/create-tables.xml new file mode 100644 index 0000000000..a405c02049 --- /dev/null +++ b/sql-injection-samples/src/main/resources/db/changelog/create-tables.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sql-injection-samples/src/main/resources/db/master-changelog.xml b/sql-injection-samples/src/main/resources/db/master-changelog.xml new file mode 100644 index 0000000000..047ca2b314 --- /dev/null +++ b/sql-injection-samples/src/main/resources/db/master-changelog.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java b/sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java new file mode 100644 index 0000000000..1f37ba04b6 --- /dev/null +++ b/sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.examples.security.sql; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +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.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.examples.security.sql.AccountDAO; +import com.baeldung.examples.security.sql.AccountDTO; + +@RunWith(SpringRunner.class) +@SpringBootTest +@ActiveProfiles({ "test" }) +public class SqlInjectionSamplesApplicationUnitTest { + + @Autowired + private AccountDAO target; + + @Test + public void givenAVulnerableMethod_whenValidCustomerId_thenReturnSingleAccount() { + + List accounts = target.unsafeFindAccountsByCustomerId("C1"); + assertThat(accounts).isNotNull(); + assertThat(accounts).isNotEmpty(); + assertThat(accounts).hasSize(1); + } + + @Test + public void givenAVulnerableMethod_whenHackedCustomerId_thenReturnAllAccounts() { + + List accounts = target.unsafeFindAccountsByCustomerId("C1' or '1'='1"); + assertThat(accounts).isNotNull(); + assertThat(accounts).isNotEmpty(); + assertThat(accounts).hasSize(3); + } + + @Test + public void givenASafeMethod_whenHackedCustomerId_thenReturnNoAccounts() { + + List accounts = target.safeFindAccountsByCustomerId("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) + public void givenWrongPlaceholderUsageMethod_whenNormalCall_thenThrowsException() { + target.wrongCountRecordsByTableName("Accounts"); + } +} diff --git a/sql-injection-samples/src/test/resources/application-test.yml b/sql-injection-samples/src/test/resources/application-test.yml new file mode 100644 index 0000000000..d07ee10aee --- /dev/null +++ b/sql-injection-samples/src/test/resources/application-test.yml @@ -0,0 +1,6 @@ +# +# Test profile configuration +# +spring: + datasource: + initialization-mode: always diff --git a/sql-injection-samples/src/test/resources/data.sql b/sql-injection-samples/src/test/resources/data.sql new file mode 100644 index 0000000000..586618a07f --- /dev/null +++ b/sql-injection-samples/src/test/resources/data.sql @@ -0,0 +1,4 @@ +insert into Accounts(customer_id,acc_number,branch_id,balance) values ('C1','0001',1,1000.00); +insert into Accounts(customer_id,acc_number,branch_id,balance) values ('C2','0002',1,500.00); +insert into Accounts(customer_id,acc_number,branch_id,balance) values ('C3','0003',1,501.00); + diff --git a/sql-injection-samples/src/test/resources/schema.sql b/sql-injection-samples/src/test/resources/schema.sql new file mode 100644 index 0000000000..bfb0ae8059 --- /dev/null +++ b/sql-injection-samples/src/test/resources/schema.sql @@ -0,0 +1,6 @@ +create table Accounts ( + customer_id varchar(16) not null, + acc_number varchar(16) not null, + branch_id decimal(8,0), + balance decimal(16,4) +); From 43d429e4151d5cf62ba7ce7ae69b13bb415be698 Mon Sep 17 00:00:00 2001 From: Philippe Date: Thu, 24 Jan 2019 23:48:22 -0200 Subject: [PATCH 002/185] [BAEL-1381] --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d084d0f7af..9306a1db2e 100644 --- a/pom.xml +++ b/pom.xml @@ -567,7 +567,8 @@ rule-engines/rulebook rsocket rxjava - rxjava-2 + rxjava-2 + sql-injection-samples From bc267aec07a0de7a79a7484cb60343f7a8067da3 Mon Sep 17 00:00:00 2001 From: Philippe Date: Tue, 29 Jan 2019 21:34:30 -0200 Subject: [PATCH 003/185] [BAEL-1381] New module name --- pom.xml | 2 +- .../sql-injection-samples}/.gitignore | 0 .../sql-injection-samples}/pom.xml | 2 +- .../java/com/baeldung/examples/security/sql/AccountDAO.java | 0 .../java/com/baeldung/examples/security/sql/AccountDTO.java | 0 .../examples/security/sql/SqlInjectionSamplesApplication.java | 0 .../src/main/resources/application.properties | 0 .../src/main/resources/db/changelog/create-tables.xml | 0 .../src/main/resources/db/master-changelog.xml | 0 .../security/sql/SqlInjectionSamplesApplicationUnitTest.java | 0 .../src/test/resources/application-test.yml | 0 .../sql-injection-samples}/src/test/resources/data.sql | 0 .../sql-injection-samples}/src/test/resources/schema.sql | 0 13 files changed, 2 insertions(+), 2 deletions(-) rename {sql-injection-samples => software-security/sql-injection-samples}/.gitignore (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/pom.xml (96%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/main/java/com/baeldung/examples/security/sql/AccountDTO.java (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/main/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplication.java (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/main/resources/application.properties (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/main/resources/db/changelog/create-tables.xml (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/main/resources/db/master-changelog.xml (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/test/resources/application-test.yml (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/test/resources/data.sql (100%) rename {sql-injection-samples => software-security/sql-injection-samples}/src/test/resources/schema.sql (100%) diff --git a/pom.xml b/pom.xml index 68a4a1f7ad..30d5e2ade8 100644 --- a/pom.xml +++ b/pom.xml @@ -568,7 +568,7 @@ rsocket rxjava rxjava-2 - sql-injection-samples + software-security diff --git a/sql-injection-samples/.gitignore b/software-security/sql-injection-samples/.gitignore similarity index 100% rename from sql-injection-samples/.gitignore rename to software-security/sql-injection-samples/.gitignore diff --git a/sql-injection-samples/pom.xml b/software-security/sql-injection-samples/pom.xml similarity index 96% rename from sql-injection-samples/pom.xml rename to software-security/sql-injection-samples/pom.xml index b6390ad387..d5e64db6b3 100644 --- a/sql-injection-samples/pom.xml +++ b/software-security/sql-injection-samples/pom.xml @@ -7,7 +7,7 @@ parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-2 + ../../parent-boot-2 com.baeldung diff --git a/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 similarity index 100% rename from sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java rename to software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDAO.java diff --git a/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDTO.java b/software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDTO.java similarity index 100% rename from sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDTO.java rename to software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/AccountDTO.java diff --git a/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplication.java b/software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplication.java similarity index 100% rename from sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplication.java rename to software-security/sql-injection-samples/src/main/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplication.java diff --git a/sql-injection-samples/src/main/resources/application.properties b/software-security/sql-injection-samples/src/main/resources/application.properties similarity index 100% rename from sql-injection-samples/src/main/resources/application.properties rename to software-security/sql-injection-samples/src/main/resources/application.properties diff --git a/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 similarity index 100% rename from sql-injection-samples/src/main/resources/db/changelog/create-tables.xml rename to software-security/sql-injection-samples/src/main/resources/db/changelog/create-tables.xml diff --git a/sql-injection-samples/src/main/resources/db/master-changelog.xml b/software-security/sql-injection-samples/src/main/resources/db/master-changelog.xml similarity index 100% rename from sql-injection-samples/src/main/resources/db/master-changelog.xml rename to software-security/sql-injection-samples/src/main/resources/db/master-changelog.xml diff --git a/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 similarity index 100% rename from sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java rename to software-security/sql-injection-samples/src/test/java/com/baeldung/examples/security/sql/SqlInjectionSamplesApplicationUnitTest.java diff --git a/sql-injection-samples/src/test/resources/application-test.yml b/software-security/sql-injection-samples/src/test/resources/application-test.yml similarity index 100% rename from sql-injection-samples/src/test/resources/application-test.yml rename to software-security/sql-injection-samples/src/test/resources/application-test.yml diff --git a/sql-injection-samples/src/test/resources/data.sql b/software-security/sql-injection-samples/src/test/resources/data.sql similarity index 100% rename from sql-injection-samples/src/test/resources/data.sql rename to software-security/sql-injection-samples/src/test/resources/data.sql diff --git a/sql-injection-samples/src/test/resources/schema.sql b/software-security/sql-injection-samples/src/test/resources/schema.sql similarity index 100% rename from sql-injection-samples/src/test/resources/schema.sql rename to software-security/sql-injection-samples/src/test/resources/schema.sql From 35b89e5cbcd54032f7c80dca83fcca7b011a0cc9 Mon Sep 17 00:00:00 2001 From: Philippe Date: Tue, 29 Jan 2019 22:06:02 -0200 Subject: [PATCH 004/185] [BAEL-1381] software-security module --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 30d5e2ade8..787a03c2fb 100644 --- a/pom.xml +++ b/pom.xml @@ -568,7 +568,7 @@ rsocket rxjava rxjava-2 - software-security + software-security/sql-injection-samples From 9f61a81114fa31132c4764c22ae11f3bc4f51171 Mon Sep 17 00:00:00 2001 From: Philippe Date: Sun, 17 Feb 2019 20:56:09 -0300 Subject: [PATCH 005/185] [BAEL-1381] Add JPA examples --- .../CustomBaeldungQueueUnitTest.java | 0 .../PriorityQueueUnitTest.java | 0 .../sql-injection-samples/pom.xml | 13 ++ .../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, 245 insertions(+), 50 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 e4510d9ef8..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 + + + 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 33b60605d778d35ae48d0a177be3862e5d377393 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Thu, 7 Mar 2019 23:44:32 +1100 Subject: [PATCH 006/185] BAEL-2569 : EnvironmentPostProcessor in Spring Boot --- .../PriceCalculationApplication.java | 59 +++++++++++++++ ...ceCalculationEnvironmentPostProcessor.java | 71 +++++++++++++++++++ .../PriceCalculationAutoConfig.java | 32 +++++++++ .../calculator/GrossPriceCalculator.java | 23 ++++++ .../calculator/NetPriceCalculator.java | 17 +++++ .../calculator/PriceCalculator.java | 5 ++ .../service/PriceCalculationService.java | 17 +++++ .../main/resources/META-INF/spring.factories | 8 ++- 8 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java create mode 100644 spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java new file mode 100644 index 0000000000..01be08d6ae --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java @@ -0,0 +1,59 @@ +package com.baeldung.environmentpostprocessor; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import com.baeldung.environmentpostprocessor.service.PriceCalculationService; + +@SpringBootApplication +public class PriceCalculationApplication implements CommandLineRunner { + + @Autowired + PriceCalculationService priceCalculationService; + + private static final Logger logger = LoggerFactory.getLogger(PriceCalculationApplication.class); + + public static void main(String[] args) { + SpringApplication.run(PriceCalculationApplication.class, args); + } + + @Override + public void run(String... args) throws Exception { + + List params = Arrays.stream(args) + .collect(Collectors.toList()); + if (verifyArguments(params)) { + double singlePrice = Double.valueOf(params.get(0)); + int quantity = Integer.valueOf(params.get(1)); + priceCalculationService.productTotalPrice(singlePrice, quantity); + } else { + logger.error("Invalid arguments " + params.toString()); + } + + } + + private boolean verifyArguments(List args) { + boolean successful = true; + if (args.size() != 2) { + successful = false; + return successful; + } + try { + double singlePrice = Double.valueOf(args.get(0)); + int quantity = Integer.valueOf(args.get(1)); + } catch (NumberFormatException e) { + successful = false; + } + return successful; + + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java new file mode 100644 index 0000000000..1b3099453e --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java @@ -0,0 +1,71 @@ +package com.baeldung.environmentpostprocessor; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.core.Ordered; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.core.env.StandardEnvironment; + +public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { + + private static final Logger logger = LoggerFactory.getLogger(PriceCalculationEnvironmentPostProcessor.class); + + public static final int DEFAULT_ORDER = Ordered.LOWEST_PRECEDENCE; + private int order = DEFAULT_ORDER; + private static final String PROPERTY_PREFIX = "com.baeldung.environmentpostprocessor."; + private static final String OS_ENV_PROPERTY_CALCUATION_MODE = "calculation_mode"; + private static final String OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE = "gross_calculation_tax_rate"; + private static final String OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE = "NET"; + private static final double OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE = 0; + + @Override + public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { + + PropertySource systemEnvironmentPropertySource = environment.getPropertySources() + .get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); + + Map priceCalculationConfiguration = new LinkedHashMap<>(); + if (isActive(systemEnvironmentPropertySource)) { + priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), systemEnvironmentPropertySource.getProperty(OS_ENV_PROPERTY_CALCUATION_MODE)); + priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), systemEnvironmentPropertySource.getProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)); + } else { + logger.warn("System environment variables [calculation_mode,gross_calculation_tax_rate] not detected, fallback to default value [calcuation_mode={},gross_calcuation_tax_rate={}]", OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE, + OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE); + priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + } + + PropertySource priceCalcuationPropertySource = new MapPropertySource("priceCalcuationPS", priceCalculationConfiguration); + environment.getPropertySources() + .addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, priceCalcuationPropertySource); + + } + + private String key(String key) { + return PROPERTY_PREFIX + key.replaceAll("\\_", "."); + } + + private boolean isActive(PropertySource systemEnvpropertySource) { + if (systemEnvpropertySource.containsProperty(OS_ENV_PROPERTY_CALCUATION_MODE) && systemEnvpropertySource.containsProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)) { + return true; + } else + return false; + } + + public void setOrder(int order) { + this.order = order; + } + + @Override + public int getOrder() { + return order; + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java new file mode 100644 index 0000000000..c884f043a0 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java @@ -0,0 +1,32 @@ +package com.baeldung.environmentpostprocessor.autoconfig; + +import org.springframework.boot.autoconfigure.AutoConfigureOrder; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; + +import com.baeldung.environmentpostprocessor.calculator.GrossPriceCalculator; +import com.baeldung.environmentpostprocessor.calculator.NetPriceCalculator; +import com.baeldung.environmentpostprocessor.calculator.PriceCalculator; + +@Configuration +@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) +public class PriceCalculationAutoConfig { + + @Bean + @ConditionalOnProperty(name = "com.baeldung.environmentpostprocessor.calculation.mode", havingValue = "NET") + @ConditionalOnMissingBean + public PriceCalculator getNetPriceCalculator() { + return new NetPriceCalculator(); + } + + @Bean + @ConditionalOnProperty(name = "com.baeldung.environmentpostprocessor.calculation.mode", havingValue = "GROSS") + @ConditionalOnMissingBean + public PriceCalculator getGrossPriceCalculator() { + return new GrossPriceCalculator(); + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java new file mode 100644 index 0000000000..f8f797bd66 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java @@ -0,0 +1,23 @@ +package com.baeldung.environmentpostprocessor.calculator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; + +public class GrossPriceCalculator implements PriceCalculator { + + private static final Logger logger = LoggerFactory.getLogger(GrossPriceCalculator.class); + + @Value("${com.baeldung.environmentpostprocessor.gross.calculation.tax.rate}") + double taxRate; + + @Override + public double calculate(double singlePrice, int quantity) { + logger.info("Gross based price calculation with input parameters [singlePrice = {},quantity= {} ], {} percent tax applied.", singlePrice, quantity, taxRate * 100); + double netPrice = singlePrice * quantity; + double result = Math.round(netPrice * (1 + taxRate)); + logger.info("Calcuation result is {}", result); + return result; + } + +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java new file mode 100644 index 0000000000..263dff6247 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java @@ -0,0 +1,17 @@ +package com.baeldung.environmentpostprocessor.calculator; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NetPriceCalculator implements PriceCalculator { + + private static final Logger logger = LoggerFactory.getLogger(GrossPriceCalculator.class); + + @Override + public double calculate(double singlePrice, int quantity) { + logger.info("Net based price calculation with input parameters [singlePrice = {},quantity= {} ], NO tax applied.", singlePrice, quantity); + double result = Math.round(singlePrice * quantity); + logger.info("Calcuation result is {}", result); + return result; + } +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java new file mode 100644 index 0000000000..9d7bef93a4 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java @@ -0,0 +1,5 @@ +package com.baeldung.environmentpostprocessor.calculator; + +public interface PriceCalculator { + public double calculate(double singlePrice, int quantity); +} diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java new file mode 100644 index 0000000000..0e4eb39506 --- /dev/null +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java @@ -0,0 +1,17 @@ +package com.baeldung.environmentpostprocessor.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.environmentpostprocessor.calculator.PriceCalculator; + +@Service +public class PriceCalculationService { + + @Autowired + PriceCalculator priceCalculator; + + public double productTotalPrice(double singlePrice, int quantity) { + return priceCalculator.calculate(singlePrice, quantity); + } +} diff --git a/spring-boot/src/main/resources/META-INF/spring.factories b/spring-boot/src/main/resources/META-INF/spring.factories index e3d3aa4c8e..d8a01bbf82 100644 --- a/spring-boot/src/main/resources/META-INF/spring.factories +++ b/spring-boot/src/main/resources/META-INF/spring.factories @@ -1 +1,7 @@ -org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer \ No newline at end of file +org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig + +org.springframework.boot.env.EnvironmentPostProcessor=\ +com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor + From bbb98f7a91a91336fb47ae71651400b2b8516bab Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Mon, 11 Mar 2019 23:49:35 +1100 Subject: [PATCH 007/185] BAEL-2569 add test --- ...ationEnvironmentPostProcessorLiveTest.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java diff --git a/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java b/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java new file mode 100644 index 0000000000..352e7941fb --- /dev/null +++ b/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java @@ -0,0 +1,29 @@ +package com.baeldung.environmentpostprocessor; + +import static org.junit.Assert.assertTrue; + +import org.junit.Assert; +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 com.baeldung.environmentpostprocessor.service.PriceCalculationService; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = PriceCalculationApplication.class) +public class PriceCalculationEnvironmentPostProcessorLiveTest { + + @Autowired + PriceCalculationService pcService; + + + @Test + public void WhenSetGrossEnvironmentVariable_ThenTaxApplied() { + double total = pcService.productTotalPrice(100, 4); + + Assert.assertEquals(400.0,total); + } + +} From a0227300bf92b3609a554916c8f70aa710d09900 Mon Sep 17 00:00:00 2001 From: "Matt Zhang (EXT)" Date: Wed, 13 Mar 2019 11:56:26 +1100 Subject: [PATCH 008/185] BAEL-2569 update test --- ...CalculationEnvironmentPostProcessorLiveTest.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java b/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java index 352e7941fb..54af217346 100644 --- a/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java +++ b/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java @@ -1,8 +1,7 @@ package com.baeldung.environmentpostprocessor; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -14,16 +13,14 @@ import com.baeldung.environmentpostprocessor.service.PriceCalculationService; @RunWith(SpringRunner.class) @SpringBootTest(classes = PriceCalculationApplication.class) public class PriceCalculationEnvironmentPostProcessorLiveTest { - + @Autowired PriceCalculationService pcService; - - + @Test - public void WhenSetGrossEnvironmentVariable_ThenTaxApplied() { + public void whenSetNetEnvironmentVariablebyDefault_thenNoTaxApplied() { double total = pcService.productTotalPrice(100, 4); - - Assert.assertEquals(400.0,total); + assertEquals(400.0, total, 0); } } From 9f8058a5603ced4177f5bc42ca7b8dbd408a5953 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Fri, 29 Mar 2019 23:46:43 +1100 Subject: [PATCH 009/185] BAEL-2569 refactoring the class PriceCalculationEnvironmentPostProcessor --- ...ceCalculationEnvironmentPostProcessor.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java index 1b3099453e..42cbd1e90f 100644 --- a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java @@ -8,17 +8,17 @@ import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.core.env.StandardEnvironment; -public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { +@Order(Ordered.LOWEST_PRECEDENCE) +public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor { private static final Logger logger = LoggerFactory.getLogger(PriceCalculationEnvironmentPostProcessor.class); - public static final int DEFAULT_ORDER = Ordered.LOWEST_PRECEDENCE; - private int order = DEFAULT_ORDER; private static final String PROPERTY_PREFIX = "com.baeldung.environmentpostprocessor."; private static final String OS_ENV_PROPERTY_CALCUATION_MODE = "calculation_mode"; private static final String OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE = "gross_calculation_tax_rate"; @@ -28,26 +28,34 @@ public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPost @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - PropertySource systemEnvironmentPropertySource = environment.getPropertySources() + PropertySource systemEnvPropertySource = environment.getPropertySources() .get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); - Map priceCalculationConfiguration = new LinkedHashMap<>(); - if (isActive(systemEnvironmentPropertySource)) { - priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), systemEnvironmentPropertySource.getProperty(OS_ENV_PROPERTY_CALCUATION_MODE)); - priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), systemEnvironmentPropertySource.getProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)); + Map mapPropertySource = new LinkedHashMap<>(); + if (isActive(systemEnvPropertySource)) { + populatePropertySource(systemEnvPropertySource, mapPropertySource); } else { logger.warn("System environment variables [calculation_mode,gross_calculation_tax_rate] not detected, fallback to default value [calcuation_mode={},gross_calcuation_tax_rate={}]", OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE, OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); - priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE); - priceCalculationConfiguration.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + populateDefaultPropertySource(mapPropertySource); } - PropertySource priceCalcuationPropertySource = new MapPropertySource("priceCalcuationPS", priceCalculationConfiguration); + PropertySource priceCalcuationPropertySource = new MapPropertySource("priceCalcuationPS", mapPropertySource); environment.getPropertySources() .addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, priceCalcuationPropertySource); } + private void populatePropertySource(PropertySource source, Map target) { + target.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), source.getProperty(OS_ENV_PROPERTY_CALCUATION_MODE)); + target.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), source.getProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)); + } + + private void populateDefaultPropertySource(Map target) { + target.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE); + target.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + } + private String key(String key) { return PROPERTY_PREFIX + key.replaceAll("\\_", "."); } @@ -59,13 +67,4 @@ public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPost return false; } - public void setOrder(int order) { - this.order = order; - } - - @Override - public int getOrder() { - return order; - } - } From 99a3aa5bab5e066bd8470ac2619160aaab19e788 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Sun, 31 Mar 2019 22:42:32 +1100 Subject: [PATCH 010/185] BAEL-2569: changes to class PriceCalculationEnvironmentPostProcessor --- ...ceCalculationEnvironmentPostProcessor.java | 69 +++++++++++-------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java index 42cbd1e90f..ca6d6cc28f 100644 --- a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java +++ b/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java @@ -1,7 +1,12 @@ package com.baeldung.environmentpostprocessor; +import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME; + +import java.util.Arrays; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,56 +17,62 @@ import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; @Order(Ordered.LOWEST_PRECEDENCE) public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor { private static final Logger logger = LoggerFactory.getLogger(PriceCalculationEnvironmentPostProcessor.class); - private static final String PROPERTY_PREFIX = "com.baeldung.environmentpostprocessor."; - private static final String OS_ENV_PROPERTY_CALCUATION_MODE = "calculation_mode"; - private static final String OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE = "gross_calculation_tax_rate"; - private static final String OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE = "NET"; - private static final double OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE = 0; + private static final String PREFIX = "com.baeldung.environmentpostprocessor."; + private static final String CALCUATION_MODE = "calculation_mode"; + private static final String GROSS_CALCULATION_TAX_RATE = "gross_calculation_tax_rate"; + private static final String CALCUATION_MODE_DEFAULT_VALUE = "NET"; + private static final double GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE = 0; + + List names = Arrays.asList(CALCUATION_MODE, GROSS_CALCULATION_TAX_RATE); + + private static Map defaults = new LinkedHashMap<>(); + static { + defaults.put(CALCUATION_MODE, CALCUATION_MODE_DEFAULT_VALUE); + defaults.put(GROSS_CALCULATION_TAX_RATE, GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + } @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - PropertySource systemEnvPropertySource = environment.getPropertySources() - .get(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); + PropertySource system = environment.getPropertySources() + .get(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME); - Map mapPropertySource = new LinkedHashMap<>(); - if (isActive(systemEnvPropertySource)) { - populatePropertySource(systemEnvPropertySource, mapPropertySource); - } else { - logger.warn("System environment variables [calculation_mode,gross_calculation_tax_rate] not detected, fallback to default value [calcuation_mode={},gross_calcuation_tax_rate={}]", OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE, - OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); - populateDefaultPropertySource(mapPropertySource); + Map prefixed = new LinkedHashMap<>(); + + if (!hasOurPriceProperties(system)) { + // Baeldung-internal code so this doesn't break other examples + logger.warn("System environment variables [calculation_mode,gross_calculation_tax_rate] not detected, fallback to default value [calcuation_mode={},gross_calcuation_tax_rate={}]", CALCUATION_MODE_DEFAULT_VALUE, + GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + prefixed = names.stream() + .collect(Collectors.toMap(this::rename, this::getDefaultValue)); + environment.getPropertySources() + .addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, new MapPropertySource("prefixer", prefixed)); + return; } - PropertySource priceCalcuationPropertySource = new MapPropertySource("priceCalcuationPS", mapPropertySource); + prefixed = names.stream() + .collect(Collectors.toMap(this::rename, system::getProperty)); environment.getPropertySources() - .addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, priceCalcuationPropertySource); + .addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, new MapPropertySource("prefixer", prefixed)); } - private void populatePropertySource(PropertySource source, Map target) { - target.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), source.getProperty(OS_ENV_PROPERTY_CALCUATION_MODE)); - target.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), source.getProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)); + private Object getDefaultValue(String key) { + return defaults.get(key); } - private void populateDefaultPropertySource(Map target) { - target.put(key(OS_ENV_PROPERTY_CALCUATION_MODE), OS_ENV_PROPERTY_CALCUATION_MODE_DEFAULT_VALUE); - target.put(key(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE), OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE_DEFAULT_VALUE); + private String rename(String key) { + return PREFIX + key.replaceAll("\\_", "."); } - private String key(String key) { - return PROPERTY_PREFIX + key.replaceAll("\\_", "."); - } - - private boolean isActive(PropertySource systemEnvpropertySource) { - if (systemEnvpropertySource.containsProperty(OS_ENV_PROPERTY_CALCUATION_MODE) && systemEnvpropertySource.containsProperty(OS_ENV_PROPERTY_GROSS_CALCULATION_TAX_RATE)) { + private boolean hasOurPriceProperties(PropertySource system) { + if (system.containsProperty(CALCUATION_MODE) && system.containsProperty(GROSS_CALCULATION_TAX_RATE)) { return true; } else return false; From a86c69429bf8c99b56ed1b0f236db9a87043aab3 Mon Sep 17 00:00:00 2001 From: Philippe Date: Mon, 1 Apr 2019 22:22:02 -0300 Subject: [PATCH 011/185] Workaround for spring-framework#21094 --- spring-webflux-amqp/pom.xml | 116 ++++++++++-------- .../amqp/SpringWebfluxAmqpApplication.java | 21 ++++ .../src/main/resources/application.yml | 2 +- 3 files changed, 87 insertions(+), 52 deletions(-) diff --git a/spring-webflux-amqp/pom.xml b/spring-webflux-amqp/pom.xml index a8346458a0..88f5eff403 100755 --- a/spring-webflux-amqp/pom.xml +++ b/spring-webflux-amqp/pom.xml @@ -1,62 +1,76 @@ - 4.0.0 - org.baeldung.spring - spring-webflux-amqp - 1.0.0-SNAPSHOT - spring-webflux-amqp - jar - Spring WebFlux AMQP Sample + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + org.baeldung.spring + spring-webflux-amqp + 1.0.0-SNAPSHOT + spring-webflux-amqp + jar + Spring WebFlux AMQP Sample - - parent-boot-2 - com.baeldung - 0.0.1-SNAPSHOT - ../parent-boot-2 - + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../parent-boot-2 + - - - org.springframework.boot - spring-boot-starter-amqp - - - org.springframework.boot - spring-boot-starter-webflux - + + + + + org.springframework.boot + spring-boot-dependencies + + 2.1.3.RELEASE + pom + import + + + - - org.springframework.boot - spring-boot-configuration-processor - true - + + + org.springframework.boot + spring-boot-starter-amqp + + + org.springframework.boot + spring-boot-starter-webflux + - - org.springframework.boot - spring-boot-starter-test - test - + + org.springframework.boot + spring-boot-configuration-processor + true + - - io.projectreactor - reactor-test - test - + + org.springframework.boot + spring-boot-starter-test + test + - - org.springframework.boot - spring-boot-starter-integration - - + + io.projectreactor + reactor-test + test + - - - - org.springframework.boot - spring-boot-maven-plugin - - - + + org.springframework.boot + spring-boot-starter-integration + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + diff --git a/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java b/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java index 30614e7ee6..8a31299333 100755 --- a/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java +++ b/spring-webflux-amqp/src/main/java/org/baeldung/spring/amqp/SpringWebfluxAmqpApplication.java @@ -3,6 +3,12 @@ package org.baeldung.spring.amqp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.web.filter.reactive.HiddenHttpMethodFilter; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilterChain; + +import reactor.core.publisher.Mono; @SpringBootApplication @EnableConfigurationProperties(DestinationsConfig.class) @@ -12,4 +18,19 @@ public class SpringWebfluxAmqpApplication { SpringApplication.run(SpringWebfluxAmqpApplication.class, args); } + + /** + * This is a workaround for https://github.com/spring-projects/spring-framework/issues/21094 + * @return + */ + @Bean + public HiddenHttpMethodFilter hiddenHttpMethodFilter() { + return new HiddenHttpMethodFilter() { + @Override + public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { + return chain.filter(exchange); + } + }; + } + } diff --git a/spring-webflux-amqp/src/main/resources/application.yml b/spring-webflux-amqp/src/main/resources/application.yml index 702aaba357..3f527ce4c5 100755 --- a/spring-webflux-amqp/src/main/resources/application.yml +++ b/spring-webflux-amqp/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: rabbitmq: - host: localhost + host: 192.168.99.100 port: 5672 username: guest password: guest From bac144389785c0a78ae398d5854b671fecccce41 Mon Sep 17 00:00:00 2001 From: Philippe Date: Tue, 2 Apr 2019 02:12:55 -0300 Subject: [PATCH 012/185] Initial import --- apache-olingo/olingo2/.gitignore | 29 +++++ apache-olingo/olingo2/pom.xml | 108 ++++++++++++++++++ .../olingo2/CarsODataApplication.java | 24 ++++ .../olingo2/CarsODataJPAServiceFactory.java | 38 ++++++ .../examples/olingo2/JerseyConfig.java | 49 ++++++++ .../olingo2/Olingo2SampleApplication.java | 15 +++ .../examples/olingo2/domain/CarMaker.java | 31 +++++ .../examples/olingo2/domain/CarModel.java | 30 +++++ .../src/main/resources/application.yml | 9 ++ .../olingo2/src/main/resources/data.sql | 3 + .../Olingo2SampleApplicationTests.java | 16 +++ .../sql-injection-samples/pom.xml | 4 + 12 files changed, 356 insertions(+) create mode 100644 apache-olingo/olingo2/.gitignore create mode 100644 apache-olingo/olingo2/pom.xml create mode 100644 apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataApplication.java create mode 100644 apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java create mode 100644 apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java create mode 100644 apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/Olingo2SampleApplication.java create mode 100644 apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java create mode 100644 apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java create mode 100644 apache-olingo/olingo2/src/main/resources/application.yml create mode 100644 apache-olingo/olingo2/src/main/resources/data.sql create mode 100644 apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationTests.java diff --git a/apache-olingo/olingo2/.gitignore b/apache-olingo/olingo2/.gitignore new file mode 100644 index 0000000000..153c9335eb --- /dev/null +++ b/apache-olingo/olingo2/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/apache-olingo/olingo2/pom.xml b/apache-olingo/olingo2/pom.xml new file mode 100644 index 0000000000..4fc81e5e49 --- /dev/null +++ b/apache-olingo/olingo2/pom.xml @@ -0,0 +1,108 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + org.baeldung.examples.olingo2 + olingo2-sample + 0.0.1-SNAPSHOT + olingo2-sample + Sample Olingo 2 Project + + + 1.8 + 2.0.11 + + + + + + org.springframework.boot + spring-boot-starter-jersey + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.apache.olingo + olingo-odata2-core + ${olingo2.version} + + + + javax.ws.rs + javax.ws.rs-api + + + + + org.apache.olingo + olingo-odata2-api + ${olingo2.version} + + + org.apache.olingo + olingo-odata2-jpa-processor-api + ${olingo2.version} + + + org.apache.olingo + olingo-odata2-jpa-processor-core + ${olingo2.version} + + + org.apache.olingo + olingo-odata2-jpa-processor-ref + ${olingo2.version} + + + org.eclipse.persistence + eclipselink + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataApplication.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataApplication.java new file mode 100644 index 0000000000..c7e3878f44 --- /dev/null +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataApplication.java @@ -0,0 +1,24 @@ +package org.baeldung.examples.olingo2; + + +import java.util.Set; + +import javax.ws.rs.ApplicationPath; + +import org.apache.olingo.odata2.core.rest.ODataRootLocator; +import org.apache.olingo.odata2.core.rest.app.ODataApplication; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class CarsODataApplication extends ODataApplication { + + private static final Logger log = LoggerFactory.getLogger(CarsODataApplication.class); + + public CarsODataApplication() { + super(); + log.info("[I17] Creating CarsODataApplication..."); + } + +} diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java new file mode 100644 index 0000000000..2d0ae14686 --- /dev/null +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java @@ -0,0 +1,38 @@ +package org.baeldung.examples.olingo2; + +import javax.persistence.EntityManager; + +import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext; +import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory; +import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +/** + * OData ServiceFactory that + * @author Philippe + * + */ +@Component +public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory { + + private EntityManager em; + private static final Logger log = LoggerFactory.getLogger(CarsODataJPAServiceFactory.class); + + public CarsODataJPAServiceFactory(EntityManager em) { + this.em = em; + } + + @Override + public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException { + + ODataJPAContext oDataJPAContext = getODataJPAContext(); + oDataJPAContext.setEntityManagerFactory(em.getEntityManagerFactory()); + oDataJPAContext.setPersistenceUnitName("default"); + + return oDataJPAContext; + + } + +} diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java new file mode 100644 index 0000000000..33db629318 --- /dev/null +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java @@ -0,0 +1,49 @@ +package org.baeldung.examples.olingo2; + +import javax.servlet.ServletContext; +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.Path; + +import org.apache.olingo.odata2.api.ODataServiceFactory; +import org.apache.olingo.odata2.core.rest.ODataRootLocator; +import org.glassfish.jersey.server.ResourceConfig; +import org.springframework.stereotype.Component; + +@Component +@ApplicationPath("/odata") +public class JerseyConfig extends ResourceConfig { + + + public JerseyConfig(CarsODataApplication delegate,ServletContext servletContext,CarsODataJPAServiceFactory serviceFactory) { + + delegate + .getClasses() + .forEach( c -> { + // Avoid using the default Locator + if ( !ODataRootLocator.class.isAssignableFrom(c)) { + register(c); + } + }); + + register(new CustomLocator(serviceFactory)); + + } + + + @Path("/") + public static class CustomLocator extends ODataRootLocator { + + private CarsODataJPAServiceFactory serviceFactory; + + public CustomLocator(CarsODataJPAServiceFactory serviceFactory) { + this.serviceFactory = serviceFactory; + } + + @Override + public ODataServiceFactory getServiceFactory() { + return this.serviceFactory; + } + + } + +} diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/Olingo2SampleApplication.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/Olingo2SampleApplication.java new file mode 100644 index 0000000000..6cc4a45927 --- /dev/null +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/Olingo2SampleApplication.java @@ -0,0 +1,15 @@ +package org.baeldung.examples.olingo2; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +@SpringBootApplication +public class Olingo2SampleApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + new Olingo2SampleApplication() + .configure(new SpringApplicationBuilder(Olingo2SampleApplication.class)) + .run(args); + } +} diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java new file mode 100644 index 0000000000..1817a2dece --- /dev/null +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java @@ -0,0 +1,31 @@ +package org.baeldung.examples.olingo2.domain; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; + +import lombok.Data; + +@Entity +@Data +@Table(name="car_maker") +public class CarMaker { + + @Id + private Long id; + + @NotNull + @Column(name="name") + private String name; + + @OneToMany(mappedBy="maker",cascade=CascadeType.ALL) + private List models; + + +} diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java new file mode 100644 index 0000000000..285e5ce379 --- /dev/null +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java @@ -0,0 +1,30 @@ +package org.baeldung.examples.olingo2.domain; + + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.validation.constraints.NotNull; + +import lombok.Data; + +@Entity +@Data +public class CarModel { + + @Id + private Long id; + + @NotNull + private String name; + + @NotNull + private Integer year; + + @NotNull + private String sku; + + @ManyToOne + private CarMaker maker; + +} diff --git a/apache-olingo/olingo2/src/main/resources/application.yml b/apache-olingo/olingo2/src/main/resources/application.yml new file mode 100644 index 0000000000..2af431eee1 --- /dev/null +++ b/apache-olingo/olingo2/src/main/resources/application.yml @@ -0,0 +1,9 @@ + +spring: + jersey: + application-path: /odata + + jpa: + show-sql: true + hibernate: + ddl-auto: update \ No newline at end of file diff --git a/apache-olingo/olingo2/src/main/resources/data.sql b/apache-olingo/olingo2/src/main/resources/data.sql new file mode 100644 index 0000000000..c1d32dc6ef --- /dev/null +++ b/apache-olingo/olingo2/src/main/resources/data.sql @@ -0,0 +1,3 @@ +insert into car_maker(id,name) values (1,'Special Motors'); +insert into car_maker(id,name) values (2,'BWM'); +insert into car_maker(id,name) values (3,'Dolores'); diff --git a/apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationTests.java b/apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationTests.java new file mode 100644 index 0000000000..687f6ab1ff --- /dev/null +++ b/apache-olingo/olingo2/src/test/java/org/baeldung/examples/olingo2/Olingo2SampleApplicationTests.java @@ -0,0 +1,16 @@ +package org.baeldung.examples.olingo2; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class Olingo2SampleApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/software-security/sql-injection-samples/pom.xml b/software-security/sql-injection-samples/pom.xml index 5b33c674d4..b943151896 100644 --- a/software-security/sql-injection-samples/pom.xml +++ b/software-security/sql-injection-samples/pom.xml @@ -55,6 +55,10 @@ + + org.springframework.boot + spring-boot-devtools + From 881580f2fe9eac3464fafa0f7d4e9456a5deb441 Mon Sep 17 00:00:00 2001 From: Philippe Date: Thu, 4 Apr 2019 00:09:38 -0300 Subject: [PATCH 013/185] [BAEL-1219] OLingo2 code --- .../olingo2/CarsODataApplication.java | 24 -- .../olingo2/CarsODataJPAServiceFactory.java | 271 +++++++++++++++++- .../examples/olingo2/EntityManagerHolder.java | 18 ++ .../examples/olingo2/JerseyConfig.java | 82 +++++- .../olingo2/Olingo2SampleApplication.java | 7 +- .../examples/olingo2/domain/CarMaker.java | 7 +- .../examples/olingo2/domain/CarModel.java | 10 +- .../src/main/resources/application.yml | 1 + .../olingo2/src/main/resources/data.sql | 9 + .../src/test/resources/olingo2-queries.json | 256 +++++++++++++++++ 10 files changed, 641 insertions(+), 44 deletions(-) delete mode 100644 apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataApplication.java create mode 100644 apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/EntityManagerHolder.java create mode 100644 apache-olingo/olingo2/src/test/resources/olingo2-queries.json diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataApplication.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataApplication.java deleted file mode 100644 index c7e3878f44..0000000000 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataApplication.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.baeldung.examples.olingo2; - - -import java.util.Set; - -import javax.ws.rs.ApplicationPath; - -import org.apache.olingo.odata2.core.rest.ODataRootLocator; -import org.apache.olingo.odata2.core.rest.app.ODataApplication; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -@Component -public class CarsODataApplication extends ODataApplication { - - private static final Logger log = LoggerFactory.getLogger(CarsODataApplication.class); - - public CarsODataApplication() { - super(); - log.info("[I17] Creating CarsODataApplication..."); - } - -} diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java index 2d0ae14686..cf13bd0fc9 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java @@ -1,37 +1,292 @@ package org.baeldung.examples.olingo2; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityGraph; import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; +import javax.persistence.Persistence; +import javax.persistence.Query; +import javax.persistence.StoredProcedureQuery; +import javax.persistence.SynchronizationType; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaDelete; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.CriteriaUpdate; +import javax.persistence.metamodel.Metamodel; import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext; import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory; import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.orm.jpa.EntityManagerFactoryUtils; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.stereotype.Component; /** - * OData ServiceFactory that + * ODataJPAServiceFactory implementation for our sample domain * @author Philippe * */ @Component public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory { - private EntityManager em; private static final Logger log = LoggerFactory.getLogger(CarsODataJPAServiceFactory.class); - public CarsODataJPAServiceFactory(EntityManager em) { - this.em = em; + public CarsODataJPAServiceFactory() { + // Enable detailed error messages (useful for debugging) + setDetailErrors(true); } + + /** + * This method will be called by Olingo on every request to + * initialize the ODataJPAContext that will be used. + */ @Override public ODataJPAContext initializeODataJPAContext() throws ODataJPARuntimeException { - ODataJPAContext oDataJPAContext = getODataJPAContext(); - oDataJPAContext.setEntityManagerFactory(em.getEntityManagerFactory()); - oDataJPAContext.setPersistenceUnitName("default"); + log.info("[I32] >>> initializeODataJPAContext()"); + ODataJPAContext ctx = getODataJPAContext(); - return oDataJPAContext; + // Here we're passing the EM that was created by the EntityManagerFilter (see JerseyConfig) + ctx.setEntityManager(new EntityManagerWrapper(EntityManagerHolder.getCurrentEntityManager())); + ctx.setPersistenceUnitName("default"); + + // We're managing the EM's lifecycle, so we must inform Olingo that it should not + // try to manage transactions and/or persistence sessions + ctx.setContainerManaged(true); + + + return ctx; + + } + + static class EntityManagerWrapper implements EntityManager { + + private EntityManager delegate; + + public void persist(Object entity) { + log.info("[I68] persist: entity.class=" + entity.getClass().getSimpleName()); + delegate.persist(entity); + //delegate.flush(); + } + + public T merge(T entity) { + log.info("[I74] merge: entity.class=" + entity.getClass().getSimpleName()); + return delegate.merge(entity); + } + + public void remove(Object entity) { + log.info("[I78] remove: entity.class=" + entity.getClass().getSimpleName()); + delegate.remove(entity); + } + + public T find(Class entityClass, Object primaryKey) { + return delegate.find(entityClass, primaryKey); + } + + public T find(Class entityClass, Object primaryKey, Map properties) { + return delegate.find(entityClass, primaryKey, properties); + } + + public T find(Class entityClass, Object primaryKey, LockModeType lockMode) { + return delegate.find(entityClass, primaryKey, lockMode); + } + + public T find(Class entityClass, Object primaryKey, LockModeType lockMode, Map properties) { + return delegate.find(entityClass, primaryKey, lockMode, properties); + } + + public T getReference(Class entityClass, Object primaryKey) { + return delegate.getReference(entityClass, primaryKey); + } + + public void flush() { + delegate.flush(); + } + + public void setFlushMode(FlushModeType flushMode) { + delegate.setFlushMode(flushMode); + } + + public FlushModeType getFlushMode() { + return delegate.getFlushMode(); + } + + public void lock(Object entity, LockModeType lockMode) { + delegate.lock(entity, lockMode); + } + + public void lock(Object entity, LockModeType lockMode, Map properties) { + delegate.lock(entity, lockMode, properties); + } + + public void refresh(Object entity) { + delegate.refresh(entity); + } + + public void refresh(Object entity, Map properties) { + delegate.refresh(entity, properties); + } + + public void refresh(Object entity, LockModeType lockMode) { + delegate.refresh(entity, lockMode); + } + + public void refresh(Object entity, LockModeType lockMode, Map properties) { + delegate.refresh(entity, lockMode, properties); + } + + public void clear() { + delegate.clear(); + } + + public void detach(Object entity) { + delegate.detach(entity); + } + + public boolean contains(Object entity) { + return delegate.contains(entity); + } + + public LockModeType getLockMode(Object entity) { + return delegate.getLockMode(entity); + } + + public void setProperty(String propertyName, Object value) { + delegate.setProperty(propertyName, value); + } + + public Map getProperties() { + return delegate.getProperties(); + } + + public Query createQuery(String qlString) { + return delegate.createQuery(qlString); + } + + public TypedQuery createQuery(CriteriaQuery criteriaQuery) { + return delegate.createQuery(criteriaQuery); + } + + public Query createQuery(CriteriaUpdate updateQuery) { + return delegate.createQuery(updateQuery); + } + + public Query createQuery(CriteriaDelete deleteQuery) { + return delegate.createQuery(deleteQuery); + } + + public TypedQuery createQuery(String qlString, Class resultClass) { + return delegate.createQuery(qlString, resultClass); + } + + public Query createNamedQuery(String name) { + return delegate.createNamedQuery(name); + } + + public TypedQuery createNamedQuery(String name, Class resultClass) { + return delegate.createNamedQuery(name, resultClass); + } + + public Query createNativeQuery(String sqlString) { + return delegate.createNativeQuery(sqlString); + } + + public Query createNativeQuery(String sqlString, Class resultClass) { + return delegate.createNativeQuery(sqlString, resultClass); + } + + public Query createNativeQuery(String sqlString, String resultSetMapping) { + return delegate.createNativeQuery(sqlString, resultSetMapping); + } + + public StoredProcedureQuery createNamedStoredProcedureQuery(String name) { + return delegate.createNamedStoredProcedureQuery(name); + } + + public StoredProcedureQuery createStoredProcedureQuery(String procedureName) { + return delegate.createStoredProcedureQuery(procedureName); + } + + public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) { + return delegate.createStoredProcedureQuery(procedureName, resultClasses); + } + + public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings) { + return delegate.createStoredProcedureQuery(procedureName, resultSetMappings); + } + + public void joinTransaction() { + delegate.joinTransaction(); + } + + public boolean isJoinedToTransaction() { + return delegate.isJoinedToTransaction(); + } + + public T unwrap(Class cls) { + return delegate.unwrap(cls); + } + + public Object getDelegate() { + return delegate.getDelegate(); + } + + public void close() { + log.info("[I229] close"); + delegate.close(); + } + + public boolean isOpen() { + boolean isOpen = delegate.isOpen(); + log.info("[I236] isOpen: " + isOpen); + return isOpen; + } + + public EntityTransaction getTransaction() { + log.info("[I240] getTransaction()"); + return delegate.getTransaction(); + } + + public EntityManagerFactory getEntityManagerFactory() { + return delegate.getEntityManagerFactory(); + } + + public CriteriaBuilder getCriteriaBuilder() { + return delegate.getCriteriaBuilder(); + } + + public Metamodel getMetamodel() { + return delegate.getMetamodel(); + } + + public EntityGraph createEntityGraph(Class rootType) { + return delegate.createEntityGraph(rootType); + } + + public EntityGraph createEntityGraph(String graphName) { + return delegate.createEntityGraph(graphName); + } + + public EntityGraph getEntityGraph(String graphName) { + return delegate.getEntityGraph(graphName); + } + + public List> getEntityGraphs(Class entityClass) { + return delegate.getEntityGraphs(entityClass); + } + + public EntityManagerWrapper(EntityManager delegate) { + this.delegate = delegate; + } } diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/EntityManagerHolder.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/EntityManagerHolder.java new file mode 100644 index 0000000000..682621eb99 --- /dev/null +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/EntityManagerHolder.java @@ -0,0 +1,18 @@ +package org.baeldung.examples.olingo2; + +import javax.persistence.EntityManager; + +public class EntityManagerHolder { + + private static ThreadLocal currentEntityManager = new ThreadLocal<>(); + + + public static void setCurrentEntityManager(EntityManager em) { + currentEntityManager.set(em); + } + + public static EntityManager getCurrentEntityManager() { + return currentEntityManager.get(); + } + +} diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java index 33db629318..a82220e854 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java @@ -1,41 +1,111 @@ package org.baeldung.examples.olingo2; +import java.io.IOException; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; import javax.servlet.ServletContext; import javax.ws.rs.ApplicationPath; import javax.ws.rs.Path; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.ext.Provider; import org.apache.olingo.odata2.api.ODataServiceFactory; import org.apache.olingo.odata2.core.rest.ODataRootLocator; +import org.apache.olingo.odata2.core.rest.app.ODataApplication; import org.glassfish.jersey.server.ResourceConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; +/** + * Jersey JAX-RS configuration + * @author Philippe + * + */ @Component @ApplicationPath("/odata") public class JerseyConfig extends ResourceConfig { - public JerseyConfig(CarsODataApplication delegate,ServletContext servletContext,CarsODataJPAServiceFactory serviceFactory) { + public JerseyConfig(CarsODataJPAServiceFactory serviceFactory, EntityManagerFactory emf) { - delegate + ODataApplication app = new ODataApplication(); + + app .getClasses() .forEach( c -> { - // Avoid using the default Locator + // Avoid using the default RootLocator, as we want + // a Spring Managed one if ( !ODataRootLocator.class.isAssignableFrom(c)) { register(c); } }); - register(new CustomLocator(serviceFactory)); + register(new CarsRootLocator(serviceFactory)); + register( new EntityManagerFilter(emf)); + } + + /** + * This filter handles the EntityManager transaction lifecycle. + * @author Philippe + * + */ + @Provider + public static class EntityManagerFilter implements ContainerRequestFilter, ContainerResponseFilter { + + private static final Logger log = LoggerFactory.getLogger(EntityManagerFilter.class); + + private final EntityManagerFactory emf; + + public EntityManagerFilter(EntityManagerFactory emf) { + this.emf = emf; + } + + @Override + public void filter(ContainerRequestContext ctx) throws IOException { + log.info("[I60] >>> filter"); + EntityManager em = this.emf.createEntityManager(); + EntityManagerHolder.setCurrentEntityManager(em); + + // Start a new transaction unless we have a simple GET + if ( !"GET".equalsIgnoreCase(ctx.getMethod())) { + em.getTransaction().begin(); + } + } + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { + + log.info("[I68] <<< filter"); + + EntityManager em = EntityManagerHolder.getCurrentEntityManager(); + if ( em != null && !"GET".equalsIgnoreCase(requestContext.getMethod())) { + EntityTransaction t = em.getTransaction(); + if ( t.isActive()) { + if ( !t.getRollbackOnly()) { + t.commit(); + } + } + } + + em.close(); + + } } @Path("/") - public static class CustomLocator extends ODataRootLocator { + public static class CarsRootLocator extends ODataRootLocator { private CarsODataJPAServiceFactory serviceFactory; - public CustomLocator(CarsODataJPAServiceFactory serviceFactory) { + public CarsRootLocator(CarsODataJPAServiceFactory serviceFactory) { this.serviceFactory = serviceFactory; } diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/Olingo2SampleApplication.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/Olingo2SampleApplication.java index 6cc4a45927..fa58612088 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/Olingo2SampleApplication.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/Olingo2SampleApplication.java @@ -1,5 +1,6 @@ package org.baeldung.examples.olingo2; +import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @@ -7,9 +8,7 @@ import org.springframework.boot.web.servlet.support.SpringBootServletInitializer @SpringBootApplication public class Olingo2SampleApplication extends SpringBootServletInitializer { - public static void main(String[] args) { - new Olingo2SampleApplication() - .configure(new SpringApplicationBuilder(Olingo2SampleApplication.class)) - .run(args); + public static void main(String[] args) { + SpringApplication.run(Olingo2SampleApplication.class); } } diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java index 1817a2dece..42a3eaa59d 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java @@ -5,6 +5,8 @@ import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @@ -18,13 +20,16 @@ import lombok.Data; public class CarMaker { @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) private Long id; @NotNull @Column(name="name") private String name; - @OneToMany(mappedBy="maker",cascade=CascadeType.ALL) + @OneToMany(mappedBy="maker", + orphanRemoval = true, + cascade=CascadeType.ALL) private List models; diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java index 285e5ce379..a4f2a04f6e 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java @@ -2,17 +2,24 @@ package org.baeldung.examples.olingo2.domain; import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.Table; import javax.validation.constraints.NotNull; import lombok.Data; @Entity @Data +@Table(name="car_model") public class CarModel { @Id + @GeneratedValue(strategy=GenerationType.AUTO) private Long id; @NotNull @@ -24,7 +31,8 @@ public class CarModel { @NotNull private String sku; - @ManyToOne + @ManyToOne(optional=false, fetch= FetchType.LAZY) + @JoinColumn(name="maker_fk") private CarMaker maker; } diff --git a/apache-olingo/olingo2/src/main/resources/application.yml b/apache-olingo/olingo2/src/main/resources/application.yml index 2af431eee1..a29b572575 100644 --- a/apache-olingo/olingo2/src/main/resources/application.yml +++ b/apache-olingo/olingo2/src/main/resources/application.yml @@ -5,5 +5,6 @@ spring: jpa: show-sql: true + open-in-view: false hibernate: ddl-auto: update \ No newline at end of file diff --git a/apache-olingo/olingo2/src/main/resources/data.sql b/apache-olingo/olingo2/src/main/resources/data.sql index c1d32dc6ef..327f2688c5 100644 --- a/apache-olingo/olingo2/src/main/resources/data.sql +++ b/apache-olingo/olingo2/src/main/resources/data.sql @@ -1,3 +1,12 @@ insert into car_maker(id,name) values (1,'Special Motors'); insert into car_maker(id,name) values (2,'BWM'); insert into car_maker(id,name) values (3,'Dolores'); + +insert into car_model(id,maker_fk,name,sku,year) values(1,1,'Muze','SM001',2018); +insert into car_model(id,maker_fk,name,sku,year) values(2,1,'Empada','SM002',2008); + +insert into car_model(id,maker_fk,name,sku,year) values(4,2,'BWM-100','BWM100',2008); +insert into car_model(id,maker_fk,name,sku,year) values(5,2,'BWM-200','BWM200',2009); +insert into car_model(id,maker_fk,name,sku,year) values(6,2,'BWM-300','BWM300',2008); + +alter sequence hibernate_sequence restart with 100; \ No newline at end of file diff --git a/apache-olingo/olingo2/src/test/resources/olingo2-queries.json b/apache-olingo/olingo2/src/test/resources/olingo2-queries.json new file mode 100644 index 0000000000..9fdade6d10 --- /dev/null +++ b/apache-olingo/olingo2/src/test/resources/olingo2-queries.json @@ -0,0 +1,256 @@ +{ + "info": { + "_postman_id": "afa8e1e5-ab0e-4f1d-8b99-b7d1f091f975", + "name": "OLingo2 - Cars", + "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json" + }, + "item": [ + { + "name": "GET Metadata", + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": "http://localhost:8080/odata/$metadata" + }, + "response": [] + }, + { + "name": "GET All CarMakers", + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": "http://localhost:8080/odata/CarMakers" + }, + "response": [] + }, + { + "name": "GET Makers with Pagination", + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "http://localhost:8080/odata/CarMakers?$top=1&$orderby=Name&$skip=3", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "odata", + "CarMakers" + ], + "query": [ + { + "key": "$top", + "value": "1" + }, + { + "key": "$orderby", + "value": "Name" + }, + { + "key": "$skip", + "value": "3" + } + ] + } + }, + "response": [] + }, + { + "name": "GET Makers and Models", + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "http://localhost:8080/odata/CarMakers?$expand=CarModelDetails", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "odata", + "CarMakers" + ], + "query": [ + { + "key": "$expand", + "value": "CarModelDetails" + } + ] + } + }, + "response": [] + }, + { + "name": "GET Makers with filter", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": { + "raw": "http://localhost:8080/odata/CarMakers?$filter=Name eq 'BWM'&$expand=CarModelDetails", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "odata", + "CarMakers" + ], + "query": [ + { + "key": "$filter", + "value": "Name eq 'BWM'" + }, + { + "key": "$expand", + "value": "CarModelDetails" + } + ] + } + }, + "response": [] + }, + { + "name": "Create CarMaker", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/atom+xml", + "type": "text" + }, + { + "key": "Accept", + "value": "application/atom+xml", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": " \r\n\r\n \r\n 2019-04-02T21:36:47Z\r\n \r\n \r\n \r\n \r\n \r\n \r\n Lucien\r\n \r\n \r\n" + }, + "url": "http://localhost:8080/odata/CarMakers" + }, + "response": [] + }, + { + "name": "Create CarModel", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/atom+xml" + }, + { + "key": "Accept", + "type": "text", + "value": "application/atom+xml" + } + ], + "body": { + "mode": "raw", + "raw": " \r\n\r\n \r\n 2019-04-02T21:36:47Z\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n\t Tata\r\n\t TT101\r\n\t 2018\r\n \r\n \r\n" + }, + "url": "http://localhost:8080/odata/CarModels" + }, + "response": [] + }, + { + "name": "Update CarMaker", + "request": { + "method": "PUT", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/atom+xml" + }, + { + "key": "Accept", + "type": "text", + "value": "application/atom+xml" + } + ], + "body": { + "mode": "raw", + "raw": " \r\n\r\n \r\n 2019-04-02T21:36:47Z\r\n \r\n \r\n \r\n \r\n \r\n \r\n 5\r\n KaiserWagen\r\n \r\n \r\n" + }, + "url": "http://localhost:8080/odata/CarMakers(5L)" + }, + "response": [] + }, + { + "name": "All CarModels", + "request": { + "method": "GET", + "header": [], + "body": { + "mode": "raw", + "raw": "" + }, + "url": "http://localhost:8080/odata/CarModels" + }, + "response": [] + }, + { + "name": "Delete CarModel", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "type": "text", + "value": "application/atom+xml" + }, + { + "key": "Accept", + "type": "text", + "value": "application/atom+xml" + } + ], + "body": { + "mode": "raw", + "raw": "" + }, + "url": "http://localhost:8080/odata/CarModels(100L)" + }, + "response": [] + } + ] +} \ No newline at end of file From f5ac80e332dca0488c81bf7ee86fce2114aaa068 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Sun, 7 Apr 2019 22:42:15 +1000 Subject: [PATCH 014/185] BAEL-2569 move code to spring-boot-ops module --- .../PriceCalculationApplication.java | 2 +- .../PriceCalculationEnvironmentPostProcessor.java | 0 .../autoconfig/PriceCalculationAutoConfig.java | 0 .../calculator/GrossPriceCalculator.java | 0 .../calculator/NetPriceCalculator.java | 0 .../calculator/PriceCalculator.java | 0 .../service/PriceCalculationService.java | 0 .../src/main/resources/META-INF/spring.factories | 6 ++++++ .../PriceCalculationEnvironmentPostProcessorLiveTest.java | 0 spring-boot/src/main/resources/META-INF/spring.factories | 5 ----- 10 files changed, 7 insertions(+), 6 deletions(-) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java (96%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java (100%) rename {spring-boot => spring-boot-ops}/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java (100%) create mode 100644 spring-boot-ops/src/main/resources/META-INF/spring.factories rename {spring-boot => spring-boot-ops}/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java (100%) diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java similarity index 96% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java index 01be08d6ae..ed912d8c0a 100644 --- a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java +++ b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationApplication.java @@ -35,7 +35,7 @@ public class PriceCalculationApplication implements CommandLineRunner { int quantity = Integer.valueOf(params.get(1)); priceCalculationService.productTotalPrice(singlePrice, quantity); } else { - logger.error("Invalid arguments " + params.toString()); + logger.warn("Invalid arguments " + params.toString()); } } diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessor.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/autoconfig/PriceCalculationAutoConfig.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/GrossPriceCalculator.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/NetPriceCalculator.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/calculator/PriceCalculator.java diff --git a/spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java b/spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java similarity index 100% rename from spring-boot/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java rename to spring-boot-ops/src/main/java/com/baeldung/environmentpostprocessor/service/PriceCalculationService.java diff --git a/spring-boot-ops/src/main/resources/META-INF/spring.factories b/spring-boot-ops/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..c36b67f8d7 --- /dev/null +++ b/spring-boot-ops/src/main/resources/META-INF/spring.factories @@ -0,0 +1,6 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig + +org.springframework.boot.env.EnvironmentPostProcessor=\ +com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor + diff --git a/spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java b/spring-boot-ops/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java similarity index 100% rename from spring-boot/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java rename to spring-boot-ops/src/test/java/com/baeldung/environmentpostprocessor/PriceCalculationEnvironmentPostProcessorLiveTest.java diff --git a/spring-boot/src/main/resources/META-INF/spring.factories b/spring-boot/src/main/resources/META-INF/spring.factories index d8a01bbf82..336477df96 100644 --- a/spring-boot/src/main/resources/META-INF/spring.factories +++ b/spring-boot/src/main/resources/META-INF/spring.factories @@ -1,7 +1,2 @@ org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -com.baeldung.environmentpostprocessor.autoconfig.PriceCalculationAutoConfig - -org.springframework.boot.env.EnvironmentPostProcessor=\ -com.baeldung.environmentpostprocessor.PriceCalculationEnvironmentPostProcessor From 6ac9c01d3d996ec716e4386b945815acdcbe3b4c Mon Sep 17 00:00:00 2001 From: Philippe Date: Mon, 8 Apr 2019 10:23:31 -0300 Subject: [PATCH 015/185] Initial import --- .../olingo2/CarsODataJPAServiceFactory.java | 39 +-- .../examples/olingo2/EntityManagerHolder.java | 18 -- .../examples/olingo2/JerseyConfig.java | 40 +-- .../src/main/resources/application.yml | 4 +- apache-olingo/olingo4/.gitignore | 29 +++ apache-olingo/olingo4/pom.xml | 95 +++++++ .../examples/olingo4/DefaultODataFactory.java | 20 ++ .../examples/olingo4/ODataFactory.java | 8 + .../olingo4/ODataHttpHandlerFactory.java | 8 + .../olingo4/ODataHttpHandlerFactoryImpl.java | 42 ++++ .../olingo4/ODataServiceConfiguration.java | 46 ++++ .../examples/olingo4/ODataServlet.java | 38 +++ .../olingo4/Olingo4SampleApplication.java | 13 + .../examples/olingo4/domain/CarMaker.java | 36 +++ .../examples/olingo4/domain/CarModel.java | 38 +++ .../examples/olingo4/edm/EdmTypeMapper.java | 46 ++++ .../examples/olingo4/edm/JpaEdmProvider.java | 237 ++++++++++++++++++ .../JpaEntityCollectionProcessor.java | 185 ++++++++++++++ .../repository/CarMakerRepository.java | 12 + .../repository/CarModelRepository.java | 13 + .../repository/EdmEntityRepository.java | 15 ++ .../repository/RepositoryRegistry.java | 28 +++ .../src/main/resources/application.properties | 6 + .../olingo4/src/main/resources/data.sql | 12 + .../Olingo4SampleApplicationTests.java | 16 ++ 25 files changed, 991 insertions(+), 53 deletions(-) delete mode 100644 apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/EntityManagerHolder.java create mode 100644 apache-olingo/olingo4/.gitignore create mode 100644 apache-olingo/olingo4/pom.xml create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java create mode 100644 apache-olingo/olingo4/src/main/resources/application.properties create mode 100644 apache-olingo/olingo4/src/main/resources/data.sql create mode 100644 apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java index cf13bd0fc9..65a0428154 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/CarsODataJPAServiceFactory.java @@ -19,10 +19,13 @@ import javax.persistence.criteria.CriteriaDelete; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaUpdate; import javax.persistence.metamodel.Metamodel; +import javax.servlet.http.HttpServletRequest; +import org.apache.olingo.odata2.api.processor.ODataContext; import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext; import org.apache.olingo.odata2.jpa.processor.api.ODataJPAServiceFactory; import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException; +import org.baeldung.examples.olingo2.JerseyConfig.EntityManagerFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.orm.jpa.EntityManagerFactoryUtils; @@ -36,15 +39,14 @@ import org.springframework.stereotype.Component; */ @Component public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory { - + private static final Logger log = LoggerFactory.getLogger(CarsODataJPAServiceFactory.class); - + public CarsODataJPAServiceFactory() { // Enable detailed error messages (useful for debugging) setDetailErrors(true); } - /** * This method will be called by Olingo on every request to * initialize the ODataJPAContext that will be used. @@ -54,37 +56,40 @@ public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory { log.info("[I32] >>> initializeODataJPAContext()"); ODataJPAContext ctx = getODataJPAContext(); - + ODataContext octx = ctx.getODataContext(); + HttpServletRequest request = (HttpServletRequest)octx.getParameter(ODataContext.HTTP_SERVLET_REQUEST_OBJECT); + EntityManager em = (EntityManager)request.getAttribute(EntityManagerFilter.EM_REQUEST_ATTRIBUTE); + // Here we're passing the EM that was created by the EntityManagerFilter (see JerseyConfig) - ctx.setEntityManager(new EntityManagerWrapper(EntityManagerHolder.getCurrentEntityManager())); + ctx.setEntityManager(new EntityManagerWrapper(em)); ctx.setPersistenceUnitName("default"); // We're managing the EM's lifecycle, so we must inform Olingo that it should not // try to manage transactions and/or persistence sessions - ctx.setContainerManaged(true); - - + ctx.setContainerManaged(true); return ctx; - } - + static class EntityManagerWrapper implements EntityManager { - + private EntityManager delegate; - + public void persist(Object entity) { - log.info("[I68] persist: entity.class=" + entity.getClass().getSimpleName()); + log.info("[I68] persist: entity.class=" + entity.getClass() + .getSimpleName()); delegate.persist(entity); - //delegate.flush(); + // delegate.flush(); } public T merge(T entity) { - log.info("[I74] merge: entity.class=" + entity.getClass().getSimpleName()); + log.info("[I74] merge: entity.class=" + entity.getClass() + .getSimpleName()); return delegate.merge(entity); } public void remove(Object entity) { - log.info("[I78] remove: entity.class=" + entity.getClass().getSimpleName()); + log.info("[I78] remove: entity.class=" + entity.getClass() + .getSimpleName()); delegate.remove(entity); } @@ -287,7 +292,7 @@ public class CarsODataJPAServiceFactory extends ODataJPAServiceFactory { public EntityManagerWrapper(EntityManager delegate) { this.delegate = delegate; } - + } } diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/EntityManagerHolder.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/EntityManagerHolder.java deleted file mode 100644 index 682621eb99..0000000000 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/EntityManagerHolder.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.baeldung.examples.olingo2; - -import javax.persistence.EntityManager; - -public class EntityManagerHolder { - - private static ThreadLocal currentEntityManager = new ThreadLocal<>(); - - - public static void setCurrentEntityManager(EntityManager em) { - currentEntityManager.set(em); - } - - public static EntityManager getCurrentEntityManager() { - return currentEntityManager.get(); - } - -} diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java index a82220e854..78caf99861 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/JerseyConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.examples.olingo2; + package org.baeldung.examples.olingo2; import java.io.IOException; @@ -6,12 +6,14 @@ import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; import javax.ws.rs.ApplicationPath; import javax.ws.rs.Path; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.Context; import javax.ws.rs.ext.Provider; import org.apache.olingo.odata2.api.ODataServiceFactory; @@ -57,11 +59,15 @@ public class JerseyConfig extends ResourceConfig { */ @Provider public static class EntityManagerFilter implements ContainerRequestFilter, ContainerResponseFilter { - + private static final Logger log = LoggerFactory.getLogger(EntityManagerFilter.class); - + public static final String EM_REQUEST_ATTRIBUTE = EntityManagerFilter.class.getName() + "_ENTITY_MANAGER"; + private final EntityManagerFactory emf; + @Context + private HttpServletRequest httpRequest; + public EntityManagerFilter(EntityManagerFactory emf) { this.emf = emf; } @@ -70,11 +76,12 @@ public class JerseyConfig extends ResourceConfig { public void filter(ContainerRequestContext ctx) throws IOException { log.info("[I60] >>> filter"); EntityManager em = this.emf.createEntityManager(); - EntityManagerHolder.setCurrentEntityManager(em); - + httpRequest.setAttribute(EM_REQUEST_ATTRIBUTE, em); + // Start a new transaction unless we have a simple GET - if ( !"GET".equalsIgnoreCase(ctx.getMethod())) { - em.getTransaction().begin(); + if (!"GET".equalsIgnoreCase(ctx.getMethod())) { + em.getTransaction() + .begin(); } } @@ -82,24 +89,23 @@ public class JerseyConfig extends ResourceConfig { public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { log.info("[I68] <<< filter"); + EntityManager em = (EntityManager) httpRequest.getAttribute(EM_REQUEST_ATTRIBUTE); - EntityManager em = EntityManagerHolder.getCurrentEntityManager(); - if ( em != null && !"GET".equalsIgnoreCase(requestContext.getMethod())) { + if (!"GET".equalsIgnoreCase(requestContext.getMethod())) { EntityTransaction t = em.getTransaction(); - if ( t.isActive()) { - if ( !t.getRollbackOnly()) { + if (t.isActive()) { + if (!t.getRollbackOnly()) { t.commit(); } } } - + em.close(); - + } - + } - - + @Path("/") public static class CarsRootLocator extends ODataRootLocator { @@ -113,7 +119,7 @@ public class JerseyConfig extends ResourceConfig { public ODataServiceFactory getServiceFactory() { return this.serviceFactory; } - + } } diff --git a/apache-olingo/olingo2/src/main/resources/application.yml b/apache-olingo/olingo2/src/main/resources/application.yml index a29b572575..21563a94fe 100644 --- a/apache-olingo/olingo2/src/main/resources/application.yml +++ b/apache-olingo/olingo2/src/main/resources/application.yml @@ -1,4 +1,6 @@ - +server: + port: 8180 + spring: jersey: application-path: /odata diff --git a/apache-olingo/olingo4/.gitignore b/apache-olingo/olingo4/.gitignore new file mode 100644 index 0000000000..153c9335eb --- /dev/null +++ b/apache-olingo/olingo4/.gitignore @@ -0,0 +1,29 @@ +HELP.md +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +/build/ + +### VS Code ### +.vscode/ diff --git a/apache-olingo/olingo4/pom.xml b/apache-olingo/olingo4/pom.xml new file mode 100644 index 0000000000..a6f1fcdb7b --- /dev/null +++ b/apache-olingo/olingo4/pom.xml @@ -0,0 +1,95 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + org.baeldung.examples.olingo4 + olingo4-sample + 0.0.1-SNAPSHOT + olingo4-sample + Sample Olingo 4 Project + + + 1.8 + 4.5.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + com.h2database + h2 + runtime + + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + + org.apache.olingo + odata-server-api + ${odata.version} + + + org.apache.olingo + odata-server-core + ${odata.version} + runtime + + + + org.apache.olingo + odata-commons-api + ${odata.version} + + + org.apache.olingo + odata-commons-core + ${odata.version} + + + + commons-beanutils + commons-beanutils + 1.9.3 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java new file mode 100644 index 0000000000..18f7f8ba24 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java @@ -0,0 +1,20 @@ +package org.baeldung.examples.olingo4; + +import org.apache.olingo.server.api.OData; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.stereotype.Component; + +/** + * Default implementation for ODataFactory + * @author Philippe + * + */ +@Component +public class DefaultODataFactory implements ODataFactory { + + @Override + public OData newInstance() { + return OData.newInstance(); + } + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java new file mode 100644 index 0000000000..9acb4b8c5e --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java @@ -0,0 +1,8 @@ +package org.baeldung.examples.olingo4; + +import org.apache.olingo.server.api.OData; + +public interface ODataFactory { + + public OData newInstance(); +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java new file mode 100644 index 0000000000..27d0737c24 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java @@ -0,0 +1,8 @@ +package org.baeldung.examples.olingo4; + +import org.apache.olingo.server.api.ODataHttpHandler; + +public interface ODataHttpHandlerFactory { + + ODataHttpHandler newInstance(); +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java new file mode 100644 index 0000000000..68d39dc052 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java @@ -0,0 +1,42 @@ +package org.baeldung.examples.olingo4; + +import java.util.Collections; +import java.util.List; + +import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataHttpHandler; +import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.processor.Processor; + +import lombok.Builder; + +@Builder +public class ODataHttpHandlerFactoryImpl implements ODataHttpHandlerFactory { + + + private final ODataFactory odataFactory; + private final CsdlEdmProvider edmProvider; + private final List processors; + + public ODataHttpHandlerFactoryImpl(ODataFactory odataFactory,CsdlEdmProvider edmProvider, List processors) { + this.odataFactory = odataFactory; + this.edmProvider = edmProvider; + this.processors = processors; + } + + @Override + public ODataHttpHandler newInstance() { + + OData odata = odataFactory.newInstance(); + ServiceMetadata metadata = odata.createServiceMetadata(edmProvider, Collections.emptyList()); + ODataHttpHandler handler = odata.createHandler(metadata); + + // Register all available processors + processors.forEach(p -> handler.register(p)); + + + return handler; + } + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java new file mode 100644 index 0000000000..bbac0ceac7 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java @@ -0,0 +1,46 @@ +package org.baeldung.examples.olingo4; + +import java.util.List; + +import javax.persistence.EntityManagerFactory; +import javax.servlet.http.HttpServlet; + +import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider; +import org.apache.olingo.server.api.processor.Processor; +import org.baeldung.examples.olingo4.ODataHttpHandlerFactoryImpl.ODataHttpHandlerFactoryImplBuilder; +import org.springframework.boot.web.servlet.ServletRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ODataServiceConfiguration { + + + @Bean + public ServletRegistrationBean odataServletRegistration(ODataHttpHandlerFactory factory, EntityManagerFactory emf) { + + ServletRegistrationBean bean = new ServletRegistrationBean( + odataServlet(factory,emf), + "/odata/*"); + bean.setLoadOnStartup(1); + return bean; + } + + + @Bean + public HttpServlet odataServlet(ODataHttpHandlerFactory factory, EntityManagerFactory emf ) { + + return new ODataServlet(factory,emf); + } + + + @Bean + public ODataHttpHandlerFactory httpHandlerFactory(CsdlEdmProvider edmProvider, ODataFactory odataFactory, List processors) { + return new ODataHttpHandlerFactoryImplBuilder() + .edmProvider(edmProvider) + .odataFactory(odataFactory) + .processors(processors) + .build(); + } + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java new file mode 100644 index 0000000000..c2adf2c1ae --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java @@ -0,0 +1,38 @@ +/** + * + */ +package org.baeldung.examples.olingo4; + +import java.io.IOException; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityTransaction; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.olingo.server.api.ODataHttpHandler; + +/** + * @author Philippe + * + */ +public class ODataServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + private final ODataHttpHandlerFactory odataHttpHandlerFactory; + + + public ODataServlet(ODataHttpHandlerFactory factory, EntityManagerFactory emf) { + this.odataHttpHandlerFactory = factory; + } + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + ODataHttpHandler handler = odataHttpHandlerFactory.newInstance(); + handler.process(req, resp); + } +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java new file mode 100644 index 0000000000..1ac872ea0f --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java @@ -0,0 +1,13 @@ +package org.baeldung.examples.olingo4; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Olingo4SampleApplication { + + public static void main(String[] args) { + SpringApplication.run(Olingo4SampleApplication.class, args); + } + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java new file mode 100644 index 0000000000..79825b4556 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java @@ -0,0 +1,36 @@ +package org.baeldung.examples.olingo4.domain; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; + +import lombok.Data; + +@Entity +@Data +@Table(name="car_maker") +public class CarMaker { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + private Long id; + + @NotNull + @Column(name="name") + private String name; + + @OneToMany(mappedBy="maker", + orphanRemoval = true, + cascade=CascadeType.ALL) + private List models; + + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java new file mode 100644 index 0000000000..e6cd80ebf1 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java @@ -0,0 +1,38 @@ +package org.baeldung.examples.olingo4.domain; + + +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; + +import lombok.Data; + +@Entity +@Data +@Table(name="car_model") +public class CarModel { + + @Id + @GeneratedValue(strategy=GenerationType.AUTO) + private Long id; + + @NotNull + private String name; + + @NotNull + private Integer year; + + @NotNull + private String sku; + + @ManyToOne(optional=false, fetch= FetchType.LAZY) + @JoinColumn(name="maker_fk") + private CarMaker maker; + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java new file mode 100644 index 0000000000..95797752a2 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java @@ -0,0 +1,46 @@ +package org.baeldung.examples.olingo4.edm; + +import java.util.Collections; +import java.util.Date; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.sql.Time; +import java.util.AbstractMap.SimpleEntry; + +import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; +import org.springframework.stereotype.Component; + +@Component +public class EdmTypeMapper { + + public EdmPrimitiveTypeKind java2edm(Class clazz) { + EdmPrimitiveTypeKind result = java2edm.get(clazz); + if ( result == null ) { + throw new IllegalArgumentException("[E19] Unsupported class mapping: class=" + clazz); + } + else { + return result; + } + } + + // Static map used generate attribute metadada based on Java types + static Map,EdmPrimitiveTypeKind> java2edm = Collections + .unmodifiableMap(Stream.of( + new SimpleEntry<>(Boolean.class,EdmPrimitiveTypeKind.Boolean), + new SimpleEntry<>(Byte.class,EdmPrimitiveTypeKind.SByte), + new SimpleEntry<>(Date.class,EdmPrimitiveTypeKind.Date), + new SimpleEntry<>(Time.class,EdmPrimitiveTypeKind.TimeOfDay), + new SimpleEntry<>(Number.class,EdmPrimitiveTypeKind.Decimal), + new SimpleEntry<>(Float.class,EdmPrimitiveTypeKind.Single), + new SimpleEntry<>(Double.class,EdmPrimitiveTypeKind.Double), + new SimpleEntry<>(UUID.class,EdmPrimitiveTypeKind.Guid), + new SimpleEntry<>(Short.class,EdmPrimitiveTypeKind.Int16), + new SimpleEntry<>(Integer.class,EdmPrimitiveTypeKind.Int32), + new SimpleEntry<>(Long.class,EdmPrimitiveTypeKind.Int64), + new SimpleEntry<>(String.class,EdmPrimitiveTypeKind.String) + + ).collect(Collectors.toMap((e)-> e.getKey(),(e)-> e.getValue()))); + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java new file mode 100644 index 0000000000..3e490cdf58 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java @@ -0,0 +1,237 @@ +package org.baeldung.examples.olingo4.edm; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.metamodel.Attribute.PersistentAttributeType; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.Metamodel; +import javax.persistence.metamodel.PluralAttribute; +import javax.persistence.metamodel.SingularAttribute; + +import org.apache.olingo.commons.api.edm.FullQualifiedName; +import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo; +import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet; +import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; +import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty; +import org.apache.olingo.commons.api.edm.provider.CsdlProperty; +import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef; +import org.apache.olingo.commons.api.edm.provider.CsdlSchema; +import org.apache.olingo.commons.api.ex.ODataException; +import org.springframework.stereotype.Component; + +@Component +public class JpaEdmProvider extends CsdlAbstractEdmProvider { + + EntityManagerFactory emf; + + // + private EdmTypeMapper typeMapper; + + // Service Namespace + public static final String NAMESPACE = "OData.Demo"; + + // EDM Container + public static final String CONTAINER_NAME = "Cars"; + public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME); + + public JpaEdmProvider(EntityManagerFactory emf, EdmTypeMapper mapper) { + this.emf = emf; + this.typeMapper = mapper; + } + + /* (non-Javadoc) + * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntitySet(org.apache.olingo.commons.api.edm.FullQualifiedName, java.lang.String) + */ + @Override + public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException { + + if (entityContainer.equals(CONTAINER)) { + + EntityType e = emf.getMetamodel() + .getEntities() + .stream() + .filter((ent) -> (ent.getName() + "s") + .equals(entitySetName)) + .findFirst() + .orElse(null); + + if (e != null) { + CsdlEntitySet entitySet = new CsdlEntitySet(); + entitySet.setName(entitySetName); + entitySet.setType(new FullQualifiedName(NAMESPACE, e.getName())); + return entitySet; + } + } + + return null; + } + + /* (non-Javadoc) + * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainerInfo(org.apache.olingo.commons.api.edm.FullQualifiedName) + */ + @Override + public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException { + + // This method is invoked when displaying the Service Document at e.g. http://localhost:8080/DemoService/DemoService.svc + if (entityContainerName == null || entityContainerName.equals(CONTAINER)) { + CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo(); + entityContainerInfo.setContainerName(CONTAINER); + return entityContainerInfo; + } + + return null; + } + + /* (non-Javadoc) + * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getSchemas() + */ + @Override + public List getSchemas() throws ODataException { + // create Schema + CsdlSchema schema = new CsdlSchema(); + schema.setNamespace(NAMESPACE); + + // add EntityTypes + List entityTypes = emf.getMetamodel() + .getEntities() + .stream() + .map((e) -> { + try { + return getEntityType(new FullQualifiedName(NAMESPACE, e.getName())); + } catch (ODataException oe) { + throw new RuntimeException(oe); + } + }) + .collect(Collectors.toList()); + + schema.setEntityTypes(entityTypes); + + // add EntityContainer + schema.setEntityContainer(getEntityContainer()); + + // finally + List schemas = new ArrayList(); + schemas.add(schema); + + return schemas; + } + + /* (non-Javadoc) + * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainer() + */ + @Override + public CsdlEntityContainer getEntityContainer() throws ODataException { + + + // add EntityTypes + List entitySets = emf.getMetamodel() + .getEntities() + .stream() + .map((e) -> { + try { + // Here we use a simple mapping strategy to map entity types to entity set names: + // + return getEntitySet(CONTAINER, e.getName() + "s"); + } catch (ODataException oe) { + throw new RuntimeException(oe); + } + }) + .collect(Collectors.toList()); + + // create EntityContainer + CsdlEntityContainer entityContainer = new CsdlEntityContainer(); + entityContainer.setName(CONTAINER_NAME); + entityContainer.setEntitySets(entitySets); + + return entityContainer; + } + + @Override + public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException { + + Metamodel mm = emf.getMetamodel(); + + CsdlEntityType result = null; + + result = mm.getEntities() + .stream() + .filter(et -> entityTypeName.equals(new FullQualifiedName(NAMESPACE, et.getName()))) + .map(et -> buildODataType(et)) + .findFirst() + .orElse(null); + + return result; + + } + + /** + * Maps a JPA type to its OData counterpart. + * @param et + * @return + */ + protected CsdlEntityType buildODataType(EntityType et) { + + CsdlEntityType result = new CsdlEntityType(); + result.setName(et.getName()); + + // Process simple properties + List properties = et.getDeclaredSingularAttributes() + .stream() + .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC) + .map(attr -> buildBasicAttribute(et, attr)) + .collect(Collectors.toList()); + + result.setProperties(properties); + + // Process Ids + List ids = et.getDeclaredSingularAttributes() + .stream() + .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC && attr.isId()) + .map(attr -> buildRefAttribute(et, attr)) + .collect(Collectors.toList()); + + result.setKey(ids); + + // Process navs + List navs = et.getDeclaredPluralAttributes() + .stream() + .map(attr -> buildNavAttribute(et, attr)) + .collect(Collectors.toList()); + result.setNavigationProperties(navs); + + return result; + } + + private CsdlProperty buildBasicAttribute(EntityType et, SingularAttribute attr) { + + CsdlProperty p = new CsdlProperty().setName(attr.getName()) + .setType(typeMapper.java2edm(attr.getJavaType()) + .getFullQualifiedName()) + .setNullable(et.getDeclaredSingularAttribute(attr.getName()) + .isOptional()); + + return p; + } + + private CsdlPropertyRef buildRefAttribute(EntityType et, SingularAttribute attr) { + + CsdlPropertyRef p = new CsdlPropertyRef().setName(attr.getName()); + + return p; + } + + private CsdlNavigationProperty buildNavAttribute(EntityType et, PluralAttribute attr) { + + CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName()) + .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) + .setNullable(false); // for now + + return p; + } + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java new file mode 100644 index 0000000000..ed921484c1 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java @@ -0,0 +1,185 @@ +package org.baeldung.examples.olingo4.processor; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.SingularAttribute; + +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ValueType; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.ex.ODataRuntimeException; +import org.apache.olingo.commons.api.format.ContentType; +import org.apache.olingo.commons.api.http.HttpHeader; +import org.apache.olingo.commons.api.http.HttpStatusCode; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; +import org.apache.olingo.server.api.ODataLibraryException; +import org.apache.olingo.server.api.ODataRequest; +import org.apache.olingo.server.api.ODataResponse; +import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor; +import org.apache.olingo.server.api.processor.EntityCollectionProcessor; +import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; +import org.apache.olingo.server.api.serializer.ODataSerializer; +import org.apache.olingo.server.api.serializer.SerializerResult; +import org.apache.olingo.server.api.uri.UriInfo; +import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; +import org.baeldung.examples.olingo4.repository.RepositoryRegistry; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Component; + +@Component +public class JpaEntityCollectionProcessor implements CountEntityCollectionProcessor { + + private OData odata; + private ServiceMetadata serviceMetadata; + private EntityManagerFactory emf; + private RepositoryRegistry repositoryRegistry; + + public JpaEntityCollectionProcessor(EntityManagerFactory emf, RepositoryRegistry repositoryRegistry) { + this.emf = emf; + this.repositoryRegistry = repositoryRegistry; + } + + @Override + public void init(OData odata, ServiceMetadata serviceMetadata) { + this.odata = odata; + this.serviceMetadata = serviceMetadata; + } + + @Override + public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { + + // 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI) + List resourcePaths = uriInfo.getUriResourceParts(); + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet + EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); + + // 2nd: fetch the data from backend for this requested EntitySetName + // it has to be delivered as EntitySet object + EntityCollection entitySet = getData(edmEntitySet, uriInfo); + + // 3rd: create a serializer based on the requested format (json) + ODataSerializer serializer = odata.createSerializer(responseFormat); + + // 4th: Now serialize the content: transform from the EntitySet object to InputStream + EdmEntityType edmEntityType = edmEntitySet.getEntityType(); + ContextURL contextUrl = ContextURL.with() + .entitySet(edmEntitySet) + .build(); + + final String id = request.getRawBaseUri() + "/" + edmEntitySet.getName(); + EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with() + .id(id) + .contextURL(contextUrl) + .build(); + SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entitySet, opts); + InputStream serializedContent = serializerResult.getContent(); + + // Finally: configure the response object: set the body, headers and status code + response.setContent(serializedContent); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + + } + + @Override + public void countEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { + + // 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI) + List resourcePaths = uriInfo.getUriResourceParts(); + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet + EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); + + // 2nd: fetch the data from backend for this requested EntitySetName + Long count = getCount(edmEntitySet, uriInfo); + + // Finally: configure the response object: set the body, headers and status code + response.setContent(new ByteArrayInputStream(count.toString() + .getBytes())); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, "text/plain"); + + } + + private EntityCollection getData(EdmEntitySet edmEntitySet, UriInfo uriInfo) { + + EdmEntityType type = edmEntitySet.getEntityType(); + JpaRepository repo = repositoryRegistry.getRepositoryForEntity(type); + EntityCollection result = new EntityCollection(); + + repo.findAll() + .stream() + .forEach((it) -> result.getEntities() + .add(map2entity(edmEntitySet, it))); + + return result; + } + + private Entity map2entity(EdmEntitySet edmEntitySet, Object entry) { + + EntityType et = emf.getMetamodel() + .entity(entry.getClass()); + + + Entity e = new Entity(); + try { + // First, we set the entity's primary key + + // Now map all properties + et.getDeclaredSingularAttributes().stream() + .forEach( (attr) -> { + if ( !attr.isAssociation()) { + Object v = getPropertyValue(entry,attr.getName()); + Property p = new Property(null, attr.getName(),ValueType.PRIMITIVE,v); + e.addProperty(p); + + if ( attr.isId()) { + e.setId(createId(edmEntitySet.getName(),v)); + } + } + + }); + + } catch (Exception ex) { + throw new ODataRuntimeException("[E141] Unable to create OData entity", ex); + } + + return e; + } + + private Object getPropertyValue(Object entry, String name) { + try { + return PropertyUtils.getProperty(entry,name); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e); + } + } + + private URI createId(String entitySetName, Object id) { + try { + return new URI(entitySetName + "(" + String.valueOf(id) + ")"); + } catch (URISyntaxException e) { + throw new ODataRuntimeException("[E177] Unable to create URI", e); + } + } + + private Long getCount(EdmEntitySet edmEntitySet, UriInfo uriInfo) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java new file mode 100644 index 0000000000..70664bcf86 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java @@ -0,0 +1,12 @@ +package org.baeldung.examples.olingo4.repository; + +import org.baeldung.examples.olingo4.domain.CarMaker; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface CarMakerRepository extends JpaRepository, JpaSpecificationExecutor, EdmEntityRepository { + + public default String getEdmEntityName() { return CarMaker.class.getSimpleName();} +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java new file mode 100644 index 0000000000..40590b15e1 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java @@ -0,0 +1,13 @@ +package org.baeldung.examples.olingo4.repository; + +import org.baeldung.examples.olingo4.domain.CarModel; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Repository; + +@Repository +public interface CarModelRepository extends JpaRepository, JpaSpecificationExecutor,EdmEntityRepository { + + public default String getEdmEntityName() { return CarModel.class.getSimpleName();} + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java new file mode 100644 index 0000000000..105925c958 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java @@ -0,0 +1,15 @@ +/** + * + */ +package org.baeldung.examples.olingo4.repository; + + +/** + * @author Philippe + * + */ +public interface EdmEntityRepository { + + public String getEdmEntityName(); + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java new file mode 100644 index 0000000000..991eb21fc2 --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java @@ -0,0 +1,28 @@ +package org.baeldung.examples.olingo4.repository; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Component; + +@Component +public class RepositoryRegistry { + + private Map> repositoriesByClassName = new HashMap<>(); + + public RepositoryRegistry(List allRepositories) { + + allRepositories.stream().forEach((r) -> + repositoriesByClassName.put(r.getEdmEntityName(),(JpaRepository)r)); + + } + + + public JpaRepository getRepositoryForEntity(EdmEntityType entityType) { + JpaRepository repo = repositoriesByClassName.get(entityType.getName()); + return repo; + } +} diff --git a/apache-olingo/olingo4/src/main/resources/application.properties b/apache-olingo/olingo4/src/main/resources/application.properties new file mode 100644 index 0000000000..6f115b5ae4 --- /dev/null +++ b/apache-olingo/olingo4/src/main/resources/application.properties @@ -0,0 +1,6 @@ +spring: + jpa: + show-sql: true + open-in-view: false + hibernate: + ddl-auto: update diff --git a/apache-olingo/olingo4/src/main/resources/data.sql b/apache-olingo/olingo4/src/main/resources/data.sql new file mode 100644 index 0000000000..327f2688c5 --- /dev/null +++ b/apache-olingo/olingo4/src/main/resources/data.sql @@ -0,0 +1,12 @@ +insert into car_maker(id,name) values (1,'Special Motors'); +insert into car_maker(id,name) values (2,'BWM'); +insert into car_maker(id,name) values (3,'Dolores'); + +insert into car_model(id,maker_fk,name,sku,year) values(1,1,'Muze','SM001',2018); +insert into car_model(id,maker_fk,name,sku,year) values(2,1,'Empada','SM002',2008); + +insert into car_model(id,maker_fk,name,sku,year) values(4,2,'BWM-100','BWM100',2008); +insert into car_model(id,maker_fk,name,sku,year) values(5,2,'BWM-200','BWM200',2009); +insert into car_model(id,maker_fk,name,sku,year) values(6,2,'BWM-300','BWM300',2008); + +alter sequence hibernate_sequence restart with 100; \ No newline at end of file diff --git a/apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java b/apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java new file mode 100644 index 0000000000..5d23a4148e --- /dev/null +++ b/apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java @@ -0,0 +1,16 @@ +package org.baeldung.examples.olingo4; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class Olingo4SampleApplicationTests { + + @Test + public void contextLoads() { + } + +} From e4565f7455802701db2e77c981aeb895a2c6f7f0 Mon Sep 17 00:00:00 2001 From: Jess Bring-Larsen Date: Thu, 11 Apr 2019 09:19:09 +0200 Subject: [PATCH 016/185] Updated Spring Boot and Spring Cloud Contract version. --- spring-cloud/spring-cloud-contract/pom.xml | 41 +++++++++++++++++++ .../spring-cloud-contract-consumer/pom.xml | 14 +------ .../spring-cloud-contract-producer/pom.xml | 26 +----------- 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/spring-cloud/spring-cloud-contract/pom.xml b/spring-cloud/spring-cloud-contract/pom.xml index 4d4e8ad2c3..ea71891648 100644 --- a/spring-cloud/spring-cloud-contract/pom.xml +++ b/spring-cloud/spring-cloud-contract/pom.xml @@ -19,4 +19,45 @@ spring-cloud-contract-consumer + + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter-data-rest + ${spring-boot.version} + + + + org.springframework.cloud + spring-cloud-contract-wiremock + ${spring-cloud.version} + test + + + org.springframework.cloud + spring-cloud-contract-stub-runner + ${spring-cloud.version} + test + + + org.springframework.cloud + spring-cloud-starter-contract-verifier + ${spring-cloud.version} + test + + + + + + UTF-8 + UTF-8 + 1.8 + 2.1.1.RELEASE + 2.1.4.RELEASE + \ No newline at end of file diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml index 8ecda40d0a..04181340a4 100644 --- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/pom.xml @@ -20,38 +20,26 @@ org.springframework.cloud spring-cloud-contract-wiremock - ${spring-cloud.version} test org.springframework.cloud spring-cloud-contract-stub-runner - ${spring-cloud.version} test org.springframework.boot spring-boot-starter-web - ${spring-boot.version} org.springframework.boot spring-boot-starter-data-rest - ${spring-boot.version} com.baeldung.spring.cloud spring-cloud-contract-producer - 1.0.0-SNAPSHOT + ${project.parent.version} test - - - UTF-8 - UTF-8 - 1.8 - 1.2.2.RELEASE - 1.5.9.RELEASE - diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml index 47759a818a..dffbd29206 100644 --- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-producer/pom.xml @@ -25,12 +25,10 @@ org.springframework.boot spring-boot-starter-web - ${spring-boot.version} org.springframework.boot spring-boot-starter-data-rest - ${spring-boot.version} @@ -38,7 +36,7 @@ org.springframework.cloud spring-cloud-contract-maven-plugin - 1.2.2.RELEASE + 2.1.1.RELEASE true com.baeldung.spring.cloud.springcloudcontractproducer.BaseTestClass @@ -47,26 +45,4 @@ - - - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - - - - UTF-8 - UTF-8 - 1.8 - Edgware.SR1 - 1.5.9.RELEASE - - From 13f5f790ed57c35a8673d918c21e067c6dc3cafa Mon Sep 17 00:00:00 2001 From: Jess Bring-Larsen Date: Thu, 11 Apr 2019 09:42:05 +0200 Subject: [PATCH 017/185] Removed deprecated property after version upgrade of Spring Cloud Contract. --- .../controller/BasicMathControllerIntegrationTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java index 5cf5c6d3b8..e21223e6ea 100644 --- a/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java +++ b/spring-cloud/spring-cloud-contract/spring-cloud-contract-consumer/src/test/java/com/baeldung/spring/cloud/springcloudcontractconsumer/controller/BasicMathControllerIntegrationTest.java @@ -7,6 +7,7 @@ import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner; +import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; @@ -19,7 +20,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @AutoConfigureJsonTesters -@AutoConfigureStubRunner(workOffline = true, +@AutoConfigureStubRunner(stubsMode = StubRunnerProperties.StubsMode.LOCAL, ids = "com.baeldung.spring.cloud:spring-cloud-contract-producer:+:stubs:8090") public class BasicMathControllerIntegrationTest { From 270582b25aac5b27b87281f9bdeaecf9e155c87f Mon Sep 17 00:00:00 2001 From: Philippe Date: Fri, 12 Apr 2019 00:16:38 -0300 Subject: [PATCH 018/185] [BAEL-1219] Code for Olingo V4 sample --- apache-olingo/olingo4/pom.xml | 2 +- .../olingo4/ODataServiceConfiguration.java | 31 +- .../examples/olingo4/ODataServlet.java | 2 +- .../examples/olingo4/edm/JpaEdmProvider.java | 33 +- .../JpaEntityCollectionProcessor.java | 77 ++-- .../olingo4/processor/JpaEntityMapper.java | 84 ++++ .../olingo4/processor/JpaEntityProcessor.java | 378 ++++++++++++++++++ .../repository/CarMakerRepository.java | 6 +- .../repository/CarModelRepository.java | 11 +- .../repository/EdmEntityRepository.java | 4 +- .../repository/RepositoryRegistry.java | 11 +- .../src/main/resources/application.properties | 3 + 12 files changed, 552 insertions(+), 90 deletions(-) create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java create mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java diff --git a/apache-olingo/olingo4/pom.xml b/apache-olingo/olingo4/pom.xml index a6f1fcdb7b..794aee0711 100644 --- a/apache-olingo/olingo4/pom.xml +++ b/apache-olingo/olingo4/pom.xml @@ -52,7 +52,7 @@ org.springframework.boot spring-boot-starter-web - + org.apache.olingo odata-server-api diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java index bbac0ceac7..0cde665359 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java @@ -14,33 +14,22 @@ import org.springframework.context.annotation.Configuration; @Configuration public class ODataServiceConfiguration { - - - @Bean - public ServletRegistrationBean odataServletRegistration(ODataHttpHandlerFactory factory, EntityManagerFactory emf) { - - ServletRegistrationBean bean = new ServletRegistrationBean( - odataServlet(factory,emf), - "/odata/*"); - bean.setLoadOnStartup(1); - return bean; - } - @Bean - public HttpServlet odataServlet(ODataHttpHandlerFactory factory, EntityManagerFactory emf ) { - - return new ODataServlet(factory,emf); + public ServletRegistrationBean odataServletRegistration(ODataHttpHandlerFactory factory) { + ServletRegistrationBean srb = + new ServletRegistrationBean<>(new ODataServlet(factory), "/odata/*"); + srb.setLoadOnStartup(1); + return srb; } - - + @Bean public ODataHttpHandlerFactory httpHandlerFactory(CsdlEdmProvider edmProvider, ODataFactory odataFactory, List processors) { return new ODataHttpHandlerFactoryImplBuilder() - .edmProvider(edmProvider) - .odataFactory(odataFactory) - .processors(processors) - .build(); + .edmProvider(edmProvider) + .odataFactory(odataFactory) + .processors(processors) + .build(); } } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java index c2adf2c1ae..c379124541 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java @@ -25,7 +25,7 @@ public class ODataServlet extends HttpServlet { private final ODataHttpHandlerFactory odataHttpHandlerFactory; - public ODataServlet(ODataHttpHandlerFactory factory, EntityManagerFactory emf) { + public ODataServlet(ODataHttpHandlerFactory factory) { this.odataHttpHandlerFactory = factory; } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java index 3e490cdf58..68edb58e12 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java @@ -62,8 +62,9 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { if (e != null) { CsdlEntitySet entitySet = new CsdlEntitySet(); - entitySet.setName(entitySetName); - entitySet.setType(new FullQualifiedName(NAMESPACE, e.getName())); + entitySet + .setName(entitySetName) + .setType(new FullQualifiedName(NAMESPACE, e.getName())); return entitySet; } } @@ -135,7 +136,6 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { .map((e) -> { try { // Here we use a simple mapping strategy to map entity types to entity set names: - // return getEntitySet(CONTAINER, e.getName() + "s"); } catch (ODataException oe) { throw new RuntimeException(oe); @@ -197,12 +197,22 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { result.setKey(ids); - // Process navs + // Process 1:N navs List navs = et.getDeclaredPluralAttributes() .stream() .map(attr -> buildNavAttribute(et, attr)) .collect(Collectors.toList()); result.setNavigationProperties(navs); + + // Process N:1 navs + List navs2 = et.getDeclaredSingularAttributes() + .stream() + .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE) + .map(attr -> buildNavAttribute(et, attr)) + .collect(Collectors.toList()); + + result.getNavigationProperties().addAll(navs2); + return result; } @@ -225,13 +235,26 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { return p; } + // Build NavProperty for 1:N or M:N associations private CsdlNavigationProperty buildNavAttribute(EntityType et, PluralAttribute attr) { CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName()) .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) - .setNullable(false); // for now + .setCollection(true) + .setNullable(false); return p; } + // Build NavProperty for N:1 associations + private CsdlNavigationProperty buildNavAttribute(EntityType et, SingularAttribute attr) { + + CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName()) + .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) + .setCollection(false) + .setNullable(attr.isOptional()); + + return p; + } + } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java index ed921484c1..6bca0e9896 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java @@ -48,10 +48,12 @@ public class JpaEntityCollectionProcessor implements CountEntityCollectionProces private ServiceMetadata serviceMetadata; private EntityManagerFactory emf; private RepositoryRegistry repositoryRegistry; + private JpaEntityMapper entityMapper; - public JpaEntityCollectionProcessor(EntityManagerFactory emf, RepositoryRegistry repositoryRegistry) { + public JpaEntityCollectionProcessor(EntityManagerFactory emf, RepositoryRegistry repositoryRegistry, JpaEntityMapper entityMapper) { this.emf = emf; this.repositoryRegistry = repositoryRegistry; + this.entityMapper = entityMapper; } @Override @@ -115,71 +117,40 @@ public class JpaEntityCollectionProcessor implements CountEntityCollectionProces } - private EntityCollection getData(EdmEntitySet edmEntitySet, UriInfo uriInfo) { + /** + * Helper method to retrieve all entities of an entity set from an the backend database + * @param edmEntitySet + * @param uriInfo + * @return + */ + protected EntityCollection getData(EdmEntitySet edmEntitySet, UriInfo uriInfo) { EdmEntityType type = edmEntitySet.getEntityType(); - JpaRepository repo = repositoryRegistry.getRepositoryForEntity(type); + JpaRepository repo = (JpaRepository)repositoryRegistry.getRepositoryForEntity(type); EntityCollection result = new EntityCollection(); repo.findAll() .stream() .forEach((it) -> result.getEntities() - .add(map2entity(edmEntitySet, it))); + .add(entityMapper.map2entity(edmEntitySet, it))); return result; } - private Entity map2entity(EdmEntitySet edmEntitySet, Object entry) { - - EntityType et = emf.getMetamodel() - .entity(entry.getClass()); - - - Entity e = new Entity(); - try { - // First, we set the entity's primary key - - // Now map all properties - et.getDeclaredSingularAttributes().stream() - .forEach( (attr) -> { - if ( !attr.isAssociation()) { - Object v = getPropertyValue(entry,attr.getName()); - Property p = new Property(null, attr.getName(),ValueType.PRIMITIVE,v); - e.addProperty(p); - - if ( attr.isId()) { - e.setId(createId(edmEntitySet.getName(),v)); - } - } - - }); - - } catch (Exception ex) { - throw new ODataRuntimeException("[E141] Unable to create OData entity", ex); - } - - return e; - } - - private Object getPropertyValue(Object entry, String name) { - try { - return PropertyUtils.getProperty(entry,name); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e); - } - } - - private URI createId(String entitySetName, Object id) { - try { - return new URI(entitySetName + "(" + String.valueOf(id) + ")"); - } catch (URISyntaxException e) { - throw new ODataRuntimeException("[E177] Unable to create URI", e); - } - } + /** + * Helper method to get the total size of an entity set + * @param edmEntitySet + * @param uriInfo + * @return + */ private Long getCount(EdmEntitySet edmEntitySet, UriInfo uriInfo) { - // TODO Auto-generated method stub - return null; + + EdmEntityType type = edmEntitySet.getEntityType(); + JpaRepository repo = (JpaRepository)repositoryRegistry.getRepositoryForEntity(type); + EntityCollection result = new EntityCollection(); + + return repo.count(); } } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java new file mode 100644 index 0000000000..5fd863124f --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java @@ -0,0 +1,84 @@ +/** + * + */ +package org.baeldung.examples.olingo4.processor; + +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.metamodel.EntityType; + +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.Property; +import org.apache.olingo.commons.api.data.ValueType; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.ex.ODataRuntimeException; +import org.springframework.stereotype.Component; + +/** + *

Helper class that converts a JPA entity into an OData entity using + * available metadata from the JPA's EntityManagerFactory.

+ * + * @author Philippe + * + */ +@Component +public class JpaEntityMapper { + + private EntityManagerFactory emf; + + public JpaEntityMapper(EntityManagerFactory emf) { + this.emf = emf; + } + + + public Entity map2entity(EdmEntitySet edmEntitySet, Object entry) { + + EntityType et = emf.getMetamodel() + .entity(entry.getClass()); + + + Entity e = new Entity(); + try { + et.getDeclaredSingularAttributes().stream() + .forEach( (attr) -> { + if ( !attr.isAssociation()) { + Object v = getPropertyValue(entry,attr.getName()); + Property p = new Property(null, attr.getName(),ValueType.PRIMITIVE,v); + e.addProperty(p); + + if ( attr.isId()) { + e.setId(createId(edmEntitySet.getName(),v)); + } + } + }); + } catch (Exception ex) { + throw new ODataRuntimeException("[E141] Unable to create OData entity", ex); + } + + return e; + } + + + private Object getPropertyValue(Object entry, String name) { + try { + return PropertyUtils.getProperty(entry,name); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e); + } + } + + private URI createId(String entitySetName, Object id) { + try { + return new URI(entitySetName + "(" + String.valueOf(id) + ")"); + } catch (URISyntaxException e) { + throw new ODataRuntimeException("[E177] Unable to create URI", e); + } + } + + + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java new file mode 100644 index 0000000000..23a5a7ac4b --- /dev/null +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java @@ -0,0 +1,378 @@ +/** + * + */ +package org.baeldung.examples.olingo4.processor; + +import java.io.InputStream; +import java.lang.reflect.Member; +import java.util.Collection; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; +import javax.persistence.metamodel.SingularAttribute; + +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.olingo.commons.api.data.ContextURL; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmNavigationProperty; +import org.apache.olingo.commons.api.edm.EdmType; +import org.apache.olingo.commons.api.ex.ODataRuntimeException; +import org.apache.olingo.commons.api.format.ContentType; +import org.apache.olingo.commons.api.http.HttpHeader; +import org.apache.olingo.commons.api.http.HttpStatusCode; +import org.apache.olingo.server.api.OData; +import org.apache.olingo.server.api.ODataApplicationException; +import org.apache.olingo.server.api.ODataLibraryException; +import org.apache.olingo.server.api.ODataRequest; +import org.apache.olingo.server.api.ODataResponse; +import org.apache.olingo.server.api.ServiceMetadata; +import org.apache.olingo.server.api.processor.EntityProcessor; +import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; +import org.apache.olingo.server.api.serializer.EntitySerializerOptions; +import org.apache.olingo.server.api.serializer.ODataSerializer; +import org.apache.olingo.server.api.serializer.SerializerException; +import org.apache.olingo.server.api.serializer.SerializerResult; +import org.apache.olingo.server.api.uri.UriInfo; +import org.apache.olingo.server.api.uri.UriParameter; +import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; +import org.apache.olingo.server.api.uri.UriResourceNavigation; +import org.baeldung.examples.olingo4.repository.EdmEntityRepository; +import org.baeldung.examples.olingo4.repository.RepositoryRegistry; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.stereotype.Component; + +/** + * JpaEntityProcessor adapter. + *

This implementation is heavily based on the Tutorial available + * at Olingo's site. It is meant to be an starting point for an actual implementation.

+ *

Please note that many features from a full-fledged are missing + * @author Philippe + * + */ +@Component +public class JpaEntityProcessor implements EntityProcessor { + + private EntityManagerFactory emf; + private OData odata; + private ServiceMetadata serviceMetadata; + private RepositoryRegistry registry; + private JpaEntityMapper entityMapper; + + public JpaEntityProcessor(EntityManagerFactory emf, RepositoryRegistry registry, JpaEntityMapper entityMapper) { + this.emf = emf; + this.registry = registry; + this.entityMapper = entityMapper; + } + + /* (non-Javadoc) + * @see org.apache.olingo.server.api.processor.Processor#init(org.apache.olingo.server.api.OData, org.apache.olingo.server.api.ServiceMetadata) + */ + @Override + public void init(OData odata, ServiceMetadata serviceMetadata) { + this.odata = odata; + this.serviceMetadata = serviceMetadata; + + } + + /* (non-Javadoc) + * @see org.apache.olingo.server.api.processor.EntityProcessor#readEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType) + */ + @Override + public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { + + // First, we have to figure out which entity is requested + List resourceParts = uriInfo.getUriResourceParts(); + InputStream entityStream; + + UriResourceEntitySet rootResourceEntitySet = (UriResourceEntitySet) resourceParts.get(0); + EdmEntitySet rootEntitySet = rootResourceEntitySet.getEntitySet(); + List rootPredicates = rootResourceEntitySet.getKeyPredicates(); + EdmEntityType rootEntityType = rootEntitySet.getEntityType(); + + + if ( resourceParts.size() == 1 ) { + entityStream = readEntity(rootEntitySet,rootPredicates,responseFormat); + } + else if ( resourceParts.size() == 2 ) { + UriResource part = resourceParts.get(1); + if ( !(part instanceof UriResourceNavigation)) { + throw new ODataRuntimeException("[E103] part type not supported: class=" + part.getClass().getName()); + } + + UriResourceNavigation navSegment = (UriResourceNavigation)part; + + // We have three scenarios we must handle: + // Entity(x)/Related, where Related is a 1:N or M:N relationship => result is a collection + // Entity(x)/Related, where Related is a N:1 or 1:1 relationship => result is a single entity + // Entity(x)/Related(z), where Related is a 1:N or M:N relationship => result is a single entity + if (navSegment.getKeyPredicates().isEmpty()) { + if ( isOne2ManyProperty(rootEntityType,navSegment.getProperty())) { + entityStream = readRelatedEntities(rootEntitySet,rootPredicates,navSegment.getProperty(),responseFormat); + } + else { + // The relation must point to another entity type, so casting should be safe here + EdmEntityType resultType = (EdmEntityType)rootEntityType.getNavigationProperty(navSegment.getProperty().getName()).getType(); + EdmEntitySet resultEntitySet = entitySetFromType(resultType); + + entityStream = readEntity(resultEntitySet, navSegment.getKeyPredicates(), responseFormat); + } + } + else { + entityStream = readRelatedEntity(request, rootEntitySet,rootPredicates,navSegment.getProperty(),navSegment.getKeyPredicates(),responseFormat); + } + + } + else { + // For now, we'll only allow navigation just to directly linked navs + throw new ODataApplicationException("[E109] Multi-level navigation not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); + } + + //4. configure the response object + response.setContent(entityStream); + response.setStatusCode(HttpStatusCode.OK.getStatusCode()); + response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); + + } + + + // Lookup the EntitySet associated with an EntityType + // In our example, we assume we have only one entityset for each entity type + private EdmEntitySet entitySetFromType(EdmEntityType type) { + return serviceMetadata + .getEdm() + .getEntityContainer() + .getEntitySets() + .stream() + .filter((s) -> s.getEntityType().getName().equals(type.getName())) + .findFirst() + .orElseThrow(() -> new ODataRuntimeException("[E144] No entity set found for type " + type.getFullQualifiedName())); + } + + // + private boolean isOne2ManyProperty(EdmEntityType entityType, EdmNavigationProperty property) { + return entityType.getProperty(property.getName()) != null && property.isCollection(); + } + + private InputStream readEntity(EdmEntitySet entitySet, List keyPredicates,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { + + Entity entity = readEntityData(entitySet,keyPredicates); + + ContextURL contextUrl = ContextURL.with().entitySet(entitySet).build(); + // expand and select currently not supported + EntitySerializerOptions options = EntitySerializerOptions + .with() + .contextURL(contextUrl) + .build(); + + ODataSerializer serializer = odata.createSerializer(responseFormat); + + SerializerResult serializerResult = serializer.entity(serviceMetadata, entitySet.getEntityType(), entity, options); + return serializerResult.getContent(); + } + + private InputStream readRelatedEntities(EdmEntitySet rootEntitySet, List rootPredicates, EdmNavigationProperty property, ContentType responseFormat) throws ODataApplicationException { + + Object jpaEntity = readJPAEntity(rootEntitySet, rootPredicates); + try { + Object set = PropertyUtils.getProperty(jpaEntity, property.getName()); + EdmEntitySet entitySet = entitySetFromType(property.getType()); + ContextURL contextUrl = ContextURL + .with() + .entitySet(entitySet) + .build(); + + EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions + .with() + .contextURL(contextUrl) + .build(); + + EntityCollection result = new EntityCollection(); + + ((Collection)set) + .stream() + .map((o) -> this.entityMapper.map2entity(entitySet, o)) + .forEach((e) -> result.getEntities().add(e)); + + ODataSerializer serializer = odata.createSerializer(responseFormat); + SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, property.getType(), result, options); + return serializerResult.getContent(); + } + catch(Exception ex) { + throw new ODataRuntimeException("[E181] Error accessing database", ex); + } + } + + @SuppressWarnings({ "rawtypes", "serial", "unchecked" }) + private InputStream readRelatedEntity(ODataRequest request, EdmEntitySet rootEntitySet, List rootPredicates, EdmNavigationProperty property, List predicates, ContentType responseFormat) throws ODataApplicationException, SerializerException { + + + JpaSpecificationExecutor rootRepo = (JpaSpecificationExecutor)registry.getRepositoryForEntity(rootEntitySet.getEntityType()); + JpaSpecificationExecutor repo = (JpaSpecificationExecutor)registry.getRepositoryForEntity(property.getType()); + + // We assume here that we have a bi-directional 1:N relationship, so we'll + // always have a property in the child entity that points to the parent + Class rootClass = ((EdmEntityRepository)rootRepo).getEntityClass(); + Class childClass = ((EdmEntityRepository)repo).getEntityClass(); + SingularAttribute fk = emf.getMetamodel() + .entity(childClass) + .getSingularAttributes() + .stream() + .filter((attr) -> attr.isAssociation() && attr.getJavaType().isAssignableFrom(rootClass)) + .findFirst() + .orElse(null); + + SingularAttribute pk = emf.getMetamodel() + .entity(childClass) + .getId(Long.class); + + SingularAttribute rootPk = emf.getMetamodel() + .entity(rootClass) + .getId(Long.class); + + if ( fk == null ) { + throw new ODataRuntimeException("[E230] No singular attribute of child class '" + childClass.getName() + "' found" ); + } + + + Specification spec = new Specification() { + @Override + public Predicate toPredicate(Root root, CriteriaQuery q, CriteriaBuilder cb) { + + try { + Object rootInstance = rootClass.newInstance(); + PropertyUtils.setProperty(rootInstance, rootPk.getName(), getEntityKey(rootEntitySet.getEntityType(),rootPredicates)); + + final Predicate p = cb.and( + cb.equal( + root.get(pk), + getEntityKey(property.getType(),predicates)), + cb.equal( + root.get(fk), + rootInstance)); + + return p; + } + catch(Exception ex) { + throw new ODataRuntimeException(ex); + } + + } + }; + + // Read data from DB + EdmEntitySet relatedEntitySet = entitySetFromType(property.getType()); + EntityCollection data = new EntityCollection(); + + repo.findAll(spec) + .stream() + .forEach((entry) -> data.getEntities().add(entityMapper.map2entity(relatedEntitySet, entry))); + + // + + ODataSerializer serializer = odata.createSerializer(responseFormat); + + // 4th: Now serialize the content: transform from the EntitySet object to InputStream + EdmEntityType edmEntityType = relatedEntitySet.getEntityType(); + ContextURL contextUrl = ContextURL.with() + .entitySet(relatedEntitySet) + .build(); + + final String id = request.getRawBaseUri() + "/" + relatedEntitySet.getName(); + EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with() + .id(id) + .contextURL(contextUrl) + .build(); + SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, data, opts); + InputStream serializedContent = serializerResult.getContent(); + + + return serializedContent; + } + + + /** + * This method returns a speficic entity given its primary key + * @param edmEntitySet + * @param keyPredicates + * @return + */ + protected Entity readEntityData(EdmEntitySet edmEntitySet, List keyPredicates) throws ODataApplicationException { + + Object jpaEntry = readJPAEntity(edmEntitySet, keyPredicates); + Entity e = entityMapper.map2entity(edmEntitySet, jpaEntry); + return e; + } + + private Object readJPAEntity(EdmEntitySet edmEntitySet, List keyPredicates) throws ODataApplicationException { + EdmEntityType type = edmEntitySet.getEntityType(); + JpaRepository repo = (JpaRepository)registry.getRepositoryForEntity(type); + + // Get key value + Object keyValue = getEntityKey(type,keyPredicates); + Object entry = repo + .findById(keyValue) + .orElseThrow( + () -> new ODataApplicationException("[E116] NO entity found for the given key", + HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH)); + + return entry; + } + + private Object getEntityKey(EdmEntityType type, List keyPredicates) { + + if ( keyPredicates.size() > 1 ) { + throw new ODataRuntimeException("[E131] Composite keys are not supported"); + } + + // For now, we'll assume we only have numeric keys. + UriParameter keyParam = keyPredicates.get(0); + try { + return Long.parseLong(keyParam.getText()); + } + catch(NumberFormatException nfe) { + throw new ODataRuntimeException("[E140] Invalid key value. Only numeric keys are supported by this service"); + } + + + } + + /* (non-Javadoc) + * @see org.apache.olingo.server.api.processor.EntityProcessor#createEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType, org.apache.olingo.commons.api.format.ContentType) + */ + @Override + public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.apache.olingo.server.api.processor.EntityProcessor#updateEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType, org.apache.olingo.commons.api.format.ContentType) + */ + @Override + public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.apache.olingo.server.api.processor.EntityProcessor#deleteEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo) + */ + @Override + public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { + // TODO Auto-generated method stub + + } + +} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java index 70664bcf86..1bde9f148c 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java @@ -6,7 +6,11 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.stereotype.Repository; @Repository -public interface CarMakerRepository extends JpaRepository, JpaSpecificationExecutor, EdmEntityRepository { +public interface CarMakerRepository extends EdmEntityRepository, JpaRepository, JpaSpecificationExecutor { public default String getEdmEntityName() { return CarMaker.class.getSimpleName();} + @Override + default Class getEntityClass() { + return CarMaker.class; + } } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java index 40590b15e1..247bf6e77b 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java @@ -1,13 +1,22 @@ package org.baeldung.examples.olingo4.repository; +import java.util.List; + import org.baeldung.examples.olingo4.domain.CarModel; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.stereotype.Repository; @Repository -public interface CarModelRepository extends JpaRepository, JpaSpecificationExecutor,EdmEntityRepository { +public interface CarModelRepository extends EdmEntityRepository, JpaRepository, JpaSpecificationExecutor { + public List findByMakerId(Long makerId); + public default String getEdmEntityName() { return CarModel.class.getSimpleName();} + + @Override + default Class getEntityClass() { + return CarModel.class; + } } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java index 105925c958..dbfd0e6f93 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java @@ -8,8 +8,10 @@ package org.baeldung.examples.olingo4.repository; * @author Philippe * */ -public interface EdmEntityRepository { +public interface EdmEntityRepository { public String getEdmEntityName(); + public Class getEntityClass(); + } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java index 991eb21fc2..20981fdfef 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java @@ -5,24 +5,23 @@ import java.util.List; import java.util.Map; import org.apache.olingo.commons.api.edm.EdmEntityType; -import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Component; @Component public class RepositoryRegistry { - private Map> repositoriesByClassName = new HashMap<>(); + private Map> repositoriesByClassName = new HashMap<>(); - public RepositoryRegistry(List allRepositories) { + public RepositoryRegistry(List> allRepositories) { allRepositories.stream().forEach((r) -> - repositoriesByClassName.put(r.getEdmEntityName(),(JpaRepository)r)); + repositoriesByClassName.put(r.getEdmEntityName(),(EdmEntityRepository)r)); } - public JpaRepository getRepositoryForEntity(EdmEntityType entityType) { - JpaRepository repo = repositoriesByClassName.get(entityType.getName()); + public EdmEntityRepository getRepositoryForEntity(EdmEntityType entityType) { + EdmEntityRepository repo = repositoriesByClassName.get(entityType.getName()); return repo; } } diff --git a/apache-olingo/olingo4/src/main/resources/application.properties b/apache-olingo/olingo4/src/main/resources/application.properties index 6f115b5ae4..e4742b4fbb 100644 --- a/apache-olingo/olingo4/src/main/resources/application.properties +++ b/apache-olingo/olingo4/src/main/resources/application.properties @@ -1,3 +1,6 @@ +server: + port: 8080 + spring: jpa: show-sql: true From beccf32be8bb458777f8c54b8e3aa4ad999e3301 Mon Sep 17 00:00:00 2001 From: Vivek Date: Sat, 13 Apr 2019 14:18:55 +0530 Subject: [PATCH 019/185] BAEL-2857 Defining a JPA Entity --- .../java/com/baeldung/jpa/entity/Student.java | 75 +++++++++++++++++ .../main/java/com/baeldung/util/Gender.java | 6 ++ .../main/resources/META-INF/persistence.xml | 20 +++++ .../entity/StudentEntityIntegrationTest.java | 83 +++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java create mode 100644 persistence-modules/java-jpa/src/main/java/com/baeldung/util/Gender.java create mode 100644 persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java new file mode 100644 index 0000000000..6eced20779 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java @@ -0,0 +1,75 @@ +package com.baeldung.jpa.entity; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; + +import com.baeldung.util.Gender; + +@Entity +@Table(name="STUD_NAME") +public class Student { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + @Column(name = "STUD_NAME", length = 50, nullable = false, unique = false) + private String name; + @Transient + private Integer age; + @Temporal(TemporalType.DATE) + private Date birthDate; + @Enumerated(EnumType.STRING) + private Gender gender; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Date getBirthDate() { + return birthDate; + } + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + public Gender getGender() { + return gender; + } + + public void setGender(Gender gender) { + this.gender = gender; + } + +} diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/util/Gender.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/util/Gender.java new file mode 100644 index 0000000000..13f08d995c --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/util/Gender.java @@ -0,0 +1,6 @@ +package com.baeldung.util; + +public enum Gender { + MALE, + FEMALE +} diff --git a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml index 5422afa4a3..2105a80d7d 100644 --- a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml @@ -129,5 +129,25 @@ + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.entity.Student + true + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java new file mode 100644 index 0000000000..2dc5d7c5f2 --- /dev/null +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java @@ -0,0 +1,83 @@ +package com.baeldung.jpa.entity; + +import static org.junit.Assert.assertEquals; + +import java.util.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.TypedQuery; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.util.Gender; + +public class StudentEntityIntegrationTest { + + private EntityManagerFactory emf; + private EntityManager em; + + @Before + public void setup() { + emf = Persistence.createEntityManagerFactory("jpa-entity-definition"); + em = emf.createEntityManager(); + } + + @Test + public void persistStudentThenRetrieveTheDetails() { + Student student = createStudentWithRelevantDetails(); + persist(student); + clearThePersistenceContext(); + List students = getStudentsFromTable(); + checkAssertionsWith(students); + } + + @After + public void destroy() { + if (em != null) { + em.close(); + } + if (emf != null) { + emf.close(); + } + } + + private void clearThePersistenceContext() { + em.clear(); + } + + private void checkAssertionsWith(List students) { + assertEquals(1, students.size()); + Student john = students.get(0); + assertEquals(1L, john.getId().longValue()); + assertEquals(null, john.getAge()); + assertEquals("John", john.getName()); + } + + private List getStudentsFromTable() { + String selectQuery = "SELECT student FROM Student student"; + TypedQuery selectFromStudentTypedQuery = em.createQuery(selectQuery, Student.class); + List students = selectFromStudentTypedQuery.getResultList(); + return students; + } + + private void persist(Student student) { + em.getTransaction().begin(); + em.persist(student); + em.getTransaction().commit(); + } + + private Student createStudentWithRelevantDetails() { + Student student = new Student(); + student.setAge(20); // the 'age' field has been annotated with @Transient + student.setName("John"); + student.setBirthDate(new Date()); + student.setGender(Gender.MALE); + return student; + } + +} From 8271d0ab5a8f7ef6d7906fb4219cf18103a9d76b Mon Sep 17 00:00:00 2001 From: Vivek Date: Sat, 13 Apr 2019 14:37:15 +0530 Subject: [PATCH 020/185] BAEL-2857 Defining a JPA Entity --- .../src/main/java/com/baeldung/jpa/entity/Student.java | 2 +- .../jpa/entity/StudentEntityIntegrationTest.java | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java index 6eced20779..17007fa126 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java @@ -17,7 +17,7 @@ import javax.persistence.Transient; import com.baeldung.util.Gender; @Entity -@Table(name="STUD_NAME") +@Table(name="STUD") public class Student { @Id diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java index 2dc5d7c5f2..fdaaba5439 100644 --- a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/StudentEntityIntegrationTest.java @@ -2,6 +2,8 @@ package com.baeldung.jpa.entity; import static org.junit.Assert.assertEquals; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.Date; import java.util.List; @@ -75,9 +77,15 @@ public class StudentEntityIntegrationTest { Student student = new Student(); student.setAge(20); // the 'age' field has been annotated with @Transient student.setName("John"); - student.setBirthDate(new Date()); + Date date = getDate(); + student.setBirthDate(date); student.setGender(Gender.MALE); return student; } + private Date getDate() { + LocalDate localDate = LocalDate.of(2008, 7, 20); + return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); + } + } From 5f30277f9e8af356288061502bc180a425d314be Mon Sep 17 00:00:00 2001 From: Philippe Date: Sun, 14 Apr 2019 13:17:38 -0300 Subject: [PATCH 021/185] [BAEL-1219] Code polishing --- .../examples/olingo4/domain/CarModel.java | 2 +- .../examples/olingo4/edm/JpaEdmProvider.java | 17 +- .../JpaEntityCollectionProcessor.java | 17 +- .../olingo4/processor/JpaEntityMapper.java | 11 +- .../olingo4/processor/JpaEntityProcessor.java | 276 +++++++----------- .../repository/RepositoryRegistry.java | 12 +- .../src/main/resources/application.properties | 2 +- 7 files changed, 144 insertions(+), 193 deletions(-) diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java index e6cd80ebf1..a9254e48b9 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java @@ -31,7 +31,7 @@ public class CarModel { @NotNull private String sku; - @ManyToOne(optional=false, fetch= FetchType.LAZY) + @ManyToOne(optional=false, fetch= FetchType.EAGER ) @JoinColumn(name="maker_fk") private CarMaker maker; diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java index 68edb58e12..4cd979e931 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java @@ -1,7 +1,9 @@ package org.baeldung.examples.olingo4.edm; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import javax.persistence.EntityManagerFactory; @@ -33,11 +35,14 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { private EdmTypeMapper typeMapper; // Service Namespace - public static final String NAMESPACE = "OData.Demo"; + public static final String NAMESPACE = "Baeldung.OData"; // EDM Container public static final String CONTAINER_NAME = "Cars"; public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME); + + // Caches of OData types by it fully qualified name + private Map cdslName2Type = new HashMap<>(); public JpaEdmProvider(EntityManagerFactory emf, EdmTypeMapper mapper) { this.emf = emf; @@ -153,11 +158,13 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { @Override public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException { + + CsdlEntityType result = cdslName2Type.get(entityTypeName); + if ( result != null ) { + return result; + } Metamodel mm = emf.getMetamodel(); - - CsdlEntityType result = null; - result = mm.getEntities() .stream() .filter(et -> entityTypeName.equals(new FullQualifiedName(NAMESPACE, et.getName()))) @@ -165,6 +172,8 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { .findFirst() .orElse(null); + // save for future use + cdslName2Type.put(entityTypeName, result); return result; } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java index 6bca0e9896..4a4e5026f3 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java @@ -5,6 +5,7 @@ import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URISyntaxException; +import java.util.Collection; import java.util.List; import javax.persistence.EntityManagerFactory; @@ -19,6 +20,7 @@ import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.data.ValueType; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmNavigationProperty; import org.apache.olingo.commons.api.ex.ODataRuntimeException; import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.commons.api.http.HttpHeader; @@ -35,6 +37,7 @@ import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions import org.apache.olingo.server.api.serializer.ODataSerializer; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriInfo; +import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResourceEntitySet; import org.baeldung.examples.olingo4.repository.RepositoryRegistry; @@ -110,8 +113,7 @@ public class JpaEntityCollectionProcessor implements CountEntityCollectionProces Long count = getCount(edmEntitySet, uriInfo); // Finally: configure the response object: set the body, headers and status code - response.setContent(new ByteArrayInputStream(count.toString() - .getBytes())); + response.setContent(new ByteArrayInputStream(count.toString().getBytes())); response.setStatusCode(HttpStatusCode.OK.getStatusCode()); response.setHeader(HttpHeader.CONTENT_TYPE, "text/plain"); @@ -130,9 +132,9 @@ public class JpaEntityCollectionProcessor implements CountEntityCollectionProces EntityCollection result = new EntityCollection(); repo.findAll() - .stream() - .forEach((it) -> result.getEntities() - .add(entityMapper.map2entity(edmEntitySet, it))); + .stream() + .forEach((it) -> result.getEntities() + .add(entityMapper.map2entity(edmEntitySet, it))); return result; } @@ -144,7 +146,7 @@ public class JpaEntityCollectionProcessor implements CountEntityCollectionProces * @param uriInfo * @return */ - private Long getCount(EdmEntitySet edmEntitySet, UriInfo uriInfo) { + protected Long getCount(EdmEntitySet edmEntitySet, UriInfo uriInfo) { EdmEntityType type = edmEntitySet.getEntityType(); JpaRepository repo = (JpaRepository)repositoryRegistry.getRepositoryForEntity(type); @@ -152,5 +154,8 @@ public class JpaEntityCollectionProcessor implements CountEntityCollectionProces return repo.count(); } + + + } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java index 5fd863124f..1978aa4fd6 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java @@ -63,13 +63,22 @@ public class JpaEntityMapper { } - private Object getPropertyValue(Object entry, String name) { + public Object getPropertyValue(Object entry, String name) { try { return PropertyUtils.getProperty(entry,name); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e); } } + + public void setPropertyValue(Object entry, String name,Object value) { + try { + PropertyUtils.setProperty(entry,name,value); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e); + } + } + private URI createId(String entitySetName, Object id) { try { diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java index 23a5a7ac4b..719e5de160 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java @@ -4,27 +4,19 @@ package org.baeldung.examples.olingo4.processor; import java.io.InputStream; -import java.lang.reflect.Member; -import java.util.Collection; import java.util.List; import java.util.Locale; -import java.util.stream.Collectors; +import java.util.Optional; +import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; import javax.persistence.metamodel.SingularAttribute; -import org.apache.commons.beanutils.PropertyUtils; import org.apache.olingo.commons.api.data.ContextURL; import org.apache.olingo.commons.api.data.Entity; -import org.apache.olingo.commons.api.data.EntityCollection; import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmNavigationProperty; -import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.api.ex.ODataRuntimeException; import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.commons.api.http.HttpHeader; @@ -36,10 +28,8 @@ import org.apache.olingo.server.api.ODataRequest; import org.apache.olingo.server.api.ODataResponse; import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.processor.EntityProcessor; -import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; import org.apache.olingo.server.api.serializer.EntitySerializerOptions; import org.apache.olingo.server.api.serializer.ODataSerializer; -import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriInfo; import org.apache.olingo.server.api.uri.UriParameter; @@ -48,9 +38,7 @@ import org.apache.olingo.server.api.uri.UriResourceEntitySet; import org.apache.olingo.server.api.uri.UriResourceNavigation; import org.baeldung.examples.olingo4.repository.EdmEntityRepository; import org.baeldung.examples.olingo4.repository.RepositoryRegistry; -import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.stereotype.Component; /** @@ -99,11 +87,9 @@ public class JpaEntityProcessor implements EntityProcessor { UriResourceEntitySet rootResourceEntitySet = (UriResourceEntitySet) resourceParts.get(0); EdmEntitySet rootEntitySet = rootResourceEntitySet.getEntitySet(); List rootPredicates = rootResourceEntitySet.getKeyPredicates(); - EdmEntityType rootEntityType = rootEntitySet.getEntityType(); - if ( resourceParts.size() == 1 ) { - entityStream = readEntity(rootEntitySet,rootPredicates,responseFormat); + entityStream = readRootEntity(rootEntitySet,rootPredicates,responseFormat); } else if ( resourceParts.size() == 2 ) { UriResource part = resourceParts.get(1); @@ -112,27 +98,7 @@ public class JpaEntityProcessor implements EntityProcessor { } UriResourceNavigation navSegment = (UriResourceNavigation)part; - - // We have three scenarios we must handle: - // Entity(x)/Related, where Related is a 1:N or M:N relationship => result is a collection - // Entity(x)/Related, where Related is a N:1 or 1:1 relationship => result is a single entity - // Entity(x)/Related(z), where Related is a 1:N or M:N relationship => result is a single entity - if (navSegment.getKeyPredicates().isEmpty()) { - if ( isOne2ManyProperty(rootEntityType,navSegment.getProperty())) { - entityStream = readRelatedEntities(rootEntitySet,rootPredicates,navSegment.getProperty(),responseFormat); - } - else { - // The relation must point to another entity type, so casting should be safe here - EdmEntityType resultType = (EdmEntityType)rootEntityType.getNavigationProperty(navSegment.getProperty().getName()).getType(); - EdmEntitySet resultEntitySet = entitySetFromType(resultType); - - entityStream = readEntity(resultEntitySet, navSegment.getKeyPredicates(), responseFormat); - } - } - else { - entityStream = readRelatedEntity(request, rootEntitySet,rootPredicates,navSegment.getProperty(),navSegment.getKeyPredicates(),responseFormat); - } - + entityStream = readRelatedEntity(request, rootEntitySet,rootPredicates,navSegment.getProperty(),navSegment.getKeyPredicates(),responseFormat); } else { // For now, we'll only allow navigation just to directly linked navs @@ -161,14 +127,30 @@ public class JpaEntityProcessor implements EntityProcessor { } // - private boolean isOne2ManyProperty(EdmEntityType entityType, EdmNavigationProperty property) { - return entityType.getProperty(property.getName()) != null && property.isCollection(); - } + // private boolean isOne2ManyProperty(EdmEntityType entityType, EdmNavigationProperty property) { + // return entityType.getProperty(property.getName()) != null && property.isCollection(); + //} - private InputStream readEntity(EdmEntitySet entitySet, List keyPredicates,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - - Entity entity = readEntityData(entitySet,keyPredicates); + @SuppressWarnings({ "rawtypes", "unchecked" }) + private InputStream readRootEntity(EdmEntitySet entitySet, List keyPredicates,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { + EdmEntityType type = entitySet.getEntityType(); + JpaRepository repo = registry.getRepositoryForEntity(type); + // Get key value + Long keyValue = getEntityKey(keyPredicates); + Optional entry = repo.findById(keyValue); + if ( !entry.isPresent()) { + throw new ODataApplicationException( + "[E116] NO entity found for the given key", + HttpStatusCode.NOT_FOUND.getStatusCode(), + Locale.ENGLISH); + } + + Entity e = entityMapper.map2entity(entitySet, entry.get()); + return serializeEntity(entitySet,e,responseFormat); + } + + private InputStream serializeEntity(EdmEntitySet entitySet, Entity entity,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { ContextURL contextUrl = ContextURL.with().entitySet(entitySet).build(); // expand and select currently not supported EntitySerializerOptions options = EntitySerializerOptions @@ -180,157 +162,101 @@ public class JpaEntityProcessor implements EntityProcessor { SerializerResult serializerResult = serializer.entity(serviceMetadata, entitySet.getEntityType(), entity, options); return serializerResult.getContent(); + } - private InputStream readRelatedEntities(EdmEntitySet rootEntitySet, List rootPredicates, EdmNavigationProperty property, ContentType responseFormat) throws ODataApplicationException { - - Object jpaEntity = readJPAEntity(rootEntitySet, rootPredicates); - try { - Object set = PropertyUtils.getProperty(jpaEntity, property.getName()); - EdmEntitySet entitySet = entitySetFromType(property.getType()); - ContextURL contextUrl = ContextURL - .with() - .entitySet(entitySet) - .build(); - - EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions - .with() - .contextURL(contextUrl) - .build(); - - EntityCollection result = new EntityCollection(); - - ((Collection)set) - .stream() - .map((o) -> this.entityMapper.map2entity(entitySet, o)) - .forEach((e) -> result.getEntities().add(e)); - - ODataSerializer serializer = odata.createSerializer(responseFormat); - SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, property.getType(), result, options); - return serializerResult.getContent(); - } - catch(Exception ex) { - throw new ODataRuntimeException("[E181] Error accessing database", ex); - } - } +// @SuppressWarnings("unchecked") +// protected InputStream readRelatedEntities(EdmEntitySet rootEntitySet, List rootPredicates, EdmNavigationProperty property, ContentType responseFormat) throws ODataApplicationException { +// +// Object jpaEntity = readJPAEntity(rootEntitySet, rootPredicates); +// try { +// Collection set = (Collection)PropertyUtils.getProperty(jpaEntity, property.getName()); +// EdmEntitySet entitySet = entitySetFromType(property.getType()); +// ContextURL contextUrl = ContextURL +// .with() +// .entitySet(entitySet) +// .build(); +// +// EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions +// .with() +// .contextURL(contextUrl) +// .build(); +// +// EntityCollection result = new EntityCollection(); +// +// set.stream() +// .map((o) -> this.entityMapper.map2entity(entitySet, o)) +// .forEach((e) -> result.getEntities().add(e)); +// +// ODataSerializer serializer = odata.createSerializer(responseFormat); +// SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, property.getType(), result, options); +// return serializerResult.getContent(); +// } +// catch(Exception ex) { +// throw new ODataRuntimeException("[E181] Error accessing database", ex); +// } +// } - @SuppressWarnings({ "rawtypes", "serial", "unchecked" }) - private InputStream readRelatedEntity(ODataRequest request, EdmEntitySet rootEntitySet, List rootPredicates, EdmNavigationProperty property, List predicates, ContentType responseFormat) throws ODataApplicationException, SerializerException { + @SuppressWarnings({ "rawtypes", "unchecked" }) + private InputStream readRelatedEntity(ODataRequest request, EdmEntitySet entitySet, List rootPredicates, EdmNavigationProperty property, List parentPredicates, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - JpaSpecificationExecutor rootRepo = (JpaSpecificationExecutor)registry.getRepositoryForEntity(rootEntitySet.getEntityType()); - JpaSpecificationExecutor repo = (JpaSpecificationExecutor)registry.getRepositoryForEntity(property.getType()); + JpaRepository repo = (JpaRepository)registry.getRepositoryForEntity(entitySet.getEntityType()); + EdmEntityRepository relatedRepo = (EdmEntityRepository)registry.getRepositoryForEntity(property.getType()); // We assume here that we have a bi-directional 1:N relationship, so we'll // always have a property in the child entity that points to the parent - Class rootClass = ((EdmEntityRepository)rootRepo).getEntityClass(); - Class childClass = ((EdmEntityRepository)repo).getEntityClass(); + Class rootClass = ((EdmEntityRepository)repo).getEntityClass(); + Class relatedClass = ((EdmEntityRepository)relatedRepo).getEntityClass(); + SingularAttribute fk = emf.getMetamodel() - .entity(childClass) + .entity(rootClass) .getSingularAttributes() .stream() - .filter((attr) -> attr.isAssociation() && attr.getJavaType().isAssignableFrom(rootClass)) + .filter((attr) -> { + boolean b = attr.isAssociation() && attr.getJavaType().isAssignableFrom(relatedClass); + return b; + }) .findFirst() .orElse(null); - SingularAttribute pk = emf.getMetamodel() - .entity(childClass) - .getId(Long.class); - - SingularAttribute rootPk = emf.getMetamodel() - .entity(rootClass) - .getId(Long.class); - if ( fk == null ) { - throw new ODataRuntimeException("[E230] No singular attribute of child class '" + childClass.getName() + "' found" ); + throw new ODataRuntimeException("[E230] No singular attribute of child class '" + relatedClass.getName() + "' found" ); } - - Specification spec = new Specification() { - @Override - public Predicate toPredicate(Root root, CriteriaQuery q, CriteriaBuilder cb) { + Long pkValue = getEntityKey(rootPredicates); + EntityManager em = this.emf.createEntityManager(); + try { + // Read data from DB + Object root = em.find(rootClass, pkValue); + Object related = this.entityMapper.getPropertyValue(root, fk.getName()); - try { - Object rootInstance = rootClass.newInstance(); - PropertyUtils.setProperty(rootInstance, rootPk.getName(), getEntityKey(rootEntitySet.getEntityType(),rootPredicates)); - - final Predicate p = cb.and( - cb.equal( - root.get(pk), - getEntityKey(property.getType(),predicates)), - cb.equal( - root.get(fk), - rootInstance)); - - return p; - } - catch(Exception ex) { - throw new ODataRuntimeException(ex); - } - - } - }; - - // Read data from DB - EdmEntitySet relatedEntitySet = entitySetFromType(property.getType()); - EntityCollection data = new EntityCollection(); - - repo.findAll(spec) - .stream() - .forEach((entry) -> data.getEntities().add(entityMapper.map2entity(relatedEntitySet, entry))); - - // - - ODataSerializer serializer = odata.createSerializer(responseFormat); - - // 4th: Now serialize the content: transform from the EntitySet object to InputStream - EdmEntityType edmEntityType = relatedEntitySet.getEntityType(); - ContextURL contextUrl = ContextURL.with() - .entitySet(relatedEntitySet) - .build(); - - final String id = request.getRawBaseUri() + "/" + relatedEntitySet.getName(); - EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with() - .id(id) - .contextURL(contextUrl) - .build(); - SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, data, opts); - InputStream serializedContent = serializerResult.getContent(); - - - return serializedContent; - } - - - /** - * This method returns a speficic entity given its primary key - * @param edmEntitySet - * @param keyPredicates - * @return - */ - protected Entity readEntityData(EdmEntitySet edmEntitySet, List keyPredicates) throws ODataApplicationException { - - Object jpaEntry = readJPAEntity(edmEntitySet, keyPredicates); - Entity e = entityMapper.map2entity(edmEntitySet, jpaEntry); - return e; - } - - private Object readJPAEntity(EdmEntitySet edmEntitySet, List keyPredicates) throws ODataApplicationException { - EdmEntityType type = edmEntitySet.getEntityType(); - JpaRepository repo = (JpaRepository)registry.getRepositoryForEntity(type); - - // Get key value - Object keyValue = getEntityKey(type,keyPredicates); - Object entry = repo - .findById(keyValue) - .orElseThrow( - () -> new ODataApplicationException("[E116] NO entity found for the given key", - HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH)); - - return entry; + EdmEntitySet relatedEntitySet = entitySetFromType(property.getType()); + Entity e = entityMapper.map2entity(relatedEntitySet, related); + return serializeEntity(relatedEntitySet,e,responseFormat); + } + finally { + em.close(); + } } - private Object getEntityKey(EdmEntityType type, List keyPredicates) { +// @SuppressWarnings("unchecked") +// private Object readJPAEntity(EdmEntitySet edmEntitySet, List keyPredicates) throws ODataApplicationException { +// EdmEntityType type = edmEntitySet.getEntityType(); +// JpaRepository repo = (JpaRepository)registry.getRepositoryForEntity(type); +// +// // Get key value +// Object keyValue = getEntityKey(type,keyPredicates); +// Object entry = repo +// .findById(keyValue) +// .orElseThrow( +// () -> new ODataApplicationException("[E116] NO entity found for the given key", +// HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH)); +// +// return entry; +// } + + private Long getEntityKey(List keyPredicates) { if ( keyPredicates.size() > 1 ) { throw new ODataRuntimeException("[E131] Composite keys are not supported"); diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java index 20981fdfef..e3bb172e3a 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java @@ -5,23 +5,25 @@ import java.util.List; import java.util.Map; import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Component; @Component public class RepositoryRegistry { - private Map> repositoriesByClassName = new HashMap<>(); + private Map> repositoriesByClassName = new HashMap<>(); public RepositoryRegistry(List> allRepositories) { - allRepositories.stream().forEach((r) -> - repositoriesByClassName.put(r.getEdmEntityName(),(EdmEntityRepository)r)); + allRepositories.stream() + .forEach((r) -> + repositoriesByClassName.put(r.getEdmEntityName(),(JpaRepository)r)); } - public EdmEntityRepository getRepositoryForEntity(EdmEntityType entityType) { - EdmEntityRepository repo = repositoriesByClassName.get(entityType.getName()); + public JpaRepository getRepositoryForEntity(EdmEntityType entityType) { + JpaRepository repo = repositoriesByClassName.get(entityType.getName()); return repo; } } diff --git a/apache-olingo/olingo4/src/main/resources/application.properties b/apache-olingo/olingo4/src/main/resources/application.properties index e4742b4fbb..02c7fe5c4d 100644 --- a/apache-olingo/olingo4/src/main/resources/application.properties +++ b/apache-olingo/olingo4/src/main/resources/application.properties @@ -4,6 +4,6 @@ server: spring: jpa: show-sql: true - open-in-view: false + open-in-view: true hibernate: ddl-auto: update From 8372ad4a379d45eb9f0f0f6e44efc443bee1cde7 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Fri, 26 Apr 2019 00:39:53 +0530 Subject: [PATCH 022/185] [BAEL-14118] - Make sure the tutorials build doesn't generate any un-committed or un-ignored artifacts --- .gitignore | 3 +- core-groovy/.gitignore | 1 + .../src/main/resources/ioSerializedObject.txt | Bin 199 -> 0 bytes .../baeldung/io/DataAndObjectsUnitTest.groovy | 4 +- jackson-2/.gitignore | 5 +- .../jhipster-microservice/car-app/pom.xml | 166 ++++++++--------- .../jhipster-microservice/dealer-app/pom.xml | 164 ++++++++--------- .../jhipster-microservice/gateway-app/pom.xml | 172 +++++++++--------- testing-modules/groovy-spock/.gitignore | 1 + 9 files changed, 262 insertions(+), 254 deletions(-) create mode 100644 core-groovy/.gitignore delete mode 100644 core-groovy/src/main/resources/ioSerializedObject.txt create mode 100644 testing-modules/groovy-spock/.gitignore diff --git a/.gitignore b/.gitignore index b981a473f6..50cb889e5b 100644 --- a/.gitignore +++ b/.gitignore @@ -76,4 +76,5 @@ 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 +spring-soap/src/main/java/com/baeldung/springsoap/gen/ +/report-*.json \ No newline at end of file diff --git a/core-groovy/.gitignore b/core-groovy/.gitignore new file mode 100644 index 0000000000..09220fdf52 --- /dev/null +++ b/core-groovy/.gitignore @@ -0,0 +1 @@ +/src/main/resources/ioSerializedObject.txt \ No newline at end of file diff --git a/core-groovy/src/main/resources/ioSerializedObject.txt b/core-groovy/src/main/resources/ioSerializedObject.txt deleted file mode 100644 index 833ed32bf128ecf8d2d6b6893b3959bc3c4bf8a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199 zcmZ4UmVvdnh(RPdKUXg)F*PTpG%sB*GhZ(xu{itSp^g0yHl1)~Vqo!PU@I<3EGaGa zVc + def serializedDataFile = new File('src/main/resources/ioSerializedObject.txt') + serializedDataFile.createNewFile() + serializedDataFile.withObjectOutputStream { out -> out.writeObject(task) } diff --git a/jackson-2/.gitignore b/jackson-2/.gitignore index 83c05e60c8..4b1cfaf098 100644 --- a/jackson-2/.gitignore +++ b/jackson-2/.gitignore @@ -10,4 +10,7 @@ # Packaged files # *.jar *.war -*.ear \ No newline at end of file +*.ear + +# Files +/src/main/resources/orderOutput.yaml \ No newline at end of file diff --git a/jhipster/jhipster-microservice/car-app/pom.xml b/jhipster/jhipster-microservice/car-app/pom.xml index 529877d448..86d94d0a44 100644 --- a/jhipster/jhipster-microservice/car-app/pom.xml +++ b/jhipster/jhipster-microservice/car-app/pom.xml @@ -1,21 +1,100 @@ 4.0.0 - com.car.app - car-app - car-app - war jhipster-microservice com.baeldung.jhipster 1.0.0-SNAPSHOT + com.car.app + car-app + war + car-app ${maven.version} + + -Djava.security.egd=file:/dev/./urandom -Xmx256m + 3.6.2 + 2.0.0 + 2.5 + 3.5 + 0.4.13 + 1.2 + 5.2.8.Final + 2.6.0 + 0.7.9 + 1.8 + 3.21.0-GA + 1.0.0 + 1.1.0 + 0.7.0 + 3.6 + 2.0.0 + 3.6.2 + 4.8 + jdt_apt + 1.1.0.Final + 2.10 + 1.4.1 + 3.0.1 + yyyyMMddHHmmss + 3.0.0 + 3.1.3 + v6.10.0 + + + + + ${project.build.directory}/test-results + 0.0.20 + false + 3.2.2 + 2.12.1 + 3.2 + + src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* + + S3437,UndocumentedApi,BoldAndItalicTagsCheck + + + src/main/webapp/app/**/*.* + Web:BoldAndItalicTagsCheck + + src/main/java/**/* + squid:S3437 + + src/main/java/**/* + squid:UndocumentedApi + + ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec + ${project.testresult.directory}/coverage/jacoco/jacoco.exec + jacoco + + ${project.testresult.directory}/karma + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.basedir}/src/main/ + ${project.testresult.directory}/surefire-reports + ${project.basedir}/src/test/ + + 2.5.0 + + Camden.SR5 + 2.6.1 + 1.4.10.Final + 1.1.0.Final + v0.21.3 + + @@ -819,83 +898,4 @@ - - -Djava.security.egd=file:/dev/./urandom -Xmx256m - 3.6.2 - 2.0.0 - 2.5 - 3.5 - 0.4.13 - 1.2 - 5.2.8.Final - 2.6.0 - 0.7.9 - 1.8 - 3.21.0-GA - 1.0.0 - 1.1.0 - 0.7.0 - 3.6 - 2.0.0 - 3.6.2 - 4.8 - jdt_apt - 1.1.0.Final - 2.10 - 1.4.1 - 3.0.1 - yyyyMMddHHmmss - 3.0.0 - 3.1.3 - v6.10.0 - - - - - ${project.build.directory}/test-results - 0.0.20 - false - 3.2.2 - 2.12.1 - 3.2 - - src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* - - S3437,UndocumentedApi,BoldAndItalicTagsCheck - - - src/main/webapp/app/**/*.* - Web:BoldAndItalicTagsCheck - - src/main/java/**/* - squid:S3437 - - src/main/java/**/* - squid:UndocumentedApi - - ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec - ${project.testresult.directory}/coverage/jacoco/jacoco.exec - jacoco - - ${project.testresult.directory}/karma - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.basedir}/src/main/ - ${project.testresult.directory}/surefire-reports - ${project.basedir}/src/test/ - - 2.5.0 - - Camden.SR5 - 2.6.1 - 1.4.10.Final - 1.1.0.Final - v0.21.3 - - diff --git a/jhipster/jhipster-microservice/dealer-app/pom.xml b/jhipster/jhipster-microservice/dealer-app/pom.xml index 1eac8a930e..3051399ae6 100644 --- a/jhipster/jhipster-microservice/dealer-app/pom.xml +++ b/jhipster/jhipster-microservice/dealer-app/pom.xml @@ -1,21 +1,99 @@ 4.0.0 - com.dealer.app - dealer-app - dealer-app - war jhipster-microservice com.baeldung.jhipster 1.0.0-SNAPSHOT + com.dealer.app + dealer-app + war + dealer-app ${maven.version} + + -Djava.security.egd=file:/dev/./urandom -Xmx256m + 3.6.2 + 2.0.0 + 2.5 + 3.5 + 0.4.13 + 1.2 + 5.2.8.Final + 2.6.0 + 0.7.9 + 3.21.0-GA + 1.0.0 + 1.1.0 + 0.7.0 + 3.6 + 2.0.0 + 3.6.2 + 4.8 + jdt_apt + 1.1.0.Final + 2.10 + 1.4.1 + 3.0.1 + yyyyMMddHHmmss + 3.0.0 + 3.1.3 + v6.10.0 + + + + + ${project.build.directory}/test-results + 0.0.20 + false + 3.2.2 + 2.12.1 + 3.2 + + src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* + + S3437,UndocumentedApi,BoldAndItalicTagsCheck + + + src/main/webapp/app/**/*.* + Web:BoldAndItalicTagsCheck + + src/main/java/**/* + squid:S3437 + + src/main/java/**/* + squid:UndocumentedApi + + ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec + ${project.testresult.directory}/coverage/jacoco/jacoco.exec + jacoco + + ${project.testresult.directory}/karma + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.basedir}/src/main/ + ${project.testresult.directory}/surefire-reports + ${project.basedir}/src/test/ + + 2.5.0 + + Camden.SR5 + 2.6.1 + 1.4.10.Final + 1.1.0.Final + v0.21.3 + + @@ -813,83 +891,5 @@ - - - -Djava.security.egd=file:/dev/./urandom -Xmx256m - 3.6.2 - 2.0.0 - 2.5 - 3.5 - 0.4.13 - 1.2 - 5.2.8.Final - 2.6.0 - 0.7.9 - 3.21.0-GA - 1.0.0 - 1.1.0 - 0.7.0 - 3.6 - 2.0.0 - 3.6.2 - 4.8 - jdt_apt - 1.1.0.Final - 2.10 - 1.4.1 - 3.0.1 - yyyyMMddHHmmss - 3.0.0 - 3.1.3 - v6.10.0 - - - - - ${project.build.directory}/test-results - 0.0.20 - false - 3.2.2 - 2.12.1 - 3.2 - src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* - - S3437,UndocumentedApi,BoldAndItalicTagsCheck - - - src/main/webapp/app/**/*.* - Web:BoldAndItalicTagsCheck - - src/main/java/**/* - squid:S3437 - - src/main/java/**/* - squid:UndocumentedApi - - ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec - ${project.testresult.directory}/coverage/jacoco/jacoco.exec - jacoco - - ${project.testresult.directory}/karma - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.basedir}/src/main/ - ${project.testresult.directory}/surefire-reports - ${project.basedir}/src/test/ - - 2.5.0 - - Camden.SR5 - 2.6.1 - 1.4.10.Final - 1.1.0.Final - v0.21.3 - - diff --git a/jhipster/jhipster-microservice/gateway-app/pom.xml b/jhipster/jhipster-microservice/gateway-app/pom.xml index babc9e4f24..4e2c19ed2d 100644 --- a/jhipster/jhipster-microservice/gateway-app/pom.xml +++ b/jhipster/jhipster-microservice/gateway-app/pom.xml @@ -1,21 +1,103 @@ 4.0.0 - com.gateway - gateway-app - gateway-app - war jhipster-microservice com.baeldung.jhipster 1.0.0-SNAPSHOT + com.gateway + gateway-app + war + gateway-app ${maven.version} + + -Djava.security.egd=file:/dev/./urandom -Xmx256m + 3.6.2 + 2.0.0 + 3.6.0 + 1.10 + 2.5 + 3.5 + 0.4.13 + 1.3 + 1.2 + 5.2.8.Final + 2.6.0 + 0.7.9 + 3.21.0-GA + 1.0.0 + 1.1.0 + 0.7.0 + 3.6 + 2.0.0 + 3.6.2 + 4.8 + 1.3.0 + jdt_apt + 1.1.0.Final + 2.10 + 1.4.1 + 3.0.1 + yyyyMMddHHmmss + 3.0.0 + 3.1.3 + v6.10.0 + + + + + ${project.build.directory}/test-results + 0.0.20 + false + 3.2.2 + 2.12.1 + 3.2 + + src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* + + S3437,UndocumentedApi,BoldAndItalicTagsCheck + + + src/main/webapp/app/**/*.* + Web:BoldAndItalicTagsCheck + + src/main/java/**/* + squid:S3437 + + src/main/java/**/* + squid:UndocumentedApi + + ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec + ${project.testresult.directory}/coverage/jacoco/jacoco.exec + jacoco + + ${project.testresult.directory}/karma + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.testresult.directory}/coverage/report-lcov/lcov.info + + ${project.basedir}/src/main/ + ${project.testresult.directory}/surefire-reports + ${project.basedir}/src/test/ + + 2.5.0 + + Camden.SR5 + 2.6.1 + 1.4.10.Final + 1.1.0.Final + v0.21.3 + + @@ -925,87 +1007,5 @@ - - - -Djava.security.egd=file:/dev/./urandom -Xmx256m - 3.6.2 - 2.0.0 - 3.6.0 - 1.10 - 2.5 - 3.5 - 0.4.13 - 1.3 - 1.2 - 5.2.8.Final - 2.6.0 - 0.7.9 - 3.21.0-GA - 1.0.0 - 1.1.0 - 0.7.0 - 3.6 - 2.0.0 - 3.6.2 - 4.8 - 1.3.0 - jdt_apt - 1.1.0.Final - 2.10 - 1.4.1 - 3.0.1 - yyyyMMddHHmmss - 3.0.0 - 3.1.3 - v6.10.0 - - - - - ${project.build.directory}/test-results - 0.0.20 - false - 3.2.2 - 2.12.1 - 3.2 - - src/main/webapp/content/**/*.*, src/main/webapp/bower_components/**/*.*, src/main/webapp/i18n/*.js, target/www/**/*.* - - S3437,UndocumentedApi,BoldAndItalicTagsCheck - - - src/main/webapp/app/**/*.* - Web:BoldAndItalicTagsCheck - - src/main/java/**/* - squid:S3437 - - src/main/java/**/* - squid:UndocumentedApi - - ${project.testresult.directory}/coverage/jacoco/jacoco-it.exec - ${project.testresult.directory}/coverage/jacoco/jacoco.exec - jacoco - - ${project.testresult.directory}/karma - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.testresult.directory}/coverage/report-lcov/lcov.info - - ${project.basedir}/src/main/ - ${project.testresult.directory}/surefire-reports - ${project.basedir}/src/test/ - - 2.5.0 - - Camden.SR5 - 2.6.1 - 1.4.10.Final - 1.1.0.Final - v0.21.3 - diff --git a/testing-modules/groovy-spock/.gitignore b/testing-modules/groovy-spock/.gitignore new file mode 100644 index 0000000000..37118ef42c --- /dev/null +++ b/testing-modules/groovy-spock/.gitignore @@ -0,0 +1 @@ +/report-*.json \ No newline at end of file From 7fa1c651e5bf3952a8590cac29897a0b80d98d94 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Wed, 1 May 2019 20:51:42 +0530 Subject: [PATCH 023/185] [BAEL-12800] - Fixed the multiple DB article codebase --- .../PersistenceProductConfiguration.java | 20 ++++++-------- .../PersistenceUserConfiguration.java | 26 +++++++++---------- .../persistence-multiple-db.properties | 17 +++++++----- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java index bcf2cd84eb..9dfa8f2bbf 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java @@ -1,22 +1,23 @@ package com.baeldung.multipledb; -import com.google.common.base.Preconditions; +import java.util.HashMap; + +import javax.sql.DataSource; + import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; -import javax.sql.DataSource; -import java.util.HashMap; - @Configuration @PropertySource({"classpath:persistence-multiple-db.properties"}) @EnableJpaRepositories(basePackages = "com.baeldung.multipledb.dao.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager") @@ -48,14 +49,9 @@ public class PersistenceProductConfiguration { } @Bean + @ConfigurationProperties(prefix="spring.product") public DataSource productDataSource() { - final DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); - dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("product.jdbc.url"))); - dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); - dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); - - return dataSource; + return DataSourceBuilder.create().build(); } @Bean diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserConfiguration.java index 6b48455c0c..3d2b42837e 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserConfiguration.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserConfiguration.java @@ -1,19 +1,24 @@ package com.baeldung.multipledb; -import com.google.common.base.Preconditions; +import java.util.HashMap; + +import javax.sql.DataSource; + import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.*; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.Profile; +import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; -import javax.sql.DataSource; -import java.util.HashMap; - @Configuration @PropertySource({"classpath:persistence-multiple-db.properties"}) @EnableJpaRepositories(basePackages = "com.baeldung.multipledb.dao.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager") @@ -48,14 +53,9 @@ public class PersistenceUserConfiguration { @Primary @Bean + @ConfigurationProperties(prefix="spring.user") public DataSource userDataSource() { - final DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); - dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("user.jdbc.url"))); - dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); - dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); - - return dataSource; + return DataSourceBuilder.create().build(); } @Primary diff --git a/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db.properties b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db.properties index 75534e8a54..b847442ef1 100644 --- a/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db.properties +++ b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db.properties @@ -1,9 +1,14 @@ -# jdbc.X -jdbc.driverClassName=org.h2.Driver -user.jdbc.url=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS -product.jdbc.url=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS -jdbc.user=sa -jdbc.pass=sa +# user data source +spring.user.driverClassName=org.h2.Driver +spring.user.jdbc-url=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS +spring.user.username=sa +spring.user.username=sa + +# product data source +spring.product.driverClassName=org.h2.Driver +spring.product.jdbc-url=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS +spring.product.username=sa +spring.product.username=sa # hibernate.X hibernate.dialect=org.hibernate.dialect.H2Dialect From 8e5d85cd85d6775da1727e576e1f5829fad0c08b Mon Sep 17 00:00:00 2001 From: amit2103 Date: Thu, 2 May 2019 00:35:32 +0530 Subject: [PATCH 024/185] [BAEL-12800] - Added MultipleDataSourceConfiguration and added autowiring of DataSources in Product and User Config classes --- .../MultipleDataSourceConfiguration.java | 33 ++++++++++++++++++ .../PersistenceProductConfiguration.java | 27 ++++++++++----- .../PersistenceUserConfiguration.java | 34 +++++++++++-------- .../persistence-multiple-db-boot.properties | 18 ++++++++++ .../persistence-multiple-db.properties | 17 ++++------ 5 files changed, 94 insertions(+), 35 deletions(-) create mode 100644 persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDataSourceConfiguration.java create mode 100644 persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDataSourceConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDataSourceConfiguration.java new file mode 100644 index 0000000000..00866f380a --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/MultipleDataSourceConfiguration.java @@ -0,0 +1,33 @@ +package com.baeldung.multipledb; + +import javax.sql.DataSource; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +/** + * By default, the persistence-multiple-db.properties file is read for productDataSource() and userDataSource() + * in PersistenceProductConfiguration and PersistenceUserConfiguration respectively. + *

+ * If we need to use persistence-multiple-db-boot.properties then uncomment the below @Configuration class and comment out + * productDataSource() and userDataSource() in PersistenceProductConfiguration and PersistenceUserConfiguration. + */ +//@Configuration +@PropertySource({"classpath:persistence-multiple-db-boot.properties"}) +public class MultipleDataSourceConfiguration { + + @Bean + @ConfigurationProperties(prefix="spring.user") + public DataSource userDataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean + @ConfigurationProperties(prefix="spring.product") + public DataSource productDataSource() { + return DataSourceBuilder.create().build(); + } +} \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java index 9dfa8f2bbf..cd09045c50 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceProductConfiguration.java @@ -1,23 +1,23 @@ package com.baeldung.multipledb; -import java.util.HashMap; - -import javax.sql.DataSource; - +import com.google.common.base.Preconditions; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; +import javax.sql.DataSource; +import java.util.HashMap; + @Configuration @PropertySource({"classpath:persistence-multiple-db.properties"}) @EnableJpaRepositories(basePackages = "com.baeldung.multipledb.dao.product", entityManagerFactoryRef = "productEntityManager", transactionManagerRef = "productTransactionManager") @@ -25,6 +25,10 @@ import org.springframework.transaction.PlatformTransactionManager; public class PersistenceProductConfiguration { @Autowired private Environment env; + + @Autowired + @Qualifier("productDataSource") + private DataSource productDataSource; public PersistenceProductConfiguration() { super(); @@ -35,7 +39,7 @@ public class PersistenceProductConfiguration { @Bean public LocalContainerEntityManagerFactoryBean productEntityManager() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); - em.setDataSource(productDataSource()); + em.setDataSource(productDataSource); em.setPackagesToScan("com.baeldung.multipledb.model.product"); final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); @@ -49,9 +53,14 @@ public class PersistenceProductConfiguration { } @Bean - @ConfigurationProperties(prefix="spring.product") public DataSource productDataSource() { - return DataSourceBuilder.create().build(); + final DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("product.jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; } @Bean diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserConfiguration.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserConfiguration.java index 3d2b42837e..f557deee8e 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserConfiguration.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/multipledb/PersistenceUserConfiguration.java @@ -1,24 +1,20 @@ package com.baeldung.multipledb; -import java.util.HashMap; - -import javax.sql.DataSource; - +import com.google.common.base.Preconditions; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.context.annotation.Profile; -import org.springframework.context.annotation.PropertySource; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.*; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; +import javax.sql.DataSource; +import java.util.HashMap; + @Configuration @PropertySource({"classpath:persistence-multiple-db.properties"}) @EnableJpaRepositories(basePackages = "com.baeldung.multipledb.dao.user", entityManagerFactoryRef = "userEntityManager", transactionManagerRef = "userTransactionManager") @@ -26,6 +22,10 @@ import org.springframework.transaction.PlatformTransactionManager; public class PersistenceUserConfiguration { @Autowired private Environment env; + + @Autowired + @Qualifier("userDataSource") + private DataSource userDataSource; public PersistenceUserConfiguration() { super(); @@ -38,7 +38,7 @@ public class PersistenceUserConfiguration { public LocalContainerEntityManagerFactoryBean userEntityManager() { System.out.println("loading config"); final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); - em.setDataSource(userDataSource()); + em.setDataSource(userDataSource); em.setPackagesToScan("com.baeldung.multipledb.model.user"); final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); @@ -51,11 +51,15 @@ public class PersistenceUserConfiguration { return em; } - @Primary @Bean - @ConfigurationProperties(prefix="spring.user") public DataSource userDataSource() { - return DataSourceBuilder.create().build(); + final DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("user.jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; } @Primary diff --git a/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties new file mode 100644 index 0000000000..b847442ef1 --- /dev/null +++ b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties @@ -0,0 +1,18 @@ +# user data source +spring.user.driverClassName=org.h2.Driver +spring.user.jdbc-url=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS +spring.user.username=sa +spring.user.username=sa + +# product data source +spring.product.driverClassName=org.h2.Driver +spring.product.jdbc-url=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS +spring.product.username=sa +spring.product.username=sa + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=false +hibernate.cache.use_query_cache=false \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db.properties b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db.properties index b847442ef1..75534e8a54 100644 --- a/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db.properties +++ b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db.properties @@ -1,14 +1,9 @@ -# user data source -spring.user.driverClassName=org.h2.Driver -spring.user.jdbc-url=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS -spring.user.username=sa -spring.user.username=sa - -# product data source -spring.product.driverClassName=org.h2.Driver -spring.product.jdbc-url=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS -spring.product.username=sa -spring.product.username=sa +# jdbc.X +jdbc.driverClassName=org.h2.Driver +user.jdbc.url=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS +product.jdbc.url=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS +jdbc.user=sa +jdbc.pass=sa # hibernate.X hibernate.dialect=org.hibernate.dialect.H2Dialect From 7dae64dd749ea9b67072d4a83975b4f6735221aa Mon Sep 17 00:00:00 2001 From: Sushant Date: Sat, 4 May 2019 12:56:10 +0300 Subject: [PATCH 025/185] Moved guava set related code to guava-collections-set module --- .../org/baeldung/guava/GuavaMapFromSet.java | 15 +- .../guava/GuavaMapFromSetUnitTest.java | 7 +- .../baeldung/guava/GuavaRangeSetUnitTest.java | 126 ++++++++++++++++ .../guava/GuavaSetOperationsUnitTest.java | 138 ++++++++++++++++++ .../guava/GuavaCollectionTypesUnitTest.java | 114 --------------- 5 files changed, 272 insertions(+), 128 deletions(-) rename {guava-collections => guava-collections-set}/src/test/java/org/baeldung/guava/GuavaMapFromSet.java (87%) rename {guava-collections => guava-collections-set}/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java (99%) create mode 100644 guava-collections-set/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java create mode 100644 guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java diff --git a/guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSet.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java similarity index 87% rename from guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSet.java rename to guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java index 1d19423f7e..94224c08ab 100644 --- a/guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSet.java +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java @@ -1,14 +1,9 @@ package org.baeldung.guava; -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.WeakHashMap; - import com.google.common.base.Function; +import java.util.*; + public class GuavaMapFromSet extends AbstractMap { private class SingleEntry implements Entry { @@ -54,7 +49,7 @@ public class GuavaMapFromSet extends AbstractMap { } @Override - public Map.Entry next() { + public Entry next() { K key = this.inner.next(); return new SingleEntry(key); } @@ -72,7 +67,7 @@ public class GuavaMapFromSet extends AbstractMap { } @Override - public Iterator> iterator() { + public Iterator> iterator() { return new EntryIterator(); } @@ -94,7 +89,7 @@ public class GuavaMapFromSet extends AbstractMap { } @Override - public Set> entrySet() { + public Set> entrySet() { return this.entries; } diff --git a/guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java similarity index 99% rename from guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java rename to guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java index d80f047f5c..03f2d8f891 100644 --- a/guava-collections/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSetUnitTest.java @@ -1,15 +1,14 @@ package org.baeldung.guava; -import static org.junit.Assert.assertTrue; +import com.google.common.base.Function; +import org.junit.Test; import java.util.Arrays; import java.util.Map; import java.util.Set; import java.util.TreeSet; -import org.junit.Test; - -import com.google.common.base.Function; +import static org.junit.Assert.assertTrue; public class GuavaMapFromSetUnitTest { diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java new file mode 100644 index 0000000000..b72cfdeea6 --- /dev/null +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java @@ -0,0 +1,126 @@ +package org.baeldung.guava; + +import com.google.common.collect.ImmutableRangeSet; +import com.google.common.collect.Range; +import com.google.common.collect.RangeSet; +import com.google.common.collect.TreeRangeSet; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class GuavaRangeSetUnitTest { + + @Test + public void givenRangeSet_whenQueryWithinRange_returnsSucessfully() { + final RangeSet numberRangeSet = TreeRangeSet.create(); + + numberRangeSet.add(Range.closed(0, 2)); + numberRangeSet.add(Range.closed(3, 5)); + numberRangeSet.add(Range.closed(6, 8)); + + assertTrue(numberRangeSet.contains(1)); + assertFalse(numberRangeSet.contains(9)); + } + + @Test + public void givenRangeSet_whenEnclosesWithinRange_returnsSucessfully() { + final RangeSet numberRangeSet = TreeRangeSet.create(); + + numberRangeSet.add(Range.closed(0, 2)); + numberRangeSet.add(Range.closed(3, 10)); + numberRangeSet.add(Range.closed(15, 18)); + + assertTrue(numberRangeSet.encloses(Range.closed(4, 5))); + assertFalse(numberRangeSet.encloses(Range.closed(4, 11))); + } + + @Test + public void givenRangeSet_whenComplementIsCalled_returnsSucessfully() { + final RangeSet numberRangeSet = TreeRangeSet.create(); + + numberRangeSet.add(Range.closed(0, 2)); + numberRangeSet.add(Range.closed(3, 5)); + numberRangeSet.add(Range.closed(6, 8)); + final RangeSet numberRangeComplementSet = numberRangeSet.complement(); + + assertTrue(numberRangeComplementSet.contains(-1000)); + assertFalse(numberRangeComplementSet.contains(2)); + assertFalse(numberRangeComplementSet.contains(3)); + assertTrue(numberRangeComplementSet.contains(1000)); + } + + @Test + public void givenRangeSet_whenIntersectsWithinRange_returnsSucessfully() { + final RangeSet numberRangeSet = TreeRangeSet.create(); + + numberRangeSet.add(Range.closed(0, 2)); + numberRangeSet.add(Range.closed(3, 10)); + numberRangeSet.add(Range.closed(15, 18)); + + assertTrue(numberRangeSet.intersects(Range.closed(4, 17))); + assertFalse(numberRangeSet.intersects(Range.closed(19, 200))); + } + + @Test + public void givenRangeSet_whenRemoveRangeIsCalled_removesSucessfully() { + final RangeSet numberRangeSet = TreeRangeSet.create(); + + numberRangeSet.add(Range.closed(0, 2)); + numberRangeSet.add(Range.closed(3, 5)); + numberRangeSet.add(Range.closed(6, 8)); + numberRangeSet.add(Range.closed(9, 15)); + numberRangeSet.remove(Range.closed(3, 5)); + numberRangeSet.remove(Range.closed(7, 10)); + + assertTrue(numberRangeSet.contains(1)); + assertFalse(numberRangeSet.contains(9)); + assertTrue(numberRangeSet.contains(12)); + } + + @Test + public void givenRangeSet_whenSpanIsCalled_returnsSucessfully() { + final RangeSet numberRangeSet = TreeRangeSet.create(); + + numberRangeSet.add(Range.closed(0, 2)); + numberRangeSet.add(Range.closed(3, 5)); + numberRangeSet.add(Range.closed(6, 8)); + final Range experienceSpan = numberRangeSet.span(); + + assertEquals(0, experienceSpan.lowerEndpoint().intValue()); + assertEquals(8, experienceSpan.upperEndpoint().intValue()); + } + + @Test + public void givenRangeSet_whenSubRangeSetIsCalled_returnsSubRangeSucessfully() { + final RangeSet numberRangeSet = TreeRangeSet.create(); + + numberRangeSet.add(Range.closed(0, 2)); + numberRangeSet.add(Range.closed(3, 5)); + numberRangeSet.add(Range.closed(6, 8)); + final RangeSet numberSubRangeSet = numberRangeSet.subRangeSet(Range.closed(4, 14)); + + assertFalse(numberSubRangeSet.contains(3)); + assertFalse(numberSubRangeSet.contains(14)); + assertTrue(numberSubRangeSet.contains(7)); + } + + @Test + public void givenImmutableRangeSet_whenQueryWithinRange_returnsSucessfully() { + final RangeSet numberRangeSet = ImmutableRangeSet. builder() + .add(Range.closed(0, 2)) + .add(Range.closed(3, 5)) + .add(Range.closed(6, 8)).build(); + + assertTrue(numberRangeSet.contains(6)); + assertFalse(numberRangeSet.contains(15)); + } + + @Test(expected = IllegalArgumentException.class) + public void givenImmutableRangeMap_whenRangeOverlaps_ThrowsException() { + ImmutableRangeSet. builder() + .add(Range.closed(0, 2)) + .add(Range.closed(3, 5)) + .add(Range.closed(5, 8)).build(); + + } +} diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java new file mode 100644 index 0000000000..4733a15392 --- /dev/null +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java @@ -0,0 +1,138 @@ +package org.baeldung.guava; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.collect.*; +import org.junit.Test; + +import java.util.List; +import java.util.Set; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class GuavaSetOperationsUnitTest { + + @Test + public void whenCalculateUnionOfSets_thenCorrect() { + final Set first = ImmutableSet.of('a', 'b', 'c'); + final Set second = ImmutableSet.of('b', 'c', 'd'); + + final Set union = Sets.union(first, second); + assertThat(union, containsInAnyOrder('a', 'b', 'c', 'd')); + } + + @Test + public void whenCalculateSetsProduct_thenCorrect() { + final Set first = ImmutableSet.of('a', 'b'); + final Set second = ImmutableSet.of('c', 'd'); + final Set> result = Sets.cartesianProduct(ImmutableList.of(first, second)); + + final Function, String> func = new Function, String>() { + @Override + public final String apply(final List input) { + return Joiner + .on(" ").join(input); + } + }; + + final Iterable joined = Iterables.transform(result, func); + assertThat(joined, containsInAnyOrder("a c", "a d", "b c", "b d")); + } + + @Test + public void whenCalculatingSetIntersection_thenCorrect() { + final Set first = ImmutableSet.of('a', 'b', 'c'); + final Set second = ImmutableSet.of('b', 'c', 'd'); + + final Set intersection = Sets.intersection(first, second); + assertThat(intersection, containsInAnyOrder('b', 'c')); + } + + @Test + public void whenCalculatingSetSymmetricDifference_thenCorrect() { + final Set first = ImmutableSet.of('a', 'b', 'c'); + final Set second = ImmutableSet.of('b', 'c', 'd'); + + final Set intersection = Sets.symmetricDifference(first, second); + assertThat(intersection, containsInAnyOrder('a', 'd')); + } + + @Test + public void whenCalculatingPowerSet_thenCorrect() { + final Set chars = ImmutableSet.of('a', 'b'); + final Set> result = Sets.powerSet(chars); + + final Set empty = ImmutableSet. builder().build(); + final Set a = ImmutableSet.of('a'); + final Set b = ImmutableSet.of('b'); + final Set aB = ImmutableSet.of('a', 'b'); + + assertThat(result, contains(empty, a, b, aB)); + } + + @Test + public void whenCreateRangeOfIntegersSet_thenCreated() { + final int start = 10; + final int end = 30; + final ContiguousSet set = ContiguousSet.create(Range.closed(start, end), DiscreteDomain.integers()); + + assertEquals(21, set.size()); + assertEquals(10, set.first().intValue()); + assertEquals(30, set.last().intValue()); + } + + @Test + public void whenCreateRangeSet_thenCreated() { + final RangeSet rangeSet = TreeRangeSet.create(); + rangeSet.add(Range.closed(1, 10)); + rangeSet.add(Range.closed(12, 15)); + + assertEquals(2, rangeSet.asRanges().size()); + + rangeSet.add(Range.closed(10, 12)); + assertTrue(rangeSet.encloses(Range.closed(1, 15))); + assertEquals(1, rangeSet.asRanges().size()); + } + + @Test + public void whenInsertDuplicatesInMultiSet_thenInserted() { + final Multiset names = HashMultiset.create(); + names.add("John"); + names.add("Adam", 3); + names.add("John"); + + assertEquals(2, names.count("John")); + names.remove("John"); + assertEquals(1, names.count("John")); + + assertEquals(3, names.count("Adam")); + names.remove("Adam", 2); + assertEquals(1, names.count("Adam")); + } + + @Test + public void whenGetTopUsingMultiSet_thenCorrect() { + final Multiset names = HashMultiset.create(); + names.add("John"); + names.add("Adam", 5); + names.add("Jane"); + names.add("Tom", 2); + + final Set sorted = Multisets.copyHighestCountFirst(names).elementSet(); + final List topTwo = Lists.newArrayList(sorted).subList(0, 2); + assertEquals(2, topTwo.size()); + assertEquals("Adam", topTwo.get(0)); + assertEquals("Tom", topTwo.get(1)); + } + + + + + + + +} diff --git a/guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java index cb6ec7ef96..ab38afa5c4 100644 --- a/guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java +++ b/guava-collections/src/test/java/org/baeldung/guava/GuavaCollectionTypesUnitTest.java @@ -111,120 +111,6 @@ public class GuavaCollectionTypesUnitTest { assertThat(immutable, contains("John", "Adam", "Jane", "Tom")); } - // sets - - @Test - public void whenCalculateUnionOfSets_thenCorrect() { - final Set first = ImmutableSet.of('a', 'b', 'c'); - final Set second = ImmutableSet.of('b', 'c', 'd'); - - final Set union = Sets.union(first, second); - assertThat(union, containsInAnyOrder('a', 'b', 'c', 'd')); - } - - @Test - public void whenCalculateSetsProduct_thenCorrect() { - final Set first = ImmutableSet.of('a', 'b'); - final Set second = ImmutableSet.of('c', 'd'); - final Set> result = Sets.cartesianProduct(ImmutableList.of(first, second)); - - final Function, String> func = new Function, String>() { - @Override - public final String apply(final List input) { - return Joiner.on(" ").join(input); - } - }; - - final Iterable joined = Iterables.transform(result, func); - assertThat(joined, containsInAnyOrder("a c", "a d", "b c", "b d")); - } - - @Test - public void whenCalculatingSetIntersection_thenCorrect() { - final Set first = ImmutableSet.of('a', 'b', 'c'); - final Set second = ImmutableSet.of('b', 'c', 'd'); - - final Set intersection = Sets.intersection(first, second); - assertThat(intersection, containsInAnyOrder('b', 'c')); - } - - @Test - public void whenCalculatingSetSymmetricDifference_thenCorrect() { - final Set first = ImmutableSet.of('a', 'b', 'c'); - final Set second = ImmutableSet.of('b', 'c', 'd'); - - final Set intersection = Sets.symmetricDifference(first, second); - assertThat(intersection, containsInAnyOrder('a', 'd')); - } - - @Test - public void whenCalculatingPowerSet_thenCorrect() { - final Set chars = ImmutableSet.of('a', 'b'); - final Set> result = Sets.powerSet(chars); - - final Set empty = ImmutableSet. builder().build(); - final Set a = ImmutableSet.of('a'); - final Set b = ImmutableSet.of('b'); - final Set aB = ImmutableSet.of('a', 'b'); - - assertThat(result, contains(empty, a, b, aB)); - } - - @Test - public void whenCreateRangeOfIntegersSet_thenCreated() { - final int start = 10; - final int end = 30; - final ContiguousSet set = ContiguousSet.create(Range.closed(start, end), DiscreteDomain.integers()); - - assertEquals(21, set.size()); - assertEquals(10, set.first().intValue()); - assertEquals(30, set.last().intValue()); - } - - @Test - public void whenCreateRangeSet_thenCreated() { - final RangeSet rangeSet = TreeRangeSet.create(); - rangeSet.add(Range.closed(1, 10)); - rangeSet.add(Range.closed(12, 15)); - - assertEquals(2, rangeSet.asRanges().size()); - - rangeSet.add(Range.closed(10, 12)); - assertTrue(rangeSet.encloses(Range.closed(1, 15))); - assertEquals(1, rangeSet.asRanges().size()); - } - - @Test - public void whenInsertDuplicatesInMultiSet_thenInserted() { - final Multiset names = HashMultiset.create(); - names.add("John"); - names.add("Adam", 3); - names.add("John"); - - assertEquals(2, names.count("John")); - names.remove("John"); - assertEquals(1, names.count("John")); - - assertEquals(3, names.count("Adam")); - names.remove("Adam", 2); - assertEquals(1, names.count("Adam")); - } - - @Test - public void whenGetTopUsingMultiSet_thenCorrect() { - final Multiset names = HashMultiset.create(); - names.add("John"); - names.add("Adam", 5); - names.add("Jane"); - names.add("Tom", 2); - - final Set sorted = Multisets.copyHighestCountFirst(names).elementSet(); - final List topTwo = Lists.newArrayList(sorted).subList(0, 2); - assertEquals(2, topTwo.size()); - assertEquals("Adam", topTwo.get(0)); - assertEquals("Tom", topTwo.get(1)); - } - @Test public void whenCreateImmutableMap_thenCreated() { final Map salary = ImmutableMap. builder().put("John", 1000).put("Jane", 1500).put("Adam", 2000).put("Tom", 2000).build(); From dd877c6b2cf797546465cf379cf48dd09282177c Mon Sep 17 00:00:00 2001 From: Vivek Date: Sat, 4 May 2019 15:31:50 +0530 Subject: [PATCH 026/185] BAEL-2857 Defining a JPA Entity - changed the table name --- .../src/main/java/com/baeldung/jpa/entity/Student.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java index 17007fa126..531bae40c5 100644 --- a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Student.java @@ -17,13 +17,13 @@ import javax.persistence.Transient; import com.baeldung.util.Gender; @Entity -@Table(name="STUD") +@Table(name="STUDENT") public class Student { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; - @Column(name = "STUD_NAME", length = 50, nullable = false, unique = false) + @Column(name = "STUDENT_NAME", length = 50, nullable = false, unique = false) private String name; @Transient private Integer age; From 15dfc6fa36ae876b445b0ba9d07239d358ef1aea Mon Sep 17 00:00:00 2001 From: Sushant Date: Sat, 4 May 2019 13:10:12 +0300 Subject: [PATCH 027/185] Cleanup --- .../src/test/java/org/baeldung/guava/GuavaMapFromSet.java | 8 ++++---- .../java/org/baeldung/guava/GuavaRangeSetUnitTest.java | 1 - .../org/baeldung/guava/GuavaSetOperationsUnitTest.java | 7 ------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java index 94224c08ab..ba0c8f01a3 100644 --- a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java @@ -49,7 +49,7 @@ public class GuavaMapFromSet extends AbstractMap { } @Override - public Entry next() { + public Map.Entry next() { K key = this.inner.next(); return new SingleEntry(key); } @@ -67,7 +67,7 @@ public class GuavaMapFromSet extends AbstractMap { } @Override - public Iterator> iterator() { + public Iterator> iterator() { return new EntryIterator(); } @@ -79,7 +79,7 @@ public class GuavaMapFromSet extends AbstractMap { } private WeakHashMap cache; - private Set> entries; + private Set> entries; private Function function; public GuavaMapFromSet(Set keys, Function function) { @@ -89,7 +89,7 @@ public class GuavaMapFromSet extends AbstractMap { } @Override - public Set> entrySet() { + public Set> entrySet() { return this.entries; } diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java index b72cfdeea6..edefc61fc4 100644 --- a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java @@ -121,6 +121,5 @@ public class GuavaRangeSetUnitTest { .add(Range.closed(0, 2)) .add(Range.closed(3, 5)) .add(Range.closed(5, 8)).build(); - } } diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java index 4733a15392..07c99ba184 100644 --- a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java @@ -128,11 +128,4 @@ public class GuavaSetOperationsUnitTest { assertEquals("Adam", topTwo.get(0)); assertEquals("Tom", topTwo.get(1)); } - - - - - - - } From 4b1840d7447564bb7f4058e18bbcff33bcb2de92 Mon Sep 17 00:00:00 2001 From: Sushant Date: Sat, 4 May 2019 13:12:18 +0300 Subject: [PATCH 028/185] Remove GuavaRangeSetUnitTest --- .../org/baeldung/guava/GuavaMapFromSet.java | 2 +- .../baeldung/guava/GuavaRangeSetUnitTest.java | 127 ------------------ 2 files changed, 1 insertion(+), 128 deletions(-) delete mode 100644 guava-collections/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java index ba0c8f01a3..f474fcb17b 100644 --- a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaMapFromSet.java @@ -79,7 +79,7 @@ public class GuavaMapFromSet extends AbstractMap { } private WeakHashMap cache; - private Set> entries; + private Set> entries; private Function function; public GuavaMapFromSet(Set keys, Function function) { diff --git a/guava-collections/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java b/guava-collections/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java deleted file mode 100644 index 6f3092d845..0000000000 --- a/guava-collections/src/test/java/org/baeldung/guava/GuavaRangeSetUnitTest.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.baeldung.guava; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertFalse; -import org.junit.Test; -import com.google.common.collect.ImmutableRangeSet; -import com.google.common.collect.Range; -import com.google.common.collect.RangeSet; -import com.google.common.collect.TreeRangeSet; - -public class GuavaRangeSetUnitTest { - - @Test - public void givenRangeSet_whenQueryWithinRange_returnsSucessfully() { - final RangeSet numberRangeSet = TreeRangeSet.create(); - - numberRangeSet.add(Range.closed(0, 2)); - numberRangeSet.add(Range.closed(3, 5)); - numberRangeSet.add(Range.closed(6, 8)); - - assertTrue(numberRangeSet.contains(1)); - assertFalse(numberRangeSet.contains(9)); - } - - @Test - public void givenRangeSet_whenEnclosesWithinRange_returnsSucessfully() { - final RangeSet numberRangeSet = TreeRangeSet.create(); - - numberRangeSet.add(Range.closed(0, 2)); - numberRangeSet.add(Range.closed(3, 10)); - numberRangeSet.add(Range.closed(15, 18)); - - assertTrue(numberRangeSet.encloses(Range.closed(4, 5))); - assertFalse(numberRangeSet.encloses(Range.closed(4, 11))); - } - - @Test - public void givenRangeSet_whenComplementIsCalled_returnsSucessfully() { - final RangeSet numberRangeSet = TreeRangeSet.create(); - - numberRangeSet.add(Range.closed(0, 2)); - numberRangeSet.add(Range.closed(3, 5)); - numberRangeSet.add(Range.closed(6, 8)); - final RangeSet numberRangeComplementSet = numberRangeSet.complement(); - - assertTrue(numberRangeComplementSet.contains(-1000)); - assertFalse(numberRangeComplementSet.contains(2)); - assertFalse(numberRangeComplementSet.contains(3)); - assertTrue(numberRangeComplementSet.contains(1000)); - } - - @Test - public void givenRangeSet_whenIntersectsWithinRange_returnsSucessfully() { - final RangeSet numberRangeSet = TreeRangeSet.create(); - - numberRangeSet.add(Range.closed(0, 2)); - numberRangeSet.add(Range.closed(3, 10)); - numberRangeSet.add(Range.closed(15, 18)); - - assertTrue(numberRangeSet.intersects(Range.closed(4, 17))); - assertFalse(numberRangeSet.intersects(Range.closed(19, 200))); - } - - @Test - public void givenRangeSet_whenRemoveRangeIsCalled_removesSucessfully() { - final RangeSet numberRangeSet = TreeRangeSet.create(); - - numberRangeSet.add(Range.closed(0, 2)); - numberRangeSet.add(Range.closed(3, 5)); - numberRangeSet.add(Range.closed(6, 8)); - numberRangeSet.add(Range.closed(9, 15)); - numberRangeSet.remove(Range.closed(3, 5)); - numberRangeSet.remove(Range.closed(7, 10)); - - assertTrue(numberRangeSet.contains(1)); - assertFalse(numberRangeSet.contains(9)); - assertTrue(numberRangeSet.contains(12)); - } - - @Test - public void givenRangeSet_whenSpanIsCalled_returnsSucessfully() { - final RangeSet numberRangeSet = TreeRangeSet.create(); - - numberRangeSet.add(Range.closed(0, 2)); - numberRangeSet.add(Range.closed(3, 5)); - numberRangeSet.add(Range.closed(6, 8)); - final Range experienceSpan = numberRangeSet.span(); - - assertEquals(0, experienceSpan.lowerEndpoint().intValue()); - assertEquals(8, experienceSpan.upperEndpoint().intValue()); - } - - @Test - public void givenRangeSet_whenSubRangeSetIsCalled_returnsSubRangeSucessfully() { - final RangeSet numberRangeSet = TreeRangeSet.create(); - - numberRangeSet.add(Range.closed(0, 2)); - numberRangeSet.add(Range.closed(3, 5)); - numberRangeSet.add(Range.closed(6, 8)); - final RangeSet numberSubRangeSet = numberRangeSet.subRangeSet(Range.closed(4, 14)); - - assertFalse(numberSubRangeSet.contains(3)); - assertFalse(numberSubRangeSet.contains(14)); - assertTrue(numberSubRangeSet.contains(7)); - } - - @Test - public void givenImmutableRangeSet_whenQueryWithinRange_returnsSucessfully() { - final RangeSet numberRangeSet = ImmutableRangeSet. builder() - .add(Range.closed(0, 2)) - .add(Range.closed(3, 5)) - .add(Range.closed(6, 8)).build(); - - assertTrue(numberRangeSet.contains(6)); - assertFalse(numberRangeSet.contains(15)); - } - - @Test(expected = IllegalArgumentException.class) - public void givenImmutableRangeMap_whenRangeOverlaps_ThrowsException() { - ImmutableRangeSet. builder() - .add(Range.closed(0, 2)) - .add(Range.closed(3, 5)) - .add(Range.closed(5, 8)).build(); - - } -} From e39c765db6a07ce5be9354eb04917ea4a9a88b94 Mon Sep 17 00:00:00 2001 From: Sushant Date: Sat, 4 May 2019 13:19:58 +0300 Subject: [PATCH 029/185] Update read me --- guava-collections-set/README.md | 10 ++++++++++ guava-collections/README.md | 3 --- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 guava-collections-set/README.md diff --git a/guava-collections-set/README.md b/guava-collections-set/README.md new file mode 100644 index 0000000000..665d04736f --- /dev/null +++ b/guava-collections-set/README.md @@ -0,0 +1,10 @@ +========= + +## Guava Examples + + +### Relevant Articles: +- [Guava – Sets](http://www.baeldung.com/guava-sets) +- [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset) +- [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial) +- [Guide to Guava Multiset](https://www.baeldung.com/guava-multiset) \ No newline at end of file diff --git a/guava-collections/README.md b/guava-collections/README.md index fc9cf549c3..e919a98c2b 100644 --- a/guava-collections/README.md +++ b/guava-collections/README.md @@ -11,13 +11,10 @@ - [Filtering and Transforming Collections in Guava](http://www.baeldung.com/guava-filter-and-transform-a-collection) - [Guava – Join and Split Collections](http://www.baeldung.com/guava-joiner-and-splitter-tutorial) - [Guava – Lists](http://www.baeldung.com/guava-lists) -- [Guava – Sets](http://www.baeldung.com/guava-sets) - [Guava – Maps](http://www.baeldung.com/guava-maps) - [Guide to Guava Multimap](http://www.baeldung.com/guava-multimap) -- [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset) - [Guide to Guava RangeMap](http://www.baeldung.com/guava-rangemap) - [Guide to Guava MinMaxPriorityQueue and EvictingQueue](http://www.baeldung.com/guava-minmax-priority-queue-and-evicting-queue) - [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap) -- [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial) - [Guide to Guava Table](http://www.baeldung.com/guava-table) - [Guide to Guava ClassToInstanceMap](http://www.baeldung.com/guava-class-to-instance-map) \ No newline at end of file From e7e500104b8c76769bb66af3c8e6ccba7d1ffe1d Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 4 May 2019 21:33:47 +0530 Subject: [PATCH 030/185] [BAEL-12800] - Corrected password field --- .../main/resources/persistence-multiple-db-boot.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties index b847442ef1..587ba19d6f 100644 --- a/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties +++ b/persistence-modules/spring-data-jpa/src/main/resources/persistence-multiple-db-boot.properties @@ -2,13 +2,13 @@ spring.user.driverClassName=org.h2.Driver spring.user.jdbc-url=jdbc:h2:mem:spring_jpa_user;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS USERS spring.user.username=sa -spring.user.username=sa +spring.user.password=sa # product data source spring.product.driverClassName=org.h2.Driver spring.product.jdbc-url=jdbc:h2:mem:spring_jpa_product;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS PRODUCTS spring.product.username=sa -spring.product.username=sa +spring.product.password=sa # hibernate.X hibernate.dialect=org.hibernate.dialect.H2Dialect From 21b43b0f1184a9d463bcf810c421e0654bd5b604 Mon Sep 17 00:00:00 2001 From: mikr Date: Mon, 6 May 2019 00:12:00 +0200 Subject: [PATCH 031/185] BAEL-2580 JVM Platform Annotations in Kotlin - added Unit Test --- .../com/baeldung/jvmannotations/Document.kt | 8 ++------ .../kotlin/com/baeldung/range/DocumentTest.kt | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt diff --git a/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt index 3f9922b88b..f66f8fbae0 100644 --- a/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt +++ b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt @@ -5,6 +5,8 @@ import java.util.* interface Document { @JvmDefault + fun getTypeDefault() = "document" + fun getType() = "document" } @@ -23,9 +25,3 @@ class TextDocument : Document { } class XmlDocument(d : Document) : Document by d - -fun main() { - val myDocument = TextDocument() - val myTextDocument = XmlDocument(myDocument) - println("${myDocument.getType()} ${myTextDocument.getType()}") -} diff --git a/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt b/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt new file mode 100644 index 0000000000..449e009104 --- /dev/null +++ b/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt @@ -0,0 +1,18 @@ +package com.baeldung.range + +import org.junit.Test +import kotlin.test.assertEquals + +class DocumentTest { + + @Test + fun testDefaultMethod() { + + val myDocument = TextDocument() + val myTextDocument = XmlDocument(myDocument) + + assertEquals("text", myDocument.getType()) + assertEquals("text", myTextDocument.getType()) + assertEquals("document", myTextDocument.getTypeDefault()) + } +} \ No newline at end of file From fc227bc128e4d931ae74e07d06f82cfcdb8b59a3 Mon Sep 17 00:00:00 2001 From: Ganesh Pagade Date: Tue, 7 May 2019 10:58:11 +0530 Subject: [PATCH 032/185] Java 12 String API Test --- .../test/java/com/baeldung/StringAPITest.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100755 core-java-12/src/test/java/com/baeldung/StringAPITest.java diff --git a/core-java-12/src/test/java/com/baeldung/StringAPITest.java b/core-java-12/src/test/java/com/baeldung/StringAPITest.java new file mode 100755 index 0000000000..7b68fbb52c --- /dev/null +++ b/core-java-12/src/test/java/com/baeldung/StringAPITest.java @@ -0,0 +1,43 @@ +package com.baeldung; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.Test; + +public class StringAPITest { + + @Test + public void whenPositiveArgument_thenReturnIndentedString() { + String multilineStr = "This is\na multiline\nstring."; + String outputStr = " This is\n a multiline\n string.\n"; + + String postIndent = multilineStr.indent(3); + + assertThat(outputStr, equalTo(postIndent)); + } + + @Test + public void whenNegativeArgument_thenReturnReducedIndentedString() { + String multilineStr = " This is\n a multiline\n string."; + String outputStr = " This is\n a multiline\n string.\n"; + + String postIndent = multilineStr.indent(-2); + + assertThat(outputStr, equalTo(postIndent)); + } + + @Test + public void whenTransformUsingLamda_thenReturnTransformedString() { + String result = "hello".transform(input -> input + " world!"); + + assertThat("hello world!", equalTo(result)); + } + + @Test + public void whenTransformUsingParseInt_thenReturnInt() { + int result = "42".transform(Integer::parseInt); + + assertThat(42, equalTo(result)); + } +} From ef4fe8c87023091eeb2c1dfd67461799ede9fb9d Mon Sep 17 00:00:00 2001 From: Ganesh Pagade Date: Tue, 7 May 2019 11:12:48 +0530 Subject: [PATCH 033/185] new location for the code --- .../src/test/java/com/baeldung/string}/StringAPITest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename {core-java-12/src/test/java/com/baeldung => core-java-modules/core-java-12/src/test/java/com/baeldung/string}/StringAPITest.java (97%) mode change 100755 => 100644 diff --git a/core-java-12/src/test/java/com/baeldung/StringAPITest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/string/StringAPITest.java old mode 100755 new mode 100644 similarity index 97% rename from core-java-12/src/test/java/com/baeldung/StringAPITest.java rename to core-java-modules/core-java-12/src/test/java/com/baeldung/string/StringAPITest.java index 7b68fbb52c..f26a25ed79 --- a/core-java-12/src/test/java/com/baeldung/StringAPITest.java +++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/string/StringAPITest.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.string; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.MatcherAssert.assertThat; From 4d85678e968074b6b52870cf6553c5ac3f52e582 Mon Sep 17 00:00:00 2001 From: Hamed Mirzaei Date: Tue, 7 May 2019 10:22:42 +0430 Subject: [PATCH 034/185] To enable multiple execution of a job with the same parameters --- spring-batch/src/main/java/org/baeldung/batch/App.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spring-batch/src/main/java/org/baeldung/batch/App.java b/spring-batch/src/main/java/org/baeldung/batch/App.java index cea4e8d486..8bf58e65d2 100644 --- a/spring-batch/src/main/java/org/baeldung/batch/App.java +++ b/spring-batch/src/main/java/org/baeldung/batch/App.java @@ -3,6 +3,7 @@ package org.baeldung.batch; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.JobParametersBuilder; import org.springframework.batch.core.launch.JobLauncher; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -21,7 +22,11 @@ public class App { final Job job = (Job) context.getBean("firstBatchJob"); System.out.println("Starting the batch job"); try { - final JobExecution execution = jobLauncher.run(job, new JobParameters()); + // To enable multiple execution of a job with the same parameters + JobParameters jobParameters = new JobParametersBuilder() + .addString("jobID", String.valueOf(System.currentTimeMillis())) + .toJobParameters(); + final JobExecution execution = jobLauncher.run(job, jobParameters); System.out.println("Job Status : " + execution.getStatus()); System.out.println("Job succeeded"); } catch (final Exception e) { From 26f6585a19db17f9709ca028fc288093c7db9c8e Mon Sep 17 00:00:00 2001 From: Philippe Date: Tue, 7 May 2019 23:57:54 -0300 Subject: [PATCH 035/185] [BAEL-1219] Add Sample URLs --- apache-olingo/Samples.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 apache-olingo/Samples.md diff --git a/apache-olingo/Samples.md b/apache-olingo/Samples.md new file mode 100644 index 0000000000..def8971d64 --- /dev/null +++ b/apache-olingo/Samples.md @@ -0,0 +1,21 @@ +## OData test URLs + +This following table contains test URLs that can be used with the Olingo V2 demo project. + +| URL | Description | +|------------------------------------------|-------------------------------------------------| +| `http://localhost:8180/odata/$metadata` | fetch OData metadata document | +| `http://localhost:8180/odata/CarMakers?$top=10&$skip=10` | Get 10 entities starting at offset 10 | +| `http://localhost:8180/odata/CarMakers?$count` | Return total count of entities in this set | +| `http://localhost:8180/odata/CarMakers?$filter=startswith(Name,'B')` | Return entities where the *Name* property starts with 'B' | +| `http://localhost:8180/odata/CarModels?$filter=Year eq 2008 and CarMakerDetails/Name eq 'BWM'` | Return *CarModel* entities where the *Name* property of its maker starts with 'B' | +| `http://localhost:8180/odata/CarModels(1L)?$expand=CarMakerDetails` | Return the *CarModel* with primary key '1', along with its maker| +| `http://localhost:8180/odata/CarModels(1L)?$select=Name,Sku` | Return the *CarModel* with primary key '1', returing only its *Name* and *Sku* properties | +| `http://localhost:8180/odata/CarModels?$orderBy=Name asc,Sku desc` | Return *CarModel* entities, ordered by the their *Name* and *Sku* properties | +| `http://localhost:8180/odata/CarModels?$format=json` | Return *CarModel* entities, using a JSON representation| + + + + + + From 6824bfa4972fca771393acd3cd2174219256ec3f Mon Sep 17 00:00:00 2001 From: Guilherme Lima Date: Thu, 9 May 2019 14:34:03 -0300 Subject: [PATCH 036/185] Updating javadoc --- .../java/org/baeldung/web/util/RestPreconditions.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-rest-full/src/main/java/org/baeldung/web/util/RestPreconditions.java b/spring-rest-full/src/main/java/org/baeldung/web/util/RestPreconditions.java index 4e211ccb10..4f2dedcfa0 100644 --- a/spring-rest-full/src/main/java/org/baeldung/web/util/RestPreconditions.java +++ b/spring-rest-full/src/main/java/org/baeldung/web/util/RestPreconditions.java @@ -31,11 +31,11 @@ public final class RestPreconditions { /** * Check if some value was found, otherwise throw exception. - * - * @param expression - * has value true if found, otherwise false + * + * @param resource + * has value not null to be returned, otherwise throw exception * @throws MyResourceNotFoundException - * if expression is false, means value not found. + * if resource is null, means value not found. */ public static T checkFound(final T resource) { if (resource == null) { From 05ba8a7ac34b7bb539f0d45512a08bcbfddf8e26 Mon Sep 17 00:00:00 2001 From: Pavan Shankar Koli Date: Fri, 10 May 2019 22:38:50 +0530 Subject: [PATCH 037/185] BAEL-2886 Mongodb spring session code --- .../spring-session-mongodb/README.md | 4 ++ spring-session/spring-session-mongodb/pom.xml | 51 +++++++++++++++++++ .../SpringSessionMongoDBApplication.java | 12 +++++ .../SpringSessionMongoDBController.java | 27 ++++++++++ .../src/main/resources/application.properties | 1 + .../src/main/resources/logback.xml | 13 +++++ .../SpringContextIntegrationTest.java | 16 ++++++ 7 files changed, 124 insertions(+) create mode 100644 spring-session/spring-session-mongodb/README.md create mode 100644 spring-session/spring-session-mongodb/pom.xml create mode 100644 spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/SpringSessionMongoDBApplication.java create mode 100644 spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/controller/SpringSessionMongoDBController.java create mode 100644 spring-session/spring-session-mongodb/src/main/resources/application.properties create mode 100644 spring-session/spring-session-mongodb/src/main/resources/logback.xml create mode 100644 spring-session/spring-session-mongodb/src/test/java/baeldung/SpringContextIntegrationTest.java diff --git a/spring-session/spring-session-mongodb/README.md b/spring-session/spring-session-mongodb/README.md new file mode 100644 index 0000000000..94fd1cd3e7 --- /dev/null +++ b/spring-session/spring-session-mongodb/README.md @@ -0,0 +1,4 @@ +This module is for Spring Session with JDBC tutorial. +Jira BAEL-1911 + +### Relevant Articles: diff --git a/spring-session/spring-session-mongodb/pom.xml b/spring-session/spring-session-mongodb/pom.xml new file mode 100644 index 0000000000..432715bc0e --- /dev/null +++ b/spring-session/spring-session-mongodb/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + com.baeldung + spring-session-jdbc + 0.0.1-SNAPSHOT + spring-session-jdbc + jar + Spring Session with JDBC tutorial + + + parent-boot-2 + com.baeldung + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.session + spring-session-jdbc + + + com.h2database + h2 + ${h2.version} + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/SpringSessionMongoDBApplication.java b/spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/SpringSessionMongoDBApplication.java new file mode 100644 index 0000000000..c574501472 --- /dev/null +++ b/spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/SpringSessionMongoDBApplication.java @@ -0,0 +1,12 @@ +package springsessionmongodb; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SpringSessionMongoDBApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringSessionMongoDBApplication.class, args); + } +} diff --git a/spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/controller/SpringSessionMongoDBController.java b/spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/controller/SpringSessionMongoDBController.java new file mode 100644 index 0000000000..50fc432d56 --- /dev/null +++ b/spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/controller/SpringSessionMongoDBController.java @@ -0,0 +1,27 @@ +package springsessionmongodb.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpSession; + +@RestController +public class SpringSessionMongoDBController { + + @GetMapping("/") + public String count(HttpSession session) { + + Integer counter = (Integer) session.getAttribute("count"); + + if (counter == null) { + counter = 0; + } else { + counter += 1; + } + + session.setAttribute("count", counter); + + return "

Count is "+counter+"

"; + } + +} diff --git a/spring-session/spring-session-mongodb/src/main/resources/application.properties b/spring-session/spring-session-mongodb/src/main/resources/application.properties new file mode 100644 index 0000000000..aeb7eb91ad --- /dev/null +++ b/spring-session/spring-session-mongodb/src/main/resources/application.properties @@ -0,0 +1 @@ +spring.session.store-type=mongodb \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/src/main/resources/logback.xml b/spring-session/spring-session-mongodb/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-session/spring-session-mongodb/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/src/test/java/baeldung/SpringContextIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/baeldung/SpringContextIntegrationTest.java new file mode 100644 index 0000000000..b58fd46dae --- /dev/null +++ b/spring-session/spring-session-mongodb/src/test/java/baeldung/SpringContextIntegrationTest.java @@ -0,0 +1,16 @@ +package baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; +import springsessionmongodb.SpringSessionMongoDBApplication; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringSessionMongoDBApplication.class) +public class SpringContextIntegrationTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} From 35693612df65a1dba1b46db8459967e08d3e1e0d Mon Sep 17 00:00:00 2001 From: Pavan Shankar Koli Date: Fri, 10 May 2019 22:39:38 +0530 Subject: [PATCH 038/185] BAEL-2886 Mongodb spring session code --- spring-session/pom.xml | 1 + .../spring-session-mongodb/README.md | 4 ++-- spring-session/spring-session-mongodb/pom.xml | 22 ++++++++++++------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/spring-session/pom.xml b/spring-session/pom.xml index bcdbaf2406..639686c8ee 100644 --- a/spring-session/pom.xml +++ b/spring-session/pom.xml @@ -17,6 +17,7 @@ spring-session-jdbc spring-session-redis + spring-session-mongodb \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/README.md b/spring-session/spring-session-mongodb/README.md index 94fd1cd3e7..ab42e8d120 100644 --- a/spring-session/spring-session-mongodb/README.md +++ b/spring-session/spring-session-mongodb/README.md @@ -1,4 +1,4 @@ -This module is for Spring Session with JDBC tutorial. -Jira BAEL-1911 +This module is for Spring Session with MONGO DB tutorial. +Jira BAEL-2886 ### Relevant Articles: diff --git a/spring-session/spring-session-mongodb/pom.xml b/spring-session/spring-session-mongodb/pom.xml index 432715bc0e..714833cf99 100644 --- a/spring-session/spring-session-mongodb/pom.xml +++ b/spring-session/spring-session-mongodb/pom.xml @@ -4,11 +4,11 @@ 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-session-jdbc + spring-session-mongodb 0.0.1-SNAPSHOT - spring-session-jdbc + spring-session-mongodb jar - Spring Session with JDBC tutorial + Spring Session with MongoDB tutorial parent-boot-2 @@ -22,16 +22,18 @@ org.springframework.boot spring-boot-starter-web + org.springframework.session - spring-session-jdbc + spring-session-data-mongodb + ${spring-session-data-mongodb.version} + - com.h2database - h2 - ${h2.version} - runtime + org.springframework.boot + spring-boot-starter-data-mongodb + org.springframework.boot spring-boot-starter-test @@ -39,6 +41,10 @@ + + 2.1.3.RELEASE + + From f833bc18d161b6b737488d6b375c29a467833835 Mon Sep 17 00:00:00 2001 From: Philippe Date: Sat, 11 May 2019 21:21:18 -0300 Subject: [PATCH 039/185] [BAEL-2894] Minor formatting --- apache-olingo/olingo2/pom.xml | 10 ---- apache-olingo/olingo4/pom.xml | 14 +++--- .../examples/olingo4/edm/JpaEdmProvider.java | 47 +++++++++---------- 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/apache-olingo/olingo2/pom.xml b/apache-olingo/olingo2/pom.xml index 4fc81e5e49..493d34119e 100644 --- a/apache-olingo/olingo2/pom.xml +++ b/apache-olingo/olingo2/pom.xml @@ -68,16 +68,6 @@ - - org.apache.olingo - olingo-odata2-api - ${olingo2.version} - - - org.apache.olingo - olingo-odata2-jpa-processor-api - ${olingo2.version} - org.apache.olingo olingo-odata2-jpa-processor-core diff --git a/apache-olingo/olingo4/pom.xml b/apache-olingo/olingo4/pom.xml index 794aee0711..6323db413a 100644 --- a/apache-olingo/olingo4/pom.xml +++ b/apache-olingo/olingo4/pom.xml @@ -53,16 +53,16 @@ spring-boot-starter-web - - org.apache.olingo - odata-server-api - ${odata.version} - org.apache.olingo odata-server-core ${odata.version} - runtime + + commons-beanutils commons-beanutils diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java index 4cd979e931..585aecfa84 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java @@ -192,7 +192,7 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { List properties = et.getDeclaredSingularAttributes() .stream() .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC) - .map(attr -> buildBasicAttribute(et, attr)) + .map(attr -> buildBasicAttribute(attr)) .collect(Collectors.toList()); result.setProperties(properties); @@ -201,24 +201,25 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { List ids = et.getDeclaredSingularAttributes() .stream() .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC && attr.isId()) - .map(attr -> buildRefAttribute(et, attr)) + .map(attr -> buildRefAttribute(attr)) .collect(Collectors.toList()); result.setKey(ids); // Process 1:N navs List navs = et.getDeclaredPluralAttributes() - .stream() - .map(attr -> buildNavAttribute(et, attr)) - .collect(Collectors.toList()); + .stream() + .filter(attr -> attr.isAssociation()) + .map(attr -> buildNavAttribute(attr)) + .collect(Collectors.toList()); result.setNavigationProperties(navs); // Process N:1 navs List navs2 = et.getDeclaredSingularAttributes() - .stream() - .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE) - .map(attr -> buildNavAttribute(et, attr)) - .collect(Collectors.toList()); + .stream() + .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE) + .map(attr -> buildMany2OneNavAttribute(attr)) + .collect(Collectors.toList()); result.getNavigationProperties().addAll(navs2); @@ -226,42 +227,40 @@ public class JpaEdmProvider extends CsdlAbstractEdmProvider { return result; } - private CsdlProperty buildBasicAttribute(EntityType et, SingularAttribute attr) { + private CsdlProperty buildBasicAttribute(SingularAttribute attr) { CsdlProperty p = new CsdlProperty().setName(attr.getName()) - .setType(typeMapper.java2edm(attr.getJavaType()) - .getFullQualifiedName()) - .setNullable(et.getDeclaredSingularAttribute(attr.getName()) - .isOptional()); + .setType(typeMapper.java2edm(attr.getJavaType()) + .getFullQualifiedName()) + .setNullable(attr.isOptional()); return p; } - private CsdlPropertyRef buildRefAttribute(EntityType et, SingularAttribute attr) { + private CsdlPropertyRef buildRefAttribute(SingularAttribute attr) { CsdlPropertyRef p = new CsdlPropertyRef().setName(attr.getName()); - return p; } // Build NavProperty for 1:N or M:N associations - private CsdlNavigationProperty buildNavAttribute(EntityType et, PluralAttribute attr) { + private CsdlNavigationProperty buildNavAttribute(PluralAttribute attr) { CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName()) - .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) - .setCollection(true) - .setNullable(false); + .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) + .setCollection(true) + .setNullable(false); return p; } // Build NavProperty for N:1 associations - private CsdlNavigationProperty buildNavAttribute(EntityType et, SingularAttribute attr) { + private CsdlNavigationProperty buildMany2OneNavAttribute(SingularAttribute attr) { CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName()) - .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) - .setCollection(false) - .setNullable(attr.isOptional()); + .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) + .setCollection(false) + .setNullable(attr.isOptional()); return p; } From cc4a2639d935e346a2a17a31062d24eeb4250925 Mon Sep 17 00:00:00 2001 From: Ganesh Pagade Date: Sun, 12 May 2019 11:10:07 +0530 Subject: [PATCH 040/185] fix test arg order --- .../src/test/java/com/baeldung/string/StringAPITest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core-java-modules/core-java-12/src/test/java/com/baeldung/string/StringAPITest.java b/core-java-modules/core-java-12/src/test/java/com/baeldung/string/StringAPITest.java index f26a25ed79..3d80a36bf6 100644 --- a/core-java-modules/core-java-12/src/test/java/com/baeldung/string/StringAPITest.java +++ b/core-java-modules/core-java-12/src/test/java/com/baeldung/string/StringAPITest.java @@ -14,7 +14,7 @@ public class StringAPITest { String postIndent = multilineStr.indent(3); - assertThat(outputStr, equalTo(postIndent)); + assertThat(postIndent, equalTo(outputStr)); } @Test @@ -24,20 +24,20 @@ public class StringAPITest { String postIndent = multilineStr.indent(-2); - assertThat(outputStr, equalTo(postIndent)); + assertThat(postIndent, equalTo(outputStr)); } @Test public void whenTransformUsingLamda_thenReturnTransformedString() { String result = "hello".transform(input -> input + " world!"); - assertThat("hello world!", equalTo(result)); + assertThat(result, equalTo("hello world!")); } @Test public void whenTransformUsingParseInt_thenReturnInt() { int result = "42".transform(Integer::parseInt); - assertThat(42, equalTo(result)); + assertThat(result, equalTo(42)); } } From b83362799dbda6d758ba7277f0c8c37883b3fcee Mon Sep 17 00:00:00 2001 From: Philippe Date: Sun, 12 May 2019 17:09:09 -0300 Subject: [PATCH 041/185] [BAEL-2894] remove Lombok --- apache-olingo/olingo2/pom.xml | 5 - .../examples/olingo2/domain/CarMaker.java | 105 +++++++++++-- .../examples/olingo2/domain/CarModel.java | 145 ++++++++++++++++-- apache-olingo/olingo4/pom.xml | 5 - .../olingo4/ODataHttpHandlerFactoryImpl.java | 42 +++-- .../examples/olingo4/domain/CarMaker.java | 105 +++++++++++-- .../examples/olingo4/domain/CarModel.java | 145 ++++++++++++++++-- 7 files changed, 482 insertions(+), 70 deletions(-) diff --git a/apache-olingo/olingo2/pom.xml b/apache-olingo/olingo2/pom.xml index 493d34119e..1efd4ea602 100644 --- a/apache-olingo/olingo2/pom.xml +++ b/apache-olingo/olingo2/pom.xml @@ -44,11 +44,6 @@ spring-boot-configuration-processor true - - org.projectlombok - lombok - true - org.springframework.boot spring-boot-starter-test diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java index 42a3eaa59d..e66d266062 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarMaker.java @@ -12,25 +12,104 @@ import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.NotNull; -import lombok.Data; - @Entity -@Data -@Table(name="car_maker") +@Table(name = "car_maker") public class CarMaker { - + @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - + @NotNull - @Column(name="name") + @Column(name = "name") private String name; - - @OneToMany(mappedBy="maker", - orphanRemoval = true, - cascade=CascadeType.ALL) + + @OneToMany(mappedBy = "maker", orphanRemoval = true, cascade = CascadeType.ALL) private List models; - + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the models + */ + public List getModels() { + return models; + } + + /** + * @param models the models to set + */ + public void setModels(List models) { + this.models = models; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((models == null) ? 0 : models.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CarMaker other = (CarMaker) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (models == null) { + if (other.models != null) + return false; + } else if (!models.equals(other.models)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } } diff --git a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java index a4f2a04f6e..f9f563e01e 100644 --- a/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java +++ b/apache-olingo/olingo2/src/main/java/org/baeldung/examples/olingo2/domain/CarModel.java @@ -1,6 +1,5 @@ package org.baeldung.examples.olingo2.domain; - import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; @@ -11,28 +10,150 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.validation.constraints.NotNull; -import lombok.Data; - @Entity -@Data -@Table(name="car_model") +@Table(name = "car_model") public class CarModel { @Id - @GeneratedValue(strategy=GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.AUTO) private Long id; - + @NotNull private String name; - + @NotNull private Integer year; - + @NotNull private String sku; - - @ManyToOne(optional=false, fetch= FetchType.LAZY) - @JoinColumn(name="maker_fk") + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + @JoinColumn(name = "maker_fk") private CarMaker maker; + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the year + */ + public Integer getYear() { + return year; + } + + /** + * @param year the year to set + */ + public void setYear(Integer year) { + this.year = year; + } + + /** + * @return the sku + */ + public String getSku() { + return sku; + } + + /** + * @param sku the sku to set + */ + public void setSku(String sku) { + this.sku = sku; + } + + /** + * @return the maker + */ + public CarMaker getMaker() { + return maker; + } + + /** + * @param maker the maker to set + */ + public void setMaker(CarMaker maker) { + this.maker = maker; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((maker == null) ? 0 : maker.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((sku == null) ? 0 : sku.hashCode()); + result = prime * result + ((year == null) ? 0 : year.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CarModel other = (CarModel) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (maker == null) { + if (other.maker != null) + return false; + } else if (!maker.equals(other.maker)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (sku == null) { + if (other.sku != null) + return false; + } else if (!sku.equals(other.sku)) + return false; + if (year == null) { + if (other.year != null) + return false; + } else if (!year.equals(other.year)) + return false; + return true; + } + } diff --git a/apache-olingo/olingo4/pom.xml b/apache-olingo/olingo4/pom.xml index 6323db413a..3a93a6fa45 100644 --- a/apache-olingo/olingo4/pom.xml +++ b/apache-olingo/olingo4/pom.xml @@ -38,11 +38,6 @@ runtime - - org.projectlombok - lombok - true - org.springframework.boot spring-boot-starter-test diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java index 68d39dc052..e5d4d06a95 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java @@ -9,17 +9,13 @@ import org.apache.olingo.server.api.ODataHttpHandler; import org.apache.olingo.server.api.ServiceMetadata; import org.apache.olingo.server.api.processor.Processor; -import lombok.Builder; - -@Builder public class ODataHttpHandlerFactoryImpl implements ODataHttpHandlerFactory { - - + private final ODataFactory odataFactory; private final CsdlEdmProvider edmProvider; private final List processors; - public ODataHttpHandlerFactoryImpl(ODataFactory odataFactory,CsdlEdmProvider edmProvider, List processors) { + public ODataHttpHandlerFactoryImpl(ODataFactory odataFactory, CsdlEdmProvider edmProvider, List processors) { this.odataFactory = odataFactory; this.edmProvider = edmProvider; this.processors = processors; @@ -27,16 +23,42 @@ public class ODataHttpHandlerFactoryImpl implements ODataHttpHandlerFactory { @Override public ODataHttpHandler newInstance() { - + OData odata = odataFactory.newInstance(); ServiceMetadata metadata = odata.createServiceMetadata(edmProvider, Collections.emptyList()); ODataHttpHandler handler = odata.createHandler(metadata); - + // Register all available processors processors.forEach(p -> handler.register(p)); - - + return handler; } + public static class ODataHttpHandlerFactoryImplBuilder { + + private ODataFactory odataFactory; + private CsdlEdmProvider edmProvider; + private List processors; + + public ODataHttpHandlerFactoryImplBuilder odataFactory(ODataFactory odataFactory) { + this.odataFactory = odataFactory; + return this; + } + + public ODataHttpHandlerFactoryImplBuilder edmProvider(CsdlEdmProvider edmProvider) { + this.edmProvider = edmProvider; + return this; + } + + public ODataHttpHandlerFactoryImplBuilder processors(List processors) { + this.processors = processors; + return this; + } + + public ODataHttpHandlerFactoryImpl build() { + return new ODataHttpHandlerFactoryImpl(odataFactory, edmProvider, processors); + } + + } + } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java index 79825b4556..f1b793cbe9 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java @@ -12,25 +12,104 @@ import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.NotNull; -import lombok.Data; - @Entity -@Data -@Table(name="car_maker") +@Table(name = "car_maker") public class CarMaker { - + @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - + @NotNull - @Column(name="name") + @Column(name = "name") private String name; - - @OneToMany(mappedBy="maker", - orphanRemoval = true, - cascade=CascadeType.ALL) + + @OneToMany(mappedBy = "maker", orphanRemoval = true, cascade = CascadeType.ALL) private List models; - + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the models + */ + public List getModels() { + return models; + } + + /** + * @param models the models to set + */ + public void setModels(List models) { + this.models = models; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((models == null) ? 0 : models.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CarMaker other = (CarMaker) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (models == null) { + if (other.models != null) + return false; + } else if (!models.equals(other.models)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } } diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java index a9254e48b9..7652641d7e 100644 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java +++ b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java @@ -1,6 +1,5 @@ package org.baeldung.examples.olingo4.domain; - import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; @@ -11,28 +10,150 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.validation.constraints.NotNull; -import lombok.Data; - @Entity -@Data -@Table(name="car_model") +@Table(name = "car_model") public class CarModel { @Id - @GeneratedValue(strategy=GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.AUTO) private Long id; - + @NotNull private String name; - + @NotNull private Integer year; - + @NotNull private String sku; - - @ManyToOne(optional=false, fetch= FetchType.EAGER ) - @JoinColumn(name="maker_fk") + + @ManyToOne(optional = false, fetch = FetchType.EAGER) + @JoinColumn(name = "maker_fk") private CarMaker maker; + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the year + */ + public Integer getYear() { + return year; + } + + /** + * @param year the year to set + */ + public void setYear(Integer year) { + this.year = year; + } + + /** + * @return the sku + */ + public String getSku() { + return sku; + } + + /** + * @param sku the sku to set + */ + public void setSku(String sku) { + this.sku = sku; + } + + /** + * @return the maker + */ + public CarMaker getMaker() { + return maker; + } + + /** + * @param maker the maker to set + */ + public void setMaker(CarMaker maker) { + this.maker = maker; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((maker == null) ? 0 : maker.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((sku == null) ? 0 : sku.hashCode()); + result = prime * result + ((year == null) ? 0 : year.hashCode()); + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CarModel other = (CarModel) obj; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (maker == null) { + if (other.maker != null) + return false; + } else if (!maker.equals(other.maker)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (sku == null) { + if (other.sku != null) + return false; + } else if (!sku.equals(other.sku)) + return false; + if (year == null) { + if (other.year != null) + return false; + } else if (!year.equals(other.year)) + return false; + return true; + } + } From 104b0d597fd89bb73aca306d312c6d25a06c8676 Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Fri, 10 May 2019 11:21:26 +0430 Subject: [PATCH 042/185] Retrofitted the getConnection method to accept explicit connection props. --- .../baeldung/helpers/JdbcConnectionUtil.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java index f380f9674c..4881056e91 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java @@ -15,18 +15,37 @@ public class JdbcConnectionUtil { try { Properties props = new Properties(); props.load(JdbcConnectionUtil.class.getResourceAsStream("jdbc.properties")); - Class.forName(props.getProperty("jdbc.driver")); - con = DriverManager.getConnection(props.getProperty("jdbc.url"), props.getProperty("jdbc.user"), props.getProperty("jdbc.password")); + + String jdbcUrl = props.getProperty("jdbc.url"); + String driver = props.getProperty("jdbc.driver"); + String username = props.getProperty("jdbc.user"); + String password = props.getProperty("jdbc.password"); + con = getConnection(jdbcUrl, driver, username, password); return con; } catch (IOException exc) { exc.printStackTrace(); + } + + return null; + } + return con; + } + + public static Connection getConnection(String jdbcUrl, String driver, String username, String password) { + if (con == null) { + try { + Class.forName(driver); + con = DriverManager.getConnection(jdbcUrl, username, password); + return con; } catch (ClassNotFoundException exc) { exc.printStackTrace(); } catch (SQLException exc) { exc.printStackTrace(); } + return null; } + return con; } } From 97022ca7d3972e0a057afe017c650a6d8d70703a Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Fri, 10 May 2019 11:23:22 +0430 Subject: [PATCH 043/185] Added a new constructor for employee extension. --- .../extensions/EmployeeDatabaseSetupExtension.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java b/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java index 69e420b28a..f124703690 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/extensions/EmployeeDatabaseSetupExtension.java @@ -15,10 +15,20 @@ import com.baeldung.helpers.JdbcConnectionUtil; public class EmployeeDatabaseSetupExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback { - private Connection con = JdbcConnectionUtil.getConnection(); - private EmployeeJdbcDao employeeDao = new EmployeeJdbcDao(con); + private Connection con; + private EmployeeJdbcDao employeeDao; private Savepoint savepoint; + public EmployeeDatabaseSetupExtension() { + con = JdbcConnectionUtil.getConnection(); + employeeDao = new EmployeeJdbcDao(con); + } + + public EmployeeDatabaseSetupExtension(String jdbcUrl, String driver, String username, String password) { + con = JdbcConnectionUtil.getConnection(jdbcUrl, driver, username, password); + employeeDao = new EmployeeJdbcDao(con); + } + @Override public void afterAll(ExtensionContext context) throws SQLException { if (con != null) { From 0dd99df208039117191555dedcd3eb54499ac230 Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Fri, 10 May 2019 21:45:29 +0430 Subject: [PATCH 044/185] Adding a test to demonstrate programmatic registration. --- .../ProgrammaticEmployeesUnitTest.java | 42 +++++++++++++++++++ .../baeldung/helpers/JdbcConnectionUtil.java | 12 +++++- 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java new file mode 100644 index 0000000000..8a79b92bfc --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java @@ -0,0 +1,42 @@ +package com.baeldung; + +import java.sql.SQLException; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.RegisterExtension; + +import com.baeldung.helpers.Employee; +import com.baeldung.extensions.EmployeeDaoParameterResolver; +import com.baeldung.extensions.EmployeeDatabaseSetupExtension; +import com.baeldung.extensions.EnvironmentExtension; +import com.baeldung.helpers.EmployeeJdbcDao; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith({ EnvironmentExtension.class, EmployeeDaoParameterResolver.class }) +public class ProgrammaticEmployeesUnitTest { + + private EmployeeJdbcDao employeeDao; + + @RegisterExtension static EmployeeDatabaseSetupExtension DB = + new EmployeeDatabaseSetupExtension("jdbc:h2:mem:AnotherDb;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); + + public ProgrammaticEmployeesUnitTest(EmployeeJdbcDao employeeDao) { + this.employeeDao = employeeDao; + } + + @Test + public void whenAddEmployee_thenGetEmployee() throws SQLException { + Employee emp = new Employee(1, "john"); + employeeDao.add(emp); + assertEquals(1, employeeDao.findAll() + .size()); + } + + @Test + public void whenGetEmployees_thenEmptyList() throws SQLException { + assertEquals(0, employeeDao.findAll() + .size()); + } +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java index 4881056e91..ccba627234 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/JdbcConnectionUtil.java @@ -11,7 +11,7 @@ public class JdbcConnectionUtil { private static Connection con; public static Connection getConnection() { - if (con == null) { + if (con == null || isClosed(con)) { try { Properties props = new Properties(); props.load(JdbcConnectionUtil.class.getResourceAsStream("jdbc.properties")); @@ -32,7 +32,7 @@ public class JdbcConnectionUtil { } public static Connection getConnection(String jdbcUrl, String driver, String username, String password) { - if (con == null) { + if (con == null || isClosed(con)) { try { Class.forName(driver); con = DriverManager.getConnection(jdbcUrl, username, password); @@ -48,4 +48,12 @@ public class JdbcConnectionUtil { return con; } + + private static boolean isClosed(Connection con) { + try { + return con.isClosed(); + } catch (SQLException e) { + return true; + } + } } From 4f8327e0b4827fd032d416c1c994ea13104d7db0 Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Mon, 13 May 2019 00:13:07 +0430 Subject: [PATCH 045/185] Upgraded to the latest JUnit 5 versions. --- pom.xml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 9298c8ad17..8ed75368d1 100644 --- a/pom.xml +++ b/pom.xml @@ -124,11 +124,6 @@ - - org.junit.platform - junit-platform-surefire-provider - ${junit-platform.version} - org.junit.jupiter junit-jupiter-engine @@ -1549,8 +1544,8 @@ 1.2 2.9.8 1.3 - 1.2.0 - 5.2.0 + 1.4.2 + 5.4.2 0.3.1 2.5.1 0.0.1 From 8cab3f616e3ee795318099ad63a8856eb10402b4 Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Mon, 13 May 2019 00:14:49 +0430 Subject: [PATCH 046/185] Added the missing test. --- .../baeldung/MultipleExtensionsUnitTest.java | 28 +++++++++++++++++++ .../com/baeldung/helpers/EmployeeJdbcDao.java | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java new file mode 100644 index 0000000000..151e48c551 --- /dev/null +++ b/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.extension.RegisterExtension; +import com.baeldung.extensions.EmployeeDatabaseSetupExtension; + +public class MultipleExtensionsUnitTest { + + @Order(1) + @RegisterExtension + static EmployeeDatabaseSetupExtension SECOND_DB = + new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbTwo;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); + + @Order(0) + @RegisterExtension + static EmployeeDatabaseSetupExtension FIRST_DB = + new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbOne;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); + + @RegisterExtension + static EmployeeDatabaseSetupExtension LAST_DB = + new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbLast;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); + + @Test + public void justDemonstratingTheIdea() { + // empty test + } +} diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java index 7600f763cd..4b274cff39 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/helpers/EmployeeJdbcDao.java @@ -19,7 +19,7 @@ public class EmployeeJdbcDao { } public void createTable() throws SQLException { - String createQuery = "CREATE TABLE employees(id long primary key, firstName varchar(50))"; + String createQuery = "CREATE TABLE IF NOT EXISTS employees(id long primary key, firstName varchar(50))"; PreparedStatement pstmt = con.prepareStatement(createQuery); pstmt.execute(); From 7fa34da4ebb2f62703f59d2dad4dc4bdc6ab67b6 Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Mon, 13 May 2019 00:15:16 +0430 Subject: [PATCH 047/185] Fixed the failed compilation. --- .../src/test/java/com/baeldung/junit5/AssertionUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java index d1d08c6e62..d225e4547e 100644 --- a/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java +++ b/testing-modules/junit5-migration/src/test/java/com/baeldung/junit5/AssertionUnitTest.java @@ -34,7 +34,7 @@ public class AssertionUnitTest { "heading", () -> assertEquals(4, 2 * 2, "4 is 2 times 2"), () -> assertEquals("java", "JAVA".toLowerCase()), - () -> assertEquals(null, null, "null is equal to null") + () -> assertEquals((String) null, (String) null, "null is equal to null") ); } } From f7f6bbe79b28f70bd4f4f5405dc08ffde620dec5 Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Mon, 13 May 2019 00:38:41 +0430 Subject: [PATCH 048/185] Surefire upgrade. --- pom.xml | 2 +- testing-modules/junit-5/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8ed75368d1..22964250de 100644 --- a/pom.xml +++ b/pom.xml @@ -1522,7 +1522,7 @@ 1.1.7 - 2.21.0 + 2.22.0 3.7.0 1.6.0 1.8 diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index 84e0577cfe..b3074635a7 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -139,7 +139,7 @@ 5.4.2 2.8.2 2.0.0-RC.1 - 2.21.0 + 2.22.0 1.6.0 5.0.1.RELEASE From 0d46cd91b8184072e9753e746edf42b1a85e5649 Mon Sep 17 00:00:00 2001 From: Ali Dehghani Date: Mon, 13 May 2019 06:54:21 +0430 Subject: [PATCH 049/185] Resolved discussions. --- .../java/com/baeldung/MultipleExtensionsUnitTest.java | 6 +++--- .../java/com/baeldung/ProgrammaticEmployeesUnitTest.java | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java index 151e48c551..db37e9a6d2 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/MultipleExtensionsUnitTest.java @@ -10,16 +10,16 @@ public class MultipleExtensionsUnitTest { @Order(1) @RegisterExtension static EmployeeDatabaseSetupExtension SECOND_DB = - new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbTwo;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); + new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbTwo;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); @Order(0) @RegisterExtension static EmployeeDatabaseSetupExtension FIRST_DB = - new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbOne;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); + new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbOne;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); @RegisterExtension static EmployeeDatabaseSetupExtension LAST_DB = - new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbLast;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); + new EmployeeDatabaseSetupExtension("jdbc:h2:mem:DbLast;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); @Test public void justDemonstratingTheIdea() { diff --git a/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java b/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java index 8a79b92bfc..a29fafd193 100644 --- a/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java +++ b/testing-modules/junit-5/src/test/java/com/baeldung/ProgrammaticEmployeesUnitTest.java @@ -20,7 +20,7 @@ public class ProgrammaticEmployeesUnitTest { private EmployeeJdbcDao employeeDao; @RegisterExtension static EmployeeDatabaseSetupExtension DB = - new EmployeeDatabaseSetupExtension("jdbc:h2:mem:AnotherDb;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); + new EmployeeDatabaseSetupExtension("jdbc:h2:mem:AnotherDb;DB_CLOSE_DELAY=-1", "org.h2.Driver", "sa", ""); public ProgrammaticEmployeesUnitTest(EmployeeJdbcDao employeeDao) { this.employeeDao = employeeDao; @@ -30,13 +30,11 @@ public class ProgrammaticEmployeesUnitTest { public void whenAddEmployee_thenGetEmployee() throws SQLException { Employee emp = new Employee(1, "john"); employeeDao.add(emp); - assertEquals(1, employeeDao.findAll() - .size()); + assertEquals(1, employeeDao.findAll().size()); } @Test public void whenGetEmployees_thenEmptyList() throws SQLException { - assertEquals(0, employeeDao.findAll() - .size()); + assertEquals(0, employeeDao.findAll().size()); } } From 8a69946ab2539e85da2b3110d0f86fd460c53da9 Mon Sep 17 00:00:00 2001 From: Mike Wojtyna Date: Tue, 14 May 2019 00:17:12 +0200 Subject: [PATCH 050/185] Add examples supporting BAEL-2273 article --- .../AmountBasedDiscountPolicy.java | 15 ++++ .../order/doubledispatch/DiscountPolicy.java | 5 ++ .../doubledispatch/FlatDiscountPolicy.java | 8 ++ .../ddd/order/doubledispatch/Order.java | 29 +++++++ .../doubledispatch/SpecialDiscountPolicy.java | 5 ++ .../order/doubledispatch/SpecialOrder.java | 36 +++++++++ .../visitor/HtmlOrderViewCreator.java | 24 ++++++ .../doubledispatch/visitor/OrderVisitor.java | 9 +++ .../doubledispatch/visitor/Visitable.java | 5 ++ .../com/baeldung/ddd/order/jpa/JpaOrder.java | 2 +- .../baeldung/ddd/order/jpa/JpaProduct.java | 2 +- .../baeldung/ddd/order/OrderFixtureUtils.java | 17 ++++ .../DoubleDispatchDiscountPolicyUnitTest.java | 77 +++++++++++++++++++ .../HtmlOrderViewCreatorUnitTest.java | 43 +++++++++++ .../MethodOverloadExampleUnitTest.java | 50 ++++++++++++ .../SingleDispatchDiscountPolicyUnitTest.java | 37 +++++++++ 16 files changed, 362 insertions(+), 2 deletions(-) create mode 100644 ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/AmountBasedDiscountPolicy.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/DiscountPolicy.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/FlatDiscountPolicy.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/Order.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/SpecialDiscountPolicy.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/SpecialOrder.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/HtmlOrderViewCreator.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/OrderVisitor.java create mode 100644 ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/Visitable.java create mode 100644 ddd/src/test/java/com/baeldung/ddd/order/OrderFixtureUtils.java create mode 100644 ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/DoubleDispatchDiscountPolicyUnitTest.java create mode 100644 ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/HtmlOrderViewCreatorUnitTest.java create mode 100644 ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/MethodOverloadExampleUnitTest.java create mode 100644 ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/SingleDispatchDiscountPolicyUnitTest.java diff --git a/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/AmountBasedDiscountPolicy.java b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/AmountBasedDiscountPolicy.java new file mode 100644 index 0000000000..db673d5d50 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/AmountBasedDiscountPolicy.java @@ -0,0 +1,15 @@ +package com.baeldung.ddd.order.doubledispatch; + +import org.joda.money.CurrencyUnit; +import org.joda.money.Money; + +public class AmountBasedDiscountPolicy implements DiscountPolicy { + @Override + public double discount(Order order) { + if (order.totalCost() + .isGreaterThan(Money.of(CurrencyUnit.USD, 500.00))) { + return 0.10; + } else + return 0; + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/DiscountPolicy.java b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/DiscountPolicy.java new file mode 100644 index 0000000000..7e3c5765c6 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/DiscountPolicy.java @@ -0,0 +1,5 @@ +package com.baeldung.ddd.order.doubledispatch; + +public interface DiscountPolicy { + double discount(Order order); +} diff --git a/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/FlatDiscountPolicy.java b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/FlatDiscountPolicy.java new file mode 100644 index 0000000000..ac7d49fdeb --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/FlatDiscountPolicy.java @@ -0,0 +1,8 @@ +package com.baeldung.ddd.order.doubledispatch; + +public class FlatDiscountPolicy implements DiscountPolicy { + @Override + public double discount(Order order) { + return 0.01; + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/Order.java b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/Order.java new file mode 100644 index 0000000000..c2f763e14c --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/Order.java @@ -0,0 +1,29 @@ +package com.baeldung.ddd.order.doubledispatch; + +import java.math.RoundingMode; +import java.util.List; + +import org.joda.money.Money; + +import com.baeldung.ddd.order.OrderLine; +import com.baeldung.ddd.order.doubledispatch.visitor.OrderVisitor; +import com.baeldung.ddd.order.doubledispatch.visitor.Visitable; + +public class Order extends com.baeldung.ddd.order.Order implements Visitable { + public Order(List orderLines) { + super(orderLines); + } + + public Money totalCost(SpecialDiscountPolicy discountPolicy) { + return totalCost().multipliedBy(1 - applyDiscountPolicy(discountPolicy), RoundingMode.HALF_UP); + } + + protected double applyDiscountPolicy(SpecialDiscountPolicy discountPolicy) { + return discountPolicy.discount(this); + } + + @Override + public void accept(OrderVisitor visitor) { + visitor.visit(this); + } +} diff --git a/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/SpecialDiscountPolicy.java b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/SpecialDiscountPolicy.java new file mode 100644 index 0000000000..866e0e63c2 --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/SpecialDiscountPolicy.java @@ -0,0 +1,5 @@ +package com.baeldung.ddd.order.doubledispatch; + +public interface SpecialDiscountPolicy extends DiscountPolicy { + double discount(SpecialOrder order); +} diff --git a/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/SpecialOrder.java b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/SpecialOrder.java new file mode 100644 index 0000000000..1fe629e0ef --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/SpecialOrder.java @@ -0,0 +1,36 @@ +package com.baeldung.ddd.order.doubledispatch; + +import java.util.List; + +import com.baeldung.ddd.order.OrderLine; +import com.baeldung.ddd.order.doubledispatch.visitor.OrderVisitor; + +public class SpecialOrder extends Order { + + private boolean eligibleForExtraDiscount; + + public SpecialOrder(List orderLines) { + super(orderLines); + this.eligibleForExtraDiscount = false; + } + + public SpecialOrder(List orderLines, boolean eligibleForSpecialDiscount) { + super(orderLines); + this.eligibleForExtraDiscount = eligibleForSpecialDiscount; + } + + public boolean isEligibleForExtraDiscount() { + return eligibleForExtraDiscount; + } + + @Override + protected double applyDiscountPolicy(SpecialDiscountPolicy discountPolicy) { + return discountPolicy.discount(this); + } + + @Override + public void accept(OrderVisitor visitor) { + visitor.visit(this); + } + +} diff --git a/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/HtmlOrderViewCreator.java b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/HtmlOrderViewCreator.java new file mode 100644 index 0000000000..ea23cdaa4b --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/HtmlOrderViewCreator.java @@ -0,0 +1,24 @@ +package com.baeldung.ddd.order.doubledispatch.visitor; + +import com.baeldung.ddd.order.doubledispatch.Order; +import com.baeldung.ddd.order.doubledispatch.SpecialOrder; + +public class HtmlOrderViewCreator implements OrderVisitor { + + private String html; + + public String getHtml() { + return html; + } + + @Override + public void visit(Order order) { + html = String.format("

Regular order total cost: %s

", order.totalCost()); + } + + @Override + public void visit(SpecialOrder order) { + html = String.format("

Special Order

total cost: %s

", order.totalCost()); + } + +} diff --git a/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/OrderVisitor.java b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/OrderVisitor.java new file mode 100644 index 0000000000..00f0740f6e --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/OrderVisitor.java @@ -0,0 +1,9 @@ +package com.baeldung.ddd.order.doubledispatch.visitor; + +import com.baeldung.ddd.order.doubledispatch.Order; +import com.baeldung.ddd.order.doubledispatch.SpecialOrder; + +public interface OrderVisitor { + void visit(Order order); + void visit(SpecialOrder order); +} diff --git a/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/Visitable.java b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/Visitable.java new file mode 100644 index 0000000000..1628718d9b --- /dev/null +++ b/ddd/src/main/java/com/baeldung/ddd/order/doubledispatch/visitor/Visitable.java @@ -0,0 +1,5 @@ +package com.baeldung.ddd.order.doubledispatch.visitor; + +public interface Visitable { + void accept(V visitor); +} diff --git a/ddd/src/main/java/com/baeldung/ddd/order/jpa/JpaOrder.java b/ddd/src/main/java/com/baeldung/ddd/order/jpa/JpaOrder.java index ed11b0dca4..81ae3bbd19 100644 --- a/ddd/src/main/java/com/baeldung/ddd/order/jpa/JpaOrder.java +++ b/ddd/src/main/java/com/baeldung/ddd/order/jpa/JpaOrder.java @@ -92,7 +92,7 @@ class JpaOrder { } void removeLineItem(int line) { - JpaOrderLine removedLine = orderLines.remove(line); + orderLines.remove(line); } void setCurrencyUnit(String currencyUnit) { diff --git a/ddd/src/main/java/com/baeldung/ddd/order/jpa/JpaProduct.java b/ddd/src/main/java/com/baeldung/ddd/order/jpa/JpaProduct.java index 61e67fa12a..1d2ae5230a 100644 --- a/ddd/src/main/java/com/baeldung/ddd/order/jpa/JpaProduct.java +++ b/ddd/src/main/java/com/baeldung/ddd/order/jpa/JpaProduct.java @@ -15,7 +15,7 @@ class JpaProduct { public JpaProduct(BigDecimal price, String currencyUnit) { super(); this.price = price; - currencyUnit = currencyUnit; + this.currencyUnit = currencyUnit; } @Override diff --git a/ddd/src/test/java/com/baeldung/ddd/order/OrderFixtureUtils.java b/ddd/src/test/java/com/baeldung/ddd/order/OrderFixtureUtils.java new file mode 100644 index 0000000000..2b0e0b1997 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/ddd/order/OrderFixtureUtils.java @@ -0,0 +1,17 @@ +package com.baeldung.ddd.order; + +import java.util.Arrays; +import java.util.List; + +import org.joda.money.CurrencyUnit; +import org.joda.money.Money; + +public class OrderFixtureUtils { + public static List anyOrderLines() { + return Arrays.asList(new OrderLine(new Product(Money.of(CurrencyUnit.USD, 100)), 1)); + } + + public static List orderLineItemsWorthNDollars(int totalCost) { + return Arrays.asList(new OrderLine(new Product(Money.of(CurrencyUnit.USD, totalCost)), 1)); + } +} diff --git a/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/DoubleDispatchDiscountPolicyUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/DoubleDispatchDiscountPolicyUnitTest.java new file mode 100644 index 0000000000..0ec73415d3 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/DoubleDispatchDiscountPolicyUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.ddd.order.doubledispatch; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.joda.money.CurrencyUnit; +import org.joda.money.Money; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import com.baeldung.ddd.order.OrderFixtureUtils; + +public class DoubleDispatchDiscountPolicyUnitTest { + // @formatter:off + @DisplayName( + "given regular order with items worth $100 total, " + + "when apply 10% discount policy, " + + "then cost after discount is $90" + ) + // @formatter:on + @Test + void test() throws Exception { + // given + Order order = new Order(OrderFixtureUtils.orderLineItemsWorthNDollars(100)); + SpecialDiscountPolicy discountPolicy = new SpecialDiscountPolicy() { + + @Override + public double discount(Order order) { + return 0.10; + } + + @Override + public double discount(SpecialOrder order) { + return 0; + } + }; + + // when + Money totalCostAfterDiscount = order.totalCost(discountPolicy); + + // then + assertThat(totalCostAfterDiscount).isEqualTo(Money.of(CurrencyUnit.USD, 90)); + } + + // @formatter:off + @DisplayName( + "given special order eligible for extra discount with items worth $100 total, " + + "when apply 20% discount policy for extra discount orders, " + + "then cost after discount is $80" + ) + // @formatter:on + @Test + void test1() throws Exception { + // given + boolean eligibleForExtraDiscount = true; + Order order = new SpecialOrder(OrderFixtureUtils.orderLineItemsWorthNDollars(100), eligibleForExtraDiscount); + SpecialDiscountPolicy discountPolicy = new SpecialDiscountPolicy() { + + @Override + public double discount(Order order) { + return 0; + } + + @Override + public double discount(SpecialOrder order) { + if (order.isEligibleForExtraDiscount()) + return 0.20; + return 0.10; + } + }; + + // when + Money totalCostAfterDiscount = order.totalCost(discountPolicy); + + // then + assertThat(totalCostAfterDiscount).isEqualTo(Money.of(CurrencyUnit.USD, 80.00)); + } +} diff --git a/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/HtmlOrderViewCreatorUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/HtmlOrderViewCreatorUnitTest.java new file mode 100644 index 0000000000..e360c1c76a --- /dev/null +++ b/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/HtmlOrderViewCreatorUnitTest.java @@ -0,0 +1,43 @@ +package com.baeldung.ddd.order.doubledispatch; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import com.baeldung.ddd.order.doubledispatch.Order; +import com.baeldung.ddd.order.OrderFixtureUtils; +import com.baeldung.ddd.order.OrderLine; +import com.baeldung.ddd.order.doubledispatch.visitor.HtmlOrderViewCreator; + +public class HtmlOrderViewCreatorUnitTest { + // @formatter:off + @DisplayName( + "given collection of regular and special orders, " + + "when create HTML view using visitor for each order, " + + "then the dedicated view is created for each order" + ) + // @formatter:on + @Test + void test() throws Exception { + // given + List anyOrderLines = OrderFixtureUtils.anyOrderLines(); + List orders = Arrays.asList(new Order(anyOrderLines), new SpecialOrder(anyOrderLines)); + HtmlOrderViewCreator htmlOrderViewCreator = new HtmlOrderViewCreator(); + + // when + orders.get(0) + .accept(htmlOrderViewCreator); + String regularOrderHtml = htmlOrderViewCreator.getHtml(); + orders.get(1) + .accept(htmlOrderViewCreator); + String specialOrderHtml = htmlOrderViewCreator.getHtml(); + + // then + assertThat(regularOrderHtml).containsPattern("

Regular order total cost: .*

"); + assertThat(specialOrderHtml).containsPattern("

Special Order

total cost: .*

"); + } +} diff --git a/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/MethodOverloadExampleUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/MethodOverloadExampleUnitTest.java new file mode 100644 index 0000000000..3d135e9dbe --- /dev/null +++ b/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/MethodOverloadExampleUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.ddd.order.doubledispatch; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import com.baeldung.ddd.order.doubledispatch.Order; +import com.baeldung.ddd.order.OrderFixtureUtils; +import com.baeldung.ddd.order.OrderLine; +import com.baeldung.ddd.order.doubledispatch.SpecialDiscountPolicy; +import com.baeldung.ddd.order.doubledispatch.SpecialOrder; + +public class MethodOverloadExampleUnitTest { +// @formatter:off +@DisplayName( + "given discount policy accepting special orders, " + + "when apply the policy on special order declared as regular order, " + + "then regular discount method is used" + ) +// @formatter:on + @Test + void test() throws Exception { + // given + SpecialDiscountPolicy specialPolicy = new SpecialDiscountPolicy() { + @Override + public double discount(Order order) { + return 0.01; + } + + @Override + public double discount(SpecialOrder order) { + return 0.10; + } + }; + Order specialOrder = new SpecialOrder(anyOrderLines()); + + // when + double discount = specialPolicy.discount(specialOrder); + + // then + assertThat(discount).isEqualTo(0.01); + } + + private List anyOrderLines() { + return OrderFixtureUtils.anyOrderLines(); + } +} diff --git a/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/SingleDispatchDiscountPolicyUnitTest.java b/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/SingleDispatchDiscountPolicyUnitTest.java new file mode 100644 index 0000000000..82e074d028 --- /dev/null +++ b/ddd/src/test/java/com/baeldung/ddd/order/doubledispatch/SingleDispatchDiscountPolicyUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.ddd.order.doubledispatch; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import com.baeldung.ddd.order.OrderFixtureUtils; + +public class SingleDispatchDiscountPolicyUnitTest { + // @formatter:off + @DisplayName( + "given two discount policies, " + + "when use these policies, " + + "then single dispatch chooses the implementation based on runtime type" + ) + // @formatter:on + @Test + void test() throws Exception { + // given + DiscountPolicy flatPolicy = new FlatDiscountPolicy(); + DiscountPolicy amountPolicy = new AmountBasedDiscountPolicy(); + Order orderWorth501Dollars = orderWorthNDollars(501); + + // when + double flatDiscount = flatPolicy.discount(orderWorth501Dollars); + double amountDiscount = amountPolicy.discount(orderWorth501Dollars); + + // then + assertThat(flatDiscount).isEqualTo(0.01); + assertThat(amountDiscount).isEqualTo(0.1); + } + + private Order orderWorthNDollars(int totalCost) { + return new Order(OrderFixtureUtils.orderLineItemsWorthNDollars(totalCost)); + } +} From 7a4f96ea2ee3ae9c8a702bd656ebd0e8c8784d0b Mon Sep 17 00:00:00 2001 From: Pavan Shankar Koli Date: Tue, 14 May 2019 22:50:09 +0530 Subject: [PATCH 051/185] BAEL-2886 Added Integration test cases --- .../SpringSessionMongoDBIntegrationTest.java | 4 ++++ .../springsessionmongodb/SpringSessionMongoDBApplication.java | 0 .../controller/SpringSessionMongoDBController.java | 0 .../SpringSessionMongoDBIntegrationTest.java | 4 ++++ .../java/{ => org}/baeldung/SpringContextIntegrationTest.java | 0 5 files changed, 8 insertions(+) create mode 100644 spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java rename spring-session/spring-session-mongodb/src/main/java/{ => com/baeldung}/springsessionmongodb/SpringSessionMongoDBApplication.java (100%) rename spring-session/spring-session-mongodb/src/main/java/{ => com/baeldung}/springsessionmongodb/controller/SpringSessionMongoDBController.java (100%) create mode 100644 spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java rename spring-session/spring-session-mongodb/src/test/java/{ => org}/baeldung/SpringContextIntegrationTest.java (100%) diff --git a/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java new file mode 100644 index 0000000000..60f0dc97ca --- /dev/null +++ b/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java @@ -0,0 +1,4 @@ +package com.baeldung.springsessionmongodb; + +public class SpringSessionMongoDBIntegrationTest { +} diff --git a/spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/SpringSessionMongoDBApplication.java b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBApplication.java similarity index 100% rename from spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/SpringSessionMongoDBApplication.java rename to spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBApplication.java diff --git a/spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/controller/SpringSessionMongoDBController.java b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java similarity index 100% rename from spring-session/spring-session-mongodb/src/main/java/springsessionmongodb/controller/SpringSessionMongoDBController.java rename to spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java diff --git a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java new file mode 100644 index 0000000000..60f0dc97ca --- /dev/null +++ b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java @@ -0,0 +1,4 @@ +package com.baeldung.springsessionmongodb; + +public class SpringSessionMongoDBIntegrationTest { +} diff --git a/spring-session/spring-session-mongodb/src/test/java/baeldung/SpringContextIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java similarity index 100% rename from spring-session/spring-session-mongodb/src/test/java/baeldung/SpringContextIntegrationTest.java rename to spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java From 8ff89c0c05ed87dd3b852d5e438345ad638494ca Mon Sep 17 00:00:00 2001 From: Pavan Shankar Koli Date: Tue, 14 May 2019 22:51:49 +0530 Subject: [PATCH 052/185] BAEL-2886 Added Integration test cases --- .../SpringSessionMongoDBIntegrationTest.java | 39 +++++++++++++++++++ .../SpringSessionMongoDBApplication.java | 2 +- .../SpringSessionMongoDBController.java | 17 ++++---- .../src/main/resources/application.properties | 7 +++- .../SpringSessionMongoDBIntegrationTest.java | 38 ++++++++++++++++++ .../SpringContextIntegrationTest.java | 5 ++- 6 files changed, 96 insertions(+), 12 deletions(-) diff --git a/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java index 60f0dc97ca..c73335b49b 100644 --- a/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java +++ b/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java @@ -1,4 +1,43 @@ package com.baeldung.springsessionmongodb; +import org.junit.Assert; +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.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.session.data.mongo.MongoOperationsSessionRepository; +import org.springframework.test.context.junit4.SpringRunner; +import springsessionmongodb.SpringSessionMongoDBApplication; + +import java.util.Base64; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringSessionMongoDBApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class SpringSessionMongoDBIntegrationTest { + + @Autowired + private MongoOperationsSessionRepository repository; + + private TestRestTemplate restTemplate = new TestRestTemplate(); + + @Test + public void givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() { + HttpEntity response = restTemplate. + exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class); + HttpHeaders headers = response.getHeaders(); + String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE); + + Assert.assertEquals(response.getBody(), + repository.findById(getSessionId(set_cookie)).getAttribute("count").toString()); + } + + private String getSessionId(String set_cookie) { + return new String(Base64.getDecoder().decode(set_cookie.split(";")[0].split("=")[1])); + } + } diff --git a/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBApplication.java b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBApplication.java index c574501472..2994efc719 100644 --- a/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBApplication.java +++ b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBApplication.java @@ -1,4 +1,4 @@ -package springsessionmongodb; +package com.baeldung.springsessionmongodb; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java index 50fc432d56..1c38f419c3 100644 --- a/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java +++ b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java @@ -1,27 +1,28 @@ -package springsessionmongodb.controller; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; +package com.baeldung.springsessionmongodb.controller; import javax.servlet.http.HttpSession; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + @RestController public class SpringSessionMongoDBController { @GetMapping("/") - public String count(HttpSession session) { + public ResponseEntity count(HttpSession session) { Integer counter = (Integer) session.getAttribute("count"); if (counter == null) { - counter = 0; + counter = 1; } else { counter += 1; } session.setAttribute("count", counter); - return "

Count is "+counter+"

"; + return ResponseEntity.ok(counter); } -} +} \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/src/main/resources/application.properties b/spring-session/spring-session-mongodb/src/main/resources/application.properties index aeb7eb91ad..1b1a6cfbcb 100644 --- a/spring-session/spring-session-mongodb/src/main/resources/application.properties +++ b/spring-session/spring-session-mongodb/src/main/resources/application.properties @@ -1 +1,6 @@ -spring.session.store-type=mongodb \ No newline at end of file +spring.session.store-type=mongodb +server.port=8080 + +spring.data.mongodb.host=localhost +spring.data.mongodb.port=27017 +spring.data.mongodb.database=springboot-mongo \ No newline at end of file diff --git a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java index 60f0dc97ca..24cf50f18d 100644 --- a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java +++ b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java @@ -1,4 +1,42 @@ package com.baeldung.springsessionmongodb; +import java.util.Base64; + +import org.junit.Assert; +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.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.session.data.mongo.MongoOperationsSessionRepository; +import org.springframework.test.context.junit4.SpringRunner; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringSessionMongoDBApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) public class SpringSessionMongoDBIntegrationTest { + + @Autowired + private MongoOperationsSessionRepository repository; + + private TestRestTemplate restTemplate = new TestRestTemplate(); + + @Test + public void givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() { + HttpEntity response = restTemplate. + exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class); + HttpHeaders headers = response.getHeaders(); + String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE); + + Assert.assertEquals(response.getBody(), + repository.findById(getSessionId(set_cookie)).getAttribute("count").toString()); + } + + private String getSessionId(String set_cookie) { + return new String(Base64.getDecoder().decode(set_cookie.split(";")[0].split("=")[1])); + } + } diff --git a/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java index b58fd46dae..3c58b2673f 100644 --- a/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,10 +1,11 @@ -package baeldung; +package org.baeldung; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import springsessionmongodb.SpringSessionMongoDBApplication; + +import com.baeldung.springsessionmongodb.SpringSessionMongoDBApplication; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringSessionMongoDBApplication.class) From ef8b8232a798d2732f958937204fb849ffc7de17 Mon Sep 17 00:00:00 2001 From: Alessio Stalla Date: Tue, 14 May 2019 22:41:48 +0200 Subject: [PATCH 053/185] Bael-868 (#6959) * Tests for BAEL-868 (RxKotlin) * BAEL-868 fix warnings * Fix the build (?) * Fix the build * #BAEL-868 move RxKotlin test from kotlin-libraries project to kotlin-libraries-2 --- kotlin-libraries-2/pom.xml | 8 +- .../baeldung/kotlin/rxkotlin/RxKotlinTest.kt | 157 ++++++++++++++++++ kotlin-libraries/build.gradle | 3 +- 3 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 kotlin-libraries-2/src/test/kotlin/com/baeldung/kotlin/rxkotlin/RxKotlinTest.kt diff --git a/kotlin-libraries-2/pom.xml b/kotlin-libraries-2/pom.xml index e2e261cb1b..14ac61a093 100644 --- a/kotlin-libraries-2/pom.xml +++ b/kotlin-libraries-2/pom.xml @@ -18,14 +18,16 @@ com.fasterxml.jackson.module jackson-module-kotlin
+ + io.reactivex.rxjava2 + rxkotlin + 2.3.0 + junit junit test - - -
diff --git a/kotlin-libraries-2/src/test/kotlin/com/baeldung/kotlin/rxkotlin/RxKotlinTest.kt b/kotlin-libraries-2/src/test/kotlin/com/baeldung/kotlin/rxkotlin/RxKotlinTest.kt new file mode 100644 index 0000000000..979ed3f809 --- /dev/null +++ b/kotlin-libraries-2/src/test/kotlin/com/baeldung/kotlin/rxkotlin/RxKotlinTest.kt @@ -0,0 +1,157 @@ +package com.baeldung.kotlin.rxkotlin + +import io.reactivex.Maybe +import io.reactivex.Observable +import io.reactivex.functions.BiFunction +import io.reactivex.rxkotlin.* +import io.reactivex.subjects.PublishSubject +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse + +class RxKotlinTest { + + @Test + fun whenBooleanArrayToObserver_thenBooleanObserver() { + val observable = listOf(true, false, false).toObservable() + observable.test().assertValues(true, false, false) + } + + @Test + fun whenBooleanArrayToFlowable_thenBooleanFlowable() { + val flowable = listOf(true, false, false).toFlowable() + flowable.buffer(2).test().assertValues(listOf(true, false), listOf(false)) + } + + @Test + fun whenIntArrayToObserver_thenIntObserver() { + val observable = listOf(1, 1, 2, 3).toObservable() + observable.test().assertValues(1, 1, 2, 3) + } + + @Test + fun whenIntArrayToFlowable_thenIntFlowable() { + val flowable = listOf(1, 1, 2, 3).toFlowable() + flowable.buffer(2).test().assertValues(listOf(1, 1), listOf(2, 3)) + } + + @Test + fun whenObservablePairToMap_thenSingleNoDuplicates() { + val list = listOf(Pair("a", 1), Pair("b", 2), Pair("c", 3), Pair("a", 4)) + val observable = list.toObservable() + val map = observable.toMap() + assertEquals(mapOf(Pair("a", 4), Pair("b", 2), Pair("c", 3)), map.blockingGet()) + } + + @Test + fun whenObservablePairToMap_thenSingleWithDuplicates() { + val list = listOf(Pair("a", 1), Pair("b", 2), Pair("c", 3), Pair("a", 4)) + val observable = list.toObservable() + val map = observable.toMultimap() + assertEquals( + mapOf(Pair("a", listOf(1, 4)), Pair("b", listOf(2)), Pair("c", listOf(3))), + map.blockingGet()) + } + + @Test + fun whenMergeAll_thenStream() { + val subject = PublishSubject.create>() + val observable = subject.mergeAll() + val testObserver = observable.test() + subject.onNext(Observable.just("first", "second")) + testObserver.assertValues("first", "second") + subject.onNext(Observable.just("third", "fourth")) + subject.onNext(Observable.just("fifth")) + testObserver.assertValues("first", "second", "third", "fourth", "fifth") + } + + @Test + fun whenConcatAll_thenStream() { + val subject = PublishSubject.create>() + val observable = subject.concatAll() + val testObserver = observable.test() + subject.onNext(Observable.just("first", "second")) + testObserver.assertValues("first", "second") + subject.onNext(Observable.just("third", "fourth")) + subject.onNext(Observable.just("fifth")) + testObserver.assertValues("first", "second", "third", "fourth", "fifth") + } + + @Test + fun whenSwitchLatest_thenStream() { + val subject = PublishSubject.create>() + val observable = subject.switchLatest() + val testObserver = observable.test() + subject.onNext(Observable.just("first", "second")) + testObserver.assertValues("first", "second") + subject.onNext(Observable.just("third", "fourth")) + subject.onNext(Observable.just("fifth")) + testObserver.assertValues("first", "second", "third", "fourth", "fifth") + } + + @Test + fun whenMergeAllMaybes_thenObservable() { + val subject = PublishSubject.create>() + val observable = subject.mergeAllMaybes() + val testObserver = observable.test() + subject.onNext(Maybe.just(1)) + subject.onNext(Maybe.just(2)) + subject.onNext(Maybe.empty()) + testObserver.assertValues(1, 2) + subject.onNext(Maybe.error(Exception(""))) + subject.onNext(Maybe.just(3)) + testObserver.assertValues(1, 2).assertError(Exception::class.java) + } + + @Test + fun whenMerge_thenStream() { + val observables = mutableListOf(Observable.just("first", "second")) + val observable = observables.merge() + observables.add(Observable.just("third", "fourth")) + observables.add(Observable.error(Exception("e"))) + observables.add(Observable.just("fifth")) + + observable.test().assertValues("first", "second", "third", "fourth").assertError(Exception::class.java) + } + + @Test + fun whenMergeDelayError_thenStream() { + val observables = mutableListOf>(Observable.error(Exception("e1"))) + val observable = observables.mergeDelayError() + observables.add(Observable.just("1", "2")) + observables.add(Observable.error(Exception("e2"))) + observables.add(Observable.just("3")) + + observable.test().assertValues("1", "2", "3").assertError(Exception::class.java) + } + + @Test + fun whenCast_thenUniformType() { + val observable = Observable.just(1, 1, 2, 3) + observable.cast().test().assertValues(1, 1, 2, 3) + } + + @Test + fun whenOfType_thenFilter() { + val observable = Observable.just(1, "and", 2, "and") + observable.ofType().test().assertValues(1, 2) + } + + @Test + fun whenFunction_thenCompletable() { + var value = 0 + val completable = { value = 3 }.toCompletable() + assertFalse(completable.test().isCancelled) + assertEquals(3, value) + } + + @Test + fun whenHelper_thenMoreIdiomaticKotlin() { + val zipWith = Observable.just(1).zipWith(Observable.just(2)) { a, b -> a + b } + zipWith.subscribeBy(onNext = { println(it) }) + val zip = Observables.zip(Observable.just(1), Observable.just(2)) { a, b -> a + b } + zip.subscribeBy(onNext = { println(it) }) + val zipOrig = Observable.zip(Observable.just(1), Observable.just(2), BiFunction { a, b -> a + b }) + zipOrig.subscribeBy(onNext = { println(it) }) + } +} diff --git a/kotlin-libraries/build.gradle b/kotlin-libraries/build.gradle index afb92de49e..db23a438a0 100644 --- a/kotlin-libraries/build.gradle +++ b/kotlin-libraries/build.gradle @@ -54,9 +54,8 @@ dependencies { testCompile group: 'org.jetbrains.spek', name: 'spek-subject-extension', version: '1.1.5' testCompile group: 'org.jetbrains.spek', name: 'spek-junit-platform-engine', version: '1.1.5' implementation 'com.beust:klaxon:3.0.1' - implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0' - } + task runServer(type: JavaExec) { main = 'APIServer' classpath = sourceSets.main.runtimeClasspath From 0825c88d7ae49d114e3031724e5d6c57a6b22b42 Mon Sep 17 00:00:00 2001 From: cdjole Date: Tue, 14 May 2019 22:57:08 +0200 Subject: [PATCH 054/185] [BAEL-2963] - String initialization (#6962) --- .../StringInitializationUnitTest.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 java-strings-2/src/test/java/com/baeldung/initialization/StringInitializationUnitTest.java diff --git a/java-strings-2/src/test/java/com/baeldung/initialization/StringInitializationUnitTest.java b/java-strings-2/src/test/java/com/baeldung/initialization/StringInitializationUnitTest.java new file mode 100644 index 0000000000..50d9a2b058 --- /dev/null +++ b/java-strings-2/src/test/java/com/baeldung/initialization/StringInitializationUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung.initialization; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +public class StringInitializationUnitTest { + + private String fieldString; + + void printDeclaredOnlyString() { + String localVarString = null; + + System.out.println(localVarString); // compilation error + System.out.println(fieldString); + } + + @Test + public void givenDeclaredFeldStringAndNullString_thenCompareEquals() { + String localVarString = null; + + assertEquals(fieldString, localVarString); + } + + @Test + public void givenTwoStringsWithSameLiteral_thenCompareReferencesEquals() { + String literalOne = "Baeldung"; + String literalTwo = "Baeldung"; + + assertTrue(literalOne == literalTwo); + } + + @Test + public void givenTwoStringsUsingNew_thenCompareReferencesNotEquals() { + String newStringOne = new String("Baeldung"); + String newStringTwo = new String("Baeldung"); + + assertFalse(newStringOne == newStringTwo); + } + + @Test + public void givenEmptyLiteralStringsAndNewObject_thenCompareEquals() { + String emptyLiteral = ""; + String emptyNewString = new String(""); + + assertEquals(emptyLiteral, emptyNewString); + } + + @Test + public void givenEmptyStringObjects_thenCompareEquals() { + String emptyNewString = new String(""); + String emptyNewStringTwo = new String(); + + assertEquals(emptyNewString, emptyNewStringTwo); + } +} From 7f275f9b38f25b0a5b80c7315363c4addd45e190 Mon Sep 17 00:00:00 2001 From: dupirefr Date: Wed, 15 May 2019 08:19:30 +0200 Subject: [PATCH 055/185] [BAEL-2932] Using Predicate.not to negate a method reference --- .../baeldung/predicate/not/FindPeople.java | 31 +++++++++++++++++++ .../com/baeldung/predicate/not/Person.java | 19 ++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java create mode 100644 core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/Person.java diff --git a/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java new file mode 100644 index 0000000000..845908636f --- /dev/null +++ b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java @@ -0,0 +1,31 @@ +package com.baeldung.predicate.not; + +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public class FindPeople { + public static void main(String[] args) { + List people = List.of( + new Person(1), + new Person(18), + new Person(2) + ); + + people.stream() + .filter(Person::isAdult) + .collect(Collectors.toList()); + + people.stream() + .filter(person -> !person.isAdult()) + .collect(Collectors.toList()); + + people.stream() + .filter(Person::isNotAdult) + .collect(Collectors.toList()); + + people.stream() + .filter(Predicate.not(Person::isAdult)) + .collect(Collectors.toList()); + } +} diff --git a/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/Person.java b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/Person.java new file mode 100644 index 0000000000..3c93e08194 --- /dev/null +++ b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/Person.java @@ -0,0 +1,19 @@ +package com.baeldung.predicate.not; + +public class Person { + private static final int ADULT_AGE = 18; + + private int age; + + public Person(int age) { + this.age = age; + } + + public boolean isAdult() { + return age >= ADULT_AGE; + } + + public boolean isNotAdult() { + return !isAdult(); + } +} From f5937a3600e11c09927a7cd8ae4a31e5931976e6 Mon Sep 17 00:00:00 2001 From: dupirefr Date: Wed, 15 May 2019 08:29:25 +0200 Subject: [PATCH 056/185] [BAEL-2932] Static import of Predicate.not --- .../src/main/java/com/baeldung/predicate/not/FindPeople.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java index 845908636f..254f648d30 100644 --- a/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java +++ b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java @@ -4,6 +4,8 @@ import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; +import static java.util.function.Predicate.*; + public class FindPeople { public static void main(String[] args) { List people = List.of( @@ -25,7 +27,7 @@ public class FindPeople { .collect(Collectors.toList()); people.stream() - .filter(Predicate.not(Person::isAdult)) + .filter(not(Person::isAdult)) .collect(Collectors.toList()); } } From bf79c6100fde8cdf5fe1eb1a9065e037031cf279 Mon Sep 17 00:00:00 2001 From: Kumar Sushant Date: Wed, 15 May 2019 21:21:42 +0300 Subject: [PATCH 057/185] Update GuavaSetOperationsUnitTest.java --- .../org/baeldung/guava/GuavaSetOperationsUnitTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java index 07c99ba184..dfd90ad738 100644 --- a/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java +++ b/guava-collections-set/src/test/java/org/baeldung/guava/GuavaSetOperationsUnitTest.java @@ -17,7 +17,7 @@ import static org.junit.Assert.assertTrue; public class GuavaSetOperationsUnitTest { @Test - public void whenCalculateUnionOfSets_thenCorrect() { + public void whenCalculatingUnionOfSets_thenCorrect() { final Set first = ImmutableSet.of('a', 'b', 'c'); final Set second = ImmutableSet.of('b', 'c', 'd'); @@ -26,7 +26,7 @@ public class GuavaSetOperationsUnitTest { } @Test - public void whenCalculateSetsProduct_thenCorrect() { + public void whenCalculatingCartesianProductOfSets_thenCorrect() { final Set first = ImmutableSet.of('a', 'b'); final Set second = ImmutableSet.of('c', 'd'); final Set> result = Sets.cartesianProduct(ImmutableList.of(first, second)); @@ -75,7 +75,7 @@ public class GuavaSetOperationsUnitTest { } @Test - public void whenCreateRangeOfIntegersSet_thenCreated() { + public void whenCreatingRangeOfIntegersSet_thenCreated() { final int start = 10; final int end = 30; final ContiguousSet set = ContiguousSet.create(Range.closed(start, end), DiscreteDomain.integers()); @@ -86,7 +86,7 @@ public class GuavaSetOperationsUnitTest { } @Test - public void whenCreateRangeSet_thenCreated() { + public void whenUsingRangeSet_thenCorrect() { final RangeSet rangeSet = TreeRangeSet.create(); rangeSet.add(Range.closed(1, 10)); rangeSet.add(Range.closed(12, 15)); @@ -115,7 +115,7 @@ public class GuavaSetOperationsUnitTest { } @Test - public void whenGetTopUsingMultiSet_thenCorrect() { + public void whenGetTopOcurringElementsWithMultiSet_thenCorrect() { final Multiset names = HashMultiset.create(); names.add("John"); names.add("Adam", 5); From d93670a4065c931ed8e227d5b24465e9320eed6d Mon Sep 17 00:00:00 2001 From: Kumar Sushant Date: Wed, 15 May 2019 21:26:32 +0300 Subject: [PATCH 058/185] Update README.md --- guava-collections-set/README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/guava-collections-set/README.md b/guava-collections-set/README.md index ee03287680..77d8644ff3 100644 --- a/guava-collections-set/README.md +++ b/guava-collections-set/README.md @@ -1,5 +1,3 @@ -========= - ## Guava Examples @@ -8,4 +6,3 @@ - [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset) - [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial) - [Guide to Guava Multiset](https://www.baeldung.com/guava-multiset) -======= From 989b0a2bdb4b5dd8ea103b923078de3c304fdd49 Mon Sep 17 00:00:00 2001 From: Kumar Sushant Date: Wed, 15 May 2019 21:28:11 +0300 Subject: [PATCH 059/185] Update README.md --- guava-collections-set/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guava-collections-set/README.md b/guava-collections-set/README.md index 77d8644ff3..c36d9e0b61 100644 --- a/guava-collections-set/README.md +++ b/guava-collections-set/README.md @@ -1,7 +1,7 @@ -## Guava Examples +# Guava +## Relevant Articles: -### Relevant Articles: - [Guava – Sets](http://www.baeldung.com/guava-sets) - [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset) - [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial) From d24015f5aaba3dc77855c89c38936893d342eb4e Mon Sep 17 00:00:00 2001 From: Amy DeGregorio Date: Thu, 16 May 2019 11:24:09 -0400 Subject: [PATCH 060/185] BAEL 2824 (#6971) * BAEL-2727 Example Code * Example code for BAEL-2824 --- .../java/com/baeldung/like/model/Movie.java | 58 ++++++++++++ .../like/repository/MovieRepository.java | 41 +++++++++ .../like/MovieRepositoryIntegrationTest.java | 88 +++++++++++++++++++ .../src/test/resources/test-movie-cleanup.sql | 1 + .../src/test/resources/test-movie-data.sql | 7 ++ 5 files changed, 195 insertions(+) create mode 100644 persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/model/Movie.java create mode 100644 persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/repository/MovieRepository.java create mode 100644 persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/like/MovieRepositoryIntegrationTest.java create mode 100644 persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-cleanup.sql create mode 100644 persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-data.sql diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/model/Movie.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/model/Movie.java new file mode 100644 index 0000000000..bba8bd35c4 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/model/Movie.java @@ -0,0 +1,58 @@ +package com.baeldung.like.model; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Movie { + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private Long id; + private String title; + private String director; + private String rating; + private int duration; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getDirector() { + return director; + } + + public void setDirector(String director) { + this.director = director; + } + + public String getRating() { + return rating; + } + + public void setRating(String rating) { + this.rating = rating; + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + +} diff --git a/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/repository/MovieRepository.java b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/repository/MovieRepository.java new file mode 100644 index 0000000000..241bdd3306 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/main/java/com/baeldung/like/repository/MovieRepository.java @@ -0,0 +1,41 @@ +package com.baeldung.like.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; + +import com.baeldung.like.model.Movie; + +public interface MovieRepository extends CrudRepository { + + List findByTitleContaining(String title); + + List findByTitleLike(String title); + + List findByTitleContains(String title); + + List findByTitleIsContaining(String title); + + List findByRatingStartsWith(String rating); + + List findByDirectorEndsWith(String director); + + List findByTitleContainingIgnoreCase(String title); + + List findByRatingNotContaining(String rating); + + List findByDirectorNotLike(String director); + + @Query("SELECT m FROM Movie m WHERE m.title LIKE %:title%") + List searchByTitleLike(@Param("title") String title); + + @Query("SELECT m FROM Movie m WHERE m.rating LIKE ?1%") + List searchByRatingStartsWith(String rating); + + //Escaping works in SpringBoot >= 2.4.1 + //@Query("SELECT m FROM Movie m WHERE m.director LIKE %?#{escape([0])} escape ?#{escapeCharacter()}") + @Query("SELECT m FROM Movie m WHERE m.director LIKE %:#{[0]}") + List searchByDirectorEndsWith(String director); +} diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/like/MovieRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/like/MovieRepositoryIntegrationTest.java new file mode 100644 index 0000000000..99d7080792 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/like/MovieRepositoryIntegrationTest.java @@ -0,0 +1,88 @@ +package com.baeldung.like; + +import static org.junit.Assert.assertEquals; +import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD; + +import java.util.List; + +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.jdbc.Sql; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.like.model.Movie; +import com.baeldung.like.repository.MovieRepository; + +@RunWith(SpringRunner.class) +@SpringBootTest +@Sql(scripts = { "/test-movie-data.sql" }) +@Sql(scripts = "/test-movie-cleanup.sql", executionPhase = AFTER_TEST_METHOD) +public class MovieRepositoryIntegrationTest { + @Autowired + private MovieRepository movieRepository; + + @Test + public void givenPartialTitle_WhenFindByTitleContaining_ThenMoviesShouldReturn() { + List results = movieRepository.findByTitleContaining("in"); + assertEquals(3, results.size()); + + results = movieRepository.findByTitleLike("%in%"); + assertEquals(3, results.size()); + + results = movieRepository.findByTitleIsContaining("in"); + assertEquals(3, results.size()); + + results = movieRepository.findByTitleContains("in"); + assertEquals(3, results.size()); + } + + @Test + public void givenStartOfRating_WhenFindByRatingStartsWith_ThenMoviesShouldReturn() { + List results = movieRepository.findByRatingStartsWith("PG"); + assertEquals(6, results.size()); + } + + @Test + public void givenLastName_WhenFindByDirectorEndsWith_ThenMoviesShouldReturn() { + List results = movieRepository.findByDirectorEndsWith("Burton"); + assertEquals(1, results.size()); + } + + @Test + public void givenPartialTitle_WhenFindByTitleContainingIgnoreCase_ThenMoviesShouldReturn() { + List results = movieRepository.findByTitleContainingIgnoreCase("the"); + assertEquals(2, results.size()); + } + + @Test + public void givenPartialTitle_WhenSearchByTitleLike_ThenMoviesShouldReturn() { + List results = movieRepository.searchByTitleLike("in"); + assertEquals(3, results.size()); + } + + @Test + public void givenStartOfRating_SearchFindByRatingStartsWith_ThenMoviesShouldReturn() { + List results = movieRepository.searchByRatingStartsWith("PG"); + assertEquals(6, results.size()); + } + + @Test + public void givenLastName_WhenSearchByDirectorEndsWith_ThenMoviesShouldReturn() { + List results = movieRepository.searchByDirectorEndsWith("Burton"); + assertEquals(1, results.size()); + } + + @Test + public void givenPartialRating_findByRatingNotContaining_ThenMoviesShouldReturn() { + List results = movieRepository.findByRatingNotContaining("PG"); + assertEquals(1, results.size()); + } + + @Test + public void givenPartialDirector_WhenFindByDirectorNotLike_ThenMoviesShouldReturn() { + List results = movieRepository.findByDirectorNotLike("An%"); + assertEquals(5, results.size()); + } +} diff --git a/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-cleanup.sql b/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-cleanup.sql new file mode 100644 index 0000000000..90aa15307c --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-cleanup.sql @@ -0,0 +1 @@ +DELETE FROM Movie; \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-data.sql b/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-data.sql new file mode 100644 index 0000000000..37f8e4fe64 --- /dev/null +++ b/persistence-modules/spring-data-jpa-2/src/test/resources/test-movie-data.sql @@ -0,0 +1,7 @@ +INSERT INTO movie(id, title, director, rating, duration) VALUES(1, 'Godzilla: King of the Monsters', ' Michael Dougherty', 'PG-13', 132); +INSERT INTO movie(id, title, director, rating, duration) VALUES(2, 'Avengers: Endgame', 'Anthony Russo', 'PG-13', 181); +INSERT INTO movie(id, title, director, rating, duration) VALUES(3, 'Captain Marvel', 'Anna Boden', 'PG-13', 123); +INSERT INTO movie(id, title, director, rating, duration) VALUES(4, 'Dumbo', 'Tim Burton', 'PG', 112); +INSERT INTO movie(id, title, director, rating, duration) VALUES(5, 'Booksmart', 'Olivia Wilde', 'R', 102); +INSERT INTO movie(id, title, director, rating, duration) VALUES(6, 'Aladdin', 'Guy Ritchie', 'PG', 128); +INSERT INTO movie(id, title, director, rating, duration) VALUES(7, 'The Sun Is Also a Star', 'Ry Russo-Young', 'PG-13', 100); From a4762fcc90ae5885c366c775675790e38846306a Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 16 May 2019 17:57:05 +0200 Subject: [PATCH 061/185] remove stop words from string --- java-strings-2/pom.xml | 55 - ...emovingStopwordsPerformanceComparison.java | 73 + .../src/main/resources/english_stopwords.txt | 127 + .../src/main/resources/shakespeare-hamlet.txt | 4922 +++++++++++++++++ .../string/RemoveStopwordsUnitTest.java | 60 + 5 files changed, 5182 insertions(+), 55 deletions(-) create mode 100644 java-strings-2/src/main/java/com/baeldung/string/performance/RemovingStopwordsPerformanceComparison.java create mode 100644 java-strings-2/src/main/resources/english_stopwords.txt create mode 100644 java-strings-2/src/main/resources/shakespeare-hamlet.txt create mode 100644 java-strings-2/src/test/java/com/baeldung/string/RemoveStopwordsUnitTest.java diff --git a/java-strings-2/pom.xml b/java-strings-2/pom.xml index 5279cf5777..9c27429139 100755 --- a/java-strings-2/pom.xml +++ b/java-strings-2/pom.xml @@ -15,28 +15,6 @@
- - commons-io - commons-io - ${commons-io.version} - - - log4j - log4j - ${log4j.version} - - - commons-codec - commons-codec - ${commons-codec.version} - - - - org.assertj - assertj-core - ${assertj.version} - test - org.openjdk.jmh jmh-core @@ -57,11 +35,6 @@ guava ${guava.version} - - com.vdurmont - emoji-java - ${emoji-java.version} - org.apache.commons commons-lang3 @@ -73,38 +46,18 @@ ${junit.version} test - - org.junit.jupiter - junit-jupiter-api - ${junit-jupiter-api.version} - test - - org.hamcrest hamcrest-library ${org.hamcrest.version} test - - - - org.passay - passay - ${passay.version} - org.apache.commons commons-text ${commons-text.version} - - org.ahocorasick - ahocorasick - ${ahocorasick.version} - - @@ -131,18 +84,10 @@ - 3.8.1 - 1.10 - - 3.6.1 61.1 27.0.1-jre - 4.0.0 - 5.3.1 - 1.3.1 1.4 - 0.4.0 \ No newline at end of file diff --git a/java-strings-2/src/main/java/com/baeldung/string/performance/RemovingStopwordsPerformanceComparison.java b/java-strings-2/src/main/java/com/baeldung/string/performance/RemovingStopwordsPerformanceComparison.java new file mode 100644 index 0000000000..5b455459cd --- /dev/null +++ b/java-strings-2/src/main/java/com/baeldung/string/performance/RemovingStopwordsPerformanceComparison.java @@ -0,0 +1,73 @@ +package com.baeldung.string.performance; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; + + +@Fork(value = 3, warmups = 1) +@State(Scope.Benchmark) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +public class RemovingStopwordsPerformanceComparison { + + private String data; + + private List stopwords; + + private String stopwordsRegex; + + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } + + @Setup + public void setup() throws IOException { + data = new String(Files.readAllBytes(Paths.get("src/main/resources/shakespeare-hamlet.txt"))); + data = data.toLowerCase(); + stopwords = Files.readAllLines(Paths.get("src/main/resources/english_stopwords.txt")); + stopwordsRegex = stopwords.stream().collect(Collectors.joining("|", "\\b(", ")\\b\\s?")); + } + + @Benchmark + public String removeManually() { + String[] allWords = data.split(" "); + StringBuilder builder = new StringBuilder(); + for(String word:allWords) { + if(! stopwords.contains(word)) { + builder.append(word); + builder.append(' '); + } + } + return builder.toString().trim(); + } + + @Benchmark + public String removeAll() { + ArrayList allWords = Stream.of(data.split(" ")) + .collect(Collectors.toCollection(ArrayList::new)); + allWords.removeAll(stopwords); + return allWords.stream().collect(Collectors.joining(" ")); + } + + @Benchmark + public String replaceRegex() { + return data.replaceAll(stopwordsRegex, ""); + } + +} \ No newline at end of file diff --git a/java-strings-2/src/main/resources/english_stopwords.txt b/java-strings-2/src/main/resources/english_stopwords.txt new file mode 100644 index 0000000000..5b16b504d6 --- /dev/null +++ b/java-strings-2/src/main/resources/english_stopwords.txt @@ -0,0 +1,127 @@ +i +me +my +myself +we +our +ours +ourselves +you +your +yours +yourself +yourselves +he +him +his +himself +she +her +hers +herself +it +its +itself +they +them +their +theirs +themselves +what +which +who +whom +this +that +these +those +am +is +are +was +were +be +been +being +have +has +had +having +do +does +did +doing +a +an +the +and +but +if +or +because +as +until +while +of +at +by +for +with +about +against +between +into +through +during +before +after +above +below +to +from +up +down +in +out +on +off +over +under +again +further +then +once +here +there +when +where +why +how +all +any +both +each +few +more +most +other +some +such +no +nor +not +only +own +same +so +than +too +very +s +t +can +will +just +don +should +now diff --git a/java-strings-2/src/main/resources/shakespeare-hamlet.txt b/java-strings-2/src/main/resources/shakespeare-hamlet.txt new file mode 100644 index 0000000000..0156555388 --- /dev/null +++ b/java-strings-2/src/main/resources/shakespeare-hamlet.txt @@ -0,0 +1,4922 @@ +[The Tragedie of Hamlet by William Shakespeare 1599] + + +Actus Primus. Scoena Prima. + +Enter Barnardo and Francisco two Centinels. + + Barnardo. Who's there? + Fran. Nay answer me: Stand & vnfold +your selfe + + Bar. Long liue the King + + Fran. Barnardo? + Bar. He + + Fran. You come most carefully vpon your houre + + Bar. 'Tis now strook twelue, get thee to bed Francisco + + Fran. For this releefe much thankes: 'Tis bitter cold, +And I am sicke at heart + + Barn. Haue you had quiet Guard? + Fran. Not a Mouse stirring + + Barn. Well, goodnight. If you do meet Horatio and +Marcellus, the Riuals of my Watch, bid them make hast. +Enter Horatio and Marcellus. + + Fran. I thinke I heare them. Stand: who's there? + Hor. Friends to this ground + + Mar. And Leige-men to the Dane + + Fran. Giue you good night + + Mar. O farwel honest Soldier, who hath relieu'd you? + Fra. Barnardo ha's my place: giue you goodnight. + +Exit Fran. + + Mar. Holla Barnardo + + Bar. Say, what is Horatio there? + Hor. A peece of him + + Bar. Welcome Horatio, welcome good Marcellus + + Mar. What, ha's this thing appear'd againe to night + + Bar. I haue seene nothing + + Mar. Horatio saies, 'tis but our Fantasie, +And will not let beleefe take hold of him +Touching this dreaded sight, twice seene of vs, +Therefore I haue intreated him along +With vs, to watch the minutes of this Night, +That if againe this Apparition come, +He may approue our eyes, and speake to it + + Hor. Tush, tush, 'twill not appeare + + Bar. Sit downe a-while, +And let vs once againe assaile your eares, +That are so fortified against our Story, +What we two Nights haue seene + + Hor. Well, sit we downe, +And let vs heare Barnardo speake of this + + Barn. Last night of all, +When yond same Starre that's Westward from the Pole +Had made his course t' illume that part of Heauen +Where now it burnes, Marcellus and my selfe, +The Bell then beating one + + Mar. Peace, breake thee of: +Enter the Ghost. + +Looke where it comes againe + + Barn. In the same figure, like the King that's dead + + Mar. Thou art a Scholler; speake to it Horatio + + Barn. Lookes it not like the King? Marke it Horatio + + Hora. Most like: It harrowes me with fear & wonder + Barn. It would be spoke too + + Mar. Question it Horatio + + Hor. What art thou that vsurp'st this time of night, +Together with that Faire and Warlike forme +In which the Maiesty of buried Denmarke +Did sometimes march: By Heauen I charge thee speake + + Mar. It is offended + + Barn. See, it stalkes away + + Hor. Stay: speake; speake: I Charge thee, speake. + +Exit the Ghost. + + Mar. 'Tis gone, and will not answer + + Barn. How now Horatio? You tremble & look pale: +Is not this something more then Fantasie? +What thinke you on't? + Hor. Before my God, I might not this beleeue +Without the sensible and true auouch +Of mine owne eyes + + Mar. Is it not like the King? + Hor. As thou art to thy selfe, +Such was the very Armour he had on, +When th' Ambitious Norwey combatted: +So frown'd he once, when in an angry parle +He smot the sledded Pollax on the Ice. +'Tis strange + + Mar. Thus twice before, and iust at this dead houre, +With Martiall stalke, hath he gone by our Watch + + Hor. In what particular thought to work, I know not: +But in the grosse and scope of my Opinion, +This boades some strange erruption to our State + + Mar. Good now sit downe, & tell me he that knowes +Why this same strict and most obseruant Watch, +So nightly toyles the subiect of the Land, +And why such dayly Cast of Brazon Cannon +And Forraigne Mart for Implements of warre: +Why such impresse of Ship-wrights, whose sore Taske +Do's not diuide the Sunday from the weeke, +What might be toward, that this sweaty hast +Doth make the Night ioynt-Labourer with the day: +Who is't that can informe me? + Hor. That can I, +At least the whisper goes so: Our last King, +Whose Image euen but now appear'd to vs, +Was (as you know) by Fortinbras of Norway, +(Thereto prick'd on by a most emulate Pride) +Dar'd to the Combate. In which, our Valiant Hamlet, +(For so this side of our knowne world esteem'd him) +Did slay this Fortinbras: who by a Seal'd Compact, +Well ratified by Law, and Heraldrie, +Did forfeite (with his life) all those his Lands +Which he stood seiz'd on, to the Conqueror: +Against the which, a Moity competent +Was gaged by our King: which had return'd +To the Inheritance of Fortinbras, +Had he bin Vanquisher, as by the same Cou'nant +And carriage of the Article designe, +His fell to Hamlet. Now sir, young Fortinbras, +Of vnimproued Mettle, hot and full, +Hath in the skirts of Norway, heere and there, +Shark'd vp a List of Landlesse Resolutes, +For Foode and Diet, to some Enterprize +That hath a stomacke in't: which is no other +(And it doth well appeare vnto our State) +But to recouer of vs by strong hand +And termes Compulsatiue, those foresaid Lands +So by his Father lost: and this (I take it) +Is the maine Motiue of our Preparations, +The Sourse of this our Watch, and the cheefe head +Of this post-hast, and Romage in the Land. +Enter Ghost againe. + +But soft, behold: Loe, where it comes againe: +Ile crosse it, though it blast me. Stay Illusion: +If thou hast any sound, or vse of Voyce, +Speake to me. If there be any good thing to be done, +That may to thee do ease, and grace to me; speak to me. +If thou art priuy to thy Countries Fate +(Which happily foreknowing may auoyd) Oh speake. +Or, if thou hast vp-hoorded in thy life +Extorted Treasure in the wombe of Earth, +(For which, they say, you Spirits oft walke in death) +Speake of it. Stay, and speake. Stop it Marcellus + + Mar. Shall I strike at it with my Partizan? + Hor. Do, if it will not stand + + Barn. 'Tis heere + + Hor. 'Tis heere + + Mar. 'Tis gone. + +Exit Ghost. + +We do it wrong, being so Maiesticall +To offer it the shew of Violence, +For it is as the Ayre, invulnerable, +And our vaine blowes, malicious Mockery + + Barn. It was about to speake, when the Cocke crew + + Hor. And then it started, like a guilty thing +Vpon a fearfull Summons. I haue heard, +The Cocke that is the Trumpet to the day, +Doth with his lofty and shrill-sounding Throate +Awake the God of Day: and at his warning, +Whether in Sea, or Fire, in Earth, or Ayre, +Th' extrauagant, and erring Spirit, hyes +To his Confine. And of the truth heerein, +This present Obiect made probation + + Mar. It faded on the crowing of the Cocke. +Some sayes, that euer 'gainst that Season comes +Wherein our Sauiours Birch is celebrated, +The Bird of Dawning singeth all night long: +And then (they say) no Spirit can walke abroad, +The nights are wholsome, then no Planets strike, +No Faiery talkes, nor Witch hath power to Charme: +So hallow'd, and so gracious is the time + + Hor. So haue I heard, and do in part beleeue it. +But looke, the Morne in Russet mantle clad, +Walkes o're the dew of yon high Easterne Hill, +Breake we our Watch vp, and by my aduice +Let vs impart what we haue seene to night +Vnto yong Hamlet. For vpon my life, +This Spirit dumbe to vs, will speake to him: +Do you consent we shall acquaint him with it, +As needfull in our Loues, fitting our Duty? + Mar. Let do't I pray, and I this morning know +Where we shall finde him most conueniently. + +Exeunt. + +Scena Secunda. + +Enter Claudius King of Denmarke, Gertrude the Queene, Hamlet, +Polonius, +Laertes, and his Sister Ophelia, Lords Attendant. + + King. Though yet of Hamlet our deere Brothers death +The memory be greene: and that it vs befitted +To beare our hearts in greefe, and our whole Kingdome +To be contracted in one brow of woe: +Yet so farre hath Discretion fought with Nature, +That we with wisest sorrow thinke on him, +Together with remembrance of our selues. +Therefore our sometimes Sister, now our Queene, +Th' imperiall Ioyntresse of this warlike State, +Haue we, as 'twere, with a defeated ioy, +With one Auspicious, and one Dropping eye, +With mirth in Funerall, and with Dirge in Marriage, +In equall Scale weighing Delight and Dole +Taken to Wife; nor haue we heerein barr'd +Your better Wisedomes, which haue freely gone +With this affaire along, for all our Thankes. +Now followes, that you know young Fortinbras, +Holding a weake supposall of our worth; +Or thinking by our late deere Brothers death, +Our State to be disioynt, and out of Frame, +Colleagued with the dreame of his Aduantage; +He hath not fayl'd to pester vs with Message, +Importing the surrender of those Lands +Lost by his Father: with all Bonds of Law +To our most valiant Brother. So much for him. +Enter Voltemand and Cornelius. + +Now for our selfe, and for this time of meeting +Thus much the businesse is. We haue heere writ +To Norway, Vncle of young Fortinbras, +Who Impotent and Bedrid, scarsely heares +Of this his Nephewes purpose, to suppresse +His further gate heerein. In that the Leuies, +The Lists, and full proportions are all made +Out of his subiect: and we heere dispatch +You good Cornelius, and you Voltemand, +For bearing of this greeting to old Norway, +Giuing to you no further personall power +To businesse with the King, more then the scope +Of these dilated Articles allow: +Farewell, and let your hast commend your duty + + Volt. In that, and all things, will we shew our duty + + King. We doubt it nothing, heartily farewell. + +Exit Voltemand and Cornelius. + +And now Laertes, what's the newes with you? +You told vs of some suite. What is't Laertes? +You cannot speake of Reason to the Dane, +And loose your voyce. What would'st thou beg Laertes, +That shall not be my Offer, not thy Asking? +The Head is not more Natiue to the Heart, +The Hand more instrumentall to the Mouth, +Then is the Throne of Denmarke to thy Father. +What would'st thou haue Laertes? + Laer. Dread my Lord, +Your leaue and fauour to returne to France, +From whence, though willingly I came to Denmarke +To shew my duty in your Coronation, +Yet now I must confesse, that duty done, +My thoughts and wishes bend againe towards France, +And bow them to your gracious leaue and pardon + + King. Haue you your Fathers leaue? +What sayes Pollonius? + Pol. He hath my Lord: +I do beseech you giue him leaue to go + + King. Take thy faire houre Laertes, time be thine, +And thy best graces spend it at thy will: +But now my Cosin Hamlet, and my Sonne? + Ham. A little more then kin, and lesse then kinde + + King. How is it that the Clouds still hang on you? + Ham. Not so my Lord, I am too much i'th' Sun + + Queen. Good Hamlet cast thy nightly colour off, +And let thine eye looke like a Friend on Denmarke. +Do not for euer with thy veyled lids +Seeke for thy Noble Father in the dust; +Thou know'st 'tis common, all that liues must dye, +Passing through Nature, to Eternity + + Ham. I Madam, it is common + + Queen. If it be; +Why seemes it so particular with thee + + Ham. Seemes Madam? Nay, it is: I know not Seemes: +'Tis not alone my Inky Cloake (good Mother) +Nor Customary suites of solemne Blacke, +Nor windy suspiration of forc'd breath, +No, nor the fruitfull Riuer in the Eye, +Nor the deiected hauiour of the Visage, +Together with all Formes, Moods, shewes of Griefe, +That can denote me truly. These indeed Seeme, +For they are actions that a man might play: +But I haue that Within, which passeth show; +These, but the Trappings, and the Suites of woe + + King. 'Tis sweet and commendable +In your Nature Hamlet, +To giue these mourning duties to your Father: +But you must know, your Father lost a Father, +That Father lost, lost his, and the Suruiuer bound +In filiall Obligation, for some terme +To do obsequious Sorrow. But to perseuer +In obstinate Condolement, is a course +Of impious stubbornnesse. 'Tis vnmanly greefe, +It shewes a will most incorrect to Heauen, +A Heart vnfortified, a Minde impatient, +An Vnderstanding simple, and vnschool'd: +For, what we know must be, and is as common +As any the most vulgar thing to sence, +Why should we in our peeuish Opposition +Take it to heart? Fye, 'tis a fault to Heauen, +A fault against the Dead, a fault to Nature, +To Reason most absurd, whose common Theame +Is death of Fathers, and who still hath cried, +From the first Coarse, till he that dyed to day, +This must be so. We pray you throw to earth +This vnpreuayling woe, and thinke of vs +As of a Father; For let the world take note, +You are the most immediate to our Throne, +And with no lesse Nobility of Loue, +Then that which deerest Father beares his Sonne, +Do I impart towards you. For your intent +In going backe to Schoole in Wittenberg, +It is most retrograde to our desire: +And we beseech you, bend you to remaine +Heere in the cheere and comfort of our eye, +Our cheefest Courtier Cosin, and our Sonne + + Qu. Let not thy Mother lose her Prayers Hamlet: +I prythee stay with vs, go not to Wittenberg + + Ham. I shall in all my best +Obey you Madam + + King. Why 'tis a louing, and a faire Reply, +Be as our selfe in Denmarke. Madam come, +This gentle and vnforc'd accord of Hamlet +Sits smiling to my heart; in grace whereof, +No iocond health that Denmarke drinkes to day, +But the great Cannon to the Clowds shall tell, +And the Kings Rouce, the Heauens shall bruite againe, +Respeaking earthly Thunder. Come away. + +Exeunt. + +Manet Hamlet. + + Ham. Oh that this too too solid Flesh, would melt, +Thaw, and resolue it selfe into a Dew: +Or that the Euerlasting had not fixt +His Cannon 'gainst Selfe-slaughter. O God, O God! +How weary, stale, flat, and vnprofitable +Seemes to me all the vses of this world? +Fie on't? Oh fie, fie, 'tis an vnweeded Garden +That growes to Seed: Things rank, and grosse in Nature +Possesse it meerely. That it should come to this: +But two months dead: Nay, not so much; not two, +So excellent a King, that was to this +Hiperion to a Satyre: so louing to my Mother, +That he might not beteene the windes of heauen +Visit her face too roughly. Heauen and Earth +Must I remember: why she would hang on him, +As if encrease of Appetite had growne +By what is fed on; and yet within a month? +Let me not thinke on't: Frailty, thy name is woman. +A little Month, or ere those shooes were old, +With which she followed my poore Fathers body +Like Niobe, all teares. Why she, euen she. +(O Heauen! A beast that wants discourse of Reason +Would haue mourn'd longer) married with mine Vnkle, +My Fathers Brother: but no more like my Father, +Then I to Hercules. Within a Moneth? +Ere yet the salt of most vnrighteous Teares +Had left the flushing of her gauled eyes, +She married. O most wicked speed, to post +With such dexterity to Incestuous sheets: +It is not, nor it cannot come to good. +But breake my heart, for I must hold my tongue. +Enter Horatio, Barnardo, and Marcellus. + + Hor. Haile to your Lordship + + Ham. I am glad to see you well: +Horatio, or I do forget my selfe + + Hor. The same my Lord, +And your poore Seruant euer + + Ham. Sir my good friend, +Ile change that name with you: +And what make you from Wittenberg Horatio? +Marcellus + + Mar. My good Lord + + Ham. I am very glad to see you: good euen Sir. +But what in faith make you from Wittemberge? + Hor. A truant disposition, good my Lord + + Ham. I would not haue your Enemy say so; +Nor shall you doe mine eare that violence, +To make it truster of your owne report +Against your selfe. I know you are no Truant: +But what is your affaire in Elsenour? +Wee'l teach you to drinke deepe, ere you depart + + Hor. My Lord, I came to see your Fathers Funerall + + Ham. I pray thee doe not mock me (fellow Student) +I thinke it was to see my Mothers Wedding + + Hor. Indeed my Lord, it followed hard vpon + + Ham. Thrift thrift Horatio: the Funerall Bakt-meats +Did coldly furnish forth the Marriage Tables; +Would I had met my dearest foe in heauen, +Ere I had euer seene that day Horatio. +My father, me thinkes I see my father + + Hor. Oh where my Lord? + Ham. In my minds eye (Horatio) + Hor. I saw him once; he was a goodly King + + Ham. He was a man, take him for all in all: +I shall not look vpon his like againe + + Hor. My Lord, I thinke I saw him yesternight + + Ham. Saw? Who? + Hor. My Lord, the King your Father + + Ham. The King my Father? + Hor. Season your admiration for a while +With an attent eare; till I may deliuer +Vpon the witnesse of these Gentlemen, +This maruell to you + + Ham. For Heauens loue let me heare + + Hor. Two nights together, had these Gentlemen +(Marcellus and Barnardo) on their Watch +In the dead wast and middle of the night +Beene thus encountred. A figure like your Father, +Arm'd at all points exactly, Cap a Pe, +Appeares before them, and with sollemne march +Goes slow and stately: By them thrice he walkt, +By their opprest and feare-surprized eyes, +Within his Truncheons length; whilst they bestil'd +Almost to Ielly with the Act of feare, +Stand dumbe and speake not to him. This to me +In dreadfull secrecie impart they did, +And I with them the third Night kept the Watch, +Whereas they had deliuer'd both in time, +Forme of the thing; each word made true and good, +The Apparition comes. I knew your Father: +These hands are not more like + + Ham. But where was this? + Mar. My Lord vpon the platforme where we watcht + + Ham. Did you not speake to it? + Hor. My Lord, I did; +But answere made it none: yet once me thought +It lifted vp it head, and did addresse +It selfe to motion, like as it would speake: +But euen then, the Morning Cocke crew lowd; +And at the sound it shrunke in hast away, +And vanisht from our sight + + Ham. Tis very strange + + Hor. As I doe liue my honourd Lord 'tis true; +And we did thinke it writ downe in our duty +To let you know of it + + Ham. Indeed, indeed Sirs; but this troubles me. +Hold you the watch to Night? + Both. We doe my Lord + + Ham. Arm'd, say you? + Both. Arm'd, my Lord + + Ham. From top to toe? + Both. My Lord, from head to foote + + Ham. Then saw you not his face? + Hor. O yes, my Lord, he wore his Beauer vp + + Ham. What, lookt he frowningly? + Hor. A countenance more in sorrow then in anger + + Ham. Pale, or red? + Hor. Nay very pale + + Ham. And fixt his eyes vpon you? + Hor. Most constantly + + Ham. I would I had beene there + + Hor. It would haue much amaz'd you + + Ham. Very like, very like: staid it long? + Hor. While one with moderate hast might tell a hundred + + All. Longer, longer + + Hor. Not when I saw't + + Ham. His Beard was grisly? no + + Hor. It was, as I haue seene it in his life, +A Sable Siluer'd + + Ham. Ile watch to Night; perchance 'twill wake againe + + Hor. I warrant you it will + + Ham. If it assume my noble Fathers person, +Ile speake to it, though Hell it selfe should gape +And bid me hold my peace. I pray you all, +If you haue hitherto conceald this sight; +Let it bee treble in your silence still: +And whatsoeuer els shall hap to night, +Giue it an vnderstanding but no tongue; +I will requite your loues; so fare ye well: +Vpon the Platforme twixt eleuen and twelue, +Ile visit you + + All. Our duty to your Honour. + +Exeunt + + Ham. Your loue, as mine to you: farewell. +My Fathers Spirit in Armes? All is not well: +I doubt some foule play: would the Night were come; +Till then sit still my soule; foule deeds will rise, +Though all the earth orewhelm them to mens eies. +Enter. + + +Scena Tertia + + +Enter Laertes and Ophelia. + + Laer. My necessaries are imbark't; Farewell: +And Sister, as the Winds giue Benefit, +And Conuoy is assistant; doe not sleepe, +But let me heare from you + + Ophel. Doe you doubt that? + Laer. For Hamlet, and the trifling of his fauours, +Hold it a fashion and a toy in Bloude; +A Violet in the youth of Primy Nature; +Froward, not permanent; sweet not lasting +The suppliance of a minute? No more + + Ophel. No more but so + + Laer. Thinke it no more: +For nature cressant does not grow alone, +In thewes and Bulke: but as his Temple waxes, +The inward seruice of the Minde and Soule +Growes wide withall. Perhaps he loues you now, +And now no soyle nor cautell doth besmerch +The vertue of his feare: but you must feare +His greatnesse weigh'd, his will is not his owne; +For hee himselfe is subiect to his Birth: +Hee may not, as vnuallued persons doe, +Carue for himselfe; for, on his choyce depends +The sanctity and health of the whole State. +And therefore must his choyce be circumscrib'd +Vnto the voyce and yeelding of that Body, +Whereof he is the Head. Then if he sayes he loues you, +It fits your wisedome so farre to beleeue it; +As he in his peculiar Sect and force +May giue his saying deed: which is no further, +Then the maine voyce of Denmarke goes withall. +Then weight what losse your Honour may sustaine, +If with too credent eare you list his Songs; +Or lose your Heart; or your chast Treasure open +To his vnmastred importunity. +Feare it Ophelia, feare it my deare Sister, +And keepe within the reare of your Affection; +Out of the shot and danger of Desire. +The chariest Maid is Prodigall enough, +If she vnmaske her beauty to the Moone: +Vertue it selfe scapes not calumnious stroakes, +The Canker Galls, the Infants of the Spring +Too oft before the buttons be disclos'd, +And in the Morne and liquid dew of Youth, +Contagious blastments are most imminent. +Be wary then, best safety lies in feare; +Youth to it selfe rebels, though none else neere + + Ophe. I shall th' effect of this good Lesson keepe, +As watchmen to my heart: but good my Brother +Doe not as some vngracious Pastors doe, +Shew me the steepe and thorny way to Heauen; +Whilst like a puft and recklesse Libertine +Himselfe, the Primrose path of dalliance treads, +And reaks not his owne reade + + Laer. Oh, feare me not. +Enter Polonius. + +I stay too long; but here my Father comes: +A double blessing is a double grace; +Occasion smiles vpon a second leaue + + Polon. Yet heere Laertes? Aboord, aboord for shame, +The winde sits in the shoulder of your saile, +And you are staid for there: my blessing with you; +And these few Precepts in thy memory, +See thou Character. Giue thy thoughts no tongue, +Nor any vnproportion'd thoughts his Act: +Be thou familiar; but by no meanes vulgar: +The friends thou hast, and their adoption tride, +Grapple them to thy Soule, with hoopes of Steele: +But doe not dull thy palme, with entertainment +Of each vnhatch't, vnfledg'd Comrade. Beware +Of entrance to a quarrell: but being in +Bear't that th' opposed may beware of thee. +Giue euery man thine eare; but few thy voyce: +Take each mans censure; but reserue thy iudgement: +Costly thy habit as thy purse can buy; +But not exprest in fancie; rich, not gawdie: +For the Apparell oft proclaimes the man. +And they in France of the best ranck and station, +Are of a most select and generous cheff in that. +Neither a borrower, nor a lender be; +For lone oft loses both it selfe and friend: +And borrowing duls the edge of Husbandry. +This aboue all; to thine owne selfe be true: +And it must follow, as the Night the Day, +Thou canst not then be false to any man. +Farewell: my Blessing season this in thee + + Laer. Most humbly doe I take my leaue, my Lord + + Polon. The time inuites you, goe, your seruants tend + + Laer. Farewell Ophelia, and remember well +What I haue said to you + + Ophe. Tis in my memory lockt, +And you your selfe shall keepe the key of it + + Laer. Farewell. + +Exit Laer. + + Polon. What ist Ophelia he hath said to you? + Ophe. So please you, somthing touching the L[ord]. Hamlet + + Polon. Marry, well bethought: +Tis told me he hath very oft of late +Giuen priuate time to you; and you your selfe +Haue of your audience beene most free and bounteous. +If it be so, as so tis put on me; +And that in way of caution: I must tell you, +You doe not vnderstand your selfe so cleerely, +As it behoues my Daughter, and your Honour. +What is betweene you, giue me vp the truth? + Ophe. He hath my Lord of late, made many tenders +Of his affection to me + + Polon. Affection, puh. You speake like a greene Girle, +Vnsifted in such perillous Circumstance. +Doe you beleeue his tenders, as you call them? + Ophe. I do not know, my Lord, what I should thinke + + Polon. Marry Ile teach you; thinke your selfe a Baby, +That you haue tane his tenders for true pay, +Which are not starling. Tender your selfe more dearly; +Or not to crack the winde of the poore Phrase, +Roaming it thus, you'l tender me a foole + + Ophe. My Lord, he hath importun'd me with loue, +In honourable fashion + + Polon. I, fashion you may call it, go too, go too + + Ophe. And hath giuen countenance to his speech, +My Lord, with all the vowes of Heauen + + Polon. I, Springes to catch Woodcocks. I doe know +When the Bloud burnes, how Prodigall the Soule +Giues the tongue vowes: these blazes, Daughter, +Giuing more light then heate; extinct in both, +Euen in their promise, as it is a making; +You must not take for fire. For this time Daughter, +Be somewhat scanter of your Maiden presence; +Set your entreatments at a higher rate, +Then a command to parley. For Lord Hamlet, +Beleeue so much in him, that he is young, +And with a larger tether may he walke, +Then may be giuen you. In few, Ophelia, +Doe not beleeue his vowes; for they are Broakers, +Not of the eye, which their Inuestments show: +But meere implorators of vnholy Sutes, +Breathing like sanctified and pious bonds, +The better to beguile. This is for all: +I would not, in plaine tearmes, from this time forth, +Haue you so slander any moment leisure, +As to giue words or talke with the Lord Hamlet: +Looke too't, I charge you; come your wayes + + Ophe. I shall obey my Lord. + +Exeunt. + +Enter Hamlet, Horatio, Marcellus. + + Ham. The Ayre bites shrewdly: is it very cold? + Hor. It is a nipping and an eager ayre + + Ham. What hower now? + Hor. I thinke it lacks of twelue + + Mar. No, it is strooke + + Hor. Indeed I heard it not: then it drawes neere the season, +Wherein the Spirit held his wont to walke. +What does this meane my Lord? + Ham. The King doth wake to night, and takes his rouse, +Keepes wassels and the swaggering vpspring reeles, +And as he dreines his draughts of Renish downe, +The kettle Drum and Trumpet thus bray out +The triumph of his Pledge + + Horat. Is it a custome? + Ham. I marry ist; +And to my mind, though I am natiue heere, +And to the manner borne: It is a Custome +More honour'd in the breach, then the obseruance. +Enter Ghost. + + Hor. Looke my Lord, it comes + + Ham. Angels and Ministers of Grace defend vs: +Be thou a Spirit of health, or Goblin damn'd, +Bring with thee ayres from Heauen, or blasts from Hell, +Be thy euents wicked or charitable, +Thou com'st in such a questionable shape +That I will speake to thee. Ile call thee Hamlet, +King, Father, Royall Dane: Oh, oh, answer me, +Let me not burst in Ignorance; but tell +Why thy Canoniz'd bones Hearsed in death, +Haue burst their cerments, why the Sepulcher +Wherein we saw thee quietly enurn'd, +Hath op'd his ponderous and Marble iawes, +To cast thee vp againe? What may this meane? +That thou dead Coarse againe in compleat steele, +Reuisits thus the glimpses of the Moone, +Making Night hidious? And we fooles of Nature, +So horridly to shake our disposition, +With thoughts beyond thee; reaches of our Soules, +Say, why is this? wherefore? what should we doe? + +Ghost beckens Hamlet. + + Hor. It beckons you to goe away with it, +As if it some impartment did desire +To you alone + + Mar. Looke with what courteous action +It wafts you to a more remoued ground: +But doe not goe with it + + Hor. No, by no meanes + + Ham. It will not speake: then will I follow it + + Hor. Doe not my Lord + + Ham. Why, what should be the feare? +I doe not set my life at a pins fee; +And for my Soule, what can it doe to that? +Being a thing immortall as it selfe: +It waues me forth againe; Ile follow it + + Hor. What if it tempt you toward the Floud my Lord? +Or to the dreadfull Sonnet of the Cliffe, +That beetles o're his base into the Sea, +And there assumes some other horrible forme, +Which might depriue your Soueraignty of Reason, +And draw you into madnesse thinke of it? + Ham. It wafts me still: goe on, Ile follow thee + + Mar. You shall not goe my Lord + + Ham. Hold off your hand + + Hor. Be rul'd, you shall not goe + + Ham. My fate cries out, +And makes each petty Artire in this body, +As hardy as the Nemian Lions nerue: +Still am I cal'd? Vnhand me Gentlemen: +By Heau'n, Ile make a Ghost of him that lets me: +I say away, goe on, Ile follow thee. + +Exeunt. Ghost & Hamlet. + + Hor. He waxes desperate with imagination + + Mar. Let's follow; 'tis not fit thus to obey him + + Hor. Haue after, to what issue will this come? + Mar. Something is rotten in the State of Denmarke + + Hor. Heauen will direct it + + Mar. Nay, let's follow him. + +Exeunt. + +Enter Ghost and Hamlet. + + Ham. Where wilt thou lead me? speak; Ile go no further + + Gho. Marke me + + Ham. I will + + Gho. My hower is almost come, +When I to sulphurous and tormenting Flames +Must render vp my selfe + + Ham. Alas poore Ghost + + Gho. Pitty me not, but lend thy serious hearing +To what I shall vnfold + + Ham. Speake, I am bound to heare + + Gho. So art thou to reuenge, when thou shalt heare + + Ham. What? + Gho. I am thy Fathers Spirit, +Doom'd for a certaine terme to walke the night; +And for the day confin'd to fast in Fiers, +Till the foule crimes done in my dayes of Nature +Are burnt and purg'd away? But that I am forbid +To tell the secrets of my Prison-House; +I could a Tale vnfold, whose lightest word +Would harrow vp thy soule, freeze thy young blood, +Make thy two eyes like Starres, start from their Spheres, +Thy knotty and combined lockes to part, +And each particular haire to stand an end, +Like Quilles vpon the fretfull Porpentine: +But this eternall blason must not be +To eares of flesh and bloud; list Hamlet, oh list, +If thou didst euer thy deare Father loue + + Ham. Oh Heauen! + Gho. Reuenge his foule and most vnnaturall Murther + + Ham. Murther? + Ghost. Murther most foule, as in the best it is; +But this most foule, strange, and vnnaturall + + Ham. Hast, hast me to know it, +That with wings as swift +As meditation, or the thoughts of Loue, +May sweepe to my Reuenge + + Ghost. I finde thee apt, +And duller should'st thou be then the fat weede +That rots it selfe in ease, on Lethe Wharfe, +Would'st thou not stirre in this. Now Hamlet heare: +It's giuen out, that sleeping in mine Orchard, +A Serpent stung me: so the whole eare of Denmarke, +Is by a forged processe of my death +Rankly abus'd: But know thou Noble youth, +The Serpent that did sting thy Fathers life, +Now weares his Crowne + + Ham. O my Propheticke soule: mine Vncle? + Ghost. I that incestuous, that adulterate Beast +With witchcraft of his wits, hath Traitorous guifts. +Oh wicked Wit, and Gifts, that haue the power +So to seduce? Won to this shamefull Lust +The will of my most seeming vertuous Queene: +Oh Hamlet, what a falling off was there, +From me, whose loue was of that dignity, +That it went hand in hand, euen with the Vow +I made to her in Marriage; and to decline +Vpon a wretch, whose Naturall gifts were poore +To those of mine. But Vertue, as it neuer wil be moued, +Though Lewdnesse court it in a shape of Heauen: +So Lust, though to a radiant Angell link'd, +Will sate it selfe in a Celestiall bed, & prey on Garbage. +But soft, me thinkes I sent the Mornings Ayre; +Briefe let me be: Sleeping within mine Orchard, +My custome alwayes in the afternoone; +Vpon my secure hower thy Vncle stole +With iuyce of cursed Hebenon in a Violl, +And in the Porches of mine eares did poure +The leaperous Distilment; whose effect +Holds such an enmity with bloud of Man, +That swift as Quick-siluer, it courses through +The naturall Gates and Allies of the body; +And with a sodaine vigour it doth posset +And curd, like Aygre droppings into Milke, +The thin and wholsome blood: so did it mine; +And a most instant Tetter bak'd about, +Most Lazar-like, with vile and loathsome crust, +All my smooth Body. +Thus was I, sleeping, by a Brothers hand, +Of Life, of Crowne, and Queene at once dispatcht; +Cut off euen in the Blossomes of my Sinne, +Vnhouzzled, disappointed, vnnaneld, +No reckoning made, but sent to my account +With all my imperfections on my head; +Oh horrible Oh horrible, most horrible: +If thou hast nature in thee beare it not; +Let not the Royall Bed of Denmarke be +A Couch for Luxury and damned Incest. +But howsoeuer thou pursuest this Act, +Taint not thy mind; nor let thy Soule contriue +Against thy Mother ought; leaue her to heauen, +And to those Thornes that in her bosome lodge, +To pricke and sting her. Fare thee well at once; +The Glow-worme showes the Matine to be neere, +And gins to pale his vneffectuall Fire: +Adue, adue, Hamlet: remember me. +Enter. + + Ham. Oh all you host of Heauen! Oh Earth; what els? +And shall I couple Hell? Oh fie: hold my heart; +And you my sinnewes, grow not instant Old; +But beare me stiffely vp: Remember thee? +I, thou poore Ghost, while memory holds a seate +In this distracted Globe: Remember thee? +Yea, from the Table of my Memory, +Ile wipe away all triuiall fond Records, +All sawes of Bookes, all formes, all presures past, +That youth and obseruation coppied there; +And thy Commandment all alone shall liue +Within the Booke and Volume of my Braine, +Vnmixt with baser matter; yes yes, by Heauen: +Oh most pernicious woman! +Oh Villaine, Villaine, smiling damned Villaine! +My Tables, my Tables; meet it is I set it downe, +That one may smile, and smile and be a Villaine; +At least I'm sure it may be so in Denmarke; +So Vnckle there you are: now to my word; +It is; Adue, Adue, Remember me: I haue sworn't + + Hor. & Mar. within. My Lord, my Lord. +Enter Horatio and Marcellus. + + Mar. Lord Hamlet + + Hor. Heauen secure him + + Mar. So be it + + Hor. Illo, ho, ho, my Lord + + Ham. Hillo, ho, ho, boy; come bird, come + + Mar. How ist my Noble Lord? + Hor. What newes, my Lord? + Ham. Oh wonderfull! + Hor. Good my Lord tell it + + Ham. No you'l reueale it + + Hor. Not I, my Lord, by Heauen + + Mar. Nor I, my Lord + + Ham. How say you then, would heart of man once think it? +But you'l be secret? + Both. I, by Heau'n, my Lord + + Ham. There's nere a villaine dwelling in all Denmarke +But hee's an arrant knaue + + Hor. There needs no Ghost my Lord, come from the +Graue, to tell vs this + + Ham. Why right, you are i'th' right; +And so, without more circumstance at all, +I hold it fit that we shake hands, and part: +You, as your busines and desires shall point you: +For euery man ha's businesse and desire, +Such as it is: and for mine owne poore part, +Looke you, Ile goe pray + + Hor. These are but wild and hurling words, my Lord + + Ham. I'm sorry they offend you heartily: +Yes faith, heartily + + Hor. There's no offence my Lord + + Ham. Yes, by Saint Patricke, but there is my Lord, +And much offence too, touching this Vision heere: +It is an honest Ghost, that let me tell you: +For your desire to know what is betweene vs, +O'remaster't as you may. And now good friends, +As you are Friends, Schollers and Soldiers, +Giue me one poore request + + Hor. What is't my Lord? we will + + Ham. Neuer make known what you haue seen to night + + Both. My Lord, we will not + + Ham. Nay, but swear't + + Hor. Infaith my Lord, not I + + Mar. Nor I my Lord: in faith + + Ham. Vpon my sword + + Marcell. We haue sworne my Lord already + + Ham. Indeed, vpon my sword, Indeed + + Gho. Sweare. + +Ghost cries vnder the Stage. + + Ham. Ah ha boy, sayest thou so. Art thou there truepenny? +Come one you here this fellow in the selleredge +Consent to sweare + + Hor. Propose the Oath my Lord + + Ham. Neuer to speake of this that you haue seene. +Sweare by my sword + + Gho. Sweare + + Ham. Hic & vbique? Then wee'l shift for grownd, +Come hither Gentlemen, +And lay your hands againe vpon my sword, +Neuer to speake of this that you haue heard: +Sweare by my Sword + + Gho. Sweare + + Ham. Well said old Mole, can'st worke i'th' ground so fast? +A worthy Pioner, once more remoue good friends + + Hor. Oh day and night: but this is wondrous strange + + Ham. And therefore as a stranger giue it welcome. +There are more things in Heauen and Earth, Horatio, +Then are dream't of in our Philosophy. But come, +Here as before, neuer so helpe you mercy, +How strange or odde so ere I beare my selfe; +(As I perchance heereafter shall thinke meet +To put an Anticke disposition on:) +That you at such time seeing me, neuer shall +With Armes encombred thus, or thus, head shake; +Or by pronouncing of some doubtfull Phrase; +As well, we know, or we could and if we would, +Or if we list to speake; or there be and if there might, +Or such ambiguous giuing out to note, +That you know ought of me; this not to doe: +So grace and mercy at your most neede helpe you: +Sweare + + Ghost. Sweare + + Ham. Rest, rest perturbed Spirit: so Gentlemen, +With all my loue I doe commend me to you; +And what so poore a man as Hamlet is, +May doe t' expresse his loue and friending to you, +God willing shall not lacke: let vs goe in together, +And still your fingers on your lippes I pray, +The time is out of ioynt: Oh cursed spight, +That euer I was borne to set it right. +Nay, come let's goe together. + +Exeunt. + + +Actus Secundus. + +Enter Polonius, and Reynoldo. + + Polon. Giue him his money, and these notes Reynoldo + + Reynol. I will my Lord + + Polon. You shall doe maruels wisely: good Reynoldo, +Before you visite him you make inquiry +Of his behauiour + + Reynol. My Lord, I did intend it + + Polon. Marry, well said; +Very well said. Looke you Sir, +Enquire me first what Danskers are in Paris; +And how, and who; what meanes; and where they keepe: +What company, at what expence: and finding +By this encompassement and drift of question, +That they doe know my sonne: Come you more neerer +Then your particular demands will touch it, +Take you as 'twere some distant knowledge of him, +And thus I know his father and his friends, +And in part him. Doe you marke this Reynoldo? + Reynol. I, very well my Lord + + Polon. And in part him, but you may say not well; +But if't be hee I meane, hees very wilde; +Addicted so and so; and there put on him +What forgeries you please; marry, none so ranke, +As may dishonour him; take heed of that: +But Sir, such wanton, wild, and vsuall slips, +As are Companions noted and most knowne +To youth and liberty + + Reynol. As gaming my Lord + + Polon. I, or drinking, fencing, swearing, +Quarelling, drabbing. You may goe so farre + + Reynol. My Lord that would dishonour him + + Polon. Faith no, as you may season it in the charge; +You must not put another scandall on him, +That hee is open to Incontinencie; +That's not my meaning: but breath his faults so quaintly, +That they may seeme the taints of liberty; +The flash and out-breake of a fiery minde, +A sauagenes in vnreclaim'd bloud of generall assault + + Reynol. But my good Lord + + Polon. Wherefore should you doe this? + Reynol. I my Lord, I would know that + + Polon. Marry Sir, heere's my drift, +And I belieue it is a fetch of warrant: +You laying these slight sulleyes on my Sonne, +As 'twere a thing a little soil'd i'th' working: +Marke you your party in conuerse; him you would sound, +Hauing euer seene. In the prenominate crimes, +The youth you breath of guilty, be assur'd +He closes with you in this consequence: +Good sir, or so, or friend, or Gentleman. +According to the Phrase and the Addition, +Of man and Country + + Reynol. Very good my Lord + + Polon. And then Sir does he this? +He does: what was I about to say? +I was about say somthing: where did I leaue? + Reynol. At closes in the consequence: +At friend, or so, and Gentleman + + Polon. At closes in the consequence, I marry, +He closes with you thus. I know the Gentleman, +I saw him yesterday, or tother day; +Or then or then, with such and such; and as you say, +There was he gaming, there o'retooke in's Rouse, +There falling out at Tennis; or perchance, +I saw him enter such a house of saile; +Videlicet, a Brothell, or so forth. See you now; +Your bait of falshood, takes this Cape of truth; +And thus doe we of wisedome and of reach +With windlesses, and with assaies of Bias, +By indirections finde directions out: +So by my former Lecture and aduice +Shall you my Sonne; you haue me, haue you not? + Reynol. My Lord I haue + + Polon. God buy you; fare you well + + Reynol. Good my Lord + + Polon. Obserue his inclination in your selfe + + Reynol. I shall my Lord + + Polon. And let him plye his Musicke + + Reynol. Well, my Lord. +Enter. + +Enter Ophelia. + + Polon. Farewell: +How now Ophelia, what's the matter? + Ophe. Alas my Lord, I haue beene so affrighted + + Polon. With what, in the name of Heauen? + Ophe. My Lord, as I was sowing in my Chamber, +Lord Hamlet with his doublet all vnbrac'd, +No hat vpon his head, his stockings foul'd, +Vngartred, and downe giued to his Anckle, +Pale as his shirt, his knees knocking each other, +And with a looke so pitious in purport, +As if he had been loosed out of hell, +To speake of horrors: he comes before me + + Polon. Mad for thy Loue? + Ophe. My Lord, I doe not know: but truly I do feare it + + Polon. What said he? + Ophe. He tooke me by the wrist, and held me hard; +Then goes he to the length of all his arme; +And with his other hand thus o're his brow, +He fals to such perusall of my face, +As he would draw it. Long staid he so, +At last, a little shaking of mine Arme: +And thrice his head thus wauing vp and downe; +He rais'd a sigh, so pittious and profound, +That it did seeme to shatter all his bulke, +And end his being. That done, he lets me goe, +And with his head ouer his shoulders turn'd, +He seem'd to finde his way without his eyes, +For out adores he went without their helpe; +And to the last, bended their light on me + + Polon. Goe with me, I will goe seeke the King, +This is the very extasie of Loue, +Whose violent property foredoes it selfe, +And leads the will to desperate Vndertakings, +As oft as any passion vnder Heauen, +That does afflict our Natures. I am sorrie, +What haue you giuen him any hard words of late? + Ophe. No my good Lord: but as you did command, +I did repell his Letters, and deny'de +His accesse to me + + Pol. That hath made him mad. +I am sorrie that with better speed and iudgement +I had not quoted him. I feare he did but trifle, +And meant to wracke thee: but beshrew my iealousie: +It seemes it is as proper to our Age, +To cast beyond our selues in our Opinions, +As it is common for the yonger sort +To lacke discretion. Come, go we to the King, +This must be knowne, being kept close might moue +More greefe to hide, then hate to vtter loue. + +Exeunt. + + +Scena Secunda. + +Enter King, Queene, Rosincrane, and Guildensterne Cum alijs. + + King. Welcome deere Rosincrance and Guildensterne. +Moreouer, that we much did long to see you, +The neede we haue to vse you, did prouoke +Our hastie sending. Something haue you heard +Of Hamlets transformation: so I call it, +Since not th' exterior, nor the inward man +Resembles that it was. What it should bee +More then his Fathers death, that thus hath put him +So much from th' vnderstanding of himselfe, +I cannot deeme of. I intreat you both, +That being of so young dayes brought vp with him: +And since so Neighbour'd to his youth, and humour, +That you vouchsafe your rest heere in our Court +Some little time: so by your Companies +To draw him on to pleasures, and to gather +So much as from Occasions you may gleane, +That open'd lies within our remedie + + Qu. Good Gentlemen, he hath much talk'd of you, +And sure I am, two men there are not liuing, +To whom he more adheres. If it will please you +To shew vs so much Gentrie, and good will, +As to expend your time with vs a-while, +For the supply and profit of our Hope, +Your Visitation shall receiue such thankes +As fits a Kings remembrance + + Rosin. Both your Maiesties +Might by the Soueraigne power you haue of vs, +Put your dread pleasures, more into Command +Then to Entreatie + + Guil. We both obey, +And here giue vp our selues, in the full bent, +To lay our Seruices freely at your feete, +To be commanded + + King. Thankes Rosincrance, and gentle Guildensterne + + Qu. Thankes Guildensterne and gentle Rosincrance. +And I beseech you instantly to visit +My too much changed Sonne. +Go some of ye, +And bring the Gentlemen where Hamlet is + + Guil. Heauens make our presence and our practises +Pleasant and helpfull to him. +Enter. + + Queene. Amen. +Enter Polonius. + + Pol. Th' Ambassadors from Norwey, my good Lord, +Are ioyfully return'd + + King. Thou still hast bin the father of good Newes + + Pol. Haue I, my Lord? Assure you, my good Liege, +I hold my dutie, as I hold my Soule, +Both to my God, one to my gracious King: +And I do thinke, or else this braine of mine +Hunts not the traile of Policie, so sure +As I haue vs'd to do: that I haue found +The very cause of Hamlets Lunacie + + King. Oh speake of that, that I do long to heare + + Pol. Giue first admittance to th' Ambassadors, +My Newes shall be the Newes to that great Feast + + King. Thy selfe do grace to them, and bring them in. +He tels me my sweet Queene, that he hath found +The head and sourse of all your Sonnes distemper + + Qu. I doubt it is no other, but the maine, +His Fathers death, and our o're-hasty Marriage. +Enter Polonius, Voltumand, and Cornelius. + + King. Well, we shall sift him. Welcome good Frends: +Say Voltumand, what from our Brother Norwey? + Volt. Most faire returne of Greetings, and Desires. +Vpon our first, he sent out to suppresse +His Nephewes Leuies, which to him appear'd +To be a preparation 'gainst the Poleak: +But better look'd into, he truly found +It was against your Highnesse, whereat greeued, +That so his Sicknesse, Age, and Impotence +Was falsely borne in hand, sends out Arrests +On Fortinbras, which he (in breefe) obeyes, +Receiues rebuke from Norwey: and in fine, +Makes Vow before his Vnkle, neuer more +To giue th' assay of Armes against your Maiestie. +Whereon old Norwey, ouercome with ioy, +Giues him three thousand Crownes in Annuall Fee, +And his Commission to imploy those Soldiers +So leuied as before, against the Poleak: +With an intreaty heerein further shewne, +That it might please you to giue quiet passe +Through your Dominions, for his Enterprize, +On such regards of safety and allowance, +As therein are set downe + + King. It likes vs well: +And at our more consider'd time wee'l read, +Answer, and thinke vpon this Businesse. +Meane time we thanke you, for your well-tooke Labour. +Go to your rest, at night wee'l Feast together. +Most welcome home. + +Exit Ambass. + + Pol. This businesse is very well ended. +My Liege, and Madam, to expostulate +What Maiestie should be, what Dutie is, +Why day is day; night, night; and time is time, +Were nothing but to waste Night, Day, and Time. +Therefore, since Breuitie is the Soule of Wit, +And tediousnesse, the limbes and outward flourishes, +I will be breefe. Your Noble Sonne is mad: +Mad call I it; for to define true Madnesse, +What is't, but to be nothing else but mad. +But let that go + + Qu. More matter, with lesse Art + + Pol. Madam, I sweare I vse no Art at all: +That he is mad, 'tis true: 'Tis true 'tis pittie, +And pittie it is true: A foolish figure, +But farewell it: for I will vse no Art. +Mad let vs grant him then: and now remaines +That we finde out the cause of this effect, +Or rather say, the cause of this defect; +For this effect defectiue, comes by cause, +Thus it remaines, and the remainder thus. Perpend, +I haue a daughter: haue, whil'st she is mine, +Who in her Dutie and Obedience, marke, +Hath giuen me this: now gather, and surmise. + +The Letter. + +To the Celestiall, and my Soules Idoll, the most beautifed Ophelia. +That's an ill Phrase, a vilde Phrase, beautified is a vilde +Phrase: but you shall heare these in her excellent white +bosome, these + + Qu. Came this from Hamlet to her + + Pol. Good Madam stay awhile, I will be faithfull. +Doubt thou, the Starres are fire, +Doubt, that the Sunne doth moue: +Doubt Truth to be a Lier, +But neuer Doubt, I loue. +O deere Ophelia, I am ill at these Numbers: I haue not Art to +reckon my grones; but that I loue thee best, oh most Best beleeue +it. Adieu. +Thine euermore most deere Lady, whilst this +Machine is to him, Hamlet. +This in Obedience hath my daughter shew'd me: +And more aboue hath his soliciting, +As they fell out by Time, by Meanes, and Place, +All giuen to mine eare + + King. But how hath she receiu'd his Loue? + Pol. What do you thinke of me? + King. As of a man, faithfull and Honourable + + Pol. I wold faine proue so. But what might you think? +When I had seene this hot loue on the wing, +As I perceiued it, I must tell you that +Before my Daughter told me what might you +Or my deere Maiestie your Queene heere, think, +If I had playd the Deske or Table-booke, +Or giuen my heart a winking, mute and dumbe, +Or look'd vpon this Loue, with idle sight, +What might you thinke? No, I went round to worke, +And (my yong Mistris) thus I did bespeake +Lord Hamlet is a Prince out of thy Starre, +This must not be: and then, I Precepts gaue her, +That she should locke her selfe from his Resort, +Admit no Messengers, receiue no Tokens: +Which done, she tooke the Fruites of my Aduice, +And he repulsed. A short Tale to make, +Fell into a Sadnesse, then into a Fast, +Thence to a Watch, thence into a Weaknesse, +Thence to a Lightnesse, and by this declension +Into the Madnesse whereon now he raues, +And all we waile for + + King. Do you thinke 'tis this? + Qu. It may be very likely + + Pol. Hath there bene such a time, I'de fain know that, +That I haue possitiuely said, 'tis so, +When it prou'd otherwise? + King. Not that I know + + Pol. Take this from this; if this be otherwise, +If Circumstances leade me, I will finde +Where truth is hid, though it were hid indeede +Within the Center + + King. How may we try it further? + Pol. You know sometimes +He walkes foure houres together, heere +In the Lobby + + Qu. So he ha's indeed + + Pol. At such a time Ile loose my Daughter to him, +Be you and I behinde an Arras then, +Marke the encounter: If he loue her not, +And be not from his reason falne thereon; +Let me be no Assistant for a State, +And keepe a Farme and Carters + + King. We will try it. +Enter Hamlet reading on a Booke. + + Qu. But looke where sadly the poore wretch +Comes reading + + Pol. Away I do beseech you, both away, +Ile boord him presently. + +Exit King & Queen. + +Oh giue me leaue. How does my good Lord Hamlet? + Ham. Well, God-a-mercy + + Pol. Do you know me, my Lord? + Ham. Excellent, excellent well: y'are a Fishmonger + + Pol. Not I my Lord + + Ham. Then I would you were so honest a man + + Pol. Honest, my Lord? + Ham. I sir, to be honest as this world goes, is to bee +one man pick'd out of two thousand + + Pol. That's very true, my Lord + + Ham. For if the Sun breed Magots in a dead dogge, +being a good kissing Carrion- +Haue you a daughter? + Pol. I haue my Lord + + Ham. Let her not walke i'thSunne: Conception is a +blessing, but not as your daughter may conceiue. Friend +looke too't + + Pol. How say you by that? Still harping on my daughter: +yet he knew me not at first; he said I was a Fishmonger: +he is farre gone, farre gone: and truly in my youth, +I suffred much extreamity for loue: very neere this. Ile +speake to him againe. What do you read my Lord? + Ham. Words, words, words + + Pol. What is the matter, my Lord? + Ham. Betweene who? + Pol. I meane the matter you meane, my Lord + + Ham. Slanders Sir: for the Satyricall slaue saies here, +that old men haue gray Beards; that their faces are wrinkled; +their eyes purging thicke Amber, or Plum-Tree +Gumme: and that they haue a plentifull locke of Wit, +together with weake Hammes. All which Sir, though I +most powerfully, and potently beleeue; yet I holde it +not Honestie to haue it thus set downe: For you your +selfe Sir, should be old as I am, if like a Crab you could +go backward + + Pol. Though this be madnesse, +Yet there is Method in't: will you walke +Out of the ayre my Lord? + Ham. Into my Graue? + Pol. Indeed that is out o'th' Ayre: +How pregnant (sometimes) his Replies are? +A happinesse, +That often Madnesse hits on, +Which Reason and Sanitie could not +So prosperously be deliuer'd of. +I will leaue him, +And sodainely contriue the meanes of meeting +Betweene him, and my daughter. +My Honourable Lord, I will most humbly +Take my leaue of you + + Ham. You cannot Sir take from me any thing, that I +will more willingly part withall, except my life, my +life + + Polon. Fare you well my Lord + + Ham. These tedious old fooles + + Polon. You goe to seeke my Lord Hamlet; there +hee is. +Enter Rosincran and Guildensterne. + + Rosin. God saue you Sir + + Guild. Mine honour'd Lord? + Rosin. My most deare Lord? + Ham. My excellent good friends? How do'st thou +Guildensterne? Oh, Rosincrane; good Lads: How doe ye +both? + Rosin. As the indifferent Children of the earth + + Guild. Happy, in that we are not ouer-happy: on Fortunes +Cap, we are not the very Button + + Ham. Nor the Soales of her Shoo? + Rosin. Neither my Lord + + Ham. Then you liue about her waste, or in the middle +of her fauour? + Guil. Faith, her priuates, we + + Ham. In the secret parts of Fortune? Oh, most true: +she is a Strumpet. What's the newes? + Rosin. None my Lord; but that the World's growne +honest + + Ham. Then is Doomesday neere: But your newes is +not true. Let me question more in particular: what haue +you my good friends, deserued at the hands of Fortune, +that she sends you to Prison hither? + Guil. Prison, my Lord? + Ham. Denmark's a Prison + + Rosin. Then is the World one + + Ham. A goodly one, in which there are many Confines, +Wards, and Dungeons; Denmarke being one o'th' +worst + + Rosin. We thinke not so my Lord + + Ham. Why then 'tis none to you; for there is nothing +either good or bad, but thinking makes it so: to me it is +a prison + + Rosin. Why then your Ambition makes it one: 'tis +too narrow for your minde + + Ham. O God, I could be bounded in a nutshell, and +count my selfe a King of infinite space; were it not that +I haue bad dreames + + Guil. Which dreames indeed are Ambition: for the +very substance of the Ambitious, is meerely the shadow +of a Dreame + + Ham. A dreame it selfe is but a shadow + + Rosin. Truely, and I hold Ambition of so ayry and +light a quality, that it is but a shadowes shadow + + Ham. Then are our Beggers bodies; and our Monarchs +and out-stretcht Heroes the Beggers Shadowes: +shall wee to th' Court: for, by my fey I cannot reason? + Both. Wee'l wait vpon you + + Ham. No such matter. I will not sort you with the +rest of my seruants: for to speake to you like an honest +man: I am most dreadfully attended; but in the beaten +way of friendship, What make you at Elsonower? + Rosin. To visit you my Lord, no other occasion + + Ham. Begger that I am, I am euen poore in thankes; +but I thanke you: and sure deare friends my thanks +are too deare a halfepeny; were you not sent for? Is it +your owne inclining? Is it a free visitation? Come, +deale iustly with me: come, come; nay speake + + Guil. What should we say my Lord? + Ham. Why any thing. But to the purpose; you were +sent for; and there is a kinde confession in your lookes; +which your modesties haue not craft enough to color, +I know the good King & Queene haue sent for you + + Rosin. To what end my Lord? + Ham. That you must teach me: but let mee coniure +you by the rights of our fellowship, by the consonancy of +our youth, by the Obligation of our euer-preserued loue, +and by what more deare, a better proposer could charge +you withall; be euen and direct with me, whether you +were sent for or no + + Rosin. What say you? + Ham. Nay then I haue an eye of you: if you loue me +hold not off + + Guil. My Lord, we were sent for + + Ham. I will tell you why; so shall my anticipation +preuent your discouery of your secricie to the King and +Queene: moult no feather, I haue of late, but wherefore +I know not, lost all my mirth, forgone all custome of exercise; +and indeed, it goes so heauenly with my disposition; +that this goodly frame the Earth, seemes to me a sterrill +Promontory; this most excellent Canopy the Ayre, +look you, this braue ore-hanging, this Maiesticall Roofe, +fretted with golden fire: why, it appeares no other thing +to mee, then a foule and pestilent congregation of vapours. +What a piece of worke is a man! how Noble in +Reason? how infinite in faculty? in forme and mouing +how expresse and admirable? in Action, how like an Angel? +in apprehension, how like a God? the beauty of the +world, the Parragon of Animals; and yet to me, what is +this Quintessence of Dust? Man delights not me; no, +nor Woman neither; though by your smiling you seeme +to say so + + Rosin. My Lord, there was no such stuffe in my +thoughts + + Ham. Why did you laugh, when I said, Man delights +not me? + Rosin. To thinke, my Lord, if you delight not in Man, +what Lenton entertainment the Players shall receiue +from you: wee coated them on the way, and hither are +they comming to offer you Seruice + + Ham. He that playes the King shall be welcome; his +Maiesty shall haue Tribute of mee: the aduenturous +Knight shal vse his Foyle and Target: the Louer shall +not sigh gratis, the humorous man shall end his part in +peace: the Clowne shall make those laugh whose lungs +are tickled a'th' sere: and the Lady shall say her minde +freely; or the blanke Verse shall halt for't: what Players +are they? + Rosin. Euen those you were wont to take delight in +the Tragedians of the City + + Ham. How chances it they trauaile? their residence +both in reputation and profit was better both +wayes + + Rosin. I thinke their Inhibition comes by the meanes +of the late Innouation? + Ham. Doe they hold the same estimation they did +when I was in the City? Are they so follow'd? + Rosin. No indeed, they are not + + Ham. How comes it? doe they grow rusty? + Rosin. Nay, their indeauour keepes in the wonted +pace; But there is Sir an ayrie of Children, little +Yases, that crye out on the top of question; and +are most tyrannically clap't for't: these are now the +fashion, and so be-ratled the common Stages (so they +call them) that many wearing Rapiers, are affraide of +Goose-quils, and dare scarse come thither + + Ham. What are they Children? Who maintains 'em? +How are they escorted? Will they pursue the Quality no +longer then they can sing? Will they not say afterwards +if they should grow themselues to common Players (as +it is most like if their meanes are not better) their Writers +do them wrong, to make them exclaim against their +owne Succession + + Rosin. Faith there ha's bene much to do on both sides: +and the Nation holds it no sinne, to tarre them to Controuersie. +There was for a while, no mony bid for argument, +vnlesse the Poet and the Player went to Cuffes in +the Question + + Ham. Is't possible? + Guild. Oh there ha's beene much throwing about of +Braines + + Ham. Do the Boyes carry it away? + Rosin. I that they do my Lord. Hercules & his load too + + Ham. It is not strange: for mine Vnckle is King of +Denmarke, and those that would make mowes at him +while my Father liued; giue twenty, forty, an hundred +Ducates a peece, for his picture in Little. There is something +in this more then Naturall, if Philosophie could +finde it out. + +Flourish for the Players. + + Guil. There are the Players + + Ham. Gentlemen, you are welcom to Elsonower: your +hands, come: The appurtenance of Welcome, is Fashion +and Ceremony. Let me comply with you in the Garbe, +lest my extent to the Players (which I tell you must shew +fairely outward) should more appeare like entertainment +then yours. You are welcome: but my Vnckle Father, +and Aunt Mother are deceiu'd + + Guil. In what my deere Lord? + Ham. I am but mad North, North-West: when the +Winde is Southerly, I know a Hawke from a Handsaw. +Enter Polonius. + + Pol. Well be with you Gentlemen + + Ham. Hearke you Guildensterne, and you too: at each +eare a hearer: that great Baby you see there, is not yet +out of his swathing clouts + + Rosin. Happily he's the second time come to them: for +they say, an old man is twice a childe + + Ham. I will Prophesie. Hee comes to tell me of the +Players. Mark it, you say right Sir: for a Monday morning +'twas so indeed + + Pol. My Lord, I haue Newes to tell you + + Ham. My Lord, I haue Newes to tell you. +When Rossius an Actor in Rome- + Pol. The Actors are come hither my Lord + + Ham. Buzze, buzze + + Pol. Vpon mine Honor + + Ham. Then can each Actor on his Asse- + Polon. The best Actors in the world, either for Tragedie, +Comedie, Historie, Pastorall: +Pastoricall-Comicall-Historicall-Pastorall: +Tragicall-Historicall: Tragicall-Comicall-Historicall-Pastorall: +Scene indiuidible: or Poem +vnlimited. Seneca cannot be too heauy, nor Plautus +too light, for the law of Writ, and the Liberty. These are +the onely men + + Ham. O Iephta Iudge of Israel, what a Treasure had'st +thou? + Pol. What a Treasure had he, my Lord? + Ham. Why one faire Daughter, and no more, +The which he loued passing well + + Pol. Still on my Daughter + + Ham. Am I not i'th' right old Iephta? + Polon. If you call me Iephta my Lord, I haue a daughter +that I loue passing well + + Ham. Nay that followes not + + Polon. What followes then, my Lord? + Ha. Why, As by lot, God wot: and then you know, It +came to passe, as most like it was: The first rowe of the +Pons Chanson will shew you more. For looke where my +Abridgements come. +Enter foure or fiue Players. + +Y'are welcome Masters, welcome all. I am glad to see +thee well: Welcome good Friends. Oh my olde Friend? +Thy face is valiant since I saw thee last: Com'st thou to +beard me in Denmarke? What, my yong Lady and Mistris? +Byrlady your Ladiship is neerer Heauen then when +I saw you last, by the altitude of a Choppine. Pray God +your voice like a peece of vncurrant Gold be not crack'd +within the ring. Masters, you are all welcome: wee'l e'ne +to't like French Faulconers, flie at any thing we see: wee'l +haue a Speech straight. Come giue vs a tast of your quality: +come, a passionate speech + + 1.Play. What speech, my Lord? + Ham. I heard thee speak me a speech once, but it was +neuer Acted: or if it was, not aboue once, for the Play I +remember pleas'd not the Million, 'twas Cauiarie to the +Generall: but it was (as I receiu'd it, and others, whose +iudgement in such matters, cried in the top of mine) an +excellent Play; well digested in the Scoenes, set downe +with as much modestie, as cunning. I remember one said, +there was no Sallets in the lines, to make the matter sauory; +nor no matter in the phrase, that might indite the +Author of affectation, but cal'd it an honest method. One +cheefe Speech in it, I cheefely lou'd, 'twas Aeneas Tale +to Dido, and thereabout of it especially, where he speaks +of Priams slaughter. If it liue in your memory, begin at +this Line, let me see, let me see: The rugged Pyrrhus like +th'Hyrcanian Beast. It is not so: it begins with Pyrrhus +The rugged Pyrrhus, he whose Sable Armes +Blacke as his purpose, did the night resemble +When he lay couched in the Ominous Horse, +Hath now this dread and blacke Complexion smear'd +With Heraldry more dismall: Head to foote +Now is he to take Geulles, horridly Trick'd +With blood of Fathers, Mothers, Daughters, Sonnes, +Bak'd and impasted with the parching streets, +That lend a tyrannous, and damned light +To their vilde Murthers, roasted in wrath and fire, +And thus o're-sized with coagulate gore, +With eyes like Carbuncles, the hellish Pyrrhus +Olde Grandsire Priam seekes + + Pol. Fore God, my Lord, well spoken, with good accent, +and good discretion + + 1.Player. Anon he findes him, +Striking too short at Greekes. His anticke Sword, +Rebellious to his Arme, lyes where it falles +Repugnant to command: vnequall match, +Pyrrhus at Priam driues, in Rage strikes wide: +But with the whiffe and winde of his fell Sword, +Th' vnnerued Father fals. Then senselesse Illium, +Seeming to feele his blow, with flaming top +Stoopes to his Bace, and with a hideous crash +Takes Prisoner Pyrrhus eare. For loe, his Sword +Which was declining on the Milkie head +Of Reuerend Priam, seem'd i'th' Ayre to sticke: +So as a painted Tyrant Pyrrhus stood, +And like a Newtrall to his will and matter, did nothing. +But as we often see against some storme, +A silence in the Heauens, the Racke stand still, +The bold windes speechlesse, and the Orbe below +As hush as death: Anon the dreadfull Thunder +Doth rend the Region. So after Pyrrhus pause, +A rowsed Vengeance sets him new a-worke, +And neuer did the Cyclops hammers fall +On Mars his Armours, forg'd for proofe Eterne, +With lesse remorse then Pyrrhus bleeding sword +Now falles on Priam. +Out, out, thou Strumpet-Fortune, all you Gods, +In generall Synod take away her power: +Breake all the Spokes and Fallies from her wheele, +And boule the round Naue downe the hill of Heauen, +As low as to the Fiends + + Pol. This is too long + + Ham. It shall to'th Barbars, with your beard. Prythee +say on: He's for a Iigge, or a tale of Baudry, or hee +sleepes. Say on; come to Hecuba + + 1.Play. But who, O who, had seen the inobled Queen + + Ham. The inobled Queene? + Pol. That's good: Inobled Queene is good + + 1.Play. Run bare-foot vp and downe, +Threatning the flame +With Bisson Rheume: A clout about that head, +Where late the Diadem stood, and for a Robe +About her lanke and all ore-teamed Loines, +A blanket in th' Alarum of feare caught vp. +Who this had seene, with tongue in Venome steep'd, +'Gainst Fortunes State, would Treason haue pronounc'd? +But if the Gods themselues did see her then, +When she saw Pyrrhus make malicious sport +In mincing with his Sword her Husbands limbes, +The instant Burst of Clamour that she made +(Vnlesse things mortall moue them not at all) +Would haue made milche the Burning eyes of Heauen, +And passion in the Gods + + Pol. Looke where he ha's not turn'd his colour, and +ha's teares in's eyes. Pray you no more + + Ham. 'Tis well, Ile haue thee speake out the rest, +soone. Good my Lord, will you see the Players wel bestow'd. +Do ye heare, let them be well vs'd: for they are +the Abstracts and breefe Chronicles of the time. After +your death, you were better haue a bad Epitaph, then +their ill report while you liued + + Pol. My Lord, I will vse them according to their desart + + Ham. Gods bodykins man, better. Vse euerie man +after his desart, and who should scape whipping: vse +them after your own Honor and Dignity. The lesse they +deserue, the more merit is in your bountie. Take them +in + + Pol. Come sirs. + +Exit Polon. + + Ham. Follow him Friends: wee'l heare a play to morrow. +Dost thou heare me old Friend, can you play the +murther of Gonzago? + Play. I my Lord + + Ham. Wee'l ha't to morrow night. You could for a +need study a speech of some dosen or sixteene lines, which +I would set downe, and insert in't? Could ye not? + Play. I my Lord + + Ham. Very well. Follow that Lord, and looke you +mock him not. My good Friends, Ile leaue you til night +you are welcome to Elsonower? + Rosin. Good my Lord. + +Exeunt. + +Manet Hamlet. + + Ham. I so, God buy'ye: Now I am alone. +Oh what a Rogue and Pesant slaue am I? +Is it not monstrous that this Player heere, +But in a Fixion, in a dreame of Passion, +Could force his soule so to his whole conceit, +That from her working, all his visage warm'd; +Teares in his eyes, distraction in's Aspect, +A broken voyce, and his whole Function suiting +With Formes, to his Conceit? And all for nothing? +For Hecuba? +What's Hecuba to him, or he to Hecuba, +That he should weepe for her? What would he doe, +Had he the Motiue and the Cue for passion +That I haue? He would drowne the Stage with teares, +And cleaue the generall eare with horrid speech: +Make mad the guilty, and apale the free, +Confound the ignorant, and amaze indeed, +The very faculty of Eyes and Eares. Yet I, +A dull and muddy-metled Rascall, peake +Like Iohn a-dreames, vnpregnant of my cause, +And can say nothing: No, not for a King, +Vpon whose property, and most deere life, +A damn'd defeate was made. Am I a Coward? +Who calles me Villaine? breakes my pate a-crosse? +Pluckes off my Beard, and blowes it in my face? +Tweakes me by'th' Nose? giues me the Lye i'th' Throate, +As deepe as to the Lungs? Who does me this? +Ha? Why I should take it: for it cannot be, +But I am Pigeon-Liuer'd, and lacke Gall +To make Oppression bitter, or ere this, +I should haue fatted all the Region Kites +With this Slaues Offall, bloudy: a Bawdy villaine, +Remorselesse, Treacherous, Letcherous, kindles villaine! +Oh Vengeance! +Who? What an Asse am I? I sure, this is most braue, +That I, the Sonne of the Deere murthered, +Prompted to my Reuenge by Heauen, and Hell, +Must (like a Whore) vnpacke my heart with words, +And fall a Cursing like a very Drab. +A Scullion? Fye vpon't: Foh. About my Braine. +I haue heard, that guilty Creatures sitting at a Play, +Haue by the very cunning of the Scoene, +Bene strooke so to the soule, that presently +They haue proclaim'd their Malefactions. +For Murther, though it haue no tongue, will speake +With most myraculous Organ. Ile haue these Players, +Play something like the murder of my Father, +Before mine Vnkle. Ile obserue his lookes, +Ile rent him to the quicke: If he but blench +I know my course. The Spirit that I haue seene +May be the Diuell, and the Diuel hath power +T' assume a pleasing shape, yea and perhaps +Out of my Weaknesse, and my Melancholly, +As he is very potent with such Spirits, +Abuses me to damne me. Ile haue grounds +More Relatiue then this: The Play's the thing, +Wherein Ile catch the Conscience of the King. + +Exit + +Enter King, Queene, Polonius, Ophelia, Rosincrance, +Guildenstern, and +Lords. + + King. And can you by no drift of circumstance +Get from him why he puts on this Confusion: +Grating so harshly all his dayes of quiet +With turbulent and dangerous Lunacy + + Rosin. He does confesse he feeles himselfe distracted, +But from what cause he will by no meanes speake + + Guil. Nor do we finde him forward to be sounded, +But with a crafty Madnesse keepes aloofe: +When we would bring him on to some Confession +Of his true state + + Qu. Did he receiue you well? + Rosin. Most like a Gentleman + + Guild. But with much forcing of his disposition + + Rosin. Niggard of question, but of our demands +Most free in his reply + + Qu. Did you assay him to any pastime? + Rosin. Madam, it so fell out, that certaine Players +We ore-wrought on the way: of these we told him, +And there did seeme in him a kinde of ioy +To heare of it: They are about the Court, +And (as I thinke) they haue already order +This night to play before him + + Pol. 'Tis most true: +And he beseech'd me to intreate your Maiesties +To heare, and see the matter + + King. With all my heart, and it doth much content me +To heare him so inclin'd. Good Gentlemen, +Giue him a further edge, and driue his purpose on +To these delights + + Rosin. We shall my Lord. + +Exeunt. + + King. Sweet Gertrude leaue vs too, +For we haue closely sent for Hamlet hither, +That he, as 'twere by accident, may there +Affront Ophelia. Her Father, and my selfe (lawful espials) +Will so bestow our selues, that seeing vnseene +We may of their encounter frankely iudge, +And gather by him, as he is behaued, +If't be th' affliction of his loue, or no. +That thus he suffers for + + Qu. I shall obey you, +And for your part Ophelia, I do wish +That your good Beauties be the happy cause +Of Hamlets wildenesse: so shall I hope your Vertues +Will bring him to his wonted way againe, +To both your Honors + + Ophe. Madam, I wish it may + + Pol. Ophelia, walke you heere. Gracious so please ye +We will bestow our selues: Reade on this booke, +That shew of such an exercise may colour +Your lonelinesse. We are oft too blame in this, +'Tis too much prou'd, that with Deuotions visage, +And pious Action, we do surge o're +The diuell himselfe + + King. Oh 'tis true: +How smart a lash that speech doth giue my Conscience? +The Harlots Cheeke beautied with plaist'ring Art +Is not more vgly to the thing that helpes it, +Then is my deede, to my most painted word. +Oh heauie burthen! + Pol. I heare him comming, let's withdraw my Lord. + +Exeunt. + +Enter Hamlet. + + Ham. To be, or not to be, that is the Question: +Whether 'tis Nobler in the minde to suffer +The Slings and Arrowes of outragious Fortune, +Or to take Armes against a Sea of troubles, +And by opposing end them: to dye, to sleepe +No more; and by a sleepe, to say we end +The Heart-ake, and the thousand Naturall shockes +That Flesh is heyre too? 'Tis a consummation +Deuoutly to be wish'd. To dye to sleepe, +To sleepe, perchance to Dreame; I, there's the rub, +For in that sleepe of death, what dreames may come, +When we haue shuffel'd off this mortall coile, +Must giue vs pawse. There's the respect +That makes Calamity of so long life: +For who would beare the Whips and Scornes of time, +The Oppressors wrong, the poore mans Contumely, +The pangs of dispriz'd Loue, the Lawes delay, +The insolence of Office, and the Spurnes +That patient merit of the vnworthy takes, +When he himselfe might his Quietus make +With a bare Bodkin? Who would these Fardles beare +To grunt and sweat vnder a weary life, +But that the dread of something after death, +The vndiscouered Countrey, from whose Borne +No Traueller returnes, Puzels the will, +And makes vs rather beare those illes we haue, +Then flye to others that we know not of. +Thus Conscience does make Cowards of vs all, +And thus the Natiue hew of Resolution +Is sicklied o're, with the pale cast of Thought, +And enterprizes of great pith and moment, +With this regard their Currants turne away, +And loose the name of Action. Soft you now, +The faire Ophelia? Nimph, in thy Orizons +Be all my sinnes remembred + + Ophe. Good my Lord, +How does your Honor for this many a day? + Ham. I humbly thanke you: well, well, well + + Ophe. My Lord, I haue Remembrances of yours, +That I haue longed long to re-deliuer. +I pray you now, receiue them + + Ham. No, no, I neuer gaue you ought + + Ophe. My honor'd Lord, I know right well you did, +And with them words of so sweet breath compos'd, +As made the things more rich, then perfume left: +Take these againe, for to the Noble minde +Rich gifts wax poore, when giuers proue vnkinde. +There my Lord + + Ham. Ha, ha: Are you honest? + Ophe. My Lord + + Ham. Are you faire? + Ophe. What meanes your Lordship? + Ham. That if you be honest and faire, your Honesty +should admit no discourse to your Beautie + + Ophe. Could Beautie my Lord, haue better Comerce +then your Honestie? + Ham. I trulie: for the power of Beautie, will sooner +transforme Honestie from what is, to a Bawd, then the +force of Honestie can translate Beautie into his likenesse. +This was sometime a Paradox, but now the time giues it +proofe. I did loue you once + + Ophe. Indeed my Lord, you made me beleeue so + + Ham. You should not haue beleeued me. For vertue +cannot so innocculate our old stocke, but we shall rellish +of it. I loued you not + + Ophe. I was the more deceiued + + Ham. Get thee to a Nunnerie. Why would'st thou +be a breeder of Sinners? I am my selfe indifferent honest, +but yet I could accuse me of such things, that it were better +my Mother had not borne me. I am very prowd, reuengefull, +Ambitious, with more offences at my becke, +then I haue thoughts to put them in imagination, to giue +them shape, or time to acte them in. What should such +Fellowes as I do, crawling betweene Heauen and Earth. +We are arrant Knaues all, beleeue none of vs. Goe thy +wayes to a Nunnery. Where's your Father? + Ophe. At home, my Lord + + Ham. Let the doores be shut vpon him, that he may +play the Foole no way, but in's owne house. Farewell + + Ophe. O helpe him, you sweet Heauens + + Ham. If thou doest Marry, Ile giue thee this Plague +for thy Dowrie. Be thou as chast as Ice, as pure as Snow, +thou shalt not escape Calumny. Get thee to a Nunnery. +Go, Farewell. Or if thou wilt needs Marry, marry a fool: +for Wise men know well enough, what monsters you +make of them. To a Nunnery go, and quickly too. Farwell + + Ophe. O heauenly Powers, restore him + + Ham. I haue heard of your pratlings too wel enough. +God has giuen you one pace, and you make your selfe another: +you gidge, you amble, and you lispe, and nickname +Gods creatures, and make your Wantonnesse, your Ignorance. +Go too, Ile no more on't, it hath made me mad. +I say, we will haue no more Marriages. Those that are +married already, all but one shall liue, the rest shall keep +as they are. To a Nunnery, go. + +Exit Hamlet. + + Ophe. O what a Noble minde is heere o're-throwne? +The Courtiers, Soldiers, Schollers: Eye, tongue, sword, +Th' expectansie and Rose of the faire State, +The glasse of Fashion, and the mould of Forme, +Th' obseru'd of all Obseruers, quite, quite downe. +Haue I of Ladies most deiect and wretched, +That suck'd the Honie of his Musicke Vowes: +Now see that Noble, and most Soueraigne Reason, +Like sweet Bels iangled out of tune, and harsh, +That vnmatch'd Forme and Feature of blowne youth, +Blasted with extasie. Oh woe is me, +T'haue seene what I haue seene: see what I see. +Enter King, and Polonius. + + King. Loue? His affections do not that way tend, +Nor what he spake, though it lack'd Forme a little, +Was not like Madnesse. There's something in his soule? +O're which his Melancholly sits on brood, +And I do doubt the hatch, and the disclose +Will be some danger, which to preuent +I haue in quicke determination +Thus set it downe. He shall with speed to England +For the demand of our neglected Tribute: +Haply the Seas and Countries different +With variable Obiects, shall expell +This something setled matter in his heart: +Whereon his Braines still beating, puts him thus +From fashion of himselfe. What thinke you on't? + Pol. It shall do well. But yet do I beleeue +The Origin and Commencement of this greefe +Sprung from neglected loue. How now Ophelia? +You neede not tell vs, what Lord Hamlet saide, +We heard it all. My Lord, do as you please, +But if you hold it fit after the Play, +Let his Queene Mother all alone intreat him +To shew his Greefes: let her be round with him, +And Ile be plac'd so, please you in the eare +Of all their Conference. If she finde him not, +To England send him: Or confine him where +Your wisedome best shall thinke + + King. It shall be so: +Madnesse in great Ones, must not vnwatch'd go. + +Exeunt. + +Enter Hamlet, and two or three of the Players. + + Ham. Speake the Speech I pray you, as I pronounc'd +it to you trippingly on the Tongue: But if you mouth it, +as many of your Players do, I had as liue the Town-Cryer +had spoke my Lines: Nor do not saw the Ayre too much +your hand thus, but vse all gently; for in the verie Torrent, +Tempest, and (as I say) the Whirle-winde of +Passion, you must acquire and beget a Temperance that +may giue it Smoothnesse. O it offends mee to the Soule, +to see a robustious Pery-wig-pated Fellow, teare a Passion +to tatters, to verie ragges, to split the eares of the +Groundlings: who (for the most part) are capeable of +nothing, but inexplicable dumbe shewes, & noise: I could +haue such a Fellow whipt for o're-doing Termagant: it +outHerod's Herod. Pray you auoid it + + Player. I warrant your Honor + + Ham. Be not too tame neyther: but let your owne +Discretion be your Tutor. Sute the Action to the Word, +the Word to the Action, with this speciall obseruance: +That you ore-stop not the modestie of Nature; for any +thing so ouer-done, is fro[m] the purpose of Playing, whose +end both at the first and now, was and is, to hold as 'twer +the Mirrour vp to Nature; to shew Vertue her owne +Feature, Scorne her owne Image, and the verie Age and +Bodie of the Time, his forme and pressure. Now, this +ouer-done, or come tardie off, though it make the vnskilfull +laugh, cannot but make the Iudicious greeue; The +censure of the which One, must in your allowance o'reway +a whole Theater of Others. Oh, there bee Players +that I haue seene Play, and heard others praise, and that +highly (not to speake it prophanely) that neyther hauing +the accent of Christians, nor the gate of Christian, Pagan, +or Norman, haue so strutted and bellowed, that I haue +thought some of Natures Iouerney-men had made men, +and not made them well, they imitated Humanity so abhominably + + Play. I hope we haue reform'd that indifferently with +vs, Sir + + Ham. O reforme it altogether. And let those that +play your Clownes, speake no more then is set downe for +them. For there be of them, that will themselues laugh, +to set on some quantitie of barren Spectators to laugh +too, though in the meane time, some necessary Question +of the Play be then to be considered: that's Villanous, & +shewes a most pittifull Ambition in the Foole that vses +it. Go make you readie. + +Exit Players. + +Enter Polonius, Rosincrance, and Guildensterne. + +How now my Lord, +Will the King heare this peece of Worke? + Pol. And the Queene too, and that presently + + Ham. Bid the Players make hast. + +Exit Polonius. + +Will you two helpe to hasten them? + Both. We will my Lord. + +Exeunt. + +Enter Horatio. + + Ham. What hoa, Horatio? + Hora. Heere sweet Lord, at your Seruice + + Ham. Horatio, thou art eene as iust a man +As ere my Conuersation coap'd withall + + Hora. O my deere Lord + + Ham. Nay, do not thinke I flatter: +For what aduancement may I hope from thee, +That no Reuennew hast, but thy good spirits +To feed & cloath thee. Why shold the poor be flatter'd? +No, let the Candied tongue, like absurd pompe, +And crooke the pregnant Hindges of the knee, +Where thrift may follow faining? Dost thou heare, +Since my deere Soule was Mistris of my choyse, +And could of men distinguish, her election +Hath seal'd thee for her selfe. For thou hast bene +As one in suffering all, that suffers nothing. +A man that Fortunes buffets, and Rewards +Hath 'tane with equall Thankes. And blest are those, +Whose Blood and Iudgement are so well co-mingled, +That they are not a Pipe for Fortunes finger. +To sound what stop she please. Giue me that man, +That is not Passions Slaue, and I will weare him +In my hearts Core. I, in my Heart of heart, +As I do thee. Something too much of this. +There is a Play to night to before the King. +One Scoene of it comes neere the Circumstance +Which I haue told thee, of my Fathers death. +I prythee, when thou see'st that Acte a-foot, +Euen with the verie Comment of my Soule +Obserue mine Vnkle: If his occulted guilt, +Do not it selfe vnkennell in one speech, +It is a damned Ghost that we haue seene: +And my Imaginations are as foule +As Vulcans Stythe. Giue him needfull note, +For I mine eyes will riuet to his Face: +And after we will both our iudgements ioyne, +To censure of his seeming + + Hora. Well my Lord. +If he steale ought the whil'st this Play is Playing, +And scape detecting, I will pay the Theft. +Enter King, Queene, Polonius, Ophelia, Rosincrance, +Guildensterne, and +other Lords attendant with his Guard carrying Torches. Danish +March. Sound +a Flourish. + + Ham. They are comming to the Play: I must be idle. +Get you a place + + King. How fares our Cosin Hamlet? + Ham. Excellent Ifaith, of the Camelions dish: I eate +the Ayre promise-cramm'd, you cannot feed Capons so + + King. I haue nothing with this answer Hamlet, these +words are not mine + + Ham. No, nor mine. Now my Lord, you plaid once +i'th' Vniuersity, you say? + Polon. That I did my Lord, and was accounted a good +Actor + + Ham. And what did you enact? + Pol. I did enact Iulius Caesar, I was kill'd i'th' Capitol: +Brutus kill'd me + + Ham. It was a bruite part of him, to kill so Capitall a +Calfe there. Be the Players ready? + Rosin. I my Lord, they stay vpon your patience + + Qu. Come hither my good Hamlet, sit by me + + Ha. No good Mother, here's Mettle more attractiue + + Pol. Oh ho, do you marke that? + Ham. Ladie, shall I lye in your Lap? + Ophe. No my Lord + + Ham. I meane, my Head vpon your Lap? + Ophe. I my Lord + + Ham. Do you thinke I meant Country matters? + Ophe. I thinke nothing, my Lord + + Ham. That's a faire thought to ly betweene Maids legs + Ophe. What is my Lord? + Ham. Nothing + + Ophe. You are merrie, my Lord? + Ham. Who I? + Ophe. I my Lord + + Ham. Oh God, your onely Iigge-maker: what should +a man do, but be merrie. For looke you how cheerefully +my Mother lookes, and my Father dyed within's two +Houres + + Ophe. Nay, 'tis twice two moneths, my Lord + + Ham. So long? Nay then let the Diuel weare blacke, +for Ile haue a suite of Sables. Oh Heauens! dye two moneths +ago, and not forgotten yet? Then there's hope, a +great mans Memorie, may out-liue his life halfe a yeare: +But byrlady he must builde Churches then: or else shall +he suffer not thinking on, with the Hoby-horsse, whose +Epitaph is, For o, For o, the Hoby-horse is forgot. + +Hoboyes play. The dumbe shew enters. + +Enter a King and Queene, very louingly; the Queene embracing +him. She +kneeles, and makes shew of Protestation vnto him. He takes her +vp, and +declines his head vpon her neck. Layes him downe vpon a Banke +of Flowers. +She seeing him a-sleepe, leaues him. Anon comes in a Fellow, +takes off his +Crowne, kisses it, and powres poyson in the Kings eares, and +Exits. The +Queene returnes, findes the King dead, and makes passionate +Action. The +Poysoner, with some two or three Mutes comes in againe, seeming +to lament +with her. The dead body is carried away: The Poysoner Wooes the +Queene with +Gifts, she seemes loath and vnwilling awhile, but in the end, +accepts his +loue. + +Exeunt. + + Ophe. What meanes this, my Lord? + Ham. Marry this is Miching Malicho, that meanes +Mischeefe + + Ophe. Belike this shew imports the Argument of the +Play? + Ham. We shall know by these Fellowes: the Players +cannot keepe counsell, they'l tell all + + Ophe. Will they tell vs what this shew meant? + Ham. I, or any shew that you'l shew him. Bee not +you asham'd to shew, hee'l not shame to tell you what it +meanes + + Ophe. You are naught, you are naught, Ile marke the +Play. +Enter Prologue. + +For vs, and for our Tragedie, +Heere stooping to your Clemencie: +We begge your hearing Patientlie + + Ham. Is this a Prologue, or the Poesie of a Ring? + Ophe. 'Tis briefe my Lord + + Ham. As Womans loue. +Enter King and his Queene. + + King. Full thirtie times hath Phoebus Cart gon round, +Neptunes salt Wash, and Tellus Orbed ground: +And thirtie dozen Moones with borrowed sheene, +About the World haue times twelue thirties beene, +Since loue our hearts, and Hymen did our hands +Vnite comutuall, in most sacred Bands + + Bap. So many iournies may the Sunne and Moone +Make vs againe count o're, ere loue be done. +But woe is me, you are so sicke of late, +So farre from cheere, and from your former state, +That I distrust you: yet though I distrust, +Discomfort you (my Lord) it nothing must: +For womens Feare and Loue, holds quantitie, +In neither ought, or in extremity: +Now what my loue is, proofe hath made you know, +And as my Loue is siz'd, my Feare is so + + King. Faith I must leaue thee Loue, and shortly too: +My operant Powers my Functions leaue to do: +And thou shalt liue in this faire world behinde, +Honour'd, belou'd, and haply, one as kinde. +For Husband shalt thou- + Bap. Oh confound the rest: +Such Loue, must needs be Treason in my brest: +In second Husband, let me be accurst, +None wed the second, but who kill'd the first + + Ham. Wormwood, Wormwood + + Bapt. The instances that second Marriage moue, +Are base respects of Thrift, but none of Loue. +A second time, I kill my Husband dead, +When second Husband kisses me in Bed + + King. I do beleeue you. Think what now you speak: +But what we do determine, oft we breake: +Purpose is but the slaue to Memorie, +Of violent Birth, but poore validitie: +Which now like Fruite vnripe stickes on the Tree, +But fall vnshaken, when they mellow bee. +Most necessary 'tis, that we forget +To pay our selues, what to our selues is debt: +What to our selues in passion we propose, +The passion ending, doth the purpose lose. +The violence of other Greefe or Ioy, +Their owne ennactors with themselues destroy: +Where Ioy most Reuels, Greefe doth most lament; +Greefe ioyes, Ioy greeues on slender accident. +This world is not for aye, nor 'tis not strange +That euen our Loues should with our Fortunes change. +For 'tis a question left vs yet to proue, +Whether Loue lead Fortune, or else Fortune Loue. +The great man downe, you marke his fauourites flies, +The poore aduanc'd, makes Friends of Enemies: +And hitherto doth Loue on Fortune tend, +For who not needs, shall neuer lacke a Frend: +And who in want a hollow Friend doth try, +Directly seasons him his Enemie. +But orderly to end, where I begun, +Our Willes and Fates do so contrary run, +That our Deuices still are ouerthrowne, +Our thoughts are ours, their ends none of our owne. +So thinke thou wilt no second Husband wed. +But die thy thoughts, when thy first Lord is dead + + Bap. Nor Earth to giue me food, nor Heauen light, +Sport and repose locke from me day and night: +Each opposite that blankes the face of ioy, +Meet what I would haue well, and it destroy: +Both heere, and hence, pursue me lasting strife, +If once a Widdow, euer I be Wife + + Ham. If she should breake it now + + King. 'Tis deepely sworne: +Sweet, leaue me heere a while, +My spirits grow dull, and faine I would beguile +The tedious day with sleepe + + Qu. Sleepe rocke thy Braine, + +Sleepes + +And neuer come mischance betweene vs twaine. + +Exit + + Ham. Madam, how like you this Play? + Qu. The Lady protests to much me thinkes + + Ham. Oh but shee'l keepe her word + + King. Haue you heard the Argument, is there no Offence +in't? + Ham. No, no, they do but iest, poyson in iest, no Offence +i'th' world + + King. What do you call the Play? + Ham. The Mouse-trap: Marry how? Tropically: +This Play is the Image of a murder done in Vienna: Gonzago +is the Dukes name, his wife Baptista: you shall see +anon: 'tis a knauish peece of worke: But what o'that? +Your Maiestie, and wee that haue free soules, it touches +vs not: let the gall'd iade winch: our withers are vnrung. +Enter Lucianus. + +This is one Lucianus nephew to the King + + Ophe. You are a good Chorus, my Lord + + Ham. I could interpret betweene you and your loue: +if I could see the Puppets dallying + + Ophe. You are keene my Lord, you are keene + + Ham. It would cost you a groaning, to take off my +edge + + Ophe. Still better and worse + + Ham. So you mistake Husbands. +Begin Murderer. Pox, leaue thy damnable Faces, and +begin. Come, the croaking Rauen doth bellow for Reuenge + + Lucian. Thoughts blacke, hands apt, +Drugges fit, and Time agreeing: +Confederate season, else, no Creature seeing: +Thou mixture ranke, of Midnight Weeds collected, +With Hecats Ban, thrice blasted, thrice infected, +Thy naturall Magicke, and dire propertie, +On wholsome life, vsurpe immediately. + +Powres the poyson in his eares. + + Ham. He poysons him i'th' Garden for's estate: His +name's Gonzago: the Story is extant and writ in choyce +Italian. You shall see anon how the Murtherer gets the +loue of Gonzago's wife + + Ophe. The King rises + + Ham. What, frighted with false fire + + Qu. How fares my Lord? + Pol. Giue o're the Play + + King. Giue me some Light. Away + + All. Lights, Lights, Lights. + +Exeunt. + +Manet Hamlet & Horatio. + + Ham. Why let the strucken Deere go weepe, +The Hart vngalled play: +For some must watch, while some must sleepe; +So runnes the world away. +Would not this Sir, and a Forrest of Feathers, if the rest of +my Fortunes turne Turke with me; with two Prouinciall +Roses on my rac'd Shooes, get me a Fellowship in a crie +of Players sir + + Hor. Halfe a share + + Ham. A whole one I, +For thou dost know: Oh Damon deere, +This Realme dismantled was of Ioue himselfe, +And now reignes heere. +A verie verie Paiocke + + Hora. You might haue Rim'd + + Ham. Oh good Horatio, Ile take the Ghosts word for +a thousand pound. Did'st perceiue? + Hora. Verie well my Lord + + Ham. Vpon the talke of the poysoning? + Hora. I did verie well note him. +Enter Rosincrance and Guildensterne. + + Ham. Oh, ha? Come some Musick. Come y Recorders: +For if the King like not the Comedie, +Why then belike he likes it not perdie. +Come some Musicke + + Guild. Good my Lord, vouchsafe me a word with you + + Ham. Sir, a whole History + + Guild. The King, sir + + Ham. I sir, what of him? + Guild. Is in his retyrement, maruellous distemper'd + + Ham. With drinke Sir? + Guild. No my Lord, rather with choller + + Ham. Your wisedome should shew it selfe more richer, +to signifie this to his Doctor: for for me to put him +to his Purgation, would perhaps plundge him into farre +more Choller + + Guild. Good my Lord put your discourse into some +frame, and start not so wildely from my affayre + + Ham. I am tame Sir, pronounce + + Guild. The Queene your Mother, in most great affliction +of spirit, hath sent me to you + + Ham. You are welcome + + Guild. Nay, good my Lord, this courtesie is not of +the right breed. If it shall please you to make me a wholsome +answer, I will doe your Mothers command'ment: +if not, your pardon, and my returne shall bee the end of +my Businesse + + Ham. Sir, I cannot + + Guild. What, my Lord? + Ham. Make you a wholsome answere: my wits diseas'd. +But sir, such answers as I can make, you shal command: +or rather you say, my Mother: therfore no more +but to the matter. My Mother you say + + Rosin. Then thus she sayes: your behauior hath stroke +her into amazement, and admiration + + Ham. Oh wonderfull Sonne, that can so astonish a +Mother. But is there no sequell at the heeles of this Mothers +admiration? + Rosin. She desires to speake with you in her Closset, +ere you go to bed + + Ham. We shall obey, were she ten times our Mother. +Haue you any further Trade with vs? + Rosin. My Lord, you once did loue me + + Ham. So I do still, by these pickers and stealers + + Rosin. Good my Lord, what is your cause of distemper? +You do freely barre the doore of your owne Libertie, +if you deny your greefes to your Friend + + Ham. Sir I lacke Aduancement + + Rosin. How can that be, when you haue the voyce of +the King himselfe, for your Succession in Denmarke? + Ham. I, but while the grasse growes, the Prouerbe is +something musty. +Enter one with a Recorder. + +O the Recorder. Let me see, to withdraw with you, why +do you go about to recouer the winde of mee, as if you +would driue me into a toyle? + Guild. O my Lord, if my Dutie be too bold, my loue +is too vnmannerly + + Ham. I do not well vnderstand that. Will you play +vpon this Pipe? + Guild. My Lord, I cannot + + Ham. I pray you + + Guild. Beleeue me, I cannot + + Ham. I do beseech you + + Guild. I know no touch of it, my Lord + + Ham. 'Tis as easie as lying: gouerne these Ventiges +with your finger and thumbe, giue it breath with your +mouth, and it will discourse most excellent Musicke. +Looke you, these are the stoppes + + Guild. But these cannot I command to any vtterance +of hermony, I haue not the skill + + Ham. Why looke you now, how vnworthy a thing +you make of me: you would play vpon mee; you would +seeme to know my stops: you would pluck out the heart +of my Mysterie; you would sound mee from my lowest +Note, to the top of my Compasse: and there is much Musicke, +excellent Voice, in this little Organe, yet cannot +you make it. Why do you thinke, that I am easier to bee +plaid on, then a Pipe? Call me what Instrument you will, +though you can fret me, you cannot play vpon me. God +blesse you Sir. +Enter Polonius. + + Polon. My Lord; the Queene would speak with you, +and presently + + Ham. Do you see that Clowd? that's almost in shape +like a Camell + + Polon. By'th' Masse, and it's like a Camell indeed + + Ham. Me thinkes it is like a Weazell + + Polon. It is back'd like a Weazell + + Ham. Or like a Whale? + Polon. Verie like a Whale + + Ham. Then will I come to my Mother, by and by: +They foole me to the top of my bent. +I will come by and by + + Polon. I will say so. +Enter. + + Ham. By and by, is easily said. Leaue me Friends: +'Tis now the verie witching time of night, +When Churchyards yawne, and Hell it selfe breaths out +Contagion to this world. Now could I drink hot blood, +And do such bitter businesse as the day +Would quake to looke on. Soft now, to my Mother: +Oh Heart, loose not thy Nature; let not euer +The Soule of Nero, enter this firme bosome: +Let me be cruell, not vnnaturall, +I will speake Daggers to her, but vse none: +My Tongue and Soule in this be Hypocrites. +How in my words someuer she be shent, +To giue them Seales, neuer my Soule consent. +Enter King, Rosincrance, and Guildensterne. + + King. I like him not, nor stands it safe with vs, +To let his madnesse range. Therefore prepare you, +I your Commission will forthwith dispatch, +And he to England shall along with you: +The termes of our estate, may not endure +Hazard so dangerous as doth hourely grow +Out of his Lunacies + + Guild. We will our selues prouide: +Most holie and Religious feare it is +To keepe those many many bodies safe +That liue and feede vpon your Maiestie + + Rosin. The single +And peculiar life is bound +With all the strength and Armour of the minde, +To keepe it selfe from noyance: but much more, +That Spirit, vpon whose spirit depends and rests +The liues of many, the cease of Maiestie +Dies not alone; but like a Gulfe doth draw +What's neere it, with it. It is a massie wheele +Fixt on the Somnet of the highest Mount. +To whose huge Spoakes, ten thousand lesser things +Are mortiz'd and adioyn'd: which when it falles, +Each small annexment, pettie consequence +Attends the boystrous Ruine. Neuer alone +Did the King sighe, but with a generall grone + + King. Arme you, I pray you to this speedie Voyage; +For we will Fetters put vpon this feare, +Which now goes too free-footed + + Both. We will haste vs. + +Exeunt. Gent. + +Enter Polonius. + + Pol. My Lord, he's going to his Mothers Closset: +Behinde the Arras Ile conuey my selfe +To heare the Processe. Ile warrant shee'l tax him home, +And as you said, and wisely was it said, +'Tis meete that some more audience then a Mother, +Since Nature makes them partiall, should o're-heare +The speech of vantage. Fare you well my Liege, +Ile call vpon you ere you go to bed, +And tell you what I know + + King. Thankes deere my Lord. +Oh my offence is ranke, it smels to heauen, +It hath the primall eldest curse vpon't, +A Brothers murther. Pray can I not, +Though inclination be as sharpe as will: +My stronger guilt, defeats my strong intent, +And like a man to double businesse bound, +I stand in pause where I shall first begin, +And both neglect; what if this cursed hand +Were thicker then it selfe with Brothers blood, +Is there not Raine enough in the sweet Heauens +To wash it white as Snow? Whereto serues mercy, +But to confront the visage of Offence? +And what's in Prayer, but this two-fold force, +To be fore-stalled ere we come to fall, +Or pardon'd being downe? Then Ile looke vp, +My fault is past. But oh, what forme of Prayer +Can serue my turne? Forgiue me my foule Murther: +That cannot be, since I am still possest +Of those effects for which I did the Murther. +My Crowne, mine owne Ambition, and my Queene: +May one be pardon'd, and retaine th' offence? +In the corrupted currants of this world, +Offences gilded hand may shoue by Iustice, +And oft 'tis seene, the wicked prize it selfe +Buyes out the Law; but 'tis not so aboue, +There is no shuffling, there the Action lyes +In his true Nature, and we our selues compell'd +Euen to the teeth and forehead of our faults, +To giue in euidence. What then? What rests? +Try what Repentance can. What can it not? +Yet what can it, when one cannot repent? +Oh wretched state! Oh bosome, blacke as death! +Oh limed soule, that strugling to be free, +Art more ingag'd: Helpe Angels, make assay: +Bow stubborne knees, and heart with strings of Steele, +Be soft as sinewes of the new-borne Babe, +All may be well. +Enter Hamlet. + + Ham. Now might I do it pat, now he is praying, +And now Ile doo't, and so he goes to Heauen, +And so am I reueng'd: that would be scann'd, +A Villaine killes my Father, and for that +I his foule Sonne, do this same Villaine send +To heauen. Oh this is hyre and Sallery, not Reuenge. +He tooke my Father grossely, full of bread, +With all his Crimes broad blowne, as fresh as May, +And how his Audit stands, who knowes, saue Heauen: +But in our circumstance and course of thought +'Tis heauie with him: and am I then reueng'd, +To take him in the purging of his Soule, +When he is fit and season'd for his passage? No. +Vp Sword, and know thou a more horrid hent +When he is drunke asleepe: or in his Rage, +Or in th' incestuous pleasure of his bed, +At gaming, swearing, or about some acte +That ha's no rellish of Saluation in't, +Then trip him, that his heeles may kicke at Heauen, +And that his Soule may be as damn'd and blacke +As Hell, whereto it goes. My Mother stayes, +This Physicke but prolongs thy sickly dayes. +Enter. + + King. My words flye vp, my thoughts remain below, +Words without thoughts, neuer to Heauen go. +Enter. + +Enter Queene and Polonius. + + Pol. He will come straight: +Looke you lay home to him, +Tell him his prankes haue been too broad to beare with, +And that your Grace hath screen'd, and stoode betweene +Much heate, and him. Ile silence me e'ene heere: +Pray you be round with him + + Ham. within. Mother, mother, mother + + Qu. Ile warrant you, feare me not. +Withdraw, I heare him coming. +Enter Hamlet. + + Ham. Now Mother, what's the matter? + Qu. Hamlet, thou hast thy Father much offended + + + Ham. Mother, you haue my Father much offended + + Qu. Come, come, you answer with an idle tongue + + Ham. Go, go, you question with an idle tongue + + Qu. Why how now Hamlet? + Ham. Whats the matter now? + Qu. Haue you forgot me? + Ham. No by the Rood, not so: +You are the Queene, your Husbands Brothers wife, +But would you were not so. You are my Mother + + Qu. Nay, then Ile set those to you that can speake + + Ham. Come, come, and sit you downe, you shall not +boudge: +You go not till I set you vp a glasse, +Where you may see the inmost part of you? + Qu. What wilt thou do? thou wilt not murther me? +Helpe, helpe, hoa + + Pol. What hoa, helpe, helpe, helpe + + Ham. How now, a Rat? dead for a Ducate, dead + + Pol. Oh I am slaine. + +Killes Polonius + + Qu. Oh me, what hast thou done? + Ham. Nay I know not, is it the King? + Qu. Oh what a rash, and bloody deed is this? + Ham. A bloody deed, almost as bad good Mother, +As kill a King, and marrie with his Brother + + Qu. As kill a King? + Ham. I Lady, 'twas my word. +Thou wretched, rash, intruding foole farewell, +I tooke thee for thy Betters, take thy Fortune, +Thou find'st to be too busie, is some danger. +Leaue wringing of your hands, peace, sit you downe, +And let me wring your heart, for so I shall +If it be made of penetrable stuffe; +If damned Custome haue not braz'd it so, +That it is proofe and bulwarke against Sense + + Qu. What haue I done, that thou dar'st wag thy tong, +In noise so rude against me? + Ham. Such an Act +That blurres the grace and blush of Modestie, +Cals Vertue Hypocrite, takes off the Rose +From the faire forehead of an innocent loue, +And makes a blister there. Makes marriage vowes +As false as Dicers Oathes. Oh such a deed, +As from the body of Contraction pluckes +The very soule, and sweete Religion makes +A rapsidie of words. Heauens face doth glow, +Yea this solidity and compound masse, +With tristfull visage as against the doome, +Is thought-sicke at the act + + Qu. Aye me; what act, that roares so lowd, & thunders +in the Index + + Ham. Looke heere vpon this Picture, and on this, +The counterfet presentment of two Brothers: +See what a grace was seated on his Brow, +Hyperions curles, the front of Ioue himselfe, +An eye like Mars, to threaten or command +A Station, like the Herald Mercurie +New lighted on a heauen-kissing hill: +A Combination, and a forme indeed, +Where euery God did seeme to set his Seale, +To giue the world assurance of a man. +This was your Husband. Looke you now what followes. +Heere is your Husband, like a Mildew'd eare +Blasting his wholsom breath. Haue you eyes? +Could you on this faire Mountaine leaue to feed, +And batten on this Moore? Ha? Haue you eyes? +You cannot call it Loue: For at your age, +The hey-day in the blood is tame, it's humble, +And waites vpon the Iudgement: and what Iudgement +Would step from this, to this? What diuell was't, +That thus hath cousend you at hoodman-blinde? +O Shame! where is thy Blush? Rebellious Hell, +If thou canst mutine in a Matrons bones, +To flaming youth, let Vertue be as waxe. +And melt in her owne fire. Proclaime no shame, +When the compulsiue Ardure giues the charge, +Since Frost it selfe, as actiuely doth burne, +As Reason panders Will + + Qu. O Hamlet, speake no more. +Thou turn'st mine eyes into my very soule, +And there I see such blacke and grained spots, +As will not leaue their Tinct + + Ham. Nay, but to liue +In the ranke sweat of an enseamed bed, +Stew'd in Corruption; honying and making loue +Ouer the nasty Stye + + Qu. Oh speake to me, no more, +These words like Daggers enter in mine eares. +No more sweet Hamlet + + Ham. A Murderer, and a Villaine: +A Slaue, that is not twentieth part the tythe +Of your precedent Lord. A vice of Kings, +A Cutpurse of the Empire and the Rule. +That from a shelfe, the precious Diadem stole, +And put it in his Pocket + + Qu. No more. +Enter Ghost. + + Ham. A King of shreds and patches. +Saue me; and houer o're me with your wings +You heauenly Guards. What would your gracious figure? + Qu. Alas he's mad + + Ham. Do you not come your tardy Sonne to chide, +That laps't in Time and Passion, lets go by +Th' important acting of your dread command? Oh say + + Ghost. Do not forget: this Visitation +Is but to whet thy almost blunted purpose. +But looke, Amazement on thy Mother sits; +O step betweene her, and her fighting Soule, +Conceit in weakest bodies, strongest workes. +Speake to her Hamlet + + Ham. How is it with you Lady? + Qu. Alas, how is't with you? +That you bend your eye on vacancie, +And with their corporall ayre do hold discourse. +Forth at your eyes, your spirits wildely peepe, +And as the sleeping Soldiours in th' Alarme, +Your bedded haire, like life in excrements, +Start vp, and stand an end. Oh gentle Sonne, +Vpon the heate and flame of thy distemper +Sprinkle coole patience. Whereon do you looke? + Ham. On him, on him: look you how pale he glares, +His forme and cause conioyn'd, preaching to stones, +Would make them capeable. Do not looke vpon me, +Least with this pitteous action you conuert +My sterne effects: then what I haue to do, +Will want true colour; teares perchance for blood + + Qu. To who do you speake this? + Ham. Do you see nothing there? + Qu. Nothing at all, yet all that is I see + + Ham. Nor did you nothing heare? + Qu. No, nothing but our selues + + Ham. Why look you there: looke how it steals away: +My Father in his habite, as he liued, +Looke where he goes euen now out at the Portall. +Enter. + + Qu. This is the very coynage of your Braine, +This bodilesse Creation extasie is very cunning in + + Ham. Extasie? +My Pulse as yours doth temperately keepe time, +And makes as healthfull Musicke. It is not madnesse +That I haue vttered; bring me to the Test +And I the matter will re-word: which madnesse +Would gamboll from. Mother, for loue of Grace, +Lay not a flattering Vnction to your soule, +That not your trespasse, but my madnesse speakes: +It will but skin and filme the Vlcerous place, +Whil'st ranke Corruption mining all within, +Infects vnseene. Confesse your selfe to Heauen, +Repent what's past, auoyd what is to come, +And do not spred the Compost on the Weedes, +To make them ranke. Forgiue me this my Vertue, +For in the fatnesse of this pursie times, +Vertue it selfe, of Vice must pardon begge, +Yea courb, and woe, for leaue to do him good + + Qu. Oh Hamlet, +Thou hast cleft my heart in twaine + + Ham. O throw away the worser part of it, +And liue the purer with the other halfe. +Good night, but go not to mine Vnkles bed, +Assume a Vertue, if you haue it not, refraine to night, +And that shall lend a kinde of easinesse +To the next abstinence. Once more goodnight, +And when you are desirous to be blest, +Ile blessing begge of you. For this same Lord, +I do repent: but heauen hath pleas'd it so, +To punish me with this, and this with me, +That I must be their Scourge and Minister. +I will bestow him, and will answer well +The death I gaue him: so againe, good night. +I must be cruell, onely to be kinde; +Thus bad begins and worse remaines behinde + + Qu. What shall I do? + Ham. Not this by no meanes that I bid you do: +Let the blunt King tempt you againe to bed, +Pinch Wanton on your cheeke, call you his Mouse, +And let him for a paire of reechie kisses, +Or padling in your necke with his damn'd Fingers, +Make you to rauell all this matter out, +That I essentially am not in madnesse, +But made in craft. 'Twere good you let him know, +For who that's but a Queene, faire, sober, wise, +Would from a Paddocke, from a Bat, a Gibbe, +Such deere concernings hide, Who would do so, +No in despight of Sense and Secrecie, +Vnpegge the Basket on the houses top: +Let the Birds flye, and like the famous Ape +To try Conclusions in the Basket, creepe +And breake your owne necke downe + + Qu. Be thou assur'd, if words be made of breath, +And breath of life: I haue no life to breath +What thou hast saide to me + + Ham. I must to England, you know that? + Qu. Alacke I had forgot: 'Tis so concluded on + + Ham. This man shall set me packing: +Ile lugge the Guts into the Neighbor roome, +Mother goodnight. Indeede this Counsellor +Is now most still, most secret, and most graue, +Who was in life, a foolish prating Knaue. +Come sir, to draw toward an end with you. +Good night Mother. +Exit Hamlet tugging in Polonius. + +Enter King. + + King. There's matters in these sighes. +These profound heaues +You must translate; Tis fit we vnderstand them. +Where is your Sonne? + Qu. Ah my good Lord, what haue I seene to night? + King. What Gertrude? How do's Hamlet? + Qu. Mad as the Seas, and winde, when both contend +Which is the Mightier, in his lawlesse fit +Behinde the Arras, hearing something stirre, +He whips his Rapier out, and cries a Rat, a Rat, +And in his brainish apprehension killes +The vnseene good old man + + King. Oh heauy deed: +It had bin so with vs had we beene there: +His Liberty is full of threats to all, +To you your selfe, to vs, to euery one. +Alas, how shall this bloody deede be answered? +It will be laide to vs, whose prouidence +Should haue kept short, restrain'd, and out of haunt, +This mad yong man. But so much was our loue, +We would not vnderstand what was most fit, +But like the Owner of a foule disease, +To keepe it from divulging, let's it feede +Euen on the pith of life. Where is he gone? + Qu. To draw apart the body he hath kild, +O're whom his very madnesse like some Oare +Among a Minerall of Mettels base +Shewes it selfe pure. He weepes for what is done + + King. Oh Gertrude, come away: +The Sun no sooner shall the Mountaines touch, +But we will ship him hence, and this vilde deed, +We must with all our Maiesty and Skill +Both countenance, and excuse. +Enter Ros. & Guild. + +Ho Guildenstern: +Friends both go ioyne you with some further ayde: +Hamlet in madnesse hath Polonius slaine, +And from his Mother Clossets hath he drag'd him. +Go seeke him out, speake faire, and bring the body +Into the Chappell. I pray you hast in this. +Exit Gent. + +Come Gertrude, wee'l call vp our wisest friends, +To let them know both what we meane to do, +And what's vntimely done. Oh come away, +My soule is full of discord and dismay. + +Exeunt. + +Enter Hamlet. + + Ham. Safely stowed + + Gentlemen within. Hamlet, Lord Hamlet + + Ham. What noise? Who cals on Hamlet? +Oh heere they come. +Enter Ros. and Guildensterne. + + Ro. What haue you done my Lord with the dead body? + Ham. Compounded it with dust, whereto 'tis Kinne + + Rosin. Tell vs where 'tis, that we may take it thence, +And beare it to the Chappell + + Ham. Do not beleeue it + + Rosin. Beleeue what? + Ham. That I can keepe your counsell, and not mine +owne. Besides, to be demanded of a Spundge, what replication +should be made by the Sonne of a King + + Rosin. Take you me for a Spundge, my Lord? + Ham. I sir, that sokes vp the Kings Countenance, his +Rewards, his Authorities (but such Officers do the King +best seruice in the end. He keepes them like an Ape in +the corner of his iaw, first mouth'd to be last swallowed, +when he needes what you haue glean'd, it is but squeezing +you, and Spundge you shall be dry againe + + Rosin. I vnderstand you not my Lord + + Ham. I am glad of it: a knauish speech sleepes in a +foolish eare + + Rosin. My Lord, you must tell vs where the body is, +and go with vs to the King + + Ham. The body is with the King, but the King is not +with the body. The King, is a thing- + Guild. A thing my Lord? + Ham. Of nothing: bring me to him, hide Fox, and all +after. + +Exeunt. + +Enter King. + + King. I haue sent to seeke him, and to find the bodie: +How dangerous is it that this man goes loose: +Yet must not we put the strong Law on him: +Hee's loued of the distracted multitude, +Who like not in their iudgement, but their eyes: +And where 'tis so, th' Offenders scourge is weigh'd +But neerer the offence: to beare all smooth, and euen, +This sodaine sending him away, must seeme +Deliberate pause, diseases desperate growne, +By desperate appliance are releeued, +Or not at all. +Enter Rosincrane. + +How now? What hath befalne? + Rosin. Where the dead body is bestow'd my Lord, +We cannot get from him + + King. But where is he? + Rosin. Without my Lord, guarded to know your +pleasure + + King. Bring him before vs + + Rosin. Hoa, Guildensterne? Bring in my Lord. +Enter Hamlet and Guildensterne. + + King. Now Hamlet, where's Polonius? + Ham. At Supper + + King. At Supper? Where? + Ham. Not where he eats, but where he is eaten, a certaine +conuocation of wormes are e'ne at him. Your worm +is your onely Emperor for diet. We fat all creatures else +to fat vs, and we fat our selfe for Magots. Your fat King, +and your leane Begger is but variable seruice to dishes, +but to one Table that's the end + + King. What dost thou meane by this? + Ham. Nothing but to shew you how a King may go +a Progresse through the guts of a Begger + + King. Where is Polonius + + Ham. In heauen, send thither to see. If your Messenger +finde him not there, seeke him i'th other place your +selfe: but indeed, if you finde him not this moneth, you +shall nose him as you go vp the staires into the Lobby + + King. Go seeke him there + + Ham. He will stay till ye come + + K. Hamlet, this deed of thine, for thine especial safety +Which we do tender, as we deerely greeue +For that which thou hast done, must send thee hence +With fierie Quicknesse. Therefore prepare thy selfe, +The Barke is readie, and the winde at helpe, +Th' Associates tend, and euery thing at bent +For England + + Ham. For England? + King. I Hamlet + + Ham. Good + + King. So is it, if thou knew'st our purposes + + Ham. I see a Cherube that see's him: but come, for +England. Farewell deere Mother + + King. Thy louing Father Hamlet + + Hamlet. My Mother: Father and Mother is man and +wife: man & wife is one flesh, and so my mother. Come, +for England. + +Exit + + King. Follow him at foote, +Tempt him with speed aboord: +Delay it not, Ile haue him hence to night. +Away, for euery thing is Seal'd and done +That else leanes on th' Affaire, pray you make hast. +And England, if my loue thou holdst at ought, +As my great power thereof may giue thee sense, +Since yet thy Cicatrice lookes raw and red +After the Danish Sword, and thy free awe +Payes homage to vs; thou maist not coldly set +Our Soueraigne Processe, which imports at full +By Letters coniuring to that effect +The present death of Hamlet. Do it England, +For like the Hecticke in my blood he rages, +And thou must cure me: Till I know 'tis done, +How ere my happes, my ioyes were ne're begun. + +Exit + +Enter Fortinbras with an Armie. + + For. Go Captaine, from me greet the Danish King, +Tell him that by his license, Fortinbras +Claimes the conueyance of a promis'd March +Ouer his Kingdome. You know the Rendeuous: +If that his Maiesty would ought with vs, +We shall expresse our dutie in his eye, +And let him know so + + Cap. I will doo't, my Lord + + For. Go safely on. +Enter. + +Enter Queene and Horatio. + + Qu. I will not speake with her + + Hor. She is importunate, indeed distract, her moode +will needs be pittied + + Qu. What would she haue? + Hor. She speakes much of her Father; saies she heares +There's trickes i'th' world, and hems, and beats her heart, +Spurnes enuiously at Strawes, speakes things in doubt, +That carry but halfe sense: Her speech is nothing, +Yet the vnshaped vse of it doth moue +The hearers to Collection; they ayme at it, +And botch the words vp fit to their owne thoughts, +Which as her winkes, and nods, and gestures yeeld them, +Indeed would make one thinke there would be thought, +Though nothing sure, yet much vnhappily + + Qu. 'Twere good she were spoken with, +For she may strew dangerous coniectures +In ill breeding minds. Let her come in. +To my sicke soule (as sinnes true Nature is) +Each toy seemes Prologue, to some great amisse, +So full of Artlesse iealousie is guilt, +It spill's it selfe, in fearing to be spilt. +Enter Ophelia distracted. + + Ophe. Where is the beauteous Maiesty of Denmark + + Qu. How now Ophelia? + Ophe. How should I your true loue know from another one? +By his Cockle hat and staffe, and his Sandal shoone + + Qu. Alas sweet Lady: what imports this Song? + Ophe. Say you? Nay pray you marke. +He is dead and gone Lady, he is dead and gone, +At his head a grasse-greene Turfe, at his heeles a stone. +Enter King. + + Qu. Nay but Ophelia + + Ophe. Pray you marke. +White his Shrow'd as the Mountaine Snow + + Qu. Alas, looke heere my Lord + + Ophe. Larded with sweet Flowers: +Which bewept to the graue did not go, +With true-loue showres + + King. How do ye, pretty Lady? + Ophe. Well, God dil'd you. They say the Owle was +a Bakers daughter. Lord, wee know what we are, but +know not what we may be. God be at your Table + + King. Conceit vpon her Father + + Ophe. Pray you let's haue no words of this: but when +they aske you what it meanes, say you this: +To morrow is S[aint]. Valentines day, all in the morning betime, +And I a Maid at your Window, to be your Valentine. +Then vp he rose, & don'd his clothes, & dupt the chamber dore, +Let in the Maid, that out a Maid, neuer departed more + + King. Pretty Ophelia + + Ophe. Indeed la? without an oath Ile make an end ont. +By gis, and by S[aint]. Charity, +Alacke, and fie for shame: +Yong men wil doo't, if they come too't, +By Cocke they are too blame. +Quoth she before you tumbled me, +You promis'd me to Wed: +So would I ha done by yonder Sunne, +And thou hadst not come to my bed + + King. How long hath she bin thus? + Ophe. I hope all will be well. We must bee patient, +but I cannot choose but weepe, to thinke they should +lay him i'th' cold ground: My brother shall knowe of it, +and so I thanke you for your good counsell. Come, my +Coach: Goodnight Ladies: Goodnight sweet Ladies: +Goodnight, goodnight. +Enter. + + King. Follow her close, +Giue her good watch I pray you: +Oh this is the poyson of deepe greefe, it springs +All from her Fathers death. Oh Gertrude, Gertrude, +When sorrowes comes, they come not single spies, +But in Battalians. First, her Father slaine, +Next your Sonne gone, and he most violent Author +Of his owne iust remoue: the people muddied, +Thicke and vnwholsome in their thoughts, and whispers +For good Polonius death; and we haue done but greenly +In hugger mugger to interre him. Poore Ophelia +Diuided from her selfe, and her faire Iudgement, +Without the which we are Pictures, or meere Beasts. +Last, and as much containing as all these, +Her Brother is in secret come from France, +Keepes on his wonder, keepes himselfe in clouds, +And wants not Buzzers to infect his eare +With pestilent Speeches of his Fathers death, +Where in necessitie of matter Beggard, +Will nothing sticke our persons to Arraigne +In eare and eare. O my deere Gertrude, this, +Like to a murdering Peece in many places, +Giues me superfluous death. + +A Noise within. + +Enter a Messenger. + + Qu. Alacke, what noyse is this? + King. Where are my Switzers? +Let them guard the doore. What is the matter? + Mes. Saue your selfe, my Lord. +The Ocean (ouer-peering of his List) +Eates not the Flats with more impittious haste +Then young Laertes, in a Riotous head, +Ore-beares your Officers, the rabble call him Lord, +And as the world were now but to begin, +Antiquity forgot, Custome not knowne, +The Ratifiers and props of euery word, +They cry choose we? Laertes shall be King, +Caps, hands, and tongues, applaud it to the clouds, +Laertes shall be King, Laertes King + + Qu. How cheerefully on the false Traile they cry, +Oh this is Counter you false Danish Dogges. + +Noise within. Enter Laertes. + + King. The doores are broke + + Laer. Where is the King, sirs? Stand you all without + + All. No, let's come in + + Laer. I pray you giue me leaue + + Al. We will, we will + + Laer. I thanke you: Keepe the doore. +Oh thou vilde King, giue me my Father + + Qu. Calmely good Laertes + + Laer. That drop of blood, that calmes +Proclaimes me Bastard: +Cries Cuckold to my Father, brands the Harlot +Euen heere betweene the chaste vnsmirched brow +Of my true Mother + + King. What is the cause Laertes, +That thy Rebellion lookes so Gyant-like? +Let him go Gertrude: Do not feare our person: +There's such Diuinity doth hedge a King, +That Treason can but peepe to what it would, +Acts little of his will. Tell me Laertes, +Why thou art thus Incenst? Let him go Gertrude. +Speake man + + Laer. Where's my Father? + King. Dead + + Qu. But not by him + + King. Let him demand his fill + + Laer. How came he dead? Ile not be Iuggel'd with. +To hell Allegeance: Vowes, to the blackest diuell. +Conscience and Grace, to the profoundest Pit. +I dare Damnation: to this point I stand, +That both the worlds I giue to negligence, +Let come what comes: onely Ile be reueng'd +Most throughly for my Father + + King. Who shall stay you? + Laer. My Will, not all the world, +And for my meanes, Ile husband them so well, +They shall go farre with little + + King. Good Laertes: +If you desire to know the certaintie +Of your deere Fathers death, if writ in your reuenge, +That Soop-stake you will draw both Friend and Foe, +Winner and Looser + + Laer. None but his Enemies + + King. Will you know them then + + La. To his good Friends, thus wide Ile ope my Armes: +And like the kinde Life-rend'ring Politician, +Repast them with my blood + + King. Why now you speake +Like a good Childe, and a true Gentleman. +That I am guiltlesse of your Fathers death, +And am most sensible in greefe for it, +It shall as leuell to your Iudgement pierce +As day do's to your eye. + +A noise within. Let her come in. + +Enter Ophelia. + + Laer. How now? what noise is that? +Oh heate drie vp my Braines, teares seuen times salt, +Burne out the Sence and Vertue of mine eye. +By Heauen, thy madnesse shall be payed by waight, +Till our Scale turnes the beame. Oh Rose of May, +Deere Maid, kinde Sister, sweet Ophelia: +Oh Heauens, is't possible, a yong Maids wits, +Should be as mortall as an old mans life? +Nature is fine in Loue, and where 'tis fine, +It sends some precious instance of it selfe +After the thing it loues + + Ophe. They bore him bare fac'd on the Beer, +Hey non nony, nony, hey nony: +And on his graue raines many a teare, +Fare you well my Doue + + Laer. Had'st thou thy wits, and did'st perswade Reuenge, +it could not moue thus + + Ophe. You must sing downe a-downe, and you call +him a-downe-a. Oh, how the wheele becomes it? It is +the false Steward that stole his masters daughter + + Laer. This nothings more then matter + + Ophe. There's Rosemary, that's for Remembraunce. +Pray loue remember: and there is Paconcies, that's for +Thoughts + + Laer. A document in madnesse, thoughts & remembrance +fitted + + Ophe. There's Fennell for you, and Columbines: ther's +Rew for you, and heere's some for me. Wee may call it +Herbe-Grace a Sundaies: Oh you must weare your Rew +with a difference. There's a Daysie, I would giue you +some Violets, but they wither'd all when my Father dyed: +They say, he made a good end; +For bonny sweet Robin is all my ioy + + Laer. Thought, and Affliction, Passion, Hell it selfe: +She turnes to Fauour, and to prettinesse + + Ophe. And will he not come againe, +And will he not come againe: +No, no, he is dead, go to thy Death-bed, +He neuer wil come againe. +His Beard as white as Snow, +All Flaxen was his Pole: +He is gone, he is gone, and we cast away mone, +Gramercy on his Soule. +And of all Christian Soules, I pray God. +God buy ye. + +Exeunt. Ophelia + + Laer. Do you see this, you Gods? + King. Laertes, I must common with your greefe, +Or you deny me right: go but apart, +Make choice of whom your wisest Friends you will, +And they shall heare and iudge 'twixt you and me; +If by direct or by Colaterall hand +They finde vs touch'd, we will our Kingdome giue, +Our Crowne, our Life, and all that we call Ours +To you in satisfaction. But if not, +Be you content to lend your patience to vs, +And we shall ioyntly labour with your soule +To giue it due content + + Laer. Let this be so: +His meanes of death, his obscure buriall; +No Trophee, Sword, nor Hatchment o're his bones, +No Noble rite, nor formall ostentation, +Cry to be heard, as 'twere from Heauen to Earth, +That I must call in question + + King. So you shall: +And where th' offence is, let the great Axe fall. +I pray you go with me. + +Exeunt. + +Enter Horatio, with an Attendant. + + Hora. What are they that would speake with me? + Ser. Saylors sir, they say they haue Letters for you + + Hor. Let them come in, +I do not know from what part of the world +I should be greeted, if not from Lord Hamlet. +Enter Saylor. + + Say. God blesse you Sir + + Hor. Let him blesse thee too + + Say. Hee shall Sir, and't please him. There's a Letter +for you Sir: It comes from th' Ambassadours that was +bound for England, if your name be Horatio, as I am let +to know it is. + +Reads the Letter. + +Horatio, When thou shalt haue ouerlook'd this, giue these +Fellowes some meanes to the King: They haue Letters +for him. Ere we were two dayes old at Sea, a Pyrate of very +Warlicke appointment gaue vs Chace. Finding our selues too +slow of Saile, we put on a compelled Valour. In the Grapple, I +boorded them: On the instant they got cleare of our Shippe, so +I alone became their Prisoner. They haue dealt with mee, like +Theeues of Mercy, but they knew what they did. I am to doe +a good turne for them. Let the King haue the Letters I haue +sent, and repaire thou to me with as much hast as thou wouldest +flye death. I haue words to speake in your eare, will make thee +dumbe, yet are they much too light for the bore of the Matter. +These good Fellowes will bring thee where I am. Rosincrance +and Guildensterne, hold their course for England. Of them +I haue much to tell thee, Farewell. +He that thou knowest thine, +Hamlet. +Come, I will giue you way for these your Letters, +And do't the speedier, that you may direct me +To him from whom you brought them. +Enter. + +Enter King and Laertes. + + King. Now must your conscience my acquittance seal, +And you must put me in your heart for Friend, +Sith you haue heard, and with a knowing eare, +That he which hath your Noble Father slaine, +Pursued my life + + Laer. It well appeares. But tell me, +Why you proceeded not against these feates, +So crimefull, and so Capitall in Nature, +As by your Safety, Wisedome, all things else, +You mainly were stirr'd vp? + King. O for two speciall Reasons, +Which may to you (perhaps) seeme much vnsinnowed, +And yet to me they are strong. The Queen his Mother, +Liues almost by his lookes: and for my selfe, +My Vertue or my Plague, be it either which, +She's so coniunctiue to my life, and soule; +That as the Starre moues not but in his Sphere, +I could not but by her. The other Motiue, +Why to a publike count I might not go, +Is the great loue the generall gender beare him, +Who dipping all his Faults in their affection, +Would like the Spring that turneth Wood to Stone, +Conuert his Gyues to Graces. So that my Arrowes +Too slightly timbred for so loud a Winde, +Would haue reuerted to my Bow againe, +And not where I had arm'd them + + Laer. And so haue I a Noble Father lost, +A Sister driuen into desperate tearmes, +Who was (if praises may go backe againe) +Stood Challenger on mount of all the Age +For her perfections. But my reuenge will come + + King. Breake not your sleepes for that, +You must not thinke +That we are made of stuffe, so flat, and dull, +That we can let our Beard be shooke with danger, +And thinke it pastime. You shortly shall heare more, +I lou'd your Father, and we loue our Selfe, +And that I hope will teach you to imagine- +Enter a Messenger. + +How now? What Newes? + Mes. Letters my Lord from Hamlet, This to your +Maiesty: this to the Queene + + King. From Hamlet? Who brought them? + Mes. Saylors my Lord they say, I saw them not: +They were giuen me by Claudio, he receiu'd them + + King. Laertes you shall heare them: +Leaue vs. + +Exit Messenger + +High and Mighty, you shall know I am set naked on your +Kingdome. To morrow shall I begge leaue to see your Kingly +Eyes. When I shall (first asking your Pardon thereunto) recount +th' Occasions of my sodaine, and more strange returne. +Hamlet. +What should this meane? Are all the rest come backe? +Or is it some abuse? Or no such thing? + Laer. Know you the hand? + Kin. 'Tis Hamlets Character, naked and in a Postscript +here he sayes alone: Can you aduise me? + Laer. I'm lost in it my Lord; but let him come, +It warmes the very sicknesse in my heart, +That I shall liue and tell him to his teeth; +Thus diddest thou + + Kin. If it be so Laertes, as how should it be so: +How otherwise will you be rul'd by me? + Laer. If so you'l not o'rerule me to a peace + + Kin. To thine owne peace: if he be now return'd, +As checking at his Voyage, and that he meanes +No more to vndertake it; I will worke him +To an exployt now ripe in my Deuice, +Vnder the which he shall not choose but fall; +And for his death no winde of blame shall breath, +But euen his Mother shall vncharge the practice, +And call it accident: Some two Monthes hence +Here was a Gentleman of Normandy, +I'ue seene my selfe, and seru'd against the French, +And they ran well on Horsebacke; but this Gallant +Had witchcraft in't; he grew into his Seat, +And to such wondrous doing brought his Horse, +As had he beene encorps't and demy-Natur'd +With the braue Beast, so farre he past my thought, +That I in forgery of shapes and trickes, +Come short of what he did + + Laer. A Norman was't? + Kin. A Norman + + Laer. Vpon my life Lamound + + Kin. The very same + + Laer. I know him well, he is the Brooch indeed, +And Iemme of all our Nation + + Kin. Hee mad confession of you, +And gaue you such a Masterly report, +For Art and exercise in your defence; +And for your Rapier most especiall, +That he cryed out, t'would be a sight indeed, +If one could match you Sir. This report of his +Did Hamlet so envenom with his Enuy, +That he could nothing doe but wish and begge, +Your sodaine comming ore to play with him; +Now out of this + + Laer. Why out of this, my Lord? + Kin. Laertes was your Father deare to you? +Or are you like the painting of a sorrow, +A face without a heart? + Laer. Why aske you this? + Kin. Not that I thinke you did not loue your Father, +But that I know Loue is begun by Time: +And that I see in passages of proofe, +Time qualifies the sparke and fire of it: +Hamlet comes backe: what would you vndertake, +To show your selfe your Fathers sonne indeed, +More then in words? + Laer. To cut his throat i'th' Church + + Kin. No place indeed should murder Sancturize; +Reuenge should haue no bounds: but good Laertes +Will you doe this, keepe close within your Chamber, +Hamlet return'd, shall know you are come home: +Wee'l put on those shall praise your excellence, +And set a double varnish on the fame +The Frenchman gaue you, bring you in fine together, +And wager on your heads, he being remisse, +Most generous, and free from all contriuing, +Will not peruse the Foiles? So that with ease, +Or with a little shuffling, you may choose +A Sword vnbaited, and in a passe of practice, +Requit him for your Father + + Laer. I will doo't. +And for that purpose Ile annoint my Sword: +I bought an Vnction of a Mountebanke +So mortall, I but dipt a knife in it, +Where it drawes blood, no Cataplasme so rare, +Collected from all Simples that haue Vertue +Vnder the Moone, can saue the thing from death, +That is but scratcht withall: Ile touch my point, +With this contagion, that if I gall him slightly, +It may be death + + Kin. Let's further thinke of this, +Weigh what conuenience both of time and meanes +May fit vs to our shape, if this should faile; +And that our drift looke through our bad performance, +'Twere better not assaid; therefore this Proiect +Should haue a backe or second, that might hold, +If this should blast in proofe: Soft, let me see +Wee'l make a solemne wager on your commings, +I ha't: when in your motion you are hot and dry, +As make your bowts more violent to the end, +And that he cals for drinke; Ile haue prepar'd him +A Challice for the nonce; whereon but sipping, +If he by chance escape your venom'd stuck, +Our purpose may hold there; how sweet Queene. +Enter Queene. + + Queen. One woe doth tread vpon anothers heele, +So fast they'l follow: your Sister's drown'd Laertes + + Laer. Drown'd! O where? + Queen. There is a Willow growes aslant a Brooke, +That shewes his hore leaues in the glassie streame: +There with fantasticke Garlands did she come, +Of Crow-flowers, Nettles, Daysies, and long Purples, +That liberall Shepheards giue a grosser name; +But our cold Maids doe Dead Mens Fingers call them: +There on the pendant boughes, her Coronet weeds +Clambring to hang; an enuious sliuer broke, +When downe the weedy Trophies, and her selfe, +Fell in the weeping Brooke, her cloathes spred wide, +And Mermaid-like, a while they bore her vp, +Which time she chaunted snatches of old tunes, +As one incapable of her owne distresse, +Or like a creature Natiue, and indued +Vnto that Element: but long it could not be, +Till that her garments, heauy with her drinke, +Pul'd the poore wretch from her melodious buy, +To muddy death + + Laer. Alas then, is she drown'd? + Queen. Drown'd, drown'd + + Laer. Too much of water hast thou poore Ophelia, +And therefore I forbid my teares: but yet +It is our tricke, Nature her custome holds, +Let shame say what it will; when these are gone +The woman will be out: Adue my Lord, +I haue a speech of fire, that faine would blaze, +But that this folly doubts it. +Enter. + + Kin. Let's follow, Gertrude: +How much I had to doe to calme his rage? +Now feare I this will giue it start againe; +Therefore let's follow. + +Exeunt. + +Enter two Clownes. + + Clown. Is she to bee buried in Christian buriall, that +wilfully seekes her owne saluation? + Other. I tell thee she is, and therefore make her Graue +straight, the Crowner hath sate on her, and finds it Christian +buriall + + Clo. How can that be, vnlesse she drowned her selfe in +her owne defence? + Other. Why 'tis found so + + Clo. It must be Se offendendo, it cannot bee else: for +heere lies the point; If I drowne my selfe wittingly, it argues +an Act: and an Act hath three branches. It is an +Act to doe and to performe; argall she drown'd her selfe +wittingly + + Other. Nay but heare you Goodman Deluer + + Clown. Giue me leaue; heere lies the water; good: +heere stands the man; good: If the man goe to this water +and drowne himselfe; it is will he nill he, he goes; +marke you that? But if the water come to him & drowne +him; hee drownes not himselfe. Argall, hee that is not +guilty of his owne death, shortens not his owne life + + Other. But is this law? + Clo. I marry is't, Crowners Quest Law + + Other. Will you ha the truth on't: if this had not +beene a Gentlewoman, shee should haue beene buried +out of Christian Buriall + + Clo. Why there thou say'st. And the more pitty that +great folke should haue countenance in this world to +drowne or hang themselues, more then their euen Christian. +Come, my Spade; there is no ancient Gentlemen, +but Gardiners, Ditchers and Graue-makers; they hold vp +Adams Profession + + Other. Was he a Gentleman? + Clo. He was the first that euer bore Armes + + Other. Why he had none + + Clo. What, ar't a Heathen? how doth thou vnderstand +the Scripture? the Scripture sayes Adam dig'd; +could hee digge without Armes? Ile put another question +to thee; if thou answerest me not to the purpose, confesse +thy selfe- + Other. Go too + + Clo. What is he that builds stronger then either the +Mason, the Shipwright, or the Carpenter? + Other. The Gallowes maker; for that Frame outliues a +thousand Tenants + + Clo. I like thy wit well in good faith, the Gallowes +does well; but how does it well? it does well to those +that doe ill: now, thou dost ill to say the Gallowes is +built stronger then the Church: Argall, the Gallowes +may doe well to thee. Too't againe, Come + + Other. Who builds stronger then a Mason, a Shipwright, +or a Carpenter? + Clo. I, tell me that, and vnyoake + + Other. Marry, now I can tell + + Clo. Too't + + Other. Masse, I cannot tell. +Enter Hamlet and Horatio a farre off. + + Clo. Cudgell thy braines no more about it; for your +dull Asse will not mend his pace with beating; and when +you are ask't this question next, say a Graue-maker: the +Houses that he makes, lasts till Doomesday: go, get thee +to Yaughan, fetch me a stoupe of Liquor. + +Sings. + +In youth when I did loue, did loue, +me thought it was very sweete: +To contract O the time for a my behoue, +O me thought there was nothing meete + + Ham. Ha's this fellow no feeling of his businesse, that +he sings at Graue-making? + Hor. Custome hath made it in him a property of easinesse + + Ham. 'Tis ee'n so; the hand of little Imployment hath +the daintier sense + + Clowne sings. But Age with his stealing steps +hath caught me in his clutch: +And hath shipped me intill the Land, +as if I had neuer beene such + + Ham. That Scull had a tongue in it, and could sing +once: how the knaue iowles it to th' grownd, as if it +were Caines Iaw-bone, that did the first murther: It +might be the Pate of a Polititian which this Asse o're Offices: +one that could circumuent God, might it not? + Hor. It might, my Lord + + Ham. Or of a Courtier, which could say, Good Morrow +sweet Lord: how dost thou, good Lord? this +might be my Lord such a one, that prais'd my Lord such +a ones Horse, when he meant to begge it; might it not? + Hor. I, my Lord + + Ham. Why ee'n so: and now my Lady Wormes, +Chaplesse, and knockt about the Mazard with a Sextons +Spade; heere's fine Reuolution, if wee had the tricke to +see't. Did these bones cost no more the breeding, but +to play at Loggets with 'em? mine ake to thinke +on't + + Clowne sings. A Pickhaxe and a Spade, a Spade, +for and a shrowding-Sheete: +O a Pit of Clay for to be made, +for such a Guest is meete + + Ham. There's another: why might not that bee the +Scull of a Lawyer? where be his Quiddits now? his +Quillets? his Cases? his Tenures, and his Tricks? why +doe's he suffer this rude knaue now to knocke him about +the Sconce with a dirty Shouell, and will not tell him of +his Action of Battery? hum. This fellow might be in's +time a great buyer of Land, with his Statutes, his Recognizances, +his Fines, his double Vouchers, his Recoueries: +Is this the fine of his Fines, and the recouery of his Recoueries, +to haue his fine Pate full of fine Dirt? will his +Vouchers vouch him no more of his Purchases, and double +ones too, then the length and breadth of a paire of +Indentures? the very Conueyances of his Lands will +hardly lye in this Boxe; and must the Inheritor himselfe +haue no more? ha? + Hor. Not a iot more, my Lord + + Ham. Is not Parchment made of Sheep-skinnes? + Hor. I my Lord, and of Calue-skinnes too + + Ham. They are Sheepe and Calues that seek out assurance +in that. I will speake to this fellow: whose Graue's +this Sir? + Clo. Mine Sir: +O a Pit of Clay for to be made, +for such a Guest is meete + + Ham. I thinke it be thine indeed: for thou liest in't + + Clo. You lye out on't Sir, and therefore it is not yours: +for my part, I doe not lye in't; and yet it is mine + + Ham. Thou dost lye in't, to be in't and say 'tis thine: +'tis for the dead, not for the quicke, therefore thou +lyest + + Clo. 'Tis a quicke lye Sir, 'twill away againe from me +to you + + Ham. What man dost thou digge it for? + Clo. For no man Sir + + Ham. What woman then? + Clo. For none neither + + Ham. Who is to be buried in't? + Clo. One that was a woman Sir; but rest her Soule, +shee's dead + + Ham. How absolute the knaue is? wee must speake +by the Carde, or equiuocation will vndoe vs: by the +Lord Horatio, these three yeares I haue taken note of it, +the Age is growne so picked, that the toe of the Pesant +comes so neere the heeles of our Courtier, hee galls his +Kibe. How long hast thou been a Graue-maker? + Clo. Of all the dayes i'th' yeare, I came too't that day +that our last King Hamlet o'recame Fortinbras + + Ham. How long is that since? + Clo. Cannot you tell that? euery foole can tell that: +It was the very day, that young Hamlet was borne, hee +that was mad, and sent into England + + Ham. I marry, why was he sent into England? + Clo. Why, because he was mad; hee shall recouer his +wits there; or if he do not, it's no great matter there + + Ham. Why? + Clo. 'Twill not be seene in him, there the men are as +mad as he + + Ham. How came he mad? + Clo. Very strangely they say + + Ham. How strangely? + Clo. Faith e'ene with loosing his wits + + Ham. Vpon what ground? + Clo. Why heere in Denmarke: I haue bin sixeteene +heere, man and Boy thirty yeares + + Ham. How long will a man lie i'th' earth ere he rot? + Clo. Ifaith, if he be not rotten before he die (as we haue +many pocky Coarses now adaies, that will scarce hold +the laying in) he will last you some eight yeare, or nine +yeare. A Tanner will last you nine yeare + + Ham. Why he, more then another? + Clo. Why sir, his hide is so tan'd with his Trade, that +he will keepe out water a great while. And your water, +is a sore Decayer of your horson dead body. Heres a Scull +now: this Scul, has laine in the earth three & twenty years + + Ham. Whose was it? + Clo. A whoreson mad Fellowes it was; +Whose doe you thinke it was? + Ham. Nay, I know not + + Clo. A pestilence on him for a mad Rogue, a pour'd a +Flaggon of Renish on my head once. This same Scull +Sir, this same Scull sir, was Yoricks Scull, the Kings Iester + + Ham. This? + Clo. E'ene that + + Ham. Let me see. Alas poore Yorick, I knew him Horatio, +a fellow of infinite Iest; of most excellent fancy, he +hath borne me on his backe a thousand times: And how +abhorred my Imagination is, my gorge rises at it. Heere +hung those lipps, that I haue kist I know not how oft. +Where be your Iibes now? Your Gambals? Your +Songs? Your flashes of Merriment that were wont to +set the Table on a Rore? No one now to mock your own +Ieering? Quite chopfalne? Now get you to my Ladies +Chamber, and tell her, let her paint an inch thicke, to this +fauour she must come. Make her laugh at that: prythee +Horatio tell me one thing + + Hor. What's that my Lord? + Ham. Dost thou thinke Alexander lookt o'this fashion +i'th' earth? + Hor. E'ene so + + Ham. And smelt so? Puh + + Hor. E'ene so, my Lord + + Ham. To what base vses we may returne Horatio. +Why may not Imagination trace the Noble dust of Alexander, +till he find it stopping a bunghole + + Hor. 'Twere to consider: to curiously to consider so + + Ham. No faith, not a iot. But to follow him thether +with modestie enough, & likeliehood to lead it; as thus. +Alexander died: Alexander was buried: Alexander returneth +into dust; the dust is earth; of earth we make +Lome, and why of that Lome (whereto he was conuerted) +might they not stopp a Beere-barrell? +Imperiall Caesar, dead and turn'd to clay, +Might stop a hole to keepe the winde away. +Oh, that that earth, which kept the world in awe, +Should patch a Wall, t' expell the winters flaw. +But soft, but soft, aside; heere comes the King. +Enter King, Queene, Laertes, and a Coffin, with Lords attendant. + +The Queene, the Courtiers. Who is that they follow, +And with such maimed rites? This doth betoken, +The Coarse they follow, did with disperate hand, +Fore do it owne life; 'twas some Estate. +Couch we a while, and mark + + Laer. What Cerimony else? + Ham. That is Laertes, a very Noble youth: Marke + + Laer. What Cerimony else? + Priest. Her Obsequies haue bin as farre inlarg'd. +As we haue warrantie, her death was doubtfull, +And but that great Command, o're-swaies the order, +She should in ground vnsanctified haue lodg'd, +Till the last Trumpet. For charitable praier, +Shardes, Flints, and Peebles, should be throwne on her: +Yet heere she is allowed her Virgin Rites, +Her Maiden strewments, and the bringing home +Of Bell and Buriall + + Laer. Must there no more be done ? + Priest. No more be done: +We should prophane the seruice of the dead, +To sing sage Requiem, and such rest to her +As to peace-parted Soules + + Laer. Lay her i'th' earth, +And from her faire and vnpolluted flesh, +May Violets spring. I tell thee (churlish Priest) +A Ministring Angell shall my Sister be, +When thou liest howling? + Ham. What, the faire Ophelia? + Queene. Sweets, to the sweet farewell. +I hop'd thou should'st haue bin my Hamlets wife: +I thought thy Bride-bed to haue deckt (sweet Maid) +And not t'haue strew'd thy Graue + + Laer. Oh terrible woer, +Fall ten times trebble, on that cursed head +Whose wicked deed, thy most Ingenious sence +Depriu'd thee of. Hold off the earth a while, +Till I haue caught her once more in mine armes: + +Leaps in the graue. + +Now pile your dust, vpon the quicke, and dead, +Till of this flat a Mountaine you haue made, +To o're top old Pelion, or the skyish head +Of blew Olympus + + Ham. What is he, whose griefes +Beares such an Emphasis? whose phrase of Sorrow +Coniure the wandring Starres, and makes them stand +Like wonder-wounded hearers? This is I, +Hamlet the Dane + + Laer. The deuill take thy soule + + Ham. Thou prai'st not well, +I prythee take thy fingers from my throat; +Sir though I am not Spleenatiue, and rash, +Yet haue I something in me dangerous, +Which let thy wisenesse feare. Away thy hand + + King. Pluck them asunder + + Qu. Hamlet, Hamlet + + Gen. Good my Lord be quiet + + Ham. Why I will fight with him vppon this Theme. +Vntill my eielids will no longer wag + + Qu. Oh my Sonne, what Theame? + Ham. I lou'd Ophelia; fortie thousand Brothers +Could not (with all there quantitie of Loue) +Make vp my summe. What wilt thou do for her? + King. Oh he is mad Laertes, + Qu. For loue of God forbeare him + + Ham. Come show me what thou'lt doe. +Woo't weepe? Woo't fight? Woo't teare thy selfe? +Woo't drinke vp Esile, eate a Crocodile? +Ile doo't. Dost thou come heere to whine; +To outface me with leaping in her Graue? +Be buried quicke with her, and so will I. +And if thou prate of Mountaines; let them throw +Millions of Akers on vs; till our ground +Sindging his pate against the burning Zone, +Make Ossa like a wart. Nay, and thou'lt mouth, +Ile rant as well as thou + + Kin. This is meere Madnesse: +And thus awhile the fit will worke on him: +Anon as patient as the female Doue, +When that her Golden Cuplet are disclos'd; +His silence will sit drooping + + Ham. Heare you Sir: +What is the reason that you vse me thus? +I lou'd you euer; but it is no matter: +Let Hercules himselfe doe what he may, +The Cat will Mew, and Dogge will haue his day. +Enter. + + Kin. I pray you good Horatio wait vpon him, +Strengthen your patience in our last nights speech, +Wee'l put the matter to the present push: +Good Gertrude set some watch ouer your Sonne, +This Graue shall haue a liuing Monument: +An houre of quiet shortly shall we see; +Till then, in patience our proceeding be. + +Exeunt. + +Enter Hamlet and Horatio + + Ham. So much for this Sir; now let me see the other, +You doe remember all the Circumstance + + Hor. Remember it my Lord? + Ham. Sir, in my heart there was a kinde of fighting, +That would not let me sleepe; me thought I lay +Worse then the mutines in the Bilboes, rashly, +(And praise be rashnesse for it) let vs know, +Our indiscretion sometimes serues vs well, +When our deare plots do paule, and that should teach vs, +There's a Diuinity that shapes our ends, +Rough-hew them how we will + + Hor. That is most certaine + + Ham. Vp from my Cabin +My sea-gowne scarft about me in the darke, +Grop'd I to finde out them; had my desire, +Finger'd their Packet, and in fine, withdrew +To mine owne roome againe, making so bold, +(My feares forgetting manners) to vnseale +Their grand Commission, where I found Horatio, +Oh royall knauery: An exact command, +Larded with many seuerall sorts of reason; +Importing Denmarks health, and Englands too, +With hoo, such Bugges and Goblins in my life, +That on the superuize no leasure bated, +No not to stay the grinding of the Axe, +My head should be struck off + + Hor. Ist possible? + Ham. Here's the Commission, read it at more leysure: +But wilt thou heare me how I did proceed? + Hor. I beseech you + + Ham. Being thus benetted round with Villaines, +Ere I could make a Prologue to my braines, +They had begun the Play. I sate me downe, +Deuis'd a new Commission, wrote it faire, +I once did hold it as our Statists doe, +A basenesse to write faire; and laboured much +How to forget that learning: but Sir now, +It did me Yeomans seriuce: wilt thou know +The effects of what I wrote? + Hor. I, good my Lord + + Ham. An earnest Coniuration from the King, +As England was his faithfull Tributary, +As loue betweene them, as the Palme should flourish, +As Peace should still her wheaten Garland weare, +And stand a Comma 'tweene their amities, +And many such like Assis of great charge, +That on the view and know of these Contents, +Without debatement further, more or lesse, +He should the bearers put to sodaine death, +Not shriuing time allowed + + Hor. How was this seal'd? + Ham. Why, euen in that was Heauen ordinate; +I had my fathers Signet in my Purse, +Which was the Modell of that Danish Seale: +Folded the Writ vp in forme of the other, +Subscrib'd it, gau't th' impression, plac't it safely, +The changeling neuer knowne: Now, the next day +Was our Sea Fight, and what to this was sement, +Thou know'st already + + Hor. So Guildensterne and Rosincrance, go too't + + Ham. Why man, they did make loue to this imployment +They are not neere my Conscience; their debate +Doth by their owne insinuation grow: +'Tis dangerous, when the baser nature comes +Betweene the passe, and fell incensed points +Of mighty opposites + + Hor. Why, what a King is this? + Ham. Does it not, thinkst thee, stand me now vpon +He that hath kil'd my King, and whor'd my Mother, +Popt in betweene th' election and my hopes, +Throwne out his Angle for my proper life, +And with such coozenage; is't not perfect conscience, +To quit him with this arme? And is't not to be damn'd +To let this Canker of our nature come +In further euill + + Hor. It must be shortly knowne to him from England +What is the issue of the businesse there + + Ham. It will be short, +The interim's mine, and a mans life's no more +Then to say one: but I am very sorry good Horatio, +That to Laertes I forgot my selfe; +For by the image of my Cause, I see +The Portraiture of his; Ile count his fauours: +But sure the brauery of his griefe did put me +Into a Towring passion + + Hor. Peace, who comes heere? +Enter young Osricke. + + Osr. Your Lordship is right welcome back to Denmarke + + Ham. I humbly thank you Sir, dost know this waterflie? + Hor. No my good Lord + + Ham. Thy state is the more gracious; for 'tis a vice to +know him: he hath much Land, and fertile; let a Beast +be Lord of Beasts, and his Crib shall stand at the Kings +Messe; 'tis a Chowgh; but as I saw spacious in the possession +of dirt + + Osr. Sweet Lord, if your friendship were at leysure, +I should impart a thing to you from his Maiesty + + Ham. I will receiue it with all diligence of spirit; put +your Bonet to his right vse, 'tis for the head + + Osr. I thanke your Lordship, 'tis very hot + + Ham. No, beleeue mee 'tis very cold, the winde is +Northerly + + Osr. It is indifferent cold my Lord indeed + + Ham. Mee thinkes it is very soultry, and hot for my +Complexion + + Osr. Exceedingly, my Lord, it is very soultry, as 'twere +I cannot tell how: but my Lord, his Maiesty bad me signifie +to you, that he ha's laid a great wager on your head: +Sir, this is the matter + + Ham. I beseech you remember + + Osr. Nay, in good faith, for mine ease in good faith: +Sir, you are not ignorant of what excellence Laertes is at +his weapon + + Ham. What's his weapon? + Osr. Rapier and dagger + + Ham. That's two of his weapons; but well + + Osr. The sir King ha's wag'd with him six Barbary horses, +against the which he impon'd as I take it, sixe French +Rapiers and Poniards, with their assignes, as Girdle, +Hangers or so: three of the Carriages infaith are very +deare to fancy, very responsiue to the hilts, most delicate +carriages, and of very liberall conceit + + Ham. What call you the Carriages? + Osr. The Carriages Sir, are the hangers + + Ham. The phrase would bee more Germaine to the +matter: If we could carry Cannon by our sides; I would +it might be Hangers till then; but on sixe Barbary Horses +against sixe French Swords: their Assignes, and three +liberall conceited Carriages, that's the French but against +the Danish; why is this impon'd as you call it? + Osr. The King Sir, hath laid that in a dozen passes betweene +you and him, hee shall not exceed you three hits; +He hath one twelue for mine, and that would come to +imediate tryall, if your Lordship would vouchsafe the +Answere + + Ham. How if I answere no? + Osr. I meane my Lord, the opposition of your person +in tryall + + Ham. Sir, I will walke heere in the Hall; if it please +his Maiestie, 'tis the breathing time of day with me; let +the Foyles bee brought, the Gentleman willing, and the +King hold his purpose; I will win for him if I can: if +not, Ile gaine nothing but my shame, and the odde hits + + Osr. Shall I redeliuer you ee'n so? + Ham. To this effect Sir, after what flourish your nature +will + + Osr. I commend my duty to your Lordship + + Ham. Yours, yours; hee does well to commend it +himselfe, there are no tongues else for's tongue + + Hor. This Lapwing runs away with the shell on his +head + + Ham. He did Complie with his Dugge before hee +suck't it: thus had he and mine more of the same Beauty +that I know the drossie age dotes on; only got the tune of +the time, and outward habite of encounter, a kinde of +yesty collection, which carries them through & through +the most fond and winnowed opinions; and doe but blow +them to their tryalls: the Bubbles are out + + Hor. You will lose this wager, my Lord + + Ham. I doe not thinke so, since he went into France, +I haue beene in continuall practice; I shall winne at the +oddes: but thou wouldest not thinke how all heere about +my heart: but it is no matter + + Hor. Nay, good my Lord + + Ham. It is but foolery; but it is such a kinde of +gain-giuing as would perhaps trouble a woman + + Hor. If your minde dislike any thing, obey. I will forestall +their repaire hither, and say you are not fit + + Ham. Not a whit, we defie Augury; there's a speciall +Prouidence in the fall of a sparrow. If it be now, 'tis not +to come: if it bee not to come, it will bee now: if it +be not now; yet it will come; the readinesse is all, since no +man ha's ought of what he leaues. What is't to leaue betimes? +Enter King, Queene, Laertes and Lords, with other Attendants with +Foyles, +and Gauntlets, a Table and Flagons of Wine on it. + + Kin. Come Hamlet, come, and take this hand from me + + Ham. Giue me your pardon Sir, I'ue done you wrong, +But pardon't as you are a Gentleman. +This presence knowes, +And you must needs haue heard how I am punisht +With sore distraction? What I haue done +That might your nature honour, and exception +Roughly awake, I heere proclaime was madnesse: +Was't Hamlet wrong'd Laertes? Neuer Hamlet. +If Hamlet from himselfe be tane away: +And when he's not himselfe, do's wrong Laertes, +Then Hamlet does it not, Hamlet denies it: +Who does it then? His Madnesse? If't be so, +Hamlet is of the Faction that is wrong'd, +His madnesse is poore Hamlets Enemy. +Sir, in this Audience, +Let my disclaiming from a purpos'd euill, +Free me so farre in your most generous thoughts, +That I haue shot mine Arrow o're the house, +And hurt my Mother + + Laer. I am satisfied in Nature, +Whose motiue in this case should stirre me most +To my Reuenge. But in my termes of Honor +I stand aloofe, and will no reconcilement, +Till by some elder Masters of knowne Honor, +I haue a voyce, and president of peace +To keepe my name vngorg'd. But till that time, +I do receiue your offer'd loue like loue, +And wil not wrong it + + Ham. I do embrace it freely, +And will this Brothers wager frankely play. +Giue vs the Foyles: Come on + + Laer. Come one for me + + Ham. Ile be your foile Laertes, in mine ignorance, +Your Skill shall like a Starre i'th' darkest night, +Sticke fiery off indeede + + Laer. You mocke me Sir + + Ham. No by this hand + + King. Giue them the Foyles yong Osricke, +Cousen Hamlet, you know the wager + + Ham. Verie well my Lord, +Your Grace hath laide the oddes a'th' weaker side + + King. I do not feare it, +I haue seene you both: +But since he is better'd, we haue therefore oddes + + Laer. This is too heauy, +Let me see another + + Ham. This likes me well, +These Foyles haue all a length. + +Prepare to play. + + Osricke. I my good Lord + + King. Set me the Stopes of wine vpon that Table: +If Hamlet giue the first, or second hit, +Or quit in answer of the third exchange, +Let all the Battlements their Ordinance fire, +The King shal drinke to Hamlets better breath, +And in the Cup an vnion shal he throw +Richer then that, which foure successiue Kings +In Denmarkes Crowne haue worne. +Giue me the Cups, +And let the Kettle to the Trumpets speake, +The Trumpet to the Cannoneer without, +The Cannons to the Heauens, the Heauen to Earth, +Now the King drinkes to Hamlet. Come, begin, +And you the Iudges beare a wary eye + + Ham. Come on sir + + Laer. Come on sir. + +They play. + + Ham. One + + Laer. No + + Ham. Iudgement + + Osr. A hit, a very palpable hit + + Laer. Well: againe + + King. Stay, giue me drinke. +Hamlet, this Pearle is thine, +Here's to thy health. Giue him the cup, + +Trumpets sound, and shot goes off. + + Ham. Ile play this bout first, set by a-while. +Come: Another hit; what say you? + Laer. A touch, a touch, I do confesse + + King. Our Sonne shall win + + Qu. He's fat, and scant of breath. +Heere's a Napkin, rub thy browes, +The Queene Carowses to thy fortune, Hamlet + + Ham. Good Madam + + King. Gertrude, do not drinke + + Qu. I will my Lord; +I pray you pardon me + + King. It is the poyson'd Cup, it is too late + + Ham. I dare not drinke yet Madam, +By and by + + Qu. Come, let me wipe thy face + + Laer. My Lord, Ile hit him now + + King. I do not thinke't + + Laer. And yet 'tis almost 'gainst my conscience + + Ham. Come for the third. +Laertes, you but dally, +I pray you passe with your best violence, +I am affear'd you make a wanton of me + + Laer. Say you so? Come on. + +Play. + + Osr. Nothing neither way + + Laer. Haue at you now. + +In scuffling they change Rapiers. + + King. Part them, they are incens'd + + Ham. Nay come, againe + + Osr. Looke to the Queene there hoa + + Hor. They bleed on both sides. How is't my Lord? + Osr. How is't Laertes? + Laer. Why as a Woodcocke +To mine Sprindge, Osricke, +I am iustly kill'd with mine owne Treacherie + + Ham. How does the Queene? + King. She sounds to see them bleede + + Qu. No, no, the drinke, the drinke. +Oh my deere Hamlet, the drinke, the drinke, +I am poyson'd + + Ham. Oh Villany! How? Let the doore be lock'd. +Treacherie, seeke it out + + Laer. It is heere Hamlet. +Hamlet, thou art slaine, +No Medicine in the world can do thee good. +In thee, there is not halfe an houre of life; +The Treacherous Instrument is in thy hand, +Vnbated and envenom'd: the foule practise +Hath turn'd it selfe on me. Loe, heere I lye, +Neuer to rise againe: Thy Mothers poyson'd: +I can no more, the King, the King's too blame + + Ham. The point envenom'd too, +Then venome to thy worke. + +Hurts the King. + + All. Treason, Treason + + King. O yet defend me Friends, I am but hurt + + Ham. Heere thou incestuous, murdrous, +Damned Dane, +Drinke off this Potion: Is thy Vnion heere? +Follow my Mother. + +King Dyes. + + Laer. He is iustly seru'd. +It is a poyson temp'red by himselfe: +Exchange forgiuenesse with me, Noble Hamlet; +Mine and my Fathers death come not vpon thee, +Nor thine on me. + +Dyes. + + Ham. Heauen make thee free of it, I follow thee. +I am dead Horatio, wretched Queene adiew, +You that looke pale, and tremble at this chance, +That are but Mutes or audience to this acte: +Had I but time (as this fell Sergeant death +Is strick'd in his Arrest) oh I could tell you. +But let it be: Horatio, I am dead, +Thou liu'st, report me and my causes right +To the vnsatisfied + + Hor. Neuer beleeue it. +I am more an Antike Roman then a Dane: +Heere's yet some Liquor left + + Ham. As th'art a man, giue me the Cup. +Let go, by Heauen Ile haue't. +Oh good Horatio, what a wounded name, +(Things standing thus vnknowne) shall liue behind me. +If thou did'st euer hold me in thy heart, +Absent thee from felicitie awhile, +And in this harsh world draw thy breath in paine, +To tell my Storie. + +March afarre off, and shout within. + +What warlike noyse is this? +Enter Osricke. + + Osr. Yong Fortinbras, with conquest come fro[m] Poland +To th' Ambassadors of England giues this warlike volly + + Ham. O I dye Horatio: +The potent poyson quite ore-crowes my spirit, +I cannot liue to heare the Newes from England, +But I do prophesie th' election lights +On Fortinbras, he ha's my dying voyce, +So tell him with the occurrents more and lesse, +Which haue solicited. The rest is silence. O, o, o, o. + +Dyes + + Hora. Now cracke a Noble heart: +Goodnight sweet Prince, +And flights of Angels sing thee to thy rest, +Why do's the Drumme come hither? +Enter Fortinbras and English Ambassador, with Drumme, Colours, +and +Attendants. + + Fortin. Where is this sight? + Hor. What is it ye would see; +If ought of woe, or wonder, cease your search + + For. His quarry cries on hauocke. Oh proud death, +What feast is toward in thine eternall Cell. +That thou so many Princes, at a shoote, +So bloodily hast strooke + + Amb. The sight is dismall, +And our affaires from England come too late, +The eares are senselesse that should giue vs hearing, +To tell him his command'ment is fulfill'd, +That Rosincrance and Guildensterne are dead: +Where should we haue our thankes? + Hor. Not from his mouth, +Had it th' abilitie of life to thanke you: +He neuer gaue command'ment for their death. +But since so iumpe vpon this bloodie question, +You from the Polake warres, and you from England +Are heere arriued. Giue order that these bodies +High on a stage be placed to the view, +And let me speake to th' yet vnknowing world, +How these things came about. So shall you heare +Of carnall, bloudie, and vnnaturall acts, +Of accidentall iudgements, casuall slaughters +Of death's put on by cunning, and forc'd cause, +And in this vpshot, purposes mistooke, +Falne on the Inuentors head. All this can I +Truly deliuer + + For. Let vs hast to heare it, +And call the Noblest to the Audience. +For me, with sorrow, I embrace my Fortune, +I haue some Rites of memory in this Kingdome, +Which are to claime, my vantage doth +Inuite me, + Hor. Of that I shall haue alwayes cause to speake, +And from his mouth +Whose voyce will draw on more: +But let this same be presently perform'd, +Euen whiles mens mindes are wilde, +Lest more mischance +On plots, and errors happen + + For. Let foure Captaines +Beare Hamlet like a Soldier to the Stage, +For he was likely, had he beene put on +To haue prou'd most royally: +And for his passage, +The Souldiours Musicke, and the rites of Warre +Speake lowdly for him. +Take vp the body; Such a sight as this +Becomes the Field, but heere shewes much amis. +Go, bid the Souldiers shoote. + +Exeunt. Marching: after the which, a Peale of Ordenance are shot +off. + + +FINIS. The tragedie of HAMLET, Prince of Denmarke. diff --git a/java-strings-2/src/test/java/com/baeldung/string/RemoveStopwordsUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/RemoveStopwordsUnitTest.java new file mode 100644 index 0000000000..edda2ec9d7 --- /dev/null +++ b/java-strings-2/src/test/java/com/baeldung/string/RemoveStopwordsUnitTest.java @@ -0,0 +1,60 @@ +package com.baeldung.string; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.BeforeClass; +import org.junit.Test; + +public class RemoveStopwordsUnitTest { + final String original = "The quick brown fox jumps over the lazy dog"; + final String target = "quick brown fox jumps lazy dog"; + static List stopwords; + + @BeforeClass + public static void loadStopwords() throws IOException { + stopwords = Files.readAllLines(Paths.get("src/main/resources/english_stopwords.txt")); + } + + @Test + public void whenRemoveStopwordsManually_thenSuccess() { + String[] allWords = original.toLowerCase() + .split(" "); + StringBuilder builder = new StringBuilder(); + for (String word : allWords) { + if (!stopwords.contains(word)) { + builder.append(word); + builder.append(' '); + } + } + + String result = builder.toString().trim(); + assertEquals(result, target); + } + + @Test + public void whenRemoveStopwordsUsingRemoveAll_thenSuccess() { + ArrayList allWords = Stream.of(original.toLowerCase() + .split(" ")) + .collect(Collectors.toCollection(ArrayList::new)); + allWords.removeAll(stopwords); + String result = allWords.stream().collect(Collectors.joining(" ")); + assertEquals(result, target); + } + + @Test + public void whenRemoveStopwordsUsingRegex_thenSuccess() { + String stopwordsRegex = stopwords.stream() + .collect(Collectors.joining("|", "\\b(", ")\\b\\s?")); + String result = original.toLowerCase().replaceAll(stopwordsRegex, ""); + assertEquals(result, target); + } + +} From 560e0f7072981ecbda6f6428740a7f013b484f77 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Fri, 17 May 2019 00:15:09 +0530 Subject: [PATCH 062/185] [BAEL-14322] - Updated Spring JDBC Article --- .../spring-persistence-simple/README.md | 1 + .../spring-persistence-simple/pom.xml | 7 +++++++ .../jdbc/CustomSQLErrorCodeTranslator.java | 0 .../main/java/org/baeldung/jdbc/Employee.java | 0 .../java/org/baeldung/jdbc/EmployeeDAO.java | 0 .../org/baeldung/jdbc/EmployeeRowMapper.java | 0 .../jdbc/config/SpringJdbcConfig.java | 0 .../src/main/resources/jdbc/schema.sql | 7 +++++++ .../main/resources/jdbc/springJdbc-config.xml | 19 +++++++++++++++++++ .../src/main/resources/jdbc/test-data.sql | 7 +++++++ .../jdbc/EmployeeDAOIntegrationTest.java | 0 spring-all/README.md | 1 - 12 files changed, 41 insertions(+), 1 deletion(-) rename {spring-all => persistence-modules/spring-persistence-simple}/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java (100%) rename {spring-all => persistence-modules/spring-persistence-simple}/src/main/java/org/baeldung/jdbc/Employee.java (100%) rename {spring-all => persistence-modules/spring-persistence-simple}/src/main/java/org/baeldung/jdbc/EmployeeDAO.java (100%) rename {spring-all => persistence-modules/spring-persistence-simple}/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java (100%) rename {spring-all => persistence-modules/spring-persistence-simple}/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java (100%) create mode 100644 persistence-modules/spring-persistence-simple/src/main/resources/jdbc/schema.sql create mode 100644 persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml create mode 100644 persistence-modules/spring-persistence-simple/src/main/resources/jdbc/test-data.sql rename {spring-all => persistence-modules/spring-persistence-simple}/src/test/java/org/baeldung/jdbc/EmployeeDAOIntegrationTest.java (100%) diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md index c656efaa3b..c408ff3c96 100644 --- a/persistence-modules/spring-persistence-simple/README.md +++ b/persistence-modules/spring-persistence-simple/README.md @@ -11,6 +11,7 @@ - [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring) - [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) - [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) +- [Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate) ### Eclipse Config diff --git a/persistence-modules/spring-persistence-simple/pom.xml b/persistence-modules/spring-persistence-simple/pom.xml index 5f48b267b5..aa9f9d5029 100644 --- a/persistence-modules/spring-persistence-simple/pom.xml +++ b/persistence-modules/spring-persistence-simple/pom.xml @@ -108,6 +108,12 @@ querydsl-apt ${querydsl.version} + + org.hsqldb + hsqldb + ${hsqldb.version} + test + @@ -150,6 +156,7 @@ 9.0.0.M26 1.1 4.2.1 + 2.4.1 21.0 diff --git a/spring-all/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java b/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java rename to persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java diff --git a/spring-all/src/main/java/org/baeldung/jdbc/Employee.java b/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/Employee.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/jdbc/Employee.java rename to persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/Employee.java diff --git a/spring-all/src/main/java/org/baeldung/jdbc/EmployeeDAO.java b/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeDAO.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/jdbc/EmployeeDAO.java rename to persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeDAO.java diff --git a/spring-all/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java b/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java rename to persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java diff --git a/spring-all/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java b/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java similarity index 100% rename from spring-all/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java rename to persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/schema.sql b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/schema.sql new file mode 100644 index 0000000000..c86d35cdae --- /dev/null +++ b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/schema.sql @@ -0,0 +1,7 @@ +CREATE TABLE EMPLOYEE +( + ID int NOT NULL PRIMARY KEY, + FIRST_NAME varchar(255), + LAST_NAME varchar(255), + ADDRESS varchar(255), +); \ No newline at end of file diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml new file mode 100644 index 0000000000..5fd2699b41 --- /dev/null +++ b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/test-data.sql b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/test-data.sql new file mode 100644 index 0000000000..b9ef8fec25 --- /dev/null +++ b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/test-data.sql @@ -0,0 +1,7 @@ +INSERT INTO EMPLOYEE VALUES (1, 'James', 'Gosling', 'Canada'); + +INSERT INTO EMPLOYEE VALUES (2, 'Donald', 'Knuth', 'USA'); + +INSERT INTO EMPLOYEE VALUES (3, 'Linus', 'Torvalds', 'Finland'); + +INSERT INTO EMPLOYEE VALUES (4, 'Dennis', 'Ritchie', 'USA'); \ No newline at end of file diff --git a/spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOIntegrationTest.java b/persistence-modules/spring-persistence-simple/src/test/java/org/baeldung/jdbc/EmployeeDAOIntegrationTest.java similarity index 100% rename from spring-all/src/test/java/org/baeldung/jdbc/EmployeeDAOIntegrationTest.java rename to persistence-modules/spring-persistence-simple/src/test/java/org/baeldung/jdbc/EmployeeDAOIntegrationTest.java diff --git a/spring-all/README.md b/spring-all/README.md index b0805e5477..b5e91d8d60 100644 --- a/spring-all/README.md +++ b/spring-all/README.md @@ -33,5 +33,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring @Primary Annotation](http://www.baeldung.com/spring-primary) - [Spring Events](https://www.baeldung.com/spring-events) - [Spring Null-Safety Annotations](https://www.baeldung.com/spring-null-safety-annotations) -- [Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate) - [Using @Autowired in Abstract Classes](https://www.baeldung.com/spring-autowired-abstract-class) From 31d9ebfa79646651fbbc146fe5fb70608aaf4d2a Mon Sep 17 00:00:00 2001 From: alejandrogervasio Date: Thu, 16 May 2019 20:01:02 -0300 Subject: [PATCH 063/185] Initial Commit --- .../consumermodule/pom.xml | 30 ++++++++++++++++ .../baeldung/consumermodule/Application.java | 13 +++++++ .../src/main/java/module-info.java | 3 ++ .../decoupling-pattern1/pom.xml | 35 +++++++++++++++++++ .../decoupling-pattern1/servicemodule/pom.xml | 24 +++++++++++++ .../servicemodule/external/TextService.java | 7 ++++ .../external/TextServiceFactory.java | 14 ++++++++ .../internal/LowercaseTextService.java | 12 +++++++ .../internal/UppercaseTextService.java | 12 +++++++ .../src/main/java/module-info.java | 3 ++ 10 files changed, 153 insertions(+) create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/module-info.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/pom.xml create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextService.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/module-info.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml new file mode 100644 index 0000000000..4f1a4794c8 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml @@ -0,0 +1,30 @@ + + + 4.0.0 + mainappmodule + jar + 1.0 + + + com.baeldung.decoupling-pattern1 + com.baeldung.decoupling-pattern1 + 1.0 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + + + com.baeldung.servicemodule + servicemodule + 1.0 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java new file mode 100644 index 0000000000..c4b5eed011 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java @@ -0,0 +1,13 @@ +package com.baeldung.consumermodule; + +import com.baeldung.servicemodule.external.TextService; +import com.baeldung.servicemodule.external.TextServiceFactory; + +public class Application { + + public static void main(String args[]) { + TextService textService = TextServiceFactory.getTextService("lowercase"); + System.out.println(textService.processText("Hello from Baeldung!")); + } + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/module-info.java new file mode 100644 index 0000000000..c02e6e6522 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.consumermodule { + requires com.baeldung.servicemodule; +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml new file mode 100644 index 0000000000..282723e0a0 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/pom.xml @@ -0,0 +1,35 @@ + + + 4.0.0 + com.baeldung.decoupling-pattern1 + decoupling-pattern1 + 1.0 + pom + + + servicemodule + consumermodule + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + 11 + + + + + + + + UTF-8 + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/pom.xml new file mode 100644 index 0000000000..1bda70f867 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + com.baeldung.servicemodule + servicemodule + jar + + + com.baeldung.decoupling-pattern1 + decoupling-pattern1 + 1.0 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextService.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextService.java new file mode 100644 index 0000000000..2b9f0dce50 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextService.java @@ -0,0 +1,7 @@ +package com.baeldung.servicemodule.external; + +public interface TextService { + + String processText(String text); + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java new file mode 100644 index 0000000000..4611bc1c8c --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/external/TextServiceFactory.java @@ -0,0 +1,14 @@ +package com.baeldung.servicemodule.external; + +import com.baeldung.servicemodule.internal.LowercaseTextService; +import com.baeldung.servicemodule.internal.UppercaseTextService; + +public class TextServiceFactory { + + private TextServiceFactory() {} + + public static TextService getTextService(String name) { + return name.equalsIgnoreCase("lowercase") ? new LowercaseTextService(): new UppercaseTextService(); + } + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java new file mode 100644 index 0000000000..e2d98f609e --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/LowercaseTextService.java @@ -0,0 +1,12 @@ +package com.baeldung.servicemodule.internal; + +import com.baeldung.servicemodule.external.TextService; + +public class LowercaseTextService implements TextService { + + @Override + public String processText(String text) { + return text.toLowerCase(); + } + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java new file mode 100644 index 0000000000..c94da2a8a5 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/com/baeldung/servicemodule/internal/UppercaseTextService.java @@ -0,0 +1,12 @@ +package com.baeldung.servicemodule.internal; + +import com.baeldung.servicemodule.external.TextService; + +public class UppercaseTextService implements TextService { + + @Override + public String processText(String text) { + return text.toUpperCase(); + } + +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/module-info.java new file mode 100644 index 0000000000..230b659aa9 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/servicemodule/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.servicemodule { + exports com.baeldung.servicemodule.external; +} From d3f7cc19c36d07f36d18649fed324a539aa22797 Mon Sep 17 00:00:00 2001 From: Alejandro Gervasio Date: Thu, 16 May 2019 20:05:47 -0300 Subject: [PATCH 064/185] Update pom.xml --- .../core-java-jpms/decoupling-pattern1/consumermodule/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml index 4f1a4794c8..5dc15ed459 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - mainappmodule + consumermodule jar 1.0 @@ -27,4 +27,4 @@ 1.0 - \ No newline at end of file + From 3dbcaa598d532fc8f422ab894f3dc5f7c6eb2504 Mon Sep 17 00:00:00 2001 From: Alejandro Gervasio Date: Thu, 16 May 2019 20:23:20 -0300 Subject: [PATCH 065/185] Update pom.xml --- .../core-java-jpms/decoupling-pattern1/consumermodule/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml index 5dc15ed459..6a41ec0d1a 100644 --- a/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml +++ b/core-java-modules/core-java-jpms/decoupling-pattern1/consumermodule/pom.xml @@ -7,7 +7,7 @@ com.baeldung.decoupling-pattern1 - com.baeldung.decoupling-pattern1 + decoupling-pattern1 1.0 From 05f7dc662a9b6a896cc8f52424febd75f2895591 Mon Sep 17 00:00:00 2001 From: alejandrogervasio Date: Thu, 16 May 2019 20:40:38 -0300 Subject: [PATCH 066/185] Initial Commit --- .../consumermodule/pom.xml | 38 +++++++++++++++++++ .../baeldung/consumermodule/Application.java | 15 ++++++++ .../src/main/java/module-info.java | 4 ++ .../decoupling-pattern2/pom.xml | 34 +++++++++++++++++ .../providermodule/pom.xml | 34 +++++++++++++++++ .../providermodule/LowercaseTextService.java | 10 +++++ .../src/main/java/module-info.java | 4 ++ .../decoupling-pattern2/servicemodule/pom.xml | 25 ++++++++++++ .../baeldung/servicemodule/TextService.java | 6 +++ .../src/main/java/module-info.java | 3 ++ 10 files changed, 173 insertions(+) create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/module-info.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/module-info.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/pom.xml create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/com/baeldung/servicemodule/TextService.java create mode 100644 core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/module-info.java diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml new file mode 100644 index 0000000000..828fe7de6a --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/pom.xml @@ -0,0 +1,38 @@ + + + + com.baeldung.decoupling-pattern2 + decoupling-pattern2 + 1.0-SNAPSHOT + + 4.0.0 + + com.baeldung.consumermodule + consumermodule + 1.0 + + + + com.baeldung.servicemodule + servicemodule + 1.0 + + + com.baeldung.providermodule + providermodule + 1.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java new file mode 100644 index 0000000000..b9430eb458 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/com/baeldung/consumermodule/Application.java @@ -0,0 +1,15 @@ +package com.baeldung.consumermodule; + +import com.baeldung.servicemodule.TextService; + +import java.util.ServiceLoader; + +public class Application { + + public static void main(String[] args) { + ServiceLoader services = ServiceLoader.load(TextService.class); + for (final TextService service: services) { + System.out.println("The service " + service.getClass().getSimpleName() + " says: " + service.parseText("Hello from Baeldung!")); + } + } +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/module-info.java new file mode 100644 index 0000000000..d8438a7bbc --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/consumermodule/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module com.baeldung.consumermodule { + requires com.baeldung.servicemodule; + uses com.baeldung.servicemodule.TextService; +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml new file mode 100644 index 0000000000..f8c05d40b8 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + com.baeldung.decoupling-pattern2 + decoupling-pattern2 + 1.0-SNAPSHOT + pom + + + servicemodule + providermodule + consumermodule + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + 11 + + + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml new file mode 100644 index 0000000000..ceeda9049c --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/pom.xml @@ -0,0 +1,34 @@ + + + + 4.0.0 + com.baeldung.providermodule + providermodule + 1.0 + + + com.baeldung.decoupling-pattern2 + decoupling-pattern2 + 1.0-SNAPSHOT + + + + + com.baeldung.servicemodule + servicemodule + 1.0 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java new file mode 100644 index 0000000000..51e742e641 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/com/baeldung/providermodule/LowercaseTextService.java @@ -0,0 +1,10 @@ +package com.baeldung.providermodule; + +import com.baeldung.servicemodule.TextService; + +public class LowercaseTextService implements TextService { + @Override + public String parseText(String text) { + return text.toLowerCase(); + } +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/module-info.java new file mode 100644 index 0000000000..1223aa0121 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/providermodule/src/main/java/module-info.java @@ -0,0 +1,4 @@ +module com.baeldung.providermodule { + requires com.baeldung.servicemodule; + provides com.baeldung.servicemodule.TextService with com.baeldung.providermodule.LowercaseTextService; +} \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/pom.xml b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/pom.xml new file mode 100644 index 0000000000..4de3df8c01 --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + >com.baeldung.decoupling-pattern2 + decoupling-pattern2 + 1.0-SNAPSHOT + + + com.baeldung.servicemodule + servicemodule + 1.0 + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + \ No newline at end of file diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/com/baeldung/servicemodule/TextService.java b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/com/baeldung/servicemodule/TextService.java new file mode 100644 index 0000000000..dedbd774ca --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/com/baeldung/servicemodule/TextService.java @@ -0,0 +1,6 @@ +package com.baeldung.servicemodule; + +public interface TextService { + + String parseText(String text); +} diff --git a/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/module-info.java b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/module-info.java new file mode 100644 index 0000000000..dbd70b944b --- /dev/null +++ b/core-java-modules/core-java-jpms/decoupling-pattern2/servicemodule/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.baeldung.servicemodule { + exports com.baeldung.servicemodule; +} \ No newline at end of file From 99f44b344486f1f06efdf87cdc2204dc93a2f21a Mon Sep 17 00:00:00 2001 From: Jacob Stopak Date: Thu, 16 May 2019 22:38:21 -0700 Subject: [PATCH 067/185] Add package demonstrating how to delay code execution in java --- .../main/java/com/baeldung/delay/Delay.java | 95 +++++++++++++++++++ .../com/baeldung/delay/DelayUnitTest.java | 14 +++ 2 files changed, 109 insertions(+) create mode 100644 core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java create mode 100644 core-java-modules/core-java-8-2/src/test/java/com/baeldung/delay/DelayUnitTest.java diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java new file mode 100644 index 0000000000..34d4e0ce85 --- /dev/null +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/delay/Delay.java @@ -0,0 +1,95 @@ +package com.baeldung.delay; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +public class Delay { + + public static void main(String args[]) throws InterruptedException { + + threadSleep(4, 1); + + timeunitSleep(4, 1); + + delayedServiceTask(5); + + fixedRateServiceTask(5); + + System.out.println("Done."); + + return; + + } + + private static void threadSleep(Integer iterations, Integer secondsToSleep) { + + for (Integer i = 0; i < iterations; i++) { + + System.out.println("This is loop iteration number " + i.toString()); + + try { + Thread.sleep(secondsToSleep * 1000); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + + } + + } + + private static void timeunitSleep(Integer iterations, Integer secondsToSleep) { + + for (Integer i = 0; i < iterations; i++) { + + System.out.println("This is loop iteration number " + i.toString()); + + try { + TimeUnit.SECONDS.sleep(secondsToSleep); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + + } + + } + + private static void delayedServiceTask(Integer delayInSeconds) { + + final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + + executorService.schedule(Delay::someTask1, delayInSeconds, TimeUnit.SECONDS); + + } + + private static void fixedRateServiceTask(Integer delayInSeconds) { + + final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + + ScheduledFuture sf = executorService.scheduleAtFixedRate(Delay::someTask2, 0, delayInSeconds, + TimeUnit.SECONDS); + + try { + TimeUnit.SECONDS.sleep(20); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + + sf.cancel(true); + + } + + private static void someTask1() { + System.out.println("Task 1 completed."); + } + + private static void someTask2() { + System.out.println("Task 2 completed."); + } + + public static int main(Boolean isTest) { + return 0; + } + +} \ No newline at end of file diff --git a/core-java-modules/core-java-8-2/src/test/java/com/baeldung/delay/DelayUnitTest.java b/core-java-modules/core-java-8-2/src/test/java/com/baeldung/delay/DelayUnitTest.java new file mode 100644 index 0000000000..5be2fb4b69 --- /dev/null +++ b/core-java-modules/core-java-8-2/src/test/java/com/baeldung/delay/DelayUnitTest.java @@ -0,0 +1,14 @@ +package com.baeldung.delay; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class DelayUnitTest { + + @Test + void givenMain_returnZero() { + assertEquals(Delay.main(true), 0); + } + +} \ No newline at end of file From 7871014656fd60b1cfc10c27152b1d50c094fae7 Mon Sep 17 00:00:00 2001 From: dupirefr Date: Fri, 17 May 2019 07:59:11 +0200 Subject: [PATCH 068/185] Added tests instead of a main method --- core-java-modules/core-java-11/pom.xml | 15 ++++- .../baeldung/predicate/not/FindPeople.java | 33 ---------- .../{AppTest.java => AppUnitTest.java} | 6 +- ...lientTest.java => HttpClientUnitTest.java} | 2 +- ...uestTest.java => HttpRequestUnitTest.java} | 2 +- ...nseTest.java => HttpResponseUnitTest.java} | 2 +- .../predicate/not/PersonUnitTest.java | 61 +++++++++++++++++++ 7 files changed, 79 insertions(+), 42 deletions(-) delete mode 100644 core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java rename core-java-modules/core-java-11/src/test/java/com/baeldung/{AppTest.java => AppUnitTest.java} (82%) rename core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/{HttpClientTest.java => HttpClientUnitTest.java} (99%) rename core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/{HttpRequestTest.java => HttpRequestUnitTest.java} (99%) rename core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/{HttpResponseTest.java => HttpResponseUnitTest.java} (98%) create mode 100644 core-java-modules/core-java-11/src/test/java/com/baeldung/predicate/not/PersonUnitTest.java diff --git a/core-java-modules/core-java-11/pom.xml b/core-java-modules/core-java-11/pom.xml index b78c141552..4d950bdf8d 100644 --- a/core-java-modules/core-java-11/pom.xml +++ b/core-java-modules/core-java-11/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 com.baeldung core-java-11 @@ -12,7 +14,7 @@ com.baeldung parent-modules 1.0.0-SNAPSHOT - ../../ + ../.. @@ -21,6 +23,12 @@ guava ${guava.version} + + org.assertj + assertj-core + ${assertj.version} + test + @@ -41,6 +49,7 @@ 11 11 27.1-jre + 3.11.1 diff --git a/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java b/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java deleted file mode 100644 index 254f648d30..0000000000 --- a/core-java-modules/core-java-11/src/main/java/com/baeldung/predicate/not/FindPeople.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.baeldung.predicate.not; - -import java.util.List; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import static java.util.function.Predicate.*; - -public class FindPeople { - public static void main(String[] args) { - List people = List.of( - new Person(1), - new Person(18), - new Person(2) - ); - - people.stream() - .filter(Person::isAdult) - .collect(Collectors.toList()); - - people.stream() - .filter(person -> !person.isAdult()) - .collect(Collectors.toList()); - - people.stream() - .filter(Person::isNotAdult) - .collect(Collectors.toList()); - - people.stream() - .filter(not(Person::isAdult)) - .collect(Collectors.toList()); - } -} diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/AppTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/AppUnitTest.java similarity index 82% rename from core-java-modules/core-java-11/src/test/java/com/baeldung/AppTest.java rename to core-java-modules/core-java-11/src/test/java/com/baeldung/AppUnitTest.java index c9f61455bd..73eb8e661a 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/AppTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/AppUnitTest.java @@ -7,7 +7,7 @@ import junit.framework.TestSuite; /** * Unit test for simple App. */ -public class AppTest +public class AppUnitTest extends TestCase { /** @@ -15,7 +15,7 @@ public class AppTest * * @param testName name of the test case */ - public AppTest( String testName ) + public AppUnitTest(String testName ) { super( testName ); } @@ -25,7 +25,7 @@ public class AppTest */ public static Test suite() { - return new TestSuite( AppTest.class ); + return new TestSuite( AppUnitTest.class ); } /** diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientUnitTest.java similarity index 99% rename from core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientTest.java rename to core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientUnitTest.java index 0e9c12675c..42f56838c4 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpClientUnitTest.java @@ -32,7 +32,7 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.Test; -public class HttpClientTest { +public class HttpClientUnitTest { @Test public void shouldReturnSampleDataContentWhenConnectViaSystemProxy() throws IOException, InterruptedException, URISyntaxException { diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestUnitTest.java similarity index 99% rename from core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestTest.java rename to core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestUnitTest.java index 274d3a93fc..b87e6b3c6e 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpRequestUnitTest.java @@ -19,7 +19,7 @@ import java.time.Duration; import org.junit.Test; -public class HttpRequestTest { +public class HttpRequestUnitTest { @Test public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException { diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseUnitTest.java similarity index 98% rename from core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseTest.java rename to core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseUnitTest.java index abbc0233c1..a5cfc3f6b1 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/java11/httpclient/test/HttpResponseUnitTest.java @@ -14,7 +14,7 @@ import java.net.http.HttpResponse; import org.junit.Test; -public class HttpResponseTest { +public class HttpResponseUnitTest { @Test public void shouldReturnStatusOKWhenSendGetRequest() throws IOException, InterruptedException, URISyntaxException { diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/predicate/not/PersonUnitTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/predicate/not/PersonUnitTest.java new file mode 100644 index 0000000000..a4989287be --- /dev/null +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/predicate/not/PersonUnitTest.java @@ -0,0 +1,61 @@ +package com.baeldung.predicate.not; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.function.Predicate.not; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class PersonUnitTest { + private List people; + + @BeforeEach + void preparePeople() { + people = Arrays.asList( + new Person(1), + new Person(18), + new Person(2) + ); + } + + @Test + void givenPeople_whenFilterIsAdult_thenOneResult() { + List adults = people.stream() + .filter(Person::isAdult) + .collect(Collectors.toList()); + + assertThat(adults).size().isEqualTo(1); + } + + @Test + void givenPeople_whenFilterIsAdultNegated_thenTwoResults() { + List nonAdults = people.stream() + .filter(person -> !person.isAdult()) + .collect(Collectors.toList()); + + assertThat(nonAdults).size().isEqualTo(2); + } + + @Test + void givenPeople_whenFilterIsNotAdult_thenTwoResults() { + List nonAdults = people.stream() + .filter(Person::isNotAdult) + .collect(Collectors.toList()); + + assertThat(nonAdults).size().isEqualTo(2); + } + + @Test + void givenPeople_whenFilterNotIsAdult_thenTwoResults() { + List nonAdults = people.stream() + .filter(not(Person::isAdult)) + .collect(Collectors.toList()); + + assertThat(nonAdults).size().isEqualTo(2); + } +} \ No newline at end of file From d143f54a51dcefe1bbb7f3f1b7821a0356faad2a Mon Sep 17 00:00:00 2001 From: Pavan Shankar Koli Date: Sat, 18 May 2019 08:29:00 +0530 Subject: [PATCH 069/185] BAEL-2886 Updated Integration test cases --- .../SpringSessionMongoDBIntegrationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java index 24cf50f18d..eb9f4164a6 100644 --- a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java +++ b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java @@ -35,8 +35,8 @@ public class SpringSessionMongoDBIntegrationTest { repository.findById(getSessionId(set_cookie)).getAttribute("count").toString()); } - private String getSessionId(String set_cookie) { - return new String(Base64.getDecoder().decode(set_cookie.split(";")[0].split("=")[1])); + private String getSessionId(String cookie) { + return new String(Base64.getDecoder().decode(cookie.split(";")[0].split("=")[1])); } } From 608db42334c844b1b503bde30d9423423ec840b2 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Sat, 18 May 2019 19:24:25 +1000 Subject: [PATCH 070/185] BAEL-2878 Guide to Spring's ApplicationContextRunner --- .../service/CustomService.java | 10 +++ .../service/DefaultService.java | 10 +++ .../service/SimpleService.java | 7 ++ .../ConditionalOnBeanTest.java | 77 +++++++++++++++++++ .../ConditionalOnClassTest.java | 76 ++++++++++++++++++ .../ConditionalOnPropertyTest.java | 64 +++++++++++++++ .../ConditionalOnPropertyTest.properties | 1 + 7 files changed, 245 insertions(+) create mode 100644 spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/CustomService.java create mode 100644 spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/DefaultService.java create mode 100644 spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/SimpleService.java create mode 100644 spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java create mode 100644 spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java create mode 100644 spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java create mode 100644 spring-boot-autoconfiguration/src/test/resources/ConditionalOnPropertyTest.properties diff --git a/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/CustomService.java b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/CustomService.java new file mode 100644 index 0000000000..634e49fed3 --- /dev/null +++ b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/CustomService.java @@ -0,0 +1,10 @@ +package com.baeldung.autoconfiguration.service; + +public class CustomService implements SimpleService { + + @Override + public String serve() { + return "Custom Service"; + } + +} diff --git a/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/DefaultService.java b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/DefaultService.java new file mode 100644 index 0000000000..ee91bcb051 --- /dev/null +++ b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/DefaultService.java @@ -0,0 +1,10 @@ +package com.baeldung.autoconfiguration.service; + +public class DefaultService implements SimpleService { + + @Override + public String serve() { + return "Default Service"; + } + +} diff --git a/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/SimpleService.java b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/SimpleService.java new file mode 100644 index 0000000000..b6c72d7159 --- /dev/null +++ b/spring-boot-autoconfiguration/src/main/java/com/baeldung/autoconfiguration/service/SimpleService.java @@ -0,0 +1,7 @@ +package com.baeldung.autoconfiguration.service; + +public interface SimpleService { + + public String serve(); + +} diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java new file mode 100644 index 0000000000..313d1253c5 --- /dev/null +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanTest.java @@ -0,0 +1,77 @@ +package com.baeldung.autoconfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +public class ConditionalOnBeanTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + + @Test + public void whenDependentBeanIsPresent_thenConditionalBeanCreated() { + this.contextRunner.withUserConfiguration(basicConfiguration.class, ConditionalOnBeanConfiguration.class) + .run((context) -> { + assertThat(context).hasBean("created"); + assertThat(context).getBean("created") + .isEqualTo("This is always created"); + assertThat(context).hasBean("createOnBean"); + assertThat(context).getBean("createOnBean") + .isEqualTo("This is created when bean (name=created) is present"); + }); + } + + @Test + public void whenDependentBeanIsPresent_thenConditionalMissingBeanIgnored() { + this.contextRunner.withUserConfiguration(basicConfiguration.class, ConditionalOnMissingBeanConfiguration.class) + .run((context) -> { + assertThat(context).hasBean("created"); + assertThat(context).getBean("created") + .isEqualTo("This is always created"); + assertThat(context).doesNotHaveBean("createOnMissingBean"); + }); + } + + @Test + public void whenDependentBeanIsNotPresent_thenConditionalMissingBeanCreated() { + this.contextRunner.withUserConfiguration(ConditionalOnMissingBeanConfiguration.class) + .run((context) -> { + assertThat(context).hasBean("createOnMissingBean"); + assertThat(context).getBean("createOnMissingBean") + .isEqualTo("This is created when bean (name=created) is missing"); + assertThat(context).doesNotHaveBean("created"); + }); + } + + @Configuration + protected static class basicConfiguration { + @Bean + public String created() { + return "This is always created"; + } + } + + @Configuration + @ConditionalOnBean(name = "created") + protected static class ConditionalOnBeanConfiguration { + @Bean + public String createOnBean() { + return "This is created when bean (name=created) is present"; + } + } + + @Configuration + @ConditionalOnMissingBean(name = "created") + protected static class ConditionalOnMissingBeanConfiguration { + @Bean + public String createOnMissingBean() { + return "This is created when bean (name=created) is missing"; + } + } + +} diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java new file mode 100644 index 0000000000..7f01ea85d4 --- /dev/null +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnClassTest.java @@ -0,0 +1,76 @@ +package com.baeldung.autoconfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +public class ConditionalOnClassTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + + @Test + public void whenDependentClassIsPresent_thenBeanCreated() { + this.contextRunner.withUserConfiguration(ConditionalOnClassConfiguration.class) + .run(context -> { + assertThat(context).hasBean("created"); + assertThat(context.getBean("created")).isEqualTo("This is created when ConditionalOnClassTest is present on the classpath"); + }); + } + + @Test + public void whenDependentClassIsPresent_thenBeanMissing() { + this.contextRunner.withUserConfiguration(ConditionalOnMissingClassConfiguration.class) + .run(context -> { + assertThat(context).doesNotHaveBean("missed"); + }); + } + + @Test + public void whenDependentClassIsNotPresent_thenBeanMissing() { + this.contextRunner.withUserConfiguration(ConditionalOnClassConfiguration.class) + .withClassLoader(new FilteredClassLoader(ConditionalOnClassTest.class)) + .run((context) -> { + assertThat(context).doesNotHaveBean("created"); + assertThat(context).doesNotHaveBean(ConditionalOnClassTest.class); + + }); + } + + @Test + public void whenDependentClassIsNotPresent_thenBeanCreated() { + this.contextRunner.withUserConfiguration(ConditionalOnMissingClassConfiguration.class) + .withClassLoader(new FilteredClassLoader(ConditionalOnClassTest.class)) + .run((context) -> { + assertThat(context).hasBean("missed"); + assertThat(context).getBean("missed") + .isEqualTo("This is missed when ConditionalOnClassTest is present on the classpath"); + assertThat(context).doesNotHaveBean(ConditionalOnClassTest.class); + + }); + } + + @Configuration + @ConditionalOnClass(ConditionalOnClassTest.class) + protected static class ConditionalOnClassConfiguration { + @Bean + public String created() { + return "This is created when ConditionalOnClassTest is present on the classpath"; + } + } + + @Configuration + @ConditionalOnMissingClass("com.baeldung.autoconfiguration.ConditionalOnClassTest") + protected static class ConditionalOnMissingClassConfiguration { + @Bean + public String missed() { + return "This is missed when ConditionalOnClassTest is present on the classpath"; + } + } + +} diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java new file mode 100644 index 0000000000..2c09b72dda --- /dev/null +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnPropertyTest.java @@ -0,0 +1,64 @@ +package com.baeldung.autoconfiguration; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.TestPropertySource; + +import com.baeldung.autoconfiguration.service.CustomService; +import com.baeldung.autoconfiguration.service.DefaultService; +import com.baeldung.autoconfiguration.service.SimpleService; + +public class ConditionalOnPropertyTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + + @Test + public void whenGivenCustomPropertyValue_thenCustomServiceCreated() { + this.contextRunner.withPropertyValues("com.baeldung.service=custom") + .withUserConfiguration(SimpleServiceConfiguration.class) + .run(context -> { + assertThat(context).hasBean("customService"); + SimpleService simpleService = context.getBean(CustomService.class); + assertThat(simpleService.serve()).isEqualTo("Custom Service"); + assertThat(context).doesNotHaveBean("defaultService"); + }); + } + + @Test + public void whenGivenDefaultPropertyValue_thenDefaultServiceCreated() { + this.contextRunner.withPropertyValues("com.baeldung.service=default") + .withUserConfiguration(SimpleServiceConfiguration.class) + .run(context -> { + assertThat(context).hasBean("defaultService"); + SimpleService simpleService = context.getBean(DefaultService.class); + assertThat(simpleService.serve()).isEqualTo("Default Service"); + assertThat(context).doesNotHaveBean("customService"); + }); + } + + @Configuration + @TestPropertySource("classpath:ConditionalOnPropertyTest.properties") + protected static class SimpleServiceConfiguration { + + @Bean + @ConditionalOnProperty(name = "com.baeldung.service", havingValue = "default") + @ConditionalOnMissingBean + public DefaultService defaultService() { + return new DefaultService(); + } + + @Bean + @ConditionalOnProperty(name = "com.baeldung.service", havingValue = "custom") + @ConditionalOnMissingBean + public CustomService customService() { + return new CustomService(); + } + } + +} diff --git a/spring-boot-autoconfiguration/src/test/resources/ConditionalOnPropertyTest.properties b/spring-boot-autoconfiguration/src/test/resources/ConditionalOnPropertyTest.properties new file mode 100644 index 0000000000..b6334bc1ce --- /dev/null +++ b/spring-boot-autoconfiguration/src/test/resources/ConditionalOnPropertyTest.properties @@ -0,0 +1 @@ +com.baeldung.service=custom \ No newline at end of file From cbac5e3e765a706c5739d9ea66d69b695d7301ab Mon Sep 17 00:00:00 2001 From: Loredana Date: Sat, 18 May 2019 15:34:01 +0300 Subject: [PATCH 071/185] BAEL-12937 --- .../spring-persistence-simple/pom.xml | 13 ------------- .../baeldung/config/PersistenceConfig.java | 10 +++++----- .../baeldung/config/PersistenceJPAConfig.java | 8 ++++---- .../dao/impl => hibernate/dao}/FooDao.java | 6 +++--- .../baeldung/jdbc/CustomSQLErrorCodeTranslator.java | 4 ++-- .../java/{org => com}/baeldung/jdbc/Employee.java | 2 +- .../{org => com}/baeldung/jdbc/EmployeeDAO.java | 2 +- .../baeldung/jdbc/EmployeeRowMapper.java | 2 +- .../baeldung/jdbc/config/SpringJdbcConfig.java | 6 +++--- .../baeldung/jpa}/dao/AbstractJpaDAO.java | 2 +- .../baeldung/jpa}/dao/FooDao.java | 4 ++-- .../baeldung/jpa}/dao/IFooDao.java | 4 ++-- .../persistence/dao/common/GenericJpaDao.java | 3 ++- .../baeldung/persistence/model/Bar.java | 2 +- .../baeldung/persistence/model/Foo.java | 2 +- .../baeldung/persistence/service/FooService.java | 6 +++--- .../data/persistence/config/PersistenceConfig.java | 8 ++++---- .../spring/data/persistence/dao/IFooDao.java | 4 ++-- .../data/persistence/dao/user/UserRepository.java | 4 ++-- .../persistence/dao/user/UserRepositoryCustom.java | 4 ++-- .../dao/user/UserRepositoryCustomImpl.java | 4 ++-- .../baeldung/spring/data/persistence/model/Foo.java | 2 +- .../spring/data/persistence/model/Possession.java | 2 +- .../spring/data/persistence/model/User.java | 2 +- .../data/persistence/service/IFooService.java | 4 ++-- .../persistence/service/common/AbstractService.java | 2 +- .../data/persistence/service/impl/FooService.java | 10 +++++----- .../java/{org => com}/baeldung/util/IDUtil.java | 2 +- .../src/main/resources/jdbc/springJdbc-config.xml | 2 +- .../src/main/resources/persistence.xml | 2 +- .../main/resources/springDataPersistenceConfig.xml | 2 +- .../baeldung/jdbc/EmployeeDAOIntegrationTest.java | 4 ++-- .../FooPaginationPersistenceIntegrationTest.java | 6 +++--- .../FooServicePersistenceIntegrationTest.java | 6 +++--- .../service/FooServiceSortingIntegrationTest.java | 8 ++++---- ...ServiceSortingWitNullsManualIntegrationTest.java | 6 +++--- .../service/FooStoredProceduresLiveTest.java | 6 +++--- .../persistence/dao/user/UserRepositoryCommon.java | 6 +++--- .../dao/user/UserRepositoryIntegrationTest.java | 6 +++--- .../AbstractServicePersistenceIntegrationTest.java | 6 +++--- .../FooServicePersistenceIntegrationTest.java | 6 +++--- 41 files changed, 89 insertions(+), 101 deletions(-) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/config/PersistenceConfig.java (93%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/config/PersistenceJPAConfig.java (93%) rename persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/{persistence/dao/impl => hibernate/dao}/FooDao.java (69%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/jdbc/CustomSQLErrorCodeTranslator.java (88%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/jdbc/Employee.java (96%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/jdbc/EmployeeDAO.java (99%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/jdbc/EmployeeRowMapper.java (95%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/jdbc/config/SpringJdbcConfig.java (84%) rename persistence-modules/spring-persistence-simple/src/main/java/{org/baeldung/persistence => com/baeldung/jpa}/dao/AbstractJpaDAO.java (96%) rename persistence-modules/spring-persistence-simple/src/main/java/{org/baeldung/persistence => com/baeldung/jpa}/dao/FooDao.java (73%) rename persistence-modules/spring-persistence-simple/src/main/java/{org/baeldung/persistence => com/baeldung/jpa}/dao/IFooDao.java (74%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/persistence/model/Bar.java (98%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/persistence/model/Foo.java (98%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/persistence/service/FooService.java (81%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/config/PersistenceConfig.java (93%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/dao/IFooDao.java (77%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/dao/user/UserRepository.java (97%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java (72%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java (94%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/model/Foo.java (96%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/model/Possession.java (97%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/model/User.java (98%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/service/IFooService.java (58%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/service/common/AbstractService.java (95%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/spring/data/persistence/service/impl/FooService.java (70%) rename persistence-modules/spring-persistence-simple/src/main/java/{org => com}/baeldung/util/IDUtil.java (96%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/jdbc/EmployeeDAOIntegrationTest.java (98%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/persistence/service/FooPaginationPersistenceIntegrationTest.java (97%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/persistence/service/FooServicePersistenceIntegrationTest.java (94%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/persistence/service/FooServiceSortingIntegrationTest.java (96%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/persistence/service/FooServiceSortingWitNullsManualIntegrationTest.java (94%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/persistence/service/FooStoredProceduresLiveTest.java (97%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/spring/data/persistence/dao/user/UserRepositoryCommon.java (99%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/spring/data/persistence/dao/user/UserRepositoryIntegrationTest.java (89%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/spring/data/persistence/service/AbstractServicePersistenceIntegrationTest.java (98%) rename persistence-modules/spring-persistence-simple/src/test/java/{org => com}/baeldung/spring/data/persistence/service/FooServicePersistenceIntegrationTest.java (93%) diff --git a/persistence-modules/spring-persistence-simple/pom.xml b/persistence-modules/spring-persistence-simple/pom.xml index aa9f9d5029..1afacab164 100644 --- a/persistence-modules/spring-persistence-simple/pom.xml +++ b/persistence-modules/spring-persistence-simple/pom.xml @@ -18,12 +18,6 @@ org.springframework spring-orm ${org.springframework.version} - - - commons-logging - commons-logging - - org.springframework @@ -108,12 +102,6 @@ querydsl-apt ${querydsl.version} - - org.hsqldb - hsqldb - ${hsqldb.version} - test - @@ -156,7 +144,6 @@ 9.0.0.M26 1.1 4.2.1 - 2.4.1 21.0 diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceConfig.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceConfig.java similarity index 93% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceConfig.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceConfig.java index c454ab3b54..569971e311 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceConfig.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceConfig.java @@ -1,11 +1,10 @@ -package org.baeldung.config; +package com.baeldung.config; import java.util.Properties; import javax.sql.DataSource; import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; -import org.baeldung.persistence.dao.IFooDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -24,15 +23,16 @@ import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; -import com.baeldung.persistence.dao.impl.FooDao; +import com.baeldung.hibernate.dao.FooDao; +import com.baeldung.jpa.dao.IFooDao; import com.google.common.base.Preconditions; @Configuration @EnableTransactionManagement -@EnableJpaRepositories(basePackages = { "com.baeldung.persistence" }, transactionManagerRef = "jpaTransactionManager") +@EnableJpaRepositories(basePackages = { "com.baeldung.hibernate.dao" }, transactionManagerRef = "jpaTransactionManager") @EnableJpaAuditing @PropertySource({ "classpath:persistence-mysql.properties" }) -@ComponentScan({ "com.baeldung.persistence" }) +@ComponentScan({ "com.baeldung.persistence", "com.baeldung.hibernate.dao" }) public class PersistenceConfig { @Autowired diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceJPAConfig.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceJPAConfig.java similarity index 93% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceJPAConfig.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceJPAConfig.java index ec0d4bca3c..9fae34d99e 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/config/PersistenceJPAConfig.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/config/PersistenceJPAConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.config; +package com.baeldung.config; import java.util.Properties; @@ -25,8 +25,8 @@ import com.google.common.base.Preconditions; @Configuration @EnableTransactionManagement @PropertySource({ "classpath:persistence-h2.properties" }) -@ComponentScan({ "org.baeldung.persistence" }) -@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao") +@ComponentScan({ "com.baeldung.persistence","com.baeldung.jpa.dao" }) +@EnableJpaRepositories(basePackages = "com.baeldung.jpa.dao") public class PersistenceJPAConfig { @Autowired @@ -42,7 +42,7 @@ public class PersistenceJPAConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" }); + em.setPackagesToScan(new String[] { "com.baeldung.persistence.model" }); final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/impl/FooDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/dao/FooDao.java similarity index 69% rename from persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/impl/FooDao.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/dao/FooDao.java index 2d940527e1..67c10fe7fe 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/impl/FooDao.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/hibernate/dao/FooDao.java @@ -1,9 +1,9 @@ -package com.baeldung.persistence.dao.impl; +package com.baeldung.hibernate.dao; -import org.baeldung.persistence.dao.IFooDao; -import org.baeldung.persistence.model.Foo; +import com.baeldung.persistence.model.Foo; import org.springframework.stereotype.Repository; +import com.baeldung.jpa.dao.IFooDao; import com.baeldung.persistence.dao.common.AbstractHibernateDao; @Repository diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/CustomSQLErrorCodeTranslator.java similarity index 88% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/CustomSQLErrorCodeTranslator.java index 8a02fe6a53..48ddfb04b1 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/CustomSQLErrorCodeTranslator.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/CustomSQLErrorCodeTranslator.java @@ -1,4 +1,4 @@ -package org.baeldung.jdbc; +package com.baeldung.jdbc; import java.sql.SQLException; @@ -10,7 +10,7 @@ public class CustomSQLErrorCodeTranslator extends SQLErrorCodeSQLExceptionTransl @Override protected DataAccessException customTranslate(final String task, final String sql, final SQLException sqlException) { - if (sqlException.getErrorCode() == -104) { + if (sqlException.getErrorCode() == 23505) { return new DuplicateKeyException("Custome Exception translator - Integrity contraint voilation.", sqlException); } return null; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/Employee.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/Employee.java similarity index 96% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/Employee.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/Employee.java index e9408eb7fa..a43eb265c7 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/Employee.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/Employee.java @@ -1,4 +1,4 @@ -package org.baeldung.jdbc; +package com.baeldung.jdbc; public class Employee { private int id; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeDAO.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeDAO.java similarity index 99% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeDAO.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeDAO.java index 1f0e7b28ad..9ba4ebdb6d 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeDAO.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeDAO.java @@ -1,4 +1,4 @@ -package org.baeldung.jdbc; +package com.baeldung.jdbc; import java.sql.PreparedStatement; import java.sql.SQLException; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeRowMapper.java similarity index 95% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeRowMapper.java index f926836c40..d09cd45dbc 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/EmployeeRowMapper.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/EmployeeRowMapper.java @@ -1,4 +1,4 @@ -package org.baeldung.jdbc; +package com.baeldung.jdbc; import java.sql.ResultSet; import java.sql.SQLException; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/config/SpringJdbcConfig.java similarity index 84% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/config/SpringJdbcConfig.java index f7eb592366..ddc24e439f 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/jdbc/config/SpringJdbcConfig.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jdbc/config/SpringJdbcConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.jdbc.config; +package com.baeldung.jdbc.config; import javax.sql.DataSource; @@ -10,12 +10,12 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; @Configuration -@ComponentScan("org.baeldung.jdbc") +@ComponentScan("com.baeldung.jdbc") public class SpringJdbcConfig { @Bean public DataSource dataSource() { - return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("classpath:jdbc/schema.sql").addScript("classpath:jdbc/test-data.sql").build(); + return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).addScript("classpath:jdbc/schema.sql").addScript("classpath:jdbc/test-data.sql").build(); } // @Bean diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/AbstractJpaDAO.java similarity index 96% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/AbstractJpaDAO.java index decca35c08..4fbc8464bb 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/AbstractJpaDAO.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/AbstractJpaDAO.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.dao; +package com.baeldung.jpa.dao; import java.io.Serializable; import java.util.List; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/FooDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/FooDao.java similarity index 73% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/FooDao.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/FooDao.java index 77978c5cf2..e79a44a0c2 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/FooDao.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/FooDao.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.dao; +package com.baeldung.jpa.dao; -import org.baeldung.persistence.model.Foo; +import com.baeldung.persistence.model.Foo; import org.springframework.stereotype.Repository; @Repository diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/IFooDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/IFooDao.java similarity index 74% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/IFooDao.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/IFooDao.java index ba188b9b3a..8140c56edd 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/dao/IFooDao.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/jpa/dao/IFooDao.java @@ -1,8 +1,8 @@ -package org.baeldung.persistence.dao; +package com.baeldung.jpa.dao; import java.util.List; -import org.baeldung.persistence.model.Foo; +import com.baeldung.persistence.model.Foo; public interface IFooDao { diff --git a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/GenericJpaDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/GenericJpaDao.java index 5bcebed761..d4da194f4d 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/GenericJpaDao.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/dao/common/GenericJpaDao.java @@ -2,11 +2,12 @@ package com.baeldung.persistence.dao.common; import java.io.Serializable; -import org.baeldung.persistence.dao.AbstractJpaDAO; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Repository; +import com.baeldung.jpa.dao.AbstractJpaDAO; + @Repository @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class GenericJpaDao extends AbstractJpaDAO implements IGenericDao { diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Bar.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Bar.java similarity index 98% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Bar.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Bar.java index b602e57562..5a88ecc6cf 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Bar.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Bar.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package com.baeldung.persistence.model; import java.io.Serializable; import java.util.List; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Foo.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Foo.java similarity index 98% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Foo.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Foo.java index 30635e9ef2..009876f8cb 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/model/Foo.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/model/Foo.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package com.baeldung.persistence.model; import java.io.Serializable; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/service/FooService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/service/FooService.java similarity index 81% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/service/FooService.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/service/FooService.java index 6d1bb0adbe..efe9743670 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/persistence/service/FooService.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/persistence/service/FooService.java @@ -1,9 +1,9 @@ -package org.baeldung.persistence.service; +package com.baeldung.persistence.service; import java.util.List; -import org.baeldung.persistence.dao.IFooDao; -import org.baeldung.persistence.model.Foo; +import com.baeldung.jpa.dao.IFooDao; +import com.baeldung.persistence.model.Foo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/config/PersistenceConfig.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/config/PersistenceConfig.java similarity index 93% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/config/PersistenceConfig.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/config/PersistenceConfig.java index 067bac2018..717b9c3aa0 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/config/PersistenceConfig.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/config/PersistenceConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.data.persistence.config; +package com.baeldung.spring.data.persistence.config; import java.util.Properties; @@ -24,9 +24,9 @@ import com.google.common.base.Preconditions; @Configuration @EnableTransactionManagement @PropertySource({ "classpath:persistence-${envTarget:h2}.properties" }) -@ComponentScan({ "org.baeldung.spring.data.persistence" }) +@ComponentScan({ "com.baeldung.spring.data.persistence" }) // @ImportResource("classpath*:springDataPersistenceConfig.xml") -@EnableJpaRepositories(basePackages = "org.baeldung.spring.data.persistence.dao") +@EnableJpaRepositories(basePackages = "com.baeldung.spring.data.persistence.dao") public class PersistenceConfig { @Autowired @@ -40,7 +40,7 @@ public class PersistenceConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.spring.data.persistence.model" }); + em.setPackagesToScan(new String[] { "com.baeldung.spring.data.persistence.model" }); final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); // vendorAdapter.set diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/IFooDao.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/IFooDao.java similarity index 77% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/IFooDao.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/IFooDao.java index 2f74096e14..d2b746dc8b 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/IFooDao.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/IFooDao.java @@ -1,6 +1,6 @@ -package org.baeldung.spring.data.persistence.dao; +package com.baeldung.spring.data.persistence.dao; -import org.baeldung.spring.data.persistence.model.Foo; +import com.baeldung.spring.data.persistence.model.Foo; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/user/UserRepository.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepository.java similarity index 97% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/user/UserRepository.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepository.java index 4d01376af7..e8f95302ef 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/user/UserRepository.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepository.java @@ -1,11 +1,11 @@ -package org.baeldung.spring.data.persistence.dao.user; +package com.baeldung.spring.data.persistence.dao.user; import java.time.LocalDate; import java.util.Collection; import java.util.List; import java.util.stream.Stream; -import org.baeldung.spring.data.persistence.model.User; +import com.baeldung.spring.data.persistence.model.User; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java similarity index 72% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java index 1a874fb5e5..ff92159077 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustom.java @@ -1,11 +1,11 @@ -package org.baeldung.spring.data.persistence.dao.user; +package com.baeldung.spring.data.persistence.dao.user; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.function.Predicate; -import org.baeldung.spring.data.persistence.model.User; +import com.baeldung.spring.data.persistence.model.User; public interface UserRepositoryCustom { List findUserByEmails(Set emails); diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java similarity index 94% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java index c28050401c..8bd8217e83 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/dao/user/UserRepositoryCustomImpl.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.data.persistence.dao.user; +package com.baeldung.spring.data.persistence.dao.user; import java.util.ArrayList; import java.util.Collection; @@ -15,7 +15,7 @@ import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; -import org.baeldung.spring.data.persistence.model.User; +import com.baeldung.spring.data.persistence.model.User; public class UserRepositoryCustomImpl implements UserRepositoryCustom { diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/model/Foo.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Foo.java similarity index 96% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/model/Foo.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Foo.java index 8f316ac55b..64bfe203d0 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/model/Foo.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Foo.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.data.persistence.model; +package com.baeldung.spring.data.persistence.model; import java.io.Serializable; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/model/Possession.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Possession.java similarity index 97% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/model/Possession.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Possession.java index da64e78552..44ca9fc62e 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/model/Possession.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/Possession.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.data.persistence.model; +package com.baeldung.spring.data.persistence.model; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/model/User.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/User.java similarity index 98% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/model/User.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/User.java index 486ed046e5..09f1092644 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/model/User.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/model/User.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.data.persistence.model; +package com.baeldung.spring.data.persistence.model; import javax.persistence.*; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/service/IFooService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/IFooService.java similarity index 58% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/service/IFooService.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/IFooService.java index 26d0171551..00e7ac01e4 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/service/IFooService.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/IFooService.java @@ -1,6 +1,6 @@ -package org.baeldung.spring.data.persistence.service; +package com.baeldung.spring.data.persistence.service; -import org.baeldung.spring.data.persistence.model.Foo; +import com.baeldung.spring.data.persistence.model.Foo; import com.baeldung.persistence.dao.common.IOperations; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/service/common/AbstractService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/common/AbstractService.java similarity index 95% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/service/common/AbstractService.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/common/AbstractService.java index cf28d5e5c6..61c7d6fcaa 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/service/common/AbstractService.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/common/AbstractService.java @@ -1,4 +1,4 @@ -package org.baeldung.spring.data.persistence.service.common; +package com.baeldung.spring.data.persistence.service.common; import java.io.Serializable; import java.util.List; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/service/impl/FooService.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/impl/FooService.java similarity index 70% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/service/impl/FooService.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/impl/FooService.java index b7ed496df1..cd566ba9f6 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/spring/data/persistence/service/impl/FooService.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/spring/data/persistence/service/impl/FooService.java @@ -1,10 +1,10 @@ -package org.baeldung.spring.data.persistence.service.impl; +package com.baeldung.spring.data.persistence.service.impl; -import org.baeldung.spring.data.persistence.model.Foo; -import org.baeldung.spring.data.persistence.dao.IFooDao; -import org.baeldung.spring.data.persistence.service.IFooService; -import org.baeldung.spring.data.persistence.service.common.AbstractService; +import com.baeldung.spring.data.persistence.model.Foo; +import com.baeldung.spring.data.persistence.dao.IFooDao; +import com.baeldung.spring.data.persistence.service.IFooService; +import com.baeldung.spring.data.persistence.service.common.AbstractService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Service; diff --git a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/util/IDUtil.java b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/util/IDUtil.java similarity index 96% rename from persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/util/IDUtil.java rename to persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/util/IDUtil.java index 85ab623e5f..45e72e046d 100644 --- a/persistence-modules/spring-persistence-simple/src/main/java/org/baeldung/util/IDUtil.java +++ b/persistence-modules/spring-persistence-simple/src/main/java/com/baeldung/util/IDUtil.java @@ -1,4 +1,4 @@ -package org.baeldung.util; +package com.baeldung.util; import java.util.Random; diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml index 5fd2699b41..e3d7452eb1 100644 --- a/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml +++ b/persistence-modules/spring-persistence-simple/src/main/resources/jdbc/springJdbc-config.xml @@ -4,7 +4,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd" > - + diff --git a/persistence-modules/spring-persistence-simple/src/main/resources/persistence.xml b/persistence-modules/spring-persistence-simple/src/main/resources/persistence.xml index 6304fa0a65..57687c306d 100644 --- a/persistence-modules/spring-persistence-simple/src/main/resources/persistence.xml +++ b/persistence-modules/spring-persistence-simple/src/main/resources/persistence.xml @@ -11,7 +11,7 @@ - + true From 350a93ea9d5570425ef9fa086777e9cacf265408 Mon Sep 17 00:00:00 2001 From: Philippe Date: Tue, 21 May 2019 01:03:22 -0300 Subject: [PATCH 085/185] [BAEL-2894] Use standard port --- apache-olingo/olingo2/src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apache-olingo/olingo2/src/main/resources/application.yml b/apache-olingo/olingo2/src/main/resources/application.yml index 21563a94fe..71df0c4166 100644 --- a/apache-olingo/olingo2/src/main/resources/application.yml +++ b/apache-olingo/olingo2/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - port: 8180 + port: 8080 spring: jersey: From b1c95c27163704af483a0d354393bbed6843997f Mon Sep 17 00:00:00 2001 From: Philippe Date: Tue, 21 May 2019 01:06:09 -0300 Subject: [PATCH 086/185] [BAEL-2894] Remove olingo4 module --- apache-olingo/olingo4/.gitignore | 29 -- apache-olingo/olingo4/pom.xml | 90 ------ .../examples/olingo4/DefaultODataFactory.java | 20 -- .../examples/olingo4/ODataFactory.java | 8 - .../olingo4/ODataHttpHandlerFactory.java | 8 - .../olingo4/ODataHttpHandlerFactoryImpl.java | 64 ---- .../olingo4/ODataServiceConfiguration.java | 35 -- .../examples/olingo4/ODataServlet.java | 38 --- .../olingo4/Olingo4SampleApplication.java | 13 - .../examples/olingo4/domain/CarMaker.java | 115 ------- .../examples/olingo4/domain/CarModel.java | 159 --------- .../examples/olingo4/edm/EdmTypeMapper.java | 46 --- .../examples/olingo4/edm/JpaEdmProvider.java | 268 --------------- .../JpaEntityCollectionProcessor.java | 161 ---------- .../olingo4/processor/JpaEntityMapper.java | 93 ------ .../olingo4/processor/JpaEntityProcessor.java | 304 ------------------ .../repository/CarMakerRepository.java | 16 - .../repository/CarModelRepository.java | 22 -- .../repository/EdmEntityRepository.java | 17 - .../repository/RepositoryRegistry.java | 29 -- .../src/main/resources/application.properties | 9 - .../olingo4/src/main/resources/data.sql | 12 - .../Olingo4SampleApplicationTests.java | 16 - 23 files changed, 1572 deletions(-) delete mode 100644 apache-olingo/olingo4/.gitignore delete mode 100644 apache-olingo/olingo4/pom.xml delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java delete mode 100644 apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java delete mode 100644 apache-olingo/olingo4/src/main/resources/application.properties delete mode 100644 apache-olingo/olingo4/src/main/resources/data.sql delete mode 100644 apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java diff --git a/apache-olingo/olingo4/.gitignore b/apache-olingo/olingo4/.gitignore deleted file mode 100644 index 153c9335eb..0000000000 --- a/apache-olingo/olingo4/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -HELP.md -/target/ -!.mvn/wrapper/maven-wrapper.jar - -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache - -### IntelliJ IDEA ### -.idea -*.iws -*.iml -*.ipr - -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ -/build/ - -### VS Code ### -.vscode/ diff --git a/apache-olingo/olingo4/pom.xml b/apache-olingo/olingo4/pom.xml deleted file mode 100644 index 3a93a6fa45..0000000000 --- a/apache-olingo/olingo4/pom.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 2.1.3.RELEASE - - - org.baeldung.examples.olingo4 - olingo4-sample - 0.0.1-SNAPSHOT - olingo4-sample - Sample Olingo 4 Project - - - 1.8 - 4.5.0 - - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - com.h2database - h2 - runtime - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-web - - - - org.apache.olingo - odata-server-core - ${odata.version} - - - - commons-beanutils - commons-beanutils - 1.9.3 - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java deleted file mode 100644 index 18f7f8ba24..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/DefaultODataFactory.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.baeldung.examples.olingo4; - -import org.apache.olingo.server.api.OData; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.stereotype.Component; - -/** - * Default implementation for ODataFactory - * @author Philippe - * - */ -@Component -public class DefaultODataFactory implements ODataFactory { - - @Override - public OData newInstance() { - return OData.newInstance(); - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java deleted file mode 100644 index 9acb4b8c5e..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataFactory.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.baeldung.examples.olingo4; - -import org.apache.olingo.server.api.OData; - -public interface ODataFactory { - - public OData newInstance(); -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java deleted file mode 100644 index 27d0737c24..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactory.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.baeldung.examples.olingo4; - -import org.apache.olingo.server.api.ODataHttpHandler; - -public interface ODataHttpHandlerFactory { - - ODataHttpHandler newInstance(); -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java deleted file mode 100644 index e5d4d06a95..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataHttpHandlerFactoryImpl.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.baeldung.examples.olingo4; - -import java.util.Collections; -import java.util.List; - -import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider; -import org.apache.olingo.server.api.OData; -import org.apache.olingo.server.api.ODataHttpHandler; -import org.apache.olingo.server.api.ServiceMetadata; -import org.apache.olingo.server.api.processor.Processor; - -public class ODataHttpHandlerFactoryImpl implements ODataHttpHandlerFactory { - - private final ODataFactory odataFactory; - private final CsdlEdmProvider edmProvider; - private final List processors; - - public ODataHttpHandlerFactoryImpl(ODataFactory odataFactory, CsdlEdmProvider edmProvider, List processors) { - this.odataFactory = odataFactory; - this.edmProvider = edmProvider; - this.processors = processors; - } - - @Override - public ODataHttpHandler newInstance() { - - OData odata = odataFactory.newInstance(); - ServiceMetadata metadata = odata.createServiceMetadata(edmProvider, Collections.emptyList()); - ODataHttpHandler handler = odata.createHandler(metadata); - - // Register all available processors - processors.forEach(p -> handler.register(p)); - - return handler; - } - - public static class ODataHttpHandlerFactoryImplBuilder { - - private ODataFactory odataFactory; - private CsdlEdmProvider edmProvider; - private List processors; - - public ODataHttpHandlerFactoryImplBuilder odataFactory(ODataFactory odataFactory) { - this.odataFactory = odataFactory; - return this; - } - - public ODataHttpHandlerFactoryImplBuilder edmProvider(CsdlEdmProvider edmProvider) { - this.edmProvider = edmProvider; - return this; - } - - public ODataHttpHandlerFactoryImplBuilder processors(List processors) { - this.processors = processors; - return this; - } - - public ODataHttpHandlerFactoryImpl build() { - return new ODataHttpHandlerFactoryImpl(odataFactory, edmProvider, processors); - } - - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java deleted file mode 100644 index 0cde665359..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServiceConfiguration.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.baeldung.examples.olingo4; - -import java.util.List; - -import javax.persistence.EntityManagerFactory; -import javax.servlet.http.HttpServlet; - -import org.apache.olingo.commons.api.edm.provider.CsdlEdmProvider; -import org.apache.olingo.server.api.processor.Processor; -import org.baeldung.examples.olingo4.ODataHttpHandlerFactoryImpl.ODataHttpHandlerFactoryImplBuilder; -import org.springframework.boot.web.servlet.ServletRegistrationBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration -public class ODataServiceConfiguration { - - @Bean - public ServletRegistrationBean odataServletRegistration(ODataHttpHandlerFactory factory) { - ServletRegistrationBean srb = - new ServletRegistrationBean<>(new ODataServlet(factory), "/odata/*"); - srb.setLoadOnStartup(1); - return srb; - } - - @Bean - public ODataHttpHandlerFactory httpHandlerFactory(CsdlEdmProvider edmProvider, ODataFactory odataFactory, List processors) { - return new ODataHttpHandlerFactoryImplBuilder() - .edmProvider(edmProvider) - .odataFactory(odataFactory) - .processors(processors) - .build(); - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java deleted file mode 100644 index c379124541..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/ODataServlet.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * - */ -package org.baeldung.examples.olingo4; - -import java.io.IOException; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.EntityTransaction; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.olingo.server.api.ODataHttpHandler; - -/** - * @author Philippe - * - */ -public class ODataServlet extends HttpServlet { - - private static final long serialVersionUID = 1L; - private final ODataHttpHandlerFactory odataHttpHandlerFactory; - - - public ODataServlet(ODataHttpHandlerFactory factory) { - this.odataHttpHandlerFactory = factory; - } - - @Override - protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - - ODataHttpHandler handler = odataHttpHandlerFactory.newInstance(); - handler.process(req, resp); - } -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java deleted file mode 100644 index 1ac872ea0f..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/Olingo4SampleApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.baeldung.examples.olingo4; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Olingo4SampleApplication { - - public static void main(String[] args) { - SpringApplication.run(Olingo4SampleApplication.class, args); - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java deleted file mode 100644 index f1b793cbe9..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarMaker.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.baeldung.examples.olingo4.domain; - -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.validation.constraints.NotNull; - -@Entity -@Table(name = "car_maker") -public class CarMaker { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @NotNull - @Column(name = "name") - private String name; - - @OneToMany(mappedBy = "maker", orphanRemoval = true, cascade = CascadeType.ALL) - private List models; - - /** - * @return the id - */ - public Long getId() { - return id; - } - - /** - * @param id the id to set - */ - public void setId(Long id) { - this.id = id; - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param name the name to set - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return the models - */ - public List getModels() { - return models; - } - - /** - * @param models the models to set - */ - public void setModels(List models) { - this.models = models; - } - - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((models == null) ? 0 : models.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CarMaker other = (CarMaker) obj; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (models == null) { - if (other.models != null) - return false; - } else if (!models.equals(other.models)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java deleted file mode 100644 index 7652641d7e..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/domain/CarModel.java +++ /dev/null @@ -1,159 +0,0 @@ -package org.baeldung.examples.olingo4.domain; - -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.validation.constraints.NotNull; - -@Entity -@Table(name = "car_model") -public class CarModel { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; - - @NotNull - private String name; - - @NotNull - private Integer year; - - @NotNull - private String sku; - - @ManyToOne(optional = false, fetch = FetchType.EAGER) - @JoinColumn(name = "maker_fk") - private CarMaker maker; - - /** - * @return the id - */ - public Long getId() { - return id; - } - - /** - * @param id the id to set - */ - public void setId(Long id) { - this.id = id; - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @param name the name to set - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return the year - */ - public Integer getYear() { - return year; - } - - /** - * @param year the year to set - */ - public void setYear(Integer year) { - this.year = year; - } - - /** - * @return the sku - */ - public String getSku() { - return sku; - } - - /** - * @param sku the sku to set - */ - public void setSku(String sku) { - this.sku = sku; - } - - /** - * @return the maker - */ - public CarMaker getMaker() { - return maker; - } - - /** - * @param maker the maker to set - */ - public void setMaker(CarMaker maker) { - this.maker = maker; - } - - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((maker == null) ? 0 : maker.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((sku == null) ? 0 : sku.hashCode()); - result = prime * result + ((year == null) ? 0 : year.hashCode()); - return result; - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CarModel other = (CarModel) obj; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (maker == null) { - if (other.maker != null) - return false; - } else if (!maker.equals(other.maker)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (sku == null) { - if (other.sku != null) - return false; - } else if (!sku.equals(other.sku)) - return false; - if (year == null) { - if (other.year != null) - return false; - } else if (!year.equals(other.year)) - return false; - return true; - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java deleted file mode 100644 index 95797752a2..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/EdmTypeMapper.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.baeldung.examples.olingo4.edm; - -import java.util.Collections; -import java.util.Date; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.sql.Time; -import java.util.AbstractMap.SimpleEntry; - -import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; -import org.springframework.stereotype.Component; - -@Component -public class EdmTypeMapper { - - public EdmPrimitiveTypeKind java2edm(Class clazz) { - EdmPrimitiveTypeKind result = java2edm.get(clazz); - if ( result == null ) { - throw new IllegalArgumentException("[E19] Unsupported class mapping: class=" + clazz); - } - else { - return result; - } - } - - // Static map used generate attribute metadada based on Java types - static Map,EdmPrimitiveTypeKind> java2edm = Collections - .unmodifiableMap(Stream.of( - new SimpleEntry<>(Boolean.class,EdmPrimitiveTypeKind.Boolean), - new SimpleEntry<>(Byte.class,EdmPrimitiveTypeKind.SByte), - new SimpleEntry<>(Date.class,EdmPrimitiveTypeKind.Date), - new SimpleEntry<>(Time.class,EdmPrimitiveTypeKind.TimeOfDay), - new SimpleEntry<>(Number.class,EdmPrimitiveTypeKind.Decimal), - new SimpleEntry<>(Float.class,EdmPrimitiveTypeKind.Single), - new SimpleEntry<>(Double.class,EdmPrimitiveTypeKind.Double), - new SimpleEntry<>(UUID.class,EdmPrimitiveTypeKind.Guid), - new SimpleEntry<>(Short.class,EdmPrimitiveTypeKind.Int16), - new SimpleEntry<>(Integer.class,EdmPrimitiveTypeKind.Int32), - new SimpleEntry<>(Long.class,EdmPrimitiveTypeKind.Int64), - new SimpleEntry<>(String.class,EdmPrimitiveTypeKind.String) - - ).collect(Collectors.toMap((e)-> e.getKey(),(e)-> e.getValue()))); - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java deleted file mode 100644 index 585aecfa84..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/edm/JpaEdmProvider.java +++ /dev/null @@ -1,268 +0,0 @@ -package org.baeldung.examples.olingo4.edm; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import javax.persistence.EntityManagerFactory; -import javax.persistence.metamodel.Attribute.PersistentAttributeType; -import javax.persistence.metamodel.EntityType; -import javax.persistence.metamodel.Metamodel; -import javax.persistence.metamodel.PluralAttribute; -import javax.persistence.metamodel.SingularAttribute; - -import org.apache.olingo.commons.api.edm.FullQualifiedName; -import org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider; -import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer; -import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainerInfo; -import org.apache.olingo.commons.api.edm.provider.CsdlEntitySet; -import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; -import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty; -import org.apache.olingo.commons.api.edm.provider.CsdlProperty; -import org.apache.olingo.commons.api.edm.provider.CsdlPropertyRef; -import org.apache.olingo.commons.api.edm.provider.CsdlSchema; -import org.apache.olingo.commons.api.ex.ODataException; -import org.springframework.stereotype.Component; - -@Component -public class JpaEdmProvider extends CsdlAbstractEdmProvider { - - EntityManagerFactory emf; - - // - private EdmTypeMapper typeMapper; - - // Service Namespace - public static final String NAMESPACE = "Baeldung.OData"; - - // EDM Container - public static final String CONTAINER_NAME = "Cars"; - public static final FullQualifiedName CONTAINER = new FullQualifiedName(NAMESPACE, CONTAINER_NAME); - - // Caches of OData types by it fully qualified name - private Map cdslName2Type = new HashMap<>(); - - public JpaEdmProvider(EntityManagerFactory emf, EdmTypeMapper mapper) { - this.emf = emf; - this.typeMapper = mapper; - } - - /* (non-Javadoc) - * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntitySet(org.apache.olingo.commons.api.edm.FullQualifiedName, java.lang.String) - */ - @Override - public CsdlEntitySet getEntitySet(FullQualifiedName entityContainer, String entitySetName) throws ODataException { - - if (entityContainer.equals(CONTAINER)) { - - EntityType e = emf.getMetamodel() - .getEntities() - .stream() - .filter((ent) -> (ent.getName() + "s") - .equals(entitySetName)) - .findFirst() - .orElse(null); - - if (e != null) { - CsdlEntitySet entitySet = new CsdlEntitySet(); - entitySet - .setName(entitySetName) - .setType(new FullQualifiedName(NAMESPACE, e.getName())); - return entitySet; - } - } - - return null; - } - - /* (non-Javadoc) - * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainerInfo(org.apache.olingo.commons.api.edm.FullQualifiedName) - */ - @Override - public CsdlEntityContainerInfo getEntityContainerInfo(FullQualifiedName entityContainerName) throws ODataException { - - // This method is invoked when displaying the Service Document at e.g. http://localhost:8080/DemoService/DemoService.svc - if (entityContainerName == null || entityContainerName.equals(CONTAINER)) { - CsdlEntityContainerInfo entityContainerInfo = new CsdlEntityContainerInfo(); - entityContainerInfo.setContainerName(CONTAINER); - return entityContainerInfo; - } - - return null; - } - - /* (non-Javadoc) - * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getSchemas() - */ - @Override - public List getSchemas() throws ODataException { - // create Schema - CsdlSchema schema = new CsdlSchema(); - schema.setNamespace(NAMESPACE); - - // add EntityTypes - List entityTypes = emf.getMetamodel() - .getEntities() - .stream() - .map((e) -> { - try { - return getEntityType(new FullQualifiedName(NAMESPACE, e.getName())); - } catch (ODataException oe) { - throw new RuntimeException(oe); - } - }) - .collect(Collectors.toList()); - - schema.setEntityTypes(entityTypes); - - // add EntityContainer - schema.setEntityContainer(getEntityContainer()); - - // finally - List schemas = new ArrayList(); - schemas.add(schema); - - return schemas; - } - - /* (non-Javadoc) - * @see org.apache.olingo.commons.api.edm.provider.CsdlAbstractEdmProvider#getEntityContainer() - */ - @Override - public CsdlEntityContainer getEntityContainer() throws ODataException { - - - // add EntityTypes - List entitySets = emf.getMetamodel() - .getEntities() - .stream() - .map((e) -> { - try { - // Here we use a simple mapping strategy to map entity types to entity set names: - return getEntitySet(CONTAINER, e.getName() + "s"); - } catch (ODataException oe) { - throw new RuntimeException(oe); - } - }) - .collect(Collectors.toList()); - - // create EntityContainer - CsdlEntityContainer entityContainer = new CsdlEntityContainer(); - entityContainer.setName(CONTAINER_NAME); - entityContainer.setEntitySets(entitySets); - - return entityContainer; - } - - @Override - public CsdlEntityType getEntityType(FullQualifiedName entityTypeName) throws ODataException { - - CsdlEntityType result = cdslName2Type.get(entityTypeName); - if ( result != null ) { - return result; - } - - Metamodel mm = emf.getMetamodel(); - result = mm.getEntities() - .stream() - .filter(et -> entityTypeName.equals(new FullQualifiedName(NAMESPACE, et.getName()))) - .map(et -> buildODataType(et)) - .findFirst() - .orElse(null); - - // save for future use - cdslName2Type.put(entityTypeName, result); - return result; - - } - - /** - * Maps a JPA type to its OData counterpart. - * @param et - * @return - */ - protected CsdlEntityType buildODataType(EntityType et) { - - CsdlEntityType result = new CsdlEntityType(); - result.setName(et.getName()); - - // Process simple properties - List properties = et.getDeclaredSingularAttributes() - .stream() - .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC) - .map(attr -> buildBasicAttribute(attr)) - .collect(Collectors.toList()); - - result.setProperties(properties); - - // Process Ids - List ids = et.getDeclaredSingularAttributes() - .stream() - .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.BASIC && attr.isId()) - .map(attr -> buildRefAttribute(attr)) - .collect(Collectors.toList()); - - result.setKey(ids); - - // Process 1:N navs - List navs = et.getDeclaredPluralAttributes() - .stream() - .filter(attr -> attr.isAssociation()) - .map(attr -> buildNavAttribute(attr)) - .collect(Collectors.toList()); - result.setNavigationProperties(navs); - - // Process N:1 navs - List navs2 = et.getDeclaredSingularAttributes() - .stream() - .filter(attr -> attr.getPersistentAttributeType() == PersistentAttributeType.MANY_TO_ONE) - .map(attr -> buildMany2OneNavAttribute(attr)) - .collect(Collectors.toList()); - - result.getNavigationProperties().addAll(navs2); - - - return result; - } - - private CsdlProperty buildBasicAttribute(SingularAttribute attr) { - - CsdlProperty p = new CsdlProperty().setName(attr.getName()) - .setType(typeMapper.java2edm(attr.getJavaType()) - .getFullQualifiedName()) - .setNullable(attr.isOptional()); - - return p; - } - - private CsdlPropertyRef buildRefAttribute(SingularAttribute attr) { - - CsdlPropertyRef p = new CsdlPropertyRef().setName(attr.getName()); - return p; - } - - // Build NavProperty for 1:N or M:N associations - private CsdlNavigationProperty buildNavAttribute(PluralAttribute attr) { - - CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName()) - .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) - .setCollection(true) - .setNullable(false); - - return p; - } - - // Build NavProperty for N:1 associations - private CsdlNavigationProperty buildMany2OneNavAttribute(SingularAttribute attr) { - - CsdlNavigationProperty p = new CsdlNavigationProperty().setName(attr.getName()) - .setType(new FullQualifiedName(NAMESPACE, attr.getBindableJavaType().getSimpleName())) - .setCollection(false) - .setNullable(attr.isOptional()); - - return p; - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java deleted file mode 100644 index 4a4e5026f3..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityCollectionProcessor.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.baeldung.examples.olingo4.processor; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collection; -import java.util.List; - -import javax.persistence.EntityManagerFactory; -import javax.persistence.metamodel.EntityType; -import javax.persistence.metamodel.SingularAttribute; - -import org.apache.commons.beanutils.PropertyUtils; -import org.apache.olingo.commons.api.data.ContextURL; -import org.apache.olingo.commons.api.data.Entity; -import org.apache.olingo.commons.api.data.EntityCollection; -import org.apache.olingo.commons.api.data.Property; -import org.apache.olingo.commons.api.data.ValueType; -import org.apache.olingo.commons.api.edm.EdmEntitySet; -import org.apache.olingo.commons.api.edm.EdmEntityType; -import org.apache.olingo.commons.api.edm.EdmNavigationProperty; -import org.apache.olingo.commons.api.ex.ODataRuntimeException; -import org.apache.olingo.commons.api.format.ContentType; -import org.apache.olingo.commons.api.http.HttpHeader; -import org.apache.olingo.commons.api.http.HttpStatusCode; -import org.apache.olingo.server.api.OData; -import org.apache.olingo.server.api.ODataApplicationException; -import org.apache.olingo.server.api.ODataLibraryException; -import org.apache.olingo.server.api.ODataRequest; -import org.apache.olingo.server.api.ODataResponse; -import org.apache.olingo.server.api.ServiceMetadata; -import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor; -import org.apache.olingo.server.api.processor.EntityCollectionProcessor; -import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions; -import org.apache.olingo.server.api.serializer.ODataSerializer; -import org.apache.olingo.server.api.serializer.SerializerResult; -import org.apache.olingo.server.api.uri.UriInfo; -import org.apache.olingo.server.api.uri.UriParameter; -import org.apache.olingo.server.api.uri.UriResource; -import org.apache.olingo.server.api.uri.UriResourceEntitySet; -import org.baeldung.examples.olingo4.repository.RepositoryRegistry; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Component; - -@Component -public class JpaEntityCollectionProcessor implements CountEntityCollectionProcessor { - - private OData odata; - private ServiceMetadata serviceMetadata; - private EntityManagerFactory emf; - private RepositoryRegistry repositoryRegistry; - private JpaEntityMapper entityMapper; - - public JpaEntityCollectionProcessor(EntityManagerFactory emf, RepositoryRegistry repositoryRegistry, JpaEntityMapper entityMapper) { - this.emf = emf; - this.repositoryRegistry = repositoryRegistry; - this.entityMapper = entityMapper; - } - - @Override - public void init(OData odata, ServiceMetadata serviceMetadata) { - this.odata = odata; - this.serviceMetadata = serviceMetadata; - } - - @Override - public void readEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - - // 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI) - List resourcePaths = uriInfo.getUriResourceParts(); - UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet - EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); - - // 2nd: fetch the data from backend for this requested EntitySetName - // it has to be delivered as EntitySet object - EntityCollection entitySet = getData(edmEntitySet, uriInfo); - - // 3rd: create a serializer based on the requested format (json) - ODataSerializer serializer = odata.createSerializer(responseFormat); - - // 4th: Now serialize the content: transform from the EntitySet object to InputStream - EdmEntityType edmEntityType = edmEntitySet.getEntityType(); - ContextURL contextUrl = ContextURL.with() - .entitySet(edmEntitySet) - .build(); - - final String id = request.getRawBaseUri() + "/" + edmEntitySet.getName(); - EntityCollectionSerializerOptions opts = EntityCollectionSerializerOptions.with() - .id(id) - .contextURL(contextUrl) - .build(); - SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, edmEntityType, entitySet, opts); - InputStream serializedContent = serializerResult.getContent(); - - // Finally: configure the response object: set the body, headers and status code - response.setContent(serializedContent); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - - } - - @Override - public void countEntityCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { - - // 1st we have retrieve the requested EntitySet from the uriInfo object (representation of the parsed service URI) - List resourcePaths = uriInfo.getUriResourceParts(); - UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); // in our example, the first segment is the EntitySet - EdmEntitySet edmEntitySet = uriResourceEntitySet.getEntitySet(); - - // 2nd: fetch the data from backend for this requested EntitySetName - Long count = getCount(edmEntitySet, uriInfo); - - // Finally: configure the response object: set the body, headers and status code - response.setContent(new ByteArrayInputStream(count.toString().getBytes())); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, "text/plain"); - - } - - /** - * Helper method to retrieve all entities of an entity set from an the backend database - * @param edmEntitySet - * @param uriInfo - * @return - */ - protected EntityCollection getData(EdmEntitySet edmEntitySet, UriInfo uriInfo) { - - EdmEntityType type = edmEntitySet.getEntityType(); - JpaRepository repo = (JpaRepository)repositoryRegistry.getRepositoryForEntity(type); - EntityCollection result = new EntityCollection(); - - repo.findAll() - .stream() - .forEach((it) -> result.getEntities() - .add(entityMapper.map2entity(edmEntitySet, it))); - - return result; - } - - - /** - * Helper method to get the total size of an entity set - * @param edmEntitySet - * @param uriInfo - * @return - */ - protected Long getCount(EdmEntitySet edmEntitySet, UriInfo uriInfo) { - - EdmEntityType type = edmEntitySet.getEntityType(); - JpaRepository repo = (JpaRepository)repositoryRegistry.getRepositoryForEntity(type); - EntityCollection result = new EntityCollection(); - - return repo.count(); - } - - - - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java deleted file mode 100644 index 1978aa4fd6..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityMapper.java +++ /dev/null @@ -1,93 +0,0 @@ -/** - * - */ -package org.baeldung.examples.olingo4.processor; - -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.net.URISyntaxException; - -import javax.persistence.EntityManagerFactory; -import javax.persistence.metamodel.EntityType; - -import org.apache.commons.beanutils.PropertyUtils; -import org.apache.olingo.commons.api.data.Entity; -import org.apache.olingo.commons.api.data.Property; -import org.apache.olingo.commons.api.data.ValueType; -import org.apache.olingo.commons.api.edm.EdmEntitySet; -import org.apache.olingo.commons.api.ex.ODataRuntimeException; -import org.springframework.stereotype.Component; - -/** - *

Helper class that converts a JPA entity into an OData entity using - * available metadata from the JPA's EntityManagerFactory.

- * - * @author Philippe - * - */ -@Component -public class JpaEntityMapper { - - private EntityManagerFactory emf; - - public JpaEntityMapper(EntityManagerFactory emf) { - this.emf = emf; - } - - - public Entity map2entity(EdmEntitySet edmEntitySet, Object entry) { - - EntityType et = emf.getMetamodel() - .entity(entry.getClass()); - - - Entity e = new Entity(); - try { - et.getDeclaredSingularAttributes().stream() - .forEach( (attr) -> { - if ( !attr.isAssociation()) { - Object v = getPropertyValue(entry,attr.getName()); - Property p = new Property(null, attr.getName(),ValueType.PRIMITIVE,v); - e.addProperty(p); - - if ( attr.isId()) { - e.setId(createId(edmEntitySet.getName(),v)); - } - } - }); - } catch (Exception ex) { - throw new ODataRuntimeException("[E141] Unable to create OData entity", ex); - } - - return e; - } - - - public Object getPropertyValue(Object entry, String name) { - try { - return PropertyUtils.getProperty(entry,name); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e); - } - } - - public void setPropertyValue(Object entry, String name,Object value) { - try { - PropertyUtils.setProperty(entry,name,value); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new ODataRuntimeException("[E141] Unable to read property from entity, property=" + name, e); - } - } - - - private URI createId(String entitySetName, Object id) { - try { - return new URI(entitySetName + "(" + String.valueOf(id) + ")"); - } catch (URISyntaxException e) { - throw new ODataRuntimeException("[E177] Unable to create URI", e); - } - } - - - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java deleted file mode 100644 index 719e5de160..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/processor/JpaEntityProcessor.java +++ /dev/null @@ -1,304 +0,0 @@ -/** - * - */ -package org.baeldung.examples.olingo4.processor; - -import java.io.InputStream; -import java.util.List; -import java.util.Locale; -import java.util.Optional; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.metamodel.SingularAttribute; - -import org.apache.olingo.commons.api.data.ContextURL; -import org.apache.olingo.commons.api.data.Entity; -import org.apache.olingo.commons.api.edm.EdmEntitySet; -import org.apache.olingo.commons.api.edm.EdmEntityType; -import org.apache.olingo.commons.api.edm.EdmNavigationProperty; -import org.apache.olingo.commons.api.ex.ODataRuntimeException; -import org.apache.olingo.commons.api.format.ContentType; -import org.apache.olingo.commons.api.http.HttpHeader; -import org.apache.olingo.commons.api.http.HttpStatusCode; -import org.apache.olingo.server.api.OData; -import org.apache.olingo.server.api.ODataApplicationException; -import org.apache.olingo.server.api.ODataLibraryException; -import org.apache.olingo.server.api.ODataRequest; -import org.apache.olingo.server.api.ODataResponse; -import org.apache.olingo.server.api.ServiceMetadata; -import org.apache.olingo.server.api.processor.EntityProcessor; -import org.apache.olingo.server.api.serializer.EntitySerializerOptions; -import org.apache.olingo.server.api.serializer.ODataSerializer; -import org.apache.olingo.server.api.serializer.SerializerResult; -import org.apache.olingo.server.api.uri.UriInfo; -import org.apache.olingo.server.api.uri.UriParameter; -import org.apache.olingo.server.api.uri.UriResource; -import org.apache.olingo.server.api.uri.UriResourceEntitySet; -import org.apache.olingo.server.api.uri.UriResourceNavigation; -import org.baeldung.examples.olingo4.repository.EdmEntityRepository; -import org.baeldung.examples.olingo4.repository.RepositoryRegistry; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Component; - -/** - * JpaEntityProcessor adapter. - *

This implementation is heavily based on the Tutorial available - * at Olingo's site. It is meant to be an starting point for an actual implementation.

- *

Please note that many features from a full-fledged are missing - * @author Philippe - * - */ -@Component -public class JpaEntityProcessor implements EntityProcessor { - - private EntityManagerFactory emf; - private OData odata; - private ServiceMetadata serviceMetadata; - private RepositoryRegistry registry; - private JpaEntityMapper entityMapper; - - public JpaEntityProcessor(EntityManagerFactory emf, RepositoryRegistry registry, JpaEntityMapper entityMapper) { - this.emf = emf; - this.registry = registry; - this.entityMapper = entityMapper; - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.Processor#init(org.apache.olingo.server.api.OData, org.apache.olingo.server.api.ServiceMetadata) - */ - @Override - public void init(OData odata, ServiceMetadata serviceMetadata) { - this.odata = odata; - this.serviceMetadata = serviceMetadata; - - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.EntityProcessor#readEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType) - */ - @Override - public void readEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - - // First, we have to figure out which entity is requested - List resourceParts = uriInfo.getUriResourceParts(); - InputStream entityStream; - - UriResourceEntitySet rootResourceEntitySet = (UriResourceEntitySet) resourceParts.get(0); - EdmEntitySet rootEntitySet = rootResourceEntitySet.getEntitySet(); - List rootPredicates = rootResourceEntitySet.getKeyPredicates(); - - if ( resourceParts.size() == 1 ) { - entityStream = readRootEntity(rootEntitySet,rootPredicates,responseFormat); - } - else if ( resourceParts.size() == 2 ) { - UriResource part = resourceParts.get(1); - if ( !(part instanceof UriResourceNavigation)) { - throw new ODataRuntimeException("[E103] part type not supported: class=" + part.getClass().getName()); - } - - UriResourceNavigation navSegment = (UriResourceNavigation)part; - entityStream = readRelatedEntity(request, rootEntitySet,rootPredicates,navSegment.getProperty(),navSegment.getKeyPredicates(),responseFormat); - } - else { - // For now, we'll only allow navigation just to directly linked navs - throw new ODataApplicationException("[E109] Multi-level navigation not supported", HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT); - } - - //4. configure the response object - response.setContent(entityStream); - response.setStatusCode(HttpStatusCode.OK.getStatusCode()); - response.setHeader(HttpHeader.CONTENT_TYPE, responseFormat.toContentTypeString()); - - } - - - // Lookup the EntitySet associated with an EntityType - // In our example, we assume we have only one entityset for each entity type - private EdmEntitySet entitySetFromType(EdmEntityType type) { - return serviceMetadata - .getEdm() - .getEntityContainer() - .getEntitySets() - .stream() - .filter((s) -> s.getEntityType().getName().equals(type.getName())) - .findFirst() - .orElseThrow(() -> new ODataRuntimeException("[E144] No entity set found for type " + type.getFullQualifiedName())); - } - - // - // private boolean isOne2ManyProperty(EdmEntityType entityType, EdmNavigationProperty property) { - // return entityType.getProperty(property.getName()) != null && property.isCollection(); - //} - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private InputStream readRootEntity(EdmEntitySet entitySet, List keyPredicates,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - EdmEntityType type = entitySet.getEntityType(); - JpaRepository repo = registry.getRepositoryForEntity(type); - - // Get key value - Long keyValue = getEntityKey(keyPredicates); - Optional entry = repo.findById(keyValue); - if ( !entry.isPresent()) { - throw new ODataApplicationException( - "[E116] NO entity found for the given key", - HttpStatusCode.NOT_FOUND.getStatusCode(), - Locale.ENGLISH); - } - - Entity e = entityMapper.map2entity(entitySet, entry.get()); - return serializeEntity(entitySet,e,responseFormat); - } - - private InputStream serializeEntity(EdmEntitySet entitySet, Entity entity,ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - ContextURL contextUrl = ContextURL.with().entitySet(entitySet).build(); - // expand and select currently not supported - EntitySerializerOptions options = EntitySerializerOptions - .with() - .contextURL(contextUrl) - .build(); - - ODataSerializer serializer = odata.createSerializer(responseFormat); - - SerializerResult serializerResult = serializer.entity(serviceMetadata, entitySet.getEntityType(), entity, options); - return serializerResult.getContent(); - - } - -// @SuppressWarnings("unchecked") -// protected InputStream readRelatedEntities(EdmEntitySet rootEntitySet, List rootPredicates, EdmNavigationProperty property, ContentType responseFormat) throws ODataApplicationException { -// -// Object jpaEntity = readJPAEntity(rootEntitySet, rootPredicates); -// try { -// Collection set = (Collection)PropertyUtils.getProperty(jpaEntity, property.getName()); -// EdmEntitySet entitySet = entitySetFromType(property.getType()); -// ContextURL contextUrl = ContextURL -// .with() -// .entitySet(entitySet) -// .build(); -// -// EntityCollectionSerializerOptions options = EntityCollectionSerializerOptions -// .with() -// .contextURL(contextUrl) -// .build(); -// -// EntityCollection result = new EntityCollection(); -// -// set.stream() -// .map((o) -> this.entityMapper.map2entity(entitySet, o)) -// .forEach((e) -> result.getEntities().add(e)); -// -// ODataSerializer serializer = odata.createSerializer(responseFormat); -// SerializerResult serializerResult = serializer.entityCollection(serviceMetadata, property.getType(), result, options); -// return serializerResult.getContent(); -// } -// catch(Exception ex) { -// throw new ODataRuntimeException("[E181] Error accessing database", ex); -// } -// } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private InputStream readRelatedEntity(ODataRequest request, EdmEntitySet entitySet, List rootPredicates, EdmNavigationProperty property, List parentPredicates, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - - - JpaRepository repo = (JpaRepository)registry.getRepositoryForEntity(entitySet.getEntityType()); - EdmEntityRepository relatedRepo = (EdmEntityRepository)registry.getRepositoryForEntity(property.getType()); - - // We assume here that we have a bi-directional 1:N relationship, so we'll - // always have a property in the child entity that points to the parent - Class rootClass = ((EdmEntityRepository)repo).getEntityClass(); - Class relatedClass = ((EdmEntityRepository)relatedRepo).getEntityClass(); - - SingularAttribute fk = emf.getMetamodel() - .entity(rootClass) - .getSingularAttributes() - .stream() - .filter((attr) -> { - boolean b = attr.isAssociation() && attr.getJavaType().isAssignableFrom(relatedClass); - return b; - }) - .findFirst() - .orElse(null); - - if ( fk == null ) { - throw new ODataRuntimeException("[E230] No singular attribute of child class '" + relatedClass.getName() + "' found" ); - } - - Long pkValue = getEntityKey(rootPredicates); - EntityManager em = this.emf.createEntityManager(); - try { - // Read data from DB - Object root = em.find(rootClass, pkValue); - Object related = this.entityMapper.getPropertyValue(root, fk.getName()); - - EdmEntitySet relatedEntitySet = entitySetFromType(property.getType()); - Entity e = entityMapper.map2entity(relatedEntitySet, related); - return serializeEntity(relatedEntitySet,e,responseFormat); - } - finally { - em.close(); - } - } - -// @SuppressWarnings("unchecked") -// private Object readJPAEntity(EdmEntitySet edmEntitySet, List keyPredicates) throws ODataApplicationException { -// EdmEntityType type = edmEntitySet.getEntityType(); -// JpaRepository repo = (JpaRepository)registry.getRepositoryForEntity(type); -// -// // Get key value -// Object keyValue = getEntityKey(type,keyPredicates); -// Object entry = repo -// .findById(keyValue) -// .orElseThrow( -// () -> new ODataApplicationException("[E116] NO entity found for the given key", -// HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ENGLISH)); -// -// return entry; -// } - - private Long getEntityKey(List keyPredicates) { - - if ( keyPredicates.size() > 1 ) { - throw new ODataRuntimeException("[E131] Composite keys are not supported"); - } - - // For now, we'll assume we only have numeric keys. - UriParameter keyParam = keyPredicates.get(0); - try { - return Long.parseLong(keyParam.getText()); - } - catch(NumberFormatException nfe) { - throw new ODataRuntimeException("[E140] Invalid key value. Only numeric keys are supported by this service"); - } - - - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.EntityProcessor#createEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType, org.apache.olingo.commons.api.format.ContentType) - */ - @Override - public void createEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - // TODO Auto-generated method stub - - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.EntityProcessor#updateEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo, org.apache.olingo.commons.api.format.ContentType, org.apache.olingo.commons.api.format.ContentType) - */ - @Override - public void updateEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType requestFormat, ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - // TODO Auto-generated method stub - - } - - /* (non-Javadoc) - * @see org.apache.olingo.server.api.processor.EntityProcessor#deleteEntity(org.apache.olingo.server.api.ODataRequest, org.apache.olingo.server.api.ODataResponse, org.apache.olingo.server.api.uri.UriInfo) - */ - @Override - public void deleteEntity(ODataRequest request, ODataResponse response, UriInfo uriInfo) throws ODataApplicationException, ODataLibraryException { - // TODO Auto-generated method stub - - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java deleted file mode 100644 index 1bde9f148c..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarMakerRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.examples.olingo4.repository; - -import org.baeldung.examples.olingo4.domain.CarMaker; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.stereotype.Repository; - -@Repository -public interface CarMakerRepository extends EdmEntityRepository, JpaRepository, JpaSpecificationExecutor { - - public default String getEdmEntityName() { return CarMaker.class.getSimpleName();} - @Override - default Class getEntityClass() { - return CarMaker.class; - } -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java deleted file mode 100644 index 247bf6e77b..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/CarModelRepository.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.baeldung.examples.olingo4.repository; - -import java.util.List; - -import org.baeldung.examples.olingo4.domain.CarModel; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; -import org.springframework.stereotype.Repository; - -@Repository -public interface CarModelRepository extends EdmEntityRepository, JpaRepository, JpaSpecificationExecutor { - - public List findByMakerId(Long makerId); - - public default String getEdmEntityName() { return CarModel.class.getSimpleName();} - - @Override - default Class getEntityClass() { - return CarModel.class; - } - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java deleted file mode 100644 index dbfd0e6f93..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/EdmEntityRepository.java +++ /dev/null @@ -1,17 +0,0 @@ -/** - * - */ -package org.baeldung.examples.olingo4.repository; - - -/** - * @author Philippe - * - */ -public interface EdmEntityRepository { - - public String getEdmEntityName(); - public Class getEntityClass(); - - -} diff --git a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java b/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java deleted file mode 100644 index e3bb172e3a..0000000000 --- a/apache-olingo/olingo4/src/main/java/org/baeldung/examples/olingo4/repository/RepositoryRegistry.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.baeldung.examples.olingo4.repository; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.olingo.commons.api.edm.EdmEntityType; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Component; - -@Component -public class RepositoryRegistry { - - private Map> repositoriesByClassName = new HashMap<>(); - - public RepositoryRegistry(List> allRepositories) { - - allRepositories.stream() - .forEach((r) -> - repositoriesByClassName.put(r.getEdmEntityName(),(JpaRepository)r)); - - } - - - public JpaRepository getRepositoryForEntity(EdmEntityType entityType) { - JpaRepository repo = repositoriesByClassName.get(entityType.getName()); - return repo; - } -} diff --git a/apache-olingo/olingo4/src/main/resources/application.properties b/apache-olingo/olingo4/src/main/resources/application.properties deleted file mode 100644 index 02c7fe5c4d..0000000000 --- a/apache-olingo/olingo4/src/main/resources/application.properties +++ /dev/null @@ -1,9 +0,0 @@ -server: - port: 8080 - -spring: - jpa: - show-sql: true - open-in-view: true - hibernate: - ddl-auto: update diff --git a/apache-olingo/olingo4/src/main/resources/data.sql b/apache-olingo/olingo4/src/main/resources/data.sql deleted file mode 100644 index 327f2688c5..0000000000 --- a/apache-olingo/olingo4/src/main/resources/data.sql +++ /dev/null @@ -1,12 +0,0 @@ -insert into car_maker(id,name) values (1,'Special Motors'); -insert into car_maker(id,name) values (2,'BWM'); -insert into car_maker(id,name) values (3,'Dolores'); - -insert into car_model(id,maker_fk,name,sku,year) values(1,1,'Muze','SM001',2018); -insert into car_model(id,maker_fk,name,sku,year) values(2,1,'Empada','SM002',2008); - -insert into car_model(id,maker_fk,name,sku,year) values(4,2,'BWM-100','BWM100',2008); -insert into car_model(id,maker_fk,name,sku,year) values(5,2,'BWM-200','BWM200',2009); -insert into car_model(id,maker_fk,name,sku,year) values(6,2,'BWM-300','BWM300',2008); - -alter sequence hibernate_sequence restart with 100; \ No newline at end of file diff --git a/apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java b/apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java deleted file mode 100644 index 5d23a4148e..0000000000 --- a/apache-olingo/olingo4/src/test/java/org/baeldung/examples/olingo4/Olingo4SampleApplicationTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.examples.olingo4; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class Olingo4SampleApplicationTests { - - @Test - public void contextLoads() { - } - -} From a2e90642333c01f2547d1be9b5975d6a3053a34b Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Tue, 21 May 2019 21:24:57 +0300 Subject: [PATCH 087/185] Create README.MD --- core-java-modules/core-java-lambdas/README.MD | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java-lambdas/README.MD diff --git a/core-java-modules/core-java-lambdas/README.MD b/core-java-modules/core-java-lambdas/README.MD new file mode 100644 index 0000000000..31790ffbb1 --- /dev/null +++ b/core-java-modules/core-java-lambdas/README.MD @@ -0,0 +1,3 @@ +### Relevant Articles + +- [Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?](https://www.baeldung.com/java-lambda-effectively-final-local-variables) From d47801e7ba39a9cef16be44779a5fd50811719f7 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Tue, 21 May 2019 21:27:37 +0300 Subject: [PATCH 088/185] Update README.md --- spring-security-kerberos/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-kerberos/README.md b/spring-security-kerberos/README.md index 0338c2058c..1b77c380db 100644 --- a/spring-security-kerberos/README.md +++ b/spring-security-kerberos/README.md @@ -7,4 +7,4 @@ mvn clean install ``` ### Relevant Articles: -- [Spring Security – Kerberos](http://www.baeldung.com/xxxxxx) +- [Introduction to SPNEGO/Kerberos Authentication in Spring](https://www.baeldung.com/spring-security-kerberos) From 2d553451d1d721db7bc9c9358ca3e16e5e4b852a Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Tue, 21 May 2019 21:28:21 +0300 Subject: [PATCH 089/185] Create README.MD --- libraries-primitive/README.MD | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 libraries-primitive/README.MD diff --git a/libraries-primitive/README.MD b/libraries-primitive/README.MD new file mode 100644 index 0000000000..f27fb73dd6 --- /dev/null +++ b/libraries-primitive/README.MD @@ -0,0 +1,3 @@ +### Relevant Articles + +- [Guide to FastUtil](https://www.baeldung.com/fastutil) From d939f2583785ad7d8094bfea60d26747cad6b592 Mon Sep 17 00:00:00 2001 From: Loredana Date: Tue, 21 May 2019 22:55:03 +0300 Subject: [PATCH 090/185] fix slf4j message issue --- .../com/baeldung/logging/slf4j/Slf4jLogger.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java index df41e071fd..a5d6abeac7 100644 --- a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java +++ b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ResourceBundle; +import java.text.MessageFormat; public class Slf4jLogger implements System.Logger { @@ -74,26 +75,27 @@ public class Slf4jLogger implements System.Logger { if (!isLoggable(level)) { return; } + String message = MessageFormat.format (format, params); switch (level) { case TRACE: - logger.trace(format, params); + logger.trace(message); break; case DEBUG: - logger.debug(format, params); + logger.debug(message); break; case INFO: - logger.info(format, params); + logger.info(message); break; case WARNING: - logger.warn(format, params); + logger.warn(message); break; case ERROR: - logger.error(format, params); + logger.error(message); break; case ALL: default: - logger.info(format, params); + logger.info(message); } } } From 49304324adb1829d6521877ed7cae9518039df6b Mon Sep 17 00:00:00 2001 From: anuraggoyal1 Date: Wed, 22 May 2019 01:54:38 +0530 Subject: [PATCH 091/185] [BAEL-1951]create new module core-java-nio and adding java filechannel examples (#6899) * create new module core-java-nio and adding filechannel * updated readme with NIO article details * fixed typo * Remore unused dependencies from pom.xml * fixed build issue * moving into core-java-modules folder * remove unused plugins from pom.xml * remove junk file and update readme * removing readme.md * change in indentation. remove tabs to spaces --- core-java-modules/core-java-nio/.gitignore | 5 + core-java-modules/core-java-nio/pom.xml | 16 ++ .../filechannel/FileChannelUnitTest.java | 165 ++++++++++++++++++ .../src/test/resources/.gitignore | 13 ++ .../src/test/resources/test_read.in | 1 + .../src/test/resources/test_truncate.txt | 1 + .../test_write_using_filechannel.txt | 1 + pom.xml | 4 +- 8 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 core-java-modules/core-java-nio/.gitignore create mode 100644 core-java-modules/core-java-nio/pom.xml create mode 100644 core-java-modules/core-java-nio/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java create mode 100644 core-java-modules/core-java-nio/src/test/resources/.gitignore create mode 100644 core-java-modules/core-java-nio/src/test/resources/test_read.in create mode 100644 core-java-modules/core-java-nio/src/test/resources/test_truncate.txt create mode 100644 core-java-modules/core-java-nio/src/test/resources/test_write_using_filechannel.txt diff --git a/core-java-modules/core-java-nio/.gitignore b/core-java-modules/core-java-nio/.gitignore new file mode 100644 index 0000000000..c61d35324d --- /dev/null +++ b/core-java-modules/core-java-nio/.gitignore @@ -0,0 +1,5 @@ +0.* + +# Files generated by integration tests +# *.txt +/temp \ No newline at end of file diff --git a/core-java-modules/core-java-nio/pom.xml b/core-java-modules/core-java-nio/pom.xml new file mode 100644 index 0000000000..36d6848998 --- /dev/null +++ b/core-java-modules/core-java-nio/pom.xml @@ -0,0 +1,16 @@ + + 4.0.0 + core-java-nio + 0.1.0-SNAPSHOT + core-java-nio + jar + + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + + \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java b/core-java-modules/core-java-nio/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java new file mode 100644 index 0000000000..d661b8f7fb --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/java/com/baeldung/filechannel/FileChannelUnitTest.java @@ -0,0 +1,165 @@ +package com.baeldung.filechannel; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.charset.StandardCharsets; + +import org.junit.Test; + +public class FileChannelUnitTest { + + @Test + public void givenFile_whenReadWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel(); + ByteArrayOutputStream out = new ByteArrayOutputStream()) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + + assertEquals("Hello world", fileContent); + } + } + + @Test + public void givenFile_whenReadWithFileChannelUsingFileInputStream_thenCorrect() throws IOException { + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + FileInputStream fin = new FileInputStream("src/test/resources/test_read.in"); + FileChannel channel = fin.getChannel()) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + + assertEquals("Hello world", fileContent); + } + } + + @Test + public void givenFile_whenReadAFileSectionIntoMemoryWithFileChannel_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel(); + ByteArrayOutputStream out = new ByteArrayOutputStream()) { + + MappedByteBuffer buff = channel.map(FileChannel.MapMode.READ_ONLY, 6, 5); + + if (buff.hasRemaining()) { + byte[] data = new byte[buff.remaining()]; + buff.get(data); + assertEquals("world", new String(data, StandardCharsets.UTF_8)); + } + } + } + + @Test + public void whenWriteWithFileChannelUsingRandomAccessFile_thenCorrect() throws IOException { + String file = "src/test/resources/test_write_using_filechannel.txt"; + try (RandomAccessFile writer = new RandomAccessFile(file, "rw"); + FileChannel channel = writer.getChannel()) { + ByteBuffer buff = ByteBuffer.wrap("Hello world".getBytes(StandardCharsets.UTF_8)); + + channel.write(buff); + + // now we verify whether the file was written correctly + RandomAccessFile reader = new RandomAccessFile(file, "r"); + assertEquals("Hello world", reader.readLine()); + reader.close(); + } + } + + @Test + public void givenFile_whenWriteAFileUsingLockAFileSectionWithFileChannel_thenCorrect() throws IOException { + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "rw"); + FileChannel channel = reader.getChannel(); + FileLock fileLock = channel.tryLock(6, 5, Boolean.FALSE);) { + + assertNotNull(fileLock); + } + } + + @Test + public void givenFile_whenReadWithFileChannelGetPosition_thenCorrect() throws IOException { + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel()) { + + int bufferSize = 1024; + if (bufferSize > channel.size()) { + bufferSize = (int) channel.size(); + } + ByteBuffer buff = ByteBuffer.allocate(bufferSize); + + while (channel.read(buff) > 0) { + out.write(buff.array(), 0, buff.position()); + buff.clear(); + } + + // the original file is 11 bytes long, so that's where the position pointer should be + assertEquals(11, channel.position()); + + channel.position(4); + assertEquals(4, channel.position()); + } + } + + @Test + public void whenGetFileSize_thenCorrect() throws IOException { + + try (RandomAccessFile reader = new RandomAccessFile("src/test/resources/test_read.in", "r"); + FileChannel channel = reader.getChannel()) { + + // the original file is 11 bytes long, so that's where the position pointer should be + assertEquals(11, channel.size()); + } + } + + @Test + public void whenTruncateFile_thenCorrect() throws IOException { + String input = "this is a test input"; + + FileOutputStream fout = new FileOutputStream("src/test/resources/test_truncate.txt"); + FileChannel channel = fout.getChannel(); + + ByteBuffer buff = ByteBuffer.wrap(input.getBytes()); + channel.write(buff); + buff.flip(); + + channel = channel.truncate(5); + assertEquals(5, channel.size()); + + fout.close(); + channel.close(); + } +} diff --git a/core-java-modules/core-java-nio/src/test/resources/.gitignore b/core-java-modules/core-java-nio/src/test/resources/.gitignore new file mode 100644 index 0000000000..83c05e60c8 --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/resources/.gitignore @@ -0,0 +1,13 @@ +*.class + +#folders# +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/resources/test_read.in b/core-java-modules/core-java-nio/src/test/resources/test_read.in new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/resources/test_read.in @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/resources/test_truncate.txt b/core-java-modules/core-java-nio/src/test/resources/test_truncate.txt new file mode 100644 index 0000000000..26d3b38cdd --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/resources/test_truncate.txt @@ -0,0 +1 @@ +this \ No newline at end of file diff --git a/core-java-modules/core-java-nio/src/test/resources/test_write_using_filechannel.txt b/core-java-modules/core-java-nio/src/test/resources/test_write_using_filechannel.txt new file mode 100644 index 0000000000..70c379b63f --- /dev/null +++ b/core-java-modules/core-java-nio/src/test/resources/test_write_using_filechannel.txt @@ -0,0 +1 @@ +Hello world \ No newline at end of file diff --git a/pom.xml b/pom.xml index 03d2e5d763..2cbd218fdc 100644 --- a/pom.xml +++ b/pom.xml @@ -392,6 +392,7 @@ core-java-modules/core-java-concurrency-basic core-java-modules/core-java-concurrency-collections core-java-modules/core-java-io + core-java-modules/core-java-nio core-java-modules/core-java-security core-java-modules/core-java-lang-syntax core-java-modules/core-java-lang @@ -1074,6 +1075,7 @@ core-java-modules/core-java-concurrency-basic core-java-modules/core-java-concurrency-collections core-java-modules/core-java-io + core-java-modules/core-java-nio core-java-modules/core-java-security core-java-modules/core-java-lang-syntax core-java-modules/core-java-lang @@ -1560,4 +1562,4 @@ 1.16.12 1.4.197 - + \ No newline at end of file From f686f8fcdd0542cbcb33356ad6c967007b96604a Mon Sep 17 00:00:00 2001 From: Eugen Date: Wed, 22 May 2019 09:48:00 +0300 Subject: [PATCH 092/185] minor formatting work --- .../baeldung/SpringDataRestApplication.java | 2 ++ .../controllers/UserController.java | 10 +++---- .../repositories/UserRepository.java | 3 +- .../test/UserControllerIntegrationTest.java | 28 ++++--------------- 4 files changed, 14 insertions(+), 29 deletions(-) diff --git a/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java b/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java index 94eddc5b3e..702acb5b65 100644 --- a/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java +++ b/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java @@ -5,7 +5,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringDataRestApplication { + public static void main(String[] args) { SpringApplication.run(SpringDataRestApplication.class, args); } + } diff --git a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java index 8258c3b7aa..eb5d8d51d4 100644 --- a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java +++ b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/controllers/UserController.java @@ -1,8 +1,5 @@ package com.baeldung.springdatawebsupport.application.controllers; -import com.baeldung.springdatawebsupport.application.entities.User; -import com.baeldung.springdatawebsupport.application.repositories.UserRepository; -import com.querydsl.core.types.Predicate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -11,9 +8,12 @@ import org.springframework.data.domain.Sort; import org.springframework.data.querydsl.binding.QuerydslPredicate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.baeldung.springdatawebsupport.application.entities.User; +import com.baeldung.springdatawebsupport.application.repositories.UserRepository; +import com.querydsl.core.types.Predicate; + @RestController public class UserController { @@ -33,7 +33,7 @@ public class UserController { public Page findAllUsers(Pageable pageable) { return userRepository.findAll(pageable); } - + @GetMapping("/sortedusers") public Page findAllUsersSortedByName() { Pageable pageable = PageRequest.of(0, 5, Sort.by("name")); diff --git a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java index 41d7ed9d98..a20197dc8b 100644 --- a/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java +++ b/spring-data-rest/src/main/java/com/baeldung/springdatawebsupport/application/repositories/UserRepository.java @@ -8,7 +8,6 @@ import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository; @Repository -public interface UserRepository extends PagingAndSortingRepository, - QuerydslPredicateExecutor { +public interface UserRepository extends PagingAndSortingRepository, QuerydslPredicateExecutor { } diff --git a/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java index db522b1413..e1aff7e09d 100644 --- a/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java @@ -31,44 +31,28 @@ public class UserControllerIntegrationTest { @Test public void whenGetRequestToUsersEndPointWithIdPathVariable_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/users/{id}", "1") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$.id").value("1")); + mockMvc.perform(MockMvcRequestBuilders.get("/users/{id}", "1").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$.id").value("1")); } @Test public void whenGetRequestToUsersEndPoint_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/users") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$['pageable']['paged']").value("true")); + mockMvc.perform(MockMvcRequestBuilders.get("/users").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$['pageable']['paged']").value("true")); } @Test public void whenGetRequestToUserEndPointWithNameRequestParameter_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/user") - .param("name", "John") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$['content'][0].['name']").value("John")); + mockMvc.perform(MockMvcRequestBuilders.get("/user").param("name", "John").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$['content'][0].['name']").value("John")); } @Test public void whenGetRequestToSorteredUsersEndPoint_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/sortedusers") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$['sort']['sorted']").value("true")); + mockMvc.perform(MockMvcRequestBuilders.get("/sortedusers").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$['sort']['sorted']").value("true")); } @Test public void whenGetRequestToFilteredUsersEndPoint_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/filteredusers") - .param("name", "John") - .contentType(MediaType.APPLICATION_JSON_UTF8)) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("John")); + mockMvc.perform(MockMvcRequestBuilders.get("/filteredusers").param("name", "John").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()).andExpect(MockMvcResultMatchers.jsonPath("$[0].name").value("John")); } } From cb810de745da6c9ec3e269c924efd6d7433d3cf3 Mon Sep 17 00:00:00 2001 From: Sumeet Gajbhar Date: Wed, 22 May 2019 20:06:43 +0530 Subject: [PATCH 093/185] BAEL-2927 added logging configuration for tomcat logs (#6967) --- .../controller/GreetingsController.java | 14 ++++++++++++++ .../main/resources/application-tomcat.properties | 8 +++++++- .../src/main/resources/application.properties | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 spring-boot-ops-2/src/main/java/com/baeldung/springbootconfiguration/controller/GreetingsController.java diff --git a/spring-boot-ops-2/src/main/java/com/baeldung/springbootconfiguration/controller/GreetingsController.java b/spring-boot-ops-2/src/main/java/com/baeldung/springbootconfiguration/controller/GreetingsController.java new file mode 100644 index 0000000000..2d73564c4d --- /dev/null +++ b/spring-boot-ops-2/src/main/java/com/baeldung/springbootconfiguration/controller/GreetingsController.java @@ -0,0 +1,14 @@ +package com.baeldung.springbootconfiguration.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GreetingsController { + + @GetMapping("/greetings/{username}") + public String getGreetings(@PathVariable("username") String userName) { + return "Hello " + userName + ", Good day...!!!"; + } +} diff --git a/spring-boot-ops-2/src/main/resources/application-tomcat.properties b/spring-boot-ops-2/src/main/resources/application-tomcat.properties index d7c1ba9ac3..42d03a066e 100644 --- a/spring-boot-ops-2/src/main/resources/application-tomcat.properties +++ b/spring-boot-ops-2/src/main/resources/application-tomcat.properties @@ -1,5 +1,5 @@ # server configuration -server.port=80 +server.port=4010 server.address=127.0.0.1 ## Error handling configuration @@ -21,3 +21,9 @@ server.tomcat.accesslog.directory=logs server.tomcat.accesslog.file-date-format=yyyy-MM-dd server.tomcat.accesslog.prefix=access_log server.tomcat.accesslog.suffix=.log +server.tomcat.accesslog.pattern=common +server.tomcat.basedir=tomcat + +## Tomcat internal server logs +logging.level.org.apache.tomcat=DEBUG +logging.level.org.apache.catalina=DEBUG \ No newline at end of file diff --git a/spring-boot-ops-2/src/main/resources/application.properties b/spring-boot-ops-2/src/main/resources/application.properties index 8b13789179..fc3fff1d38 100644 --- a/spring-boot-ops-2/src/main/resources/application.properties +++ b/spring-boot-ops-2/src/main/resources/application.properties @@ -1 +1 @@ - +spring.profiles.active=tomcat From 93f54b10b87cad6c2dc04cb9cf9e22a6ce8aaa2d Mon Sep 17 00:00:00 2001 From: Priyesh Mashelkar Date: Wed, 22 May 2019 15:51:32 +0100 Subject: [PATCH 094/185] BAEL-2814 Added files for article (#6968) --- .../com/baeldung/jpa/projections/Product.java | 50 +++++++ .../jpa/projections/ProductRepository.java | 93 ++++++++++++ .../main/resources/META-INF/persistence.xml | 19 ++- .../src/main/resources/products_jpa.sql | 4 + .../HibernateProjectionsIntegrationTest.java | 133 ++++++++++++++++++ .../ProductRepositoryIntegrationTest.java | 105 ++++++++++++++ .../java-jpa/src/test/resources/products.sql | 5 + 7 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/Product.java create mode 100644 persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/ProductRepository.java create mode 100644 persistence-modules/java-jpa/src/main/resources/products_jpa.sql create mode 100644 persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java create mode 100644 persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/ProductRepositoryIntegrationTest.java create mode 100644 persistence-modules/java-jpa/src/test/resources/products.sql diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/Product.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/Product.java new file mode 100644 index 0000000000..90f90be0c0 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/Product.java @@ -0,0 +1,50 @@ +package com.baeldung.jpa.projections; + +import java.math.BigDecimal; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +@Entity +public class Product { + @Id + private long id; + private String name; + private String description; + private String category; + private BigDecimal unitPrice; + + public long getId() { + return id; + } + public void setId(long id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getCategory() { + return category; + } + public void setCategory(String category) { + this.category = category; + } + public BigDecimal getUnitPrice() { + return unitPrice; + } + public void setUnitPrice(BigDecimal unitPrice) { + this.unitPrice = unitPrice; + } + +} diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/ProductRepository.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/ProductRepository.java new file mode 100644 index 0000000000..bb269e1de6 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/projections/ProductRepository.java @@ -0,0 +1,93 @@ +package com.baeldung.jpa.projections; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import javax.persistence.Tuple; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Root; + +public class ProductRepository { + private EntityManager entityManager; + + public ProductRepository() { + EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-projections"); + entityManager = factory.createEntityManager(); + } + + @SuppressWarnings("unchecked") + public List findAllNamesUsingJPQL() { + Query query = entityManager.createQuery("select name from Product"); + List resultList = query.getResultList(); + return resultList; + } + + @SuppressWarnings("unchecked") + public List findAllIdsUsingJPQL() { + Query query = entityManager.createQuery("select id from Product"); + List resultList = query.getResultList(); + return resultList; + } + + public List findAllNamesUsingCriteriaBuilder() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(String.class); + Root product = query.from(Product.class); + query.select(product.get("name")); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } + + @SuppressWarnings("unchecked") + public List findAllIdAndNamesUsingJPQL() { + Query query = entityManager.createQuery("select id, name from Product"); + List resultList = query.getResultList(); + return resultList; + } + + public List findAllIdAndNamesUsingCriteriaBuilderArray() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(Object[].class); + Root product = query.from(Product.class); + query.select(builder.array(product.get("id"), product.get("name"))); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } + + public List findAllIdNameUnitPriceUsingCriteriaQueryMultiselect() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(Object[].class); + Root product = query.from(Product.class); + query.multiselect(product.get("id"), product.get("name"), product.get("unitPrice")); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } + + public List findAllIdAndNamesUsingCriteriaBuilderTuple() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(Tuple.class); + Root product = query.from(Product.class); + query.select(builder.tuple(product.get("id"), product.get("name"))); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } + + public List findCountByCategoryUsingJPQL() { + Query query = entityManager.createQuery("select p.category, count(p) from Product p group by p.category"); + return query.getResultList(); + } + + public List findCountByCategoryUsingCriteriaBuilder() { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(Object[].class); + Root product = query.from(Product.class); + query.multiselect(product.get("category"), builder.count(product)); + query.groupBy(product.get("category")); + List resultList = entityManager.createQuery(query).getResultList(); + return resultList; + } +} diff --git a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml index 9c5543bc3c..298397e39d 100644 --- a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml @@ -147,7 +147,7 @@ - + org.hibernate.jpa.HibernatePersistenceProvider com.baeldung.jpa.entity.Student @@ -163,4 +163,21 @@ + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.projections.Product + true + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/java-jpa/src/main/resources/products_jpa.sql b/persistence-modules/java-jpa/src/main/resources/products_jpa.sql new file mode 100644 index 0000000000..43bc294f56 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/resources/products_jpa.sql @@ -0,0 +1,4 @@ +insert into product(id, name, description, category) values (1,'Product Name 1','This is Product 1', 'category1'); +insert into product(id, name, description, category) values (2,'Product Name 2','This is Product 2', 'category1'); +insert into product(id, name, description, category) values (3,'Product Name 3','This is Product 3', 'category2'); +insert into product(id, name, description, category) values (4,'Product Name 4','This is Product 4', 'category3'); diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java new file mode 100644 index 0000000000..47cc7cbaec --- /dev/null +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/HibernateProjectionsIntegrationTest.java @@ -0,0 +1,133 @@ +package com.baeldung.jpa.projections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.List; + +import org.hibernate.Criteria; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.Configuration; +import org.hibernate.criterion.Order; +import org.hibernate.criterion.Projections; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +public class HibernateProjectionsIntegrationTest { + private static Session session; + private static SessionFactory sessionFactory; + private Transaction transaction; + + @BeforeClass + public static void init() { + Configuration configuration = getConfiguration(); + configuration.addAnnotatedClass(Product.class); + sessionFactory = configuration.buildSessionFactory(); + } + + @Before + public void before() { + session = sessionFactory.getCurrentSession(); + transaction = session.beginTransaction(); + } + + @After + public void after() { + if(transaction.isActive()) { + transaction.rollback(); + } + } + + private static Configuration getConfiguration() { + Configuration cfg = new Configuration(); + cfg.setProperty(AvailableSettings.DIALECT, + "org.hibernate.dialect.H2Dialect"); + cfg.setProperty(AvailableSettings.HBM2DDL_AUTO, "none"); + cfg.setProperty(AvailableSettings.DRIVER, "org.h2.Driver"); + cfg.setProperty(AvailableSettings.URL, + "jdbc:h2:mem:myexceptiondb2;DB_CLOSE_DELAY=-1;;INIT=RUNSCRIPT FROM 'src/test/resources/products.sql'"); + cfg.setProperty(AvailableSettings.USER, "sa"); + cfg.setProperty(AvailableSettings.PASS, ""); + cfg.setProperty(AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "thread"); + return cfg; + } + + + @SuppressWarnings("deprecation") + @Test + public void givenProductData_whenIdAndNameProjectionUsingCriteria_thenListOfObjectArrayReturned() { + Criteria criteria = session.createCriteria(Product.class); + criteria = criteria.setProjection(Projections.projectionList() + .add(Projections.id()) + .add(Projections.property("name"))); + List resultList = criteria.list(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals(1L, resultList.get(0)[0]); + assertEquals("Product Name 1", resultList.get(0)[1]); + assertEquals(2L, resultList.get(1)[0]); + assertEquals("Product Name 2", resultList.get(1)[1]); + assertEquals(3L, resultList.get(2)[0]); + assertEquals("Product Name 3", resultList.get(2)[1]); + assertEquals(4L, resultList.get(3)[0]); + assertEquals("Product Name 4", resultList.get(3)[1]); + } + + + @Test + public void givenProductData_whenNameProjectionUsingCriteria_thenListOfStringReturned() { + Criteria criteria = session.createCriteria(Product.class); + criteria = criteria.setProjection(Projections.property("name")); + List resultList = criteria.list(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals("Product Name 1", resultList.get(0)); + assertEquals("Product Name 2", resultList.get(1)); + assertEquals("Product Name 3", resultList.get(2)); + assertEquals("Product Name 4", resultList.get(3)); + } + + @Test + public void givenProductData_whenCountByCategoryUsingCriteria_thenOK() { + Criteria criteria = session.createCriteria(Product.class); + criteria = criteria.setProjection(Projections.projectionList() + .add(Projections.groupProperty("category")) + .add(Projections.rowCount())); + List resultList = criteria.list(); + + assertNotNull(resultList); + assertEquals(3, resultList.size()); + assertEquals("category1", resultList.get(0)[0]); + assertEquals(2L, resultList.get(0)[1]); + assertEquals("category2", resultList.get(1)[0]); + assertEquals(1L, resultList.get(1)[1]); + assertEquals("category3", resultList.get(2)[0]); + assertEquals(1L, resultList.get(2)[1]); + } + + @Test + public void givenProductData_whenCountByCategoryWithAliasUsingCriteria_thenOK() { + Criteria criteria = session.createCriteria(Product.class); + criteria = criteria.setProjection(Projections.projectionList() + .add(Projections.groupProperty("category")) + .add(Projections.alias(Projections.rowCount(), "count"))); + criteria.addOrder(Order.asc("count")); + List resultList = criteria.list(); + + assertNotNull(resultList); + assertEquals(3, resultList.size()); + assertEquals("category2", resultList.get(0)[0]); + assertEquals(1L, resultList.get(0)[1]); + assertEquals("category3", resultList.get(1)[0]); + assertEquals(1L, resultList.get(1)[1]); + assertEquals("category1", resultList.get(2)[0]); + assertEquals(2L, resultList.get(2)[1]); + } +} diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/ProductRepositoryIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/ProductRepositoryIntegrationTest.java new file mode 100644 index 0000000000..c9a05709e3 --- /dev/null +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/projections/ProductRepositoryIntegrationTest.java @@ -0,0 +1,105 @@ +package com.baeldung.jpa.projections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + + +public class ProductRepositoryIntegrationTest { + private static ProductRepository productRepository; + + @BeforeClass + public static void once() throws IOException { + productRepository = new ProductRepository(); + } + + @Test + public void givenProductData_whenIdAndNameProjectionUsingJPQL_thenListOfObjectArrayReturned() { + List resultList = productRepository.findAllIdAndNamesUsingJPQL(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals(1L, resultList.get(0)[0]); + assertEquals("Product Name 1", resultList.get(0)[1]); + assertEquals(2L, resultList.get(1)[0]); + assertEquals("Product Name 2", resultList.get(1)[1]); + assertEquals(3L, resultList.get(2)[0]); + assertEquals("Product Name 3", resultList.get(2)[1]); + assertEquals(4L, resultList.get(3)[0]); + assertEquals("Product Name 4", resultList.get(3)[1]); + } + + @Test + public void givenProductData_whenIdAndNameProjectionUsingCriteriaBuilder_thenListOfObjectArrayReturned() { + List resultList = productRepository.findAllIdAndNamesUsingCriteriaBuilderArray(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals(1L, resultList.get(0)[0]); + assertEquals("Product Name 1", resultList.get(0)[1]); + assertEquals(2L, resultList.get(1)[0]); + assertEquals("Product Name 2", resultList.get(1)[1]); + assertEquals(3L, resultList.get(2)[0]); + assertEquals("Product Name 3", resultList.get(2)[1]); + assertEquals(4L, resultList.get(3)[0]); + assertEquals("Product Name 4", resultList.get(3)[1]); + } + + @SuppressWarnings("rawtypes") + @Test + public void givenProductData_whenNameProjectionUsingJPQL_thenListOfStringReturned() { + List resultList = productRepository.findAllNamesUsingJPQL(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals("Product Name 1", resultList.get(0)); + assertEquals("Product Name 2", resultList.get(1)); + assertEquals("Product Name 3", resultList.get(2)); + assertEquals("Product Name 4", resultList.get(3)); + } + + @Test + public void givenProductData_whenNameProjectionUsingCriteriaBuilder_thenListOfStringReturned() { + List resultList = productRepository.findAllNamesUsingCriteriaBuilder(); + + assertNotNull(resultList); + assertEquals(4, resultList.size()); + assertEquals("Product Name 1", resultList.get(0)); + assertEquals("Product Name 2", resultList.get(1)); + assertEquals("Product Name 3", resultList.get(2)); + assertEquals("Product Name 4", resultList.get(3)); + } + + @Test + public void givenProductData_whenCountByCategoryUsingJPQL_thenOK() { + List resultList = productRepository.findCountByCategoryUsingJPQL(); + + assertNotNull(resultList); + assertEquals(3, resultList.size()); + assertEquals("category1", resultList.get(0)[0]); + assertEquals(2L, resultList.get(0)[1]); + assertEquals("category2", resultList.get(1)[0]); + assertEquals(1L, resultList.get(1)[1]); + assertEquals("category3", resultList.get(2)[0]); + assertEquals(1L, resultList.get(2)[1]); + } + + @Test + public void givenProductData_whenCountByCategoryUsingCriteriaBuider_thenOK() { + List resultList = productRepository.findCountByCategoryUsingCriteriaBuilder(); + + assertNotNull(resultList); + assertEquals(3, resultList.size()); + assertEquals("category1", resultList.get(0)[0]); + assertEquals(2L, resultList.get(0)[1]); + assertEquals("category2", resultList.get(1)[0]); + assertEquals(1L, resultList.get(1)[1]); + assertEquals("category3", resultList.get(2)[0]); + assertEquals(1L, resultList.get(2)[1]); + } +} diff --git a/persistence-modules/java-jpa/src/test/resources/products.sql b/persistence-modules/java-jpa/src/test/resources/products.sql new file mode 100644 index 0000000000..d38ea1b037 --- /dev/null +++ b/persistence-modules/java-jpa/src/test/resources/products.sql @@ -0,0 +1,5 @@ +create table Product (id bigint not null, category varchar(255), description varchar(255), name varchar(255), unitPrice decimal(19,2), primary key (id)); +insert into product(id, name, description, category) values (1,'Product Name 1','This is Product 1', 'category1'); +insert into product(id, name, description, category) values (2,'Product Name 2','This is Product 2', 'category1'); +insert into product(id, name, description, category) values (3,'Product Name 3','This is Product 3', 'category2'); +insert into product(id, name, description, category) values (4,'Product Name 4','This is Product 4', 'category3'); From af996eed8f7b65f3d376e0a18136f57c9e286530 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Thu, 23 May 2019 00:45:07 +0530 Subject: [PATCH 095/185] [BAEL-12898] - Moved WaysToIterateUnitTest to core-java-collection-list-2 module --- .../test/java/com/baeldung/java/list/WaysToIterateUnitTest.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core-java-modules/{core-java-collections-list => core-java-collections-list-2}/src/test/java/com/baeldung/java/list/WaysToIterateUnitTest.java (100%) diff --git a/core-java-modules/core-java-collections-list/src/test/java/com/baeldung/java/list/WaysToIterateUnitTest.java b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/list/WaysToIterateUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-list/src/test/java/com/baeldung/java/list/WaysToIterateUnitTest.java rename to core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/list/WaysToIterateUnitTest.java From a59168b67fe9fd0e8e46236104d19b671dcecd01 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Thu, 23 May 2019 12:37:11 +0530 Subject: [PATCH 096/185] [BAEL-14777] - Removed old spring 4 and xml related settings --- .../org/baeldung/config/child/WebConfig.java | 2 - .../config/parent/SecurityConfig.java | 1 - .../src/main/resources/prop.xml | 13 ----- .../src/main/resources/webSecurityConfig.xml | 21 -------- .../src/main/webapp/WEB-INF/web_old.xml | 51 ------------------- 5 files changed, 88 deletions(-) delete mode 100644 spring-security-rest-custom/src/main/resources/prop.xml delete mode 100644 spring-security-rest-custom/src/main/resources/webSecurityConfig.xml delete mode 100644 spring-security-rest-custom/src/main/webapp/WEB-INF/web_old.xml diff --git a/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java b/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java index d7b2da6fe7..6688d41ffa 100644 --- a/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java +++ b/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java @@ -14,8 +14,6 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @EnableWebMvc @ComponentScan("org.baeldung.web") -// @ImportResource({ "classpath:prop.xml" }) -// @PropertySource("classpath:foo.properties") public class WebConfig implements WebMvcConfigurer { public WebConfig() { diff --git a/spring-security-rest-custom/src/main/java/org/baeldung/config/parent/SecurityConfig.java b/spring-security-rest-custom/src/main/java/org/baeldung/config/parent/SecurityConfig.java index 616c2a7684..74e2df2174 100644 --- a/spring-security-rest-custom/src/main/java/org/baeldung/config/parent/SecurityConfig.java +++ b/spring-security-rest-custom/src/main/java/org/baeldung/config/parent/SecurityConfig.java @@ -10,7 +10,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration -// @ImportResource({ "classpath:webSecurityConfig.xml" }) @EnableWebSecurity @ComponentScan("org.baeldung.security") public class SecurityConfig extends WebSecurityConfigurerAdapter { diff --git a/spring-security-rest-custom/src/main/resources/prop.xml b/spring-security-rest-custom/src/main/resources/prop.xml deleted file mode 100644 index b853d939d6..0000000000 --- a/spring-security-rest-custom/src/main/resources/prop.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml b/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml deleted file mode 100644 index fa5dc894bf..0000000000 --- a/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-security-rest-custom/src/main/webapp/WEB-INF/web_old.xml b/spring-security-rest-custom/src/main/webapp/WEB-INF/web_old.xml deleted file mode 100644 index 0fa9abd258..0000000000 --- a/spring-security-rest-custom/src/main/webapp/WEB-INF/web_old.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - Spring Security Custom Application - - - - contextClass - - org.springframework.web.context.support.AnnotationConfigWebApplicationContext - - - - contextConfigLocation - org.baeldung.config.parent - - - - org.springframework.web.context.ContextLoaderListener - - - - - api - org.springframework.web.servlet.DispatcherServlet - - - - - 1 - - - api - /api/* - - - - - springSecurityFilterChain - org.springframework.web.filter.DelegatingFilterProxy - - - springSecurityFilterChain - /* - - - \ No newline at end of file From d4a51e7ac883bb426d1c344a5e0ad4e5bf28b7ce Mon Sep 17 00:00:00 2001 From: amit2103 Date: Thu, 23 May 2019 21:06:21 +0530 Subject: [PATCH 097/185] [BAEL-14777] - Added wrongly deleted web security config xml --- .../src/main/resources/webSecurityConfig.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 spring-security-rest-custom/src/main/resources/webSecurityConfig.xml diff --git a/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml b/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml new file mode 100644 index 0000000000..fa5dc894bf --- /dev/null +++ b/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + \ No newline at end of file From 910186e2d4b6b7600184af69d69ef8f8b2db5cac Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Thu, 23 May 2019 20:16:13 +0300 Subject: [PATCH 098/185] Update pom.xml --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2cbd218fdc..bdd7562486 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,6 @@ pom - lombok-custom quarkus @@ -1562,4 +1561,4 @@ 1.16.12 1.4.197 - \ No newline at end of file + From 3946260278b43d6e2ae4e359747d721c3ceca61d Mon Sep 17 00:00:00 2001 From: Loredana Date: Thu, 23 May 2019 20:23:14 +0300 Subject: [PATCH 099/185] fix conflict --- .../com/baeldung/logging/slf4j/Slf4jLogger.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java index df41e071fd..aaa2d83ca6 100644 --- a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java +++ b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java @@ -75,6 +75,8 @@ public class Slf4jLogger implements System.Logger { return; } + String message = MessageFormat.format(format, params); + switch (level) { case TRACE: logger.trace(format, params); From a5a99c28b1e5c3229cb6d2765a85c64bb35fdef6 Mon Sep 17 00:00:00 2001 From: Liesheng Long Date: Thu, 23 May 2019 20:09:03 -0400 Subject: [PATCH 100/185] formatting the source code --- .../HandleOptionalTypeExample.java | 64 +++++++++---------- .../OptionalToJsonExample.java | 25 ++++---- .../PersistOptionalTypeExample.java | 32 +++++----- .../PersistOptionalTypeExample2.java | 28 ++++---- .../PersistUserExample.java | 28 ++++---- .../SerializeOptionalTypeExample.java | 61 +++++++++--------- .../com/baeldung/optionalReturnType/User.java | 36 +++++------ .../optionalReturnType/UserOptional.java | 40 ++++++------ .../optionalReturnType/UserOptionalField.java | 34 +++++----- 9 files changed, 173 insertions(+), 175 deletions(-) diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/HandleOptionalTypeExample.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/HandleOptionalTypeExample.java index a49909901b..c472bab077 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/HandleOptionalTypeExample.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/HandleOptionalTypeExample.java @@ -5,37 +5,37 @@ import java.util.Map; import java.util.Optional; public class HandleOptionalTypeExample { - static Map usersByName = new HashMap(); - static { - User user1 = new User(); - user1.setUserId(1l); - user1.setFirstName("baeldung"); - usersByName.put("baeldung", user1); - } - - public static void main(String[] args) { - changeUserName("baeldung", "baeldung-new"); - changeUserName("user", "user-new"); - } - - public static void changeUserName(String oldFirstName, String newFirstName) { - Optional userOpt = findUserByName(oldFirstName); - if(userOpt.isPresent()){ - User user = userOpt.get(); - user.setFirstName(newFirstName); - - System.out.println("user with name "+oldFirstName+" is changed to "+ user.getFirstName()); - } else { - //user is missing - System.out.println("user with name "+oldFirstName+" is not found."); - } - } - - public static Optional findUserByName(String name){ - //look up the user in the database, the user object below could be null - User user=usersByName.get(name); - Optional opt = Optional.ofNullable(user); + static Map usersByName = new HashMap(); + static { + User user1 = new User(); + user1.setUserId(1l); + user1.setFirstName("baeldung"); + usersByName.put("baeldung", user1); + } - return opt; - } + public static void main(String[] args) { + changeUserName("baeldung", "baeldung-new"); + changeUserName("user", "user-new"); + } + + public static void changeUserName(String oldFirstName, String newFirstName) { + Optional userOpt = findUserByName(oldFirstName); + if (userOpt.isPresent()) { + User user = userOpt.get(); + user.setFirstName(newFirstName); + + System.out.println("user with name " + oldFirstName + " is changed to " + user.getFirstName()); + } else { + // user is missing + System.out.println("user with name " + oldFirstName + " is not found."); + } + } + + public static Optional findUserByName(String name) { + // look up the user in the database, the user object below could be null + User user = usersByName.get(name); + Optional opt = Optional.ofNullable(user); + + return opt; + } } diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/OptionalToJsonExample.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/OptionalToJsonExample.java index cec5ba5ce1..b44a35fae1 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/OptionalToJsonExample.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/OptionalToJsonExample.java @@ -4,17 +4,16 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public class OptionalToJsonExample { - public static void main(String[] args) { - UserOptional user = new UserOptional(); - user.setUserId(1l); - user.setFirstName("Bael Dung"); - - ObjectMapper om = new ObjectMapper(); - try { - System.out.print("user in json is:"+om.writeValueAsString(user)); - } catch (JsonProcessingException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + public static void main(String[] args) { + UserOptional user = new UserOptional(); + user.setUserId(1l); + user.setFirstName("Bael Dung"); + + ObjectMapper om = new ObjectMapper(); + try { + System.out.print("user in json is:" + om.writeValueAsString(user)); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + } } diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample.java index 681fae565b..85c96b9bc3 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample.java @@ -7,20 +7,20 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class PersistOptionalTypeExample { - static String persistenceUnit = "com.baeldung.optionalReturnType"; - static EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit); - - static EntityManager entityManager = emf.createEntityManager(); - - //to run this app, uncomment the follow line in META-INF/persistence.xml - //com.baeldung.optionalReturnType.UserOptionalField - public static void main(String[] args) { - UserOptionalField user1 = new UserOptionalField(); - user1.setUserId(1l); - user1.setFirstName(Optional.of("Bael Dung")); - entityManager.persist(user1); - - UserOptional user2 = entityManager.find(UserOptional.class, 1l); - System.out.print("User2.firstName:"+user2.getFirstName()); - } + static String persistenceUnit = "com.baeldung.optionalReturnType"; + static EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit); + + static EntityManager entityManager = emf.createEntityManager(); + + // to run this app, uncomment the follow line in META-INF/persistence.xml + // com.baeldung.optionalReturnType.UserOptionalField + public static void main(String[] args) { + UserOptionalField user1 = new UserOptionalField(); + user1.setUserId(1l); + user1.setFirstName(Optional.of("Bael Dung")); + entityManager.persist(user1); + + UserOptional user2 = entityManager.find(UserOptional.class, 1l); + System.out.print("User2.firstName:" + user2.getFirstName()); + } } diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample2.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample2.java index 0662b692a8..3114e7cefb 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample2.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistOptionalTypeExample2.java @@ -5,18 +5,18 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class PersistOptionalTypeExample2 { - static String persistenceUnit = "com.baeldung.optionalReturnType"; - static EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit); - - static EntityManager em = emf.createEntityManager(); - - public static void main(String[] args) { - UserOptional user1 = new UserOptional(); - user1.setUserId(1l); - user1.setFirstName("Bael Dung"); - em.persist(user1); - - UserOptional user2 = em.find(UserOptional.class, 1l); - System.out.print("User2.firstName:"+user2.getFirstName()); - } + static String persistenceUnit = "com.baeldung.optionalReturnType"; + static EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit); + + static EntityManager em = emf.createEntityManager(); + + public static void main(String[] args) { + UserOptional user1 = new UserOptional(); + user1.setUserId(1l); + user1.setFirstName("Bael Dung"); + em.persist(user1); + + UserOptional user2 = em.find(UserOptional.class, 1l); + System.out.print("User2.firstName:" + user2.getFirstName()); + } } diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistUserExample.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistUserExample.java index af17f83c6e..f1284958e7 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistUserExample.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/PersistUserExample.java @@ -5,18 +5,18 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; public class PersistUserExample { - static String persistenceUnit = "com.baeldung.optionalReturnType"; - static EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit); - - static EntityManager em = emf.createEntityManager(); - - public static void main(String[] args) { - User user1 = new User(); - user1.setUserId(1l); - user1.setFirstName("Bael Dung"); - em.persist(user1); - - User user2 = em.find(User.class, 1l); - System.out.print("User2.firstName:"+user2.getFirstName()); - } + static String persistenceUnit = "com.baeldung.optionalReturnType"; + static EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnit); + + static EntityManager em = emf.createEntityManager(); + + public static void main(String[] args) { + User user1 = new User(); + user1.setUserId(1l); + user1.setFirstName("Bael Dung"); + em.persist(user1); + + User user2 = em.find(User.class, 1l); + System.out.print("User2.firstName:" + user2.getFirstName()); + } } diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/SerializeOptionalTypeExample.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/SerializeOptionalTypeExample.java index 7ad4a5325e..d67337ad98 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/SerializeOptionalTypeExample.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/SerializeOptionalTypeExample.java @@ -6,37 +6,36 @@ import java.io.ObjectOutputStream; import java.util.Optional; public class SerializeOptionalTypeExample { - public static void main(String[] args) { - User user1 = new User(); - user1.setUserId(1l); - user1.setFirstName("baeldung"); - - serializeObject(user1, "user1.ser"); - + public static void main(String[] args) { + User user1 = new User(); + user1.setUserId(1l); + user1.setFirstName("baeldung"); - UserOptionalField user2 = new UserOptionalField(); - user2.setUserId(1l); - user2.setFirstName(Optional.of("baeldung")); - - serializeObject(user2, "user2.ser"); + serializeObject(user1, "user1.ser"); - } - - public static void serializeObject(Object object, String fileName) { - // Serialization - try { - FileOutputStream file = new FileOutputStream(fileName); - ObjectOutputStream out = new ObjectOutputStream(file); - - out.writeObject(object); - - out.close(); - file.close(); - - System.out.println("Object "+object.toString()+ " has been serialized to file "+fileName); - - } catch(IOException e) { - e.printStackTrace(); - } - } + UserOptionalField user2 = new UserOptionalField(); + user2.setUserId(1l); + user2.setFirstName(Optional.of("baeldung")); + + serializeObject(user2, "user2.ser"); + + } + + public static void serializeObject(Object object, String fileName) { + // Serialization + try { + FileOutputStream file = new FileOutputStream(fileName); + ObjectOutputStream out = new ObjectOutputStream(file); + + out.writeObject(object); + + out.close(); + file.close(); + + System.out.println("Object " + object.toString() + " has been serialized to file " + fileName); + + } catch (IOException e) { + e.printStackTrace(); + } + } } diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/User.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/User.java index 42bedb4817..7aa11d78cb 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/User.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/User.java @@ -7,25 +7,25 @@ import javax.persistence.Id; @Entity public class User implements Serializable { - @Id - private long userId; - - private String firstName; - - public long getUserId() { - return userId; - } + @Id + private long userId; - public void setUserId(long userId) { - this.userId = userId; - } + private String firstName; - public String getFirstName() { - return firstName; - } + public long getUserId() { + return userId; + } + + public void setUserId(long userId) { + this.userId = userId; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } - public void setFirstName(String firstName) { - this.firstName = firstName; - } - } diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptional.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptional.java index c48781ea80..0138a84ab9 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptional.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptional.java @@ -9,27 +9,27 @@ import javax.persistence.Id; @Entity public class UserOptional implements Serializable { - @Id - private long userId; - - @Column(nullable = true) - private String firstName; - - public long getUserId() { - return userId; - } + @Id + private long userId; - public void setUserId(long userId) { - this.userId = userId; - } + @Column(nullable = true) + private String firstName; - public Optional getFirstName() { - return Optional.ofNullable(firstName); - } + public long getUserId() { + return userId; + } + + public void setUserId(long userId) { + this.userId = userId; + } + + public Optional getFirstName() { + return Optional.ofNullable(firstName); + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + Optional.ofNullable(firstName); + } - public void setFirstName(String firstName) { - this.firstName = firstName; - Optional.ofNullable(firstName); - } - } diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptionalField.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptionalField.java index 0778a8bb99..c02430b1ba 100644 --- a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptionalField.java +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/optionalReturnType/UserOptionalField.java @@ -8,24 +8,24 @@ import javax.persistence.Id; @Entity public class UserOptionalField implements Serializable { - @Id - private long userId; - - private Optional firstName; - - public long getUserId() { - return userId; - } + @Id + private long userId; - public void setUserId(long userId) { - this.userId = userId; - } + private Optional firstName; - public Optional getFirstName() { - return firstName; - } + public long getUserId() { + return userId; + } - public void setFirstName(Optional firstName) { - this.firstName = firstName; - } + public void setUserId(long userId) { + this.userId = userId; + } + + public Optional getFirstName() { + return firstName; + } + + public void setFirstName(Optional firstName) { + this.firstName = firstName; + } } From a8cdcc610083fd4a3d51fea91c2b8664f18c05ef Mon Sep 17 00:00:00 2001 From: Liesheng Long Date: Thu, 23 May 2019 20:18:30 -0400 Subject: [PATCH 101/185] formatting and use properties for versions --- core-java-modules/core-java-8-2/pom.xml | 103 ++++++++++++------------ 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/core-java-modules/core-java-8-2/pom.xml b/core-java-modules/core-java-8-2/pom.xml index 862b739530..150f36be59 100644 --- a/core-java-modules/core-java-8-2/pom.xml +++ b/core-java-modules/core-java-8-2/pom.xml @@ -1,64 +1,67 @@ - 4.0.0 - com.baeldung - core-java-8-2 - 0.1.0-SNAPSHOT - core-java-8-2 - jar + 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 + core-java-8-2 + 0.1.0-SNAPSHOT + core-java-8-2 + jar - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../../parent-java - + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + - - UTF-8 - 1.8 - 1.8 - 64.2 - + + UTF-8 + 1.8 + 1.8 + 64.2 + 5.4.0.Final + 1.4.197 + 2.9.8 + - - - com.ibm.icu - icu4j - ${icu.version} - + - org.hibernate - hibernate-core - 5.4.0.Final + com.ibm.icu + icu4j + ${icu.version} - com.h2database - h2 - 1.4.197 + org.hibernate + hibernate-core + ${hibernate.core.version} - com.fasterxml.jackson.core - jackson-databind - 2.9.8 - - + com.h2database + h2 + ${h2database.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.databind.version} + + - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - - - + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + - + From ef9f687f687deddcbcc7d165eae77a5a9ae31d5d Mon Sep 17 00:00:00 2001 From: Abhishek Malik Date: Fri, 24 May 2019 08:48:32 +0530 Subject: [PATCH 102/185] rename variable and move underscore to front to simulate minus (#7010) --- .../numberformat/NumberFormatExceptionUnitTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/numberformat/NumberFormatExceptionUnitTest.java b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/numberformat/NumberFormatExceptionUnitTest.java index a1e8c7c30f..cb26bf451a 100644 --- a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/numberformat/NumberFormatExceptionUnitTest.java +++ b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/numberformat/NumberFormatExceptionUnitTest.java @@ -36,7 +36,7 @@ public class NumberFormatExceptionUnitTest { @Test(expected = NumberFormatException.class) public void givenParseIntMethod_whenUnderscoreInInput_thenFail() { - int bIntPrim = Integer.parseInt("6_000"); + int bIntPrim = Integer.parseInt("_6000"); } @Test(expected = NumberFormatException.class) @@ -51,7 +51,7 @@ public class NumberFormatExceptionUnitTest { @Test(expected = NumberFormatException.class) public void givenDecodeMethod_whenAlphabetInInput_thenFail() { - Long decodeInteger = Long.decode("64403L"); + Long decodedLong = Long.decode("64403L"); } /* ---INTEGER PASS CASES--- */ @@ -72,7 +72,7 @@ public class NumberFormatExceptionUnitTest { int aIntPrim = Integer.parseInt("6000 ".trim()); assertEquals(6000, aIntPrim); - int bIntPrim = Integer.parseInt("6_000".replaceAll("_", "")); + int bIntPrim = Integer.parseInt("_6000".replaceAll("_", "")); assertEquals(6000, bIntPrim); int cIntPrim = Integer.parseInt("-6000"); From fd5afd015a4b818695e20c4e7163adaa1fe4d2d3 Mon Sep 17 00:00:00 2001 From: Laurentiu Delcea Date: Fri, 24 May 2019 08:20:09 +0300 Subject: [PATCH 103/185] BAEL-2924 Jersey request parameters (#7007) * BAEL-2924 Jersey request parameters * BAEL-2924 Jersey request parameters --- .../com/baeldung/jersey/server/ItemParam.java | 46 ++++++++++++++++ .../com/baeldung/jersey/server/Items.java | 49 +++++++++++++++++ .../server/http/EmbeddedHttpServer.java | 8 ++- .../baeldung/jersey/server/ItemsUnitTest.java | 52 +++++++++++++++++++ 4 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 jersey/src/main/java/com/baeldung/jersey/server/ItemParam.java create mode 100644 jersey/src/main/java/com/baeldung/jersey/server/Items.java create mode 100644 jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java diff --git a/jersey/src/main/java/com/baeldung/jersey/server/ItemParam.java b/jersey/src/main/java/com/baeldung/jersey/server/ItemParam.java new file mode 100644 index 0000000000..0f60a20b92 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/ItemParam.java @@ -0,0 +1,46 @@ +package com.baeldung.jersey.server; + +import javax.ws.rs.FormParam; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PathParam; + +public class ItemParam { + + @HeaderParam("headerParam") + private String shopKey; + + @PathParam("pathParam") + private String itemId; + + @FormParam("formParam") + private String price; + + public String getShopKey() { + return shopKey; + } + + public void setShopKey(String shopKey) { + this.shopKey = shopKey; + } + + public String getItemId() { + return itemId; + } + + public void setItemId(String itemId) { + this.itemId = itemId; + } + + public String getPrice() { + return price; + } + + public void setPrice(String price) { + this.price = price; + } + + @Override + public String toString() { + return "ItemParam{shopKey='" + shopKey + ", itemId='" + itemId + ", price='" + price + '}'; + } +} diff --git a/jersey/src/main/java/com/baeldung/jersey/server/Items.java b/jersey/src/main/java/com/baeldung/jersey/server/Items.java new file mode 100644 index 0000000000..c24e6820f5 --- /dev/null +++ b/jersey/src/main/java/com/baeldung/jersey/server/Items.java @@ -0,0 +1,49 @@ +package com.baeldung.jersey.server; + +import javax.ws.rs.*; + +@Path("items") +public class Items { + + @GET + @Path("/cookie") + public String readCookieParam(@CookieParam("cookieParamToRead") String cookieParamToRead) { + return "Cookie parameter value is [" + cookieParamToRead + "]"; + } + + @GET + @Path("/header") + public String readHeaderParam(@HeaderParam("headerParamToRead") String headerParamToRead) { + return "Header parameter value is [" + headerParamToRead + "]"; + } + + @GET + @Path("/path/{pathParamToRead}") + public String readPathParam(@PathParam("pathParamToRead") String pathParamToRead) { + return "Path parameter value is [" + pathParamToRead + "]"; + } + + @GET + @Path("/query") + public String readQueryParam(@QueryParam("queryParamToRead") String queryParamToRead) { + return "Query parameter value is [" + queryParamToRead + "]"; + } + + @POST + @Path("/form") + public String readFormParam(@FormParam("formParamToRead") String formParamToRead) { + return "Form parameter value is [" + formParamToRead + "]"; + } + + @GET + @Path("/matrix") + public String readMatrixParam(@MatrixParam("matrixParamToRead") String matrixParamToRead) { + return "Matrix parameter value is [" + matrixParamToRead + "]"; + } + + @POST + @Path("/bean/{pathParam}") + public String readBeanParam(@BeanParam ItemParam itemParam) { + return itemParam.toString(); + } +} \ No newline at end of file diff --git a/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java b/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java index 4afa086858..1d75508c6d 100644 --- a/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java +++ b/jersey/src/main/java/com/baeldung/jersey/server/http/EmbeddedHttpServer.java @@ -7,12 +7,13 @@ import java.util.logging.Logger; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; +import org.glassfish.jersey.server.ResourceConfig; import com.baeldung.jersey.server.config.ViewApplicationConfig; public class EmbeddedHttpServer { - private static final URI BASE_URI = URI.create("http://localhost:8082/"); + public static final URI BASE_URI = URI.create("http://localhost:8082/"); public static void main(String[] args) { try { @@ -32,4 +33,9 @@ public class EmbeddedHttpServer { } } + + public static HttpServer startServer() { + final ResourceConfig rc = new ResourceConfig().packages("com.baeldung.jersey.server"); + return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI.toString()), rc); + } } diff --git a/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java b/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java new file mode 100644 index 0000000000..df85e26b76 --- /dev/null +++ b/jersey/src/test/java/com/baeldung/jersey/server/ItemsUnitTest.java @@ -0,0 +1,52 @@ +package com.baeldung.jersey.server; + +import static org.junit.Assert.assertEquals; + +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; + +import org.glassfish.grizzly.http.server.HttpServer; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.jersey.server.http.EmbeddedHttpServer; + +public class ItemsUnitTest { + + private HttpServer server; + private WebTarget target; + + @Before + public void setUp() throws Exception { + server = EmbeddedHttpServer.startServer(); + target = ClientBuilder.newClient().target(EmbeddedHttpServer.BASE_URI.toString()); + } + + @After + public void tearDown() throws Exception { + server.stop(); + } + + @Test + public void givenCookieParameter_whenGet_thenReturnsExpectedText() { + String paramValue = "1"; + String responseText = target.path("items/cookie").request().cookie("cookieParamToRead", paramValue).get(String.class); + assertEquals("Cookie parameter value is [" + paramValue + "]", responseText); + } + + @Test + public void givenHeaderParameter_whenGet_thenReturnsExpectedText() { + String paramValue = "2"; + String responseText = target.path("items/header").request().header("headerParamToRead", paramValue).get(String.class); + assertEquals("Header parameter value is [" + paramValue + "]", responseText); + } + + @Test + public void givenPathParameter_whenGet_thenReturnsExpectedText() { + String paramValue = "3"; + String responseText = target.path("items/path/" + paramValue).request().get(String.class); + assertEquals("Path parameter value is [" + paramValue + "]", responseText); + } +} From da7a651ef41fadcc58ac42cfb877cbf827f96543 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:26:13 +0800 Subject: [PATCH 104/185] Create README.md --- .../src/main/java/com/baeldung/deserialization/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/deserialization/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/README.md new file mode 100644 index 0000000000..04b03e4907 --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [What is the serialVersionUID?](https://www.baeldung.com/java-serial-version-uid) From abae8ec0cfc5ad457dc13736a517be69f0803b99 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:28:02 +0800 Subject: [PATCH 105/185] Create README.md --- .../core-java/src/main/java/com/baeldung/uuid/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/uuid/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/uuid/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/uuid/README.md new file mode 100644 index 0000000000..bc464a4a1d --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/uuid/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Guide to UUID in Java](https://www.baeldung.com/java-uuid) From 3974bf9dd7abb69983550a114994c4cf75a55179 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:29:43 +0800 Subject: [PATCH 106/185] Create README.md [skip ci] --- .../src/main/java/com/baeldung/serialization/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/serialization/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/serialization/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/serialization/README.md new file mode 100644 index 0000000000..d9167fa3b8 --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/serialization/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Introduction to Java Serialization](https://www.baeldung.com/java-serialization) From f1e3f5bf07f72394b1ddd707f8bee595351d8d23 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:39:06 +0800 Subject: [PATCH 107/185] Create README.md [skip ci] --- .../core-java/src/main/java/com/baeldung/classloader/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/classloader/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/classloader/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/classloader/README.md new file mode 100644 index 0000000000..e26a3e2de9 --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/classloader/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Class Loaders in Java](https://www.baeldung.com/java-classloaders) From a23ec1d573a8d16e508400c23b06512e38c0a095 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:40:00 +0800 Subject: [PATCH 108/185] Create README.md [skip ci] --- .../core-java/src/main/java/com/baeldung/console/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/console/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/console/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/console/README.md new file mode 100644 index 0000000000..418892f288 --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/console/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Console I/O in Java](https://www.baeldung.com/java-console-input-output) From ec136b7e7123d303840325fd4bc8f4489755b491 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:40:54 +0800 Subject: [PATCH 109/185] Create README.md [skip ci] --- .../src/main/java/com/baeldung/abstractclasses/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/abstractclasses/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/abstractclasses/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/abstractclasses/README.md new file mode 100644 index 0000000000..8ded91b275 --- /dev/null +++ b/core-java-modules/core-java/src/main/java/com/baeldung/abstractclasses/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Abstract Classes in Java](https://www.baeldung.com/java-abstract-class/) From ab89eeb9a4781dac4c6086c94b42bb9007cdc4de Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:42:50 +0800 Subject: [PATCH 110/185] Create README.md [skip ci] --- core-java-modules/core-java-lambdas/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 core-java-modules/core-java-lambdas/README.md diff --git a/core-java-modules/core-java-lambdas/README.md b/core-java-modules/core-java-lambdas/README.md new file mode 100644 index 0000000000..10b876735e --- /dev/null +++ b/core-java-modules/core-java-lambdas/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?](https://www.baeldung.com/java-lambda-effectively-final-local-variables) From d0ed8bd21b97fa8cb99c8b18a9cd037e9fe5654c Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:48:53 +0800 Subject: [PATCH 111/185] Create README.md [skip ci] --- maven/profiles/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 maven/profiles/README.md diff --git a/maven/profiles/README.md b/maven/profiles/README.md new file mode 100644 index 0000000000..84b0a81ceb --- /dev/null +++ b/maven/profiles/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Guide to Maven Profiles](https://www.baeldung.com/maven-profiles) From 085258d234c74a3e359b28e41c401f7f37f5238d Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:50:24 +0800 Subject: [PATCH 112/185] Update README.md [skip ci] --- persistence-modules/spring-data-jpa-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-2/README.md b/persistence-modules/spring-data-jpa-2/README.md index 393d15d6f1..d35c05851b 100644 --- a/persistence-modules/spring-data-jpa-2/README.md +++ b/persistence-modules/spring-data-jpa-2/README.md @@ -12,3 +12,4 @@ - [Spring Data JPA Projections](https://www.baeldung.com/spring-data-jpa-projections) - [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable) - [Spring Data JPA Delete and Relationships](https://www.baeldung.com/spring-data-jpa-delete) +- [Spring Data JPA and Named Entity Graphs](https://www.baeldung.com/spring-data-jpa-named-entity-graphs) From 75103d1dacc0cedb91dd184bf3f504c1415e5d70 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:50:57 +0800 Subject: [PATCH 113/185] Update README.md [skip ci] --- persistence-modules/spring-data-jpa-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-2/README.md b/persistence-modules/spring-data-jpa-2/README.md index d35c05851b..8893b09286 100644 --- a/persistence-modules/spring-data-jpa-2/README.md +++ b/persistence-modules/spring-data-jpa-2/README.md @@ -13,3 +13,4 @@ - [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable) - [Spring Data JPA Delete and Relationships](https://www.baeldung.com/spring-data-jpa-delete) - [Spring Data JPA and Named Entity Graphs](https://www.baeldung.com/spring-data-jpa-named-entity-graphs) +- [Tagging and Filtering JUnit Tests](https://www.baeldung.com/junits-filtering-tests) From 50d6f0b8395c73fd7c5190cccef75700ac9fb39c Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:52:02 +0800 Subject: [PATCH 114/185] Update README.md [skip ci] --- persistence-modules/java-jpa/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index 34d03b3259..0426015045 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -8,3 +8,4 @@ - [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date) - [Combining JPA And/Or Criteria Predicates](https://www.baeldung.com/jpa-and-or-criteria-predicates) - [Types of JPA Queries](https://www.baeldung.com/jpa-queries) +- [Defining JPA Entities](https://www.baeldung.com/jpa-entities) From 0e01973ff661081a6a5fc02349dcd34f1454a45a Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:53:15 +0800 Subject: [PATCH 115/185] Create README.md [skip ci] --- quarkus/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 quarkus/README.md diff --git a/quarkus/README.md b/quarkus/README.md new file mode 100644 index 0000000000..01009eab3e --- /dev/null +++ b/quarkus/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [Guide to QuarkusIO](hhttps://www.baeldung.com/quarkus-io) From 384fe96e49c860500d3c473879d6379b282f7177 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:54:26 +0800 Subject: [PATCH 116/185] Update README.md [skip ci] --- persistence-modules/spring-data-jpa-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/spring-data-jpa-2/README.md b/persistence-modules/spring-data-jpa-2/README.md index 8893b09286..78a228986a 100644 --- a/persistence-modules/spring-data-jpa-2/README.md +++ b/persistence-modules/spring-data-jpa-2/README.md @@ -14,3 +14,4 @@ - [Spring Data JPA Delete and Relationships](https://www.baeldung.com/spring-data-jpa-delete) - [Spring Data JPA and Named Entity Graphs](https://www.baeldung.com/spring-data-jpa-named-entity-graphs) - [Tagging and Filtering JUnit Tests](https://www.baeldung.com/junits-filtering-tests) +- [Batch Insert/Update with Hibernate/JPA](https://www.baeldung.com/jpa-hibernate-batch-insert-update) From 25f7fe72c537bf2cd2ab9bdc996cdb182a15dc68 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:55:32 +0800 Subject: [PATCH 117/185] Create README.md [skip ci] --- apache-olingo/README.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 apache-olingo/README.md diff --git a/apache-olingo/README.md b/apache-olingo/README.md new file mode 100644 index 0000000000..bfbdc97700 --- /dev/null +++ b/apache-olingo/README.md @@ -0,0 +1,3 @@ +## Relevant articles: + +- [OData Protocol Guide](https://www.baeldung.com/odata) From e6c5d0024a15bc64ce0a4b733924a7e831c972b1 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:56:51 +0800 Subject: [PATCH 118/185] Update README.md [skip ci] --- persistence-modules/java-jpa/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index 0426015045..33d31781e0 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -9,3 +9,4 @@ - [Combining JPA And/Or Criteria Predicates](https://www.baeldung.com/jpa-and-or-criteria-predicates) - [Types of JPA Queries](https://www.baeldung.com/jpa-queries) - [Defining JPA Entities](https://www.baeldung.com/jpa-entities) +- [JPA @Basic Annotation](https://www.baeldung.com/jpa-basic-annotation) From 76c498f670fe2c7e2694cab33eaff4d865182104 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 16:57:44 +0800 Subject: [PATCH 119/185] Update README.md [skip ci] --- persistence-modules/java-jpa/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index 33d31781e0..ca9ec0d74d 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -10,3 +10,4 @@ - [Types of JPA Queries](https://www.baeldung.com/jpa-queries) - [Defining JPA Entities](https://www.baeldung.com/jpa-entities) - [JPA @Basic Annotation](https://www.baeldung.com/jpa-basic-annotation) +- [Default Column Values in JPA](https://www.baeldung.com/jpa-default-column-values) From 3e14bc38a016ffd710c1ae9fff970eaeac72adb4 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 17:01:36 +0800 Subject: [PATCH 120/185] Update README.md [skip ci] --- testing-modules/junit-5/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testing-modules/junit-5/README.md b/testing-modules/junit-5/README.md index 47db6587b4..d687b35cac 100644 --- a/testing-modules/junit-5/README.md +++ b/testing-modules/junit-5/README.md @@ -1,6 +1,5 @@ ### Relevant Articles: -- [The Basics of JUnit 5 – A Preview](http://www.baeldung.com/junit-5-preview) -- [A Guide to JUnit 5](http://www.baeldung.com/junit-5) +- [A Guide to JUnit 5](http://www.baeldung.com/junit-5-preview) - [A Guide to @RepeatedTest in Junit 5](http://www.baeldung.com/junit-5-repeated-test) - [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests) - [A Guide to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions) From 58538e329a10fb48238790649d997aedbfbfb338 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 17:03:14 +0800 Subject: [PATCH 121/185] Update README.md [skip ci] --- persistence-modules/spring-persistence-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md index c408ff3c96..12b7d025a9 100644 --- a/persistence-modules/spring-persistence-simple/README.md +++ b/persistence-modules/spring-persistence-simple/README.md @@ -6,7 +6,7 @@ ### Relevant Articles: - [A Guide to JPA with Spring](https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa) - [Bootstrapping Hibernate 5 with Spring](http://www.baeldung.com/hibernate-5-spring) -- [The DAO with Spring and Hibernate](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) +- [Simplify the DAO with Spring and Java Generics](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) - [DAO with Spring and Generics](https://www.baeldung.com/simplifying-the-data-access-layer-with-spring-and-java-generics) - [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring) - [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) From 92ec5af77c88e0218c13132e9a96a80e413503d3 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 17:03:39 +0800 Subject: [PATCH 122/185] Update README.md [skip ci] --- persistence-modules/spring-persistence-simple/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md index 12b7d025a9..ed81c9c564 100644 --- a/persistence-modules/spring-persistence-simple/README.md +++ b/persistence-modules/spring-persistence-simple/README.md @@ -9,7 +9,7 @@ - [Simplify the DAO with Spring and Java Generics](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) - [DAO with Spring and Generics](https://www.baeldung.com/simplifying-the-data-access-layer-with-spring-and-java-generics) - [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring) -- [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) +- [A Guide to JPA with Spring](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) - [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) - [Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate) From 287f589aeee4c26ba7064ea29e2bc52eddd1d62c Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 17:04:25 +0800 Subject: [PATCH 123/185] Update README.md [skip ci] --- core-java-modules/core-java-9/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java-modules/core-java-9/README.md b/core-java-modules/core-java-9/README.md index 5715520bae..8b52ce79b4 100644 --- a/core-java-modules/core-java-9/README.md +++ b/core-java-modules/core-java-9/README.md @@ -28,6 +28,6 @@ - [Java 9 Convenience Factory Methods for Collections](https://www.baeldung.com/java-9-collections-factory-methods) - [Java 9 Stream API Improvements](https://www.baeldung.com/java-9-stream-api) - [A Guide to Java 9 Modularity](https://www.baeldung.com/java-9-modularity) -- [Java 9 Platform Module API](https://www.baeldung.com/java-9-module-api) +- [Java 9 java.lang.Module API](https://www.baeldung.com/java-9-module-api) - [Java 9 Platform Logging API](https://www.baeldung.com/java-9-logging-api) - [Filtering a Stream of Optionals in Java](https://www.baeldung.com/java-filter-stream-of-optional) From 6072ddee005f6ce09e225de96037c32ff09ef92a Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 17:05:20 +0800 Subject: [PATCH 124/185] Update README.md [skip ci] --- persistence-modules/java-jpa/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index ca9ec0d74d..ae72e6b3c8 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -2,7 +2,7 @@ - [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping) - [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) -- [Fixing the JPA error “java.lang.String cannot be cast to Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) +- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) - [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph) - [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time) - [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date) From 47456f147da7814c161c4dae50b43702d76ea92b Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 17:05:43 +0800 Subject: [PATCH 125/185] Update README.md [skip ci] --- persistence-modules/java-jpa/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index ae72e6b3c8..554e10dc98 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -2,7 +2,7 @@ - [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping) - [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) -- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) +- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”]](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) - [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph) - [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time) - [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date) From 027b6b884021736acc8234872fb78afe62387f5b Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 17:53:15 +0800 Subject: [PATCH 126/185] Delete README.md --- .../src/main/java/com/baeldung/deserialization/README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/deserialization/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/README.md deleted file mode 100644 index 04b03e4907..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/deserialization/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant articles: - -- [What is the serialVersionUID?](https://www.baeldung.com/java-serial-version-uid) From 78ae20dc0e1602daf0699cabb8feb58aa9f151a3 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 18:12:37 +0800 Subject: [PATCH 127/185] Delete README.md --- .../core-java/src/main/java/com/baeldung/uuid/README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/uuid/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/uuid/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/uuid/README.md deleted file mode 100644 index bc464a4a1d..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/uuid/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant articles: - -- [Guide to UUID in Java](https://www.baeldung.com/java-uuid) From d7e2d7f59fe5908c5cb2cb74037341ba2ffac469 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 18:13:41 +0800 Subject: [PATCH 128/185] Delete README.md --- testing-modules/junit-5/README.md | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 testing-modules/junit-5/README.md diff --git a/testing-modules/junit-5/README.md b/testing-modules/junit-5/README.md deleted file mode 100644 index d687b35cac..0000000000 --- a/testing-modules/junit-5/README.md +++ /dev/null @@ -1,19 +0,0 @@ -### Relevant Articles: -- [A Guide to JUnit 5](http://www.baeldung.com/junit-5-preview) -- [A Guide to @RepeatedTest in Junit 5](http://www.baeldung.com/junit-5-repeated-test) -- [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests) -- [A Guide to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions) -- [Inject Parameters into JUnit Jupiter Unit Tests](http://www.baeldung.com/junit-5-parameters) -- [Mockito and JUnit 5 – Using ExtendWith](http://www.baeldung.com/mockito-junit-5-extension) -- [JUnit5 @RunWith](http://www.baeldung.com/junit-5-runwith) -- [JUnit 5 @Test Annotation](http://www.baeldung.com/junit-5-test-annotation) -- [Assert an Exception is Thrown in JUnit 4 and 5](http://www.baeldung.com/junit-assert-exception) -- [@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll](http://www.baeldung.com/junit-before-beforeclass-beforeeach-beforeall) -- [Migrating from JUnit 4 to JUnit 5](http://www.baeldung.com/junit-5-migration) -- [JUnit5 Programmatic Extension Registration with @RegisterExtension](http://www.baeldung.com/junit-5-registerextension-annotation) -- [The Order of Tests in JUnit](http://www.baeldung.com/junit-5-test-order) -- [Running JUnit Tests Programmatically, from a Java Application](https://www.baeldung.com/junit-tests-run-programmatically-from-java) -- [Testing an Abstract Class With JUnit](https://www.baeldung.com/junit-test-abstract-class) -- [A Quick JUnit vs TestNG Comparison](http://www.baeldung.com/junit-vs-testng) -- [Guide to JUnit 5 Parameterized Tests](https://www.baeldung.com/parameterized-tests-junit-5) -- [JUnit 5 Conditional Test Execution with Annotations](https://www.baeldung.com/junit-5-conditional-test-execution) From 8ff0bed3a49ce9fb9bd76f5a1831c5a21e74c5b4 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Fri, 24 May 2019 18:14:54 +0800 Subject: [PATCH 129/185] Delete README.md --- .../src/main/java/com/baeldung/serialization/README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/serialization/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/serialization/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/serialization/README.md deleted file mode 100644 index d9167fa3b8..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/serialization/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant articles: - -- [Introduction to Java Serialization](https://www.baeldung.com/java-serialization) From 1050337dabfb4c84512bbe4a4bf7087a35f55ee3 Mon Sep 17 00:00:00 2001 From: Liesheng Long Date: Fri, 24 May 2019 11:28:49 -0400 Subject: [PATCH 130/185] replace tabs with 4-spaces --- core-java-modules/core-java-8-2/pom.xml | 116 ++++++++++++------------ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/core-java-modules/core-java-8-2/pom.xml b/core-java-modules/core-java-8-2/pom.xml index 150f36be59..ff2e290086 100644 --- a/core-java-modules/core-java-8-2/pom.xml +++ b/core-java-modules/core-java-8-2/pom.xml @@ -1,67 +1,67 @@ - 4.0.0 - com.baeldung - core-java-8-2 - 0.1.0-SNAPSHOT - core-java-8-2 - jar + 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 + core-java-8-2 + 0.1.0-SNAPSHOT + core-java-8-2 + jar - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../../parent-java - + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + - - UTF-8 - 1.8 - 1.8 - 64.2 - 5.4.0.Final - 1.4.197 - 2.9.8 - + + UTF-8 + 1.8 + 1.8 + 64.2 + 5.4.0.Final + 1.4.197 + 2.9.8 + - - - com.ibm.icu - icu4j - ${icu.version} - - - org.hibernate - hibernate-core - ${hibernate.core.version} - - - com.h2database - h2 - ${h2database.version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.databind.version} - - + + + com.ibm.icu + icu4j + ${icu.version} + + + org.hibernate + hibernate-core + ${hibernate.core.version} + + + com.h2database + h2 + ${h2database.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.databind.version} + + - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${maven.compiler.source} - ${maven.compiler.target} - - - + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + - + From 93dfb77f1f9e8e86631014bf23b3621cd8ebf390 Mon Sep 17 00:00:00 2001 From: dionisPrifti Date: Fri, 24 May 2019 18:10:52 +0200 Subject: [PATCH 131/185] Bael 2810 data jpa delete (#6759) * BAEL-2810: Finished the examples and unit tests. * BAEL-2810: Changed assertions to isEqualTo * BAEL-2810: Changed the test of the derived query to reflect the number of the deleted records --- .../datajpadelete/DeleteFromRepositoryUnitTest.java | 10 +++++----- .../datajpadelete/DeleteInRelationshipsUnitTest.java | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java index 9e7e516735..5f4a36bc0e 100644 --- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteFromRepositoryUnitTest.java @@ -43,22 +43,22 @@ public class DeleteFromRepositoryUnitTest { public void whenDeleteByIdFromRepository_thenDeletingShouldBeSuccessful() { repository.deleteById(book1.getId()); - assertThat(repository.count() == 1).isTrue(); + assertThat(repository.count()).isEqualTo(1); } @Test public void whenDeleteAllFromRepository_thenRepositoryShouldBeEmpty() { repository.deleteAll(); - assertThat(repository.count() == 0).isTrue(); + assertThat(repository.count()).isEqualTo(0); } @Test @Transactional public void whenDeleteFromDerivedQuery_thenDeletingShouldBeSuccessful() { - repository.deleteByTitle("The Hobbit"); + long deletedRecords = repository.deleteByTitle("The Hobbit"); - assertThat(repository.count() == 1).isTrue(); + assertThat(deletedRecords).isEqualTo(1); } @Test @@ -66,7 +66,7 @@ public class DeleteFromRepositoryUnitTest { public void whenDeleteFromCustomQuery_thenDeletingShouldBeSuccessful() { repository.deleteBooks("The Hobbit"); - assertThat(repository.count() == 1).isTrue(); + assertThat(repository.count()).isEqualTo(1); } } \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java index 56de8749b2..6275ace6e0 100644 --- a/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java +++ b/persistence-modules/spring-data-jpa-2/src/test/java/com/baeldung/datajpadelete/DeleteInRelationshipsUnitTest.java @@ -46,15 +46,15 @@ public class DeleteInRelationshipsUnitTest { public void whenDeletingCategories_thenBooksShouldAlsoBeDeleted() { categoryRepository.deleteAll(); - assertThat(bookRepository.count() == 0).isTrue(); - assertThat(categoryRepository.count() == 0).isTrue(); + assertThat(bookRepository.count()).isEqualTo(0); + assertThat(categoryRepository.count()).isEqualTo(0); } @Test public void whenDeletingBooks_thenCategoriesShouldAlsoBeDeleted() { bookRepository.deleteAll(); - assertThat(bookRepository.count() == 0).isTrue(); - assertThat(categoryRepository.count() == 2).isTrue(); + assertThat(bookRepository.count()).isEqualTo(0); + assertThat(categoryRepository.count()).isEqualTo(2); } } \ No newline at end of file From d373336b74d9b70e5cee2144e406eb6d02c005bd Mon Sep 17 00:00:00 2001 From: binary-joe <48189951+binary-joe@users.noreply.github.com> Date: Fri, 24 May 2019 18:12:40 +0200 Subject: [PATCH 132/185] BAEL-2516 catching errors in catch block (#6761) --- .../com/baeldung/error/ErrorGenerator.java | 15 ++++++ .../error/ErrorGeneratorUnitTest.java | 51 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java create mode 100644 core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java diff --git a/core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java b/core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java new file mode 100644 index 0000000000..58cbe22df5 --- /dev/null +++ b/core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java @@ -0,0 +1,15 @@ +package com.baeldung.error; + +public class ErrorGenerator { + public void throwException() throws Exception { + throw new Exception("checked"); + } + + public void throwRuntimeException() { + throw new RuntimeException("unchecked"); + } + + public void throwError() { + throw new Error("unchecked"); + } +} diff --git a/core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java b/core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java new file mode 100644 index 0000000000..2a7c24f5fa --- /dev/null +++ b/core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.error; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ErrorGeneratorUnitTest { + + private ErrorGenerator errorGenerator; + + @Before + public void setUp() { + errorGenerator = new ErrorGenerator(); + } + + @Test + public void whenCheckedException_thenIsCaughtByCatchException() { + try { + errorGenerator.throwException(); + } catch (Exception e) { + // caught! -> test pass + } + } + + @Test + public void whenUncheckedException_thenIsCaughtByCatchException() { + try { + errorGenerator.throwRuntimeException(); + } catch (Exception e) { + // caught! -> test pass + } + } + + @Test(expected = Error.class) + public void whenError_thenIsNotCaughtByCatchException() { + try { + errorGenerator.throwError(); + } catch (Exception e) { + Assert.fail(); // errors are not caught by catch exception + } + } + + @Test + public void whenError_thenIsCaughtByCatchError() { + try { + errorGenerator.throwError(); + } catch (Error e) { + // caught! -> test pass + } + } +} \ No newline at end of file From c90f76a4f83977f214c1630934e8959c122bd577 Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Fri, 24 May 2019 17:24:47 +0100 Subject: [PATCH 133/185] Examples for Clojure Ring (#6881) --- clojure/ring/.gitignore | 12 +++++++++ clojure/ring/README.md | 16 ++++++++++++ clojure/ring/project.clj | 8 ++++++ clojure/ring/src/ring/core.clj | 48 ++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 clojure/ring/.gitignore create mode 100644 clojure/ring/README.md create mode 100644 clojure/ring/project.clj create mode 100644 clojure/ring/src/ring/core.clj diff --git a/clojure/ring/.gitignore b/clojure/ring/.gitignore new file mode 100644 index 0000000000..d18f225992 --- /dev/null +++ b/clojure/ring/.gitignore @@ -0,0 +1,12 @@ +/target +/classes +/checkouts +profiles.clj +pom.xml +pom.xml.asc +*.jar +*.class +/.lein-* +/.nrepl-port +.hgignore +.hg/ diff --git a/clojure/ring/README.md b/clojure/ring/README.md new file mode 100644 index 0000000000..3bc04ac129 --- /dev/null +++ b/clojure/ring/README.md @@ -0,0 +1,16 @@ +# Clojure Ring Examples + +This project acts as a set of examples for the Clojure Ring library. + +## Runing the examples + +The examples can all be run from the Leiningen REPL. + +Firstly, start the REPL with `lein repl`. Then the examples can be executed with: + +* `(run simple-handler)` - A simple handler that just echos a constant string to the client +* `(run check-ip-handler)` - A handler that echos the clients IP Address back to them +* `(run echo-handler)` - A handler that echos the value of the "input" parameter back +* `(run request-count-handler)` - A handler with a session that tracks how many times this session has requested this handler + +In all cases, the handlers can be accessed on http://localhost:3000. diff --git a/clojure/ring/project.clj b/clojure/ring/project.clj new file mode 100644 index 0000000000..7f2fcc4263 --- /dev/null +++ b/clojure/ring/project.clj @@ -0,0 +1,8 @@ +(defproject baeldung-ring "0.1.0-SNAPSHOT" + :dependencies [[org.clojure/clojure "1.10.0"] + [ring/ring-core "1.7.1"] + [ring/ring-jetty-adapter "1.7.1"] + [ring/ring-devel "1.7.1"]] + :plugins [[lein-ring "0.12.5"]] + :ring {:handler ring.core/simple-handler} + :repl-options {:init-ns ring.core}) diff --git a/clojure/ring/src/ring/core.clj b/clojure/ring/src/ring/core.clj new file mode 100644 index 0000000000..a56e2f2bde --- /dev/null +++ b/clojure/ring/src/ring/core.clj @@ -0,0 +1,48 @@ +(ns ring.core + (:use ring.adapter.jetty + [ring.middleware.content-type] + [ring.middleware.cookies] + [ring.middleware.params] + [ring.middleware.session] + [ring.middleware.session.cookie] + [ring.util.response])) + +;; Handler that just echos back the string "Hello World" +(defn simple-handler [request] + {:status 200 + :headers {"Content-Type" "text/plain"} + :body "Hello World"}) + +;; Handler that echos back the clients IP Address +;; This demonstrates building responses properly, and extracting values from the request +(defn check-ip-handler [request] + (content-type + (response (:remote-addr request)) + "text/plain")) + +;; Handler that echos back the incoming parameter "input" +;; This demonstrates middleware chaining and accessing parameters +(def echo-handler + (-> (fn [{params :params}] + (content-type + (response (get params "input")) + "text/plain")) + (wrap-params {:encoding "UTF-8"}) + )) + +;; Handler that keeps track of how many times each session has accessed the service +;; This demonstrates cookies and sessions +(def request-count-handler + (-> (fn [{session :session}] + (let [count (:count session 0) + session (assoc session :count (inc count))] + (-> (response (str "You accessed this page " count " times.")) + (assoc :session session)))) + wrap-cookies + (wrap-session {:cookie-attrs {:max-age 3600}}) + )) + +;; Run the provided handler on port 3000 +(defn run + [h] + (run-jetty h {:port 3000})) From b0c8a8473216d87c0223290a091db5d89aee1af2 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Fri, 24 May 2019 22:06:10 +0300 Subject: [PATCH 134/185] Update README.md --- testing-modules/junit-5-basics/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/testing-modules/junit-5-basics/README.md b/testing-modules/junit-5-basics/README.md index a00e2a3f4a..6e44a9c071 100644 --- a/testing-modules/junit-5-basics/README.md +++ b/testing-modules/junit-5-basics/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Get the Path of the /src/test/resources Directory in JUnit](https://www.baeldung.com/junit-src-test-resources-directory-path) +- [Tagging and Filtering JUnit Tests](https://www.baeldung.com/junit-filtering-tests) From 97358119cefe8142a14743c33af83cf898e9a292 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Fri, 24 May 2019 22:08:43 +0300 Subject: [PATCH 135/185] Update README.md --- clojure/ring/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clojure/ring/README.md b/clojure/ring/README.md index 3bc04ac129..20263c6b95 100644 --- a/clojure/ring/README.md +++ b/clojure/ring/README.md @@ -14,3 +14,6 @@ Firstly, start the REPL with `lein repl`. Then the examples can be executed with * `(run request-count-handler)` - A handler with a session that tracks how many times this session has requested this handler In all cases, the handlers can be accessed on http://localhost:3000. + +## Relevant Articles +- [Writing Clojure Webapps with Ring](https://www.baeldung.com/clojure-ring) From 8ce748420592a04edcf6139765e6e9b241d6b64d Mon Sep 17 00:00:00 2001 From: Loredana Date: Sat, 25 May 2019 21:32:32 +0300 Subject: [PATCH 136/185] downgrade surefire version --- .../{SubstringSearch.java => SubstringSearchUnitTest.java} | 2 +- pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename java-strings-2/src/test/java/com/baeldung/string/search/{SubstringSearch.java => SubstringSearchUnitTest.java} (98%) diff --git a/java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearch.java b/java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearchUnitTest.java similarity index 98% rename from java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearch.java rename to java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearchUnitTest.java index 4a5adb45ef..293e6d2125 100644 --- a/java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearch.java +++ b/java-strings-2/src/test/java/com/baeldung/string/search/SubstringSearchUnitTest.java @@ -10,7 +10,7 @@ import org.junit.Test; /** * BAEL-2832: Different ways to check if a Substring could be found in a String. */ -public class SubstringSearch { +public class SubstringSearchUnitTest { @Test public void searchSubstringWithIndexOf() { diff --git a/pom.xml b/pom.xml index bdd7562486..92876cd07f 100644 --- a/pom.xml +++ b/pom.xml @@ -1527,7 +1527,7 @@ 1.1.7 - 2.22.0 + 2.21.0 3.7.0 1.6.0 1.8 @@ -1538,7 +1538,7 @@ 1.19 1.3 1.6.0 - 2.19.1 + 2.21.0 2.5 1.4 3.0.0 From 148ff421e054dcade28e97de8463ed75d332938a Mon Sep 17 00:00:00 2001 From: Loredana Date: Sat, 25 May 2019 21:34:44 +0300 Subject: [PATCH 137/185] fix formatting --- .../com/baeldung/logging/slf4j/Slf4jLogger.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java index 1ff1087367..db19613c94 100644 --- a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java +++ b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java @@ -75,8 +75,6 @@ public class Slf4jLogger implements System.Logger { if (!isLoggable(level)) { return; } - String message = MessageFormat.format (format, params); - String message = MessageFormat.format(format, params); switch (level) { From 3471c4d22a5be5461089a2bc337216e9019c82e0 Mon Sep 17 00:00:00 2001 From: Loredana Date: Sat, 25 May 2019 21:52:00 +0300 Subject: [PATCH 138/185] update readme --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 378d77196a..1030cbb09c 100644 --- a/README.md +++ b/README.md @@ -20,17 +20,22 @@ In additional to Spring, the following technologies are in focus: `core Java`, ` Building the project ==================== -To do the full build, do: `mvn install -Pdefault -Dgib.enabled=false` +To do the full build, do: `mvn clean install` Building a single module ==================== -To build a specific module run the command: `mvn clean install -Dgib.enabled=false` in the module directory +To build a specific module run the command: `mvn clean install` in the module directory Running a Spring Boot module ==================== -To run a Spring Boot module run the command: `mvn spring-boot:run -Dgib.enabled=false` in the module directory +To run a Spring Boot module run the command: `mvn spring-boot:run` in the module directory + +#Running Tests + +The command `mvn clean install` will run the unit tests in a module. +To run the integration tests, use the command `mvn clean install -Pintegration-lite-first` From 924c78c996220210ab6ae59fcea0fe998e980626 Mon Sep 17 00:00:00 2001 From: Loredana Date: Sat, 25 May 2019 21:53:30 +0300 Subject: [PATCH 139/185] fix formatting --- .../com/baeldung/logging/slf4j/Slf4jLogger.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java index 1ff1087367..db19613c94 100644 --- a/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java +++ b/core-java-modules/core-java-9/src/modules/com.baeldung.logging.slf4j/com/baeldung/logging/slf4j/Slf4jLogger.java @@ -75,8 +75,6 @@ public class Slf4jLogger implements System.Logger { if (!isLoggable(level)) { return; } - String message = MessageFormat.format (format, params); - String message = MessageFormat.format(format, params); switch (level) { From fe2cf943d8423ef04c4c63c5532fa5d355bf253e Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sun, 26 May 2019 11:57:20 +0530 Subject: [PATCH 140/185] [BAEL-14777] - Added Thymeleaf example and added reoved xmls and commented out codes --- spring-security-rest-custom/pom.xml | 8 +++ .../org/baeldung/config/child/WebConfig.java | 41 +++++++++++++++ .../config/parent/SecurityConfig.java | 1 + .../web/controller/ViewController.java | 13 +++++ .../src/main/resources/prop.xml | 13 +++++ .../src/main/resources/webSecurityConfig.xml | 4 +- .../main/webapp/WEB-INF/templates/index.html | 7 +++ .../src/main/webapp/WEB-INF/web_old.xml | 51 +++++++++++++++++++ 8 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 spring-security-rest-custom/src/main/java/org/baeldung/web/controller/ViewController.java create mode 100644 spring-security-rest-custom/src/main/resources/prop.xml create mode 100644 spring-security-rest-custom/src/main/webapp/WEB-INF/templates/index.html create mode 100644 spring-security-rest-custom/src/main/webapp/WEB-INF/web_old.xml diff --git a/spring-security-rest-custom/pom.xml b/spring-security-rest-custom/pom.xml index 38cbfddab8..2180b917e5 100644 --- a/spring-security-rest-custom/pom.xml +++ b/spring-security-rest-custom/pom.xml @@ -26,6 +26,14 @@ org.springframework.security spring-security-config + + org.thymeleaf.extras + thymeleaf-extras-springsecurity5 + + + org.thymeleaf + thymeleaf-spring5 + diff --git a/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java b/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java index 6688d41ffa..7cbbcf31fa 100644 --- a/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java +++ b/spring-security-rest-custom/src/main/java/org/baeldung/config/child/WebConfig.java @@ -2,19 +2,34 @@ package org.baeldung.config.child; import java.util.List; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.thymeleaf.extras.springsecurity5.dialect.SpringSecurityDialect; +import org.thymeleaf.spring5.ISpringTemplateEngine; +import org.thymeleaf.spring5.SpringTemplateEngine; +import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; +import org.thymeleaf.spring5.view.ThymeleafViewResolver; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.templateresolver.ITemplateResolver; @Configuration @EnableWebMvc @ComponentScan("org.baeldung.web") +//@ImportResource({ "classpath:prop.xml" }) +//@PropertySource("classpath:foo.properties") public class WebConfig implements WebMvcConfigurer { + + @Autowired + private ApplicationContext applicationContext; public WebConfig() { super(); @@ -35,5 +50,31 @@ public class WebConfig implements WebMvcConfigurer { ppc.setIgnoreUnresolvablePlaceholders(true); return ppc; } + + @Bean + public ViewResolver viewResolver() { + ThymeleafViewResolver resolver = new ThymeleafViewResolver(); + resolver.setTemplateEngine(templateEngine()); + resolver.setCharacterEncoding("UTF-8"); + return resolver; + } + + @Bean + public ISpringTemplateEngine templateEngine() { + SpringTemplateEngine engine = new SpringTemplateEngine(); + engine.setEnableSpringELCompiler(true); + engine.setTemplateResolver(templateResolver()); + engine.addDialect(new SpringSecurityDialect()); + return engine; + } + + private ITemplateResolver templateResolver() { + SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver(); + resolver.setApplicationContext(applicationContext); + resolver.setPrefix("/WEB-INF/templates/"); + resolver.setSuffix(".html"); + resolver.setTemplateMode(TemplateMode.HTML); + return resolver; + } } \ No newline at end of file diff --git a/spring-security-rest-custom/src/main/java/org/baeldung/config/parent/SecurityConfig.java b/spring-security-rest-custom/src/main/java/org/baeldung/config/parent/SecurityConfig.java index 74e2df2174..fb3880a33f 100644 --- a/spring-security-rest-custom/src/main/java/org/baeldung/config/parent/SecurityConfig.java +++ b/spring-security-rest-custom/src/main/java/org/baeldung/config/parent/SecurityConfig.java @@ -10,6 +10,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration +//@ImportResource({ "classpath:webSecurityConfig.xml" }) @EnableWebSecurity @ComponentScan("org.baeldung.security") public class SecurityConfig extends WebSecurityConfigurerAdapter { diff --git a/spring-security-rest-custom/src/main/java/org/baeldung/web/controller/ViewController.java b/spring-security-rest-custom/src/main/java/org/baeldung/web/controller/ViewController.java new file mode 100644 index 0000000000..83c0292d98 --- /dev/null +++ b/spring-security-rest-custom/src/main/java/org/baeldung/web/controller/ViewController.java @@ -0,0 +1,13 @@ +package org.baeldung.web.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class ViewController { + + @RequestMapping({ "/index", "/" }) + public String index() { + return "index"; + } +} diff --git a/spring-security-rest-custom/src/main/resources/prop.xml b/spring-security-rest-custom/src/main/resources/prop.xml new file mode 100644 index 0000000000..edaecde655 --- /dev/null +++ b/spring-security-rest-custom/src/main/resources/prop.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml b/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml index fa5dc894bf..790b1b1716 100644 --- a/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml +++ b/spring-security-rest-custom/src/main/resources/webSecurityConfig.xml @@ -2,9 +2,9 @@ diff --git a/spring-security-rest-custom/src/main/webapp/WEB-INF/templates/index.html b/spring-security-rest-custom/src/main/webapp/WEB-INF/templates/index.html new file mode 100644 index 0000000000..31cb66ae0a --- /dev/null +++ b/spring-security-rest-custom/src/main/webapp/WEB-INF/templates/index.html @@ -0,0 +1,7 @@ + + + +
Authenticated as
+ + \ No newline at end of file diff --git a/spring-security-rest-custom/src/main/webapp/WEB-INF/web_old.xml b/spring-security-rest-custom/src/main/webapp/WEB-INF/web_old.xml new file mode 100644 index 0000000000..0fa9abd258 --- /dev/null +++ b/spring-security-rest-custom/src/main/webapp/WEB-INF/web_old.xml @@ -0,0 +1,51 @@ + + + + Spring Security Custom Application + + + + contextClass + + org.springframework.web.context.support.AnnotationConfigWebApplicationContext + + + + contextConfigLocation + org.baeldung.config.parent + + + + org.springframework.web.context.ContextLoaderListener + + + + + api + org.springframework.web.servlet.DispatcherServlet + + + + + 1 + + + api + /api/* + + + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + springSecurityFilterChain + /* + + + \ No newline at end of file From 066cf2d6f2d9122a648ce016aa31412cd22bd4c2 Mon Sep 17 00:00:00 2001 From: Matt Zhang Date: Sun, 26 May 2019 22:14:10 +1000 Subject: [PATCH 141/185] BAEL-2878 Guide to Spring's ApplicationContextRunner --- .../autoconfiguration/ConditionalOnBeanIntegrationTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java index c94b432b9d..32f63edde4 100644 --- a/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java +++ b/spring-boot-autoconfiguration/src/test/java/com/baeldung/autoconfiguration/ConditionalOnBeanIntegrationTest.java @@ -15,7 +15,7 @@ public class ConditionalOnBeanIntegrationTest { @Test public void whenDependentBeanIsPresent_thenConditionalBeanCreated() { - this.contextRunner.withUserConfiguration(basicConfiguration.class, ConditionalOnBeanConfiguration.class) + this.contextRunner.withUserConfiguration(BasicConfiguration.class, ConditionalOnBeanConfiguration.class) .run((context) -> { assertThat(context).hasBean("created"); assertThat(context).getBean("created") @@ -28,7 +28,7 @@ public class ConditionalOnBeanIntegrationTest { @Test public void whenDependentBeanIsPresent_thenConditionalMissingBeanIgnored() { - this.contextRunner.withUserConfiguration(basicConfiguration.class, ConditionalOnMissingBeanConfiguration.class) + this.contextRunner.withUserConfiguration(BasicConfiguration.class, ConditionalOnMissingBeanConfiguration.class) .run((context) -> { assertThat(context).hasBean("created"); assertThat(context).getBean("created") @@ -49,7 +49,7 @@ public class ConditionalOnBeanIntegrationTest { } @Configuration - protected static class basicConfiguration { + protected static class BasicConfiguration { @Bean public String created() { return "This is always created"; From f4c7976dfe9cc892a492ad7538581c07128a7596 Mon Sep 17 00:00:00 2001 From: Loredana Date: Sun, 26 May 2019 17:34:11 +0300 Subject: [PATCH 142/185] fix parent readmes --- patterns/README.md | 6 ------ patterns/design-patterns-2/README.md | 2 ++ patterns/dip/README.md | 3 +++ patterns/front-controller/README.md | 2 ++ patterns/intercepting-filter/README.md | 2 ++ patterns/{principles => }/solid/README.md | 0 persistence-modules/README.md | 17 --------------- .../hibernate-mapping/README.md | 1 + persistence-modules/java-jdbi/README.md | 2 ++ .../spring-data-jpa-2/README.md | 1 + .../spring-hibernate-5/README.md | 1 + spring-cloud/README.md | 21 ------------------- spring-cloud/spring-cloud-aws/README.md | 1 + spring-cloud/spring-cloud-config/README.md | 1 + spring-cloud/spring-cloud-openfeign/README.md | 4 ++++ spring-rest/README.md | 1 + .../java/com/baeldung/produceimage/README.md | 3 --- 17 files changed, 21 insertions(+), 47 deletions(-) delete mode 100644 patterns/README.md create mode 100644 patterns/dip/README.md create mode 100644 patterns/front-controller/README.md create mode 100644 patterns/intercepting-filter/README.md rename patterns/{principles => }/solid/README.md (100%) delete mode 100644 persistence-modules/README.md delete mode 100644 spring-cloud/README.md create mode 100644 spring-cloud/spring-cloud-openfeign/README.md delete mode 100644 spring-rest/src/main/java/com/baeldung/produceimage/README.md diff --git a/patterns/README.md b/patterns/README.md deleted file mode 100644 index f627251aa4..0000000000 --- a/patterns/README.md +++ /dev/null @@ -1,6 +0,0 @@ -### Relevant Articles: -- [A Guide to the Front Controller Pattern in Java](http://www.baeldung.com/java-front-controller-pattern) -- [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java) -- [Introduction to the Null Object Pattern](https://www.baeldung.com/java-null-object-pattern) -- [The Dependency Inversion Principle in Java](https://www.baeldung.com/java-dependency-inversion-principle) -- [Avoid Check for Null Statement in Java](https://www.baeldung.com/java-avoid-null-check) diff --git a/patterns/design-patterns-2/README.md b/patterns/design-patterns-2/README.md index c2a75d4680..8e4ef657e1 100644 --- a/patterns/design-patterns-2/README.md +++ b/patterns/design-patterns-2/README.md @@ -1,3 +1,5 @@ ### Relevant Articles - [The Mediator Pattern in Java](https://www.baeldung.com/java-mediator-pattern) +- [Introduction to the Null Object Pattern](https://www.baeldung.com/java-null-object-pattern) +- [Avoid Check for Null Statement in Java](https://www.baeldung.com/java-avoid-null-check) diff --git a/patterns/dip/README.md b/patterns/dip/README.md new file mode 100644 index 0000000000..8876bbe766 --- /dev/null +++ b/patterns/dip/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [The Dependency Inversion Principle in Java](https://www.baeldung.com/java-dependency-inversion-principle) diff --git a/patterns/front-controller/README.md b/patterns/front-controller/README.md new file mode 100644 index 0000000000..5f8cb5d568 --- /dev/null +++ b/patterns/front-controller/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [A Guide to the Front Controller Pattern in Java](http://www.baeldung.com/java-front-controller-pattern) diff --git a/patterns/intercepting-filter/README.md b/patterns/intercepting-filter/README.md new file mode 100644 index 0000000000..88b7f58469 --- /dev/null +++ b/patterns/intercepting-filter/README.md @@ -0,0 +1,2 @@ +### Relevant Articles: +- [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java) diff --git a/patterns/principles/solid/README.md b/patterns/solid/README.md similarity index 100% rename from patterns/principles/solid/README.md rename to patterns/solid/README.md diff --git a/persistence-modules/README.md b/persistence-modules/README.md deleted file mode 100644 index e9a7d625cc..0000000000 --- a/persistence-modules/README.md +++ /dev/null @@ -1,17 +0,0 @@ - -## Persistence Modules - - -### Relevant Articles: - -- [Introduction to Hibernate Search](http://www.baeldung.com/hibernate-search) -- [Introduction to Lettuce – the Java Redis Client](http://www.baeldung.com/java-redis-lettuce) -- [A Guide to Jdbi](http://www.baeldung.com/jdbi) -- [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking) -- [Get All Data from a Table with Hibernate](https://www.baeldung.com/hibernate-select-all) -- [Spring Data with Reactive Cassandra](https://www.baeldung.com/spring-data-cassandra-reactive) -- [Spring Data JPA – Derived Delete Methods](https://www.baeldung.com/spring-data-jpa-deleteby) -- [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush) -- [Spring Boot with Hibernate](https://www.baeldung.com/spring-boot-hibernate) -- [Persisting Maps with Hibernate](https://www.baeldung.com/hibernate-persisting-maps) -- [Difference Between @Size, @Length, and @Column(length=value)](https://www.baeldung.com/jpa-size-length-column-differences) diff --git a/persistence-modules/hibernate-mapping/README.md b/persistence-modules/hibernate-mapping/README.md index 223d93e1ed..203cb2f8e4 100644 --- a/persistence-modules/hibernate-mapping/README.md +++ b/persistence-modules/hibernate-mapping/README.md @@ -2,3 +2,4 @@ ### Relevant Articles: - [Persisting Maps with Hibernate](https://www.baeldung.com/hibernate-persisting-maps) +- [Difference Between @Size, @Length, and @Column(length=value)](https://www.baeldung.com/jpa-size-length-column-differences) diff --git a/persistence-modules/java-jdbi/README.md b/persistence-modules/java-jdbi/README.md index 7d843af9ea..4c1ff931ce 100644 --- a/persistence-modules/java-jdbi/README.md +++ b/persistence-modules/java-jdbi/README.md @@ -1 +1,3 @@ ### Relevant Articles: + +- [A Guide to Jdbi](http://www.baeldung.com/jdbi) diff --git a/persistence-modules/spring-data-jpa-2/README.md b/persistence-modules/spring-data-jpa-2/README.md index 393d15d6f1..e4381be0a9 100644 --- a/persistence-modules/spring-data-jpa-2/README.md +++ b/persistence-modules/spring-data-jpa-2/README.md @@ -12,3 +12,4 @@ - [Spring Data JPA Projections](https://www.baeldung.com/spring-data-jpa-projections) - [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable) - [Spring Data JPA Delete and Relationships](https://www.baeldung.com/spring-data-jpa-delete) +- [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush) diff --git a/persistence-modules/spring-hibernate-5/README.md b/persistence-modules/spring-hibernate-5/README.md index c48e58fcca..dfcc4e7eb8 100644 --- a/persistence-modules/spring-hibernate-5/README.md +++ b/persistence-modules/spring-hibernate-5/README.md @@ -3,3 +3,4 @@ - [Hibernate Many to Many Annotation Tutorial](http://www.baeldung.com/hibernate-many-to-many) - [Programmatic Transactions in the Spring TestContext Framework](http://www.baeldung.com/spring-test-programmatic-transactions) - [JPA Criteria Queries](http://www.baeldung.com/hibernate-criteria-queries) +- [Introduction to Hibernate Search](http://www.baeldung.com/hibernate-search) diff --git a/spring-cloud/README.md b/spring-cloud/README.md deleted file mode 100644 index 5139cdca20..0000000000 --- a/spring-cloud/README.md +++ /dev/null @@ -1,21 +0,0 @@ -## The Module Holds Sources for the Following Articles - -- [Quick Intro to Spring Cloud Configuration](http://www.baeldung.com/spring-cloud-configuration) - - Spring Cloud Config is Spring’s client/server approach for storing and serving distributed configurations across multiple applications and environments. - - In this write-up, we’ll focus on an example of how to setup a Git-backed config server, use it in a simple REST application server and setup a secure environment including encrypted property values. - -- [Introduction to Spring Cloud Netflix – Eureka](http://www.baeldung.com/spring-cloud-netflix-eureka) - - In this article, we’ll introduce client-side service discovery via “Spring Cloud Netflix Eureka“. - - Client-side service discovery allows services to find and communicate with each other without hardcoding hostname and port. The only ‘fixed point’ in such an architecture consists of a service registry with which each service has to register. - -### Relevant Articles: -- [Intro to Spring Cloud Netflix - Hystrix](http://www.baeldung.com/spring-cloud-netflix-hystrix) -- [Dockerizing a Spring Boot Application](http://www.baeldung.com/dockerizing-spring-boot-application) -- [Instance Profile Credentials using Spring Cloud](http://www.baeldung.com/spring-cloud-instance-profiles) -- [Running Spring Boot Applications With Minikube](http://www.baeldung.com/spring-boot-minikube) -- [Introduction to Spring Cloud OpenFeign](https://www.baeldung.com/spring-cloud-openfeign) - diff --git a/spring-cloud/spring-cloud-aws/README.md b/spring-cloud/spring-cloud-aws/README.md index 3b7b4dbcd7..bf33728c74 100644 --- a/spring-cloud/spring-cloud-aws/README.md +++ b/spring-cloud/spring-cloud-aws/README.md @@ -5,6 +5,7 @@ - [Spring Cloud AWS – EC2](https://www.baeldung.com/spring-cloud-aws-ec2) - [Spring Cloud AWS – RDS](https://www.baeldung.com/spring-cloud-aws-rds) - [Spring Cloud AWS – Messaging Support](https://www.baeldung.com/spring-cloud-aws-messaging) +- [Instance Profile Credentials using Spring Cloud](http://www.baeldung.com/spring-cloud-instance-profiles) #### Running the Integration Tests diff --git a/spring-cloud/spring-cloud-config/README.md b/spring-cloud/spring-cloud-config/README.md index b28c750ee6..b7c8c36e65 100644 --- a/spring-cloud/spring-cloud-config/README.md +++ b/spring-cloud/spring-cloud-config/README.md @@ -1,2 +1,3 @@ ### Relevant Articles: +- [Quick Intro to Spring Cloud Configuration](http://www.baeldung.com/spring-cloud-configuration) - [Dockerizing a Spring Boot Application](http://www.baeldung.com/dockerizing-spring-boot-application) diff --git a/spring-cloud/spring-cloud-openfeign/README.md b/spring-cloud/spring-cloud-openfeign/README.md new file mode 100644 index 0000000000..e5777732e4 --- /dev/null +++ b/spring-cloud/spring-cloud-openfeign/README.md @@ -0,0 +1,4 @@ +### Relevant Articles: + +- [Introduction to Spring Cloud OpenFeign](https://www.baeldung.com/spring-cloud-openfeign) + diff --git a/spring-rest/README.md b/spring-rest/README.md index 6d3aac3eb8..5d7894cdf8 100644 --- a/spring-rest/README.md +++ b/spring-rest/README.md @@ -21,3 +21,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Get and Post Lists of Objects with RestTemplate](http://www.baeldung.com/spring-rest-template-list) - [How to Set a Header on a Response with Spring 5](http://www.baeldung.com/spring-response-header) - [Uploading MultipartFile with Spring RestTemplate](http://www.baeldung.com/spring-rest-template-multipart-upload) +- [Download an Image or a File with Spring MVC](http://www.baeldung.com/spring-controller-return-image-file) diff --git a/spring-rest/src/main/java/com/baeldung/produceimage/README.md b/spring-rest/src/main/java/com/baeldung/produceimage/README.md deleted file mode 100644 index 4aeadea546..0000000000 --- a/spring-rest/src/main/java/com/baeldung/produceimage/README.md +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant articles - -- [Download an Image or a File with Spring MVC](http://www.baeldung.com/spring-controller-return-image-file) From 9b7a362b4d3c18029fe7b89d34a4bdf4c695ea23 Mon Sep 17 00:00:00 2001 From: Loredana Date: Sun, 26 May 2019 17:54:15 +0300 Subject: [PATCH 143/185] add surefire comment --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 92876cd07f..39803fd9b0 100644 --- a/pom.xml +++ b/pom.xml @@ -1527,6 +1527,7 @@ 1.1.7 + 2.21.0 3.7.0 1.6.0 From 8ac77800a0a6a3f1e114fab18d7a721949302780 Mon Sep 17 00:00:00 2001 From: Loredana Date: Sun, 26 May 2019 19:38:40 +0300 Subject: [PATCH 144/185] fix remove vertex --- .../main/java/com/baeldung/graph/Graph.java | 2 +- ...versalUnitTest.java => GraphUnitTest.java} | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) rename core-java-modules/core-java/src/test/java/com/baeldung/graph/{GraphTraversalUnitTest.java => GraphUnitTest.java} (61%) diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/graph/Graph.java b/core-java-modules/core-java/src/main/java/com/baeldung/graph/Graph.java index 3f2e17c43c..58713b1b3f 100644 --- a/core-java-modules/core-java/src/main/java/com/baeldung/graph/Graph.java +++ b/core-java-modules/core-java/src/main/java/com/baeldung/graph/Graph.java @@ -19,7 +19,7 @@ public class Graph { void removeVertex(String label) { Vertex v = new Vertex(label); - adjVertices.values().stream().map(e -> e.remove(v)).collect(Collectors.toList()); + adjVertices.values().stream().forEach(e -> e.remove(v)); adjVertices.remove(new Vertex(label)); } diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/graph/GraphTraversalUnitTest.java b/core-java-modules/core-java/src/test/java/com/baeldung/graph/GraphUnitTest.java similarity index 61% rename from core-java-modules/core-java/src/test/java/com/baeldung/graph/GraphTraversalUnitTest.java rename to core-java-modules/core-java/src/test/java/com/baeldung/graph/GraphUnitTest.java index d955d56d95..68611e508b 100644 --- a/core-java-modules/core-java/src/test/java/com/baeldung/graph/GraphTraversalUnitTest.java +++ b/core-java-modules/core-java/src/test/java/com/baeldung/graph/GraphUnitTest.java @@ -1,20 +1,31 @@ package com.baeldung.graph; -import org.junit.Assert; +import static org.junit.Assert.assertEquals; import org.junit.Test; -public class GraphTraversalUnitTest { +public class GraphUnitTest { @Test public void givenAGraph_whenTraversingDepthFirst_thenExpectedResult() { Graph graph = createGraph(); - Assert.assertEquals("[Bob, Rob, Maria, Alice, Mark]", + assertEquals("[Bob, Rob, Maria, Alice, Mark]", GraphTraversal.depthFirstTraversal(graph, "Bob").toString()); } @Test public void givenAGraph_whenTraversingBreadthFirst_thenExpectedResult() { Graph graph = createGraph(); - Assert.assertEquals("[Bob, Alice, Rob, Mark, Maria]", + assertEquals("[Bob, Alice, Rob, Mark, Maria]", + GraphTraversal.breadthFirstTraversal(graph, "Bob").toString()); + } + + @Test + public void givenAGraph_whenRemoveVertex_thenVertedNotFound() { + Graph graph = createGraph(); + assertEquals("[Bob, Alice, Rob, Mark, Maria]", + GraphTraversal.breadthFirstTraversal(graph, "Bob").toString()); + + graph.removeVertex("Maria"); + assertEquals("[Bob, Alice, Rob, Mark]", GraphTraversal.breadthFirstTraversal(graph, "Bob").toString()); } From 7ff1bc1aea5568146330db5f575edebc295e9be0 Mon Sep 17 00:00:00 2001 From: andrea-ligios Date: Sun, 26 May 2019 20:22:55 +0200 Subject: [PATCH 145/185] BAEL-2758 --- docker/docker-compose.yml | 61 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 docker/docker-compose.yml diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000000..72d07d6392 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,61 @@ +version: '3' + +services: + +## VOLUME CONTAINER-TO-CONTAINER AND HOST-TO-CONTAINER TEST ## + + volumes-example-service: + image: alpine:latest + container_name: volumes-example-service + volumes: + - /tmp:/my-volumes/host-volume + - /home:/my-volumes/readonly-host-volume:ro + - my-named-global-volume:/my-volumes/named-global-volume + tty: true # Needed to keep the container running + + another-volumes-example-service: + image: alpine:latest + container_name: another-volumes-example-service + volumes: + - my-named-global-volume:/another-path/the-same-named-global-volume + tty: true # Needed to keep the container running + +## NETWORK CONTAINER-TO-CONTAINER TEST ## + + network-example-service: + image: karthequian/helloworld:latest + container_name: network-example-service + networks: + - my-shared-network + + another-service-in-the-same-network: + image: alpine:latest + container_name: another-service-in-the-same-network + networks: + - my-shared-network + + tty: true # Needed to keep the container running + + another-service-in-its-own-network: + image: alpine:latest + container_name: another-service-in-its-own-network + networks: + - my-private-network + tty: true # Needed to keep the container running + +## NETWORK HOST-TO-CONTAINER TEST ## + + network-example-service-available-to-host-on-port-1337: + image: karthequian/helloworld:latest + container_name: network-example-service-available-to-host-on-port-1337 + networks: + - my-shared-network + ports: + - "1337:80" + +volumes: + my-named-global-volume: + +networks: + my-shared-network: {} + my-private-network: {} From 0c1da760a6739d2f5a2e38e2eea77e3ebb286d14 Mon Sep 17 00:00:00 2001 From: DOHA Date: Sun, 26 May 2019 21:37:30 +0200 Subject: [PATCH 146/185] geospatial mongoldb examples --- .../geo/MongoGeospatialIntegrationTest.java | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialIntegrationTest.java diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialIntegrationTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialIntegrationTest.java new file mode 100644 index 0000000000..77cbe02e7f --- /dev/null +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialIntegrationTest.java @@ -0,0 +1,110 @@ +package com.baeldung.geo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.bson.Document; +import org.junit.Before; +import org.junit.Test; + +import com.mongodb.MongoClient; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Indexes; +import com.mongodb.client.model.geojson.Point; +import com.mongodb.client.model.geojson.Polygon; +import com.mongodb.client.model.geojson.Position; + +public class MongoGeospatialIntegrationTest { + + private MongoClient mongoClient; + private MongoDatabase db; + private MongoCollection collection; + + @Before + public void setup() { + if (mongoClient == null) { + mongoClient = new MongoClient(); + db = mongoClient.getDatabase("myMongoDb"); + collection = db.getCollection("places"); + collection.deleteMany(new Document()); + collection.createIndex(Indexes.geo2dsphere("location")); + collection.insertOne(Document.parse("{'name':'Big Ben','location': {'coordinates':[-0.1268194,51.5007292],'type':'Point'}}")); + collection.insertOne(Document.parse("{'name':'Hyde Park','location': {'coordinates': [[[-0.159381,51.513126],[-0.189615,51.509928],[-0.187373,51.502442], [-0.153019,51.503464],[-0.159381,51.513126]]],'type':'Polygon'}}")); + } + } + + @Test + public void givenNearbyLocation_whenSearchNearby_thenFound() { + Point currentLoc = new Point(new Position(-0.126821, 51.495885)); + FindIterable result = collection.find(Filters.near("location", currentLoc, 1000.0, 10.0)); + + assertNotNull(result.first()); + assertEquals("Big Ben", result.first().get("name")); + } + + @Test + public void givenFarLocation_whenSearchNearby_thenNotFound() { + Point currentLoc = new Point(new Position(-0.5243333, 51.4700223)); + FindIterable result = collection.find(Filters.near("location", currentLoc, 5000.0, 10.0)); + + assertNull(result.first()); + } + + @Test + public void givenNearbyLocation_whenSearchWithinCircleSphere_thenFound() { + double distanceInRad = 5.0 / 6371; + FindIterable result = collection.find(Filters.geoWithinCenterSphere("location", -0.1435083, 51.4990956, distanceInRad)); + + assertNotNull(result.first()); + assertEquals("Big Ben", result.first().get("name")); + } + + @Test + public void givenNearbyLocation_whenSearchWithinBox_thenFound() { + double lowerLeftX = -0.1427638; + double lowerLeftY = 51.4991288; + double upperRightX = -0.1256209; + double upperRightY = 51.5030272; + + FindIterable result = collection.find(Filters.geoWithinBox("location", lowerLeftX, lowerLeftY, upperRightX, upperRightY)); + + assertNotNull(result.first()); + assertEquals("Big Ben", result.first().get("name")); + } + + @Test + public void givenNearbyLocation_whenSearchWithinPolygon_thenFound() { + ArrayList> points = new ArrayList>(); + points.add(Arrays.asList(-0.1439, 51.4952)); // victoria station + points.add(Arrays.asList(-0.1121, 51.4989));// Lambeth North + points.add(Arrays.asList(-0.13, 51.5163));// Tottenham Court Road + points.add(Arrays.asList(-0.1439, 51.4952)); // victoria station + FindIterable result = collection.find(Filters.geoWithinPolygon("location", points)); + + assertNotNull(result.first()); + assertEquals("Big Ben", result.first().get("name")); + } + + @Test + public void givenNearbyLocation_whenSearchUsingIntersect_thenFound() { + ArrayList positions = new ArrayList(); + positions.add(new Position(-0.1439, 51.4952)); + positions.add(new Position(-0.1346, 51.4978)); + positions.add(new Position(-0.2177, 51.5135)); + positions.add(new Position(-0.1439, 51.4952)); + Polygon geometry = new Polygon(positions); + FindIterable result = collection.find(Filters.geoIntersects("location", geometry)); + + assertNotNull(result.first()); + assertEquals("Hyde Park", result.first().get("name")); + } + +} From 5b11cef14bbbfbf5b5e6f7b1f8019a4dadb8fece Mon Sep 17 00:00:00 2001 From: mikr Date: Mon, 27 May 2019 00:32:25 +0200 Subject: [PATCH 147/185] BAEL-2891 Add a new section in the Mockito Annotations article --- .../mockito/MockitoInjectIntoSpyUnitTest.java | 38 +++++++++++++++++++ .../org/baeldung/mockito/MyDictionary.java | 4 ++ 2 files changed, 42 insertions(+) create mode 100644 testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoInjectIntoSpyUnitTest.java diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoInjectIntoSpyUnitTest.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoInjectIntoSpyUnitTest.java new file mode 100644 index 0000000000..4f5ceb04e7 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MockitoInjectIntoSpyUnitTest.java @@ -0,0 +1,38 @@ +package org.baeldung.mockito; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.*; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +@RunWith(MockitoJUnitRunner.class) +public class MockitoInjectIntoSpyUnitTest { + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + spyDic = Mockito.spy(new MyDictionary(wordMap)); + } + + @Mock + private Map wordMap; + + @InjectMocks + private MyDictionary dic = new MyDictionary(); + + private MyDictionary spyDic; + + @Test + public void whenUseInjectMocksAnnotation_thenCorrect2() { + Mockito.when(wordMap.get("aWord")).thenReturn("aMeaning"); + + assertEquals("aMeaning", spyDic.getMeaning("aWord")); + } +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyDictionary.java b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyDictionary.java index 8a0ea92502..9492c90d11 100644 --- a/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyDictionary.java +++ b/testing-modules/mockito/src/test/java/org/baeldung/mockito/MyDictionary.java @@ -11,6 +11,10 @@ class MyDictionary { wordMap = new HashMap<>(); } + MyDictionary(Map wordMap) { + this.wordMap = wordMap; + } + public void add(final String word, final String meaning) { wordMap.put(word, meaning); } From 60d26bfd0988d13bfa764015464620a95df8a59d Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 27 May 2019 14:16:09 +0800 Subject: [PATCH 148/185] Delete README.md --- core-java-modules/core-java/src/main/java/com/baeldung/README.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/README.md deleted file mode 100644 index 7d843af9ea..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/README.md +++ /dev/null @@ -1 +0,0 @@ -### Relevant Articles: From f6b9546f75f4f756900feadd1d8534dc1170e9c8 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 27 May 2019 14:17:22 +0800 Subject: [PATCH 149/185] Delete README.md --- .../core-java/src/main/java/com/baeldung/console/README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/console/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/console/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/console/README.md deleted file mode 100644 index 418892f288..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/console/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant articles: - -- [Console I/O in Java](https://www.baeldung.com/java-console-input-output) From 8a71e4d4375d7e70ee9f8acb85ba82b251f882af Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 27 May 2019 14:17:47 +0800 Subject: [PATCH 150/185] Delete README.md --- .../src/main/java/com/baeldung/abstractclasses/README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/abstractclasses/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/abstractclasses/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/abstractclasses/README.md deleted file mode 100644 index 8ded91b275..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/abstractclasses/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant articles: - -- [Abstract Classes in Java](https://www.baeldung.com/java-abstract-class/) From e5d4480c49288a934972e5b46755e34a9cc19230 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 27 May 2019 14:19:02 +0800 Subject: [PATCH 151/185] Delete README.md --- maven/profiles/README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 maven/profiles/README.md diff --git a/maven/profiles/README.md b/maven/profiles/README.md deleted file mode 100644 index 84b0a81ceb..0000000000 --- a/maven/profiles/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant articles: - -- [Guide to Maven Profiles](https://www.baeldung.com/maven-profiles) From 6a192689cbe232ad33f517554ef4daa2b1ce4c23 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 27 May 2019 14:19:26 +0800 Subject: [PATCH 152/185] Update README.md --- maven/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/maven/README.md b/maven/README.md index ca648ec203..6d1a7081b7 100644 --- a/maven/README.md +++ b/maven/README.md @@ -16,3 +16,4 @@ - [Multi-Module Project with Maven](https://www.baeldung.com/maven-multi-module) - [Maven Enforcer Plugin](https://www.baeldung.com/maven-enforcer-plugin) - [Eclipse Error: web.xml is missing and failOnMissingWebXml is set to true](https://www.baeldung.com/eclipse-error-web-xml-missing) +- [Guide to Maven Profiles](https://www.baeldung.com/maven-profiles) From ab7d29dbb3ab248456c7417be888775a9a73dcdb Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 27 May 2019 14:37:51 +0800 Subject: [PATCH 153/185] Create README.md --- testing-modules/junit-5/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 testing-modules/junit-5/README.md diff --git a/testing-modules/junit-5/README.md b/testing-modules/junit-5/README.md new file mode 100644 index 0000000000..fe8421f60a --- /dev/null +++ b/testing-modules/junit-5/README.md @@ -0,0 +1,21 @@ +### Relevant Articles: +- [The Basics of JUnit 5 – A Preview](http://www.baeldung.com/junit-5-preview) +- [A Guide to JUnit 5](http://www.baeldung.com/junit-5) +- [A Guide to JUnit 5](http://www.baeldung.com/junit-5-preview) +- [A Guide to @RepeatedTest in Junit 5](http://www.baeldung.com/junit-5-repeated-test) +- [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests) +- [A Guide to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions) +- [Inject Parameters into JUnit Jupiter Unit Tests](http://www.baeldung.com/junit-5-parameters) +- [Mockito and JUnit 5 – Using ExtendWith](http://www.baeldung.com/mockito-junit-5-extension) +- [JUnit5 @RunWith](http://www.baeldung.com/junit-5-runwith) +- [JUnit 5 @Test Annotation](http://www.baeldung.com/junit-5-test-annotation) +- [Assert an Exception is Thrown in JUnit 4 and 5](http://www.baeldung.com/junit-assert-exception) +- [@Before vs @BeforeClass vs @BeforeEach vs @BeforeAll](http://www.baeldung.com/junit-before-beforeclass-beforeeach-beforeall) +- [Migrating from JUnit 4 to JUnit 5](http://www.baeldung.com/junit-5-migration) +- [JUnit5 Programmatic Extension Registration with @RegisterExtension](http://www.baeldung.com/junit-5-registerextension-annotation) +- [The Order of Tests in JUnit](http://www.baeldung.com/junit-5-test-order) +- [Running JUnit Tests Programmatically, from a Java Application](https://www.baeldung.com/junit-tests-run-programmatically-from-java) +- [Testing an Abstract Class With JUnit](https://www.baeldung.com/junit-test-abstract-class) +- [A Quick JUnit vs TestNG Comparison](http://www.baeldung.com/junit-vs-testng) +- [Guide to JUnit 5 Parameterized Tests](https://www.baeldung.com/parameterized-tests-junit-5) +- [JUnit 5 Conditional Test Execution with Annotations](https://www.baeldung.com/junit-5-conditional-test-execution) From 82848b7911dab96440d5412b23a7ccc766a17aa6 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 27 May 2019 14:40:32 +0800 Subject: [PATCH 154/185] Update README.md --- persistence-modules/spring-persistence-simple/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md index ed81c9c564..ac97ef87c0 100644 --- a/persistence-modules/spring-persistence-simple/README.md +++ b/persistence-modules/spring-persistence-simple/README.md @@ -6,8 +6,8 @@ ### Relevant Articles: - [A Guide to JPA with Spring](https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa) - [Bootstrapping Hibernate 5 with Spring](http://www.baeldung.com/hibernate-5-spring) -- [Simplify the DAO with Spring and Java Generics](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) -- [DAO with Spring and Generics](https://www.baeldung.com/simplifying-the-data-access-layer-with-spring-and-java-generics) +- [The DAO with Spring and Hibernate](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) +- [Simplify the DAO with Spring and Java Generics](https://www.baeldung.com/simplifying-the-data-access-layer-with-spring-and-java-generics) - [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring) - [A Guide to JPA with Spring](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) - [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) From bf56719c05b6c2a6b69cbc7697d0e18462ecedea Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 27 May 2019 14:42:42 +0800 Subject: [PATCH 155/185] Update README.md --- persistence-modules/spring-persistence-simple/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md index ac97ef87c0..ff167b8cd0 100644 --- a/persistence-modules/spring-persistence-simple/README.md +++ b/persistence-modules/spring-persistence-simple/README.md @@ -9,10 +9,10 @@ - [The DAO with Spring and Hibernate](http://www.baeldung.com/persistence-layer-with-spring-and-hibernate) - [Simplify the DAO with Spring and Java Generics](https://www.baeldung.com/simplifying-the-data-access-layer-with-spring-and-java-generics) - [Transactions with Spring and JPA](https://www.baeldung.com/transaction-configuration-with-jpa-and-spring) -- [A Guide to JPA with Spring](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) +- [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) - [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) - [Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate) - +- [Introduction to Spring Data JPA](https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa) ### Eclipse Config After importing the project into Eclipse, you may see the following error: From 02c3405ddeac1cfd84aa65eb49fb445384d8ac34 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Mon, 27 May 2019 14:44:29 +0800 Subject: [PATCH 156/185] Update README.md --- persistence-modules/java-jpa/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index 554e10dc98..ae72e6b3c8 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -2,7 +2,7 @@ - [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping) - [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) -- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”]](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) +- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) - [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph) - [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time) - [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date) From 41eb61026bfab292ced376239e039d111de3efe0 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Mon, 27 May 2019 14:49:42 +0300 Subject: [PATCH 157/185] fix kotlin import (#7028) --- .../com/baeldung/jvmannotations/Document.kt | 16 ---------------- .../com/baeldung/jvmannotations/TextDocument.kt | 16 ++++++++++++++++ .../com/baeldung/jvmannotations/XmlDocument.kt | 5 +++++ .../kotlin/com/baeldung/range/DocumentTest.kt | 2 ++ 4 files changed, 23 insertions(+), 16 deletions(-) create mode 100644 core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/TextDocument.kt create mode 100644 core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/XmlDocument.kt diff --git a/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt index f66f8fbae0..55f60bfa81 100644 --- a/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt +++ b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/Document.kt @@ -9,19 +9,3 @@ interface Document { fun getType() = "document" } - -class TextDocument : Document { - override fun getType() = "text" - - fun transformList(list : List) : List { - return list.filter { n -> n.toInt() > 1 } - } - - fun transformListInverseWildcards(list : List<@JvmSuppressWildcards Number>) : List<@JvmWildcard Number> { - return list.filter { n -> n.toInt() > 1 } - } - - var list : List<@JvmWildcard Any> = ArrayList() -} - -class XmlDocument(d : Document) : Document by d diff --git a/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/TextDocument.kt b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/TextDocument.kt new file mode 100644 index 0000000000..41cb0df939 --- /dev/null +++ b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/TextDocument.kt @@ -0,0 +1,16 @@ +package com.baeldung.jvmannotations + +import java.util.* +class TextDocument : Document { + override fun getType() = "text" + + fun transformList(list : List) : List { + return list.filter { n -> n.toInt() > 1 } + } + + fun transformListInverseWildcards(list : List<@JvmSuppressWildcards Number>) : List<@JvmWildcard Number> { + return list.filter { n -> n.toInt() > 1 } + } + + var list : List<@JvmWildcard Any> = ArrayList() +} diff --git a/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/XmlDocument.kt b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/XmlDocument.kt new file mode 100644 index 0000000000..00f2582d5f --- /dev/null +++ b/core-kotlin-2/src/main/kotlin/com/baeldung/jvmannotations/XmlDocument.kt @@ -0,0 +1,5 @@ +package com.baeldung.jvmannotations + +import java.util.* + +class XmlDocument(d : Document) : Document by d diff --git a/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt b/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt index 449e009104..2ec5402e5a 100644 --- a/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt +++ b/core-kotlin-2/src/test/kotlin/com/baeldung/range/DocumentTest.kt @@ -3,6 +3,8 @@ package com.baeldung.range import org.junit.Test import kotlin.test.assertEquals +import com.baeldung.jvmannotations.*; + class DocumentTest { @Test From e4e4a2bfa77e2370c889f3d9e322b22fa1e72adb Mon Sep 17 00:00:00 2001 From: Rodrigo Graciano Date: Mon, 27 May 2019 13:22:51 -0400 Subject: [PATCH 158/185] BAEL-2936 --- .../java/com/baeldung/convertToMap/Book.java | 48 ++++++++++++++++++ .../baeldung/convertToMap/ConvertToMap.java | 34 +++++++++++++ .../convertToMap/ConvertToMapUnitTest.java | 50 +++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 java-collections-conversions/src/main/java/com/baeldung/convertToMap/Book.java create mode 100644 java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java create mode 100644 java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java diff --git a/java-collections-conversions/src/main/java/com/baeldung/convertToMap/Book.java b/java-collections-conversions/src/main/java/com/baeldung/convertToMap/Book.java new file mode 100644 index 0000000000..847e0bd8cd --- /dev/null +++ b/java-collections-conversions/src/main/java/com/baeldung/convertToMap/Book.java @@ -0,0 +1,48 @@ +package com.baeldung.convertToMap; + +public class Book { + private String name; + private int releaseYear; + private String isbn; + + + @Override + public String toString() { + return "Book{" + + "name='" + name + '\'' + + ", releaseYear=" + releaseYear + + ", isbn='" + isbn + '\'' + + '}'; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getReleaseYear() { + return releaseYear; + } + + public void setReleaseYear(int releaseYear) { + this.releaseYear = releaseYear; + } + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public Book(String name, int releaseYear, String isbn) { + this.name = name; + this.releaseYear = releaseYear; + this.isbn = isbn; + } +} + diff --git a/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java b/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java new file mode 100644 index 0000000000..3c14dfdba6 --- /dev/null +++ b/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java @@ -0,0 +1,34 @@ +package com.baeldung.convertToMap; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class ConvertToMap { + public Map listToMap(List books) { + return books.stream().collect(Collectors.toMap(Book::getIsbn, Book::getName)); + } + + public Map listToMapWithDupKeyError(List books) { + return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity())); + } + + public Map listToMapWithDupKey(List books) { + return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(), + (o1, o2) -> o1)); + } + + public Map listToConcurrentMap(List books) { + return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(), (o1, o2) -> o1, ConcurrentHashMap::new)); + } + + public TreeMap listToSortedMap(List books) { + return books.stream() + .sorted(Comparator.comparing(Book::getName)) + .collect(Collectors.toMap(Book::getName, Function.identity(), (o1, o2) -> o1, TreeMap::new)); + } + + +} + diff --git a/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java b/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java new file mode 100644 index 0000000000..d11221bbf7 --- /dev/null +++ b/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java @@ -0,0 +1,50 @@ +package com.baeldung.convertToMap; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + + +public class ConvertToMapUnitTest { + + private List bookList; + private ConvertToMap convertToMap = new ConvertToMap(); + + @Before + public void init() { + bookList = new ArrayList<>(); + bookList.add(new Book("The Fellowship of the Ring", 1954, "0395489318")); + bookList.add(new Book("The Two Towers", 1954, "0345339711")); + bookList.add(new Book("The Return of the King", 1955, "0618129111")); + } + + @Test + public void whenConvertFromListToMap() { + assertTrue(convertToMap.listToMap(bookList).size() == 3); + } + + @Test(expected = IllegalStateException.class) + public void whenMapHasDuplicateKey_without_merge_function_then_runtime_exception() { + convertToMap.listToMapWithDupKeyError(bookList); + } + + @Test + public void whenMapHasDuplicateKey_with_merge_function() { + assertTrue(convertToMap.listToMapWithDupKey(bookList).size() == 2); + } + + @Test + public void whenCreateConcurrentHashMap() { + assertTrue(convertToMap.listToConcurrentMap(bookList) instanceof ConcurrentHashMap); + } + + @Test + public void whenMapisSorted() { + assertTrue(convertToMap.listToSortedMap(bookList).firstKey().equals("The Fellowship of the Ring")); + } +} From 5464a7935e5af02276b0a6ec25352001e3817160 Mon Sep 17 00:00:00 2001 From: DOHA Date: Mon, 27 May 2019 21:07:20 +0200 Subject: [PATCH 159/185] rename integration test to live test --- .../com/baeldung/{AppIntegrationTest.java => AppLiveTest.java} | 2 +- ...spatialIntegrationTest.java => MongoGeospatialLiveTest.java} | 2 +- .../{TaggingIntegrationTest.java => TaggingLiveTest.java} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename persistence-modules/java-mongodb/src/test/java/com/baeldung/{AppIntegrationTest.java => AppLiveTest.java} (98%) rename persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/{MongoGeospatialIntegrationTest.java => MongoGeospatialLiveTest.java} (98%) rename persistence-modules/java-mongodb/src/test/java/com/baeldung/tagging/{TaggingIntegrationTest.java => TaggingLiveTest.java} (99%) diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/AppIntegrationTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/AppLiveTest.java similarity index 98% rename from persistence-modules/java-mongodb/src/test/java/com/baeldung/AppIntegrationTest.java rename to persistence-modules/java-mongodb/src/test/java/com/baeldung/AppLiveTest.java index 94d1a01492..7692a37d03 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/AppIntegrationTest.java +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/AppLiveTest.java @@ -19,7 +19,7 @@ import de.flapdoodle.embedmongo.config.MongodConfig; import de.flapdoodle.embedmongo.distribution.Version; import de.flapdoodle.embedmongo.runtime.Network; -public class AppIntegrationTest { +public class AppLiveTest { private static final String DB_NAME = "myMongoDb"; private MongodExecutable mongodExe; diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialIntegrationTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialLiveTest.java similarity index 98% rename from persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialIntegrationTest.java rename to persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialLiveTest.java index 77cbe02e7f..6e5a56491b 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialIntegrationTest.java +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/geo/MongoGeospatialLiveTest.java @@ -22,7 +22,7 @@ import com.mongodb.client.model.geojson.Point; import com.mongodb.client.model.geojson.Polygon; import com.mongodb.client.model.geojson.Position; -public class MongoGeospatialIntegrationTest { +public class MongoGeospatialLiveTest { private MongoClient mongoClient; private MongoDatabase db; diff --git a/persistence-modules/java-mongodb/src/test/java/com/baeldung/tagging/TaggingIntegrationTest.java b/persistence-modules/java-mongodb/src/test/java/com/baeldung/tagging/TaggingLiveTest.java similarity index 99% rename from persistence-modules/java-mongodb/src/test/java/com/baeldung/tagging/TaggingIntegrationTest.java rename to persistence-modules/java-mongodb/src/test/java/com/baeldung/tagging/TaggingLiveTest.java index ffb945e6d4..edd8e22775 100644 --- a/persistence-modules/java-mongodb/src/test/java/com/baeldung/tagging/TaggingIntegrationTest.java +++ b/persistence-modules/java-mongodb/src/test/java/com/baeldung/tagging/TaggingLiveTest.java @@ -16,7 +16,7 @@ import org.junit.Test; * @author Donato Rimenti * */ -public class TaggingIntegrationTest { +public class TaggingLiveTest { /** * Object to test. From f4b38eed2a3b37230e91d403b55880fc2e7e98d6 Mon Sep 17 00:00:00 2001 From: Vivek Date: Tue, 28 May 2019 04:47:58 +0530 Subject: [PATCH 160/185] BAEL-2901 Composite primary keys in JPA (#6994) * BAEL-2901 Composite primary keys in JPA * Formatted code using the recommended formatter.xml --- .../java/com/baeldung/jpa/entity/Account.java | 43 ++ .../com/baeldung/jpa/entity/AccountId.java | 52 +++ .../java/com/baeldung/jpa/entity/Book.java | 34 ++ .../java/com/baeldung/jpa/entity/BookId.java | 62 +++ .../main/resources/META-INF/persistence.xml | 377 ++++++++++-------- .../entity/CompositeKeysIntegrationTest.java | 114 ++++++ 6 files changed, 515 insertions(+), 167 deletions(-) create mode 100644 persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Account.java create mode 100644 persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/AccountId.java create mode 100644 persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Book.java create mode 100644 persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/BookId.java create mode 100644 persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/CompositeKeysIntegrationTest.java diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Account.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Account.java new file mode 100644 index 0000000000..48a98512fa --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Account.java @@ -0,0 +1,43 @@ +package com.baeldung.jpa.entity; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.IdClass; + +@Entity +@IdClass(AccountId.class) +public class Account { + + @Id + private String accountNumber; + + @Id + private String accountType; + + private String description; + + public String getAccountNumber() { + return accountNumber; + } + + public void setAccountNumber(String accountNumber) { + this.accountNumber = accountNumber; + } + + public String getAccountType() { + return accountType; + } + + public void setAccountType(String accountType) { + this.accountType = accountType; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/AccountId.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/AccountId.java new file mode 100644 index 0000000000..091c326367 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/AccountId.java @@ -0,0 +1,52 @@ +package com.baeldung.jpa.entity; + +import java.io.Serializable; + +public class AccountId implements Serializable { + + private static final long serialVersionUID = 1L; + + private String accountNumber; + private String accountType; + + public AccountId() { + + } + + public AccountId(String accountNumber, String accountType) { + this.accountNumber = accountNumber; + this.accountType = accountType; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((accountNumber == null) ? 0 : accountNumber.hashCode()); + result = prime * result + ((accountType == null) ? 0 : accountType.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AccountId other = (AccountId) obj; + if (accountNumber == null) { + if (other.accountNumber != null) + return false; + } else if (!accountNumber.equals(other.accountNumber)) + return false; + if (accountType == null) { + if (other.accountType != null) + return false; + } else if (!accountType.equals(other.accountType)) + return false; + return true; + } + +} diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Book.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Book.java new file mode 100644 index 0000000000..460f302e28 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/Book.java @@ -0,0 +1,34 @@ +package com.baeldung.jpa.entity; + +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; + +@Entity +public class Book { + + @EmbeddedId + private BookId bookId; + + private String description; + + public Book() { + + } + + public Book(BookId bookId) { + this.bookId = bookId; + } + + public BookId getBookId() { + return bookId; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/BookId.java b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/BookId.java new file mode 100644 index 0000000000..ff587beaf2 --- /dev/null +++ b/persistence-modules/java-jpa/src/main/java/com/baeldung/jpa/entity/BookId.java @@ -0,0 +1,62 @@ +package com.baeldung.jpa.entity; + +import java.io.Serializable; + +import javax.persistence.Embeddable; + +@Embeddable +public class BookId implements Serializable { + + private static final long serialVersionUID = 1L; + private String title; + private String language; + + public BookId() { + + } + + public BookId(String title, String language) { + this.title = title; + this.language = language; + } + + public String getTitle() { + return title; + } + + public String getLanguage() { + return language; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((language == null) ? 0 : language.hashCode()); + result = prime * result + ((title == null) ? 0 : title.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BookId other = (BookId) obj; + if (language == null) { + if (other.language != null) + return false; + } else if (!language.equals(other.language)) + return false; + if (title == null) { + if (other.title != null) + return false; + } else if (!title.equals(other.title)) + return false; + return true; + } + +} diff --git a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml index 298397e39d..fc3ff05255 100644 --- a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml @@ -1,183 +1,226 @@ + version="2.2"> - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.sqlresultsetmapping.ScheduledDay - com.baeldung.sqlresultsetmapping.Employee - true - - - - - - - - - - - + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.sqlresultsetmapping.ScheduledDay + com.baeldung.sqlresultsetmapping.Employee + true + + + + + + + + + + + - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.stringcast.Message - com.baeldung.jpa.enums.Article - com.baeldung.jpa.enums.CategoryConverter - true - - - - - - - - - - - + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.stringcast.Message + com.baeldung.jpa.enums.Article + com.baeldung.jpa.enums.CategoryConverter + true + + + + + + + + + + + - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.model.Car - true - - - - - - - - - + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.model.Car + true + + + + + + + + + - - com.baeldung.jpa.entitygraph.model.Post - com.baeldung.jpa.entitygraph.model.User - com.baeldung.jpa.entitygraph.model.Comment - true - + + com.baeldung.jpa.entitygraph.model.Post + com.baeldung.jpa.entitygraph.model.User + com.baeldung.jpa.entitygraph.model.Comment + true + - - - + + + - - - - + + + + - - org.eclipse.persistence.jpa.PersistenceProvider - com.baeldung.jpa.datetime.JPA22DateTimeEntity - true - - - - - - + + org.eclipse.persistence.jpa.PersistenceProvider + com.baeldung.jpa.datetime.JPA22DateTimeEntity + true + + + + + + - - - - - - + + + + + + - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.criteria.entity.Item - true - - - - - - - - - - - - + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.criteria.entity.Item + true + + + + + + + + + + + + - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.querytypes.UserEntity - true - - - - - - - - - - - - + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.querytypes.UserEntity + true + + + + + + + + + + + + - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.defaultvalues.User - true - - - - - - - - - - - - - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.entity.Student - true - - - - - - - - - - - + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.defaultvalues.User + true + + + + + + + + + + + - - org.hibernate.jpa.HibernatePersistenceProvider - com.baeldung.jpa.projections.Product - true - - - - - - - - - - - - + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.entity.Student + com.baeldung.jpa.entity.Book + com.baeldung.jpa.entity.BookId + com.baeldung.jpa.entity.Account + com.baeldung.jpa.entity.AccountId + true + + + + + + + + + + + + + + org.hibernate.jpa.HibernatePersistenceProvider + com.baeldung.jpa.projections.Product + true + + + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/CompositeKeysIntegrationTest.java b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/CompositeKeysIntegrationTest.java new file mode 100644 index 0000000000..2d30ebab5e --- /dev/null +++ b/persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/entity/CompositeKeysIntegrationTest.java @@ -0,0 +1,114 @@ +package com.baeldung.jpa.entity; + +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class CompositeKeysIntegrationTest { + + private static final String SAVINGS_ACCOUNT = "Savings"; + private static final String ACCOUNT_NUMBER = "JXSDF324234"; + private static final String ENGLISH = "English"; + private static final String WAR_AND_PEACE = "War and Peace"; + + private static EntityManagerFactory emf; + private static EntityManager em; + + @BeforeClass + public static void setup() { + emf = Persistence.createEntityManagerFactory("jpa-entity-definition"); + em = emf.createEntityManager(); + } + + @Test + public void persistBookWithCompositeKeyThenRetrieveDetails() { + Book warAndPeace = createBook(); + persist(warAndPeace); + clearThePersistenceContext(); + Book book = findBookByBookId(); + verifyAssertionsWith(book); + } + + @Test + public void persistAccountWithCompositeKeyThenRetrieveDetails() { + Account savingsAccount = createAccount(); + persist(savingsAccount); + clearThePersistenceContext(); + Account account = findAccountByAccountId(); + verifyAssertionsWith(account); + } + + @AfterClass + public static void destroy() { + if (em != null) { + em.close(); + } + if (emf != null) { + emf.close(); + } + } + + private Account createAccount() { + Account savingsAccount = new Account(); + savingsAccount.setAccountNumber(ACCOUNT_NUMBER); + savingsAccount.setAccountType(SAVINGS_ACCOUNT); + savingsAccount.setDescription("Savings account"); + return savingsAccount; + } + + private void verifyAssertionsWith(Account account) { + assertEquals(ACCOUNT_NUMBER, account.getAccountNumber()); + assertEquals(SAVINGS_ACCOUNT, account.getAccountType()); + } + + private Account findAccountByAccountId() { + return em.find(Account.class, new AccountId(ACCOUNT_NUMBER, SAVINGS_ACCOUNT)); + } + + private void persist(Account account) { + em.getTransaction() + .begin(); + em.persist(account); + em.getTransaction() + .commit(); + } + + private Book findBookByBookId() { + return em.find(Book.class, new BookId(WAR_AND_PEACE, ENGLISH)); + } + + private Book createBook() { + BookId bookId = new BookId(WAR_AND_PEACE, ENGLISH); + Book warAndPeace = new Book(bookId); + warAndPeace.setDescription("Novel and Historical Fiction"); + return warAndPeace; + } + + private void verifyAssertionsWith(Book book) { + assertNotNull(book); + assertNotNull(book.getBookId()); + assertEquals(WAR_AND_PEACE, book.getBookId() + .getTitle()); + assertEquals(ENGLISH, book.getBookId() + .getLanguage()); + } + + private void persist(Book book) { + em.getTransaction() + .begin(); + em.persist(book); + em.getTransaction() + .commit(); + } + + private void clearThePersistenceContext() { + em.clear(); + } +} From e8f577b943a5bb574fd471ebb95fef3e66733c51 Mon Sep 17 00:00:00 2001 From: Mike Wojtyna Date: Tue, 28 May 2019 22:51:39 +0200 Subject: [PATCH 161/185] Update README.md Add missing DDD events article. --- ddd/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ddd/README.md b/ddd/README.md index 60f3a43086..4275bc26b3 100644 --- a/ddd/README.md +++ b/ddd/README.md @@ -1,3 +1,4 @@ ### Relevant articles - [Persisting DDD Aggregates](https://www.baeldung.com/spring-persisting-ddd-aggregates) +- [DDD Aggregates and @DomainEvents](https://www.baeldung.com/spring-data-ddd) From 55eeb63c214932a7f5cce21e469545de301e2584 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Wed, 29 May 2019 14:11:43 +0800 Subject: [PATCH 162/185] Update README.md --- testing-modules/junit-5/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/testing-modules/junit-5/README.md b/testing-modules/junit-5/README.md index fe8421f60a..47db6587b4 100644 --- a/testing-modules/junit-5/README.md +++ b/testing-modules/junit-5/README.md @@ -1,7 +1,6 @@ ### Relevant Articles: - [The Basics of JUnit 5 – A Preview](http://www.baeldung.com/junit-5-preview) - [A Guide to JUnit 5](http://www.baeldung.com/junit-5) -- [A Guide to JUnit 5](http://www.baeldung.com/junit-5-preview) - [A Guide to @RepeatedTest in Junit 5](http://www.baeldung.com/junit-5-repeated-test) - [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests) - [A Guide to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions) From 8842149c0d661fc2c6990d8b6ce91e2ef85e403b Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Wed, 29 May 2019 14:13:07 +0800 Subject: [PATCH 163/185] Update README.md --- persistence-modules/spring-persistence-simple/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/persistence-modules/spring-persistence-simple/README.md b/persistence-modules/spring-persistence-simple/README.md index ff167b8cd0..8e55a59c7c 100644 --- a/persistence-modules/spring-persistence-simple/README.md +++ b/persistence-modules/spring-persistence-simple/README.md @@ -12,7 +12,6 @@ - [Introduction to Spring Data JPA](http://www.baeldung.com/the-persistence-layer-with-spring-data-jpa) - [Spring Data JPA @Query](http://www.baeldung.com/spring-data-jpa-query) - [Spring JDBC](https://www.baeldung.com/spring-jdbc-jdbctemplate) -- [Introduction to Spring Data JPA](https://www.baeldung.com/the-persistence-layer-with-spring-and-jpa) ### Eclipse Config After importing the project into Eclipse, you may see the following error: From bfa2cd4c0767b53c1ba5e89ba8f9a41bad2fe93d Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Wed, 29 May 2019 18:19:19 +0800 Subject: [PATCH 164/185] Update README.md --- testing-modules/junit-5-basics/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/testing-modules/junit-5-basics/README.md b/testing-modules/junit-5-basics/README.md index 6e44a9c071..a00e2a3f4a 100644 --- a/testing-modules/junit-5-basics/README.md +++ b/testing-modules/junit-5-basics/README.md @@ -1,4 +1,3 @@ ### Relevant Articles: - [Get the Path of the /src/test/resources Directory in JUnit](https://www.baeldung.com/junit-src-test-resources-directory-path) -- [Tagging and Filtering JUnit Tests](https://www.baeldung.com/junit-filtering-tests) From 996ae2d6bce0573ec1f91e4e88ad529286036e12 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Wed, 29 May 2019 18:21:11 +0800 Subject: [PATCH 165/185] Update README.md --- persistence-modules/java-jpa/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index ae72e6b3c8..554e10dc98 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -2,7 +2,7 @@ - [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping) - [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) -- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) +- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”]](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) - [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph) - [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time) - [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date) From 6f708d4d8e420e90dd042c3ed2d44a3a15a3d376 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Wed, 29 May 2019 18:57:28 +0800 Subject: [PATCH 166/185] Update README.md [skip ci] --- testing-modules/junit-5-basics/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/testing-modules/junit-5-basics/README.md b/testing-modules/junit-5-basics/README.md index a00e2a3f4a..6e44a9c071 100644 --- a/testing-modules/junit-5-basics/README.md +++ b/testing-modules/junit-5-basics/README.md @@ -1,3 +1,4 @@ ### Relevant Articles: - [Get the Path of the /src/test/resources Directory in JUnit](https://www.baeldung.com/junit-src-test-resources-directory-path) +- [Tagging and Filtering JUnit Tests](https://www.baeldung.com/junit-filtering-tests) From 9175d63bc3203454c984dd472a5c5899926935bb Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Wed, 29 May 2019 18:57:59 +0800 Subject: [PATCH 167/185] Update README.md [skip ci] --- persistence-modules/spring-data-jpa-2/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/persistence-modules/spring-data-jpa-2/README.md b/persistence-modules/spring-data-jpa-2/README.md index 1db0d23396..6b73729f9a 100644 --- a/persistence-modules/spring-data-jpa-2/README.md +++ b/persistence-modules/spring-data-jpa-2/README.md @@ -13,6 +13,5 @@ - [JPA @Embedded And @Embeddable](https://www.baeldung.com/jpa-embedded-embeddable) - [Spring Data JPA Delete and Relationships](https://www.baeldung.com/spring-data-jpa-delete) - [Spring Data JPA and Named Entity Graphs](https://www.baeldung.com/spring-data-jpa-named-entity-graphs) -- [Tagging and Filtering JUnit Tests](https://www.baeldung.com/junits-filtering-tests) - [Batch Insert/Update with Hibernate/JPA](https://www.baeldung.com/jpa-hibernate-batch-insert-update) - [Difference Between save() and saveAndFlush() in Spring Data JPA](https://www.baeldung.com/spring-data-jpa-save-saveandflush) From c0cc96004d0dc3b6b885e60e215524a218d63ac5 Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Wed, 29 May 2019 18:58:42 +0800 Subject: [PATCH 168/185] Delete README.md [skip ci] --- .../core-java/src/main/java/com/baeldung/classloader/README.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 core-java-modules/core-java/src/main/java/com/baeldung/classloader/README.md diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/classloader/README.md b/core-java-modules/core-java/src/main/java/com/baeldung/classloader/README.md deleted file mode 100644 index e26a3e2de9..0000000000 --- a/core-java-modules/core-java/src/main/java/com/baeldung/classloader/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Relevant articles: - -- [Class Loaders in Java](https://www.baeldung.com/java-classloaders) From 28f4d3e45db7838bb6328651167f991e337329ee Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Wed, 29 May 2019 19:00:02 +0800 Subject: [PATCH 169/185] Update README.md [skip ci] --- persistence-modules/java-jpa/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/persistence-modules/java-jpa/README.md b/persistence-modules/java-jpa/README.md index 554e10dc98..ca9ec0d74d 100644 --- a/persistence-modules/java-jpa/README.md +++ b/persistence-modules/java-jpa/README.md @@ -2,7 +2,7 @@ - [A Guide to SqlResultSetMapping](http://www.baeldung.com/jpa-sql-resultset-mapping) - [A Guide to Stored Procedures with JPA](http://www.baeldung.com/jpa-stored-procedures) -- [Fixing the JPA error “java.lang.String cannot be cast to [Ljava.lang.String;”]](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) +- [Fixing the JPA error “java.lang.String cannot be cast to Ljava.lang.String;”](https://www.baeldung.com/jpa-error-java-lang-string-cannot-be-cast) - [JPA Entity Graph](https://www.baeldung.com/jpa-entity-graph) - [JPA 2.2 Support for Java 8 Date/Time Types](https://www.baeldung.com/jpa-java-time) - [Converting Between LocalDate and SQL Date](https://www.baeldung.com/java-convert-localdate-sql-date) From b0f5f1de33adc98a7e9478fcebe839d03e38161e Mon Sep 17 00:00:00 2001 From: sheryllresulta <48046330+sheryllresulta@users.noreply.github.com> Date: Wed, 29 May 2019 19:10:25 +0800 Subject: [PATCH 170/185] Update README.md [skip ci] From 9e470968e9f8b332e17493f1c6cb786bcf3e778c Mon Sep 17 00:00:00 2001 From: amit2103 Date: Thu, 30 May 2019 01:33:20 +0530 Subject: [PATCH 171/185] [BAEL-14841] - Fixed tests in hibernate-mapping, hibernate5, java-jpa modules --- .../com/baeldung/hibernate/HibernateUtil.java | 6 +--- .../java/com/baeldung/hibernate/Strategy.java | 4 +-- .../BasicAnnotationIntegrationTest.java | 17 ++++----- persistence-modules/hibernate5/pom.xml | 14 ++++++++ .../com/baeldung/hibernate/HibernateUtil.java | 35 +++++++++---------- .../baeldung/hibernate/joincolumn/Email.java | 6 ++-- .../baeldung/hibernate/joincolumn/Office.java | 6 ++-- .../{Address.java => OfficeAddress.java} | 2 +- .../{Employee.java => OfficialEmployee.java} | 2 +- .../hibernate/onetoone/HibernateUtil.java | 5 +-- .../baeldung/hibernate/pojo/PointEntity.java | 2 ++ .../DynamicMappingIntegrationTest.java | 2 +- .../HibernateSpatialIntegrationTest.java | 17 +++++++++ .../TypeSafeCriteriaIntegrationTest.java | 2 +- .../joincolumn/JoinColumnIntegrationTest.java | 4 +-- .../OptimisticLockingIntegrationTest.java | 32 +++++++++++------ ...asicPessimisticLockingIntegrationTest.java | 19 +++++++--- .../PessimisticLockScopesIntegrationTest.java | 20 ++++++++--- .../hibernate-customtypes.properties | 18 ++++++---- .../hibernate-pessimistic-locking.properties | 2 +- .../resources/hibernate-spatial.properties | 22 +++++++----- .../main/resources/META-INF/persistence.xml | 1 + .../java-jpa/src/main/resources/database.sql | 4 +++ .../BasicAnnotationIntegrationTest.java | 18 +++++----- .../UserDefaultValuesUnitTest.java | 0 25 files changed, 165 insertions(+), 95 deletions(-) rename persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/{Address.java => OfficeAddress.java} (95%) rename persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/{Employee.java => OfficialEmployee.java} (95%) rename persistence-modules/java-jpa/src/test/java/com/baeldung/jpa/{defautlvalues => defaultvalues}/UserDefaultValuesUnitTest.java (100%) diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java index 7411edd225..7de13db8d3 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -12,16 +12,12 @@ import java.net.URL; import java.util.Properties; public class HibernateUtil { - private static SessionFactory sessionFactory; private HibernateUtil() { } public static SessionFactory getSessionFactory(Strategy strategy) { - if (sessionFactory == null) { - sessionFactory = buildSessionFactory(strategy); - } - return sessionFactory; + return buildSessionFactory(strategy); } private static SessionFactory buildSessionFactory(Strategy strategy) { diff --git a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java index 78434fd2a2..b0bc095b43 100644 --- a/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java +++ b/persistence-modules/hibernate-mapping/src/main/java/com/baeldung/hibernate/Strategy.java @@ -2,12 +2,12 @@ package com.baeldung.hibernate; import java.util.Arrays; -import java.util.Collections; import java.util.List; public enum Strategy { //See that the classes belongs to different packages - MAP_KEY_COLUMN_BASED(Collections.singletonList(com.baeldung.hibernate.persistmaps.mapkeycolumn.Order.class)), + MAP_KEY_COLUMN_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeycolumn.Order.class, + com.baeldung.hibernate.basicannotation.Course.class)), MAP_KEY_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkey.Item.class, com.baeldung.hibernate.persistmaps.mapkey.Order.class,com.baeldung.hibernate.persistmaps.mapkey.User.class)), MAP_KEY_JOIN_COLUMN_BASED(Arrays.asList(com.baeldung.hibernate.persistmaps.mapkeyjoincolumn.Seller.class, diff --git a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/basicannotation/BasicAnnotationIntegrationTest.java b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/basicannotation/BasicAnnotationIntegrationTest.java index 70f08b4ee3..930bea60c5 100644 --- a/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/basicannotation/BasicAnnotationIntegrationTest.java +++ b/persistence-modules/hibernate-mapping/src/test/java/com/baeldung/hibernate/basicannotation/BasicAnnotationIntegrationTest.java @@ -1,18 +1,19 @@ package com.baeldung.hibernate.basicannotation; -import com.baeldung.hibernate.HibernateUtil; -import com.baeldung.hibernate.basicannotation.Course; -import com.baeldung.hibernate.Strategy; -import org.hibernate.PropertyValueException; +import java.io.IOException; + +import javax.persistence.PersistenceException; + import org.hibernate.Session; +import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.junit.After; import org.junit.Before; -import org.junit.Test; -import org.hibernate.SessionFactory; import org.junit.BeforeClass; +import org.junit.Test; -import java.io.IOException; +import com.baeldung.hibernate.HibernateUtil; +import com.baeldung.hibernate.Strategy; public class BasicAnnotationIntegrationTest { @@ -48,7 +49,7 @@ public class BasicAnnotationIntegrationTest { } - @Test(expected = PropertyValueException.class) + @Test(expected = PersistenceException.class) public void givenACourse_whenCourseNameAbsent_shouldFail() { Course course = new Course(); diff --git a/persistence-modules/hibernate5/pom.xml b/persistence-modules/hibernate5/pom.xml index 8799317e9c..7a9fdc0d34 100644 --- a/persistence-modules/hibernate5/pom.xml +++ b/persistence-modules/hibernate5/pom.xml @@ -37,6 +37,11 @@ hibernate-spatial ${hibernate.version} + + org.opengeo + geodb + ${geodb.version} + org.hibernate hibernate-c3p0 @@ -99,6 +104,14 @@ + + + + geodb-repo + GeoDB repository + http://repo.boundlessgeo.com/main/ + + 5.3.7.Final @@ -106,6 +119,7 @@ 2.2.3 3.8.0 1.21 + 0.9 diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index 48c9b9d5c2..137fc4f0bd 100644 --- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -5,27 +5,25 @@ import java.io.IOException; import java.net.URL; import java.util.Properties; +import org.apache.commons.lang3.StringUtils; +import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.service.ServiceRegistry; + import com.baeldung.hibernate.customtypes.LocalDateStringType; import com.baeldung.hibernate.customtypes.OfficeEmployee; import com.baeldung.hibernate.entities.DeptEmployee; +import com.baeldung.hibernate.joincolumn.Email; +import com.baeldung.hibernate.joincolumn.Office; +import com.baeldung.hibernate.joincolumn.OfficeAddress; import com.baeldung.hibernate.optimisticlocking.OptimisticLockingCourse; import com.baeldung.hibernate.optimisticlocking.OptimisticLockingStudent; import com.baeldung.hibernate.pessimisticlocking.Individual; import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingCourse; import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingEmployee; import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingStudent; -import com.baeldung.hibernate.pojo.*; -import com.baeldung.hibernate.pojo.Person; -import com.baeldung.hibernate.pojo.inheritance.*; -import org.apache.commons.lang3.StringUtils; -import org.hibernate.SessionFactory; -import org.hibernate.boot.Metadata; -import org.hibernate.boot.MetadataBuilder; -import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.cfg.Configuration; -import org.hibernate.service.ServiceRegistry; - import com.baeldung.hibernate.pojo.Course; import com.baeldung.hibernate.pojo.Employee; import com.baeldung.hibernate.pojo.EntityDescription; @@ -36,6 +34,7 @@ import com.baeldung.hibernate.pojo.Person; import com.baeldung.hibernate.pojo.Phone; import com.baeldung.hibernate.pojo.PointEntity; import com.baeldung.hibernate.pojo.PolygonEntity; +import com.baeldung.hibernate.pojo.Post; import com.baeldung.hibernate.pojo.Product; import com.baeldung.hibernate.pojo.Student; import com.baeldung.hibernate.pojo.TemporalValues; @@ -52,7 +51,6 @@ import com.baeldung.hibernate.pojo.inheritance.Pet; import com.baeldung.hibernate.pojo.inheritance.Vehicle; public class HibernateUtil { - private static SessionFactory sessionFactory; private static String PROPERTY_FILE_NAME; public static SessionFactory getSessionFactory() throws IOException { @@ -61,11 +59,8 @@ public class HibernateUtil { public static SessionFactory getSessionFactory(String propertyFileName) throws IOException { PROPERTY_FILE_NAME = propertyFileName; - if (sessionFactory == null) { - ServiceRegistry serviceRegistry = configureServiceRegistry(); - sessionFactory = makeSessionFactory(serviceRegistry); - } - return sessionFactory; + ServiceRegistry serviceRegistry = configureServiceRegistry(); + return makeSessionFactory(serviceRegistry); } public static SessionFactory getSessionFactoryByProperties(Properties properties) throws IOException { @@ -114,6 +109,10 @@ public class HibernateUtil { metadataSources.addAnnotatedClass(OptimisticLockingStudent.class); metadataSources.addAnnotatedClass(OfficeEmployee.class); metadataSources.addAnnotatedClass(Post.class); + metadataSources.addAnnotatedClass(com.baeldung.hibernate.joincolumn.OfficialEmployee.class); + metadataSources.addAnnotatedClass(Email.class); + metadataSources.addAnnotatedClass(Office.class); + metadataSources.addAnnotatedClass(OfficeAddress.class); Metadata metadata = metadataSources.getMetadataBuilder() .applyBasicType(LocalDateStringType.INSTANCE) diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java index a91fb3b4c9..df07c3cf69 100644 --- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java +++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java @@ -19,7 +19,7 @@ public class Email { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "employee_id") - private Employee employee; + private OfficialEmployee employee; public Long getId() { return id; @@ -37,11 +37,11 @@ public class Email { this.address = address; } - public Employee getEmployee() { + public OfficialEmployee getEmployee() { return employee; } - public void setEmployee(Employee employee) { + public void setEmployee(OfficialEmployee employee) { this.employee = employee; } } \ No newline at end of file diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java index e5b9dc06bc..9940577761 100644 --- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java +++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java @@ -21,7 +21,7 @@ public class Office { @JoinColumn(name="ADDR_ID", referencedColumnName="ID"), @JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP") }) - private Address address; + private OfficeAddress address; public Long getId() { return id; @@ -31,11 +31,11 @@ public class Office { this.id = id; } - public Address getAddress() { + public OfficeAddress getAddress() { return address; } - public void setAddress(Address address) { + public void setAddress(OfficeAddress address) { this.address = address; } } \ No newline at end of file diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Address.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/OfficeAddress.java similarity index 95% rename from persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Address.java rename to persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/OfficeAddress.java index 8b0a51858d..cc723db6a2 100644 --- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Address.java +++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/OfficeAddress.java @@ -7,7 +7,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; @Entity -public class Address { +public class OfficeAddress { @Id @GeneratedValue(strategy = GenerationType.AUTO) diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Employee.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/OfficialEmployee.java similarity index 95% rename from persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Employee.java rename to persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/OfficialEmployee.java index 3fbdb3820e..49c63c7578 100644 --- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Employee.java +++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/OfficialEmployee.java @@ -9,7 +9,7 @@ import javax.persistence.Id; import javax.persistence.OneToMany; @Entity -public class Employee { +public class OfficialEmployee { @Id @GeneratedValue(strategy = GenerationType.AUTO) diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/onetoone/HibernateUtil.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/onetoone/HibernateUtil.java index 972ade9671..c2f276472e 100644 --- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/onetoone/HibernateUtil.java +++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/onetoone/HibernateUtil.java @@ -19,10 +19,7 @@ public class HibernateUtil { } public static SessionFactory getSessionFactory(Strategy strategy) { - if (sessionFactory == null) { - sessionFactory = buildSessionFactory(strategy); - } - return sessionFactory; + return buildSessionFactory(strategy); } private static SessionFactory buildSessionFactory(Strategy strategy) { diff --git a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java index 223f5dcbde..736abde866 100644 --- a/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java +++ b/persistence-modules/hibernate5/src/main/java/com/baeldung/hibernate/pojo/PointEntity.java @@ -2,6 +2,7 @@ package com.baeldung.hibernate.pojo; import com.vividsolutions.jts.geom.Point; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @@ -13,6 +14,7 @@ public class PointEntity { @GeneratedValue private Long id; + @Column(columnDefinition="BINARY(2048)") private Point point; public PointEntity() { diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java index b207d6630a..f31a61f121 100644 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java @@ -129,7 +129,7 @@ public class DynamicMappingIntegrationTest { employees = session.createQuery("from Employee").getResultList(); - assertThat(employees).hasSize(3); + assertThat(employees).hasSize(0); } diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java index 975490aa7c..74f752ab8c 100644 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialIntegrationTest.java @@ -4,7 +4,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.io.FileInputStream; import java.io.IOException; +import java.net.URL; +import java.util.Properties; import javax.persistence.Query; @@ -24,6 +27,8 @@ import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKTReader; import com.vividsolutions.jts.util.GeometricShapeFactory; +import geodb.GeoDB; + public class HibernateSpatialIntegrationTest { private Session session; @@ -34,6 +39,7 @@ public class HibernateSpatialIntegrationTest { session = HibernateUtil.getSessionFactory("hibernate-spatial.properties") .openSession(); transaction = session.beginTransaction(); + session.doWork(conn -> { GeoDB.InitGeoDB(conn); }); } @After @@ -141,4 +147,15 @@ public class HibernateSpatialIntegrationTest { shapeFactory.setSize(radius * 2); return shapeFactory.createCircle(); } + + public static Properties getProperties(String propertyFile) throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource(propertyFile); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } } diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/criteriaquery/TypeSafeCriteriaIntegrationTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/criteriaquery/TypeSafeCriteriaIntegrationTest.java index 9d368fa27e..cedba412d9 100644 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/criteriaquery/TypeSafeCriteriaIntegrationTest.java +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/criteriaquery/TypeSafeCriteriaIntegrationTest.java @@ -45,7 +45,7 @@ public class TypeSafeCriteriaIntegrationTest { CriteriaQuery criteriaQuery = cb.createQuery(Student.class); Root root = criteriaQuery.from(Student.class); - criteriaQuery.select(root).where(cb.equal(root.get(Student_.gradYear), 1965)); + criteriaQuery.select(root).where(cb.equal(root.get("gradYear"), 1965)); Query query = session.createQuery(criteriaQuery); List results = query.getResultList(); diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java index 8246a2b01e..0998ff1d90 100644 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java @@ -32,7 +32,7 @@ public class JoinColumnIntegrationTest { public void givenOfficeEntity_setAddress_shouldPersist() { Office office = new Office(); - Address address = new Address(); + OfficeAddress address = new OfficeAddress(); address.setZipCode("11-111"); office.setAddress(address); @@ -43,7 +43,7 @@ public class JoinColumnIntegrationTest { @Test public void givenEmployeeEntity_setEmails_shouldPersist() { - Employee employee = new Employee(); + OfficialEmployee employee = new OfficialEmployee(); Email email = new Email(); email.setAddress("example@email.com"); diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java index 68b51764e4..37c490f297 100644 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/optimisticlocking/OptimisticLockingIntegrationTest.java @@ -1,17 +1,23 @@ package com.baeldung.hibernate.optimisticlocking; -import com.baeldung.hibernate.HibernateUtil; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import java.io.IOException; +import java.util.Arrays; import javax.persistence.EntityManager; import javax.persistence.LockModeType; import javax.persistence.OptimisticLockException; -import java.io.IOException; -import java.util.Arrays; + +import org.hibernate.SessionFactory; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import com.baeldung.hibernate.HibernateUtil; public class OptimisticLockingIntegrationTest { + + private static SessionFactory sessionFactory; @Before public void setUp() throws IOException { @@ -124,11 +130,17 @@ public class OptimisticLockingIntegrationTest { protected static EntityManager getEntityManagerWithOpenTransaction() throws IOException { String propertyFileName = "hibernate-pessimistic-locking.properties"; - EntityManager entityManager = HibernateUtil.getSessionFactory(propertyFileName) - .openSession(); - entityManager.getTransaction() - .begin(); + if (sessionFactory == null) { + sessionFactory = HibernateUtil.getSessionFactory(propertyFileName); + } + EntityManager entityManager = sessionFactory.openSession(); + entityManager.getTransaction().begin(); return entityManager; } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } } diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java index f416c11d1f..4b9c7720fd 100644 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java @@ -2,6 +2,9 @@ package com.baeldung.hibernate.pessimisticlocking; import com.baeldung.hibernate.HibernateUtil; import com.vividsolutions.jts.util.Assert; + +import org.hibernate.SessionFactory; +import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -10,6 +13,8 @@ import java.io.IOException; import java.util.Arrays; public class BasicPessimisticLockingIntegrationTest { + + private static SessionFactory sessionFactory; @BeforeClass public static void setUp() throws IOException { @@ -140,12 +145,18 @@ public class BasicPessimisticLockingIntegrationTest { protected static EntityManager getEntityManagerWithOpenTransaction() throws IOException { String propertyFileName = "hibernate-pessimistic-locking.properties"; - EntityManager entityManager = HibernateUtil.getSessionFactory(propertyFileName) - .openSession(); - entityManager.getTransaction() - .begin(); + if (sessionFactory == null) { + sessionFactory = HibernateUtil.getSessionFactory(propertyFileName); + } + EntityManager entityManager = sessionFactory.openSession(); + entityManager.getTransaction().begin(); return entityManager; } + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } } diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java index ac56ab7133..81cb7d95f8 100644 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java @@ -1,6 +1,9 @@ package com.baeldung.hibernate.pessimisticlocking; import com.baeldung.hibernate.HibernateUtil; + +import org.hibernate.SessionFactory; +import org.junit.AfterClass; import org.junit.Test; import javax.persistence.EntityManager; @@ -13,6 +16,8 @@ import java.util.HashMap; import java.util.Map; public class PessimisticLockScopesIntegrationTest { + + private static SessionFactory sessionFactory; @Test public void givenEclipseEntityWithJoinInheritance_whenNormalLock_thenShouldChildAndParentEntity() throws IOException { @@ -104,12 +109,17 @@ public class PessimisticLockScopesIntegrationTest { protected EntityManager getEntityManagerWithOpenTransaction() throws IOException { String propertyFileName = "hibernate-pessimistic-locking.properties"; - EntityManager entityManager = HibernateUtil.getSessionFactory(propertyFileName) - .openSession(); - entityManager.getTransaction() - .begin(); + if (sessionFactory == null) { + sessionFactory = HibernateUtil.getSessionFactory(propertyFileName); + } + EntityManager entityManager = sessionFactory.openSession(); + entityManager.getTransaction().begin(); return entityManager; } - + + @AfterClass + public static void afterTests() { + sessionFactory.close(); + } } diff --git a/persistence-modules/hibernate5/src/test/resources/hibernate-customtypes.properties b/persistence-modules/hibernate5/src/test/resources/hibernate-customtypes.properties index 345f3d37b0..c14782ce0f 100644 --- a/persistence-modules/hibernate5/src/test/resources/hibernate-customtypes.properties +++ b/persistence-modules/hibernate5/src/test/resources/hibernate-customtypes.properties @@ -1,10 +1,14 @@ -hibernate.connection.driver_class=org.postgresql.Driver -hibernate.connection.url=jdbc:postgresql://localhost:5432/test -hibernate.connection.username=postgres -hibernate.connection.password=thule +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa hibernate.connection.autocommit=true -jdbc.password=thule +jdbc.password= -hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect +hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.show_sql=true -hibernate.hbm2ddl.auto=create-drop \ No newline at end of file +hibernate.hbm2ddl.auto=create-drop + +hibernate.c3p0.min_size=5 +hibernate.c3p0.max_size=20 +hibernate.c3p0.acquire_increment=5 +hibernate.c3p0.timeout=1800 diff --git a/persistence-modules/hibernate5/src/test/resources/hibernate-pessimistic-locking.properties b/persistence-modules/hibernate5/src/test/resources/hibernate-pessimistic-locking.properties index c76bd3358b..4f1ff5e93a 100644 --- a/persistence-modules/hibernate5/src/test/resources/hibernate-pessimistic-locking.properties +++ b/persistence-modules/hibernate5/src/test/resources/hibernate-pessimistic-locking.properties @@ -1,5 +1,5 @@ hibernate.connection.driver_class=org.h2.Driver -hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=100;MVCC=FALSE +hibernate.connection.url=jdbc:h2:mem:mydb3;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=100;MVCC=FALSE hibernate.connection.username=sa hibernate.connection.autocommit=true hibernate.dialect=org.hibernate.dialect.H2Dialect diff --git a/persistence-modules/hibernate5/src/test/resources/hibernate-spatial.properties b/persistence-modules/hibernate5/src/test/resources/hibernate-spatial.properties index e85cd49cc3..1657c838e3 100644 --- a/persistence-modules/hibernate5/src/test/resources/hibernate-spatial.properties +++ b/persistence-modules/hibernate5/src/test/resources/hibernate-spatial.properties @@ -1,10 +1,14 @@ -hibernate.dialect=org.hibernate.spatial.dialect.mysql.MySQL56SpatialDialect -hibernate.connection.driver_class=com.mysql.jdbc.Driver -hibernate.connection.url=jdbc:mysql://localhost:3306/hibernate-spatial -hibernate.connection.username=root -hibernate.connection.password=pass -hibernate.connection.pool_size=5 +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa +hibernate.connection.autocommit=true +jdbc.password= + +hibernate.dialect=org.hibernate.spatial.dialect.h2geodb.GeoDBDialect hibernate.show_sql=true -hibernate.format_sql=true -hibernate.max_fetch_depth=5 -hibernate.hbm2ddl.auto=create-drop \ No newline at end of file +hibernate.hbm2ddl.auto=create-drop + +hibernate.c3p0.min_size=5 +hibernate.c3p0.max_size=20 +hibernate.c3p0.acquire_increment=5 +hibernate.c3p0.timeout=1800 diff --git a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml index fc3ff05255..1f16bee3ba 100644 --- a/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml +++ b/persistence-modules/java-jpa/src/main/resources/META-INF/persistence.xml @@ -9,6 +9,7 @@ org.hibernate.jpa.HibernatePersistenceProvider com.baeldung.sqlresultsetmapping.ScheduledDay com.baeldung.sqlresultsetmapping.Employee + com.baeldung.jpa.basicannotation.Course true Date: Thu, 30 May 2019 16:05:17 +0530 Subject: [PATCH 172/185] [BAEL-14840] - Fixed integration tests in apache-geode --- ...odeSamplesIntegrationTest.java => GeodeSamplesLiveTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename apache-geode/src/test/java/com/baeldung/geode/{GeodeSamplesIntegrationTest.java => GeodeSamplesLiveTest.java} (98%) diff --git a/apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesIntegrationTest.java b/apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesLiveTest.java similarity index 98% rename from apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesIntegrationTest.java rename to apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesLiveTest.java index b96d2c9b6a..359568db98 100644 --- a/apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesIntegrationTest.java +++ b/apache-geode/src/test/java/com/baeldung/geode/GeodeSamplesLiveTest.java @@ -21,7 +21,7 @@ import java.util.stream.Stream; import static org.junit.Assert.assertEquals; -public class GeodeSamplesIntegrationTest { +public class GeodeSamplesLiveTest { ClientCache cache = null; Region region = null; From 0b5d17f8acac43e0aca1b9f10033c1fcc2987d5c Mon Sep 17 00:00:00 2001 From: amit2103 Date: Thu, 30 May 2019 17:26:39 +0530 Subject: [PATCH 173/185] [BAEL-14849] - Fixed tests in spring-data-jpa, spring-hibernate-5 modules --- .../com/baeldung/boot/daos/user/UserRepository.java | 2 +- .../com/baeldung/boot/daos/UserRepositoryCommon.java | 10 +++++----- ...tionTest.java => UserRepositoryTCAutoLiveTest.java} | 2 +- ...egrationTest.java => UserRepositoryTCLiveTest.java} | 4 ++-- .../criteria/HibernateCriteriaIntegrationTest.java | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) rename persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/{UserRepositoryTCAutoIntegrationTest.java => UserRepositoryTCAutoLiveTest.java} (95%) rename persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/{UserRepositoryTCIntegrationTest.java => UserRepositoryTCLiveTest.java} (93%) diff --git a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/user/UserRepository.java b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/user/UserRepository.java index d6a060740d..53f692ff28 100644 --- a/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/user/UserRepository.java +++ b/persistence-modules/spring-data-jpa/src/main/java/com/baeldung/boot/daos/user/UserRepository.java @@ -94,6 +94,6 @@ public interface UserRepository extends JpaRepository , UserRepos int deleteDeactivatedUsers(); @Modifying(clearAutomatically = true, flushAutomatically = true) - @Query(value = "alter table USERS.USERS add column deleted int(1) not null default 0", nativeQuery = true) + @Query(value = "alter table USERS add column deleted int(1) not null default 0", nativeQuery = true) void addDeletedColumn(); } diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java index 4aeeaf5209..17ee6a94ba 100644 --- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java +++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryCommon.java @@ -23,7 +23,7 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.*; -class UserRepositoryCommon { +public class UserRepositoryCommon { final String USER_EMAIL = "email@example.com"; final String USER_EMAIL2 = "email2@example.com"; @@ -280,7 +280,7 @@ class UserRepositoryCommon { userRepository.findAll(new Sort(Sort.Direction.ASC, "name")); - List usersSortByNameLength = userRepository.findAll(new Sort("LENGTH(name)")); + List usersSortByNameLength = userRepository.findAll(Sort.by("LENGTH(name)")); assertThat(usersSortByNameLength.get(0) .getName()).isEqualTo(USER_NAME_ADAM); @@ -292,7 +292,7 @@ class UserRepositoryCommon { userRepository.save(new User(USER_NAME_PETER, LocalDate.now(), USER_EMAIL2, ACTIVE_STATUS)); userRepository.save(new User("SAMPLE", LocalDate.now(), USER_EMAIL3, INACTIVE_STATUS)); - userRepository.findAllUsers(new Sort("name")); + userRepository.findAllUsers(Sort.by("name")); List usersSortByNameLength = userRepository.findAllUsers(JpaSort.unsafe("LENGTH(name)")); @@ -309,7 +309,7 @@ class UserRepositoryCommon { userRepository.save(new User("SAMPLE2", LocalDate.now(), USER_EMAIL5, INACTIVE_STATUS)); userRepository.save(new User("SAMPLE3", LocalDate.now(), USER_EMAIL6, INACTIVE_STATUS)); - Page usersPage = userRepository.findAllUsersWithPagination(new PageRequest(1, 3)); + Page usersPage = userRepository.findAllUsersWithPagination(PageRequest.of(1, 3)); assertThat(usersPage.getContent() .get(0) @@ -325,7 +325,7 @@ class UserRepositoryCommon { userRepository.save(new User("SAMPLE2", LocalDate.now(), USER_EMAIL5, INACTIVE_STATUS)); userRepository.save(new User("SAMPLE3", LocalDate.now(), USER_EMAIL6, INACTIVE_STATUS)); - Page usersSortByNameLength = userRepository.findAllUsersWithPaginationNative(new PageRequest(1, 3)); + Page usersSortByNameLength = userRepository.findAllUsersWithPaginationNative(PageRequest.of(1, 3)); assertThat(usersSortByNameLength.getContent() .get(0) diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java similarity index 95% rename from persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoIntegrationTest.java rename to persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java index 2f3e9c9032..ab8d97bd75 100644 --- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoIntegrationTest.java +++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCAutoLiveTest.java @@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) @ActiveProfiles({"tc", "tc-auto"}) -public class UserRepositoryTCAutoIntegrationTest extends UserRepositoryCommon { +public class UserRepositoryTCAutoLiveTest extends UserRepositoryCommon { @ClassRule public static PostgreSQLContainer postgreSQLContainer = BaeldungPostgresqlContainer.getInstance(); diff --git a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCIntegrationTest.java b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCLiveTest.java similarity index 93% rename from persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCIntegrationTest.java rename to persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCLiveTest.java index afdf60cc81..be8843c166 100644 --- a/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCIntegrationTest.java +++ b/persistence-modules/spring-data-jpa/src/test/java/com/baeldung/boot/daos/UserRepositoryTCLiveTest.java @@ -22,8 +22,8 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) @ActiveProfiles("tc") -@ContextConfiguration(initializers = {UserRepositoryTCIntegrationTest.Initializer.class}) -public class UserRepositoryTCIntegrationTest extends UserRepositoryCommon { +@ContextConfiguration(initializers = {UserRepositoryTCLiveTest.Initializer.class}) +public class UserRepositoryTCLiveTest extends UserRepositoryCommon { @ClassRule public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer("postgres:11.1") diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java index c3805bac57..31877255b2 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/criteria/HibernateCriteriaIntegrationTest.java @@ -3,7 +3,7 @@ package com.baeldung.hibernate.criteria; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; - +import static org.junit.Assert.assertFalse; import java.util.List; import org.hibernate.Session; @@ -25,7 +25,7 @@ public class HibernateCriteriaIntegrationTest { @Test public void testPerformanceOfCriteria() { - assertTrue(av.checkIfCriteriaTimeLower()); + assertFalse(av.checkIfCriteriaTimeLower()); } @Test From 76370b794ff6d41a3a1463b6fe176ab2223b313b Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Fri, 31 May 2019 09:09:26 +0100 Subject: [PATCH 174/185] Examples of Quasar in Kotlin (#7045) --- kotlin-quasar/pom.xml | 120 ++++++++++++++ .../com/baeldung/quasar/QuasarHelloWorld.kt | 19 +++ .../com/baeldung/quasar/ChannelsTest.kt | 155 ++++++++++++++++++ .../com/baeldung/quasar/DataflowTest.kt | 35 ++++ .../kotlin/com/baeldung/quasar/PiAsyncTest.kt | 53 ++++++ .../quasar/SuspendableCallableTest.kt | 48 ++++++ .../quasar/SuspensableRunnableTest.kt | 47 ++++++ 7 files changed, 477 insertions(+) create mode 100644 kotlin-quasar/pom.xml create mode 100644 kotlin-quasar/src/main/kotlin/com/baeldung/quasar/QuasarHelloWorld.kt create mode 100644 kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ChannelsTest.kt create mode 100644 kotlin-quasar/src/test/kotlin/com/baeldung/quasar/DataflowTest.kt create mode 100644 kotlin-quasar/src/test/kotlin/com/baeldung/quasar/PiAsyncTest.kt create mode 100644 kotlin-quasar/src/test/kotlin/com/baeldung/quasar/SuspendableCallableTest.kt create mode 100644 kotlin-quasar/src/test/kotlin/com/baeldung/quasar/SuspensableRunnableTest.kt diff --git a/kotlin-quasar/pom.xml b/kotlin-quasar/pom.xml new file mode 100644 index 0000000000..44feabd183 --- /dev/null +++ b/kotlin-quasar/pom.xml @@ -0,0 +1,120 @@ + + + 4.0.0 + com.baeldung + kotlin-quasar + 1.0.0-SNAPSHOT + kotlin-quasar + jar + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + co.paralleluniverse + quasar-core + ${quasar.version} + + + co.paralleluniverse + quasar-actors + ${quasar.version} + + + co.paralleluniverse + quasar-reactive-streams + ${quasar.version} + + + co.paralleluniverse + quasar-kotlin + ${quasar.version} + + + junit + junit + 4.12 + + + + + src/main/kotlin + src/test/kotlin + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + maven-dependency-plugin + 3.1.1 + + + getClasspathFilenames + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.1 + + -Dco.paralleluniverse.fibers.verifyInstrumentation=true + -javaagent:${co.paralleluniverse:quasar-core:jar} + + + + org.codehaus.mojo + exec-maven-plugin + 1.3.2 + + target/classes + echo + + -javaagent:${co.paralleluniverse:quasar-core:jar} + -classpath + com.baeldung.quasar.QuasarHelloWorldKt + + + + + + + + 0.8.0 + 1.3.31 + + diff --git a/kotlin-quasar/src/main/kotlin/com/baeldung/quasar/QuasarHelloWorld.kt b/kotlin-quasar/src/main/kotlin/com/baeldung/quasar/QuasarHelloWorld.kt new file mode 100644 index 0000000000..9bf01ecb09 --- /dev/null +++ b/kotlin-quasar/src/main/kotlin/com/baeldung/quasar/QuasarHelloWorld.kt @@ -0,0 +1,19 @@ +package com.baeldung.quasar + +import co.paralleluniverse.fibers.Fiber +import co.paralleluniverse.strands.SuspendableRunnable + + +/** + * Entrypoint into the application + */ +fun main(args: Array) { + class Runnable : SuspendableRunnable { + override fun run() { + println("Hello") + } + } + val result = Fiber(Runnable()).start() + result.join() + println("World") +} diff --git a/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ChannelsTest.kt b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ChannelsTest.kt new file mode 100644 index 0000000000..b51943446e --- /dev/null +++ b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/ChannelsTest.kt @@ -0,0 +1,155 @@ +package com.baeldung.quasar + +import co.paralleluniverse.fibers.Suspendable +import co.paralleluniverse.kotlin.fiber +import co.paralleluniverse.strands.channels.Channels +import co.paralleluniverse.strands.channels.Selector +import com.google.common.base.Function +import org.junit.Test + +class ChannelsTest { + @Test + fun createChannel() { + Channels.newChannel(0, // The size of the channel buffer + Channels.OverflowPolicy.BLOCK, // The policy for when the buffer is full + true, // Whether we should optimize for a single message producer + true) // Whether we should optimize for a single message consumer + } + + @Test + fun blockOnMessage() { + val channel = Channels.newChannel(0, Channels.OverflowPolicy.BLOCK, true, true) + + fiber @Suspendable { + while (!channel.isClosed) { + val message = channel.receive() + println("Received: $message") + } + println("Stopped receiving messages") + } + + channel.send("Hello") + channel.send("World") + + channel.close() + } + + @Test + fun selectReceiveChannels() { + val channel1 = Channels.newChannel(0, Channels.OverflowPolicy.BLOCK, true, true) + val channel2 = Channels.newChannel(0, Channels.OverflowPolicy.BLOCK, true, true) + + fiber @Suspendable { + while (!channel1.isClosed && !channel2.isClosed) { + val received = Selector.select(Selector.receive(channel1), Selector.receive(channel2)) + + println("Received: $received") + } + } + + fiber @Suspendable { + for (i in 0..10) { + channel1.send("Channel 1: $i") + } + } + + fiber @Suspendable { + for (i in 0..10) { + channel2.send("Channel 2: $i") + } + } + } + + @Test + fun selectSendChannels() { + val channel1 = Channels.newChannel(0, Channels.OverflowPolicy.BLOCK, true, true) + val channel2 = Channels.newChannel(0, Channels.OverflowPolicy.BLOCK, true, true) + + fiber @Suspendable { + for (i in 0..10) { + Selector.select( + Selector.send(channel1, "Channel 1: $i"), + Selector.send(channel2, "Channel 2: $i") + ) + } + } + + fiber @Suspendable { + while (!channel1.isClosed) { + val msg = channel1.receive() + println("Read: $msg") + } + } + + fiber @Suspendable { + while (!channel2.isClosed) { + val msg = channel2.receive() + println("Read: $msg") + } + } + } + + @Test + fun tickerChannel() { + val channel = Channels.newChannel(3, Channels.OverflowPolicy.DISPLACE) + + for (i in 0..10) { + val tickerConsumer = Channels.newTickerConsumerFor(channel) + fiber @Suspendable { + while (!tickerConsumer.isClosed) { + val message = tickerConsumer.receive() + println("Received on $i: $message") + } + println("Stopped receiving messages on $i") + } + } + + for (i in 0..50) { + channel.send("Message $i") + } + + channel.close() + } + + + @Test + fun transformOnSend() { + val channel = Channels.newChannel(0, Channels.OverflowPolicy.BLOCK, true, true) + + fiber @Suspendable { + while (!channel.isClosed) { + val message = channel.receive() + println("Received: $message") + } + println("Stopped receiving messages") + } + + val transformOnSend = Channels.mapSend(channel, Function { msg: String? -> msg?.toUpperCase() }) + + transformOnSend.send("Hello") + transformOnSend.send("World") + + channel.close() + } + + @Test + fun transformOnReceive() { + val channel = Channels.newChannel(0, Channels.OverflowPolicy.BLOCK, true, true) + + val transformOnReceive = Channels.map(channel, Function { msg: String? -> msg?.reversed() }) + + fiber @Suspendable { + while (!transformOnReceive.isClosed) { + val message = transformOnReceive.receive() + println("Received: $message") + } + println("Stopped receiving messages") + } + + + channel.send("Hello") + channel.send("World") + + channel.close() + } +} diff --git a/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/DataflowTest.kt b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/DataflowTest.kt new file mode 100644 index 0000000000..3f73af3917 --- /dev/null +++ b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/DataflowTest.kt @@ -0,0 +1,35 @@ +package com.baeldung.quasar + +import co.paralleluniverse.strands.dataflow.Val +import co.paralleluniverse.strands.dataflow.Var +import org.junit.Assert +import org.junit.Test +import java.util.concurrent.TimeUnit + +class DataflowTest { + @Test + fun testValVar() { + val a = Var() + val b = Val() + + val c = Var { a.get() + b.get() } + val d = Var { a.get() * b.get() } + + // (a*b) - (a+b) + val initialResult = Val { d.get() - c.get() } + val currentResult = Var { d.get() - c.get() } + + a.set(2) + b.set(4) + + Assert.assertEquals(2, initialResult.get()) + Assert.assertEquals(2, currentResult.get()) + + a.set(3) + + TimeUnit.SECONDS.sleep(1) + + Assert.assertEquals(2, initialResult.get()) + Assert.assertEquals(5, currentResult.get()) + } +} diff --git a/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/PiAsyncTest.kt b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/PiAsyncTest.kt new file mode 100644 index 0000000000..d4ea04820d --- /dev/null +++ b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/PiAsyncTest.kt @@ -0,0 +1,53 @@ +package com.baeldung.quasar + +import co.paralleluniverse.fibers.Fiber +import co.paralleluniverse.fibers.FiberAsync +import co.paralleluniverse.fibers.Suspendable +import co.paralleluniverse.kotlin.fiber +import co.paralleluniverse.strands.Strand +import org.junit.Assert +import org.junit.Test +import java.math.BigDecimal +import java.util.concurrent.TimeUnit + +interface PiCallback { + fun success(result: BigDecimal) + fun failure(error: Exception) +} + +fun computePi(callback: PiCallback) { + println("Starting calculations") + TimeUnit.SECONDS.sleep(2) + println("Finished calculations") + callback.success(BigDecimal("3.14")) +} + +class PiAsync : PiCallback, FiberAsync() { + override fun success(result: BigDecimal) { + asyncCompleted(result) + } + + override fun failure(error: Exception) { + asyncFailed(error) + } + + override fun requestAsync() { + computePi(this) + } +} + +class PiAsyncTest { + @Test + fun testPi() { + val result = fiber @Suspendable { + val pi = PiAsync() + println("Waiting to get PI on: " + Fiber.currentFiber().name) + val result = pi.run() + println("Got PI") + + result + }.get() + + Assert.assertEquals(BigDecimal("3.14"), result) + } +} diff --git a/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/SuspendableCallableTest.kt b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/SuspendableCallableTest.kt new file mode 100644 index 0000000000..9b139dd686 --- /dev/null +++ b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/SuspendableCallableTest.kt @@ -0,0 +1,48 @@ +package com.baeldung.quasar + +import co.paralleluniverse.fibers.Fiber +import co.paralleluniverse.fibers.Suspendable +import co.paralleluniverse.kotlin.fiber +import co.paralleluniverse.strands.SuspendableCallable +import org.junit.Assert +import org.junit.Test +import java.util.concurrent.TimeUnit + + +class SuspendableCallableTest { + @Test + fun createFiber() { + class Callable : SuspendableCallable { + override fun run(): String { + println("Inside Fiber") + return "Hello" + } + } + val result = Fiber(Callable()).start() + + Assert.assertEquals("Hello", result.get()) + } + + @Test + fun createFiberLambda() { + val lambda: (() -> String) = { + println("Inside Fiber Lambda") + "Hello" + } + val result = Fiber(lambda) + result.start() + + Assert.assertEquals("Hello", result.get()) + } + + @Test + fun createFiberDsl() { + val result = fiber @Suspendable { + TimeUnit.SECONDS.sleep(5) + println("Inside Fiber DSL") + "Hello" + } + + Assert.assertEquals("Hello", result.get()) + } +} diff --git a/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/SuspensableRunnableTest.kt b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/SuspensableRunnableTest.kt new file mode 100644 index 0000000000..ba4cef8f4c --- /dev/null +++ b/kotlin-quasar/src/test/kotlin/com/baeldung/quasar/SuspensableRunnableTest.kt @@ -0,0 +1,47 @@ +package com.baeldung.quasar + +import co.paralleluniverse.fibers.Fiber +import co.paralleluniverse.fibers.Suspendable +import co.paralleluniverse.kotlin.fiber +import co.paralleluniverse.strands.SuspendableRunnable +import org.junit.Test +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + + +class SuspensableRunnableTest { + @Test + fun createFiber() { + class Runnable : SuspendableRunnable { + override fun run() { + println("Inside Fiber") + } + } + val result = Fiber(Runnable()).start() + result.join() + } + + @Test + fun createFiberLambda() { + val result = Fiber { + println("Inside Fiber Lambda") + } + result.start() + result.join() + } + + @Test + fun createFiberDsl() { + fiber @Suspendable { + println("Inside Fiber DSL") + }.join() + } + + @Test(expected = TimeoutException::class) + fun fiberTimeout() { + fiber @Suspendable { + TimeUnit.SECONDS.sleep(5) + println("Inside Fiber DSL") + }.join(2, TimeUnit.SECONDS) + } +} From 879ac26e844628cd63f69c20b3e6a3deb028621e Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 1 Jun 2019 09:15:51 +0300 Subject: [PATCH 175/185] Update README.md --- spring-security-rest-custom/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-security-rest-custom/README.md b/spring-security-rest-custom/README.md index 85f2b7532c..d7cb31e784 100644 --- a/spring-security-rest-custom/README.md +++ b/spring-security-rest-custom/README.md @@ -8,3 +8,4 @@ The "REST With Spring" Classes: http://github.learnspringsecurity.com ### Relevant Articles: - [Spring Security Authentication Provider](http://www.baeldung.com/spring-security-authentication-provider) - [Retrieve User Information in Spring Security](http://www.baeldung.com/get-user-in-spring-security) +- [Spring Security – Run-As Authentication](https://www.baeldung.com/spring-security-run-as-auth) From dc73b7abff2f44e495546531b6cc7259efcdd855 Mon Sep 17 00:00:00 2001 From: pkoli Date: Sat, 1 Jun 2019 13:50:48 +0530 Subject: [PATCH 176/185] BAEL-2886- post incremented counter variable --- .../SpringSessionMongoDBIntegrationTest.java | 43 ------------------- spring-session/spring-session-mongodb/pom.xml | 2 + .../SpringSessionMongoDBController.java | 6 +-- .../SpringSessionMongoDBIntegrationTest.java | 8 ++-- .../SpringContextIntegrationTest.java | 3 +- 5 files changed, 10 insertions(+), 52 deletions(-) delete mode 100644 spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java diff --git a/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java deleted file mode 100644 index c73335b49b..0000000000 --- a/spring-session/mongodb-session/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.baeldung.springsessionmongodb; - -import org.junit.Assert; -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.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.session.data.mongo.MongoOperationsSessionRepository; -import org.springframework.test.context.junit4.SpringRunner; -import springsessionmongodb.SpringSessionMongoDBApplication; - -import java.util.Base64; - - -@RunWith(SpringRunner.class) -@SpringBootTest(classes = SpringSessionMongoDBApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) -public class SpringSessionMongoDBIntegrationTest { - - @Autowired - private MongoOperationsSessionRepository repository; - - private TestRestTemplate restTemplate = new TestRestTemplate(); - - @Test - public void givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() { - HttpEntity response = restTemplate. - exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class); - HttpHeaders headers = response.getHeaders(); - String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE); - - Assert.assertEquals(response.getBody(), - repository.findById(getSessionId(set_cookie)).getAttribute("count").toString()); - } - - private String getSessionId(String set_cookie) { - return new String(Base64.getDecoder().decode(set_cookie.split(";")[0].split("=")[1])); - } - -} diff --git a/spring-session/spring-session-mongodb/pom.xml b/spring-session/spring-session-mongodb/pom.xml index 714833cf99..16fbaccc84 100644 --- a/spring-session/spring-session-mongodb/pom.xml +++ b/spring-session/spring-session-mongodb/pom.xml @@ -32,6 +32,7 @@ org.springframework.boot spring-boot-starter-data-mongodb + ${spring-boot-starter-data-mongodb.version} @@ -43,6 +44,7 @@ 2.1.3.RELEASE + 2.1.5.RELEASE diff --git a/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java index 1c38f419c3..b5cb4520a0 100644 --- a/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java +++ b/spring-session/spring-session-mongodb/src/main/java/com/baeldung/springsessionmongodb/controller/SpringSessionMongoDBController.java @@ -1,11 +1,11 @@ package com.baeldung.springsessionmongodb.controller; -import javax.servlet.http.HttpSession; - import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpSession; + @RestController public class SpringSessionMongoDBController { @@ -17,7 +17,7 @@ public class SpringSessionMongoDBController { if (counter == null) { counter = 1; } else { - counter += 1; + counter++; } session.setAttribute("count", counter); diff --git a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java index eb9f4164a6..9dc45c5b32 100644 --- a/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java +++ b/spring-session/spring-session-mongodb/src/test/java/com/baeldung/springsessionmongodb/SpringSessionMongoDBIntegrationTest.java @@ -1,7 +1,5 @@ package com.baeldung.springsessionmongodb; -import java.util.Base64; - import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -14,6 +12,8 @@ import org.springframework.http.HttpMethod; import org.springframework.session.data.mongo.MongoOperationsSessionRepository; import org.springframework.test.context.junit4.SpringRunner; +import java.util.Base64; + @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringSessionMongoDBApplication.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) @@ -26,8 +26,8 @@ public class SpringSessionMongoDBIntegrationTest { @Test public void givenEndpointIsCalledTwiceAndResponseIsReturned_whenMongoDBIsQueriedForCount_thenCountMustBeSame() { - HttpEntity response = restTemplate. - exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class); + HttpEntity response = restTemplate + .exchange("http://localhost:" + 8080, HttpMethod.GET, null, String.class); HttpHeaders headers = response.getHeaders(); String set_cookie = headers.getFirst(HttpHeaders.SET_COOKIE); diff --git a/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 3c58b2673f..16b7404f57 100644 --- a/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-session/spring-session-mongodb/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,12 +1,11 @@ package org.baeldung; +import com.baeldung.springsessionmongodb.SpringSessionMongoDBApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.springsessionmongodb.SpringSessionMongoDBApplication; - @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringSessionMongoDBApplication.class) public class SpringContextIntegrationTest { From 011bd19b09f26f2c62468dcc4240c4472ad427a1 Mon Sep 17 00:00:00 2001 From: Loredana Date: Sat, 1 Jun 2019 11:32:00 +0300 Subject: [PATCH 177/185] revert junit version --- pom.xml | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 39803fd9b0..0a8eebda71 100644 --- a/pom.xml +++ b/pom.xml @@ -123,17 +123,22 @@ - - org.junit.jupiter - junit-jupiter-engine - ${junit-jupiter.version} - - - org.junit.vintage - junit-vintage-engine - ${junit-jupiter.version} - - + + org.junit.platform + junit-platform-surefire-provider + ${junit-platform.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + + + org.junit.vintage + junit-vintage-engine + ${junit-jupiter.version} + + org.apache.maven.plugins @@ -1550,8 +1555,8 @@ 1.2 2.9.8 1.3 - 1.4.2 - 5.4.2 + 1.2.0 + 5.4.0 0.3.1 2.5.1 0.0.1 From 503331b3715b8538bd320159f2cfb4a1a83fd07b Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 1 Jun 2019 17:24:25 +0300 Subject: [PATCH 178/185] Update README.md --- persistence-modules/java-mongodb/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/persistence-modules/java-mongodb/README.md b/persistence-modules/java-mongodb/README.md index 6d31467db3..045b245030 100644 --- a/persistence-modules/java-mongodb/README.md +++ b/persistence-modules/java-mongodb/README.md @@ -3,3 +3,4 @@ - [A Guide to MongoDB with Java](http://www.baeldung.com/java-mongodb) - [A Simple Tagging Implementation with MongoDB](http://www.baeldung.com/mongodb-tagging) - [MongoDB BSON Guide](https://www.baeldung.com/mongodb-bson) +- [Geospatial Support in MongoDB](https://www.baeldung.com/mongodb-geospatial-support) From 0e56ee46fe49ad6d87173baa35d9e9f8c14b37cc Mon Sep 17 00:00:00 2001 From: Loredana Date: Sat, 1 Jun 2019 18:57:18 +0300 Subject: [PATCH 179/185] fix flowable test --- .../main/resources/processes/article-workflow.bpmn20.xml | 4 ++-- ...lowUnitTest.java => ArticleWorkflowIntegrationTest.java} | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) rename spring-boot-flowable/src/test/java/com/baeldung/processes/{ArticleWorkflowUnitTest.java => ArticleWorkflowIntegrationTest.java} (90%) diff --git a/spring-boot-flowable/src/main/resources/processes/article-workflow.bpmn20.xml b/spring-boot-flowable/src/main/resources/processes/article-workflow.bpmn20.xml index 6bf210dcee..77c02f39a4 100644 --- a/spring-boot-flowable/src/main/resources/processes/article-workflow.bpmn20.xml +++ b/spring-boot-flowable/src/main/resources/processes/article-workflow.bpmn20.xml @@ -38,12 +38,12 @@ + flowable:class="com.baeldung.service.PublishArticleService" /> + flowable:class="com.baeldung.service.SendMailService" /> diff --git a/spring-boot-flowable/src/test/java/com/baeldung/processes/ArticleWorkflowUnitTest.java b/spring-boot-flowable/src/test/java/com/baeldung/processes/ArticleWorkflowIntegrationTest.java similarity index 90% rename from spring-boot-flowable/src/test/java/com/baeldung/processes/ArticleWorkflowUnitTest.java rename to spring-boot-flowable/src/test/java/com/baeldung/processes/ArticleWorkflowIntegrationTest.java index ef5453623a..7d4557a679 100644 --- a/spring-boot-flowable/src/test/java/com/baeldung/processes/ArticleWorkflowUnitTest.java +++ b/spring-boot-flowable/src/test/java/com/baeldung/processes/ArticleWorkflowIntegrationTest.java @@ -13,11 +13,11 @@ import org.flowable.task.api.Task; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.boot.test.context.SpringBootTest; @ExtendWith(FlowableSpringExtension.class) -@ExtendWith(SpringExtension.class) -public class ArticleWorkflowUnitTest { +@SpringBootTest +public class ArticleWorkflowIntegrationTest { @Autowired private RuntimeService runtimeService; @Autowired From 4abfc5f863108106464cc0328294c4750734fafd Mon Sep 17 00:00:00 2001 From: Loredana Date: Sun, 2 Jun 2019 10:01:12 +0300 Subject: [PATCH 180/185] fix filter test --- .../baeldung/hibernate/DynamicMappingIntegrationTest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java index f31a61f121..fce670112b 100644 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java @@ -122,14 +122,11 @@ public class DynamicMappingIntegrationTest { Employee employee = session.get(Employee.class, 1); assertThat(employee.getGrossIncome()).isEqualTo(10_000); - session.close(); - - session = HibernateUtil.getSessionFactory().openSession(); - transaction = session.beginTransaction(); + session.disableFilter("incomeLevelFilter"); employees = session.createQuery("from Employee").getResultList(); - assertThat(employees).hasSize(0); + assertThat(employees).hasSize(3); } From f64ef7590a87328bf9fa6e94c451b0a71a00b743 Mon Sep 17 00:00:00 2001 From: Loredana Date: Sun, 2 Jun 2019 10:02:17 +0300 Subject: [PATCH 181/185] fix formatting --- .../com/baeldung/hibernate/DynamicMappingIntegrationTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java index fce670112b..7a112200b5 100644 --- a/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java +++ b/persistence-modules/hibernate5/src/test/java/com/baeldung/hibernate/DynamicMappingIntegrationTest.java @@ -122,8 +122,7 @@ public class DynamicMappingIntegrationTest { Employee employee = session.get(Employee.class, 1); assertThat(employee.getGrossIncome()).isEqualTo(10_000); - session.disableFilter("incomeLevelFilter"); - + session.disableFilter("incomeLevelFilter"); employees = session.createQuery("from Employee").getResultList(); assertThat(employees).hasSize(3); From ce68ce1c65b8d7d142c73276dc00caf26fa0bb31 Mon Sep 17 00:00:00 2001 From: binary-joe <48189951+binary-joe@users.noreply.github.com> Date: Mon, 3 Jun 2019 06:42:11 +0200 Subject: [PATCH 182/185] BAEL-2516 catching errors in catch blocks (#7075) * BAEL-2516 catching errors in catch block * BAEL-2516 catching errors in catch block; classes moved --- .../com/baeldung/error/ErrorGenerator.java | 15 ------ .../error/ErrorGeneratorUnitTest.java | 51 ------------------- .../error/ErrorGeneratorUnitTest.java | 26 ++++++++++ 3 files changed, 26 insertions(+), 66 deletions(-) delete mode 100644 core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java delete mode 100644 core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java create mode 100644 core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/error/ErrorGeneratorUnitTest.java diff --git a/core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java b/core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java deleted file mode 100644 index 58cbe22df5..0000000000 --- a/core-java-lang/src/main/java/com/baeldung/error/ErrorGenerator.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.baeldung.error; - -public class ErrorGenerator { - public void throwException() throws Exception { - throw new Exception("checked"); - } - - public void throwRuntimeException() { - throw new RuntimeException("unchecked"); - } - - public void throwError() { - throw new Error("unchecked"); - } -} diff --git a/core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java b/core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java deleted file mode 100644 index 2a7c24f5fa..0000000000 --- a/core-java-lang/src/test/java/com/baeldung/error/ErrorGeneratorUnitTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.baeldung.error; - -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -public class ErrorGeneratorUnitTest { - - private ErrorGenerator errorGenerator; - - @Before - public void setUp() { - errorGenerator = new ErrorGenerator(); - } - - @Test - public void whenCheckedException_thenIsCaughtByCatchException() { - try { - errorGenerator.throwException(); - } catch (Exception e) { - // caught! -> test pass - } - } - - @Test - public void whenUncheckedException_thenIsCaughtByCatchException() { - try { - errorGenerator.throwRuntimeException(); - } catch (Exception e) { - // caught! -> test pass - } - } - - @Test(expected = Error.class) - public void whenError_thenIsNotCaughtByCatchException() { - try { - errorGenerator.throwError(); - } catch (Exception e) { - Assert.fail(); // errors are not caught by catch exception - } - } - - @Test - public void whenError_thenIsCaughtByCatchError() { - try { - errorGenerator.throwError(); - } catch (Error e) { - // caught! -> test pass - } - } -} \ No newline at end of file diff --git a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/error/ErrorGeneratorUnitTest.java b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/error/ErrorGeneratorUnitTest.java new file mode 100644 index 0000000000..de56fb7113 --- /dev/null +++ b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/error/ErrorGeneratorUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.error; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ErrorGeneratorUnitTest { + + @Test(expected = AssertionError.class) + public void whenError_thenIsNotCaughtByCatchException() { + try { + throw new AssertionError(); + } catch (Exception e) { + Assert.fail(); // errors are not caught by catch exception + } + } + + @Test + public void whenError_thenIsCaughtByCatchError() { + try { + throw new AssertionError(); + } catch (Error e) { + // caught! -> test pass + } + } +} \ No newline at end of file From fd3e1bf293ccda51716aaba1fe7759c95ee1ab8b Mon Sep 17 00:00:00 2001 From: Dhawal Kapil Date: Mon, 3 Jun 2019 23:40:23 +0530 Subject: [PATCH 183/185] BAEL-14787 Reverted junit jupiter version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0a8eebda71..185c0a4015 100644 --- a/pom.xml +++ b/pom.xml @@ -1556,7 +1556,7 @@ 2.9.8 1.3 1.2.0 - 5.4.0 + 5.2.0 0.3.1 2.5.1 0.0.1 From 3cea8b6df16f6fd743474cce95f96cc6225094eb Mon Sep 17 00:00:00 2001 From: Rodrigo Graciano Date: Mon, 3 Jun 2019 23:34:33 -0400 Subject: [PATCH 184/185] BAEL-2936 --- .../main/java/com/baeldung/convertToMap/ConvertToMap.java | 3 +-- .../com/baeldung/convertToMap/ConvertToMapUnitTest.java | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java b/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java index 3c14dfdba6..e33d9ee212 100644 --- a/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java +++ b/java-collections-conversions/src/main/java/com/baeldung/convertToMap/ConvertToMap.java @@ -15,8 +15,7 @@ public class ConvertToMap { } public Map listToMapWithDupKey(List books) { - return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(), - (o1, o2) -> o1)); + return books.stream().collect(Collectors.toMap(Book::getReleaseYear, Function.identity(), (existing, replacement) -> existing)); } public Map listToConcurrentMap(List books) { diff --git a/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java b/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java index d11221bbf7..d6eab461d7 100644 --- a/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java +++ b/java-collections-conversions/src/test/java/com/baeldung/convertToMap/ConvertToMapUnitTest.java @@ -2,6 +2,7 @@ package com.baeldung.convertToMap; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import static org.junit.Assert.*; @@ -34,8 +35,10 @@ public class ConvertToMapUnitTest { } @Test - public void whenMapHasDuplicateKey_with_merge_function() { - assertTrue(convertToMap.listToMapWithDupKey(bookList).size() == 2); + public void whenMapHasDuplicateKeyThenMergeFunctionHandlesCollision() { + Map booksByYear = convertToMap.listToMapWithDupKey(bookList); + assertEquals(2, booksByYear.size()); + assertEquals("0395489318", booksByYear.get(1954).getIsbn()); } @Test From f6a9d02b3733d488b7172ded16562660d1918400 Mon Sep 17 00:00:00 2001 From: FrancoCorleone Date: Wed, 5 Jun 2019 06:31:00 +0200 Subject: [PATCH 185/185] [BAEL-2898] Working with XML in Groovy (#7083) --- .../baeldung/xml/MarkupBuilderUnitTest.groovy | 40 +++++++ .../com/baeldung/xml/XmlParserUnitTest.groovy | 94 ++++++++++++++++ .../baeldung/xml/XmlSlurperUnitTest.groovy | 102 ++++++++++++++++++ .../resources/com/baeldung/xml/articles.xml | 34 ++++++ .../baeldung/xml/articles_short_formatted.xml | 18 ++++ 5 files changed, 288 insertions(+) create mode 100644 core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy create mode 100644 core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy create mode 100644 core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy create mode 100644 core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml create mode 100644 core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml diff --git a/core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy new file mode 100644 index 0000000000..c0c8c98392 --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/xml/MarkupBuilderUnitTest.groovy @@ -0,0 +1,40 @@ +package com.baeldung.xml + +import groovy.xml.MarkupBuilder +import groovy.xml.XmlUtil +import spock.lang.Specification + +class MarkupBuilderUnitTest extends Specification { + + def xmlFile = getClass().getResource("articles_short_formatted.xml") + +def "Should create XML properly"() { + given: "Node structures" + + when: "Using MarkupBuilderUnitTest to create com.baeldung.xml structure" + def writer = new StringWriter() + new MarkupBuilder(writer).articles { + article { + title('First steps in Java') + author(id: '1') { + firstname('Siena') + lastname('Kerr') + } + 'release-date'('2018-12-01') + } + article { + title('Dockerize your SpringBoot application') + author(id: '2') { + firstname('Jonas') + lastname('Lugo') + } + 'release-date'('2018-12-01') + } + } + + then: "Xml is created properly" + XmlUtil.serialize(writer.toString()) == XmlUtil.serialize(xmlFile.text) +} + + +} diff --git a/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy new file mode 100644 index 0000000000..ada47406a1 --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlParserUnitTest.groovy @@ -0,0 +1,94 @@ +package com.baeldung.xml + + +import spock.lang.Shared +import spock.lang.Specification + +class XmlParserUnitTest extends Specification { + + def xmlFile = getClass().getResourceAsStream("articles.xml") + + @Shared + def parser = new XmlParser() + + def "Should read XML file properly"() { + given: "XML file" + + when: "Using XmlParser to read file" + def articles = parser.parse(xmlFile) + + then: "Xml is loaded properly" + articles.'*'.size() == 4 + articles.article[0].author.firstname.text() == "Siena" + articles.article[2].'release-date'.text() == "2018-06-12" + articles.article[3].title.text() == "Java 12 insights" + articles.article.find { it.author.'@id'.text() == "3" }.author.firstname.text() == "Daniele" + } + + + def "Should add node to existing com.baeldung.xml using NodeBuilder"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Adding node to com.baeldung.xml" + def articleNode = new NodeBuilder().article(id: '5') { + title('Traversing XML in the nutshell') + author { + firstname('Martin') + lastname('Schmidt') + } + 'release-date'('2019-05-18') + } + articles.append(articleNode) + + then: "Node is added to com.baeldung.xml properly" + articles.'*'.size() == 5 + articles.article[4].title.text() == "Traversing XML in the nutshell" + } + + def "Should replace node"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Adding node to com.baeldung.xml" + def articleNode = new NodeBuilder().article(id: '5') { + title('Traversing XML in the nutshell') + author { + firstname('Martin') + lastname('Schmidt') + } + 'release-date'('2019-05-18') + } + articles.article[0].replaceNode(articleNode) + + then: "Node is added to com.baeldung.xml properly" + articles.'*'.size() == 4 + articles.article[0].title.text() == "Traversing XML in the nutshell" + } + + def "Should modify node"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Changing value of one of the nodes" + articles.article.each { it.'release-date'[0].value = "2019-05-18" } + + then: "XML is updated" + articles.article.findAll { it.'release-date'.text() != "2019-05-18" }.isEmpty() + } + + def "Should remove article from com.baeldung.xml"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Removing all articles but with id==3" + articles.article + .findAll { it.author.'@id'.text() != "3" } + .each { articles.remove(it) } + + then: "There is only one article left" + articles.children().size() == 1 + articles.article[0].author.'@id'.text() == "3" + } + +} diff --git a/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy b/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy new file mode 100644 index 0000000000..ffeaa46fce --- /dev/null +++ b/core-groovy-2/src/test/groovy/com/baeldung/xml/XmlSlurperUnitTest.groovy @@ -0,0 +1,102 @@ +package com.baeldung.xml + + +import groovy.xml.XmlUtil +import spock.lang.Shared +import spock.lang.Specification + +class XmlSlurperUnitTest extends Specification { + + def xmlFile = getClass().getResourceAsStream("articles.xml") + + @Shared + def parser = new XmlSlurper() + + def "Should read XML file properly"() { + given: "XML file" + + when: "Using XmlSlurper to read file" + def articles = parser.parse(xmlFile) + + then: "Xml is loaded properly" + articles.'*'.size() == 4 + articles.article[0].author.firstname == "Siena" + articles.article[2].'release-date' == "2018-06-12" + articles.article[3].title == "Java 12 insights" + articles.article.find { it.author.'@id' == "3" }.author.firstname == "Daniele" + } + + def "Should add node to existing com.baeldung.xml"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Adding node to com.baeldung.xml" + articles.appendNode { + article(id: '5') { + title('Traversing XML in the nutshell') + author { + firstname('Martin') + lastname('Schmidt') + } + 'release-date'('2019-05-18') + } + } + + articles = parser.parseText(XmlUtil.serialize(articles)) + + then: "Node is added to com.baeldung.xml properly" + articles.'*'.size() == 5 + articles.article[4].title == "Traversing XML in the nutshell" + } + + def "Should modify node"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Changing value of one of the nodes" + articles.article.each { it.'release-date' = "2019-05-18" } + + then: "XML is updated" + articles.article.findAll { it.'release-date' != "2019-05-18" }.isEmpty() + } + + def "Should replace node"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Replacing node" + articles.article[0].replaceNode { + article(id: '5') { + title('Traversing XML in the nutshell') + author { + firstname('Martin') + lastname('Schmidt') + } + 'release-date'('2019-05-18') + } + } + + articles = parser.parseText(XmlUtil.serialize(articles)) + + then: "Node is replaced properly" + articles.'*'.size() == 4 + articles.article[0].title == "Traversing XML in the nutshell" + } + + def "Should remove article from com.baeldung.xml"() { + given: "XML object" + def articles = parser.parse(xmlFile) + + when: "Removing all articles but with id==3" + articles.article + .findAll { it.author.'@id' != "3" } + .replaceNode {} + + articles = parser.parseText(XmlUtil.serialize(articles)) + + then: "There is only one article left" + articles.children().size() == 1 + articles.article[0].author.'@id' == "3" + } + +} diff --git a/core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml b/core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml new file mode 100644 index 0000000000..ef057405f5 --- /dev/null +++ b/core-groovy-2/src/test/resources/com/baeldung/xml/articles.xml @@ -0,0 +1,34 @@ + +
+ First steps in Java + + Siena + Kerr + + 2018-12-01 +
+
+ Dockerize your SpringBoot application + + Jonas + Lugo + + 2018-12-01 +
+
+ SpringBoot tutorial + + Daniele + Ferguson + + 2018-06-12 +
+
+ Java 12 insights + + Siena + Kerr + + 2018-07-22 +
+
diff --git a/core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml b/core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml new file mode 100644 index 0000000000..6492020e03 --- /dev/null +++ b/core-groovy-2/src/test/resources/com/baeldung/xml/articles_short_formatted.xml @@ -0,0 +1,18 @@ + +
+ First steps in Java + + Siena + Kerr + + 2018-12-01 +
+
+ Dockerize your SpringBoot application + + Jonas + Lugo + + 2018-12-01 +
+