Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
2b886c78fe
@ -1,22 +1,15 @@
|
|||||||
package com.baeldung.algorithms.editdistance;
|
package com.baeldung.algorithms.editdistance;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class EditDistanceBase {
|
public class EditDistanceBase {
|
||||||
|
|
||||||
public static int costOfSubstitution(char a, char b) {
|
static int costOfSubstitution(char a, char b) {
|
||||||
if (a == b) {
|
return a == b ? 0 : 1;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int min(int... numbers) {
|
static int min(int... numbers) {
|
||||||
int min = Integer.MAX_VALUE;
|
return Arrays.stream(numbers)
|
||||||
|
.min().orElse(Integer.MAX_VALUE);
|
||||||
for (int x : numbers) {
|
|
||||||
if (x < min)
|
|
||||||
min = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
return min;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package com.baeldung.algorithms.editdistance;
|
|||||||
|
|
||||||
public class EditDistanceDynamicProgramming extends EditDistanceBase {
|
public class EditDistanceDynamicProgramming extends EditDistanceBase {
|
||||||
|
|
||||||
public static int calculate(String x, String y) {
|
static int calculate(String x, String y) {
|
||||||
int[][] dp = new int[x.length() + 1][y.length() + 1];
|
int[][] dp = new int[x.length() + 1][y.length() + 1];
|
||||||
|
|
||||||
for (int i = 0; i <= x.length(); i++) {
|
for (int i = 0; i <= x.length(); i++) {
|
||||||
@ -14,12 +14,13 @@ public class EditDistanceDynamicProgramming extends EditDistanceBase {
|
|||||||
dp[i][j] = i;
|
dp[i][j] = i;
|
||||||
|
|
||||||
else {
|
else {
|
||||||
dp[i][j] = min(dp[i - 1][j - 1] + costOfSubstitution(x.charAt(i - 1), y.charAt(j - 1)), dp[i - 1][j] + 1, dp[i][j - 1] + 1);
|
dp[i][j] = min(dp[i - 1][j - 1]
|
||||||
|
+ costOfSubstitution(x.charAt(i - 1), y.charAt(j - 1)),
|
||||||
|
dp[i - 1][j] + 1, dp[i][j - 1] + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return dp[x.length()][y.length()];
|
return dp[x.length()][y.length()];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,15 @@ package com.baeldung.algorithms.editdistance;
|
|||||||
|
|
||||||
public class EditDistanceRecursive extends EditDistanceBase {
|
public class EditDistanceRecursive extends EditDistanceBase {
|
||||||
|
|
||||||
public static int calculate(String x, String y) {
|
static int calculate(String x, String y) {
|
||||||
|
|
||||||
if (x.isEmpty())
|
if (x.isEmpty()) {
|
||||||
return y.length();
|
return y.length();
|
||||||
|
}
|
||||||
|
|
||||||
if (y.isEmpty())
|
if (y.isEmpty()) {
|
||||||
return x.length();
|
return x.length();
|
||||||
|
}
|
||||||
|
|
||||||
int substitution = calculate(x.substring(1), y.substring(1)) + costOfSubstitution(x.charAt(0), y.charAt(0));
|
int substitution = calculate(x.substring(1), y.substring(1)) + costOfSubstitution(x.charAt(0), y.charAt(0));
|
||||||
int insertion = calculate(x, y.substring(1)) + 1;
|
int insertion = calculate(x, y.substring(1)) + 1;
|
||||||
@ -16,5 +18,4 @@ public class EditDistanceRecursive extends EditDistanceBase {
|
|||||||
|
|
||||||
return min(substitution, insertion, deletion);
|
return min(substitution, insertion, deletion);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
package com.baeldung.algorithms.editdistance;
|
package com.baeldung.algorithms.editdistance;
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class EditDistanceTest extends EditDistanceDataProvider {
|
public class EditDistanceTest extends EditDistanceDataProvider {
|
||||||
|
|
||||||
String x;
|
private String x;
|
||||||
String y;
|
private String y;
|
||||||
int result;
|
private int result;
|
||||||
|
|
||||||
public EditDistanceTest(String a, String b, int res) {
|
public EditDistanceTest(String a, String b, int res) {
|
||||||
super();
|
super();
|
||||||
@ -21,11 +22,11 @@ public class EditDistanceTest extends EditDistanceDataProvider {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEditDistance_RecursiveImplementation() {
|
public void testEditDistance_RecursiveImplementation() {
|
||||||
Assert.assertEquals(result, EditDistanceRecursive.calculate(x, y));
|
assertEquals(result, EditDistanceRecursive.calculate(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEditDistance_givenDynamicProgrammingImplementation() {
|
public void testEditDistance_givenDynamicProgrammingImplementation() {
|
||||||
Assert.assertEquals(result, EditDistanceDynamicProgramming.calculate(x, y));
|
assertEquals(result, EditDistanceDynamicProgramming.calculate(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,37 +17,24 @@ import scala.Tuple2;
|
|||||||
public class WordCount {
|
public class WordCount {
|
||||||
|
|
||||||
private static final Pattern SPACE = Pattern.compile(" ");
|
private static final Pattern SPACE = Pattern.compile(" ");
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
System.err.println("Usage: JavaWordCount <file>");
|
System.err.println("Usage: JavaWordCount <file>");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
|
}
|
||||||
|
SparkConf sparkConf = new SparkConf().setAppName("JavaWordCount")
|
||||||
|
.setMaster("local");
|
||||||
|
JavaSparkContext ctx = new JavaSparkContext(sparkConf);
|
||||||
|
JavaRDD<String> lines = ctx.textFile(args[0], 1);
|
||||||
|
|
||||||
|
JavaRDD<String> words = lines.flatMap(s -> Arrays.asList(SPACE.split(s)).iterator());
|
||||||
|
JavaPairRDD<String, Integer> wordAsTuple = words.mapToPair(word -> new Tuple2<>(word, 1));
|
||||||
|
JavaPairRDD<String, Integer> wordWithCount = wordAsTuple.reduceByKey((Integer i1, Integer i2)->i1 + i2);
|
||||||
|
List<Tuple2<String, Integer>> output = wordWithCount.collect();
|
||||||
|
for (Tuple2<?, ?> tuple : output) {
|
||||||
|
System.out.println(tuple._1() + ": " + tuple._2());
|
||||||
|
}
|
||||||
|
ctx.stop();
|
||||||
}
|
}
|
||||||
SparkConf sparkConf = new SparkConf().setAppName("JavaWordCount").setMaster("local");
|
|
||||||
JavaSparkContext ctx = new JavaSparkContext(sparkConf);
|
|
||||||
JavaRDD<String> lines = ctx.textFile(args[0], 1);
|
|
||||||
|
|
||||||
JavaRDD<String> words = lines.flatMap(s -> Arrays.asList(SPACE.split(s)).iterator());
|
|
||||||
JavaPairRDD<String, Integer> ones = words.mapToPair(
|
|
||||||
new PairFunction<String, String, Integer>() {
|
|
||||||
@Override
|
|
||||||
public Tuple2<String, Integer> call(String s) {
|
|
||||||
return new Tuple2<>(s, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
JavaPairRDD<String, Integer> counts = ones.reduceByKey(
|
|
||||||
new Function2<Integer, Integer, Integer>() {
|
|
||||||
@Override
|
|
||||||
public Integer call(Integer i1, Integer i2) {
|
|
||||||
return i1 + i2;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<Tuple2<String, Integer>> output = counts.collect();
|
|
||||||
for (Tuple2<?, ?> tuple : output) {
|
|
||||||
System.out.println(tuple._1() + ": " + tuple._2());
|
|
||||||
}
|
|
||||||
ctx.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
## Relevant articles:
|
|
27
cas/cas-secured-app/.gitignore
vendored
Normal file
27
cas/cas-secured-app/.gitignore
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
nbproject/private/
|
||||||
|
build/
|
||||||
|
nbbuild/
|
||||||
|
dist/
|
||||||
|
nbdist/
|
||||||
|
.nb-gradle/
|
||||||
|
/.mvn/
|
||||||
|
/mvnw
|
||||||
|
/mvnw.cmd
|
0
cas-server/mvnw → cas/cas-server/mvnw
vendored
0
cas-server/mvnw → cas/cas-server/mvnw
vendored
@ -0,0 +1,20 @@
|
|||||||
|
package com.baeldung.concurrent.daemon;
|
||||||
|
|
||||||
|
public class NewThread extends Thread {
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
while (true) {
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
System.out.println("New Thread is running..." + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent the Thread to run forever. It will finish it's execution after 2 seconds
|
||||||
|
if (System.currentTimeMillis() - startTime > 2000) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.baeldung.concurrent.daemon;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class DaemonThreadTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void whenCallIsDaemon_thenCorrect() {
|
||||||
|
NewThread daemonThread = new NewThread();
|
||||||
|
NewThread userThread = new NewThread();
|
||||||
|
daemonThread.setDaemon(true);
|
||||||
|
daemonThread.start();
|
||||||
|
userThread.start();
|
||||||
|
|
||||||
|
assertTrue(daemonThread.isDaemon());
|
||||||
|
assertFalse(userThread.isDaemon());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalThreadStateException.class)
|
||||||
|
@Ignore
|
||||||
|
public void givenUserThread_whenSetDaemonWhileRunning_thenIllegalThreadStateException() {
|
||||||
|
NewThread daemonThread = new NewThread();
|
||||||
|
daemonThread.start();
|
||||||
|
daemonThread.setDaemon(true);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
package com.baeldung.concurrent.runnable;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class RunnableVsThreadTest {
|
||||||
|
|
||||||
|
private static Logger log =
|
||||||
|
LoggerFactory.getLogger(RunnableVsThreadTest.class);
|
||||||
|
|
||||||
|
private static ExecutorService executorService;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
executorService = Executors.newCachedThreadPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenARunnable_whenRunIt_thenResult() throws Exception{
|
||||||
|
Thread thread = new Thread(new SimpleRunnable(
|
||||||
|
"SimpleRunnable executed using Thread"));
|
||||||
|
thread.start();
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenARunnable_whenSubmitToES_thenResult() throws Exception{
|
||||||
|
|
||||||
|
executorService.submit(new SimpleRunnable(
|
||||||
|
"SimpleRunnable executed using ExecutorService")).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenARunnableLambda_whenSubmitToES_thenResult()
|
||||||
|
throws Exception{
|
||||||
|
|
||||||
|
executorService.submit(()->
|
||||||
|
log.info("Lambda runnable executed!!!")).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAThread_whenRunIt_thenResult() throws Exception{
|
||||||
|
Thread thread = new SimpleThread(
|
||||||
|
"SimpleThread executed using Thread");
|
||||||
|
thread.start();
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenAThread_whenSubmitToES_thenResult() throws Exception{
|
||||||
|
|
||||||
|
executorService.submit(new SimpleThread(
|
||||||
|
"SimpleThread executed using ExecutorService")).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenACallable_whenSubmitToES_thenResult() throws Exception {
|
||||||
|
|
||||||
|
Future<Integer> future = executorService.submit(
|
||||||
|
new SimpleCallable());
|
||||||
|
log.info("Result from callable: {}", future.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenACallableAsLambda_whenSubmitToES_thenResult()
|
||||||
|
throws Exception {
|
||||||
|
|
||||||
|
Future<Integer> future = executorService.submit(() -> {
|
||||||
|
return RandomUtils.nextInt(0, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
log.info("Result from callable: {}", future.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDown() {
|
||||||
|
if ( executorService != null && !executorService.isShutdown()) {
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SimpleThread extends Thread{
|
||||||
|
|
||||||
|
private static final Logger log =
|
||||||
|
LoggerFactory.getLogger(SimpleThread.class);
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public SimpleThread(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
log.info(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SimpleRunnable implements Runnable {
|
||||||
|
|
||||||
|
private static final Logger log =
|
||||||
|
LoggerFactory.getLogger(SimpleRunnable.class);
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public SimpleRunnable(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
log.info(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SimpleCallable implements Callable<Integer> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer call() throws Exception {
|
||||||
|
return RandomUtils.nextInt(0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,73 +2,77 @@ package com.baeldung.array;
|
|||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
|
|
||||||
public class ArrayInitializer {
|
public class ArrayInitializer {
|
||||||
|
|
||||||
public static int[] initializeArrayInLoop() {
|
static int[] initializeArrayInLoop() {
|
||||||
int array[] = new int[5];
|
int array[] = new int[5];
|
||||||
for (int i = 0; i < array.length; i++)
|
for (int i = 0; i < array.length; i++) {
|
||||||
array[i] = i + 2;
|
array[i] = i + 2;
|
||||||
|
}
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[][] initializeMultiDimensionalArrayInLoop() {
|
static int[][] initializeMultiDimensionalArrayInLoop() {
|
||||||
int array[][] = new int[2][5];
|
int array[][] = new int[2][5];
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++) {
|
||||||
for (int j = 0; j < 5; j++)
|
for (int j = 0; j < 5; j++) {
|
||||||
array[i][j] = j + 1;
|
array[i][j] = j + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] initializeArrayAtTimeOfDeclarationMethod1() {
|
static String[] initializeArrayAtTimeOfDeclarationMethod1() {
|
||||||
String array[] = new String[] { "Toyota", "Mercedes", "BMW", "Volkswagen", "Skoda" };
|
String array[] = new String[] { "Toyota", "Mercedes", "BMW", "Volkswagen", "Skoda" };
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] initializeArrayAtTimeOfDeclarationMethod2() {
|
static int[] initializeArrayAtTimeOfDeclarationMethod2() {
|
||||||
int[] array = new int[] { 1, 2, 3, 4, 5 };
|
int[] array = new int[] { 1, 2, 3, 4, 5 };
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] initializeArrayAtTimeOfDeclarationMethod3() {
|
static int[] initializeArrayAtTimeOfDeclarationMethod3() {
|
||||||
int array[] = { 1, 2, 3, 4, 5 };
|
int array[] = { 1, 2, 3, 4, 5 };
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long[] initializeArrayUsingArraysFill() {
|
static long[] initializeArrayUsingArraysFill() {
|
||||||
long array[] = new long[5];
|
long array[] = new long[5];
|
||||||
Arrays.fill(array, 30);
|
Arrays.fill(array, 30);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] initializeArrayRangeUsingArraysFill() {
|
static int[] initializeArrayRangeUsingArraysFill() {
|
||||||
int array[] = new int[5];
|
int array[] = new int[5];
|
||||||
Arrays.fill(array, 0, 3, -50);
|
Arrays.fill(array, 0, 3, -50);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] initializeArrayUsingArraysCopy() {
|
static int[] initializeArrayUsingArraysCopy() {
|
||||||
int array[] = { 1, 2, 3, 4, 5 };
|
int array[] = { 1, 2, 3, 4, 5 };
|
||||||
int[] copy = Arrays.copyOf(array, 5);
|
int[] copy = Arrays.copyOf(array, 5);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] initializeLargerArrayUsingArraysCopy() {
|
static int[] initializeLargerArrayUsingArraysCopy() {
|
||||||
int array[] = { 1, 2, 3, 4, 5 };
|
int array[] = { 1, 2, 3, 4, 5 };
|
||||||
int[] copy = Arrays.copyOf(array, 6);
|
int[] copy = Arrays.copyOf(array, 6);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int[] initializeArrayUsingArraysSetAll() {
|
static int[] initializeArrayUsingArraysSetAll() {
|
||||||
int[] array = new int[20];
|
int[] array = new int[20];
|
||||||
|
|
||||||
for (int i = 0; i < 20; i++) {
|
Arrays.setAll(array, p -> p > 9 ? 0 : p);
|
||||||
Arrays.setAll(array, p -> {
|
|
||||||
if (p > 9)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return p;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char[] initializeArrayUsingArraysUtilClone() {
|
||||||
|
char[] array = new char[] { 'a', 'b', 'c' };
|
||||||
|
return ArrayUtils.clone(array);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class EchoServer {
|
public class EchoServer {
|
||||||
|
|
||||||
|
private static final String POISON_PILL = "POISON_PILL";
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
Selector selector = Selector.open();
|
Selector selector = Selector.open();
|
||||||
ServerSocketChannel serverSocket = ServerSocketChannel.open();
|
ServerSocketChannel serverSocket = ServerSocketChannel.open();
|
||||||
@ -30,23 +32,36 @@ public class EchoServer {
|
|||||||
SelectionKey key = iter.next();
|
SelectionKey key = iter.next();
|
||||||
|
|
||||||
if (key.isAcceptable()) {
|
if (key.isAcceptable()) {
|
||||||
SocketChannel client = serverSocket.accept();
|
register(selector, serverSocket);
|
||||||
client.configureBlocking(false);
|
|
||||||
client.register(selector, SelectionKey.OP_READ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.isReadable()) {
|
if (key.isReadable()) {
|
||||||
SocketChannel client = (SocketChannel) key.channel();
|
answerWithEcho(buffer, key);
|
||||||
client.read(buffer);
|
|
||||||
buffer.flip();
|
|
||||||
client.write(buffer);
|
|
||||||
buffer.clear();
|
|
||||||
}
|
}
|
||||||
iter.remove();
|
iter.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void answerWithEcho(ByteBuffer buffer, SelectionKey key) throws IOException {
|
||||||
|
SocketChannel client = (SocketChannel) key.channel();
|
||||||
|
client.read(buffer);
|
||||||
|
if (new String(buffer.array()).trim().equals(POISON_PILL)) {
|
||||||
|
client.close();
|
||||||
|
System.out.println("Not accepting client messages anymore");
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.flip();
|
||||||
|
client.write(buffer);
|
||||||
|
buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void register(Selector selector, ServerSocketChannel serverSocket) throws IOException {
|
||||||
|
SocketChannel client = serverSocket.accept();
|
||||||
|
client.configureBlocking(false);
|
||||||
|
client.register(selector, SelectionKey.OP_READ);
|
||||||
|
}
|
||||||
|
|
||||||
public static Process start() throws IOException, InterruptedException {
|
public static Process start() throws IOException, InterruptedException {
|
||||||
String javaHome = System.getProperty("java.home");
|
String javaHome = System.getProperty("java.home");
|
||||||
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
|
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
|
||||||
|
@ -8,6 +8,7 @@ import static com.baeldung.array.ArrayInitializer.initializeArrayRangeUsingArray
|
|||||||
import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysCopy;
|
import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysCopy;
|
||||||
import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysFill;
|
import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysFill;
|
||||||
import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysSetAll;
|
import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysSetAll;
|
||||||
|
import static com.baeldung.array.ArrayInitializer.initializeArrayUsingArraysUtilClone;
|
||||||
import static com.baeldung.array.ArrayInitializer.initializeLargerArrayUsingArraysCopy;
|
import static com.baeldung.array.ArrayInitializer.initializeLargerArrayUsingArraysCopy;
|
||||||
import static com.baeldung.array.ArrayInitializer.initializeMultiDimensionalArrayInLoop;
|
import static com.baeldung.array.ArrayInitializer.initializeMultiDimensionalArrayInLoop;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
@ -65,4 +66,9 @@ public class ArrayInitializerTest {
|
|||||||
public void whenInitializeLargerArrayRangeUsingArraysSetAll_thenCorrect() {
|
public void whenInitializeLargerArrayRangeUsingArraysSetAll_thenCorrect() {
|
||||||
assertArrayEquals(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, initializeArrayUsingArraysSetAll());
|
assertArrayEquals(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, initializeArrayUsingArraysSetAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenInitializeArrayUsingArraysUtilClone_thenCorrect() {
|
||||||
|
assertArrayEquals(new char[] { 'a', 'b', 'c' }, initializeArrayUsingArraysUtilClone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import static org.junit.Assert.assertEquals;
|
|||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.IllegalFormatException;
|
import java.util.IllegalFormatException;
|
||||||
import java.util.regex.PatternSyntaxException;
|
import java.util.regex.PatternSyntaxException;
|
||||||
@ -29,11 +30,17 @@ public class StringTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenGetBytes_thenCorrect() {
|
public void whenGetBytes_thenCorrect() throws UnsupportedEncodingException {
|
||||||
byte[] byteArray = "abcd".getBytes();
|
byte[] byteArray1 = "abcd".getBytes();
|
||||||
byte[] expected = new byte[] { 97, 98, 99, 100 };
|
byte[] byteArray2 = "efgh".getBytes(StandardCharsets.US_ASCII);
|
||||||
|
byte[] byteArray3 = "ijkl".getBytes("UTF-8");
|
||||||
|
byte[] expected1 = new byte[] { 97, 98, 99, 100 };
|
||||||
|
byte[] expected2 = new byte[] { 101, 102, 103, 104 };
|
||||||
|
byte[] expected3 = new byte[] { 105, 106, 107, 108 };
|
||||||
|
|
||||||
assertArrayEquals(expected, byteArray);
|
assertArrayEquals(expected1, byteArray1);
|
||||||
|
assertArrayEquals(expected2, byteArray2);
|
||||||
|
assertArrayEquals(expected3, byteArray3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -123,6 +130,7 @@ public class StringTest {
|
|||||||
@Test
|
@Test
|
||||||
public void whenCallLastIndexOf_thenCorrect() {
|
public void whenCallLastIndexOf_thenCorrect() {
|
||||||
assertEquals(2, "foo".lastIndexOf("o"));
|
assertEquals(2, "foo".lastIndexOf("o"));
|
||||||
|
assertEquals(2, "foo".lastIndexOf(111));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.baeldung.datetime
|
||||||
|
|
||||||
|
import java.time.Duration
|
||||||
|
import java.time.LocalTime
|
||||||
|
|
||||||
|
class UseDuration {
|
||||||
|
|
||||||
|
fun modifyDates(localTime: LocalTime, duration: Duration): LocalTime {
|
||||||
|
return localTime.plus(duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDifferenceBetweenDates(localTime1: LocalTime, localTime2: LocalTime): Duration {
|
||||||
|
return Duration.between(localTime1, localTime2)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.baeldung.datetime
|
||||||
|
|
||||||
|
import java.time.DayOfWeek
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.temporal.ChronoUnit
|
||||||
|
import java.time.temporal.TemporalAdjusters
|
||||||
|
|
||||||
|
class UseLocalDate {
|
||||||
|
|
||||||
|
fun getLocalDateUsingFactoryOfMethod(year: Int, month: Int, dayOfMonth: Int): LocalDate {
|
||||||
|
return LocalDate.of(year, month, dayOfMonth)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLocalDateUsingParseMethod(representation: String): LocalDate {
|
||||||
|
return LocalDate.parse(representation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLocalDateFromClock(): LocalDate {
|
||||||
|
return LocalDate.now()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getNextDay(localDate: LocalDate): LocalDate {
|
||||||
|
return localDate.plusDays(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPreviousDay(localDate: LocalDate): LocalDate {
|
||||||
|
return localDate.minus(1, ChronoUnit.DAYS)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDayOfWeek(localDate: LocalDate): DayOfWeek {
|
||||||
|
return localDate.dayOfWeek
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFirstDayOfMonth(): LocalDate {
|
||||||
|
return LocalDate.now().with(TemporalAdjusters.firstDayOfMonth())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getStartOfDay(localDate: LocalDate): LocalDateTime {
|
||||||
|
return localDate.atStartOfDay()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.datetime
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
class UseLocalDateTime {
|
||||||
|
|
||||||
|
fun getLocalDateTimeUsingParseMethod(representation: String): LocalDateTime {
|
||||||
|
return LocalDateTime.parse(representation)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.baeldung.datetime
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.LocalTime
|
||||||
|
import java.time.temporal.ChronoUnit
|
||||||
|
|
||||||
|
class UseLocalTime {
|
||||||
|
|
||||||
|
fun getLocalTimeUsingFactoryOfMethod(hour: Int, min: Int, seconds: Int): LocalTime {
|
||||||
|
return LocalTime.of(hour, min, seconds)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLocalTimeUsingParseMethod(timeRepresentation: String): LocalTime {
|
||||||
|
return LocalTime.parse(timeRepresentation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLocalTimeFromClock(): LocalTime {
|
||||||
|
return LocalTime.now()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAnHour(localTime: LocalTime): LocalTime {
|
||||||
|
return localTime.plus(1, ChronoUnit.HOURS)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getHourFromLocalTime(localTime: LocalTime): Int {
|
||||||
|
return localTime.hour
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLocalTimeWithMinuteSetToValue(localTime: LocalTime, minute: Int): LocalTime {
|
||||||
|
return localTime.withMinute(minute)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.baeldung.datetime
|
||||||
|
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.Period
|
||||||
|
|
||||||
|
class UsePeriod {
|
||||||
|
|
||||||
|
fun modifyDates(localDate: LocalDate, period: Period): LocalDate {
|
||||||
|
return localDate.plus(period)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDifferenceBetweenDates(localDate1: LocalDate, localDate2: LocalDate): Period {
|
||||||
|
return Period.between(localDate1, localDate2)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.baeldung.datetime
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.ZoneId
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
|
class UseZonedDateTime {
|
||||||
|
|
||||||
|
fun getZonedDateTime(localDateTime: LocalDateTime, zoneId: ZoneId): ZonedDateTime {
|
||||||
|
return ZonedDateTime.of(localDateTime, zoneId)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.baeldung.kotlin.datetime
|
||||||
|
|
||||||
|
import com.baeldung.datetime.UseLocalDateTime
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalTime
|
||||||
|
import java.time.Month
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
|
||||||
|
class UseLocalDateTimeUnitTest {
|
||||||
|
|
||||||
|
var useLocalDateTime = UseLocalDateTime()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenString_whenUsingParse_thenLocalDateTime() {
|
||||||
|
assertEquals(LocalDate.of(2016, Month.MAY, 10), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30")
|
||||||
|
.toLocalDate())
|
||||||
|
assertEquals(LocalTime.of(6, 30), useLocalDateTime.getLocalDateTimeUsingParseMethod("2016-05-10T06:30")
|
||||||
|
.toLocalTime())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package com.baeldung.kotlin.datetime
|
||||||
|
|
||||||
|
import com.baeldung.datetime.UseLocalDate
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Test
|
||||||
|
import java.time.DayOfWeek
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
class UseLocalDateUnitTest {
|
||||||
|
|
||||||
|
var useLocalDate = UseLocalDate()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenValues_whenUsingFactoryOf_thenLocalDate() {
|
||||||
|
Assert.assertEquals("2016-05-10", useLocalDate.getLocalDateUsingFactoryOfMethod(2016, 5, 10)
|
||||||
|
.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenString_whenUsingParse_thenLocalDate() {
|
||||||
|
Assert.assertEquals("2016-05-10", useLocalDate.getLocalDateUsingParseMethod("2016-05-10")
|
||||||
|
.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun whenUsingClock_thenLocalDate() {
|
||||||
|
Assert.assertEquals(LocalDate.now(), useLocalDate.getLocalDateFromClock())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenDate_whenUsingPlus_thenNextDay() {
|
||||||
|
Assert.assertEquals(LocalDate.now()
|
||||||
|
.plusDays(1), useLocalDate.getNextDay(LocalDate.now()))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenDate_whenUsingMinus_thenPreviousDay() {
|
||||||
|
Assert.assertEquals(LocalDate.now()
|
||||||
|
.minusDays(1), useLocalDate.getPreviousDay(LocalDate.now()))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenToday_whenUsingGetDayOfWeek_thenDayOfWeek() {
|
||||||
|
Assert.assertEquals(DayOfWeek.SUNDAY, useLocalDate.getDayOfWeek(LocalDate.parse("2016-05-22")))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenToday_whenUsingWithTemporalAdjuster_thenFirstDayOfMonth() {
|
||||||
|
Assert.assertEquals(1, useLocalDate.getFirstDayOfMonth()
|
||||||
|
.dayOfMonth.toLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenLocalDate_whenUsingAtStartOfDay_thenReturnMidnight() {
|
||||||
|
Assert.assertEquals(LocalDateTime.parse("2016-05-22T00:00:00"), useLocalDate.getStartOfDay(LocalDate.parse("2016-05-22")))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.baeldung.kotlin.datetime
|
||||||
|
|
||||||
|
import com.baeldung.datetime.UseLocalTime
|
||||||
|
import java.time.LocalTime
|
||||||
|
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class UseLocalTimeUnitTest {
|
||||||
|
|
||||||
|
internal var useLocalTime = UseLocalTime()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenValues_whenUsingFactoryOf_thenLocalTime() {
|
||||||
|
Assert.assertEquals("07:07:07", useLocalTime.getLocalTimeUsingFactoryOfMethod(7, 7, 7).toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenString_whenUsingParse_thenLocalTime() {
|
||||||
|
Assert.assertEquals("06:30", useLocalTime.getLocalTimeUsingParseMethod("06:30").toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenTime_whenAddHour_thenLocalTime() {
|
||||||
|
Assert.assertEquals("07:30", useLocalTime.addAnHour(LocalTime.of(6, 30)).toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getHourFromLocalTime() {
|
||||||
|
Assert.assertEquals(1, useLocalTime.getHourFromLocalTime(LocalTime.of(1, 1)).toLong())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getLocalTimeWithMinuteSetToValue() {
|
||||||
|
Assert.assertEquals(LocalTime.of(10, 20), useLocalTime.getLocalTimeWithMinuteSetToValue(LocalTime.of(10, 10), 20))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.baeldung.kotlin.datetime
|
||||||
|
|
||||||
|
import com.baeldung.datetime.UsePeriod
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.Period
|
||||||
|
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class UsePeriodUnitTest {
|
||||||
|
|
||||||
|
var usingPeriod = UsePeriod()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenPeriodAndLocalDate_thenCalculateModifiedDate() {
|
||||||
|
val period = Period.ofDays(1)
|
||||||
|
val localDate = LocalDate.parse("2007-05-10")
|
||||||
|
Assert.assertEquals(localDate.plusDays(1), usingPeriod.modifyDates(localDate, period))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenDates_thenGetPeriod() {
|
||||||
|
val localDate1 = LocalDate.parse("2007-05-10")
|
||||||
|
val localDate2 = LocalDate.parse("2007-05-15")
|
||||||
|
|
||||||
|
Assert.assertEquals(Period.ofDays(5), usingPeriod.getDifferenceBetweenDates(localDate1, localDate2))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.baeldung.kotlin.datetime
|
||||||
|
|
||||||
|
import com.baeldung.datetime.UseZonedDateTime
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Test
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.time.ZoneId
|
||||||
|
|
||||||
|
class UseZonedDateTimeUnitTest {
|
||||||
|
|
||||||
|
internal var zonedDateTime = UseZonedDateTime()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun givenZoneId_thenZonedDateTime() {
|
||||||
|
val zoneId = ZoneId.of("Europe/Paris")
|
||||||
|
val zonedDatetime = zonedDateTime.getZonedDateTime(LocalDateTime.parse("2016-05-20T06:30"), zoneId)
|
||||||
|
Assert.assertEquals(zoneId, ZoneId.from(zonedDatetime))
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,12 @@ class CalculatorTest5 {
|
|||||||
private val calculator = Calculator()
|
private val calculator = Calculator()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testAddition() {
|
fun whenAdding1and3_thenAnswerIs4() {
|
||||||
Assertions.assertEquals(4, calculator.add(1, 3))
|
Assertions.assertEquals(4, calculator.add(1, 3))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDivideByZero() {
|
fun whenDividingBy0_thenErrorOccurs() {
|
||||||
val exception = Assertions.assertThrows(DivideByZeroException::class.java) {
|
val exception = Assertions.assertThrows(DivideByZeroException::class.java) {
|
||||||
calculator.divide(5, 0)
|
calculator.divide(5, 0)
|
||||||
}
|
}
|
||||||
@ -21,7 +21,7 @@ class CalculatorTest5 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSquares() {
|
fun whenSquaringNumbers_thenCorrectAnswerGiven() {
|
||||||
Assertions.assertAll(
|
Assertions.assertAll(
|
||||||
Executable { Assertions.assertEquals(1, calculator.square(1)) },
|
Executable { Assertions.assertEquals(1, calculator.square(1)) },
|
||||||
Executable { Assertions.assertEquals(4, calculator.square(2)) },
|
Executable { Assertions.assertEquals(4, calculator.square(2)) },
|
||||||
@ -31,9 +31,9 @@ class CalculatorTest5 {
|
|||||||
|
|
||||||
@TestFactory
|
@TestFactory
|
||||||
fun testSquaresFactory() = listOf(
|
fun testSquaresFactory() = listOf(
|
||||||
DynamicTest.dynamicTest("1 squared") { Assertions.assertEquals(1,calculator.square(1))},
|
DynamicTest.dynamicTest("when I calculate 1^2 then I get 1") { Assertions.assertEquals(1,calculator.square(1))},
|
||||||
DynamicTest.dynamicTest("2 squared") { Assertions.assertEquals(4,calculator.square(2))},
|
DynamicTest.dynamicTest("when I calculate 2^2 then I get 4") { Assertions.assertEquals(4,calculator.square(2))},
|
||||||
DynamicTest.dynamicTest("3 squared") { Assertions.assertEquals(9,calculator.square(3))}
|
DynamicTest.dynamicTest("when I calculate 3^2 then I get 9") { Assertions.assertEquals(9,calculator.square(3))}
|
||||||
)
|
)
|
||||||
|
|
||||||
@TestFactory
|
@TestFactory
|
||||||
@ -44,7 +44,7 @@ class CalculatorTest5 {
|
|||||||
4 to 16,
|
4 to 16,
|
||||||
5 to 25)
|
5 to 25)
|
||||||
.map { (input, expected) ->
|
.map { (input, expected) ->
|
||||||
DynamicTest.dynamicTest("$input squared") {
|
DynamicTest.dynamicTest("when I calculate $input^2 then I get $expected") {
|
||||||
Assertions.assertEquals(expected, calculator.square(input))
|
Assertions.assertEquals(expected, calculator.square(input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,14 +59,14 @@ class CalculatorTest5 {
|
|||||||
@TestFactory
|
@TestFactory
|
||||||
fun testSquaresFactory3() = squaresTestData
|
fun testSquaresFactory3() = squaresTestData
|
||||||
.map { (input, expected) ->
|
.map { (input, expected) ->
|
||||||
DynamicTest.dynamicTest("$input squared") {
|
DynamicTest.dynamicTest("when I calculate $input^2 then I get $expected") {
|
||||||
Assertions.assertEquals(expected, calculator.square(input))
|
Assertions.assertEquals(expected, calculator.square(input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@TestFactory
|
@TestFactory
|
||||||
fun testSquareRootsFactory3() = squaresTestData
|
fun testSquareRootsFactory3() = squaresTestData
|
||||||
.map { (expected, input) ->
|
.map { (expected, input) ->
|
||||||
DynamicTest.dynamicTest("Square root of $input") {
|
DynamicTest.dynamicTest("I calculate the square root of $input then I get $expected") {
|
||||||
Assertions.assertEquals(expected.toDouble(), calculator.squareRoot(input))
|
Assertions.assertEquals(expected.toDouble(), calculator.squareRoot(input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ class CalculatorTest5 {
|
|||||||
Tag("logarithms")
|
Tag("logarithms")
|
||||||
)
|
)
|
||||||
@Test
|
@Test
|
||||||
fun testLogarithms() {
|
fun whenIcalculateLog2Of8_thenIget3() {
|
||||||
Assertions.assertEquals(3.0, calculator.log(2, 8))
|
Assertions.assertEquals(3.0, calculator.log(2, 8))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,14 @@ import org.junit.jupiter.api.Test
|
|||||||
|
|
||||||
class SimpleTest5 {
|
class SimpleTest5 {
|
||||||
@Test
|
@Test
|
||||||
fun testEmpty() {
|
fun whenEmptyList_thenListIsEmpty() {
|
||||||
val list = listOf<String>()
|
val list = listOf<String>()
|
||||||
Assertions.assertTrue(list::isEmpty)
|
Assertions.assertTrue(list::isEmpty)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled
|
@Disabled
|
||||||
fun testMessage() {
|
fun when3equals4_thenTestFails() {
|
||||||
Assertions.assertEquals(3, 4) {
|
Assertions.assertEquals(3, 4) {
|
||||||
"Three does not equal four"
|
"Three does not equal four"
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.baeldung.drools;
|
||||||
|
|
||||||
|
import org.kie.api.KieServices;
|
||||||
|
import org.kie.api.runtime.KieContainer;
|
||||||
|
import org.kie.api.runtime.KieSession;
|
||||||
|
|
||||||
|
import com.baeldung.drools.model.Fact;
|
||||||
|
import com.baeldung.drools.model.Result;
|
||||||
|
|
||||||
|
public class BackwardChaining {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Result result = new BackwardChaining().backwardChaining();
|
||||||
|
System.out.println(result.getValue());
|
||||||
|
result.getFacts().stream().forEach(System.out::println);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result backwardChaining() {
|
||||||
|
Result result = new Result();
|
||||||
|
KieServices ks = KieServices.Factory.get();
|
||||||
|
KieContainer kContainer = ks.getKieClasspathContainer();
|
||||||
|
KieSession ksession = kContainer.newKieSession("ksession-backward-chaining");
|
||||||
|
ksession.setGlobal("result", result);
|
||||||
|
ksession.insert(new Fact("Asia", "Planet Earth"));
|
||||||
|
// ksession.insert(new Fact("China", "Asia"));
|
||||||
|
ksession.insert(new Fact("Great Wall of China", "China"));
|
||||||
|
|
||||||
|
ksession.fireAllRules();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package com.baeldung.drools.model;
|
||||||
|
|
||||||
|
import org.kie.api.definition.type.Position;
|
||||||
|
|
||||||
|
public class Fact {
|
||||||
|
|
||||||
|
@Position(0)
|
||||||
|
private String element;
|
||||||
|
|
||||||
|
@Position(1)
|
||||||
|
private String place;
|
||||||
|
|
||||||
|
public Fact(String element, String place) {
|
||||||
|
this.element = element;
|
||||||
|
this.place = place;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getElement() {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElement(String element) {
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlace() {
|
||||||
|
return place;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlace(String place) {
|
||||||
|
this.place = place;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((element == null) ? 0 : element.hashCode());
|
||||||
|
result = prime * result + ((place == null) ? 0 : place.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;
|
||||||
|
Fact other = (Fact) obj;
|
||||||
|
if (element == null) {
|
||||||
|
if (other.element != null)
|
||||||
|
return false;
|
||||||
|
} else if (!element.equals(other.element))
|
||||||
|
return false;
|
||||||
|
if (place == null) {
|
||||||
|
if (other.place != null)
|
||||||
|
return false;
|
||||||
|
} else if (!place.equals(other.place))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Fact{" + "element='" + element + '\'' + ", place='" + place + '\'' + '}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.baeldung.drools.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Result {
|
||||||
|
private String value;
|
||||||
|
private List<String> facts = new ArrayList<>();
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getFacts() {
|
||||||
|
return facts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFacts(List<String> facts) {
|
||||||
|
this.facts = facts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFact(String fact) {
|
||||||
|
this.facts.add(fact);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
groupId=com.baeldung.drools
|
||||||
|
artifactId=DroosBackwardChaining
|
||||||
|
version=1.0.0-SNAPSHOT
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.baeldung
|
||||||
|
|
||||||
|
import com.baeldung.drools.model.Fact;
|
||||||
|
|
||||||
|
global com.baeldung.drools.model.Result result;
|
||||||
|
|
||||||
|
dialect "mvel"
|
||||||
|
|
||||||
|
query belongsTo(String x, String y)
|
||||||
|
Fact(x, y;)
|
||||||
|
or
|
||||||
|
(Fact(z, y;) and belongsTo(x, z;))
|
||||||
|
end
|
||||||
|
|
||||||
|
rule "Great Wall of China BELONGS TO Planet Earth"
|
||||||
|
when
|
||||||
|
belongsTo("Great Wall of China", "Planet Earth";)
|
||||||
|
then
|
||||||
|
result.setValue("Decision one taken: Great Wall of China BELONGS TO Planet Earth");
|
||||||
|
end
|
||||||
|
|
||||||
|
rule "Great Wall of China DOES NOT BELONG TO of Planet Earth"
|
||||||
|
when
|
||||||
|
not belongsTo("Great Wall of China", "Planet Earth";)
|
||||||
|
then
|
||||||
|
result.setValue("Decision two taken: Great Wall of China DOES NOT BELONG TO Planet Earth");
|
||||||
|
end
|
||||||
|
|
||||||
|
rule "print all facts"
|
||||||
|
when
|
||||||
|
belongsTo(element, place;)
|
||||||
|
then
|
||||||
|
result.addFact(element + " IS ELEMENT OF " + place);
|
||||||
|
end
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.baeldung.test;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.JUnit4;
|
||||||
|
import org.kie.api.KieServices;
|
||||||
|
import org.kie.api.runtime.KieContainer;
|
||||||
|
import org.kie.api.runtime.KieSession;
|
||||||
|
|
||||||
|
import com.baeldung.drools.model.Fact;
|
||||||
|
import com.baeldung.drools.model.Result;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
|
||||||
|
@RunWith(value = JUnit4.class)
|
||||||
|
public class BackwardChainingTest {
|
||||||
|
private Result result;
|
||||||
|
private KieServices ks;
|
||||||
|
private KieContainer kContainer;
|
||||||
|
private KieSession ksession;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
result = new Result();
|
||||||
|
ks = KieServices.Factory.get();
|
||||||
|
kContainer = ks.getKieClasspathContainer();
|
||||||
|
ksession = kContainer.newKieSession("ksession-backward-chaining");
|
||||||
|
ksession.setGlobal("result", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenWallOfChinaIsGiven_ThenItBelongsToPlanetEarth() {
|
||||||
|
|
||||||
|
ksession.setGlobal("result", result);
|
||||||
|
ksession.insert(new Fact("Asia", "Planet Earth"));
|
||||||
|
ksession.insert(new Fact("China", "Asia"));
|
||||||
|
ksession.insert(new Fact("Great Wall of China", "China"));
|
||||||
|
|
||||||
|
ksession.fireAllRules();
|
||||||
|
|
||||||
|
// Assert Decision one
|
||||||
|
assertEquals(result.getValue(), "Decision one taken: Great Wall of China BELONGS TO Planet Earth");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenChinaIsNotGiven_ThenWallOfChinaDoesNotBelongToPlanetEarth() {
|
||||||
|
ksession.insert(new Fact("Asia", "Planet Earth"));
|
||||||
|
// ksession.insert(new Location("China", "Asia")); // not provided to force Decision two
|
||||||
|
ksession.insert(new Fact("Great Wall of China", "China"));
|
||||||
|
|
||||||
|
ksession.fireAllRules();
|
||||||
|
|
||||||
|
// Assert Decision two
|
||||||
|
assertEquals(result.getValue(), "Decision two taken: Great Wall of China DOES NOT BELONG TO Planet Earth");
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.ejb.EJB;
|
import javax.ejb.EJB;
|
||||||
@ -15,19 +16,32 @@ import wildfly.beans.UserBeanLocal;
|
|||||||
* Servlet implementation class TestEJBServlet
|
* Servlet implementation class TestEJBServlet
|
||||||
*/
|
*/
|
||||||
public class TestEJBServlet extends HttpServlet {
|
public class TestEJBServlet extends HttpServlet {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@EJB
|
@EJB
|
||||||
private UserBeanLocal userBean;
|
private UserBeanLocal userBean;
|
||||||
|
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
||||||
List<User> users = userBean.getUsers();
|
throws ServletException, IOException {
|
||||||
|
List<User> users = userBean.getUsers();
|
||||||
|
|
||||||
response.getWriter()
|
PrintWriter out = response.getWriter();
|
||||||
.append("The number of users is: " + users.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
out.println("<html>");
|
||||||
doGet(request, response);
|
out.println("<head><title>Users</title></head>");
|
||||||
}
|
out.println("<body>");
|
||||||
|
out.println("<center><h1>List of users:</h1>");
|
||||||
|
out.println("<table border=\"1\" align=\"center\" style=\"width:50%\">");
|
||||||
|
for (User user : users) {
|
||||||
|
out.println("<tr>");
|
||||||
|
out.print("<td>" + user.getUsername() + "</td>");
|
||||||
|
out.print("<td>" + user.getEmail() + "</td>");
|
||||||
|
out.println("</tr>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
doGet(request, response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,13 @@
|
|||||||
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
|
||||||
<persistence-unit name="wildfly-jpa" transaction-type="JTA">
|
<persistence-unit name="wildfly-jpa" transaction-type="JTA">
|
||||||
<jta-data-source>java:/PostgresDS</jta-data-source>
|
<jta-data-source>java:/H2DS</jta-data-source>
|
||||||
<class>model.User</class>
|
<class>model.User</class>
|
||||||
|
<properties>
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
|
||||||
|
<property name="hibernate.show_sql" value="true" />
|
||||||
|
<property name="hibernate.hbm2ddl.auto" value="create" />
|
||||||
|
<property name="hibernate.hbm2ddl.import_files" value="data.sql" />
|
||||||
|
</properties>
|
||||||
</persistence-unit>
|
</persistence-unit>
|
||||||
</persistence>
|
</persistence>
|
||||||
|
1
ejb/wildfly/wildfly-jpa/src/main/resources/data.sql
Normal file
1
ejb/wildfly/wildfly-jpa/src/main/resources/data.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
INSERT INTO users (username, email, postal_number) VALUES ('user1', 'user1@baeldung.com', 1000), ('user2', 'user2@baeldung.com', 2);
|
17
guest/spring-mvc/README.md
Normal file
17
guest/spring-mvc/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
## Building
|
||||||
|
|
||||||
|
To build the module, use Maven's `package` goal:
|
||||||
|
|
||||||
|
```
|
||||||
|
mvn clean package
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
To run the application, use Spring Boot's `run` goal:
|
||||||
|
|
||||||
|
```
|
||||||
|
mvn spring-boot:run
|
||||||
|
```
|
||||||
|
|
||||||
|
The application will be accessible at [http://localhost:8080/](http://localhost:8080/)
|
@ -3,7 +3,7 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.forketyfork.guest</groupId>
|
<groupId>com.stackify.guest</groupId>
|
||||||
<artifactId>spring-mvc</artifactId>
|
<artifactId>spring-mvc</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package com.forketyfork.guest.springmvc;
|
package com.stackify.guest.springmvc;
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@ComponentScan(basePackages = {"com.forketyfork.guest.springmvc"})
|
@ComponentScan(basePackages = {"com.stackify.guest.springmvc"})
|
||||||
public class Spring5Application {
|
public class Spring5Application {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
@ -1,4 +1,4 @@
|
|||||||
package com.forketyfork.guest.springmvc.model;
|
package com.stackify.guest.springmvc.model;
|
||||||
|
|
||||||
public class LoginData {
|
public class LoginData {
|
||||||
|
|
@ -1,11 +1,14 @@
|
|||||||
package com.forketyfork.guest.springmvc.web;
|
package com.stackify.guest.springmvc.web;
|
||||||
|
|
||||||
import com.forketyfork.guest.springmvc.model.LoginData;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import com.stackify.guest.springmvc.model.LoginData;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@ -28,4 +31,10 @@ public class InternalsController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResponseBody
|
||||||
|
@PostMapping("/message")
|
||||||
|
public MyOutputResource sendMessage(@RequestBody MyInputResource inputResource) {
|
||||||
|
return new MyOutputResource("Received: " + inputResource.getRequestMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.stackify.guest.springmvc.web;
|
||||||
|
|
||||||
|
public class MyInputResource {
|
||||||
|
|
||||||
|
private String requestMessage;
|
||||||
|
|
||||||
|
public String getRequestMessage() {
|
||||||
|
return requestMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestMessage(String requestMessage) {
|
||||||
|
this.requestMessage = requestMessage;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.stackify.guest.springmvc.web;
|
||||||
|
|
||||||
|
public class MyOutputResource {
|
||||||
|
|
||||||
|
private String responseMessage;
|
||||||
|
|
||||||
|
public MyOutputResource(String responseMessage) {
|
||||||
|
this.responseMessage = responseMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResponseMessage() {
|
||||||
|
return responseMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.stackify.guest.springmvc.web;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class RestfulWebServiceController {
|
||||||
|
|
||||||
|
@GetMapping("/message")
|
||||||
|
public MyOutputResource getMessage() {
|
||||||
|
return new MyOutputResource("Hello!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1 +1,3 @@
|
|||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
|
||||||
|
- [Dynamic Mapping with Hibernate](http://www.baeldung.com/hibernate-dynamic-mapping)
|
||||||
|
@ -22,13 +22,19 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.hibernate</groupId>
|
||||||
<artifactId>hibernate-core</artifactId>
|
<artifactId>hibernate-core</artifactId>
|
||||||
<version>5.2.9.Final</version>
|
<version>5.2.12.Final</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.12</version>
|
<version>4.12</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.8.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
|
@ -68,7 +68,7 @@ public class HibernateMultiTenantUtil {
|
|||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
URL propertiesURL = Thread.currentThread()
|
URL propertiesURL = Thread.currentThread()
|
||||||
.getContextClassLoader()
|
.getContextClassLoader()
|
||||||
.getResource("hibernate.properties");
|
.getResource("hibernate-multitenancy.properties");
|
||||||
FileInputStream inputStream = new FileInputStream(propertiesURL.getFile());
|
FileInputStream inputStream = new FileInputStream(propertiesURL.getFile());
|
||||||
properties.load(inputStream);
|
properties.load(inputStream);
|
||||||
System.out.println("LOADED PROPERTIES FROM hibernate.properties");
|
System.out.println("LOADED PROPERTIES FROM hibernate.properties");
|
||||||
|
@ -1,24 +1,60 @@
|
|||||||
package com.baeldung.hibernate;
|
package com.baeldung.hibernate;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.pojo.Employee;
|
||||||
|
import com.baeldung.hibernate.pojo.EntityDescription;
|
||||||
|
import com.baeldung.hibernate.pojo.Phone;
|
||||||
|
import com.baeldung.hibernate.pojo.TemporalValues;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.boot.Metadata;
|
||||||
|
import org.hibernate.boot.MetadataSources;
|
||||||
|
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
|
||||||
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
public class HibernateUtil {
|
public class HibernateUtil {
|
||||||
|
private static SessionFactory sessionFactory;
|
||||||
|
|
||||||
private static final SessionFactory sessionFactory;
|
public static SessionFactory getSessionFactory() throws IOException {
|
||||||
|
if (sessionFactory == null) {
|
||||||
static {
|
ServiceRegistry serviceRegistry = configureServiceRegistry();
|
||||||
try {
|
sessionFactory = makeSessionFactory(serviceRegistry);
|
||||||
Configuration configuration = new Configuration().configure();
|
|
||||||
sessionFactory = configuration.buildSessionFactory();
|
|
||||||
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
System.err.println("Initial SessionFactory creation failed." + ex);
|
|
||||||
throw new ExceptionInInitializerError(ex);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static SessionFactory getSessionFactory() {
|
|
||||||
return sessionFactory;
|
return sessionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static SessionFactory makeSessionFactory(ServiceRegistry serviceRegistry) {
|
||||||
|
MetadataSources metadataSources = new MetadataSources(serviceRegistry);
|
||||||
|
metadataSources.addPackage("com.baeldung.hibernate.pojo");
|
||||||
|
metadataSources.addAnnotatedClass(Employee.class);
|
||||||
|
metadataSources.addAnnotatedClass(Phone.class);
|
||||||
|
metadataSources.addAnnotatedClass(EntityDescription.class);
|
||||||
|
metadataSources.addAnnotatedClass(TemporalValues.class);
|
||||||
|
|
||||||
|
Metadata metadata = metadataSources.buildMetadata();
|
||||||
|
return metadata.getSessionFactoryBuilder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ServiceRegistry configureServiceRegistry() throws IOException {
|
||||||
|
Properties properties = getProperties();
|
||||||
|
return new StandardServiceRegistryBuilder().applySettings(properties)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Properties getProperties() throws IOException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
URL propertiesURL = Thread.currentThread()
|
||||||
|
.getContextClassLoader()
|
||||||
|
.getResource("hibernate.properties");
|
||||||
|
try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) {
|
||||||
|
properties.load(inputStream);
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,87 @@
|
|||||||
|
package com.baeldung.hibernate.pojo;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.*;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Where(clause = "deleted = false")
|
||||||
|
@FilterDef(name = "incomeLevelFilter", parameters = @ParamDef(name = "incomeLimit", type = "int"))
|
||||||
|
@Filter(name = "incomeLevelFilter", condition = "grossIncome > :incomeLimit")
|
||||||
|
public class Employee implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private long grossIncome;
|
||||||
|
|
||||||
|
private int taxInPercents;
|
||||||
|
|
||||||
|
private boolean deleted;
|
||||||
|
|
||||||
|
public long getTaxJavaWay() {
|
||||||
|
return grossIncome * taxInPercents / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Formula("grossIncome * taxInPercents / 100")
|
||||||
|
private long tax;
|
||||||
|
|
||||||
|
@OneToMany
|
||||||
|
@JoinColumn(name = "employee_id")
|
||||||
|
@Where(clause = "deleted = false")
|
||||||
|
private Set<Phone> phones = new HashSet<>(0);
|
||||||
|
|
||||||
|
public Employee() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Employee(long grossIncome, int taxInPercents) {
|
||||||
|
this.grossIncome = grossIncome;
|
||||||
|
this.taxInPercents = taxInPercents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getGrossIncome() {
|
||||||
|
return grossIncome;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTaxInPercents() {
|
||||||
|
return taxInPercents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTax() {
|
||||||
|
return tax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGrossIncome(long grossIncome) {
|
||||||
|
this.grossIncome = grossIncome;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaxInPercents(int taxInPercents) {
|
||||||
|
this.taxInPercents = taxInPercents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleted(boolean deleted) {
|
||||||
|
this.deleted = deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Phone> getPhones() {
|
||||||
|
return phones;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.baeldung.hibernate.pojo;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.Any;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class EntityDescription implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Any(
|
||||||
|
metaDef = "EntityDescriptionMetaDef",
|
||||||
|
metaColumn = @Column(name = "entity_type")
|
||||||
|
)
|
||||||
|
@JoinColumn(name = "entity_id")
|
||||||
|
private Serializable entity;
|
||||||
|
|
||||||
|
public EntityDescription() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityDescription(String description, Serializable entity) {
|
||||||
|
this.description = description;
|
||||||
|
this.entity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Serializable getEntity() {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntity(Serializable entity) {
|
||||||
|
this.entity = entity;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package com.baeldung.hibernate.pojo;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Phone implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private boolean deleted;
|
||||||
|
|
||||||
|
private String number;
|
||||||
|
|
||||||
|
public Phone() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Phone(String number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeleted(boolean deleted) {
|
||||||
|
this.deleted = deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(String number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,195 @@
|
|||||||
|
package com.baeldung.hibernate.pojo;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.sql.Time;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.*;
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class TemporalValues implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private long id;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.sql.Date sqlDate;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.sql.Time sqlTime;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.sql.Timestamp sqlTimestamp;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
@Temporal(TemporalType.DATE)
|
||||||
|
private java.util.Date utilDate;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
@Temporal(TemporalType.TIME)
|
||||||
|
private java.util.Date utilTime;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private java.util.Date utilTimestamp;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
@Temporal(TemporalType.DATE)
|
||||||
|
private java.util.Calendar calendarDate;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
|
private java.util.Calendar calendarTimestamp;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.time.LocalDate localDate;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.time.LocalTime localTime;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.time.OffsetTime offsetTime;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.time.Instant instant;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.time.LocalDateTime localDateTime;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.time.OffsetDateTime offsetDateTime;
|
||||||
|
|
||||||
|
@Basic
|
||||||
|
private java.time.ZonedDateTime zonedDateTime;
|
||||||
|
|
||||||
|
public long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getSqlDate() {
|
||||||
|
return sqlDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSqlDate(Date sqlDate) {
|
||||||
|
this.sqlDate = sqlDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time getSqlTime() {
|
||||||
|
return sqlTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSqlTime(Time sqlTime) {
|
||||||
|
this.sqlTime = sqlTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timestamp getSqlTimestamp() {
|
||||||
|
return sqlTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSqlTimestamp(Timestamp sqlTimestamp) {
|
||||||
|
this.sqlTimestamp = sqlTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.util.Date getUtilDate() {
|
||||||
|
return utilDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUtilDate(java.util.Date utilDate) {
|
||||||
|
this.utilDate = utilDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.util.Date getUtilTime() {
|
||||||
|
return utilTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUtilTime(java.util.Date utilTime) {
|
||||||
|
this.utilTime = utilTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.util.Date getUtilTimestamp() {
|
||||||
|
return utilTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUtilTimestamp(java.util.Date utilTimestamp) {
|
||||||
|
this.utilTimestamp = utilTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Calendar getCalendarDate() {
|
||||||
|
return calendarDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCalendarDate(Calendar calendarDate) {
|
||||||
|
this.calendarDate = calendarDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Calendar getCalendarTimestamp() {
|
||||||
|
return calendarTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCalendarTimestamp(Calendar calendarTimestamp) {
|
||||||
|
this.calendarTimestamp = calendarTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getLocalDate() {
|
||||||
|
return localDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalDate(LocalDate localDate) {
|
||||||
|
this.localDate = localDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalTime getLocalTime() {
|
||||||
|
return localTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalTime(LocalTime localTime) {
|
||||||
|
this.localTime = localTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetTime getOffsetTime() {
|
||||||
|
return offsetTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffsetTime(OffsetTime offsetTime) {
|
||||||
|
this.offsetTime = offsetTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getInstant() {
|
||||||
|
return instant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstant(Instant instant) {
|
||||||
|
this.instant = instant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getLocalDateTime() {
|
||||||
|
return localDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalDateTime(LocalDateTime localDateTime) {
|
||||||
|
this.localDateTime = localDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetDateTime getOffsetDateTime() {
|
||||||
|
return offsetDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffsetDateTime(OffsetDateTime offsetDateTime) {
|
||||||
|
this.offsetDateTime = offsetDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZonedDateTime getZonedDateTime() {
|
||||||
|
return zonedDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZonedDateTime(ZonedDateTime zonedDateTime) {
|
||||||
|
this.zonedDateTime = zonedDateTime;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
@AnyMetaDef(name = "EntityDescriptionMetaDef", metaType = "string", idType = "int",
|
||||||
|
metaValues = {
|
||||||
|
@MetaValue(value = "Employee", targetEntity = Employee.class),
|
||||||
|
@MetaValue(value = "Phone", targetEntity = Phone.class)
|
||||||
|
})
|
||||||
|
package com.baeldung.hibernate.pojo;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.AnyMetaDef;
|
||||||
|
import org.hibernate.annotations.MetaValue;
|
@ -0,0 +1,164 @@
|
|||||||
|
package com.baeldung.hibernate;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.pojo.Employee;
|
||||||
|
import com.baeldung.hibernate.pojo.EntityDescription;
|
||||||
|
import com.baeldung.hibernate.pojo.Phone;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class DynamicMappingIntegrationTest {
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
|
||||||
|
private Transaction transaction;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws IOException {
|
||||||
|
session = HibernateUtil.getSessionFactory().openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
session.createNativeQuery("delete from phone").executeUpdate();
|
||||||
|
session.createNativeQuery("delete from employee").executeUpdate();
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
transaction.rollback();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEntity_whenFieldMappedWithFormula_thenFieldIsCalculated() {
|
||||||
|
Employee employee = new Employee(10_000L, 25);
|
||||||
|
assertThat(employee.getTaxJavaWay()).isEqualTo(2_500L);
|
||||||
|
|
||||||
|
session.save(employee);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
employee = session.get(Employee.class, employee.getId());
|
||||||
|
assertThat(employee.getTax()).isEqualTo(2_500L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEntityMappedWithWhere_whenDeletedIsTrue_thenEntityNotFetched() {
|
||||||
|
Employee employee = new Employee();
|
||||||
|
|
||||||
|
session.save(employee);
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
employee = session.find(Employee.class, employee.getId());
|
||||||
|
assertThat(employee).isNotNull();
|
||||||
|
|
||||||
|
employee.setDeleted(true);
|
||||||
|
session.flush();
|
||||||
|
|
||||||
|
employee = session.find(Employee.class, employee.getId());
|
||||||
|
assertThat(employee).isNotNull();
|
||||||
|
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
employee = session.find(Employee.class, employee.getId());
|
||||||
|
assertThat(employee).isNull();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCollectionMappedWithWhere_whenDeletedIsTrue_thenEntityNotFetched() {
|
||||||
|
Employee employee = new Employee();
|
||||||
|
Phone phone1 = new Phone("555-45-67");
|
||||||
|
Phone phone2 = new Phone("555-89-01");
|
||||||
|
employee.getPhones().add(phone1);
|
||||||
|
employee.getPhones().add(phone2);
|
||||||
|
|
||||||
|
session.save(phone1);
|
||||||
|
session.save(phone2);
|
||||||
|
session.save(employee);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
employee = session.find(Employee.class, employee.getId());
|
||||||
|
assertThat(employee.getPhones()).hasSize(2);
|
||||||
|
|
||||||
|
employee.getPhones().iterator().next().setDeleted(true);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
employee = session.find(Employee.class, employee.getId());
|
||||||
|
assertThat(employee.getPhones()).hasSize(1);
|
||||||
|
|
||||||
|
List<Phone> fullPhoneList = session.createQuery("from Phone").getResultList();
|
||||||
|
assertThat(fullPhoneList).hasSize(2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenFilterByIncome_whenIncomeLimitSet_thenFilterIsApplied() throws IOException {
|
||||||
|
session.save(new Employee(10_000, 25));
|
||||||
|
session.save(new Employee(12_000, 25));
|
||||||
|
session.save(new Employee(15_000, 25));
|
||||||
|
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
session.enableFilter("incomeLevelFilter")
|
||||||
|
.setParameter("incomeLimit", 11_000);
|
||||||
|
|
||||||
|
List<Employee> employees = session.createQuery("from Employee").getResultList();
|
||||||
|
|
||||||
|
assertThat(employees).hasSize(2);
|
||||||
|
|
||||||
|
Employee employee = session.get(Employee.class, 1);
|
||||||
|
assertThat(employee.getGrossIncome()).isEqualTo(10_000);
|
||||||
|
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
session = HibernateUtil.getSessionFactory().openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
|
||||||
|
employees = session.createQuery("from Employee").getResultList();
|
||||||
|
|
||||||
|
assertThat(employees).hasSize(3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenMappingWithAny_whenDescriptionAddedToEntity_thenDescriptionCanReferAnyEntity() {
|
||||||
|
Employee employee = new Employee();
|
||||||
|
Phone phone1 = new Phone("555-45-67");
|
||||||
|
Phone phone2 = new Phone("555-89-01");
|
||||||
|
employee.getPhones().add(phone1);
|
||||||
|
employee.getPhones().add(phone2);
|
||||||
|
|
||||||
|
EntityDescription employeeDescription = new EntityDescription("Send to conference next year", employee);
|
||||||
|
EntityDescription phone1Description = new EntityDescription("Home phone (do not call after 10PM)", phone1);
|
||||||
|
EntityDescription phone2Description = new EntityDescription("Work phone", phone1);
|
||||||
|
|
||||||
|
session.save(phone1);
|
||||||
|
session.save(phone2);
|
||||||
|
session.save(employee);
|
||||||
|
session.save(employeeDescription);
|
||||||
|
session.save(phone1Description);
|
||||||
|
session.save(phone2Description);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
List<EntityDescription> descriptions = session.createQuery("from EntityDescription").getResultList();
|
||||||
|
|
||||||
|
assertThat(Employee.class.isAssignableFrom(descriptions.get(0).getEntity().getClass())).isTrue();
|
||||||
|
assertThat(Phone.class.isAssignableFrom(descriptions.get(1).getEntity().getClass())).isTrue();
|
||||||
|
assertThat(Phone.class.isAssignableFrom(descriptions.get(2).getEntity().getClass())).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,126 @@
|
|||||||
|
package com.baeldung.hibernate;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.pojo.TemporalValues;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.*;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class TemporalValuesTest {
|
||||||
|
|
||||||
|
private Session session;
|
||||||
|
|
||||||
|
private Transaction transaction;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws IOException {
|
||||||
|
session = HibernateUtil.getSessionFactory().withOptions()
|
||||||
|
.jdbcTimeZone(TimeZone.getTimeZone("UTC"))
|
||||||
|
.openSession();
|
||||||
|
transaction = session.beginTransaction();
|
||||||
|
session.createNativeQuery("delete from temporalvalues").executeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
transaction.rollback();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEntity_whenMappingSqlTypes_thenTemporalIsSelectedAutomatically() {
|
||||||
|
TemporalValues temporalValues = new TemporalValues();
|
||||||
|
temporalValues.setSqlDate(java.sql.Date.valueOf("2017-11-15"));
|
||||||
|
temporalValues.setSqlTime(java.sql.Time.valueOf("15:30:14"));
|
||||||
|
temporalValues.setSqlTimestamp(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
|
||||||
|
|
||||||
|
session.save(temporalValues);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
temporalValues = session.get(TemporalValues.class, temporalValues.getId());
|
||||||
|
assertThat(temporalValues.getSqlDate()).isEqualTo(java.sql.Date.valueOf("2017-11-15"));
|
||||||
|
assertThat(temporalValues.getSqlTime()).isEqualTo(java.sql.Time.valueOf("15:30:14"));
|
||||||
|
assertThat(temporalValues.getSqlTimestamp()).isEqualTo(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEntity_whenMappingUtilDateType_thenTemporalIsSpecifiedExplicitly() throws Exception {
|
||||||
|
TemporalValues temporalValues = new TemporalValues();
|
||||||
|
temporalValues.setUtilDate(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15"));
|
||||||
|
temporalValues.setUtilTime(new SimpleDateFormat("HH:mm:ss").parse("15:30:14"));
|
||||||
|
temporalValues.setUtilTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.332"));
|
||||||
|
|
||||||
|
session.save(temporalValues);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
temporalValues = session.get(TemporalValues.class, temporalValues.getId());
|
||||||
|
assertThat(temporalValues.getUtilDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15"));
|
||||||
|
assertThat(temporalValues.getUtilTime()).isEqualTo(new SimpleDateFormat("HH:mm:ss").parse("15:30:14"));
|
||||||
|
assertThat(temporalValues.getUtilTimestamp()).isEqualTo(java.sql.Timestamp.valueOf("2017-11-15 15:30:14.332"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEntity_whenMappingCalendarType_thenTemporalIsSpecifiedExplicitly() throws Exception {
|
||||||
|
TemporalValues temporalValues = new TemporalValues();
|
||||||
|
|
||||||
|
Calendar calendarDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
|
calendarDate.set(Calendar.YEAR, 2017);
|
||||||
|
calendarDate.set(Calendar.MONTH, 10);
|
||||||
|
calendarDate.set(Calendar.DAY_OF_MONTH, 15);
|
||||||
|
temporalValues.setCalendarDate(calendarDate);
|
||||||
|
|
||||||
|
Calendar calendarTimestamp = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
|
calendarTimestamp.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.322"));
|
||||||
|
temporalValues.setCalendarTimestamp(calendarTimestamp);
|
||||||
|
|
||||||
|
session.save(temporalValues);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
temporalValues = session.get(TemporalValues.class, temporalValues.getId());
|
||||||
|
assertThat(temporalValues.getCalendarDate().getTime()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2017-11-15"));
|
||||||
|
assertThat(temporalValues.getCalendarTimestamp().getTime()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse("2017-11-15 15:30:14.322"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenEntity_whenMappingJavaTimeTypes_thenTemporalIsSelectedAutomatically() {
|
||||||
|
TemporalValues temporalValues = new TemporalValues();
|
||||||
|
|
||||||
|
temporalValues.setLocalDate(LocalDate.parse("2017-11-15"));
|
||||||
|
temporalValues.setLocalTime(LocalTime.parse("15:30:18"));
|
||||||
|
temporalValues.setOffsetTime(OffsetTime.parse("08:22:12+01:00"));
|
||||||
|
temporalValues.setInstant(Instant.parse("2017-11-15T08:22:12Z"));
|
||||||
|
temporalValues.setLocalDateTime(LocalDateTime.parse("2017-11-15T08:22:12"));
|
||||||
|
temporalValues.setOffsetDateTime(OffsetDateTime.parse("2017-11-15T08:22:12+01:00"));
|
||||||
|
temporalValues.setZonedDateTime(ZonedDateTime.parse("2017-11-15T08:22:12+01:00[Europe/Paris]"));
|
||||||
|
|
||||||
|
session.save(temporalValues);
|
||||||
|
session.flush();
|
||||||
|
session.clear();
|
||||||
|
|
||||||
|
temporalValues = session.get(TemporalValues.class, temporalValues.getId());
|
||||||
|
assertThat(temporalValues.getLocalDate()).isEqualTo(LocalDate.parse("2017-11-15"));
|
||||||
|
assertThat(temporalValues.getLocalTime()).isEqualTo(LocalTime.parse("15:30:18"));
|
||||||
|
assertThat(temporalValues.getOffsetTime()).isEqualTo(OffsetTime.parse("08:22:12+01:00"));
|
||||||
|
assertThat(temporalValues.getInstant()).isEqualTo(Instant.parse("2017-11-15T08:22:12Z"));
|
||||||
|
assertThat(temporalValues.getLocalDateTime()).isEqualTo(LocalDateTime.parse("2017-11-15T08:22:12"));
|
||||||
|
assertThat(temporalValues.getOffsetDateTime()).isEqualTo(OffsetDateTime.parse("2017-11-15T08:22:12+01:00"));
|
||||||
|
assertThat(temporalValues.getZonedDateTime()).isEqualTo(ZonedDateTime.parse("2017-11-15T08:22:12+01:00[Europe/Paris]"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
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.dialect.H2Dialect
|
||||||
|
hibernate.show_sql=true
|
||||||
|
hibernate.multiTenancy=DATABASE
|
@ -6,4 +6,4 @@ jdbc.password=
|
|||||||
|
|
||||||
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||||
hibernate.show_sql=true
|
hibernate.show_sql=true
|
||||||
hibernate.multiTenancy=DATABASE
|
hibernate.hbm2ddl.auto=create-drop
|
@ -35,3 +35,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
|||||||
- [Jackson – Unmarshall to Collection/Array](http://www.baeldung.com/jackson-collection-array)
|
- [Jackson – Unmarshall to Collection/Array](http://www.baeldung.com/jackson-collection-array)
|
||||||
- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property)
|
- [Jackson – Change Name of Field](http://www.baeldung.com/jackson-name-of-property)
|
||||||
- [Serialize Only Fields that meet a Custom Criteria with Jackson](http://www.baeldung.com/jackson-serialize-field-custom-criteria)
|
- [Serialize Only Fields that meet a Custom Criteria with Jackson](http://www.baeldung.com/jackson-serialize-field-custom-criteria)
|
||||||
|
- [Mapping Nested Values with Jackson](http://www.baeldung.com/jackson-nested-values)
|
||||||
|
@ -6,4 +6,4 @@
|
|||||||
- [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests)
|
- [Guide to Dynamic Tests in Junit 5](http://www.baeldung.com/junit5-dynamic-tests)
|
||||||
- [A Guied to JUnit 5 Extensions](http://www.baeldung.com/junit-5-extensions)
|
- [A Guied 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)
|
- [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)
|
||||||
|
@ -19,15 +19,17 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<junit.jupiter.version>5.0.0-RC2</junit.jupiter.version>
|
<junit.jupiter.version>5.0.1</junit.jupiter.version>
|
||||||
<junit.platform.version>1.0.0-RC2</junit.platform.version>
|
<junit.platform.version>1.0.1</junit.platform.version>
|
||||||
<junit.vintage.version>4.12.0-RC2</junit.vintage.version>
|
<junit.vintage.version>4.12.1</junit.vintage.version>
|
||||||
<log4j2.version>2.8.2</log4j2.version>
|
<log4j2.version>2.8.2</log4j2.version>
|
||||||
<h2.version>1.4.196</h2.version>
|
<h2.version>1.4.196</h2.version>
|
||||||
|
<mockito.version>2.11.0</mockito.version>
|
||||||
|
|
||||||
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
|
||||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||||
<junit4.version>4.12</junit4.version>
|
<junit4.version>4.12</junit4.version>
|
||||||
|
<spring.version>5.0.1.RELEASE</spring.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -110,6 +112,17 @@
|
|||||||
<version>${junit4.version}</version>
|
<version>${junit4.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
9
junit5/src/main/java/com/baeldung/junit5/Greetings.java
Normal file
9
junit5/src/main/java/com/baeldung/junit5/Greetings.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.junit5;
|
||||||
|
|
||||||
|
public class Greetings {
|
||||||
|
|
||||||
|
public static String sayHello() {
|
||||||
|
return "Hello";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
41
junit5/src/main/java/com/baeldung/junit5/mockito/User.java
Normal file
41
junit5/src/main/java/com/baeldung/junit5/mockito/User.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package com.baeldung.junit5.mockito;
|
||||||
|
|
||||||
|
public class User {
|
||||||
|
|
||||||
|
private Integer id;
|
||||||
|
private String name;
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
public User() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String name, int age) {
|
||||||
|
this.name = name;
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
public int getAge() {
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
public void setAge(int age) {
|
||||||
|
this.age = age;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.junit5.mockito.repository;
|
||||||
|
|
||||||
|
import com.baeldung.junit5.mockito.User;
|
||||||
|
|
||||||
|
public interface MailClient {
|
||||||
|
|
||||||
|
void sendUserRegistrationMail(User user);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.junit5.mockito.repository;
|
||||||
|
|
||||||
|
public interface SettingRepository {
|
||||||
|
|
||||||
|
int getUserMinAge();
|
||||||
|
|
||||||
|
int getUserNameMinLength();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.junit5.mockito.repository;
|
||||||
|
|
||||||
|
import com.baeldung.junit5.mockito.User;
|
||||||
|
|
||||||
|
public interface UserRepository {
|
||||||
|
|
||||||
|
User insert(User user);
|
||||||
|
boolean isUsernameAlreadyExists(String userName);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package com.baeldung.junit5.mockito.service;
|
||||||
|
|
||||||
|
import com.baeldung.junit5.mockito.User;
|
||||||
|
import com.baeldung.junit5.mockito.repository.MailClient;
|
||||||
|
import com.baeldung.junit5.mockito.repository.SettingRepository;
|
||||||
|
import com.baeldung.junit5.mockito.repository.UserRepository;
|
||||||
|
|
||||||
|
public class DefaultUserService implements UserService {
|
||||||
|
|
||||||
|
private UserRepository userRepository;
|
||||||
|
private SettingRepository settingRepository;
|
||||||
|
private MailClient mailClient;
|
||||||
|
|
||||||
|
public DefaultUserService(UserRepository userRepository, SettingRepository settingRepository, MailClient mailClient) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
this.settingRepository = settingRepository;
|
||||||
|
this.mailClient = mailClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User register(User user) {
|
||||||
|
validate(user);
|
||||||
|
User insertedUser = userRepository.insert(user);
|
||||||
|
mailClient.sendUserRegistrationMail(insertedUser);
|
||||||
|
return insertedUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validate(User user) {
|
||||||
|
if(user.getName() == null) {
|
||||||
|
throw new RuntimeException(Errors.USER_NAME_REQUIRED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(user.getName().length() < settingRepository.getUserNameMinLength()) {
|
||||||
|
throw new RuntimeException(Errors.USER_NAME_SHORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(user.getAge() < settingRepository.getUserMinAge()) {
|
||||||
|
throw new RuntimeException(Errors.USER_AGE_YOUNG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(userRepository.isUsernameAlreadyExists(user.getName())) {
|
||||||
|
throw new RuntimeException(Errors.USER_NAME_DUPLICATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.baeldung.junit5.mockito.service;
|
||||||
|
|
||||||
|
public class Errors {
|
||||||
|
|
||||||
|
public static final String USER_NAME_REQUIRED = "user.name.required";
|
||||||
|
public static final String USER_NAME_SHORT = "user.name.short";
|
||||||
|
public static final String USER_AGE_YOUNG = "user.age.young";
|
||||||
|
public static final String USER_NAME_DUPLICATE = "user.name.duplicate";
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.baeldung.junit5.mockito.service;
|
||||||
|
|
||||||
|
import com.baeldung.junit5.mockito.User;
|
||||||
|
|
||||||
|
public interface UserService {
|
||||||
|
|
||||||
|
User register(User user);
|
||||||
|
|
||||||
|
}
|
19
junit5/src/test/java/com/baeldung/GreetingsTest.java
Normal file
19
junit5/src/test/java/com/baeldung/GreetingsTest.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.platform.runner.JUnitPlatform;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import com.baeldung.junit5.Greetings;
|
||||||
|
|
||||||
|
@RunWith(JUnitPlatform.class)
|
||||||
|
public class GreetingsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingSayHello_thenReturnHello() {
|
||||||
|
assertTrue("Hello".equals(Greetings.sayHello()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015-2016 the original author or authors.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials are
|
||||||
|
* made available under the terms of the Eclipse Public License v1.0 which
|
||||||
|
* accompanies this distribution and is available at
|
||||||
|
*
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.baeldung.junit5.mockito;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import java.lang.reflect.Parameter;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||||
|
import org.junit.jupiter.api.extension.ParameterContext;
|
||||||
|
import org.junit.jupiter.api.extension.ParameterResolver;
|
||||||
|
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code MockitoExtension} showcases the {@link TestInstancePostProcessor}
|
||||||
|
* and {@link ParameterResolver} extension APIs of JUnit 5 by providing
|
||||||
|
* dependency injection support at the field level and at the method parameter
|
||||||
|
* level via Mockito 2.x's {@link Mock @Mock} annotation.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
public class MockitoExtension implements TestInstancePostProcessor, ParameterResolver {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcessTestInstance(Object testInstance, ExtensionContext context) {
|
||||||
|
MockitoAnnotations.initMocks(testInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
|
||||||
|
return parameterContext.getParameter().isAnnotationPresent(Mock.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
|
||||||
|
return getMock(parameterContext.getParameter(), extensionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getMock(Parameter parameter, ExtensionContext extensionContext) {
|
||||||
|
Class<?> mockType = parameter.getType();
|
||||||
|
Store mocks = extensionContext.getStore(Namespace.create(MockitoExtension.class, mockType));
|
||||||
|
String mockName = getMockName(parameter);
|
||||||
|
|
||||||
|
if (mockName != null) {
|
||||||
|
return mocks.getOrComputeIfAbsent(mockName, key -> mock(mockType, mockName));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return mocks.getOrComputeIfAbsent(mockType.getCanonicalName(), key -> mock(mockType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMockName(Parameter parameter) {
|
||||||
|
String explicitMockName = parameter.getAnnotation(Mock.class).name().trim();
|
||||||
|
if (!explicitMockName.isEmpty()) {
|
||||||
|
return explicitMockName;
|
||||||
|
}
|
||||||
|
else if (parameter.isNamePresent()) {
|
||||||
|
return parameter.getName();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
package com.baeldung.junit5.mockito;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.platform.runner.JUnitPlatform;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
import com.baeldung.junit5.mockito.repository.MailClient;
|
||||||
|
import com.baeldung.junit5.mockito.repository.SettingRepository;
|
||||||
|
import com.baeldung.junit5.mockito.repository.UserRepository;
|
||||||
|
import com.baeldung.junit5.mockito.service.DefaultUserService;
|
||||||
|
import com.baeldung.junit5.mockito.service.Errors;
|
||||||
|
import com.baeldung.junit5.mockito.service.UserService;
|
||||||
|
|
||||||
|
@RunWith(JUnitPlatform.class)
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class UserServiceUnitTest {
|
||||||
|
|
||||||
|
UserService userService;
|
||||||
|
@Mock UserRepository userRepository;
|
||||||
|
|
||||||
|
User user;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void init(@Mock SettingRepository settingRepository, @Mock MailClient mailClient) {
|
||||||
|
userService = new DefaultUserService(userRepository, settingRepository, mailClient);
|
||||||
|
when(settingRepository.getUserMinAge()).thenReturn(10);
|
||||||
|
when(settingRepository.getUserNameMinLength()).thenReturn(4);
|
||||||
|
when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenValidUser_whenSaveUser_thenSucceed(@Mock MailClient mailClient) {
|
||||||
|
// Given
|
||||||
|
user = new User("Jerry", 12);
|
||||||
|
when(userRepository.insert(any(User.class))).then(new Answer<User>() {
|
||||||
|
int sequence = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User answer(InvocationOnMock invocation) throws Throwable {
|
||||||
|
User user = (User) invocation.getArgument(0);
|
||||||
|
user.setId(sequence++);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// When
|
||||||
|
User insertedUser = userService.register(user);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
verify(userRepository).insert(user);
|
||||||
|
Assertions.assertNotNull(user.getId());
|
||||||
|
verify(mailClient).sendUserRegistrationMail(insertedUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenShortName_whenSaveUser_thenGiveShortUsernameError() {
|
||||||
|
// Given
|
||||||
|
user = new User("tom", 12);
|
||||||
|
|
||||||
|
// When
|
||||||
|
try {
|
||||||
|
userService.register(user);
|
||||||
|
fail("Should give an error");
|
||||||
|
} catch(Exception ex) {
|
||||||
|
assertEquals(ex.getMessage(), Errors.USER_NAME_SHORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then
|
||||||
|
verify(userRepository, never()).insert(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenSmallAge_whenSaveUser_thenGiveYoungUserError() {
|
||||||
|
// Given
|
||||||
|
user = new User("jerry", 3);
|
||||||
|
|
||||||
|
// When
|
||||||
|
try {
|
||||||
|
userService.register(user);
|
||||||
|
fail("Should give an error");
|
||||||
|
} catch(Exception ex) {
|
||||||
|
assertEquals(ex.getMessage(), Errors.USER_AGE_YOUNG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then
|
||||||
|
verify(userRepository, never()).insert(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenUserWithExistingName_whenSaveUser_thenGiveUsernameAlreadyExistsError() {
|
||||||
|
// Given
|
||||||
|
user = new User("jerry", 12);
|
||||||
|
Mockito.reset(userRepository);
|
||||||
|
when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(true);
|
||||||
|
|
||||||
|
// When
|
||||||
|
try {
|
||||||
|
userService.register(user);
|
||||||
|
fail("Should give an error");
|
||||||
|
} catch(Exception ex) {
|
||||||
|
assertEquals(ex.getMessage(), Errors.USER_NAME_DUPLICATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then
|
||||||
|
verify(userRepository, never()).insert(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.baeldung.junit5.spring;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
|
import com.baeldung.junit5.Greetings;
|
||||||
|
|
||||||
|
@ExtendWith(SpringExtension.class)
|
||||||
|
@ContextConfiguration(classes = { SpringTestConfiguration.class })
|
||||||
|
public class GreetingsSpringTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingSayHello_thenReturnHello() {
|
||||||
|
assertTrue("Hello".equals(Greetings.sayHello()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user