diff --git a/core-java-8/pom.xml b/core-java-8/pom.xml index f5506f095e..17d330b3b8 100644 --- a/core-java-8/pom.xml +++ b/core-java-8/pom.xml @@ -1,258 +1,276 @@ - - 4.0.0 - com.baeldung - core-java-8 - 0.1.0-SNAPSHOT - jar - - core-java-8 - - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - - - com.google.guava - guava - ${guava.version} - - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - - - - commons-io - commons-io - ${commons-io.version} - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - - org.apache.commons - commons-math3 - ${commons-math3.version} - - - - log4j - log4j - 1.2.17 - - - - commons-codec - commons-codec - ${commons-codec.version} - - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - - - org.assertj - assertj-core - ${assertj.version} - test - - - - com.jayway.awaitility - awaitility - ${avaitility.version} - test - - - - - - core-java-8 - - - src/main/resources - true - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - - - - org.apache.maven.plugins - maven-jar-plugin - - - - true - libs/ - org.baeldung.executable.ExecutableMavenJar - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - ${project.basedir} - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - - - - - - - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - - - **/*IntegrationTest.java - - - - - - - json - - - - - - - - - - - - 21.0 - 3.5 - 3.6.1 - 2.5 - 4.1 - 4.01 - 1.10 - 1.16.12 - - - 3.6.1 - 1.7.0 - - + + 4.0.0 + com.baeldung + core-java-8 + 0.1.0-SNAPSHOT + jar + + core-java-8 + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + + + + com.google.guava + guava + ${guava.version} + + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + commons-io + commons-io + ${commons-io.version} + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + org.apache.commons + commons-math3 + ${commons-math3.version} + + + + log4j + log4j + 1.2.17 + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + + org.openjdk.jmh + jmh-core + 1.19 + + + + org.openjdk.jmh + jmh-generator-annprocess + 1.19 + + + + org.openjdk.jmh + jmh-generator-bytecode + 1.19 + + + + + + core-java-8 + + + src/main/resources + true + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/libs + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + org.baeldung.executable.ExecutableMavenJar + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + ${project.basedir} + + + org.baeldung.executable.ExecutableMavenJar + + + + jar-with-dependencies + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + true + + + org.baeldung.executable.ExecutableMavenJar + + + + + + + + com.jolira + onejar-maven-plugin + + + + org.baeldung.executable.ExecutableMavenJar + true + ${project.build.finalName}-onejar.${project.packaging} + + + one-jar + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + spring-boot + org.baeldung.executable.ExecutableMavenJar + + + + + + + + + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + + + + + + + + 21.0 + 3.5 + 3.6.1 + 2.5 + 4.1 + 4.01 + 1.10 + 1.16.12 + + + 3.6.1 + 1.7.0 + + \ No newline at end of file diff --git a/core-java-8/src/test/java/com/baeldung/counter/CounterStatistics.java b/core-java-8/src/test/java/com/baeldung/counter/CounterStatistics.java new file mode 100644 index 0000000000..2a42a166fa --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/counter/CounterStatistics.java @@ -0,0 +1,45 @@ +package com.baeldung.counter; + +import java.util.HashMap; +import java.util.Map; + +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 com.baeldung.counter.CounterUtil.MutableInteger; + +@Fork(value = 1, warmups = 3) +@BenchmarkMode(Mode.All) +public class CounterStatistics { + + private static final Map counterMap = new HashMap<>(); + private static final Map counterWithMutableIntMap = new HashMap<>(); + private static final Map counterWithIntArrayMap = new HashMap<>(); + private static final Map counterWithLongWrapperMap = new HashMap<>(); + + @Benchmark + public void wrapperAsCounter() { + CounterUtil.counterWithWrapperObject(counterMap); + } + + @Benchmark + public void lambdaExpressionWithWrapper() { + CounterUtil.counterWithLambdaAndWrapper(counterWithLongWrapperMap); + } + + @Benchmark + public void mutableIntegerAsCounter() { + CounterUtil.counterWithMutableInteger(counterWithMutableIntMap); + } + + @Benchmark + public void primitiveArrayAsCounter() { + CounterUtil.counterWithPrimitiveArray(counterWithIntArrayMap); + } + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/counter/CounterTest.java b/core-java-8/src/test/java/com/baeldung/counter/CounterTest.java new file mode 100644 index 0000000000..657b510452 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/counter/CounterTest.java @@ -0,0 +1,53 @@ +package com.baeldung.counter; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import com.baeldung.counter.CounterUtil.MutableInteger; + +public class CounterTest { + + @Test + public void whenMapWithWrapperAsCounter_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithWrapperObject(counterMap); + + assertEquals(3, counterMap.get("China") + .intValue()); + assertEquals(2, counterMap.get("India") + .intValue()); + } + + @Test + public void whenMapWithLambdaAndWrapperCounter_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithLambdaAndWrapper(counterMap); + + assertEquals(3l, counterMap.get("China") + .longValue()); + assertEquals(2l, counterMap.get("India") + .longValue()); + } + + @Test + public void whenMapWithMutableIntegerCounter_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithMutableInteger(counterMap); + assertEquals(3, counterMap.get("China") + .getCount()); + assertEquals(2, counterMap.get("India") + .getCount()); + } + + @Test + public void whenMapWithPrimitiveArray_runsSuccessfully() { + Map counterMap = new HashMap<>(); + CounterUtil.counterWithPrimitiveArray(counterMap); + assertEquals(3, counterMap.get("China")[0]); + assertEquals(2, counterMap.get("India")[0]); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/counter/CounterUtil.java b/core-java-8/src/test/java/com/baeldung/counter/CounterUtil.java new file mode 100644 index 0000000000..647fbfb0cc --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/counter/CounterUtil.java @@ -0,0 +1,61 @@ +package com.baeldung.counter; + +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class CounterUtil { + + private final static String[] COUNTRY_NAMES = { "China", "Australia", "India", "USA", "USSR", "UK", "China", "France", "Poland", "Austria", "India", "USA", "Egypt", "China" }; + + public static void counterWithWrapperObject(Map counterMap) { + for (String country : COUNTRY_NAMES) { + counterMap.compute(country, (k, v) -> v == null ? 1 : v + 1); + } + } + + public static void counterWithLambdaAndWrapper(Map counterMap) { + counterMap.putAll(Stream.of(COUNTRY_NAMES) + .parallel() + .collect(Collectors.groupingBy(k -> k, Collectors.counting()))); + } + + public static class MutableInteger { + int count; + + public MutableInteger(int count) { + this.count = count; + } + + public void increment() { + this.count++; + } + + public int getCount() { + return this.count; + } + } + + public static void counterWithMutableInteger(Map counterMap) { + for (String country : COUNTRY_NAMES) { + MutableInteger oldValue = counterMap.get(country); + if (oldValue != null) { + oldValue.increment(); + } else { + counterMap.put(country, new MutableInteger(1)); + } + } + } + + public static void counterWithPrimitiveArray(Map counterMap) { + for (String country : COUNTRY_NAMES) { + int[] oldCounter = counterMap.get(country); + if (oldCounter != null) { + oldCounter[0] += 1; + } else { + counterMap.put(country, new int[] { 1 }); + } + } + } + +} diff --git a/core-java/README.md b/core-java/README.md index 1feee4126e..8287a21d1e 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -120,4 +120,5 @@ - [Guide to Java String Pool](http://www.baeldung.com/java-string-pool) - [Copy a File with Java](http://www.baeldung.com/java-copy-file) - [Introduction to Creational Design Patterns](http://www.baeldung.com/creational-design-patterns) +- [Quick Example - Comparator vs Comparable in Java](http://www.baeldung.com/java-comparator-comparable) diff --git a/core-java/customers.xml b/core-java/customers.xml new file mode 100644 index 0000000000..b52dc27633 --- /dev/null +++ b/core-java/customers.xml @@ -0,0 +1,95 @@ + + + + SELECT * FROM customers + 1008 + + true + 1000 + 0 + 2 + + + + + 0 + 0 + 0 + true + ResultSet.TYPE_SCROLL_INSENSITIVE + false + customers + jdbc:h2:mem:testdb + + com.sun.rowset.providers.RIOptimisticProvider + Oracle Corporation + 1.0 + 2 + 1 + + + + 2 + + 1 + false + true + false + 0 + true + true + 11 + ID + ID + PUBLIC + 10 + 0 + CUSTOMERS + TESTDB + 4 + INTEGER + + + 2 + false + true + false + 0 + true + true + 50 + NAME + NAME + PUBLIC + 50 + 0 + CUSTOMERS + TESTDB + 12 + VARCHAR + + + + + 1 + Customer1 + + + 2 + Customer2 + + + 3 + Customer3 + + + 4 + Customer4 + + + 5 + Customer5 + + + diff --git a/core-java/pom.xml b/core-java/pom.xml index 2c4cbfc37b..068a772c43 100644 --- a/core-java/pom.xml +++ b/core-java/pom.xml @@ -1,479 +1,496 @@ - 4.0.0 - com.baeldung - core-java - 0.1.0-SNAPSHOT - jar + 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 + 0.1.0-SNAPSHOT + jar - core-java + core-java - + - - - net.sourceforge.collections - collections-generic - ${collections-generic.version} - - - com.google.guava - guava - ${guava.version} - - - - org.apache.commons - commons-collections4 - ${commons-collections4.version} - - - - commons-io - commons-io - ${commons-io.version} - - - - org.apache.commons - commons-lang3 - ${commons-lang3.version} - - - - org.apache.commons - commons-math3 - ${commons-math3.version} - - - - org.decimal4j - decimal4j - ${decimal4j.version} - - - - org.bouncycastle - bcprov-jdk15on - ${bouncycastle.version} - - - - org.unix4j - unix4j-command - ${unix4j.version} - - - - com.googlecode.grep4j - grep4j - ${grep4j.version} - - - - - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - - - - - log4j - log4j - 1.2.17 - - - org.slf4j - slf4j-api - ${org.slf4j.version} - - - ch.qos.logback - logback-classic - ${logback.version} - - - - org.slf4j - jcl-over-slf4j - ${org.slf4j.version} - - - - org.slf4j - log4j-over-slf4j - ${org.slf4j.version} - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - - - org.hamcrest - hamcrest-all - 1.3 - test - - - - junit - junit - ${junit.version} - test - - - - org.hamcrest - hamcrest-core - ${org.hamcrest.version} - test - - - org.hamcrest - hamcrest-library - ${org.hamcrest.version} - test - - - - org.assertj - assertj-core - ${assertj.version} - test - - - - org.mockito - mockito-core - ${mockito.version} - test - - - com.jayway.awaitility - awaitility - ${avaitility.version} - test - - - - commons-codec - commons-codec - ${commons-codec.version} - - - - org.javamoney - moneta - 1.1 - - - - org.owasp.esapi - esapi - 2.1.0.1 - - - - com.codepoetics - protonpack - ${protonpack.version} - - - one.util - streamex - ${streamex.version} - - - io.vavr - vavr - ${vavr.version} - - - org.openjdk.jmh - jmh-core - 1.19 - - - org.openjdk.jmh - jmh-generator-annprocess - 1.19 - + - org.springframework - spring-web - 4.3.4.RELEASE + net.sourceforge.collections + collections-generic + ${collections-generic.version} + + + com.google.guava + guava + ${guava.version} - - - core-java - - - src/main/resources - true - - + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + - + + commons-io + commons-io + ${commons-io.version} + - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - 1.8 - 1.8 - - + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*LiveTest.java - **/*IntegrationTest.java - **/*LongRunningUnitTest.java - **/*ManualTest.java - + + org.apache.commons + commons-math3 + ${commons-math3.version} + - - + + org.decimal4j + decimal4j + ${decimal4j.version} + - - org.apache.maven.plugins - maven-dependency-plugin - - - copy-dependencies - prepare-package - - copy-dependencies - - - ${project.build.directory}/libs - - - - + + org.bouncycastle + bcprov-jdk15on + ${bouncycastle.version} + - - org.apache.maven.plugins - maven-jar-plugin - - - - true - libs/ - org.baeldung.executable.ExecutableMavenJar - - - - + + org.unix4j + unix4j-command + ${unix4j.version} + - - org.apache.maven.plugins - maven-assembly-plugin - - - package - - single - - - ${project.basedir} - - - org.baeldung.executable.ExecutableMavenJar - - - - jar-with-dependencies - - - - - + + com.googlecode.grep4j + grep4j + ${grep4j.version} + + - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - - true - - - org.baeldung.executable.ExecutableMavenJar - - - - - - + - - com.jolira - onejar-maven-plugin - - - - org.baeldung.executable.ExecutableMavenJar - true - ${project.build.finalName}-onejar.${project.packaging} - - - one-jar - - - - + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - spring-boot - org.baeldung.executable.ExecutableMavenJar - - - - + + + log4j + log4j + 1.2.17 + + + org.slf4j + slf4j-api + ${org.slf4j.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + + org.slf4j + jcl-over-slf4j + ${org.slf4j.version} + + + + org.slf4j + log4j-over-slf4j + ${org.slf4j.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + - - org.codehaus.mojo - exec-maven-plugin - 1.6.0 - - java - com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed - - -Xmx300m - -XX:+UseParallelGC - -classpath - - com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed - - - + + + + org.hamcrest + hamcrest-all + 1.3 + test + + + + junit + junit + ${junit.version} + test + + + + org.hamcrest + hamcrest-core + ${org.hamcrest.version} + test + + + org.hamcrest + hamcrest-library + ${org.hamcrest.version} + test + + + + org.assertj + assertj-core + ${assertj.version} + test + + + + org.mockito + mockito-core + ${mockito.version} + test + + + com.jayway.awaitility + awaitility + ${avaitility.version} + test + + + + commons-codec + commons-codec + ${commons-codec.version} + + + + org.javamoney + moneta + 1.1 + + + + org.owasp.esapi + esapi + 2.1.0.1 + + + com.h2database + h2 + 1.4.196 + runtime + + + com.sun.messaging.mq + fscontext + ${fscontext.version} + + + com.codepoetics + protonpack + ${protonpack.version} + + + one.util + streamex + ${streamex.version} + + + io.vavr + vavr + ${vavr.version} + + + org.openjdk.jmh + jmh-core + 1.19 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.19 + + + org.springframework + spring-web + 4.3.4.RELEASE + + + + org.springframework.boot + spring-boot-starter + 1.5.8.RELEASE + + + + + + core-java + + + src/main/resources + true + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + 1.8 + 1.8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*LiveTest.java + **/*IntegrationTest.java + **/*LongRunningUnitTest.java + **/*ManualTest.java + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/libs + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + org.baeldung.executable.ExecutableMavenJar + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + ${project.basedir} + + + org.baeldung.executable.ExecutableMavenJar + + + + jar-with-dependencies + + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + shade + + + true + + + org.baeldung.executable.ExecutableMavenJar + + + + + + + + + com.jolira + onejar-maven-plugin + + + + org.baeldung.executable.ExecutableMavenJar + true + ${project.build.finalName}-onejar.${project.packaging} + + + one-jar + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + spring-boot + org.baeldung.executable.ExecutableMavenJar + + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + java + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + -Xmx300m + -XX:+UseParallelGC + -classpath + + com.baeldung.outofmemoryerror.OutOfMemoryGCLimitExceed + + + - + - + - - - integration - - - - org.apache.maven.plugins - maven-surefire-plugin - - - integration-test - - test - - - - **/*ManualTest.java - - - **/*IntegrationTest.java - - - - - - - json - - - - - org.codehaus.mojo - exec-maven-plugin + + + integration + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration-test + + test + + + + **/*ManualTest.java + + + **/*IntegrationTest.java + + + + + + + json + + + + + org.codehaus.mojo + exec-maven-plugin - - - run-benchmarks - - none - - exec - - - test - java - - -classpath - - org.openjdk.jmh.Main - .* - - - - - - - - - + + + run-benchmarks + + none + + exec + + + test + java + + -classpath + + org.openjdk.jmh.Main + .* + + + + + + + + + - - - 2.8.5 + + + 2.8.5 - - 1.7.21 - 1.1.7 + + 1.7.21 + 1.1.7 - - 23.0 - 3.5 - 1.55 - 1.10 - 3.6.1 - 1.0.3 - 2.5 - 4.1 - 4.01 - 0.4 - 1.8.7 - 1.16.12 - 4.6-b01 - 1.13 - 0.6.5 - 0.9.0 - - - 1.3 - 4.12 - 2.8.9 - 3.6.1 - 1.7.0 + + 22.0 + 3.5 + 1.55 + 1.10 + 3.6.1 + 1.0.3 + 2.5 + 4.1 + 4.01 + 0.4 + 1.8.7 + 1.16.12 + 4.6-b01 + 1.13 + 0.6.5 + 0.9.0 - - 3.6.0 - 2.19.1 - - \ No newline at end of file + + 1.3 + 4.12 + 2.8.9 + 3.6.1 + 1.7.0 + + + 3.6.0 + 2.19.1 + + diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java b/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java new file mode 100644 index 0000000000..9cfcff468e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/DatabaseConfiguration.java @@ -0,0 +1,51 @@ +package com.baeldung.jdbcrowset; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.sql.rowset.JdbcRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetProvider; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +public class DatabaseConfiguration { + + + public static Connection geth2Connection() throws Exception { + Class.forName("org.h2.Driver"); + System.out.println("Driver Loaded."); + String url = "jdbc:h2:mem:testdb"; + return DriverManager.getConnection(url, "sa", ""); + } + + public static void initDatabase(Statement stmt) throws SQLException{ + int iter = 1; + while(iter<=5){ + String customer = "Customer"+iter; + String sql ="INSERT INTO customers(id, name) VALUES ("+iter+ ",'"+customer+"');"; + System.out.println("here is sql statmeent for execution: " + sql); + stmt.executeUpdate(sql); + iter++; + } + + int iterb = 1; + while(iterb<=5){ + String associate = "Associate"+iter; + String sql = "INSERT INTO associates(id, name) VALUES("+iterb+",'"+associate+"');"; + System.out.println("here is sql statement for associate:"+ sql); + stmt.executeUpdate(sql); + iterb++; + } + + + } + + + +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java b/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java new file mode 100644 index 0000000000..7d5bb759f5 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/ExampleListener.java @@ -0,0 +1,24 @@ +package com.baeldung.jdbcrowset; + +import javax.sql.RowSetEvent; +import javax.sql.RowSetListener; + +public class ExampleListener implements RowSetListener { + + + public void cursorMoved(RowSetEvent event) { + System.out.println("ExampleListener alerted of cursorMoved event"); + System.out.println(event.toString()); + } + + public void rowChanged(RowSetEvent event) { + System.out.println("ExampleListener alerted of rowChanged event"); + System.out.println(event.toString()); + } + + public void rowSetChanged(RowSetEvent event) { + System.out.println("ExampleListener alerted of rowSetChanged event"); + System.out.println(event.toString()); + } + +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java b/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java new file mode 100644 index 0000000000..14e738f72d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/FilterExample.java @@ -0,0 +1,46 @@ +package com.baeldung.jdbcrowset; + +import java.sql.SQLException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.sql.RowSet; +import javax.sql.rowset.Predicate; + +public class FilterExample implements Predicate { + + private Pattern pattern; + + public FilterExample(String regexQuery) { + if (regexQuery != null && !regexQuery.isEmpty()) { + pattern = Pattern.compile(regexQuery); + } + } + + public boolean evaluate(RowSet rs) { + try { + if (!rs.isAfterLast()) { + String name = rs.getString("name"); + System.out.println(String.format( + "Searching for pattern '%s' in %s", pattern.toString(), + name)); + Matcher matcher = pattern.matcher(name); + return matcher.matches(); + } else + return false; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public boolean evaluate(Object value, int column) throws SQLException { + throw new UnsupportedOperationException("This operation is unsupported."); + } + + public boolean evaluate(Object value, String columnName) + throws SQLException { + throw new UnsupportedOperationException("This operation is unsupported."); + } + +} diff --git a/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java b/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java new file mode 100644 index 0000000000..72c462ac42 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/jdbcrowset/JdbcRowsetApplication.java @@ -0,0 +1,139 @@ +package com.baeldung.jdbcrowset; + +import java.io.FileOutputStream; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import com.sun.rowset.*; + +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.FilteredRowSet; +import javax.sql.rowset.JdbcRowSet; +import javax.sql.rowset.JoinRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetProvider; +import javax.sql.rowset.WebRowSet; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class JdbcRowsetApplication { + + public static void main(String[] args) throws Exception { + SpringApplication.run(JdbcRowsetApplication.class, args); + Statement stmt = null; + try { + Connection conn = DatabaseConfiguration.geth2Connection(); + + String drop = "DROP TABLE IF EXISTS customers, associates;"; + String schema = "CREATE TABLE customers (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id)); "; + String schemapartb = "CREATE TABLE associates (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id));"; + + stmt = conn.createStatement(); + stmt.executeUpdate(drop); + stmt.executeUpdate(schema); + stmt.executeUpdate(schemapartb); + // insert data + DatabaseConfiguration.initDatabase(stmt); + // JdbcRowSet Example + String sql = "SELECT * FROM customers"; + JdbcRowSet jdbcRS; + jdbcRS = new JdbcRowSetImpl(conn); + jdbcRS.setType(ResultSet.TYPE_SCROLL_INSENSITIVE); + jdbcRS.setCommand(sql); + jdbcRS.execute(); + jdbcRS.addRowSetListener(new ExampleListener()); + + while (jdbcRS.next()) { + // each call to next, generates a cursorMoved event + System.out.println("id=" + jdbcRS.getString(1)); + System.out.println("name=" + jdbcRS.getString(2)); + } + + // CachedRowSet Example + String username = "sa"; + String password = ""; + String url = "jdbc:h2:mem:testdb"; + CachedRowSet crs = new CachedRowSetImpl(); + crs.setUsername(username); + crs.setPassword(password); + crs.setUrl(url); + crs.setCommand(sql); + crs.execute(); + crs.addRowSetListener(new ExampleListener()); + while (crs.next()) { + if (crs.getInt("id") == 1) { + System.out.println("CRS found customer1 and will remove the record."); + crs.deleteRow(); + break; + } + } + + // WebRowSet example + WebRowSet wrs = new WebRowSetImpl(); + wrs.setUsername(username); + wrs.setPassword(password); + wrs.setUrl(url); + wrs.setCommand(sql); + wrs.execute(); + FileOutputStream ostream = new FileOutputStream("customers.xml"); + wrs.writeXml(ostream); + + // JoinRowSet example + CachedRowSetImpl customers = new CachedRowSetImpl(); + customers.setUsername(username); + customers.setPassword(password); + customers.setUrl(url); + customers.setCommand(sql); + customers.execute(); + + CachedRowSetImpl associates = new CachedRowSetImpl(); + associates.setUsername(username); + associates.setPassword(password); + associates.setUrl(url); + String associatesSQL = "SELECT * FROM associates"; + associates.setCommand(associatesSQL); + associates.execute(); + + JoinRowSet jrs = new JoinRowSetImpl(); + final String ID = "id"; + final String NAME = "name"; + jrs.addRowSet(customers, ID); + jrs.addRowSet(associates, ID); + jrs.last(); + System.out.println("Total rows: " + jrs.getRow()); + jrs.beforeFirst(); + while (jrs.next()) { + + String string1 = jrs.getString(ID); + String string2 = jrs.getString(NAME); + System.out.println("ID: " + string1 + ", NAME: " + string2); + } + + // FilteredRowSet example + RowSetFactory rsf = RowSetProvider.newFactory(); + FilteredRowSet frs = rsf.createFilteredRowSet(); + frs.setCommand("select * from customers"); + frs.execute(conn); + frs.setFilter(new FilterExample("^[A-C].*")); + + ResultSetMetaData rsmd = frs.getMetaData(); + int columncount = rsmd.getColumnCount(); + while (frs.next()) { + for (int i = 1; i <= columncount; i++) { + System.out.println(rsmd.getColumnLabel(i) + " = " + frs.getObject(i) + " "); + } + } + + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/core-java/src/test/java/com/baeldung/array/SearchArrayTest.java b/core-java/src/test/java/com/baeldung/array/SearchArrayTest.java new file mode 100644 index 0000000000..94911baac9 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/array/SearchArrayTest.java @@ -0,0 +1,116 @@ +package com.baeldung.array; + +import org.junit.Test; + +import java.util.*; + +public class SearchArrayTest { + + + @Test + public void searchArrayAllocNewCollections() { + + int count = 1000; + + String[] strings = seedArray(count); + + long startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + searchList(strings, "W"); + } + long duration = System.nanoTime() - startTime; + System.out.println("SearchList: " + duration / 10000); + + startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + searchSet(strings,"S"); + } + duration = System.nanoTime() - startTime; + System.out.println("SearchSet: " + duration / 10000); + + startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + searchLoop(strings, "T"); + } + duration = System.nanoTime() - startTime; + System.out.println("SearchLoop: " + duration / 10000); + } + + @Test + public void searchArrayReuseCollections() { + + int count = 10000; + String[] strings = seedArray(count); + + List asList = Arrays.asList(strings); + Set asSet = new HashSet<>(Arrays.asList(strings)); + + long startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + asList.contains("W"); + } + long duration = System.nanoTime() - startTime; + System.out.println("List: " + duration / 10000); + + startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + asSet.contains("S"); + } + duration = System.nanoTime() - startTime; + System.out.println("Set: " + duration / 10000); + + startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + searchLoop(strings, "T"); + } + duration = System.nanoTime() - startTime; + System.out.println("Loop: " + duration / 10000); + + } + + + @Test + public void searchArrayBinarySearch() { + + int count = 10000; + String[] strings = seedArray(count); + Arrays.sort(strings); + + long startTime = System.nanoTime(); + for (int i = 0; i < count; i++) { + Arrays.binarySearch(strings, "A"); + } + long duration = System.nanoTime() - startTime; + System.out.println("Binary search: " + duration / 10000); + + } + + private boolean searchList(String[] strings, String searchString) { + return Arrays.asList(strings).contains(searchString); + } + + private boolean searchSet(String[] strings, String searchString) { + Set set = new HashSet<>(Arrays.asList(strings)); + return set.contains(searchString); + } + + private boolean searchLoop(String[] strings, String searchString) { + for (String s : strings) { + if (s.equals(searchString)) + return true; + } + return false; + } + + private String[] seedArray(int length) { + + String[] strings = new String[length]; + Random random = new Random(); + for (int i = 0; i < length; i++) + { + strings[i] = String.valueOf(random.nextInt()); + } + return strings; + } + +} diff --git a/core-java/src/test/java/com/baeldung/collection/WhenUsingHashSet.java b/core-java/src/test/java/com/baeldung/collection/WhenUsingHashSet.java new file mode 100644 index 0000000000..7dc47ee8c2 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/collection/WhenUsingHashSet.java @@ -0,0 +1,93 @@ +package com.baeldung.collection; + +import java.util.ConcurrentModificationException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; + +public class WhenUsingHashSet { + + @Test + public void whenAddingElement_shouldAddElement() { + Set hashset = new HashSet<>(); + Assert.assertTrue(hashset.add("String Added")); + } + + @Test + public void whenCheckingForElement_shouldSearchForElement() { + Set hashsetContains = new HashSet<>(); + hashsetContains.add("String Added"); + Assert.assertTrue(hashsetContains.contains("String Added")); + } + + @Test + public void whenCheckingTheSizeOfHashSet_shouldReturnThesize() { + Set hashSetSize = new HashSet<>(); + hashSetSize.add("String Added"); + Assert.assertEquals(1, hashSetSize.size()); + } + + @Test + public void whenCheckingForEmptyHashSet_shouldCheckForEmpty() { + Set emptyHashSet = new HashSet<>(); + Assert.assertTrue(emptyHashSet.isEmpty()); + } + + @Test + public void whenRemovingElement_shouldRemoveElement() { + Set removeFromHashSet = new HashSet<>(); + removeFromHashSet.add("String Added"); + Assert.assertTrue(removeFromHashSet.remove("String Added")); + } + + @Test + public void whenClearingHashSet_shouldClearHashSet() { + Set clearHashSet = new HashSet<>(); + clearHashSet.add("String Added"); + clearHashSet.clear(); + Assert.assertTrue(clearHashSet.isEmpty()); + } + + @Test + public void whenIteratingHashSet_shouldIterateHashSet() { + Set hashset = new HashSet<>(); + hashset.add("First"); + hashset.add("Second"); + hashset.add("Third"); + Iterator itr = hashset.iterator(); + while (itr.hasNext()) { + System.out.println(itr.next()); + } + } + + @Test(expected = ConcurrentModificationException.class) + public void whenModifyingHashSetWhileIterating_shouldThrowException() { + Set hashset = new HashSet<>(); + hashset.add("First"); + hashset.add("Second"); + hashset.add("Third"); + Iterator itr = hashset.iterator(); + while (itr.hasNext()) { + itr.next(); + hashset.remove("Second"); + } + } + + @Test + public void whenRemovingElementUsingIterator_shouldRemoveElement() { + Set hashset = new HashSet<>(); + hashset.add("First"); + hashset.add("Second"); + hashset.add("Third"); + Iterator itr = hashset.iterator(); + while (itr.hasNext()) { + String element = itr.next(); + if (element.equals("Second")) + itr.remove(); + } + Assert.assertEquals(2, hashset.size()); + } +} diff --git a/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetTest.java b/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetTest.java new file mode 100644 index 0000000000..cb455c213a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/jdbcrowset/JdbcRowSetTest.java @@ -0,0 +1,157 @@ +package com.baeldung.jdbcrowset; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.FilteredRowSet; +import javax.sql.rowset.JdbcRowSet; +import javax.sql.rowset.JoinRowSet; +import javax.sql.rowset.RowSetFactory; +import javax.sql.rowset.RowSetProvider; +import javax.sql.rowset.WebRowSet; + +import org.junit.Before; +import org.junit.Test; + +import com.sun.rowset.CachedRowSetImpl; +import com.sun.rowset.JdbcRowSetImpl; +import com.sun.rowset.JoinRowSetImpl; +import com.sun.rowset.WebRowSetImpl; + +public class JdbcRowSetTest { + Statement stmt = null; + String username = "sa"; + String password = ""; + String url = "jdbc:h2:mem:testdb"; + String sql = "SELECT * FROM customers"; + + @Before + public void setup() throws Exception { + Connection conn = DatabaseConfiguration.geth2Connection(); + + String drop = "DROP TABLE IF EXISTS customers, associates;"; + String schema = "CREATE TABLE customers (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id)); "; + String schemapartb = "CREATE TABLE associates (id INT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY (id));"; + stmt = conn.createStatement(); + stmt.executeUpdate(drop); + stmt.executeUpdate(schema); + stmt.executeUpdate(schemapartb); + DatabaseConfiguration.initDatabase(stmt); + + } + + // JdbcRowSet Example + @Test + public void createJdbcRowSet_SelectCustomers_ThenCorrect() throws Exception { + + String sql = "SELECT * FROM customers"; + JdbcRowSet jdbcRS; + Connection conn = DatabaseConfiguration.geth2Connection(); + jdbcRS = new JdbcRowSetImpl(conn); + jdbcRS.setType(ResultSet.TYPE_SCROLL_INSENSITIVE); + jdbcRS.setCommand(sql); + jdbcRS.execute(); + jdbcRS.addRowSetListener(new ExampleListener()); + + while (jdbcRS.next()) { + // each call to next, generates a cursorMoved event + System.out.println("id=" + jdbcRS.getString(1)); + System.out.println("name=" + jdbcRS.getString(2)); + } + + } + + // CachedRowSet Example + @Test + public void createCachedRowSet_DeleteRecord_ThenCorrect() throws Exception { + + CachedRowSet crs = new CachedRowSetImpl(); + crs.setUsername(username); + crs.setPassword(password); + crs.setUrl(url); + crs.setCommand(sql); + crs.execute(); + crs.addRowSetListener(new ExampleListener()); + while (crs.next()) { + if (crs.getInt("id") == 1) { + System.out.println("CRS found customer1 and will remove the record."); + crs.deleteRow(); + break; + } + } + } + + // WebRowSet example + @Test + public void createWebRowSet_SelectCustomers_WritetoXML_ThenCorrect() throws SQLException, IOException { + + WebRowSet wrs = new WebRowSetImpl(); + wrs.setUsername(username); + wrs.setPassword(password); + wrs.setUrl(url); + wrs.setCommand(sql); + wrs.execute(); + FileOutputStream ostream = new FileOutputStream("customers.xml"); + wrs.writeXml(ostream); + } + + // JoinRowSet example + @Test + public void createCachedRowSets_DoJoinRowSet_ThenCorrect() throws Exception { + + CachedRowSetImpl customers = new CachedRowSetImpl(); + customers.setUsername(username); + customers.setPassword(password); + customers.setUrl(url); + customers.setCommand(sql); + customers.execute(); + + CachedRowSetImpl associates = new CachedRowSetImpl(); + associates.setUsername(username); + associates.setPassword(password); + associates.setUrl(url); + String associatesSQL = "SELECT * FROM associates"; + associates.setCommand(associatesSQL); + associates.execute(); + + JoinRowSet jrs = new JoinRowSetImpl(); + final String ID = "id"; + final String NAME = "name"; + jrs.addRowSet(customers, ID); + jrs.addRowSet(associates, ID); + jrs.last(); + System.out.println("Total rows: " + jrs.getRow()); + jrs.beforeFirst(); + while (jrs.next()) { + + String string1 = jrs.getString(ID); + String string2 = jrs.getString(NAME); + System.out.println("ID: " + string1 + ", NAME: " + string2); + } + } + + // FilteredRowSet example + @Test + public void createFilteredRowSet_filterByRegexExpression_thenCorrect() throws Exception { + RowSetFactory rsf = RowSetProvider.newFactory(); + FilteredRowSet frs = rsf.createFilteredRowSet(); + frs.setCommand("select * from customers"); + Connection conn = DatabaseConfiguration.geth2Connection(); + frs.execute(conn); + frs.setFilter(new FilterExample("^[A-C].*")); + + ResultSetMetaData rsmd = frs.getMetaData(); + int columncount = rsmd.getColumnCount(); + while (frs.next()) { + for (int i = 1; i <= columncount; i++) { + System.out.println(rsmd.getColumnLabel(i) + " = " + frs.getObject(i) + " "); + } + } + } +} diff --git a/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java b/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java index 9590eabfef..f82f9ddaa7 100644 --- a/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java +++ b/core-java/src/test/java/com/baeldung/loops/WhenUsingLoops.java @@ -1,11 +1,38 @@ package com.baeldung.loops; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; public class WhenUsingLoops { private LoopsInJava loops = new LoopsInJava(); + private static List list = new ArrayList<>(); + private static Set set = new HashSet<>(); + private static Map map = new HashMap<>(); + + @BeforeClass + public static void setUp() { + list.add("One"); + list.add("Two"); + list.add("Three"); + + set.add("Four"); + set.add("Five"); + set.add("Six"); + + map.put("One", 1); + map.put("Two", 2); + map.put("Three", 3); + } @Test public void shouldRunForLoop() { @@ -34,4 +61,47 @@ public class WhenUsingLoops { int[] actual = loops.do_while_loop(); Assert.assertArrayEquals(expected, actual); } + + @Test + public void whenUsingSimpleFor_shouldIterateList() { + for (int i = 0; i < list.size(); i++) { + System.out.println(list.get(i)); + } + } + + @Test + public void whenUsingEnhancedFor_shouldIterateList() { + for (String item : list) { + System.out.println(item); + } + } + + @Test + public void whenUsingEnhancedFor_shouldIterateSet() { + for (String item : set) { + System.out.println(item); + } + } + + @Test + public void whenUsingEnhancedFor_shouldIterateMap() { + for (Entry entry : map.entrySet()) { + System.out.println("Key: " + entry.getKey() + " - " + "Value: " + entry.getValue()); + } + } + + @Test + public void whenUsingSimpleFor_shouldRunLabelledLoop() { + aa: for (int i = 1; i <= 3; i++) { + if (i == 1) + continue; + bb: for (int j = 1; j <= 3; j++) { + if (i == 2 && j == 2) { + break aa; + } + System.out.println(i + " " + j); + } + } + } + } diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ExtensionMethods.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ExtensionMethods.kt new file mode 100644 index 0000000000..09ce898860 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/ExtensionMethods.kt @@ -0,0 +1,51 @@ +package com.baeldung.kotlin + +import org.junit.Assert +import org.junit.Test + +class ExtensionMethods { + @Test + fun simpleExtensionMethod() { + fun String.escapeForXml() : String { + return this + .replace("&", "&") + .replace("<", "<") + .replace(">", ">") + } + + Assert.assertEquals("Nothing", "Nothing".escapeForXml()) + Assert.assertEquals("<Tag>", "".escapeForXml()) + Assert.assertEquals("a&b", "a&b".escapeForXml()) + } + + @Test + fun genericExtensionMethod() { + fun T.concatAsString(b: T) : String { + return this.toString() + b.toString() + } + + Assert.assertEquals("12", "1".concatAsString("2")) + Assert.assertEquals("12", 1.concatAsString(2)) + // This doesn't compile + // Assert.assertEquals("12", 1.concatAsString(2.0)) + } + + @Test + fun infixExtensionMethod() { + infix fun Number.toPowerOf(exponent: Number): Double { + return Math.pow(this.toDouble(), exponent.toDouble()) + } + + Assert.assertEquals(9.0, 3 toPowerOf 2, 0.1) + Assert.assertEquals(3.0, 9 toPowerOf 0.5, 0.1) + } + + @Test + fun operatorExtensionMethod() { + operator fun List.times(by: Int): List { + return this.map { it * by } + } + + Assert.assertEquals(listOf(2, 4, 6), listOf(1, 2, 3) * 2) + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java index 6d0aa0a4cd..a5c7b329fc 100644 --- a/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java +++ b/hibernate5/src/test/java/com/baeldung/hibernate/HibernateSpatialTest.java @@ -14,7 +14,9 @@ import org.junit.Test; import javax.persistence.Query; import java.io.IOException; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; + import static org.junit.Assert.assertTrue; public class HibernateSpatialTest { @@ -76,10 +78,8 @@ public class HibernateSpatialTest { Query query = session.createQuery("select p from PointEntity p where within(p.point, :area) = true", PointEntity.class); query.setParameter("area", wktToGeometry("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))")); - assertEquals(3, query.getResultList().size()); - assertEquals("POINT (1 1)", ((PointEntity) query.getResultList().get(0)).getPoint().toString()); - assertEquals("POINT (1 2)", ((PointEntity) query.getResultList().get(1)).getPoint().toString()); - assertEquals("POINT (3 4)", ((PointEntity) query.getResultList().get(2)).getPoint().toString()); + assertThat(query.getResultList().stream().map(p -> ((PointEntity) p).getPoint().toString())) + .containsOnly("POINT (1 1)", "POINT (1 2)", "POINT (3 4)"); } private void insertPoint(String point) throws ParseException { diff --git a/libraries/helloWorld.docx b/libraries/helloWorld.docx new file mode 100644 index 0000000000..09e71a4d4e Binary files /dev/null and b/libraries/helloWorld.docx differ diff --git a/logging-modules/logback/README.md b/logging-modules/logback/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/logging-modules/logback/pom.xml b/logging-modules/logback/pom.xml new file mode 100644 index 0000000000..8169134442 --- /dev/null +++ b/logging-modules/logback/pom.xml @@ -0,0 +1,35 @@ + + + + 4.0.0 + + logback + logback + 0.1-SNAPSHOT + + + UTF-8 + 1.2.3 + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + + + + ch.qos.logback + logback-classic + ${logback.version} + + + + + + diff --git a/logging-modules/logback/src/main/java/com/baeldung/logback/Example.java b/logging-modules/logback/src/main/java/com/baeldung/logback/Example.java new file mode 100644 index 0000000000..e3d09dc321 --- /dev/null +++ b/logging-modules/logback/src/main/java/com/baeldung/logback/Example.java @@ -0,0 +1,14 @@ +package com.baeldung.logback; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Example { + + private static final Logger logger = LoggerFactory.getLogger(Example.class); + + public static void main(String[] args) { + logger.info("Example log from {}", Example.class.getSimpleName()); + } + +} diff --git a/logging-modules/logback/src/main/java/com/baeldung/logback/MapAppender.java b/logging-modules/logback/src/main/java/com/baeldung/logback/MapAppender.java new file mode 100644 index 0000000000..99cc6488e5 --- /dev/null +++ b/logging-modules/logback/src/main/java/com/baeldung/logback/MapAppender.java @@ -0,0 +1,37 @@ +package com.baeldung.logback; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; + +import java.util.HashMap; +import java.util.Map; + +public class MapAppender extends AppenderBase { + + private final Map eventMap = new HashMap<>(); + + private String prefix; + + @Override + protected void append(final ILoggingEvent event) { + if (prefix == null || "".equals(prefix)) { + addError("Prefix is not set for MapAppender."); + return; + } + + eventMap.put(prefix + System.currentTimeMillis(), event); + } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(final String prefix) { + this.prefix = prefix; + } + + public Map getEventMap() { + return eventMap; + } + +} diff --git a/logging-modules/logback/src/main/resources/logback.xml b/logging-modules/logback/src/main/resources/logback.xml new file mode 100644 index 0000000000..37ae2adbb0 --- /dev/null +++ b/logging-modules/logback/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + test + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + \ No newline at end of file diff --git a/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderIntegrationTest.java b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderIntegrationTest.java new file mode 100644 index 0000000000..20366a229d --- /dev/null +++ b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderIntegrationTest.java @@ -0,0 +1,33 @@ +package com.baeldung.logback; + +import ch.qos.logback.classic.Logger; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.assertEquals; + +public class MapAppenderIntegrationTest { + + private Logger rootLogger; + + @Before + public void setUp() throws Exception { + rootLogger = (Logger) LoggerFactory.getLogger("ROOT"); + } + + @Test + public void whenLoggerEmitsLoggingEvent_thenAppenderReceivesEvent() throws Exception { + rootLogger.info("Test from {}", this.getClass().getSimpleName()); + MapAppender appender = (MapAppender) rootLogger.getAppender("map"); + assertEquals(appender.getEventMap().size(), 1); + } + + @Test + public void givenNoPrefixSet_whenLoggerEmitsEvent_thenAppenderReceivesNoEvent() throws Exception { + rootLogger.info("Test from {}", this.getClass().getSimpleName()); + MapAppender appender = (MapAppender) rootLogger.getAppender("badMap"); + assertEquals(appender.getEventMap().size(), 0); + } + +} diff --git a/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderTest.java b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderTest.java new file mode 100644 index 0000000000..a5a938a923 --- /dev/null +++ b/logging-modules/logback/src/test/java/com/baeldung/logback/MapAppenderTest.java @@ -0,0 +1,60 @@ +package com.baeldung.logback; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.core.BasicStatusManager; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class MapAppenderTest { + + private LoggerContext ctx; + + private MapAppender mapAppender = new MapAppender(); + + private LoggingEvent event; + + @Before + public void setUp() throws Exception { + ctx = new LoggerContext(); + ctx.setName("test context"); + ctx.setStatusManager(new BasicStatusManager()); + mapAppender.setContext(ctx); + mapAppender.setPrefix("prefix"); + event = new LoggingEvent("fqcn", ctx.getLogger("logger"), Level.INFO, "Test message for logback appender", null, new Object[0]); + ctx.start(); + } + + @After + public void tearDown() throws Exception { + ctx.stop(); + mapAppender.stop(); + } + + @Test + public void whenPrefixIsNull_thenMapAppenderDoesNotLog() throws Exception { + mapAppender.setPrefix(null); + mapAppender.append(event); + assertTrue(mapAppender.getEventMap().isEmpty()); + } + + @Test + public void whenPrefixIsEmpty_thenMapAppenderDoesNotLog() throws Exception { + mapAppender.setPrefix(""); + mapAppender.append(event); + assertTrue(mapAppender.getEventMap().isEmpty()); + } + + @Test + public void whenLogMessageIsEmitted_thenMapAppenderReceivesMessage() throws Exception { + mapAppender.append(event); + assertEquals(mapAppender.getEventMap().size(), 1); + mapAppender.getEventMap().forEach((k, v) -> assertTrue(k.startsWith("prefix"))); + } + +} diff --git a/logging-modules/logback/src/test/resources/logback-test.xml b/logging-modules/logback/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8254e6ac80 --- /dev/null +++ b/logging-modules/logback/src/test/resources/logback-test.xml @@ -0,0 +1,14 @@ + + + + test + + + + + + + + + + \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/pom.xml b/persistence-modules/spring-hibernate-5/pom.xml index 57eb1aeffb..23cf9a4d44 100644 --- a/persistence-modules/spring-hibernate-5/pom.xml +++ b/persistence-modules/spring-hibernate-5/pom.xml @@ -57,6 +57,11 @@ jta ${jta.version} + + org.hibernate + hibernate-search-orm + ${hibernatesearch.version} + org.apache.tomcat @@ -184,6 +189,7 @@ 5.2.10.Final + 5.8.2.Final 8.0.7-dmr 9.0.0.M26 1.1 diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java new file mode 100644 index 0000000000..6bbd2625fc --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/HibernateSearchConfig.java @@ -0,0 +1,76 @@ +package com.baeldung.hibernatesearch; + +import com.google.common.base.Preconditions; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; +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.JpaVendorAdapter; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; +import java.util.Properties; + +@EnableTransactionManagement +@Configuration +@PropertySource({ "classpath:persistence-h2.properties" }) +@EnableJpaRepositories(basePackages = { "com.baeldung.hibernatesearch" }) +@ComponentScan({ "com.baeldung.hibernatesearch" }) +public class HibernateSearchConfig { + + @Autowired + private Environment env; + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory() { + LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); + em.setDataSource(dataSource()); + em.setPackagesToScan(new String[] { "com.baeldung.hibernatesearch.model" }); + + JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); + em.setJpaVendorAdapter(vendorAdapter); + em.setJpaProperties(additionalProperties()); + + return em; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager transactionManager(EntityManagerFactory emf) { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(emf); + + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + Properties additionalProperties() { + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", Preconditions.checkNotNull(env.getProperty("hibernate.hbm2ddl.auto"))); + properties.setProperty("hibernate.dialect", Preconditions.checkNotNull(env.getProperty("hibernate.dialect"))); + return properties; + } +} \ No newline at end of file diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/ProductSearchDao.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/ProductSearchDao.java new file mode 100644 index 0000000000..210c1c58b3 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/ProductSearchDao.java @@ -0,0 +1,195 @@ +package com.baeldung.hibernatesearch; + +import com.baeldung.hibernatesearch.model.Product; +import org.apache.lucene.search.Query; +import org.hibernate.search.engine.ProjectionConstants; +import org.hibernate.search.jpa.FullTextEntityManager; +import org.hibernate.search.jpa.FullTextQuery; +import org.hibernate.search.jpa.Search; +import org.hibernate.search.query.dsl.QueryBuilder; +import org.springframework.stereotype.Repository; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.List; + +@Repository +public class ProductSearchDao { + + @PersistenceContext + private EntityManager entityManager; + + public List searchProductNameByKeywordQuery(String text) { + + Query keywordQuery = getQueryBuilder() + .keyword() + .onField("productName") + .matching(text) + .createQuery(); + + List results = getJpaQuery(keywordQuery).getResultList(); + + return results; + } + + public List searchProductNameByFuzzyQuery(String text) { + + Query fuzzyQuery = getQueryBuilder() + .keyword() + .fuzzy() + .withEditDistanceUpTo(2) + .withPrefixLength(0) + .onField("productName") + .matching(text) + .createQuery(); + + List results = getJpaQuery(fuzzyQuery).getResultList(); + + return results; + } + + public List searchProductNameByWildcardQuery(String text) { + + Query wildcardQuery = getQueryBuilder() + .keyword() + .wildcard() + .onField("productName") + .matching(text) + .createQuery(); + + List results = getJpaQuery(wildcardQuery).getResultList(); + + return results; + } + + public List searchProductDescriptionByPhraseQuery(String text) { + + Query phraseQuery = getQueryBuilder() + .phrase() + .withSlop(1) + .onField("description") + .sentence(text) + .createQuery(); + + List results = getJpaQuery(phraseQuery).getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionBySimpleQueryStringQuery(String text) { + + Query simpleQueryStringQuery = getQueryBuilder() + .simpleQueryString() + .onFields("productName", "description") + .matching(text) + .createQuery(); + + List results = getJpaQuery(simpleQueryStringQuery).getResultList(); + + return results; + } + + public List searchProductNameByRangeQuery(int low, int high) { + + Query rangeQuery = getQueryBuilder() + .range() + .onField("memory") + .from(low) + .to(high) + .createQuery(); + + List results = getJpaQuery(rangeQuery).getResultList(); + + return results; + } + + public List searchProductNameByMoreLikeThisQuery(Product entity) { + + Query moreLikeThisQuery = getQueryBuilder() + .moreLikeThis() + .comparingField("productName") + .toEntity(entity) + .createQuery(); + + List results = getJpaQuery(moreLikeThisQuery).setProjection(ProjectionConstants.THIS, ProjectionConstants.SCORE) + .getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionByKeywordQuery(String text) { + + Query keywordQuery = getQueryBuilder() + .keyword() + .onFields("productName", "description") + .matching(text) + .createQuery(); + + List results = getJpaQuery(keywordQuery).getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionByMoreLikeThisQuery(Product entity) { + + Query moreLikeThisQuery = getQueryBuilder() + .moreLikeThis() + .comparingField("productName") + .toEntity(entity) + .createQuery(); + + List results = getJpaQuery(moreLikeThisQuery).setProjection(ProjectionConstants.THIS, ProjectionConstants.SCORE) + .getResultList(); + + return results; + } + + public List searchProductNameAndDescriptionByCombinedQuery(String manufactorer, int memoryLow, int memoryTop, String extraFeature, String exclude) { + + Query combinedQuery = getQueryBuilder() + .bool() + .must(getQueryBuilder().keyword() + .onField("productName") + .matching(manufactorer) + .createQuery()) + .must(getQueryBuilder() + .range() + .onField("memory") + .from(memoryLow) + .to(memoryTop) + .createQuery()) + .should(getQueryBuilder() + .phrase() + .onField("description") + .sentence(extraFeature) + .createQuery()) + .must(getQueryBuilder() + .keyword() + .onField("productName") + .matching(exclude) + .createQuery()) + .not() + .createQuery(); + + List results = getJpaQuery(combinedQuery).getResultList(); + + return results; + } + + private FullTextQuery getJpaQuery(org.apache.lucene.search.Query luceneQuery) { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + + return fullTextEntityManager.createFullTextQuery(luceneQuery, Product.class); + } + + private QueryBuilder getQueryBuilder() { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + + return fullTextEntityManager.getSearchFactory() + .buildQueryBuilder() + .forEntity(Product.class) + .get(); + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/model/Product.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/model/Product.java new file mode 100644 index 0000000000..3ca020fe57 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/hibernatesearch/model/Product.java @@ -0,0 +1,94 @@ +package com.baeldung.hibernatesearch.model; + +import org.hibernate.search.annotations.*; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Indexed +@Table(name = "product") +public class Product { + + @Id + private int id; + + @Field(termVector = TermVector.YES) + private String productName; + + @Field(termVector = TermVector.YES) + private String description; + + @Field + private int memory; + + public Product(int id, String productName, int memory, String description) { + this.id = id; + this.productName = productName; + this.memory = memory; + this.description = description; + } + + public Product() { + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof Product)) + return false; + + Product product = (Product) o; + + if (id != product.id) + return false; + if (memory != product.memory) + return false; + if (!productName.equals(product.productName)) + return false; + return description.equals(product.description); + } + + @Override + public int hashCode() { + int result = id; + result = 31 * result + productName.hashCode(); + result = 31 * result + memory; + result = 31 * result + description.hashCode(); + return result; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public int getMemory() { + return memory; + } + + public void setMemory(int memory) { + this.memory = memory; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java index 74ac0a269e..e64f0a4efe 100644 --- a/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java +++ b/persistence-modules/spring-hibernate-5/src/main/java/com/baeldung/spring/PersistenceConfig.java @@ -21,7 +21,7 @@ import java.util.Properties; @Configuration @EnableTransactionManagement -@PropertySource({ "classpath:persistence-h2.properties" }) +@PropertySource({ "classpath:persistence-mysql.properties" }) @ComponentScan({ "com.baeldung.persistence" }) public class PersistenceConfig { diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml b/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml index 8a10fc1580..3c753a89af 100644 --- a/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml +++ b/persistence-modules/spring-hibernate-5/src/main/resources/manytomany.cfg.xml @@ -4,24 +4,12 @@ "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd"> - - com.mysql.jdbc.Driver - - - buddhinisam123 - - - jdbc:mysql://localhost:3306/spring_hibernate_many_to_many - - - root - - - org.hibernate.dialect.MySQLDialect - - - thread - + com.mysql.jdbc.Driver + tutorialmy5ql + jdbc:mysql://localhost:3306/spring_hibernate_many_to_many + tutorialuser + org.hibernate.dialect.MySQLDialect + thread true diff --git a/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties index 696e805cff..915bc4317b 100644 --- a/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties +++ b/persistence-modules/spring-hibernate-5/src/main/resources/persistence-h2.properties @@ -9,5 +9,9 @@ hibernate.dialect=org.hibernate.dialect.H2Dialect hibernate.show_sql=false hibernate.hbm2ddl.auto=create-drop +# hibernate.search.X +hibernate.search.default.directory_provider = filesystem +hibernate.search.default.indexBase = /data/index/default + # envers.X envers.audit_table_suffix=_audit_log diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java index d6ecdb29d6..1572f23ed1 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/immutable/HibernateImmutableIntegrationTest.java @@ -4,7 +4,6 @@ import com.baeldung.hibernate.immutable.entities.Event; import com.baeldung.hibernate.immutable.entities.EventGeneratedId; import com.baeldung.hibernate.immutable.util.HibernateUtil; import com.google.common.collect.Sets; -import org.hibernate.CacheMode; import org.hibernate.Session; import org.junit.*; import org.junit.rules.ExpectedException; @@ -14,6 +13,9 @@ import javax.persistence.PersistenceException; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsEqual.equalTo; +/** + * Configured in: immutable.cfg.xml + */ public class HibernateImmutableIntegrationTest { private static Session session; @@ -98,6 +100,7 @@ public class HibernateImmutableIntegrationTest { public void updateEventGenerated() { createEventGenerated(); EventGeneratedId eventGeneratedId = (EventGeneratedId) session.createQuery("FROM EventGeneratedId WHERE name LIKE '%John%'").list().get(0); + eventGeneratedId.setName("Mike"); session.update(eventGeneratedId); session.flush(); @@ -115,7 +118,6 @@ public class HibernateImmutableIntegrationTest { private static void createEventGenerated() { EventGeneratedId eventGeneratedId = new EventGeneratedId("John", "Doe"); - eventGeneratedId.setId(4L); session.save(eventGeneratedId); } diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java index 9a536a0f80..0073e181cc 100644 --- a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernate/manytomany/HibernateManyToManyAnnotationMainIntegrationTest.java @@ -17,6 +17,9 @@ import com.baeldung.hibernate.manytomany.util.HibernateUtil; import com.baeldung.hibernate.manytomany.model.Employee; import com.baeldung.hibernate.manytomany.model.Project; +/** + * Configured in: manytomany.cfg.xml + */ public class HibernateManyToManyAnnotationMainIntegrationTest { private static SessionFactory sessionFactory; diff --git a/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernatesearch/HibernateSearchIntegrationTest.java b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernatesearch/HibernateSearchIntegrationTest.java new file mode 100644 index 0000000000..b69f8d3a60 --- /dev/null +++ b/persistence-modules/spring-hibernate-5/src/test/java/com/baeldung/hibernatesearch/HibernateSearchIntegrationTest.java @@ -0,0 +1,187 @@ +package com.baeldung.hibernatesearch; + +import com.baeldung.hibernatesearch.model.Product; + +import static org.hamcrest.collection.IsIterableContainingInOrder.contains; +import static org.junit.Assert.*; + +import org.hibernate.search.jpa.FullTextEntityManager; +import org.hibernate.search.jpa.Search; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Commit; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { HibernateSearchConfig.class }, loader = AnnotationConfigContextLoader.class) +@Transactional +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class HibernateSearchIntegrationTest { + + @Autowired + ProductSearchDao dao; + + @PersistenceContext + private EntityManager entityManager; + + private List products; + + @Before + public void setupTestData() { + + products = Arrays.asList(new Product(1, "Apple iPhone X 256 GB", 256, "The current high-end smartphone from Apple, with lots of memory and also Face ID"), + new Product(2, "Apple iPhone X 128 GB", 128, "The current high-end smartphone from Apple, with Face ID"), new Product(3, "Apple iPhone 8 128 GB", 128, "The latest smartphone from Apple within the regular iPhone line, supporting wireless charging"), + new Product(4, "Samsung Galaxy S7 128 GB", 64, "A great Android smartphone"), new Product(5, "Microsoft Lumia 650 32 GB", 32, "A cheaper smartphone, coming with Windows Mobile"), + new Product(6, "Microsoft Lumia 640 32 GB", 32, "A cheaper smartphone, coming with Windows Mobile"), new Product(7, "Microsoft Lumia 630 16 GB", 16, "A cheaper smartphone, coming with Windows Mobile")); + } + + @Commit + @Test + public void testA_whenInitialTestDataInserted_thenSuccess() { + + for (int i = 0; i < products.size() - 1; i++) { + entityManager.persist(products.get(i)); + } + } + + @Test + public void testB_whenIndexInitialized_thenCorrectIndexSize() throws InterruptedException { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + fullTextEntityManager.createIndexer() + .startAndWait(); + int indexSize = fullTextEntityManager.getSearchFactory() + .getStatistics() + .getNumberOfIndexedEntities(Product.class.getName()); + + assertEquals(products.size() - 1, indexSize); + } + + @Commit + @Test + public void testC_whenAdditionalTestDataInserted_thenSuccess() { + + entityManager.persist(products.get(products.size() - 1)); + } + + @Test + public void testD_whenAdditionalTestDataInserted_thenIndexUpdatedAutomatically() { + + FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); + int indexSize = fullTextEntityManager.getSearchFactory() + .getStatistics() + .getNumberOfIndexedEntities(Product.class.getName()); + + assertEquals(products.size(), indexSize); + } + + @Test + public void testE_whenKeywordSearchOnName_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2)); + List results = dao.searchProductNameByKeywordQuery("iphone"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } + + @Test + public void testF_whenFuzzySearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2)); + List results = dao.searchProductNameByFuzzyQuery("iPhaen"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } + + @Test + public void testG_whenWildcardSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(4), products.get(5), products.get(6)); + List results = dao.searchProductNameByWildcardQuery("6*"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testH_whenPhraseSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(2)); + List results = dao.searchProductDescriptionByPhraseQuery("with wireless charging"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testI_whenSimpleQueryStringSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1)); + List results = dao.searchProductNameAndDescriptionBySimpleQueryStringQuery("Aple~2 + \"iPhone X\" + (256 | 128)"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testJ_whenRangeSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2), products.get(3)); + List results = dao.searchProductNameByRangeQuery(64, 256); + + assertThat(results, containsInAnyOrder(expected.toArray())); + + } + + @Test + public void testK_whenMoreLikeThisSearch_thenCorrectMatchesInOrder() { + List expected = products; + List resultsWithScore = dao.searchProductNameByMoreLikeThisQuery(products.get(0)); + List results = new LinkedList(); + + for (Object[] resultWithScore : resultsWithScore) { + results.add((Product) resultWithScore[0]); + } + + assertThat(results, contains(expected.toArray())); + + } + + @Test + public void testL_whenKeywordSearchOnNameAndDescription_thenCorrectMatches() { + List expected = Arrays.asList(products.get(0), products.get(1), products.get(2)); + List results = dao.searchProductNameAndDescriptionByKeywordQuery("iphone"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } + + @Test + public void testM_whenMoreLikeThisSearchOnProductNameAndDescription_thenCorrectMatchesInOrder() { + List expected = products; + List resultsWithScore = dao.searchProductNameAndDescriptionByMoreLikeThisQuery(products.get(0)); + List results = new LinkedList(); + + for (Object[] resultWithScore : resultsWithScore) { + results.add((Product) resultWithScore[0]); + } + + assertThat(results, contains(expected.toArray())); + } + + @Test + public void testN_whenCombinedSearch_thenCorrectMatches() { + List expected = Arrays.asList(products.get(1), products.get(2)); + List results = dao.searchProductNameAndDescriptionByCombinedQuery("apple", 64, 128, "face id", "samsung"); + + assertThat(results, containsInAnyOrder(expected.toArray())); + } +} diff --git a/pom.xml b/pom.xml index cac0cc5845..c8fa30e8c9 100644 --- a/pom.xml +++ b/pom.xml @@ -107,6 +107,7 @@ logging-modules/log-mdc logging-modules/log4j logging-modules/log4j2 + logging-modules/logback lombok mapstruct diff --git a/spring-5/README.md b/spring-5/README.md index 15e12cb5dc..1b65d01811 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -10,4 +10,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Exploring the Spring 5 MVC URL Matching Improvements](http://www.baeldung.com/spring-5-mvc-url-matching) - [Spring 5 WebClient](http://www.baeldung.com/spring-5-webclient) - [Spring 5 Functional Bean Registration](http://www.baeldung.com/spring-5-functional-beans) - +- [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](http://www.baeldung.com/spring-5-junit-config) diff --git a/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/BDDMockitoTest.java b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/BDDMockitoTest.java new file mode 100644 index 0000000000..9cc586fb84 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/BDDMockitoTest.java @@ -0,0 +1,104 @@ +package org.baeldung.bddmockito; + +import static org.junit.Assert.fail; +import static org.mockito.BDDMockito.*; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; + + +public class BDDMockitoTest { + + PhoneBookService phoneBookService; + PhoneBookRepository phoneBookRepository; + + String momContactName = "Mom"; + String momPhoneNumber = "01234"; + String xContactName = "x"; + String tooLongPhoneNumber = "01111111111111"; + + @Before + public void init() { + phoneBookRepository = Mockito.mock(PhoneBookRepository.class); + phoneBookService = new PhoneBookService(phoneBookRepository); + } + + @Test + public void givenValidContactName_whenSearchInPhoneBook_thenRetunPhoneNumber() { + given(phoneBookRepository.contains(momContactName)).willReturn(true); + given(phoneBookRepository.getPhoneNumberByContactName(momContactName)) + .will((InvocationOnMock invocation) -> { + if(invocation.getArgument(0).equals(momContactName)) { + return momPhoneNumber; + } else { + return null; + } + }); + + String phoneNumber = phoneBookService.search(momContactName); + + then(phoneBookRepository).should().contains(momContactName); + then(phoneBookRepository).should().getPhoneNumberByContactName(momContactName); + Assert.assertEquals(phoneNumber, momPhoneNumber); + } + + @Test + public void givenInvalidContactName_whenSearch_thenRetunNull() { + given(phoneBookRepository.contains(xContactName)).willReturn(false); + + String phoneNumber = phoneBookService.search(xContactName); + + then(phoneBookRepository).should().contains(xContactName); + then(phoneBookRepository).should(never()).getPhoneNumberByContactName(xContactName); + Assert.assertEquals(phoneNumber, null); + } + + @Test + public void givenValidContactNameAndPhoneNumber_whenRegister_thenSucceed() { + given(phoneBookRepository.contains(momContactName)).willReturn(false); + + phoneBookService.register(momContactName, momPhoneNumber); + + verify(phoneBookRepository).insert(momContactName, momPhoneNumber); + } + + @Test + public void givenEmptyPhoneNumber_whenRegister_thenFail() { + given(phoneBookRepository.contains(momContactName)).willReturn(false); + + phoneBookService.register(xContactName, ""); + + then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber); + } + + @Test + public void givenLongPhoneNumber_whenRegister_thenFail() { + given(phoneBookRepository.contains(xContactName)).willReturn(false); + willThrow(new RuntimeException()) + .given(phoneBookRepository).insert(any(String.class), eq(tooLongPhoneNumber)); + + try { + phoneBookService.register(xContactName, tooLongPhoneNumber); + fail("Should throw exception"); + } catch (RuntimeException ex) { } + + then(phoneBookRepository).should(never()).insert(momContactName, tooLongPhoneNumber); + } + + @Test + public void givenExistentContactName_whenRegister_thenFail() { + given(phoneBookRepository.contains(momContactName)) + .willThrow(new RuntimeException("Name already exist")); + + try { + phoneBookService.register(momContactName, momPhoneNumber); + fail("Should throw exception"); + } catch(Exception ex) { } + + then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber); + } + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookRepository.java b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookRepository.java new file mode 100644 index 0000000000..b73a1d835c --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookRepository.java @@ -0,0 +1,26 @@ +package org.baeldung.bddmockito; + +public interface PhoneBookRepository { + + /** + * Insert phone record + * @param name Contact name + * @param phone Phone number + */ + void insert(String name, String phone); + + /** + * Search for contact phone number + * @param name Contact name + * @return phone number + */ + String getPhoneNumberByContactName(String name); + + /** + * Check if the phonebook contains this contact + * @param name Contact name + * @return true if this contact name exists + */ + boolean contains(String name); + +} diff --git a/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookService.java b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookService.java new file mode 100644 index 0000000000..645884af02 --- /dev/null +++ b/testing-modules/mockito/src/test/java/org/baeldung/bddmockito/PhoneBookService.java @@ -0,0 +1,34 @@ +package org.baeldung.bddmockito; + +public class PhoneBookService { + + private PhoneBookRepository phoneBookRepository; + + public PhoneBookService(PhoneBookRepository phoneBookRepository) { + this.phoneBookRepository = phoneBookRepository; + } + + /** + * Register a contact + * @param name Contact name + * @param phone Phone number + */ + public void register(String name, String phone) { + if(!name.isEmpty() && !phone.isEmpty() && !phoneBookRepository.contains(name)) { + phoneBookRepository.insert(name, phone); + } + } + + /** + * Search for a phone number by contact name + * @param name Contact name + * @return Phone number + */ + public String search(String name) { + if(!name.isEmpty() && phoneBookRepository.contains(name)) { + return phoneBookRepository.getPhoneNumberByContactName(name); + } + return null; + } + +} diff --git a/xml/src/test/resources/example_dom4j_new.xml b/xml/src/test/resources/example_dom4j_new.xml new file mode 100644 index 0000000000..020760fdd3 --- /dev/null +++ b/xml/src/test/resources/example_dom4j_new.xml @@ -0,0 +1,10 @@ + + + + + XML with Dom4J + XML handling with Dom4J + 14/06/2016 + Dom4J tech writer + + diff --git a/xml/src/test/resources/example_jaxb_new.xml b/xml/src/test/resources/example_jaxb_new.xml new file mode 100644 index 0000000000..646d938869 --- /dev/null +++ b/xml/src/test/resources/example_jaxb_new.xml @@ -0,0 +1,9 @@ + + + + Jaxb author + 04/02/2015 + XML Binding with Jaxb + XML with Jaxb + +