list = new ArrayList<>();
+
+ public void populateList() {
+ for (int i = 0; i < 10000000; i++) {
+ list.add(Math.random());
+ }
+ System.out.println("Debug Point 2");
+ }
+
+ public static void main(String[] args) {
+ System.out.println("Debug Point 1");
+ new StaticFieldsDemo().populateList();
+ System.out.println("Debug Point 3");
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/nth/root/calculator/NthRootCalculator.java b/core-java/src/main/java/com/baeldung/nth/root/calculator/NthRootCalculator.java
new file mode 100644
index 0000000000..217f1e06de
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/nth/root/calculator/NthRootCalculator.java
@@ -0,0 +1,8 @@
+package com.baeldung.nth.root.calculator;
+
+public class NthRootCalculator
+{
+ public Double calculate(Double base, Double n) {
+ return Math.pow(Math.E, Math.log(base)/n);
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/nth/root/main/Main.java b/core-java/src/main/java/com/baeldung/nth/root/main/Main.java
new file mode 100644
index 0000000000..3fcd36812f
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/nth/root/main/Main.java
@@ -0,0 +1,13 @@
+package com.baeldung.nth.root.main;
+
+import com.baeldung.nth.root.calculator.NthRootCalculator;
+
+public class Main {
+ public static void main(String[] args) {
+ NthRootCalculator calculator = new NthRootCalculator();
+ Double base = Double.parseDouble(args[0]);
+ Double n = Double.parseDouble(args[1]);
+ Double result = calculator.calculate(base, n);
+ System.out.println("The " + n + " root of " + base + " equals to " + result + ".");
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java
new file mode 100644
index 0000000000..e2259e4249
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java
@@ -0,0 +1,149 @@
+package com.baeldung.passwordhashing;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * Hash passwords for storage, and test passwords against password tokens.
+ *
+ * Instances of this class can be used concurrently by multiple threads.
+ *
+ * @author erickson
+ * @see StackOverflow
+ */
+public final class PBKDF2Hasher
+{
+
+ /**
+ * Each token produced by this class uses this identifier as a prefix.
+ */
+ public static final String ID = "$31$";
+
+ /**
+ * The minimum recommended cost, used by default
+ */
+ public static final int DEFAULT_COST = 16;
+
+ private static final String ALGORITHM = "PBKDF2WithHmacSHA1";
+
+ private static final int SIZE = 128;
+
+ private static final Pattern layout = Pattern.compile("\\$31\\$(\\d\\d?)\\$(.{43})");
+
+ private final SecureRandom random;
+
+ private final int cost;
+
+ public PBKDF2Hasher()
+ {
+ this(DEFAULT_COST);
+ }
+
+ /**
+ * Create a password manager with a specified cost
+ *
+ * @param cost the exponential computational cost of hashing a password, 0 to 30
+ */
+ public PBKDF2Hasher(int cost)
+ {
+ iterations(cost); /* Validate cost */
+ this.cost = cost;
+ this.random = new SecureRandom();
+ }
+
+ private static int iterations(int cost)
+ {
+ if ((cost < 0) || (cost > 30))
+ throw new IllegalArgumentException("cost: " + cost);
+ return 1 << cost;
+ }
+
+ /**
+ * Hash a password for storage.
+ *
+ * @return a secure authentication token to be stored for later authentication
+ */
+ public String hash(char[] password)
+ {
+ byte[] salt = new byte[SIZE / 8];
+ random.nextBytes(salt);
+ byte[] dk = pbkdf2(password, salt, 1 << cost);
+ byte[] hash = new byte[salt.length + dk.length];
+ System.arraycopy(salt, 0, hash, 0, salt.length);
+ System.arraycopy(dk, 0, hash, salt.length, dk.length);
+ Base64.Encoder enc = Base64.getUrlEncoder().withoutPadding();
+ return ID + cost + '$' + enc.encodeToString(hash);
+ }
+
+ /**
+ * Authenticate with a password and a stored password token.
+ *
+ * @return true if the password and token match
+ */
+ public boolean checkPassword(char[] password, String token)
+ {
+ Matcher m = layout.matcher(token);
+ if (!m.matches())
+ throw new IllegalArgumentException("Invalid token format");
+ int iterations = iterations(Integer.parseInt(m.group(1)));
+ byte[] hash = Base64.getUrlDecoder().decode(m.group(2));
+ byte[] salt = Arrays.copyOfRange(hash, 0, SIZE / 8);
+ byte[] check = pbkdf2(password, salt, iterations);
+ int zero = 0;
+ for (int idx = 0; idx < check.length; ++idx)
+ zero |= hash[salt.length + idx] ^ check[idx];
+ return zero == 0;
+ }
+
+ private static byte[] pbkdf2(char[] password, byte[] salt, int iterations)
+ {
+ KeySpec spec = new PBEKeySpec(password, salt, iterations, SIZE);
+ try {
+ SecretKeyFactory f = SecretKeyFactory.getInstance(ALGORITHM);
+ return f.generateSecret(spec).getEncoded();
+ }
+ catch (NoSuchAlgorithmException ex) {
+ throw new IllegalStateException("Missing algorithm: " + ALGORITHM, ex);
+ }
+ catch (InvalidKeySpecException ex) {
+ throw new IllegalStateException("Invalid SecretKeyFactory", ex);
+ }
+ }
+
+ /**
+ * Hash a password in an immutable {@code String}.
+ *
+ * Passwords should be stored in a {@code char[]} so that it can be filled
+ * with zeros after use instead of lingering on the heap and elsewhere.
+ *
+ * @deprecated Use {@link #hash(char[])} instead
+ */
+ @Deprecated
+ public String hash(String password)
+ {
+ return hash(password.toCharArray());
+ }
+
+ /**
+ * Authenticate with a password in an immutable {@code String} and a stored
+ * password token.
+ *
+ * @deprecated Use {@link #checkPassword(char[],String)} instead.
+ * @see #hash(String)
+ */
+ @Deprecated
+ public boolean checkPassword(String password, String token)
+ {
+ return checkPassword(password.toCharArray(), token);
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java
new file mode 100644
index 0000000000..4f5337f963
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java
@@ -0,0 +1,35 @@
+package com.baeldung.passwordhashing;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+
+/** A really simple SHA_512 Encryption example.
+ *
+ */
+public class SHA512Hasher {
+
+ public String hash(String passwordToHash, byte[] salt){
+ String generatedPassword = null;
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-512");
+ md.update(salt);
+ byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i< bytes.length ;i++){
+ sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
+ }
+ generatedPassword = sb.toString();
+ }
+ catch (NoSuchAlgorithmException e){
+ e.printStackTrace();
+ }
+ return generatedPassword;
+ }
+
+ public boolean checkPassword(String hash, String attempt, byte[] salt){
+ String generatedHash = hash(attempt, salt);
+ return hash.equals(generatedHash);
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java
new file mode 100644
index 0000000000..36c9b65070
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java
@@ -0,0 +1,18 @@
+package com.baeldung.passwordhashing;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import java.security.spec.KeySpec;
+
+/** A really simple SimplePBKDF2 Encryption example.
+ *
+ */
+public class SimplePBKDF2Hasher {
+
+ public static String hashSimple(String password, byte[] salt) throws Exception{
+ KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
+ SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+ byte[] hash = f.generateSecret(spec).getEncoded();
+ return String.valueOf(hash);
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java b/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java
new file mode 100644
index 0000000000..69e151bfcb
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java
@@ -0,0 +1,70 @@
+package com.baeldung.switchstatement;
+
+public class SwitchStatement {
+
+ public String exampleOfIF(String animal) {
+
+ String result;
+
+ if (animal.equals("DOG") || animal.equals("CAT")) {
+ result = "domestic animal";
+ } else if (animal.equals("TIGER")) {
+ result = "wild animal";
+ } else {
+ result = "unknown animal";
+ }
+ return result;
+ }
+
+ public String exampleOfSwitch(String animal) {
+
+ String result;
+
+ switch (animal) {
+ case "DOG":
+ case "CAT":
+ result = "domestic animal";
+ break;
+ case "TIGER":
+ result = "wild animal";
+ break;
+ default:
+ result = "unknown animal";
+ break;
+ }
+ return result;
+ }
+
+ public String forgetBreakInSwitch(String animal) {
+
+ String result;
+
+ switch (animal) {
+
+ case "DOG":
+ System.out.println("domestic animal");
+ result = "domestic animal";
+
+ default:
+ System.out.println("unknown animal");
+ result = "unknown animal";
+
+ }
+ return result;
+ }
+
+ public String constantCaseValue(String animal) {
+
+ String result = "";
+
+ final String dog = "DOG";
+
+ switch (animal) {
+
+ case dog:
+ result = "domestic animal";
+ }
+ return result;
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java
new file mode 100644
index 0000000000..fb92eb8d0d
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java
@@ -0,0 +1,13 @@
+package com.baeldung.zoneddatetime;
+
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+
+public class OffsetDateTimeExample {
+
+ public OffsetDateTime getCurrentTimeByZoneOffset(String offset) {
+ ZoneOffset zoneOffSet= ZoneOffset.of(offset);
+ OffsetDateTime date = OffsetDateTime.now(zoneOffSet);
+ return date;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java
new file mode 100644
index 0000000000..58e2d4d5ad
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java
@@ -0,0 +1,13 @@
+package com.baeldung.zoneddatetime;
+
+import java.time.OffsetTime;
+import java.time.ZoneOffset;
+
+public class OffsetTimeExample {
+
+ public OffsetTime getCurrentTimeByZoneOffset(String offset) {
+ ZoneOffset zoneOffSet = ZoneOffset.of(offset);
+ OffsetTime time = OffsetTime.now(zoneOffSet);
+ return time;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java
new file mode 100644
index 0000000000..b54b8c5225
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java
@@ -0,0 +1,21 @@
+package com.baeldung.zoneddatetime;
+
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+public class ZoneDateTimeExample {
+
+ public ZonedDateTime getCurrentTimeByZoneId(String region) {
+ ZoneId zone = ZoneId.of(region);
+ ZonedDateTime date = ZonedDateTime.now(zone);
+ return date;
+ }
+
+ public ZonedDateTime convertZonedDateTime(ZonedDateTime sourceDate, String destZone) {
+
+ ZoneId destZoneId = ZoneId.of(destZone);
+ ZonedDateTime destDate = sourceDate.withZoneSameInstant(destZoneId);
+
+ return destDate;
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderUnitTest.java b/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderUnitTest.java
index ec35885b84..cabf9f7bdb 100644
--- a/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderUnitTest.java
+++ b/core-java/src/test/java/com/baeldung/classloader/CustomClassLoaderUnitTest.java
@@ -11,7 +11,7 @@ public class CustomClassLoaderUnitTest {
public void customLoader() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
CustomClassLoader customClassLoader = new CustomClassLoader();
- Class> c = customClassLoader.getClass(PrintClassLoader.class.getName());
+ Class> c = customClassLoader.findClass(PrintClassLoader.class.getName());
Object ob = c.newInstance();
diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/equalshashcode/PersonMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/equalshashcode/PersonMemoryLeakUnitTest.java
new file mode 100644
index 0000000000..3fa1db18d2
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/memoryleaks/equalshashcode/PersonMemoryLeakUnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.memoryleaks.equalshashcode;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class PersonMemoryLeakUnitTest {
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenMap_whenEqualsAndHashCodeNotOverridden_thenMemoryLeak() {
+ Map map = new HashMap();
+ for(int i=0; i<10000000; i++) {
+ map.put(new Person("jon"), 1);
+ }
+ assertTrue(map.size() > 1);
+ System.out.print("Debug Point - VisuaLVM");
+ }
+
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenMap_whenEqualsAndHashCodeOverridden_thenNoMemoryLeak() {
+ Map map = new HashMap();
+ for(int i=0; i<10000; i++) {
+ map.put(new PersonOptimized("jon"), 1);
+ }
+ assertTrue(map.size() == 1);
+ System.out.print("Debug Point - VisuaLVM");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/finalize/FinalizeMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/finalize/FinalizeMemoryLeakUnitTest.java
new file mode 100644
index 0000000000..b6d81a8968
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/memoryleaks/finalize/FinalizeMemoryLeakUnitTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.memoryleaks.finalize;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class FinalizeMemoryLeakUnitTest {
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenObjectWithFinalizer_whenCreatingAndDestroyingThisObject_thenMemoryLeak() {
+ BulkyObject[] stock = new BulkyObject[100000];
+
+ for(int i=0; i<100000; i++) {
+ stock[i] = new BulkyObject();
+ }
+ System.out.print("Debug Point - VisuaLVM");
+ }
+
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenObjectWithoutFinalizer_whenCreatingAndDestroyingThisObject_thenNoMemoryLeak() {
+ BulkyObjectOptimized[] stock = new BulkyObjectOptimized[100000];
+
+ for(int i=0; i<100000; i++) {
+ stock[i] = new BulkyObjectOptimized();
+ }
+ System.out.print("Debug Point - VisuaLVM");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/innerclass/StaticInnerClassMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/innerclass/StaticInnerClassMemoryLeakUnitTest.java
new file mode 100644
index 0000000000..0854e4a38a
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/memoryleaks/innerclass/StaticInnerClassMemoryLeakUnitTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.memoryleaks.innerclass;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class StaticInnerClassMemoryLeakUnitTest {
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenUsingInnerClass_whenInitializingInnerClass_thenInnerClassHoldsReferenceOfOuterObject() {
+ InnerClassWrapper.SimpleInnerClass simpleInnerClassObj = new InnerClassWrapper().new SimpleInnerClass();
+ System.out.print("Debug Point - VisuaLVM");
+ }
+
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenUsingStaticNestedClass_whenInitializingInnerClass_thenStaticNestedClassDoesntReferenceOuterObject() {
+ StaticNestedClassWrapper.StaticNestedClass staticNestedClassObj = new StaticNestedClassWrapper.StaticNestedClass();
+ System.out.print("Debug Point - VisuaLVM");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/internedstrings/StringInternMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/internedstrings/StringInternMemoryLeakUnitTest.java
new file mode 100644
index 0000000000..6d363e0bdc
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/memoryleaks/internedstrings/StringInternMemoryLeakUnitTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.memoryleaks.internedstrings;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class StringInternMemoryLeakUnitTest {
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenJava6OrBelow_whenInterningLargeStrings_thenPermgenIncreases() {
+ new InternedString().readString();
+ System.out.print("Debug Point - VisuaLVM");
+ }
+
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenJava6OrBelow_whenNotInterningLargeStrings_thenPermgenDoesntIncrease() {
+ new StringObject().readString();
+ System.out.print("Debug Point - VisuaLVM");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/NonStaticFieldsMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/NonStaticFieldsMemoryLeakUnitTest.java
new file mode 100644
index 0000000000..e64fdb73e0
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/NonStaticFieldsMemoryLeakUnitTest.java
@@ -0,0 +1,26 @@
+package com.baeldung.memoryleaks.staticfields;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class NonStaticFieldsMemoryLeakUnitTest {
+ public List list = new ArrayList<>();
+
+ public void populateList() {
+ for (int i = 0; i < 10000000; i++) {
+ list.add(Math.random());
+ }
+ System.out.println("Debug Point 2");
+ }
+
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenNonStaticLargeList_whenPopulatingList_thenListGarbageCollected() {
+ System.out.println("Debug Point 1");
+ new NonStaticFieldsMemoryLeakUnitTest().populateList();
+ System.out.println("Debug Point 3");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/StaticFieldsMemoryLeakUnitTest.java b/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/StaticFieldsMemoryLeakUnitTest.java
new file mode 100644
index 0000000000..1765f0cf0d
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/memoryleaks/staticfields/StaticFieldsMemoryLeakUnitTest.java
@@ -0,0 +1,26 @@
+package com.baeldung.memoryleaks.staticfields;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class StaticFieldsMemoryLeakUnitTest {
+ public static List list = new ArrayList<>();
+
+ public void populateList() {
+ for (int i = 0; i < 10000000; i++) {
+ list.add(Math.random());
+ }
+ System.out.println("Debug Point 2");
+ }
+
+ @Test
+ @Ignore // Test deliberately ignored as memory leak tests consume lots of resources
+ public void givenStaticLargeList_whenPopulatingList_thenListIsNotGarbageCollected() {
+ System.out.println("Debug Point 1");
+ new StaticFieldsDemo().populateList();
+ System.out.println("Debug Point 3");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/nth/root/calculator/NthRootCalculatorUnitTest.java b/core-java/src/test/java/com/baeldung/nth/root/calculator/NthRootCalculatorUnitTest.java
new file mode 100644
index 0000000000..388bceef49
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/nth/root/calculator/NthRootCalculatorUnitTest.java
@@ -0,0 +1,21 @@
+package com.baeldung.nth.root.calculator;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(MockitoJUnitRunner.class)
+public class NthRootCalculatorUnitTest {
+
+ @InjectMocks
+ private NthRootCalculator nthRootCalculator;
+
+ @Test
+ public void giventThatTheBaseIs125_andTheExpIs3_whenCalculateIsCalled_thenTheResultIsTheCorrectOne() {
+ Double result = nthRootCalculator.calculate(125.0, 3.0);
+ assertEquals(result, (Double) 5.0d);
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/nth/root/main/MainUnitTest.java b/core-java/src/test/java/com/baeldung/nth/root/main/MainUnitTest.java
new file mode 100644
index 0000000000..a2fd839ba4
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/nth/root/main/MainUnitTest.java
@@ -0,0 +1,34 @@
+package com.baeldung.nth.root.main;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import static org.junit.Assert.assertEquals;
+
+public class MainUnitTest {
+ @InjectMocks
+ private Main main;
+
+ private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+ private final PrintStream originalOut = System.out;
+
+ @Before
+ public void setUpStreams() {
+ System.setOut(new PrintStream(outContent));
+ }
+
+ @After
+ public void restoreStreams() {
+ System.setOut(originalOut);
+ }
+
+ @Test
+ public void givenThatTheBaseIs125_andTheExpIs3_whenMainIsCalled_thenTheCorrectResultIsPrinted() {
+ main.main(new String[]{"125.0", "3.0"});
+ assertEquals("The 3.0 root of 125.0 equals to 5.0.\n", outContent.toString().replaceAll("\r", ""));
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java b/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java
new file mode 100644
index 0000000000..8e90725c77
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.passwordhashing;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+public class PBKDF2HasherUnitTest {
+
+ private PBKDF2Hasher mPBKDF2Hasher;
+
+ @Before
+ public void setUp() throws Exception {
+ mPBKDF2Hasher = new PBKDF2Hasher();
+ }
+
+ @Test
+ public void givenCorrectMessageAndHash_whenAuthenticated_checkAuthenticationSucceeds() throws Exception {
+ String message1 = "password123";
+
+ String hash1 = mPBKDF2Hasher.hash(message1.toCharArray());
+
+ assertTrue(mPBKDF2Hasher.checkPassword(message1.toCharArray(), hash1));
+
+ }
+
+ @Test
+ public void givenWrongMessage_whenAuthenticated_checkAuthenticationFails() throws Exception {
+ String message1 = "password123";
+
+ String hash1 = mPBKDF2Hasher.hash(message1.toCharArray());
+
+ String wrongPasswordAttempt = "IamWrong";
+
+ assertFalse(mPBKDF2Hasher.checkPassword(wrongPasswordAttempt.toCharArray(), hash1));
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java b/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java
new file mode 100644
index 0000000000..3acfb0ba9d
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java
@@ -0,0 +1,70 @@
+package com.baeldung.passwordhashing;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.security.SecureRandom;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by PhysicsSam on 06-Sep-18.
+ */
+public class SHA512HasherUnitTest {
+
+ private SHA512Hasher hasher;
+ private SecureRandom secureRandom;
+
+ @Before
+ public void setUp() throws Exception {
+ hasher = new SHA512Hasher();
+ secureRandom = new SecureRandom();
+ }
+
+ @Test
+ public void givenSamePasswordAndSalt_whenHashed_checkResultingHashesAreEqual() throws Exception {
+
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+
+ String hash1 = hasher.hash("password", salt);
+ String hash2 = hasher.hash("password", salt);
+
+ assertEquals(hash1, hash2);
+
+ }
+
+ @Test
+ public void givenSamePasswordAndDifferentSalt_whenHashed_checkResultingHashesNotEqual() throws Exception {
+
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+ String hash1 = hasher.hash("password", salt);
+ //generate a second salt
+ byte[] secondSalt = new byte[16];
+ String hash2 = hasher.hash("password", secondSalt);
+
+ assertNotEquals(hash1, hash2);
+
+ }
+
+ @Test
+ public void givenPredefinedHash_whenCorrectAttemptGiven_checkAuthenticationSucceeds() throws Exception {
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+
+ String originalHash = hasher.hash("password123", salt);
+
+ assertTrue(hasher.checkPassword(originalHash, "password123", salt));
+ }
+
+ @Test
+ public void givenPredefinedHash_whenIncorrectAttemptGiven_checkAuthenticationFails() throws Exception {
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+
+ String originalHash = hasher.hash("password123", salt);
+
+ assertFalse(hasher.checkPassword(originalHash, "password124", salt));
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java
new file mode 100644
index 0000000000..8dbfcaf5e7
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java
@@ -0,0 +1,100 @@
+package com.baeldung.removingdecimals;
+
+import org.junit.Test;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark compares some of the approaches to formatting a floating-point
+ * value into a {@link String} while removing the decimal part.
+ *
+ * To run, simply run the {@link RemovingDecimalsManualTest#runBenchmarks()} test
+ * at the end of this class.
+ *
+ * The benchmark takes about 15 minutes to run. Since it is using {@link Mode#Throughput},
+ * higher numbers mean better performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@Warmup(iterations = 5)
+@Measurement(iterations = 20)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Benchmark)
+public class RemovingDecimalsManualTest {
+ @Param(value = {"345.56", "345345345.56", "345345345345345345.56"}) double doubleValue;
+
+ NumberFormat nf;
+ DecimalFormat df;
+
+ @Setup
+ public void readyFormatters() {
+ nf = NumberFormat.getInstance();
+ nf.setMaximumFractionDigits(0);
+ df = new DecimalFormat("#,###");
+ }
+
+ @Benchmark
+ public String whenCastToInt_thenValueIsTruncated() {
+ return String.valueOf((int) doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingStringFormat_thenValueIsRounded() {
+ return String.format("%.0f", doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingNumberFormat_thenValueIsRounded() {
+ nf.setRoundingMode(RoundingMode.HALF_UP);
+ return nf.format(doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingNumberFormatWithFloor_thenValueIsTruncated() {
+ nf.setRoundingMode(RoundingMode.FLOOR);
+ return nf.format(doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingDecimalFormat_thenValueIsRounded() {
+ df.setRoundingMode(RoundingMode.HALF_UP);
+ return df.format(doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingDecimalFormatWithFloor_thenValueIsTruncated() {
+ df.setRoundingMode(RoundingMode.FLOOR);
+ return df.format(doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingBigDecimalDoubleValue_thenValueIsTruncated() {
+ BigDecimal big = new BigDecimal(doubleValue);
+ big = big.setScale(0, RoundingMode.FLOOR);
+ return big.toString();
+ }
+
+ @Benchmark
+ public String whenUsingBigDecimalDoubleValueWithHalfUp_thenValueIsRounded() {
+ BigDecimal big = new BigDecimal(doubleValue);
+ big = big.setScale(0, RoundingMode.HALF_UP);
+ return big.toString();
+ }
+
+ @Test
+ public void runBenchmarks() throws Exception {
+ Options options = new OptionsBuilder()
+ .include(this.getClass().getSimpleName()).threads(1)
+ .forks(1).shouldFailOnError(true).shouldDoGC(true)
+ .jvmArgs("-server").build();
+
+ new Runner(options).run();
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java
new file mode 100644
index 0000000000..2f634b553b
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java
@@ -0,0 +1,95 @@
+package com.baeldung.removingdecimals;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+/**
+ * Tests that demonstrate some different approaches for formatting a
+ * floating-point value into a {@link String} while removing the decimal part.
+ */
+public class RemovingDecimalsUnitTest {
+ private final double doubleValue = 345.56;
+
+ @Test
+ public void whenCastToInt_thenValueIsTruncated() {
+ String truncated = String.valueOf((int) doubleValue);
+ assertEquals("345", truncated);
+ }
+
+ @Test
+ public void givenALargeDouble_whenCastToInt_thenValueIsNotTruncated() {
+ double outOfIntRange = 6_000_000_000.56;
+ String truncationAttempt = String.valueOf((int) outOfIntRange);
+ assertNotEquals("6000000000", truncationAttempt);
+ }
+
+ @Test
+ public void whenUsingStringFormat_thenValueIsRounded() {
+ String rounded = String.format("%.0f", doubleValue);
+ assertEquals("346", rounded);
+ }
+
+ @Test
+ public void givenALargeDouble_whenUsingStringFormat_thenValueIsStillRounded() {
+ double outOfIntRange = 6_000_000_000.56;
+ String rounded = String.format("%.0f", outOfIntRange);
+ assertEquals("6000000001", rounded);
+ }
+
+ @Test
+ public void whenUsingNumberFormat_thenValueIsRounded() {
+ NumberFormat nf = NumberFormat.getInstance();
+ nf.setMaximumFractionDigits(0);
+ nf.setRoundingMode(RoundingMode.HALF_UP);
+ String rounded = nf.format(doubleValue);
+ assertEquals("346", rounded);
+ }
+
+ @Test
+ public void whenUsingNumberFormatWithFloor_thenValueIsTruncated() {
+ NumberFormat nf = NumberFormat.getInstance();
+ nf.setMaximumFractionDigits(0);
+ nf.setRoundingMode(RoundingMode.FLOOR);
+ String truncated = nf.format(doubleValue);
+ assertEquals("345", truncated);
+ }
+
+ @Test
+ public void whenUsingDecimalFormat_thenValueIsRounded() {
+ DecimalFormat df = new DecimalFormat("#,###");
+ df.setRoundingMode(RoundingMode.HALF_UP);
+ String rounded = df.format(doubleValue);
+ assertEquals("346", rounded);
+ }
+
+ @Test
+ public void whenUsingDecimalFormatWithFloor_thenValueIsTruncated() {
+ DecimalFormat df = new DecimalFormat("#,###");
+ df.setRoundingMode(RoundingMode.FLOOR);
+ String truncated = df.format(doubleValue);
+ assertEquals("345", truncated);
+ }
+
+ @Test
+ public void whenUsingBigDecimalDoubleValue_thenValueIsTruncated() {
+ BigDecimal big = new BigDecimal(doubleValue);
+ big = big.setScale(0, RoundingMode.FLOOR);
+ String truncated = big.toString();
+ assertEquals("345", truncated);
+ }
+
+ @Test
+ public void whenUsingBigDecimalDoubleValueWithHalfUp_thenValueIsRounded() {
+ BigDecimal big = new BigDecimal(doubleValue);
+ big = big.setScale(0, RoundingMode.HALF_UP);
+ String truncated = big.toString();
+ assertEquals("346", truncated);
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java b/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java
new file mode 100644
index 0000000000..e8ac645531
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java
@@ -0,0 +1,38 @@
+package com.baeldung.switchstatement;
+
+import org.junit.Test;
+
+import org.junit.Assert;
+
+public class SwitchStatementUnitTest {
+ private SwitchStatement s = new SwitchStatement();
+
+
+ @Test
+ public void whenDog_thenDomesticAnimal() {
+
+ String animal = "DOG";
+ Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal));
+ }
+
+ @Test
+ public void whenNoBreaks_thenGoThroughBlocks() {
+ String animal = "DOG";
+ Assert.assertEquals("unknown animal", s.forgetBreakInSwitch(animal));
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void whenSwitchAgumentIsNull_thenNullPointerException() {
+ String animal = null;
+ Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal));
+ }
+
+
+ @Test
+ public void whenCompareStrings_thenByEqual() {
+ String animal = new String("DOG");
+ Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal));
+ }
+
+
+}
diff --git a/core-java/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java b/core-java/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java
new file mode 100644
index 0000000000..6b292ad8ab
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/ternaryoperator/TernaryOperatorUnitTest.java
@@ -0,0 +1,43 @@
+package com.baeldung.ternaryoperator;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class TernaryOperatorUnitTest {
+
+ @Test
+ public void givenACondition_whenUsingTernaryOperator_thenItEvaluatesConditionAndReturnsAValue() {
+ int number = 10;
+ String msg = number > 10 ? "Number is greater than 10" : "Number is less than or equal to 10";
+
+ assertThat(msg).isEqualTo("Number is less than or equal to 10");
+ }
+
+ @Test
+ public void givenATrueCondition_whenUsingTernaryOperator_thenOnlyExpression1IsEvaluated() {
+ int exp1 = 0, exp2 = 0;
+ int result = 12 > 10 ? ++exp1 : ++exp2;
+
+ assertThat(exp1).isEqualTo(1);
+ assertThat(exp2).isEqualTo(0);
+ assertThat(result).isEqualTo(1);
+ }
+
+ @Test
+ public void givenAFalseCondition_whenUsingTernaryOperator_thenOnlyExpression2IsEvaluated() {
+ int exp1 = 0, exp2 = 0;
+ int result = 8 > 10 ? ++exp1 : ++exp2;
+
+ assertThat(exp1).isEqualTo(0);
+ assertThat(exp2).isEqualTo(1);
+ assertThat(result).isEqualTo(1);
+ }
+
+ @Test
+ public void givenANestedCondition_whenUsingTernaryOperator_thenCorrectValueIsReturned() {
+ int number = 6;
+ String msg = number > 10 ? "Number is greater than 10" : number > 5 ? "Number is greater than 5" : "Number is less than or equal to 5";
+
+ assertThat(msg).isEqualTo("Number is greater than 5");
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetDateTimeExampleUnitTest.java b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetDateTimeExampleUnitTest.java
new file mode 100644
index 0000000000..a08d3737cd
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetDateTimeExampleUnitTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.zoneddatetime;
+
+import static org.junit.Assert.assertTrue;
+
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+
+import org.junit.Test;
+
+public class OffsetDateTimeExampleUnitTest {
+
+ OffsetDateTimeExample offsetDateTimeExample = new OffsetDateTimeExample();
+
+ @Test
+ public void givenZoneOffset_whenGetCurrentTime_thenResultHasZone() {
+ String offset = "+02:00";
+ OffsetDateTime time = offsetDateTimeExample.getCurrentTimeByZoneOffset(offset);
+
+ assertTrue(time.getOffset()
+ .equals(ZoneOffset.of(offset)));
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetTimeExampleUnitTest.java b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetTimeExampleUnitTest.java
new file mode 100644
index 0000000000..488f934179
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/zoneddatetime/OffsetTimeExampleUnitTest.java
@@ -0,0 +1,22 @@
+package com.baeldung.zoneddatetime;
+
+import static org.junit.Assert.assertTrue;
+
+import java.time.OffsetTime;
+import java.time.ZoneOffset;
+
+import org.junit.Test;
+
+public class OffsetTimeExampleUnitTest {
+
+ OffsetTimeExample offsetTimeExample = new OffsetTimeExample();
+
+ @Test
+ public void givenZoneOffset_whenGetCurrentTime_thenResultHasZone() {
+ String offset = "+02:00";
+ OffsetTime time = offsetTimeExample.getCurrentTimeByZoneOffset(offset);
+
+ assertTrue(time.getOffset()
+ .equals(ZoneOffset.of(offset)));
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/zoneddatetime/ZoneDateTimeExampleUnitTest.java b/core-java/src/test/java/com/baeldung/zoneddatetime/ZoneDateTimeExampleUnitTest.java
new file mode 100644
index 0000000000..e78ff3e3fd
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/zoneddatetime/ZoneDateTimeExampleUnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.zoneddatetime;
+
+import static org.junit.Assert.assertTrue;
+
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+import org.junit.Test;
+
+public class ZoneDateTimeExampleUnitTest {
+
+ ZoneDateTimeExample zoneDateTimeExample = new ZoneDateTimeExample();
+
+ @Test
+ public void givenZone_whenGetCurrentTime_thenResultHasZone() {
+ String zone = "Europe/Berlin";
+ ZonedDateTime time = zoneDateTimeExample.getCurrentTimeByZoneId(zone);
+
+ assertTrue(time.getZone()
+ .equals(ZoneId.of(zone)));
+ }
+
+ @Test
+ public void givenZones_whenConvertDateByZone_thenGetConstantDiff() {
+ String sourceZone = "Europe/Berlin";
+ String destZone = "Asia/Tokyo";
+ ZonedDateTime sourceDate = zoneDateTimeExample.getCurrentTimeByZoneId(sourceZone);
+ ZonedDateTime destDate = zoneDateTimeExample.convertZonedDateTime(sourceDate, destZone);
+
+ assertTrue(sourceDate.toInstant()
+ .compareTo(destDate.toInstant()) == 0);
+ }
+}
diff --git a/core-kotlin/README.md b/core-kotlin/README.md
index 734b2c08b3..7d8d5213d1 100644
--- a/core-kotlin/README.md
+++ b/core-kotlin/README.md
@@ -8,7 +8,6 @@
- [Generics in Kotlin](http://www.baeldung.com/kotlin-generics)
- [Introduction to Kotlin Coroutines](http://www.baeldung.com/kotlin-coroutines)
- [Destructuring Declarations in Kotlin](http://www.baeldung.com/kotlin-destructuring-declarations)
-- [Kotlin with Mockito](http://www.baeldung.com/kotlin-mockito)
- [Lazy Initialization in Kotlin](http://www.baeldung.com/kotlin-lazy-initialization)
- [Overview of Kotlin Collections API](http://www.baeldung.com/kotlin-collections-api)
- [Converting a List to Map in Kotlin](http://www.baeldung.com/kotlin-list-to-map)
@@ -19,8 +18,6 @@
- [Extension Methods in Kotlin](http://www.baeldung.com/kotlin-extension-methods)
- [Infix Functions in Kotlin](http://www.baeldung.com/kotlin-infix-functions)
- [Try-with-resources in Kotlin](http://www.baeldung.com/kotlin-try-with-resources)
-- [HTTP Requests with Kotlin and khttp](http://www.baeldung.com/kotlin-khttp)
-- [Kotlin Dependency Injection with Kodein](http://www.baeldung.com/kotlin-kodein-dependency-injection)
- [Regular Expressions in Kotlin](http://www.baeldung.com/kotlin-regular-expressions)
- [Objects in Kotlin](http://www.baeldung.com/kotlin-objects)
- [Reading from a File in Kotlin](http://www.baeldung.com/kotlin-read-file)
@@ -28,13 +25,15 @@
- [Filtering Kotlin Collections](http://www.baeldung.com/kotlin-filter-collection)
- [Writing to a File in Kotlin](http://www.baeldung.com/kotlin-write-file)
- [Lambda Expressions in Kotlin](http://www.baeldung.com/kotlin-lambda-expressions)
-- [Writing Specifications with Kotlin and Spek](http://www.baeldung.com/kotlin-spek)
-- [Processing JSON with Kotlin and Klaxson](http://www.baeldung.com/kotlin-json-klaxson)
- [Kotlin String Templates](http://www.baeldung.com/kotlin-string-template)
-- [Java EE 8 Security API](http://www.baeldung.com/java-ee-8-security)
-- [Kotlin with Ktor](http://www.baeldung.com/kotlin-ktor)
- [Working with Enums in Kotlin](http://www.baeldung.com/kotlin-enum)
- [Create a Java and Kotlin Project with Maven](http://www.baeldung.com/kotlin-maven-java-project)
- [Reflection with Kotlin](http://www.baeldung.com/kotlin-reflection)
- [Get a Random Number in Kotlin](http://www.baeldung.com/kotlin-random-number)
- [Idiomatic Logging in Kotlin](http://www.baeldung.com/kotlin-logging)
+- [Kotlin Constructors](https://www.baeldung.com/kotlin-constructors)
+- [Creational Design Patterns in Kotlin: Builder](https://www.baeldung.com/kotlin-builder-pattern)
+- [Kotlin Nested and Inner Classes](https://www.baeldung.com/kotlin-inner-classes)
+- [Kotlin with Ktor](https://www.baeldung.com/kotlin-ktor)
+- [Fuel HTTP Library with Kotlin](https://www.baeldung.com/kotlin-fuel)
+- [Introduction to Kovenant Library for Kotlin](https://www.baeldung.com/kotlin-kovenant)
diff --git a/core-kotlin/build.gradle b/core-kotlin/build.gradle
index 6c1e06aa25..2b6527fca7 100755
--- a/core-kotlin/build.gradle
+++ b/core-kotlin/build.gradle
@@ -6,7 +6,6 @@ version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.2.41'
- ext.ktor_version = '0.9.2'
repositories {
mavenCentral()
@@ -44,14 +43,6 @@ sourceSets {
}
dependencies {
- compile "io.ktor:ktor-server-netty:$ktor_version"
compile "ch.qos.logback:logback-classic:1.2.1"
- compile "io.ktor:ktor-gson:$ktor_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
- implementation 'com.beust:klaxon:3.0.1'
-
-}
-task runServer(type: JavaExec) {
- main = 'APIServer'
- classpath = sourceSets.main.runtimeClasspath
}
\ No newline at end of file
diff --git a/core-kotlin/kotlin-ktor/webapp/WEB-INF/web.xml b/core-kotlin/kotlin-ktor/webapp/WEB-INF/web.xml
deleted file mode 100755
index 513a80cb27..0000000000
--- a/core-kotlin/kotlin-ktor/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
- io.ktor.ktor.config
- application.conf
-
-
-
- KtorServlet
- KtorServlet
- io.ktor.server.servlet.ServletApplicationEngine
-
-
- true
-
-
-
- 304857600
- 304857600
- 0
-
-
-
-
- KtorServlet
- /
-
-
-
\ No newline at end of file
diff --git a/core-kotlin/pom.xml b/core-kotlin/pom.xml
index 88f54963ed..0894a57320 100644
--- a/core-kotlin/pom.xml
+++ b/core-kotlin/pom.xml
@@ -12,33 +12,7 @@
../parent-kotlin
-
-
- exposed
- exposed
- https://dl.bintray.com/kotlin/exposed
-
-
-
-
- org.jetbrains.spek
- spek-api
- 1.1.5
- test
-
-
- org.jetbrains.spek
- spek-subject-extension
- 1.1.5
- test
-
-
- org.jetbrains.spek
- spek-junit-platform-engine
- 1.1.5
- test
-
org.apache.commons
commons-math3
@@ -50,38 +24,12 @@
${junit.platform.version}
test
-
- khttp
- khttp
- ${khttp.version}
-
-
- com.nhaarman
- mockito-kotlin
- ${mockito-kotlin.version}
- test
-
-
- com.github.salomonbrys.kodein
- kodein
- ${kodein.version}
-
org.assertj
assertj-core
${assertj.version}
test
-
- com.beust
- klaxon
- ${klaxon.version}
-
-
- org.jetbrains.exposed
- exposed
- ${exposed.version}
-
com.h2database
h2
@@ -107,19 +55,20 @@
fuel-coroutines
${fuel.version}
+
+ nl.komponents.kovenant
+ kovenant
+ 3.3.0
+ pom
+
- 1.5.0
- 4.1.0
- 3.0.4
- 0.1.0
3.6.1
1.1.1
5.2.0
3.10.0
1.4.197
- 0.10.4
1.15.0
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/ktor/APIServer.kt b/core-kotlin/src/main/kotlin/com/baeldung/ktor/APIServer.kt
deleted file mode 100755
index a12182ccc8..0000000000
--- a/core-kotlin/src/main/kotlin/com/baeldung/ktor/APIServer.kt
+++ /dev/null
@@ -1,73 +0,0 @@
-@file:JvmName("APIServer")
-
-
-import io.ktor.application.call
-import io.ktor.application.install
-import io.ktor.features.CallLogging
-import io.ktor.features.ContentNegotiation
-import io.ktor.features.DefaultHeaders
-import io.ktor.gson.gson
-import io.ktor.request.path
-import io.ktor.request.receive
-import io.ktor.response.respond
-import io.ktor.routing.*
-import io.ktor.server.engine.embeddedServer
-import io.ktor.server.netty.Netty
-import org.slf4j.event.Level
-
-data class Author(val name: String, val website: String)
-data class ToDo(var id: Int, val name: String, val description: String, val completed: Boolean)
-
-fun main(args: Array) {
-
- val toDoList = ArrayList();
- val jsonResponse = """{
- "id": 1,
- "task": "Pay waterbill",
- "description": "Pay water bill today",
- }"""
-
-
- embeddedServer(Netty, 8080) {
- install(DefaultHeaders) {
- header("X-Developer", "Baeldung")
- }
- install(CallLogging) {
- level = Level.DEBUG
- filter { call -> call.request.path().startsWith("/todo") }
- filter { call -> call.request.path().startsWith("/author") }
- }
- install(ContentNegotiation) {
- gson {
- setPrettyPrinting()
- }
- }
- routing() {
- route("/todo") {
- post {
- var toDo = call.receive();
- toDo.id = toDoList.size;
- toDoList.add(toDo);
- call.respond("Added")
-
- }
- delete("/{id}") {
- call.respond(toDoList.removeAt(call.parameters["id"]!!.toInt()));
- }
- get("/{id}") {
-
- call.respond(toDoList[call.parameters["id"]!!.toInt()]);
- }
- get {
- call.respond(toDoList);
- }
- }
- get("/author"){
- call.respond(Author("Baeldung","baeldung.com"));
-
- }
-
-
- }
- }.start(wait = true)
-}
\ No newline at end of file
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesUnitTest.kt
similarity index 100%
rename from core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesTest.kt
rename to core-kotlin/src/test/kotlin/com/baeldung/kotlin/CoroutinesUnitTest.kt
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTest.kt
new file mode 100644
index 0000000000..469118f0f6
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTest.kt
@@ -0,0 +1,191 @@
+package com.baeldung.kotlin
+
+import nl.komponents.kovenant.*
+import nl.komponents.kovenant.Kovenant.deferred
+import nl.komponents.kovenant.combine.and
+import nl.komponents.kovenant.combine.combine
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import java.io.IOException
+import java.util.*
+import java.util.concurrent.TimeUnit
+
+class KovenantTest {
+ @Before
+ fun setupTestMode() {
+ Kovenant.testMode { error ->
+ println("An unexpected error occurred")
+ Assert.fail(error.message)
+ }
+ }
+
+ @Test
+ fun testSuccessfulDeferred() {
+ val def = deferred()
+ Assert.assertFalse(def.promise.isDone())
+
+ def.resolve(1L)
+ Assert.assertTrue(def.promise.isDone())
+ Assert.assertTrue(def.promise.isSuccess())
+ Assert.assertFalse(def.promise.isFailure())
+ }
+
+ @Test
+ fun testFailedDeferred() {
+ val def = deferred()
+ Assert.assertFalse(def.promise.isDone())
+
+ def.reject(RuntimeException())
+ Assert.assertTrue(def.promise.isDone())
+ Assert.assertFalse(def.promise.isSuccess())
+ Assert.assertTrue(def.promise.isFailure())
+ }
+
+ @Test
+ fun testResolveDeferredTwice() {
+ val def = deferred()
+ def.resolve(1L)
+ try {
+ def.resolve(1L)
+ } catch (e: AssertionError) {
+ // Expected.
+ // This is slightly unusual. The AssertionError comes from Assert.fail() from setupTestMode()
+ }
+ }
+
+ @Test
+ fun testSuccessfulTask() {
+ val promise = task { 1L }
+ Assert.assertTrue(promise.isDone())
+ Assert.assertTrue(promise.isSuccess())
+ Assert.assertFalse(promise.isFailure())
+ }
+
+ @Test
+ fun testFailedTask() {
+ val promise = task { throw RuntimeException() }
+ Assert.assertTrue(promise.isDone())
+ Assert.assertFalse(promise.isSuccess())
+ Assert.assertTrue(promise.isFailure())
+ }
+
+ @Test
+ fun testCallbacks() {
+ val promise = task { 1L }
+
+ promise.success {
+ println("This was a success")
+ Assert.assertEquals(1L, it)
+ }
+
+ promise.fail {
+ println(it)
+ Assert.fail("This shouldn't happen")
+ }
+
+ promise.always {
+ println("This always happens")
+ }
+ }
+
+ @Test
+ fun testGetValues() {
+ val promise = task { 1L }
+ Assert.assertEquals(1L, promise.get())
+ }
+
+ @Test
+ fun testAllSucceed() {
+ val numbers = all(
+ task { 1L },
+ task { 2L },
+ task { 3L }
+ )
+
+ Assert.assertEquals(listOf(1L, 2L, 3L), numbers.get())
+ }
+
+ @Test
+ fun testOneFails() {
+ val runtimeException = RuntimeException()
+
+ val numbers = all(
+ task { 1L },
+ task { 2L },
+ task { throw runtimeException }
+ )
+
+ Assert.assertEquals(runtimeException, numbers.getError())
+ }
+
+ @Test
+ fun testAnySucceeds() {
+ val promise = any(
+ task {
+ TimeUnit.SECONDS.sleep(3)
+ 1L
+ },
+ task {
+ TimeUnit.SECONDS.sleep(2)
+ 2L
+ },
+ task {
+ TimeUnit.SECONDS.sleep(1)
+ 3L
+ }
+ )
+
+ Assert.assertTrue(promise.isDone())
+ Assert.assertTrue(promise.isSuccess())
+ Assert.assertFalse(promise.isFailure())
+ }
+
+ @Test
+ fun testAllFails() {
+ val runtimeException = RuntimeException()
+ val ioException = IOException()
+ val illegalStateException = IllegalStateException()
+ val promise = any(
+ task {
+ TimeUnit.SECONDS.sleep(3)
+ throw runtimeException
+ },
+ task {
+ TimeUnit.SECONDS.sleep(2)
+ throw ioException
+ },
+ task {
+ TimeUnit.SECONDS.sleep(1)
+ throw illegalStateException
+ }
+ )
+
+ Assert.assertTrue(promise.isDone())
+ Assert.assertFalse(promise.isSuccess())
+ Assert.assertTrue(promise.isFailure())
+ }
+
+ @Test
+ fun testSimpleCombine() {
+ val promise = task { 1L } and task { "Hello" }
+ val result = promise.get()
+
+ Assert.assertEquals(1L, result.first)
+ Assert.assertEquals("Hello", result.second)
+ }
+
+ @Test
+ fun testLongerCombine() {
+ val promise = combine(
+ task { 1L },
+ task { "Hello" },
+ task { Currency.getInstance("USD") }
+ )
+ val result = promise.get()
+
+ Assert.assertEquals(1L, result.first)
+ Assert.assertEquals("Hello", result.second)
+ Assert.assertEquals(Currency.getInstance("USD"), result.third)
+ }
+}
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTimeoutTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTimeoutTest.kt
new file mode 100644
index 0000000000..e37d2cc2fa
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/KovenantTimeoutTest.kt
@@ -0,0 +1,38 @@
+package com.baeldung.kotlin
+
+import nl.komponents.kovenant.Promise
+import nl.komponents.kovenant.any
+import nl.komponents.kovenant.task
+import org.junit.Assert
+import org.junit.Ignore
+import org.junit.Test
+
+@Ignore
+// Note that this can not run in the same test run if KovenantTest has already been executed
+class KovenantTimeoutTest {
+ @Test
+ fun testTimeout() {
+ val promise = timedTask(1000) { "Hello" }
+ val result = promise.get()
+ Assert.assertEquals("Hello", result)
+ }
+
+ @Test
+ fun testTimeoutExpired() {
+ val promise = timedTask(1000) {
+ Thread.sleep(3000)
+ "Hello"
+ }
+ val result = promise.get()
+ Assert.assertNull(result)
+ }
+
+ fun timedTask(millis: Long, body: () -> T) : Promise> {
+ val timeoutTask = task {
+ Thread.sleep(millis)
+ null
+ }
+ val activeTask = task(body = body)
+ return any(activeTask, timeoutTask)
+ }
+}
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StringConcatenationTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StringConcatenationTest.kt
new file mode 100644
index 0000000000..9c371614a4
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StringConcatenationTest.kt
@@ -0,0 +1,48 @@
+package com.baeldung.kotlin
+
+import org.junit.Test
+import kotlin.test.assertEquals
+
+class StringConcatenationTest {
+
+ @Test
+ fun givenTwoStrings_concatenateWithTemplates_thenEquals() {
+ val a = "Hello"
+ val b = "Baeldung"
+ val c = "$a $b"
+
+ assertEquals("Hello Baeldung", c)
+ }
+
+ @Test
+ fun givenTwoStrings_concatenateWithPlusOperator_thenEquals() {
+ val a = "Hello"
+ val b = "Baeldung"
+ val c = a + " " + b
+
+ assertEquals("Hello Baeldung", c)
+ }
+
+ @Test
+ fun givenTwoStrings_concatenateWithStringBuilder_thenEquals() {
+ val a = "Hello"
+ val b = "Baeldung"
+
+ val builder = StringBuilder()
+ builder.append(a).append(" ").append(b)
+
+ val c = builder.toString()
+
+ assertEquals("Hello Baeldung", c)
+ }
+
+ @Test
+ fun givenTwoStrings_concatenateWithPlusMethod_thenEquals() {
+ val a = "Hello"
+ val b = "Baeldung"
+ val c = a.plus(" ").plus(b)
+
+ assertEquals("Hello Baeldung", c)
+ }
+
+}
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpUnitTest.kt
new file mode 100644
index 0000000000..436dc9e2ba
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/StructuralJumpUnitTest.kt
@@ -0,0 +1,121 @@
+package com.baeldung.kotlin
+
+import org.junit.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+
+class StructuralJumpUnitTest {
+
+ @Test
+ fun givenLoop_whenBreak_thenComplete() {
+ var value = ""
+ for (i in "hello_world") {
+ if (i == '_')
+ break
+ value += i.toString()
+ }
+ assertEquals("hello", value)
+ }
+ @Test
+ fun givenLoop_whenBreakWithLabel_thenComplete() {
+ var value = ""
+ outer_loop@ for (i in 'a'..'d') {
+ for (j in 1..3) {
+ value += "" + i + j
+ if (i == 'b' && j == 1)
+ break@outer_loop
+ }
+ }
+ assertEquals("a1a2a3b1", value)
+ }
+
+ @Test
+ fun givenLoop_whenContinue_thenComplete() {
+ var result = ""
+ for (i in "hello_world") {
+ if (i == '_')
+ continue
+ result += i
+ }
+ assertEquals("helloworld", result)
+ }
+ @Test
+ fun givenLoop_whenContinueWithLabel_thenComplete() {
+ var result = ""
+ outer_loop@ for (i in 'a'..'c') {
+ for (j in 1..3) {
+ if (i == 'b')
+ continue@outer_loop
+ result += "" + i + j
+ }
+ }
+ assertEquals("a1a2a3c1c2c3", result)
+ }
+
+ @Test
+ fun givenLambda_whenReturn_thenComplete() {
+ var result = returnInLambda();
+ assertEquals("hello", result)
+ }
+
+ private fun returnInLambda(): String {
+ var result = ""
+ "hello_world".forEach {
+ // non-local return directly to the caller
+ if (it == '_') return result
+ result += it.toString()
+ }
+ //this line won't be reached
+ return result;
+ }
+
+ @Test
+ fun givenLambda_whenReturnWithExplicitLabel_thenComplete() {
+ var result = ""
+ "hello_world".forEach lit@{
+ if (it == '_') {
+ // local return to the caller of the lambda, i.e. the forEach loop
+ return@lit
+ }
+ result += it.toString()
+ }
+ assertEquals("helloworld", result)
+ }
+
+ @Test
+ fun givenLambda_whenReturnWithImplicitLabel_thenComplete() {
+ var result = ""
+ "hello_world".forEach {
+ if (it == '_') {
+ // local return to the caller of the lambda, i.e. the forEach loop
+ return@forEach
+ }
+ result += it.toString()
+ }
+ assertEquals("helloworld", result)
+ }
+
+ @Test
+ fun givenAnonymousFunction_return_thenComplete() {
+ var result = ""
+ "hello_world".forEach(fun(element) {
+ // local return to the caller of the anonymous fun, i.e. the forEach loop
+ if (element == '_') return
+ result += element.toString()
+ })
+ assertEquals("helloworld", result)
+ }
+
+ @Test
+ fun givenAnonymousFunction_returnToLabel_thenComplete() {
+ var result = ""
+ run loop@{
+ "hello_world".forEach {
+ // non-local return from the lambda passed to run
+ if (it == '_') return@loop
+ result += it.toString()
+ }
+ }
+ assertEquals("hello", result)
+ }
+}
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt
new file mode 100644
index 0000000000..bdf44d3b49
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/gson/GsonUnitTest.kt
@@ -0,0 +1,30 @@
+package com.baeldung.kotlin.gson
+
+import com.google.gson.Gson
+
+import org.junit.Assert
+import org.junit.Test
+
+class GsonUnitTest {
+
+ var gson = Gson()
+
+ @Test
+ fun givenObject_thenGetJSONString() {
+ var jsonString = gson.toJson(TestModel(1,"Test"))
+ Assert.assertEquals(jsonString, "{\"id\":1,\"description\":\"Test\"}")
+ }
+
+ @Test
+ fun givenJSONString_thenGetObject() {
+ var jsonString = "{\"id\":1,\"description\":\"Test\"}";
+ var testModel = gson.fromJson(jsonString, TestModel::class.java)
+ Assert.assertEquals(testModel.id, 1)
+ Assert.assertEquals(testModel.description, "Test")
+ }
+
+ data class TestModel(
+ val id: Int,
+ val description: String
+ )
+}
\ No newline at end of file
diff --git a/disruptor/pom.xml b/disruptor/pom.xml
index d3cef3bd9b..c26dcc0cd4 100644
--- a/disruptor/pom.xml
+++ b/disruptor/pom.xml
@@ -36,22 +36,6 @@
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- copy-dependencies
- prepare-package
-
- copy-dependencies
-
-
- ${project.build.directory}/libs
-
-
-
-
org.apache.maven.plugins
maven-jar-plugin
diff --git a/ejb/ejb-remote/pom.xml b/ejb/ejb-remote/pom.xml
index fffbbdb1da..dac2fefb84 100755
--- a/ejb/ejb-remote/pom.xml
+++ b/ejb/ejb-remote/pom.xml
@@ -15,7 +15,6 @@
javax
javaee-api
- ${javaee-api.version}
provided
diff --git a/ejb/ejb-session-beans/pom.xml b/ejb/ejb-session-beans/pom.xml
index 14ab0790e7..da76169729 100644
--- a/ejb/ejb-session-beans/pom.xml
+++ b/ejb/ejb-session-beans/pom.xml
@@ -24,7 +24,6 @@
javax
javaee-api
- ${javaee-api.version}
provided
diff --git a/flyway-cdi-extension/README.md b/flyway-cdi-extension/README.md
new file mode 100644
index 0000000000..3e03d5aee8
--- /dev/null
+++ b/flyway-cdi-extension/README.md
@@ -0,0 +1,3 @@
+### Relevant articles
+
+- [CDI Portable Extension and Flyway](https://www.baeldung.com/cdi-portable-extension)
diff --git a/flyway-cdi-extension/pom.xml b/flyway-cdi-extension/pom.xml
new file mode 100644
index 0000000000..c6ee26f783
--- /dev/null
+++ b/flyway-cdi-extension/pom.xml
@@ -0,0 +1,51 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ flyway-cdi-extension
+ 1.0-SNAPSHOT
+
+
+ 1.8
+ 1.8
+
+
+
+
+ javax.enterprise
+ cdi-api
+ 2.0.SP1
+
+
+ org.jboss.weld.se
+ weld-se-core
+ 3.0.5.Final
+ runtime
+
+
+ org.flywaydb
+ flyway-core
+ 5.1.4
+
+
+ org.apache.tomcat
+ tomcat-jdbc
+ 8.5.33
+
+
+ javax.annotation
+ javax.annotation-api
+ 1.3.2
+
+
+ com.h2database
+ h2
+ 1.4.197
+ runtime
+
+
+
+
diff --git a/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java
new file mode 100644
index 0000000000..a5019b82c1
--- /dev/null
+++ b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayExtension.java
@@ -0,0 +1,74 @@
+package com.baeldung.cdi.extension;
+
+import org.apache.tomcat.jdbc.pool.DataSource;
+import org.flywaydb.core.Flyway;
+
+import javax.annotation.sql.DataSourceDefinition;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Any;
+import javax.enterprise.inject.Default;
+import javax.enterprise.inject.literal.InjectLiteral;
+import javax.enterprise.inject.spi.*;
+import javax.enterprise.util.AnnotationLiteral;
+
+
+/**
+ * Flyway is now under CDI container like:
+ *
+ * @ApplicationScoped
+ * @FlywayType public class Flyway{
+ * @Inject setDataSource(DataSource dataSource){
+ * //...
+ * }
+ * }
+ */
+
+public class FlywayExtension implements Extension {
+
+ DataSourceDefinition dataSourceDefinition = null;
+
+ public void registerFlywayType(@Observes BeforeBeanDiscovery bbdEvent) {
+ bbdEvent.addAnnotatedType(Flyway.class, Flyway.class.getName());
+ }
+
+ public void detectDataSourceDefinition(@Observes @WithAnnotations(DataSourceDefinition.class) ProcessAnnotatedType> patEvent) {
+ AnnotatedType at = patEvent.getAnnotatedType();
+ dataSourceDefinition = at.getAnnotation(DataSourceDefinition.class);
+ }
+
+ public void processAnnotatedType(@Observes ProcessAnnotatedType patEvent) {
+ patEvent.configureAnnotatedType()
+ //Add Scope
+ .add(ApplicationScoped.Literal.INSTANCE)
+ //Add Qualifier
+ .add(new AnnotationLiteral() {
+ })
+ //Decorate setDataSource(DataSource dataSource){} with @Inject
+ .filterMethods(annotatedMethod -> {
+ return annotatedMethod.getParameters().size() == 1 &&
+ annotatedMethod.getParameters().get(0).getBaseType().equals(javax.sql.DataSource.class);
+ })
+ .findFirst().get().add(InjectLiteral.INSTANCE);
+ }
+
+ void afterBeanDiscovery(@Observes AfterBeanDiscovery abdEvent, BeanManager bm) {
+ abdEvent.addBean()
+ .types(javax.sql.DataSource.class, DataSource.class)
+ .qualifiers(new AnnotationLiteral() {}, new AnnotationLiteral() {})
+ .scope(ApplicationScoped.class)
+ .name(DataSource.class.getName())
+ .beanClass(DataSource.class)
+ .createWith(creationalContext -> {
+ DataSource instance = new DataSource();
+ instance.setUrl(dataSourceDefinition.url());
+ instance.setDriverClassName(dataSourceDefinition.className());
+ return instance;
+ });
+ }
+
+ void runFlywayMigration(@Observes AfterDeploymentValidation adv, BeanManager manager) {
+ Flyway flyway = manager.createInstance().select(Flyway.class, new AnnotationLiteral() {}).get();
+ flyway.migrate();
+ }
+}
diff --git a/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayType.java b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayType.java
new file mode 100644
index 0000000000..7c3a5affa6
--- /dev/null
+++ b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/FlywayType.java
@@ -0,0 +1,14 @@
+package com.baeldung.cdi.extension;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({FIELD, METHOD, PARAMETER, TYPE})
+@Qualifier
+public @interface FlywayType {
+}
\ No newline at end of file
diff --git a/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/MainApp.java b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/MainApp.java
new file mode 100644
index 0000000000..1f6c5b43ba
--- /dev/null
+++ b/flyway-cdi-extension/src/main/java/com/baeldung/cdi/extension/MainApp.java
@@ -0,0 +1,16 @@
+package com.baeldung.cdi.extension;
+
+import javax.annotation.sql.DataSourceDefinition;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.se.SeContainer;
+import javax.enterprise.inject.se.SeContainerInitializer;
+
+@ApplicationScoped
+@DataSourceDefinition(name = "ds", className = "org.h2.Driver", url = "jdbc:h2:mem:testdb")
+public class MainApp {
+ public static void main(String[] args) {
+ SeContainerInitializer initializer = SeContainerInitializer.newInstance();
+ try (SeContainer container = initializer.initialize()) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/flyway-cdi-extension/src/main/resources/META-INF/beans.xml b/flyway-cdi-extension/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000000..44959bfa99
--- /dev/null
+++ b/flyway-cdi-extension/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/flyway-cdi-extension/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/flyway-cdi-extension/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000000..a82dc47714
--- /dev/null
+++ b/flyway-cdi-extension/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1,2 @@
+com.baeldung.cdi.extension.FlywayExtension
+
diff --git a/flyway-cdi-extension/src/main/resources/db/migration/V1__Create_person_table.sql b/flyway-cdi-extension/src/main/resources/db/migration/V1__Create_person_table.sql
new file mode 100644
index 0000000000..6bddc7689e
--- /dev/null
+++ b/flyway-cdi-extension/src/main/resources/db/migration/V1__Create_person_table.sql
@@ -0,0 +1,4 @@
+create table PERSON (
+ ID int not null,
+ NAME varchar(100) not null
+);
diff --git a/flyway-cdi-extension/src/main/resources/db/migration/V2__Add_people.sql b/flyway-cdi-extension/src/main/resources/db/migration/V2__Add_people.sql
new file mode 100644
index 0000000000..d8f1d62667
--- /dev/null
+++ b/flyway-cdi-extension/src/main/resources/db/migration/V2__Add_people.sql
@@ -0,0 +1,3 @@
+insert into PERSON (ID, NAME) values (1, 'Axel');
+insert into PERSON (ID, NAME) values (2, 'Mr. Foo');
+insert into PERSON (ID, NAME) values (3, 'Ms. Bar');
diff --git a/flyway/pom.xml b/flyway/pom.xml
index b1cc58af3d..353bbfb1ec 100644
--- a/flyway/pom.xml
+++ b/flyway/pom.xml
@@ -65,6 +65,7 @@
5.0.2
5.0.2
+ 1.4.195
diff --git a/flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationTest.java b/flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationUnitTest.java
similarity index 98%
rename from flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationTest.java
rename to flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationUnitTest.java
index 5e96fff64d..bf30ce604d 100644
--- a/flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationTest.java
+++ b/flyway/src/test/java/com/baeldung/flywaycallbacks/FlywayApplicationUnitTest.java
@@ -16,7 +16,7 @@ import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
@ContextConfiguration(classes = FlywayCallbackTestConfig.class)
-public class FlywayApplicationTest {
+public class FlywayApplicationUnitTest {
private Log log = LogFactory.getLog(getClass());
diff --git a/gson/README.md b/gson/README.md
index bedfbd206c..4122b21431 100644
--- a/gson/README.md
+++ b/gson/README.md
@@ -7,3 +7,4 @@
- [Gson Deserialization Cookbook](http://www.baeldung.com/gson-deserialization-guide)
- [Jackson vs Gson](http://www.baeldung.com/jackson-vs-gson)
- [Exclude Fields from Serialization in Gson](http://www.baeldung.com/gson-exclude-fields-serialization)
+- [Save Data to a JSON File with Gson](https://www.baeldung.com/gson-save-file)
diff --git a/gson/pom.xml b/gson/pom.xml
index 6e7779d26a..8222cb50e1 100644
--- a/gson/pom.xml
+++ b/gson/pom.xml
@@ -1,73 +1,73 @@
- 4.0.0
- com.baeldung
- gson
- 0.1-SNAPSHOT
- gson
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ 4.0.0
+ com.baeldung
+ gson
+ 0.1-SNAPSHOT
+ gson
-
- com.baeldung
- parent-java
- 0.0.1-SNAPSHOT
- ../parent-java
-
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../parent-java
+
-
-
-
- org.projectlombok
- lombok
- ${lombok.version}
- provided
-
-
- joda-time
- joda-time
- ${joda-time.version}
-
-
- commons-io
- commons-io
- ${commons-io.version}
-
-
- org.apache.commons
- commons-collections4
- ${commons-collections4.version}
-
-
- org.apache.commons
- commons-lang3
- ${commons-lang3.version}
-
-
-
- com.google.code.gson
- gson
- ${gson.version}
-
-
+
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
+
+ joda-time
+ joda-time
+ ${joda-time.version}
+
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+ org.apache.commons
+ commons-collections4
+ ${commons-collections4.version}
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
+
+
+ com.google.code.gson
+ gson
+ ${gson.version}
+
+
-
- gson
-
-
- src/main/resources
- true
-
-
-
+
+ gson
+
+
+ src/main/resources
+ true
+
+
+
-
-
- 2.8.0
-
- 3.5
- 4.1
- 2.9.6
+
+
+ 2.8.0
+
+ 3.5
+ 4.1
+ 2.9.6
1.16.10
-
+
\ No newline at end of file
diff --git a/gson/src/main/java/org/baeldung/gson/entities/Employee.java b/gson/src/main/java/org/baeldung/gson/entities/Employee.java
new file mode 100644
index 0000000000..cedcd6572e
--- /dev/null
+++ b/gson/src/main/java/org/baeldung/gson/entities/Employee.java
@@ -0,0 +1,36 @@
+package org.baeldung.gson.entities;
+
+public class Employee {
+ private int id;
+ private String name;
+ private String address;
+
+ public Employee(int id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+}
diff --git a/gson/src/main/java/org/baeldung/gson/serialization/HashMapDeserializer.java b/gson/src/main/java/org/baeldung/gson/serialization/HashMapDeserializer.java
new file mode 100644
index 0000000000..bb73e32559
--- /dev/null
+++ b/gson/src/main/java/org/baeldung/gson/serialization/HashMapDeserializer.java
@@ -0,0 +1,66 @@
+package org.baeldung.gson.serialization;
+
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.baeldung.gson.entities.Employee;
+
+import com.google.gson.*;
+
+public class HashMapDeserializer implements JsonDeserializer> {
+
+ @Override
+ public HashMap deserialize(JsonElement elem, Type type, JsonDeserializationContext context) throws JsonParseException {
+ HashMap map = new HashMap<>();
+ for (Map.Entry entry : elem.getAsJsonObject().entrySet()) {
+ JsonElement jsonValue = entry.getValue();
+ Object value = null;
+ if (jsonValue.isJsonPrimitive()) {
+ value = toPrimitive(jsonValue.getAsJsonPrimitive(), context);
+ } else {
+ value = context.deserialize(jsonValue, Employee.class);
+ }
+ map.put(entry.getKey(), value);
+ }
+ return map;
+
+ }
+
+ private Object toPrimitive(JsonPrimitive jsonValue, JsonDeserializationContext context) {
+ if (jsonValue.isBoolean())
+ return jsonValue.getAsBoolean();
+ else if (jsonValue.isString())
+ return jsonValue.getAsString();
+ else {
+ BigDecimal bigDec = jsonValue.getAsBigDecimal();
+ Long l;
+ Integer i;
+ if ((i = toInteger(bigDec)) != null) {
+ return i;
+ } else if ((l = toLong(bigDec)) != null) {
+ return l;
+ } else {
+ return bigDec.doubleValue();
+ }
+ }
+ }
+
+ private Long toLong(BigDecimal val) {
+ try {
+ return val.toBigIntegerExact().longValue();
+ } catch (ArithmeticException e) {
+ return null;
+ }
+ }
+
+ private Integer toInteger(BigDecimal val) {
+ try {
+ return val.intValueExact();
+ } catch (ArithmeticException e) {
+ return null;
+ }
+ }
+
+}
diff --git a/gson/src/main/resources/logback.xml b/gson/src/main/resources/logback.xml
index 56af2d397e..7bd5154680 100644
--- a/gson/src/main/resources/logback.xml
+++ b/gson/src/main/resources/logback.xml
@@ -7,13 +7,13 @@
-
-
+
+
-
+
-
+
\ No newline at end of file
diff --git a/gson/src/test/java/org/baeldung/gson/deserialization/HashMapDeserializationUnitTest.java b/gson/src/test/java/org/baeldung/gson/deserialization/HashMapDeserializationUnitTest.java
new file mode 100644
index 0000000000..6905ade0da
--- /dev/null
+++ b/gson/src/test/java/org/baeldung/gson/deserialization/HashMapDeserializationUnitTest.java
@@ -0,0 +1,86 @@
+package org.baeldung.gson.deserialization;
+
+import java.lang.reflect.Type;
+import java.util.HashMap;
+
+import org.baeldung.gson.entities.Employee;
+import org.baeldung.gson.serialization.HashMapDeserializer;
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.internal.LinkedTreeMap;
+import com.google.gson.reflect.TypeToken;
+
+public class HashMapDeserializationUnitTest {
+
+ private static final Logger logger = LoggerFactory.getLogger(HashMapDeserializationUnitTest.class);
+
+ @Test
+ public void whenUsingHashMapClass_thenShouldReturnMapWithDefaultClasses() {
+
+ String jsonString = "{'employee.name':'Bob','employee.salary':10000, 'employee.active':true, "
+ + "'employee':{'id':10, 'name': 'Bob Willis', 'address':'London'}}";
+
+ Gson gson = new Gson();
+ HashMap map = gson.fromJson(jsonString, HashMap.class);
+
+ logger.info("The converted map: {}", map);
+ Assert.assertEquals(4, map.size());
+ Assert.assertEquals(Double.class, map.get("employee.salary").getClass());
+ Assert.assertEquals(LinkedTreeMap.class, map.get("employee").getClass());
+
+ }
+
+ @Test(expected = JsonSyntaxException.class)
+ public void whenUsingJsonStringWithDuplicateKey_thenShouldThrowJsonSyntaxException() {
+
+ String jsonString = "{'employee.name':'Bob', 'employee.name':'Jenny','employee.salary':10000, "
+ + "'employee.active':true, " + "'employee':{'id':10, 'name': 'Bob Willis', 'address':'London'}}";
+
+ Gson gson = new Gson();
+ HashMap map = gson.fromJson(jsonString, HashMap.class);
+
+ logger.info("The converted map: {}", map);
+ }
+
+ @Test
+ public void whenUsingTypeToken_thenShouldReturnMapWithProperClass() {
+
+ String jsonString = "{'Bob':{'id':10, 'name': 'Bob Willis', 'address':'UK'},"
+ + "'Jenny':{'id':10, 'name': 'Jenny McCarthy', 'address':'USA'}, "
+ + "'Steve':{'id':10, 'name': 'Steven Waugh', 'address':'Australia'}}";
+
+ Gson gson = new Gson();
+ Type empMapType = new TypeToken>(){}.getType();
+ HashMap nameEmployeeMap = gson.fromJson(jsonString, empMapType);
+
+ logger.info("The converted map: {}", nameEmployeeMap);
+ Assert.assertEquals(3, nameEmployeeMap.size());
+ Assert.assertEquals(Employee.class, nameEmployeeMap.get("Bob").getClass());
+ }
+
+ @Test
+ public void whenUsingCustomDeserializer_thenShouldReturnMapWithProperClass() {
+
+ String jsonString = "{'employee.name':'Bob','employee.salary':10000, 'employee.active':true, "
+ + "'employee':{'id':10, 'name': 'Bob Willis', 'address':'London'}}";
+
+ Type type = new TypeToken>(){}.getType();
+ Gson gson = new GsonBuilder()
+ .registerTypeAdapter(type, new HashMapDeserializer())
+ .create();
+ HashMap blendedMap = gson.fromJson(jsonString, type);
+
+ logger.info("The converted map: {}", blendedMap);
+ Assert.assertEquals(4, blendedMap.size());
+ Assert.assertEquals(Integer.class, blendedMap.get("employee.salary").getClass());
+ Assert.assertEquals(Employee.class, blendedMap.get("employee").getClass());
+
+ }
+
+}
diff --git a/gson/src/test/resources/logback-test.xml b/gson/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..7bd5154680
--- /dev/null
+++ b/gson/src/test/resources/logback-test.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/guava/README.md b/guava/README.md
index bb4e225649..fe1a347d72 100644
--- a/guava/README.md
+++ b/guava/README.md
@@ -33,3 +33,4 @@
- [Using Guava CountingOutputStream](http://www.baeldung.com/guava-counting-outputstream)
- [Hamcrest Text Matchers](http://www.baeldung.com/hamcrest-text-matchers)
- [Quick Guide to the Guava RateLimiter](http://www.baeldung.com/guava-rate-limiter)
+- [Initialize a HashMap in Java](https://www.baeldung.com/java-initialize-hashmap)
diff --git a/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java b/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceUnitTest.java
similarity index 98%
rename from guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java
rename to guest/log4j2-example/src/test/java/com/stackify/services/MyServiceUnitTest.java
index 49e367e45b..bd08225be4 100644
--- a/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceTest.java
+++ b/guest/log4j2-example/src/test/java/com/stackify/services/MyServiceUnitTest.java
@@ -18,9 +18,9 @@ import org.junit.Test;
import com.stackify.models.User;
import com.stackify.services.MyService;
-public class MyServiceTest {
+public class MyServiceUnitTest {
- private static final Logger logger = LogManager.getLogger(MyServiceTest.class);
+ private static final Logger logger = LogManager.getLogger(MyServiceUnitTest.class);
@Test
public void testService() {
diff --git a/guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceTest.java b/guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceUnitTest.java
similarity index 98%
rename from guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceTest.java
rename to guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceUnitTest.java
index 187b27e1df..a3051f7087 100644
--- a/guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceTest.java
+++ b/guest/logback-example/src/test/java/com/stackify/services/EmployeeServiceUnitTest.java
@@ -9,7 +9,7 @@ import com.stackify.models.Employee;
import ch.qos.logback.classic.Level;
-public class EmployeeServiceTest {
+public class EmployeeServiceUnitTest {
private static final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
private EmployeeService employeeService = new EmployeeService();
diff --git a/guest/spring-mvc/pom.xml b/guest/spring-mvc/pom.xml
index 42543b5be0..c0ef451605 100644
--- a/guest/spring-mvc/pom.xml
+++ b/guest/spring-mvc/pom.xml
@@ -12,7 +12,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.M5
+ 2.0.0.RELEASE
diff --git a/guest/spring-security/pom.xml b/guest/spring-security/pom.xml
index baca3bce85..8be42ba32b 100644
--- a/guest/spring-security/pom.xml
+++ b/guest/spring-security/pom.xml
@@ -11,7 +11,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.0.0.M6
+ 2.0.0.RELEASE
diff --git a/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceTest.java b/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceLiveTest.java
similarity index 95%
rename from guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceTest.java
rename to guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceLiveTest.java
index 064951fbbe..be3992b7f7 100644
--- a/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceTest.java
+++ b/guest/webservices/rest-server/src/test/java/com/stackify/services/UserServiceLiveTest.java
@@ -6,7 +6,7 @@ import io.restassured.RestAssured;
import static io.restassured.RestAssured.*;
import static org.hamcrest.CoreMatchers.*;
-public class UserServiceTest {
+public class UserServiceLiveTest {
@Test
public void whenAddUser_thenGetUserOk() {
RestAssured.baseURI = "http://localhost:8080/rest-server";
diff --git a/hazelcast/README.md b/hazelcast/README.md
index b90f66a8d0..7adb13f2af 100644
--- a/hazelcast/README.md
+++ b/hazelcast/README.md
@@ -1,2 +1,3 @@
### Relevant Articles:
- [Guide to Hazelcast with Java](http://www.baeldung.com/java-hazelcast)
+- [Introduction to Hazelcast Jet](https://www.baeldung.com/hazelcast-jet)
diff --git a/hibernate5/README.md b/hibernate5/README.md
index 1bce52bd5e..b90f885c78 100644
--- a/hibernate5/README.md
+++ b/hibernate5/README.md
@@ -13,3 +13,6 @@
- [Pessimistic Locking in JPA](http://www.baeldung.com/jpa-pessimistic-locking)
- [Bootstrapping JPA Programmatically in Java](http://www.baeldung.com/java-bootstrap-jpa)
- [Optimistic Locking in JPA](http://www.baeldung.com/jpa-optimistic-locking)
+- [Hibernate Entity Lifecycle](https://www.baeldung.com/hibernate-entity-lifecycle)
+- [Mapping A Hibernate Query to a Custom Class](https://www.baeldung.com/hibernate-query-to-custom-class)
+- [@JoinColumn Annotation Explained](https://www.baeldung.com/jpa-join-column)
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java
index 23d7d2e201..2212e736ab 100644
--- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java
@@ -1,5 +1,11 @@
package com.baeldung.hibernate;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Properties;
+
+import com.baeldung.hibernate.entities.DeptEmployee;
import com.baeldung.hibernate.optimisticlocking.OptimisticLockingCourse;
import com.baeldung.hibernate.optimisticlocking.OptimisticLockingStudent;
import com.baeldung.hibernate.pessimisticlocking.Individual;
@@ -16,10 +22,30 @@ 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;
+import com.baeldung.hibernate.pojo.Course;
+import com.baeldung.hibernate.pojo.Employee;
+import com.baeldung.hibernate.pojo.EntityDescription;
+import com.baeldung.hibernate.pojo.OrderEntry;
+import com.baeldung.hibernate.pojo.OrderEntryIdClass;
+import com.baeldung.hibernate.pojo.OrderEntryPK;
+import com.baeldung.hibernate.pojo.Person;
+import com.baeldung.hibernate.pojo.Phone;
+import com.baeldung.hibernate.pojo.PointEntity;
+import com.baeldung.hibernate.pojo.PolygonEntity;
+import com.baeldung.hibernate.pojo.Product;
+import com.baeldung.hibernate.pojo.Student;
+import com.baeldung.hibernate.pojo.TemporalValues;
+import com.baeldung.hibernate.pojo.User;
+import com.baeldung.hibernate.pojo.UserProfile;
+import com.baeldung.hibernate.pojo.inheritance.Animal;
+import com.baeldung.hibernate.pojo.inheritance.Bag;
+import com.baeldung.hibernate.pojo.inheritance.Book;
+import com.baeldung.hibernate.pojo.inheritance.Car;
+import com.baeldung.hibernate.pojo.inheritance.MyEmployee;
+import com.baeldung.hibernate.pojo.inheritance.MyProduct;
+import com.baeldung.hibernate.pojo.inheritance.Pen;
+import com.baeldung.hibernate.pojo.inheritance.Pet;
+import com.baeldung.hibernate.pojo.inheritance.Vehicle;
public class HibernateUtil {
private static SessionFactory sessionFactory;
@@ -72,6 +98,8 @@ public class HibernateUtil {
metadataSources.addAnnotatedClass(PessimisticLockingCourse.class);
metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Customer.class);
metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Address.class);
+ metadataSources.addAnnotatedClass(DeptEmployee.class);
+ metadataSources.addAnnotatedClass(com.baeldung.hibernate.entities.Department.class);
metadataSources.addAnnotatedClass(OptimisticLockingCourse.class);
metadataSources.addAnnotatedClass(OptimisticLockingStudent.class);
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/entities/Department.java b/hibernate5/src/main/java/com/baeldung/hibernate/entities/Department.java
new file mode 100644
index 0000000000..ff94f4f849
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/entities/Department.java
@@ -0,0 +1,45 @@
+package com.baeldung.hibernate.entities;
+
+import java.util.List;
+
+import javax.persistence.*;
+
+@Entity
+public class Department {
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private long id;
+
+ private String name;
+
+ @OneToMany(mappedBy="department")
+ private List employees;
+
+ public Department(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getEmployees() {
+ return employees;
+ }
+
+ public void setEmployees(List employees) {
+ this.employees = employees;
+ }
+}
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java b/hibernate5/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java
new file mode 100644
index 0000000000..7a51009b62
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/entities/DeptEmployee.java
@@ -0,0 +1,65 @@
+package com.baeldung.hibernate.entities;
+
+import javax.persistence.*;
+
+@Entity
+public class DeptEmployee {
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private long id;
+
+ private String employeeNumber;
+
+ private String designation;
+
+ private String name;
+
+ @ManyToOne
+ private Department department;
+
+ public DeptEmployee(String name, String employeeNumber, Department department) {
+ this.name = name;
+ this.employeeNumber = employeeNumber;
+ this.department = department;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getEmployeeNumber() {
+ return employeeNumber;
+ }
+
+ public void setEmployeeNumber(String employeeNumber) {
+ this.employeeNumber = employeeNumber;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Department getDepartment() {
+ return department;
+ }
+
+ public void setDepartment(Department department) {
+ this.department = department;
+ }
+
+ public String getDesignation() {
+ return designation;
+ }
+
+ public void setDesignation(String designation) {
+ this.designation = designation;
+ }
+}
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java
new file mode 100644
index 0000000000..74bcb9e411
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/CustomPhysicalNamingStrategy.java
@@ -0,0 +1,47 @@
+package com.baeldung.hibernate.namingstrategy;
+
+import org.hibernate.boot.model.naming.Identifier;
+import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
+import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
+
+public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy {
+
+ @Override
+ public Identifier toPhysicalCatalogName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
+ return convertToSnakeCase(identifier);
+ }
+
+ @Override
+ public Identifier toPhysicalColumnName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
+ return convertToSnakeCase(identifier);
+ }
+
+ @Override
+ public Identifier toPhysicalSchemaName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
+ return convertToSnakeCase(identifier);
+ }
+
+ @Override
+ public Identifier toPhysicalSequenceName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
+ return convertToSnakeCase(identifier);
+ }
+
+ @Override
+ public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
+ return convertToSnakeCase(identifier);
+ }
+
+ private Identifier convertToSnakeCase(final Identifier identifier) {
+ if (identifier == null) {
+ return identifier;
+ }
+
+ final String regex = "([a-z])([A-Z])";
+ final String replacement = "$1_$2";
+ final String newName = identifier.getText()
+ .replaceAll(regex, replacement)
+ .toLowerCase();
+ return Identifier.toIdentifier(newName);
+ }
+
+}
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java
new file mode 100644
index 0000000000..b3fb3b32b6
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/namingstrategy/Customer.java
@@ -0,0 +1,56 @@
+package com.baeldung.hibernate.namingstrategy;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "Customers")
+public class Customer {
+
+ @Id
+ @GeneratedValue
+ private Long id;
+
+ private String firstName;
+
+ private String lastName;
+
+ @Column(name = "email")
+ private String emailAddress;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getEmailAddress() {
+ return emailAddress;
+ }
+
+ public void setEmailAddress(String emailAddress) {
+ this.emailAddress = emailAddress;
+ }
+
+}
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Result.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Result.java
new file mode 100644
index 0000000000..607269a267
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/Result.java
@@ -0,0 +1,31 @@
+package com.baeldung.hibernate.pojo;
+
+public class Result {
+ private String employeeName;
+
+ private String departmentName;
+
+ public Result(String employeeName, String departmentName) {
+ this.employeeName = employeeName;
+ this.departmentName = departmentName;
+ }
+
+ public Result() {
+ }
+
+ public String getEmployeeName() {
+ return employeeName;
+ }
+
+ public void setEmployeeName(String employeeName) {
+ this.employeeName = employeeName;
+ }
+
+ public String getDepartmentName() {
+ return departmentName;
+ }
+
+ public void setDepartmentName(String departmentName) {
+ this.departmentName = departmentName;
+ }
+}
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java
index 90203d29ec..ccbdf80bf1 100644
--- a/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/pojo/User.java
@@ -4,13 +4,23 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
-import javax.persistence.SequenceGenerator;
+
+import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Parameter;
@Entity
public class User {
@Id
- @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence-generator")
- @SequenceGenerator(name = "sequence-generator", sequenceName = "user_sequence", initialValue = 4)
+ @GeneratedValue(generator = "sequence-generator")
+ @GenericGenerator(
+ name = "sequence-generator",
+ strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
+ parameters = {
+ @Parameter(name = "sequence_name", value = "user_sequence"),
+ @Parameter(name = "initial_value", value = "4"),
+ @Parameter(name = "increment_size", value = "1")
+ }
+ )
private long userId;
public long getUserId() {
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Company.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Company.java
new file mode 100644
index 0000000000..f146a8674e
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Company.java
@@ -0,0 +1,62 @@
+package com.baeldung.hibernate.proxy;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+@Entity
+public class Company implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private Long id;
+
+ @Column(name = "name")
+ private String name;
+
+ @OneToMany
+ @JoinColumn(name = "workplace_id")
+ private Set employees = new HashSet<>();
+
+ public Company() { }
+
+ public Company(String name) {
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Set getEmployees() {
+ return this.employees;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Company company = (Company) o;
+ return Objects.equals(id, company.id) &&
+ Objects.equals(name, company.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name);
+ }
+}
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java
new file mode 100644
index 0000000000..4bc0b8f25c
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java
@@ -0,0 +1,69 @@
+package com.baeldung.hibernate.proxy;
+
+import org.hibernate.annotations.BatchSize;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Objects;
+
+@Entity
+@BatchSize(size = 5)
+public class Employee implements Serializable {
+
+ @Id
+ @GeneratedValue (strategy = GenerationType.SEQUENCE)
+ private Long id;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "workplace_id")
+ private Company workplace;
+
+ @Column(name = "first_name")
+ private String firstName;
+
+ public Employee() { }
+
+ public Employee(Company workplace, String firstName) {
+ this.workplace = workplace;
+ this.firstName = firstName;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Company getWorkplace() {
+ return workplace;
+ }
+
+ public void setWorkplace(Company workplace) {
+ this.workplace = workplace;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Employee employee = (Employee) o;
+ return Objects.equals(id, employee.id) &&
+ Objects.equals(workplace, employee.workplace) &&
+ Objects.equals(firstName, employee.firstName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, workplace, firstName);
+ }
+}
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/HibernateUtil.java
new file mode 100644
index 0000000000..37c083049f
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/HibernateUtil.java
@@ -0,0 +1,57 @@
+package com.baeldung.hibernate.proxy;
+
+import org.apache.commons.lang3.StringUtils;
+import org.hibernate.SessionFactory;
+import org.hibernate.boot.Metadata;
+import org.hibernate.boot.MetadataSources;
+import org.hibernate.boot.SessionFactoryBuilder;
+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 {
+
+ private static SessionFactory sessionFactory;
+ private static String PROPERTY_FILE_NAME;
+
+ public static SessionFactory getSessionFactory(String propertyFileName) throws IOException {
+ PROPERTY_FILE_NAME = propertyFileName;
+ if (sessionFactory == null) {
+ ServiceRegistry serviceRegistry = configureServiceRegistry();
+ sessionFactory = getSessionFactoryBuilder(serviceRegistry).build();
+ }
+ return sessionFactory;
+ }
+
+ private static SessionFactoryBuilder getSessionFactoryBuilder(ServiceRegistry serviceRegistry) {
+ MetadataSources metadataSources = new MetadataSources(serviceRegistry);
+ metadataSources.addPackage("com.baeldung.hibernate.proxy");
+ metadataSources.addAnnotatedClass(Company.class);
+ metadataSources.addAnnotatedClass(Employee.class);
+
+ Metadata metadata = metadataSources.buildMetadata();
+ return metadata.getSessionFactoryBuilder();
+
+ }
+
+ 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(StringUtils.defaultString(PROPERTY_FILE_NAME, "hibernate.properties"));
+ try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) {
+ properties.load(inputStream);
+ }
+ return properties;
+ }
+}
diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java
new file mode 100644
index 0000000000..29ae55b773
--- /dev/null
+++ b/hibernate5/src/test/java/com/baeldung/hibernate/CustomClassIntegrationTest.java
@@ -0,0 +1,77 @@
+package com.baeldung.hibernate;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.baeldung.hibernate.entities.DeptEmployee;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.query.Query;
+import org.hibernate.transform.Transformers;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import com.baeldung.hibernate.entities.Department;
+import com.baeldung.hibernate.pojo.Result;
+
+public class CustomClassIntegrationTest {
+
+ private Session session;
+
+ private Transaction transaction;
+
+ @BeforeEach
+ public void setUp() throws IOException {
+ session = HibernateUtil.getSessionFactory().openSession();
+ transaction = session.beginTransaction();
+ session.createNativeQuery("delete from manager").executeUpdate();
+ session.createNativeQuery("delete from department").executeUpdate();
+ Department department = new Department("Sales");
+ DeptEmployee employee = new DeptEmployee("John Smith", "001", department);
+ session.persist(department);
+ session.persist(employee);
+ transaction.commit();
+ transaction = session.beginTransaction();
+ }
+
+ @Test
+ public void whenAllManagersAreSelected_ThenObjectGraphIsReturned() {
+ Query query = session.createQuery("from com.baeldung.hibernate.entities.DeptEmployee");
+ List deptEmployees = query.list();
+ DeptEmployee deptEmployee = deptEmployees.get(0);
+ assertEquals("John Smith", deptEmployee.getName());
+ assertEquals("Sales", deptEmployee.getDepartment().getName());
+ }
+
+ @Test
+ public void whenIndividualPropertiesAreSelected_ThenObjectArrayIsReturned() {
+ Query query = session.createQuery("select m.name, m.department.name from com.baeldung.hibernate.entities.DeptEmployee m");
+ List managers = query.list();
+ Object[] manager = (Object[]) managers.get(0);
+ assertEquals("John Smith", manager[0]);
+ assertEquals("Sales", manager[1]);
+ }
+
+ @Test
+ public void whenResultConstructorInSelect_ThenListOfResultIsReturned() {
+ Query query = session.createQuery("select new com.baeldung.hibernate.pojo.Result(m.name, m.department.name) "
+ + "from DeptEmployee m");
+ List results = query.list();
+ Result result = results.get(0);
+ assertEquals("John Smith", result.getEmployeeName());
+ assertEquals("Sales", result.getDepartmentName());
+ }
+
+ @Test
+ public void whenResultTransformerOnQuery_ThenListOfResultIsReturned() {
+ Query query = session.createQuery("select m.name as employeeName, m.department.name as departmentName "
+ + "from com.baeldung.hibernate.entities.DeptEmployee m");
+ query.setResultTransformer(Transformers.aliasToBean(Result.class));
+ List results = query.list();
+ Result result = results.get(0);
+ assertEquals("John Smith", result.getEmployeeName());
+ assertEquals("Sales", result.getDepartmentName());
+ }
+}
diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java
new file mode 100644
index 0000000000..0d6aed3370
--- /dev/null
+++ b/hibernate5/src/test/java/com/baeldung/hibernate/namingstrategy/NamingStrategyLiveTest.java
@@ -0,0 +1,75 @@
+package com.baeldung.hibernate.namingstrategy;
+
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.boot.MetadataSources;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.service.ServiceRegistry;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class NamingStrategyLiveTest {
+
+ private Session session;
+
+ @Before
+ public void init() {
+ try {
+ Configuration configuration = new Configuration();
+
+ Properties properties = new Properties();
+ properties.load(Thread.currentThread()
+ .getContextClassLoader()
+ .getResourceAsStream("hibernate-namingstrategy.properties"));
+
+ configuration.setProperties(properties);
+
+ ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties())
+ .build();
+ MetadataSources metadataSources = new MetadataSources(serviceRegistry);
+ metadataSources.addAnnotatedClass(Customer.class);
+
+ SessionFactory factory = metadataSources.buildMetadata()
+ .buildSessionFactory();
+
+ session = factory.openSession();
+ } catch (HibernateException | IOException e) {
+ fail("Failed to initiate Hibernate Session [Exception:" + e.toString() + "]");
+ }
+ }
+
+ @After
+ public void close() {
+ if (session != null)
+ session.close();
+ }
+
+ @Test
+ public void testCustomPhysicalNamingStrategy() {
+
+ Customer customer = new Customer();
+ customer.setFirstName("first name");
+ customer.setLastName("last name");
+ customer.setEmailAddress("customer@example.com");
+
+ session.beginTransaction();
+
+ Long id = (Long) session.save(customer);
+
+ session.flush();
+ session.clear();
+
+ Object[] result = (Object[]) session.createNativeQuery("select c.first_name, c.last_name, c.email from customers c where c.id = :id")
+ .setParameter("id", id)
+ .getSingleResult();
+
+ }
+}
diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java
new file mode 100644
index 0000000000..0a4caf032b
--- /dev/null
+++ b/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java
@@ -0,0 +1,156 @@
+package com.baeldung.hibernate.proxy;
+
+import org.hibernate.*;
+import org.hibernate.proxy.HibernateProxy;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import static org.junit.Assert.fail;
+
+public class HibernateProxyUnitTest {
+
+ private SessionFactory factory;
+
+ private Session session;
+
+ private Company workplace;
+
+ private Employee albert;
+
+ private Employee bob;
+
+ private Employee charlotte;
+
+ @Before
+ public void init(){
+ try {
+ factory = HibernateUtil.getSessionFactory("hibernate.properties");
+ session = factory.openSession();
+ } catch (HibernateException | IOException e) {
+ fail("Failed to initiate Hibernate Session [Exception:" + e.toString() + "]");
+ }
+ }
+
+ @After
+ public void close(){
+ if(session != null) {
+ session.close();
+ }
+ }
+
+ @Test
+ public void givenAnInexistentEmployeeId_whenUseGetMethod_thenReturnNull() {
+ Employee employee = session.get(Employee.class, 14L);
+ assertNull(employee);
+ }
+
+ @Test(expected = ObjectNotFoundException.class)
+ public void givenAnNonExistentEmployeeId_whenUseLoadMethod_thenThrowObjectNotFoundException() {
+ Employee employee = session.load(Employee.class, 999L);
+ assertNotNull(employee);
+ employee.getFirstName();
+ }
+
+ @Test
+ public void givenAnNonExistentEmployeeId_whenUseLoadMethod_thenReturnAProxy() {
+ Employee employee = session.load(Employee.class, 14L);
+ assertNotNull(employee);
+ assertTrue(employee instanceof HibernateProxy);
+ }
+
+ @Test
+ public void givenAnEmployeeFromACompany_whenUseLoadMethod_thenCompanyIsAProxy() {
+ Transaction tx = session.beginTransaction();
+
+ this.workplace = new Company("Bizco");
+ session.save(workplace);
+
+ this.albert = new Employee(workplace, "Albert");
+ session.save(albert);
+
+ session.flush();
+ session.clear();
+
+ tx.commit();
+ this.session = factory.openSession();
+
+ Employee proxyAlbert = session.load(Employee.class, albert.getId());
+ assertTrue(proxyAlbert instanceof HibernateProxy);
+
+ // with many-to-one lazy-loading, associations remain proxies
+ assertTrue(proxyAlbert.getWorkplace() instanceof HibernateProxy);
+ }
+
+ @Test
+ public void givenACompanyWithEmployees_whenUseLoadMethod_thenEmployeesAreProxies() {
+ Transaction tx = session.beginTransaction();
+
+ this.workplace = new Company("Bizco");
+ session.save(workplace);
+
+ this.albert = new Employee(workplace, "Albert");
+ session.save(albert);
+
+ session.flush();
+ session.clear();
+
+ tx.commit();
+ this.session = factory.openSession();
+
+ Company proxyBizco = session.load(Company.class, workplace.getId());
+ assertTrue(proxyBizco instanceof HibernateProxy);
+
+ // with one-to-many, associations aren't proxies
+ assertFalse(proxyBizco.getEmployees().iterator().next() instanceof HibernateProxy);
+ }
+
+ @Test
+ public void givenThreeEmployees_whenLoadThemWithBatch_thenReturnAllOfThemWithOneQuery() {
+ Transaction tx = session.beginTransaction();
+
+ //We are saving 3 entities with one flush
+
+ this.workplace = new Company("Bizco");
+ session.save(workplace);
+
+ this.albert = new Employee(workplace, "Albert");
+ session.save(albert);
+
+ this.bob = new Employee(workplace, "Bob");
+ session.save(bob);
+
+ this.charlotte = new Employee(workplace, "Charlotte");
+ session.save(charlotte);
+
+ session.flush();
+ session.clear();
+
+ tx.commit();
+ session = factory.openSession();
+
+ Employee proxyAlbert = session.load(Employee.class, this.albert.getId());
+ assertNotNull(proxyAlbert);
+ assertTrue(proxyAlbert instanceof HibernateProxy);
+
+ Employee proxyBob = session.load(Employee.class, this.bob.getId());
+ assertNotNull(proxyBob);
+ assertTrue(proxyBob instanceof HibernateProxy);
+
+ Employee proxyCharlotte = session.load(Employee.class, this.charlotte.getId());
+ assertNotNull(proxyCharlotte);
+ assertTrue(proxyCharlotte instanceof HibernateProxy);
+
+ //Fetching from database 3 entities with one call
+ //Select from log: where employee0_.id in (?, ?, ?)
+ proxyAlbert.getFirstName();
+
+ assertEquals(proxyAlbert, this.albert);
+ assertEquals(proxyBob, this.bob);
+ assertEquals(proxyCharlotte, this.charlotte);
+ }
+}
diff --git a/hibernate5/src/test/resources/hibernate-namingstrategy.properties b/hibernate5/src/test/resources/hibernate-namingstrategy.properties
new file mode 100644
index 0000000000..f75a35bdfe
--- /dev/null
+++ b/hibernate5/src/test/resources/hibernate-namingstrategy.properties
@@ -0,0 +1,10 @@
+hibernate.connection.driver_class=org.h2.Driver
+hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1
+hibernate.connection.username=sa
+hibernate.dialect=org.hibernate.dialect.H2Dialect
+
+hibernate.show_sql=true
+hibernate.hbm2ddl.auto=create-drop
+
+hibernate.physical_naming_strategy=com.baeldung.hibernate.namingstrategy.CustomPhysicalNamingStrategy
+hibernate.implicit_naming_strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
\ No newline at end of file
diff --git a/intelliJ/README.md b/intelliJ/README.md
new file mode 100644
index 0000000000..d45bd0cee5
--- /dev/null
+++ b/intelliJ/README.md
@@ -0,0 +1,3 @@
+### Relevant Articles:
+
+- [Writing IntelliJ IDEA Plugins](https://www.baeldung.com/intellij-new-custom-plugin)
diff --git a/jackson/pom.xml b/jackson/pom.xml
index 9592e11961..e941ababc5 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -118,7 +118,7 @@
- 2.9.6
+ 2.9.7
3.8
2.10
diff --git a/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java
new file mode 100644
index 0000000000..19dabb30b0
--- /dev/null
+++ b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Color.java
@@ -0,0 +1,5 @@
+package com.baeldung.jackson.xmlToJson;
+
+public enum Color {
+ PINK, BLUE, YELLOW, RED;
+}
diff --git a/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java
new file mode 100644
index 0000000000..0b1ee1b16a
--- /dev/null
+++ b/jackson/src/main/java/com/baeldung/jackson/xmlToJson/Flower.java
@@ -0,0 +1,42 @@
+package com.baeldung.jackson.xmlToJson;
+
+public class Flower {
+
+ private String name;
+
+ private Color color;
+
+ private Integer petals;
+
+ public Flower() { }
+
+ public Flower(String name, Color color, Integer petals) {
+ this.name = name;
+ this.color = color;
+ this.petals = petals;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+ public void setColor(Color color) {
+ this.color = color;
+ }
+
+ public Integer getPetals() {
+ return petals;
+ }
+
+ public void setPetals(Integer petals) {
+ this.petals = petals;
+ }
+}
diff --git a/jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java b/jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java
new file mode 100644
index 0000000000..295bb9d6e8
--- /dev/null
+++ b/jackson/src/test/java/com/baeldung/jackson/xmlToJson/XmlToJsonUnitTest.java
@@ -0,0 +1,56 @@
+package com.baeldung.jackson.xmlToJson;
+
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+public class XmlToJsonUnitTest {
+
+ @Test
+ public void givenAnXML_whenUseDataBidingToConvertToJSON_thenReturnDataOK() {
+ String flowerXML = "PoppyRED9";
+
+ try {
+ XmlMapper xmlMapper = new XmlMapper();
+ Flower poppy = xmlMapper.readValue(flowerXML, Flower.class);
+
+ assertEquals(poppy.getName(), "Poppy");
+ assertEquals(poppy.getColor(), Color.RED);
+ assertEquals(poppy.getPetals(), new Integer(9));
+
+ ObjectMapper mapper = new ObjectMapper();
+ String json = mapper.writeValueAsString(poppy);
+
+ assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":9}");
+ System.out.println(json);
+ } catch(IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ public void givenAnXML_whenUseATreeConvertToJSON_thenReturnDataOK() {
+ String flowerXML = "PoppyRED9";
+
+ try {
+ XmlMapper xmlMapper = new XmlMapper();
+ JsonNode node = xmlMapper.readTree(flowerXML.getBytes());
+
+ ObjectMapper jsonMapper = new ObjectMapper();
+ String json = jsonMapper.writeValueAsString(node);
+
+ System.out.println(json);
+
+ assertEquals(json, "{\"name\":\"Poppy\",\"color\":\"RED\",\"petals\":\"9\"}");
+ } catch(IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/java-dates/pom.xml b/java-dates/pom.xml
index 877dd615a8..13e2a077e1 100644
--- a/java-dates/pom.xml
+++ b/java-dates/pom.xml
@@ -61,23 +61,6 @@
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- copy-dependencies
- prepare-package
-
- copy-dependencies
-
-
- ${project.build.directory}/libs
-
-
-
-
-
org.apache.maven.plugins
maven-compiler-plugin
diff --git a/java-dates/src/main/java/com/baeldung/date/AgeCalculator.java b/java-dates/src/main/java/com/baeldung/date/AgeCalculator.java
new file mode 100644
index 0000000000..c031c97dec
--- /dev/null
+++ b/java-dates/src/main/java/com/baeldung/date/AgeCalculator.java
@@ -0,0 +1,32 @@
+package com.baeldung.date;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.Period;
+import java.util.Date;
+import org.joda.time.Years;
+
+public class AgeCalculator {
+
+ public int calculateAge(LocalDate birthDate, LocalDate currentDate) {
+ // validate inputs ...
+ return Period.between(birthDate, currentDate)
+ .getYears();
+ }
+
+ public int calculateAgeWithJodaTime(org.joda.time.LocalDate birthDate, org.joda.time.LocalDate currentDate) {
+ // validate inputs ...
+ Years age = Years.yearsBetween(birthDate, currentDate);
+ return age.getYears();
+ }
+
+ public int calculateAgeWithJava7(Date birthDate, Date currentDate) {
+ // validate inputs ...
+ DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
+ int d1 = Integer.parseInt(formatter.format(birthDate));
+ int d2 = Integer.parseInt(formatter.format(currentDate));
+ int age = (d2 - d1) / 10000;
+ return age;
+ }
+}
\ No newline at end of file
diff --git a/java-dates/src/test/java/com/baeldung/date/AgeCalculatorUnitTest.java b/java-dates/src/test/java/com/baeldung/date/AgeCalculatorUnitTest.java
new file mode 100644
index 0000000000..dcd261337c
--- /dev/null
+++ b/java-dates/src/test/java/com/baeldung/date/AgeCalculatorUnitTest.java
@@ -0,0 +1,31 @@
+package com.baeldung.date;
+
+import static org.junit.Assert.assertEquals;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.util.Date;
+import org.junit.jupiter.api.Test;
+
+public class AgeCalculatorUnitTest {
+ AgeCalculator ageCalculator = new AgeCalculator();
+
+ @Test
+ public void givenLocalDate_whenCalculateAge_thenOk() {
+ assertEquals(10, ageCalculator.calculateAge(LocalDate.of(2008, 5, 20), LocalDate.of(2018, 9, 20)));
+ }
+
+ @Test
+ public void givenJodaTime_whenCalculateAge_thenOk() {
+ assertEquals(10, ageCalculator.calculateAgeWithJodaTime(new org.joda.time.LocalDate(2008, 5, 20), new org.joda.time.LocalDate(2018, 9, 20)));
+ }
+
+ @Test
+ public void givenDate_whenCalculateAge_thenOk() throws ParseException {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
+ Date birthDate = sdf.parse("2008-05-20");
+ Date currentDate = sdf.parse("2018-09-20");
+ assertEquals(10, ageCalculator.calculateAgeWithJava7(birthDate, currentDate));
+ }
+
+}
\ No newline at end of file
diff --git a/java-dates/src/test/java/com/baeldung/date/DateDiffUnitTest.java b/java-dates/src/test/java/com/baeldung/date/DateDiffUnitTest.java
index 545009a2a9..58d192bfdb 100644
--- a/java-dates/src/test/java/com/baeldung/date/DateDiffUnitTest.java
+++ b/java-dates/src/test/java/com/baeldung/date/DateDiffUnitTest.java
@@ -5,7 +5,9 @@ import org.junit.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
+import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.Period;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
@@ -26,6 +28,17 @@ public class DateDiffUnitTest {
assertEquals(diff, 6);
}
+
+ @Test
+ public void givenTwoDatesInJava8_whenDifferentiating_thenWeGetSix() {
+ LocalDate now = LocalDate.now();
+ LocalDate sixDaysBehind = now.minusDays(6);
+
+ Period period = Period.between(now, sixDaysBehind);
+ int diff = period.getDays();
+
+ assertEquals(diff, 6);
+ }
@Test
public void givenTwoDateTimesInJava8_whenDifferentiating_thenWeGetSix() {
diff --git a/java-difference-date/README.md b/java-difference-date/README.md
deleted file mode 100644
index 2a024c27a2..0000000000
--- a/java-difference-date/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-## Relevant articles:
-
-- [Period and Duration in Java](http://www.baeldung.com/java-period-duration)
-- [Introduction to the Java 8 Date/Time API](http://www.baeldung.com/java-8-date-time-intro)
-- [Migrating to the New Java 8 Date Time API](http://www.baeldung.com/migrating-to-java-8-date-time-api)
\ No newline at end of file
diff --git a/java-difference-date/pom.xml b/java-difference-date/pom.xml
deleted file mode 100644
index 8c87afc0a2..0000000000
--- a/java-difference-date/pom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
- 4.0.0
- com.baeldung
- java-difference-date
- 0.0.1-SNAPSHOT
- jar
- java-difference-date
- Difference between two dates in java
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
-
- joda-time
- joda-time
- ${joda-time.version}
-
-
- com.darwinsys
- hirondelle-date4j
- ${hirondelle-date4j.version}
-
-
-
-
- 2.9.9
- 1.5.1
-
-
-
diff --git a/java-difference-date/src/test/java/com/baeldung/DateDiffTest.java b/java-difference-date/src/test/java/com/baeldung/DateDiffTest.java
deleted file mode 100644
index 4203f7ef38..0000000000
--- a/java-difference-date/src/test/java/com/baeldung/DateDiffTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.baeldung;
-
-import org.joda.time.DateTime;
-import org.junit.Test;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.time.Duration;
-import java.time.ZonedDateTime;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-import java.util.concurrent.TimeUnit;
-
-import static org.junit.Assert.assertEquals;
-
-public class DateDiffTest {
- @Test
- public void givenTwoDatesBeforeJava8_whenDifferentiating_thenWeGetSix() throws ParseException {
- SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
- Date firstDate = sdf.parse("06/24/2017");
- Date secondDate = sdf.parse("06/30/2017");
-
- long diffInMillies = Math.abs(secondDate.getTime() - firstDate.getTime());
- long diff = TimeUnit.DAYS.convert(diffInMillies, TimeUnit.MILLISECONDS);
-
- assertEquals(diff, 6);
- }
-
- @Test
- public void givenTwoDatesInJava8_whenDifferentiating_thenWeGetSix() {
- ZonedDateTime now = ZonedDateTime.now();
- ZonedDateTime sixDaysBehind = now.minusDays(6);
-
- Duration duration = Duration.between(now, sixDaysBehind);
- long diff = Math.abs(duration.toDays());
-
- assertEquals(diff, 6);
- }
-
- @Test
- public void givenTwoDatesInJodaTime_whenDifferentiating_thenWeGetSix() {
- DateTime now = DateTime.now();
- DateTime sixDaysBehind = now.minusDays(6);
-
- org.joda.time.Duration duration = new org.joda.time.Duration(now, sixDaysBehind);
- long diff = Math.abs(duration.getStandardDays());
-
- assertEquals(diff, 6);
- }
-
- @Test
- public void givenTwoDatesInDate4j_whenDifferentiating_thenWeGetSix() {
- hirondelle.date4j.DateTime now = hirondelle.date4j.DateTime.now(TimeZone.getDefault());
- hirondelle.date4j.DateTime sixDaysBehind = now.minusDays(6);
-
- long diff = Math.abs(now.numDaysFrom(sixDaysBehind));
-
- assertEquals(diff, 6);
- }
-}
\ No newline at end of file
diff --git a/java-ee-8-security-api/pom.xml b/java-ee-8-security-api/pom.xml
index 5490cd40f7..3d235e10a8 100644
--- a/java-ee-8-security-api/pom.xml
+++ b/java-ee-8-security-api/pom.xml
@@ -3,11 +3,16 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- com.baeldung
java-ee-8-security-api
1.0-SNAPSHOT
pom
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
@@ -53,10 +58,6 @@
- 1.8
- 1.8
- UTF-8
-
9080
9443
diff --git a/java-numbers/pom.xml b/java-numbers/pom.xml
index bf4d3e8792..bb63c8cfe1 100644
--- a/java-numbers/pom.xml
+++ b/java-numbers/pom.xml
@@ -83,23 +83,6 @@
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- copy-dependencies
- prepare-package
-
- copy-dependencies
-
-
- ${project.build.directory}/libs
-
-
-
-
-
org.apache.maven.plugins
maven-javadoc-plugin
diff --git a/java-numbers/src/main/java/com/baeldung/maths/BigDecimalDemo.java b/java-numbers/src/main/java/com/baeldung/maths/BigDecimalDemo.java
new file mode 100644
index 0000000000..7de0197769
--- /dev/null
+++ b/java-numbers/src/main/java/com/baeldung/maths/BigDecimalDemo.java
@@ -0,0 +1,29 @@
+package com.baeldung.maths;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+public class BigDecimalDemo {
+
+ /** Calculate total amount to be paid for an item rounded to cents..
+ * @param quantity
+ * @param unitPrice
+ * @param discountRate
+ * @param taxRate
+ * @return
+ */
+ public static BigDecimal calculateTotalAmount(BigDecimal quantity,
+ BigDecimal unitPrice, BigDecimal discountRate, BigDecimal taxRate) {
+ BigDecimal amount = quantity.multiply(unitPrice);
+ BigDecimal discount = amount.multiply(discountRate);
+ BigDecimal discountedAmount = amount.subtract(discount);
+ BigDecimal tax = discountedAmount.multiply(taxRate);
+ BigDecimal total = discountedAmount.add(tax);
+
+ // round to 2 decimal places using HALF_EVEN
+ BigDecimal roundedTotal = total.setScale(2, RoundingMode.HALF_EVEN);
+
+ return roundedTotal;
+ }
+
+}
diff --git a/java-numbers/src/main/java/com/baeldung/percentage/PercentageCalculator.java b/java-numbers/src/main/java/com/baeldung/percentage/PercentageCalculator.java
new file mode 100644
index 0000000000..e74de2cc67
--- /dev/null
+++ b/java-numbers/src/main/java/com/baeldung/percentage/PercentageCalculator.java
@@ -0,0 +1,21 @@
+package com.baeldung.percentage;
+
+import java.util.Scanner;
+
+public class PercentageCalculator {
+
+ public double calculatePercentage(double obtained,double total){
+ return obtained*100/total;
+ }
+
+ public static void main(String[] args) {
+ PercentageCalculator pc = new PercentageCalculator();
+ Scanner in = new Scanner(System.in);
+ System.out.println("Enter obtained marks:");
+ double obtained = in.nextDouble();
+ System.out.println("Enter total marks:");
+ double total =in.nextDouble();
+ System.out.println("Percentage obtained :"+pc.calculatePercentage(obtained,total));
+ }
+
+}
diff --git a/java-numbers/src/test/java/com/baeldung/maths/BigDecimalDemoUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/BigDecimalDemoUnitTest.java
new file mode 100644
index 0000000000..2bf9872bec
--- /dev/null
+++ b/java-numbers/src/test/java/com/baeldung/maths/BigDecimalDemoUnitTest.java
@@ -0,0 +1,120 @@
+package com.baeldung.maths;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.math.RoundingMode;
+import java.util.Random;
+
+import org.junit.jupiter.api.Test;
+
+public class BigDecimalDemoUnitTest {
+
+ @Test
+ public void whenBigDecimalCreated_thenValueMatches() {
+ BigDecimal bdFromString = new BigDecimal("0.1");
+ BigDecimal bdFromCharArray = new BigDecimal(
+ new char[] { '3', '.', '1', '6', '1', '5' });
+ BigDecimal bdlFromInt = new BigDecimal(42);
+ BigDecimal bdFromLong = new BigDecimal(123412345678901L);
+ BigInteger bigInteger = BigInteger.probablePrime(100, new Random());
+ BigDecimal bdFromBigInteger = new BigDecimal(bigInteger);
+
+ assertEquals("0.1", bdFromString.toString());
+ assertEquals("3.1615", bdFromCharArray.toString());
+ assertEquals("42", bdlFromInt.toString());
+ assertEquals("123412345678901", bdFromLong.toString());
+ assertEquals(bigInteger.toString(), bdFromBigInteger.toString());
+ }
+
+ @Test
+ public void whenBigDecimalCreatedFromDouble_thenValueMayNotMatch() {
+ BigDecimal bdFromDouble = new BigDecimal(0.1d);
+ assertNotEquals("0.1", bdFromDouble.toString());
+ }
+
+ @Test
+ public void whenBigDecimalCreatedUsingValueOf_thenValueMatches() {
+ BigDecimal bdFromLong1 = BigDecimal.valueOf(123412345678901L);
+ BigDecimal bdFromLong2 = BigDecimal.valueOf(123412345678901L, 2);
+ BigDecimal bdFromDouble = BigDecimal.valueOf(0.1d);
+
+ assertEquals("123412345678901", bdFromLong1.toString());
+ assertEquals("1234123456789.01", bdFromLong2.toString());
+ assertEquals("0.1", bdFromDouble.toString());
+ }
+
+ @Test
+ public void whenEqualsCalled_thenSizeAndScaleMatched() {
+ BigDecimal bd1 = new BigDecimal("1.0");
+ BigDecimal bd2 = new BigDecimal("1.00");
+
+ assertFalse(bd1.equals(bd2));
+ }
+
+ @Test
+ public void whenComparingBigDecimals_thenExpectedResult() {
+ BigDecimal bd1 = new BigDecimal("1.0");
+ BigDecimal bd2 = new BigDecimal("1.00");
+ BigDecimal bd3 = new BigDecimal("2.0");
+
+ assertTrue(bd1.compareTo(bd3) < 0);
+ assertTrue(bd3.compareTo(bd1) > 0);
+ assertTrue(bd1.compareTo(bd2) == 0);
+ assertTrue(bd1.compareTo(bd3) <= 0);
+ assertTrue(bd1.compareTo(bd2) >= 0);
+ assertTrue(bd1.compareTo(bd3) != 0);
+ }
+
+ @Test
+ public void whenPerformingArithmetic_thenExpectedResult() {
+ BigDecimal bd1 = new BigDecimal("4.0");
+ BigDecimal bd2 = new BigDecimal("2.0");
+
+ BigDecimal sum = bd1.add(bd2);
+ BigDecimal difference = bd1.subtract(bd2);
+ BigDecimal quotient = bd1.divide(bd2);
+ BigDecimal product = bd1.multiply(bd2);
+
+ assertTrue(sum.compareTo(new BigDecimal("6.0")) == 0);
+ assertTrue(difference.compareTo(new BigDecimal("2.0")) == 0);
+ assertTrue(quotient.compareTo(new BigDecimal("2.0")) == 0);
+ assertTrue(product.compareTo(new BigDecimal("8.0")) == 0);
+ }
+
+ @Test
+ public void whenGettingAttributes_thenExpectedResult() {
+ BigDecimal bd = new BigDecimal("-12345.6789");
+
+ assertEquals(9, bd.precision());
+ assertEquals(4, bd.scale());
+ assertEquals(-1, bd.signum());
+ }
+
+ @Test
+ public void whenRoundingDecimal_thenExpectedResult() {
+ BigDecimal bd = new BigDecimal("2.5");
+ // Round to 1 digit using HALF_EVEN
+ BigDecimal rounded = bd
+ .round(new MathContext(1, RoundingMode.HALF_EVEN));
+
+ assertEquals("2", rounded.toString());
+ }
+
+ @Test
+ public void givenPurchaseTxn_whenCalculatingTotalAmount_thenExpectedResult() {
+ BigDecimal quantity = new BigDecimal("4.5");
+ BigDecimal unitPrice = new BigDecimal("2.69");
+ BigDecimal discountRate = new BigDecimal("0.10");
+ BigDecimal taxRate = new BigDecimal("0.0725");
+
+ BigDecimal amountToBePaid = BigDecimalDemo
+ .calculateTotalAmount(quantity, unitPrice, discountRate, taxRate);
+ assertEquals("11.68", amountToBePaid.toString());
+ }
+}
diff --git a/java-numbers/src/test/java/com/baeldung/maths/BigIntegerDemoUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/BigIntegerDemoUnitTest.java
new file mode 100644
index 0000000000..3537ccb3a3
--- /dev/null
+++ b/java-numbers/src/test/java/com/baeldung/maths/BigIntegerDemoUnitTest.java
@@ -0,0 +1,128 @@
+package com.baeldung.maths;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+import org.junit.jupiter.api.Test;
+
+public class BigIntegerDemoUnitTest {
+
+ @Test
+ public void whenBigIntegerCreatedFromConstructor_thenExpectedResult() {
+ BigInteger biFromString = new BigInteger("1234567890987654321");
+ BigInteger biFromByteArray = new BigInteger(
+ new byte[] { 64, 64, 64, 64, 64, 64 });
+ BigInteger biFromSignMagnitude = new BigInteger(-1,
+ new byte[] { 64, 64, 64, 64, 64, 64 });
+
+ assertEquals("1234567890987654321", biFromString.toString());
+ assertEquals("70644700037184", biFromByteArray.toString());
+ assertEquals("-70644700037184", biFromSignMagnitude.toString());
+ }
+
+ @Test
+ public void whenLongConvertedToBigInteger_thenValueMatches() {
+ BigInteger bi = BigInteger.valueOf(2305843009213693951L);
+
+ assertEquals("2305843009213693951", bi.toString());
+ }
+
+ @Test
+ public void givenBigIntegers_whentCompared_thenExpectedResult() {
+ BigInteger i = new BigInteger("123456789012345678901234567890");
+ BigInteger j = new BigInteger("123456789012345678901234567891");
+ BigInteger k = new BigInteger("123456789012345678901234567892");
+
+ assertTrue(i.compareTo(i) == 0);
+ assertTrue(j.compareTo(i) > 0);
+ assertTrue(j.compareTo(k) < 0);
+ }
+
+ @Test
+ public void givenBigIntegers_whenPerformingArithmetic_thenExpectedResult() {
+ BigInteger i = new BigInteger("4");
+ BigInteger j = new BigInteger("2");
+
+ BigInteger sum = i.add(j);
+ BigInteger difference = i.subtract(j);
+ BigInteger quotient = i.divide(j);
+ BigInteger product = i.multiply(j);
+
+ assertEquals(new BigInteger("6"), sum);
+ assertEquals(new BigInteger("2"), difference);
+ assertEquals(new BigInteger("2"), quotient);
+ assertEquals(new BigInteger("8"), product);
+ }
+
+ @Test
+ public void givenBigIntegers_whenPerformingBitOperations_thenExpectedResult() {
+ BigInteger i = new BigInteger("17");
+ BigInteger j = new BigInteger("7");
+
+ BigInteger and = i.and(j);
+ BigInteger or = i.or(j);
+ BigInteger not = j.not();
+ BigInteger xor = i.xor(j);
+ BigInteger andNot = i.andNot(j);
+ BigInteger shiftLeft = i.shiftLeft(1);
+ BigInteger shiftRight = i.shiftRight(1);
+
+ assertEquals(new BigInteger("1"), and);
+ assertEquals(new BigInteger("23"), or);
+ assertEquals(new BigInteger("-8"), not);
+ assertEquals(new BigInteger("22"), xor);
+ assertEquals(new BigInteger("16"), andNot);
+ assertEquals(new BigInteger("34"), shiftLeft);
+ assertEquals(new BigInteger("8"), shiftRight);
+ }
+
+ @Test
+ public void givenBigIntegers_whenPerformingBitManipulations_thenExpectedResult() {
+ BigInteger i = new BigInteger("1018");
+
+ int bitCount = i.bitCount();
+ int bitLength = i.bitLength();
+ int getLowestSetBit = i.getLowestSetBit();
+ boolean testBit3 = i.testBit(3);
+ BigInteger setBit12 = i.setBit(12);
+ BigInteger flipBit0 = i.flipBit(0);
+ BigInteger clearBit3 = i.clearBit(3);
+
+ assertEquals(8, bitCount);
+ assertEquals(10, bitLength);
+ assertEquals(1, getLowestSetBit);
+ assertEquals(true, testBit3);
+ assertEquals(new BigInteger("5114"), setBit12);
+ assertEquals(new BigInteger("1019"), flipBit0);
+ assertEquals(new BigInteger("1010"), clearBit3);
+ }
+
+ @Test
+ public void givenBigIntegers_whenModularCalculation_thenExpectedResult() {
+ BigInteger i = new BigInteger("31");
+ BigInteger j = new BigInteger("24");
+ BigInteger k = new BigInteger("16");
+
+ BigInteger gcd = j.gcd(k);
+ BigInteger multiplyAndmod = j.multiply(k)
+ .mod(i);
+ BigInteger modInverse = j.modInverse(i);
+ BigInteger modPow = j.modPow(k, i);
+
+ assertEquals(new BigInteger("8"), gcd);
+ assertEquals(new BigInteger("12"), multiplyAndmod);
+ assertEquals(new BigInteger("22"), modInverse);
+ assertEquals(new BigInteger("7"), modPow);
+ }
+
+ @Test
+ public void givenBigIntegers_whenPrimeOperations_thenExpectedResult() {
+ BigInteger i = BigInteger.probablePrime(100, new Random());
+
+ boolean isProbablePrime = i.isProbablePrime(1000);
+ assertEquals(true, isProbablePrime);
+ }
+}
diff --git a/java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java b/java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java
new file mode 100644
index 0000000000..111b2f4465
--- /dev/null
+++ b/java-numbers/src/test/java/com/baeldung/maths/MathSinUnitTest.java
@@ -0,0 +1,20 @@
+package com.baeldung.maths;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.jupiter.api.Test;
+
+public class MathSinUnitTest {
+
+ @Test
+ public void givenAnAngleInDegrees_whenUsingToRadians_thenResultIsInRadians() {
+ double angleInDegrees = 30;
+ double sinForDegrees = Math.sin(Math.toRadians(angleInDegrees)); // 0.5
+
+ double thirtyDegreesInRadians = 1/6 * Math.PI;
+ double sinForRadians = Math.sin(thirtyDegreesInRadians); // 0.5
+
+ assertTrue(sinForDegrees == sinForRadians);
+ }
+
+}
diff --git a/java-numbers/src/test/java/com/baeldung/percentage/PercentageCalculatorUnitTest.java b/java-numbers/src/test/java/com/baeldung/percentage/PercentageCalculatorUnitTest.java
new file mode 100644
index 0000000000..202d4f8112
--- /dev/null
+++ b/java-numbers/src/test/java/com/baeldung/percentage/PercentageCalculatorUnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.percentage;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PercentageCalculatorUnitTest {
+ private PercentageCalculator pc = new PercentageCalculator();
+
+ @Test
+ public void whenPass2Integers_thenShouldCalculatePercentage(){
+ Assert.assertEquals("Result not as expected",
+ 50.0,pc.calculatePercentage(50,100),0.1);
+ }
+
+ @Test
+ public void whenPassObtainedMarksAsDouble_thenShouldCalculatePercentage(){
+ Assert.assertEquals("Result not as expected",5.05,
+ pc.calculatePercentage(50.5,1000),0.1);
+ }
+
+ @Test
+ public void whenPassTotalMarksAsDouble_thenShouldCalculatePercentage(){
+ Assert.assertEquals("Result not as expected",19.6,
+ pc.calculatePercentage(5,25.5),0.1);
+ }
+
+ @Test
+ public void whenPass2DoubleNumbers_thenShouldCalculatePercentage(){
+ Assert.assertEquals("Result not as expected",20,
+ pc.calculatePercentage(5.5,27.5),0.1);
+ }
+
+}
diff --git a/java-streams/README.md b/java-streams/README.md
index 4bfcabb7cf..548d4b6a33 100644
--- a/java-streams/README.md
+++ b/java-streams/README.md
@@ -12,3 +12,4 @@
- [Iterable to Stream in Java](http://www.baeldung.com/java-iterable-to-stream)
- [How to Iterate Over a Stream With Indices](http://www.baeldung.com/java-stream-indices)
- [Primitive Type Streams in Java 8](http://www.baeldung.com/java-8-primitive-streams)
+- [Stream Ordering in Java](https://www.baeldung.com/java-stream-ordering)
diff --git a/java-streams/pom.xml b/java-streams/pom.xml
index 4f8651a756..e4670c268d 100644
--- a/java-streams/pom.xml
+++ b/java-streams/pom.xml
@@ -86,23 +86,6 @@
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- copy-dependencies
- prepare-package
-
- copy-dependencies
-
-
- ${project.build.directory}/libs
-
-
-
-
-
org.apache.maven.plugins
maven-compiler-plugin
@@ -122,7 +105,7 @@
3.5
1.16.12
0.9.0
- 1.13
+ 1.15
0.6.5
2.10
diff --git a/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java b/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java
new file mode 100644
index 0000000000..1b64c8924a
--- /dev/null
+++ b/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java
@@ -0,0 +1,209 @@
+package com.baeldung.protonpack;
+
+import com.codepoetics.protonpack.Indexed;
+import com.codepoetics.protonpack.StreamUtils;
+import com.codepoetics.protonpack.collectors.CollectorUtils;
+import com.codepoetics.protonpack.collectors.NonUniqueValueException;
+import com.codepoetics.protonpack.selectors.Selector;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.util.Arrays.asList;
+import static java.util.Arrays.stream;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+@SuppressWarnings("unchecked")
+public class ProtonpackUnitTest {
+ @Test
+ public void whenTakeWhile_thenTakenWhile() {
+ Stream streamOfInt = Stream.iterate(1, i -> i + 1);
+ List result = StreamUtils.takeWhile(streamOfInt, i -> i < 5).collect(Collectors.toList());
+ assertThat(result).contains(1, 2, 3, 4);
+ }
+
+ @Test
+ public void whenTakeUntil_thenTakenUntil() {
+ Stream streamOfInt = Stream.iterate(1, i -> i + 1);
+ List result = StreamUtils.takeUntil(streamOfInt, i -> i > 50).collect(Collectors.toList());
+ assertThat(result).contains(10, 20, 30, 40);
+ }
+
+ @Test
+ public void givenMultipleStream_whenZipped_thenZipped() {
+ String[] clubs = { "Juventus", "Barcelona", "Liverpool", "PSG" };
+ String[] players = { "Ronaldo", "Messi", "Salah" };
+ Set zippedFrom2Sources = StreamUtils.zip(stream(clubs), stream(players), (club, player) -> club + " " + player)
+ .collect(Collectors.toSet());
+ assertThat(zippedFrom2Sources).contains("Juventus Ronaldo", "Barcelona Messi", "Liverpool Salah");
+
+ String[] leagues = { "Serie A", "La Liga", "Premier League" };
+ Set zippedFrom3Sources = StreamUtils.zip(stream(clubs), stream(players), stream(leagues),
+ (club, player, league) -> club + " " + player + " " + league).collect(Collectors.toSet());
+ assertThat(zippedFrom3Sources).contains("Juventus Ronaldo Serie A", "Barcelona Messi La Liga",
+ "Liverpool Salah Premier League");
+ }
+
+ @Test
+ public void whenZippedWithIndex_thenZippedWithIndex() {
+ Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool");
+ Set> zipsWithIndex = StreamUtils.zipWithIndex(streamOfClubs).collect(Collectors.toSet());
+ assertThat(zipsWithIndex).contains(Indexed.index(0, "Juventus"), Indexed.index(1, "Barcelona"),
+ Indexed.index(2, "Liverpool"));
+ }
+
+ @Test
+ public void givenMultipleStream_whenMerged_thenMerged() {
+ Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool", "PSG");
+ Stream streamOfPlayers = Stream.of("Ronaldo", "Messi", "Salah");
+ Stream streamOfLeagues = Stream.of("Serie A", "La Liga", "Premier League");
+
+ Set merged = StreamUtils.merge(() -> "", (valOne, valTwo) -> valOne + " " + valTwo, streamOfClubs,
+ streamOfPlayers, streamOfLeagues).collect(Collectors.toSet());
+
+ assertThat(merged).contains(" Juventus Ronaldo Serie A", " Barcelona Messi La Liga", " Liverpool Salah Premier League",
+ " PSG");
+ }
+
+ @Test
+ public void givenMultipleStream_whenMergedToList_thenMergedToList() {
+ Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "PSG");
+ Stream streamOfPlayers = Stream.of("Ronaldo", "Messi");
+
+ List> mergedListOfList = StreamUtils.mergeToList(streamOfClubs, streamOfPlayers)
+ .collect(Collectors.toList());
+ assertThat(mergedListOfList.get(0)).isInstanceOf(List.class);
+ assertThat(mergedListOfList.get(0)).containsExactly("Juventus", "Ronaldo");
+ assertThat(mergedListOfList.get(1)).containsExactly("Barcelona", "Messi");
+ assertThat(mergedListOfList.get(2)).containsExactly("PSG");
+ }
+
+ @Test
+ public void givenMultipleStream_whenInterleaved_thenInterleaved() {
+ Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool");
+ Stream streamOfPlayers = Stream.of("Ronaldo", "Messi");
+ Stream streamOfLeagues = Stream.of("Serie A", "La Liga");
+
+ AtomicInteger counter = new AtomicInteger(0);
+ Selector roundRobinSelector = (o) -> {
+ Object[] vals = (Object[]) o;
+ while (counter.get() >= vals.length || vals[counter.get()] == null) {
+ if (counter.incrementAndGet() >= vals.length)
+ counter.set(0);
+ }
+ return counter.getAndIncrement();
+ };
+ Stream interleavedStream = StreamUtils.interleave(roundRobinSelector, streamOfClubs, streamOfPlayers,
+ streamOfLeagues);
+ List interleavedList = interleavedStream.collect(Collectors.toList());
+ assertThat(interleavedList).containsExactly("Juventus", "Ronaldo", "Serie A", "Barcelona", "Messi", "La Liga",
+ "Liverpool");
+ }
+
+ @Test
+ public void whenSkippedUntil_thenSkippedUntil() {
+ Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ List skippedUntilGreaterThan5 = StreamUtils.skipUntil(stream(numbers), i -> i > 5).collect(Collectors.toList());
+ assertThat(skippedUntilGreaterThan5).containsExactly(6, 7, 8, 9, 10);
+
+ List skippedUntilLessThanEquals5 = StreamUtils.skipUntil(stream(numbers), i -> i <= 5)
+ .collect(Collectors.toList());
+ assertThat(skippedUntilLessThanEquals5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ }
+
+ @Test
+ public void whenSkippedWhile_thenSkippedWhile() {
+ Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ List skippedWhileLessThanEquals5 = StreamUtils.skipWhile(stream(numbers), i -> i <= 5)
+ .collect(Collectors.toList());
+ assertThat(skippedWhileLessThanEquals5).containsExactly(6, 7, 8, 9, 10);
+
+ List skippedWhileGreaterThan5 = StreamUtils.skipWhile(stream(numbers), i -> i > 5).collect(Collectors.toList());
+ assertThat(skippedWhileGreaterThan5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ }
+
+ @Test
+ public void givenFibonacciGenerator_whenUnfolded_thenUnfolded() {
+ AtomicInteger lastValue = new AtomicInteger(0);
+ Function> fibonacciGenerator = (i) -> (i < 10) ?
+ Optional.of(i + lastValue.getAndSet(i)) :
+ Optional.empty();
+
+ List fib = StreamUtils.unfold(1, fibonacciGenerator).collect(Collectors.toList());
+ assertThat(fib).containsExactly(1, 1, 2, 3, 5, 8, 13);
+ }
+
+ @Test
+ public void whenWindowed_thenWindowed() {
+ Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
+
+ List> windowedWithSkip1 = StreamUtils.windowed(stream(numbers), 3, 1).collect(Collectors.toList());
+ assertThat(windowedWithSkip1).containsExactly(asList(1, 2, 3), asList(2, 3, 4), asList(3, 4, 5), asList(4, 5, 6),
+ asList(5, 6, 7));
+
+ List> windowedWithSkip2 = StreamUtils.windowed(stream(numbers), 3, 2).collect(Collectors.toList());
+ assertThat(windowedWithSkip2).containsExactly(asList(1, 2, 3), asList(3, 4, 5), asList(5, 6, 7));
+ }
+
+ @Test
+ public void whenAggregated_thenAggregated() {
+ Integer[] numbers = { 1, 2, 2, 3, 4, 4, 4, 5 };
+ List> aggregated = StreamUtils.aggregate(stream(numbers), (int1, int2) -> int1.compareTo(int2) == 0)
+ .collect(Collectors.toList());
+ assertThat(aggregated).containsExactly(asList(1), asList(2, 2), asList(3), asList(4, 4, 4), asList(5));
+
+ List> aggregatedFixSize = StreamUtils.aggregate(stream(numbers), 5).collect(Collectors.toList());
+ assertThat(aggregatedFixSize).containsExactly(asList(1, 2, 2, 3, 4), asList(4, 4, 5));
+ }
+
+ @Test
+ public void whenGroupedRun_thenGroupedRun() {
+ Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 };
+ List> grouped = StreamUtils.groupRuns(stream(numbers)).collect(Collectors.toList());
+ assertThat(grouped).containsExactly(asList(1, 1), asList(2), asList(3), asList(4, 4), asList(5));
+
+ Integer[] numbers2 = { 1, 2, 3, 1 };
+ List> grouped2 = StreamUtils.groupRuns(stream(numbers2)).collect(Collectors.toList());
+ assertThat(grouped2).containsExactly(asList(1), asList(2), asList(3), asList(1));
+ }
+
+ @Test
+ public void whenAggregatedOnListCondition_thenAggregatedOnListCondition() {
+ Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 };
+ Stream> aggregated = StreamUtils.aggregateOnListCondition(stream(numbers),
+ (currentList, nextInt) -> currentList.stream().mapToInt(Integer::intValue).sum() + nextInt <= 5);
+ assertThat(aggregated).containsExactly(asList(1, 1, 2), asList(3), asList(4), asList(4), asList(5));
+ }
+
+ @Test
+ public void givenProjectionFunction_whenMaxedBy_thenMaxedBy() {
+ Stream clubs = Stream.of("Juventus", "Barcelona", "PSG");
+ Optional longestName = clubs.collect(CollectorUtils.maxBy(String::length));
+ assertThat(longestName.get()).isEqualTo("Barcelona");
+ }
+
+ @Test
+ public void givenStreamOfMultipleElem_whenUniqueCollector_thenValueReturned() {
+ Stream singleElement = Stream.of(1);
+ Optional unique = singleElement.collect(CollectorUtils.unique());
+ assertThat(unique.get()).isEqualTo(1);
+
+ }
+
+ @Test
+ public void givenStreamOfMultipleElem_whenUniqueCollector_thenExceptionThrown() {
+ Stream multipleElement = Stream.of(1, 2, 3);
+ assertThatExceptionOfType(NonUniqueValueException.class).isThrownBy(() -> {
+ multipleElement.collect(CollectorUtils.unique());
+ });
+ }
+
+}
diff --git a/core-java-collections/src/test/java/com/baeldung/collection/StreamOperateAndRemoveUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/StreamOperateAndRemoveUnitTest.java
similarity index 98%
rename from core-java-collections/src/test/java/com/baeldung/collection/StreamOperateAndRemoveUnitTest.java
rename to java-streams/src/test/java/com/baeldung/stream/StreamOperateAndRemoveUnitTest.java
index 9f002c89a2..c5aa9a1651 100644
--- a/core-java-collections/src/test/java/com/baeldung/collection/StreamOperateAndRemoveUnitTest.java
+++ b/java-streams/src/test/java/com/baeldung/stream/StreamOperateAndRemoveUnitTest.java
@@ -1,4 +1,4 @@
-package com.baeldung.collection;
+package com.baeldung.stream;
import java.util.ArrayList;
import java.util.List;
diff --git a/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkUnitTest.java b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java
similarity index 98%
rename from java-streams/src/test/java/com/baeldung/streamordering/BenchmarkUnitTest.java
rename to java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java
index ba1cb1f726..656a6d95f9 100644
--- a/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkUnitTest.java
+++ b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java
@@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
-public class BenchmarkUnitTest
+public class BenchmarkManualTest
{
public void
diff --git a/java-strings/README.md b/java-strings/README.md
index d5b9b45b20..b12fc75f30 100644
--- a/java-strings/README.md
+++ b/java-strings/README.md
@@ -24,4 +24,10 @@
- [Check If a String Is Numeric in Java](http://www.baeldung.com/java-check-string-number)
- [Why Use char[] Array Over a String for Storing Passwords in Java?](http://www.baeldung.com/java-storing-passwords)
- [Convert a String to Title Case](http://www.baeldung.com/java-string-title-case)
-- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string)
\ No newline at end of file
+- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string)
+- [Java Check a String for Lowercase/Uppercase Letter, Special Character and Digit](https://www.baeldung.com/java-lowercase-uppercase-special-character-digit-regex)
+- [Convert java.util.Date to String](https://www.baeldung.com/java-util-date-to-string)
+- [Get Substring from String in Java](https://www.baeldung.com/java-substring)
+- [Converting a Stack Trace to a String in Java](https://www.baeldung.com/java-stacktrace-to-string)
+- [Sorting a String Alphabetically in Java](https://www.baeldung.com/java-sort-string-alphabetically)
+- [Remove Emojis from a Java String](https://www.baeldung.com/java-string-remove-emojis)
diff --git a/java-strings/pom.xml b/java-strings/pom.xml
index 0c83b4d9e7..b1ba49b33a 100644
--- a/java-strings/pom.xml
+++ b/java-strings/pom.xml
@@ -47,11 +47,21 @@
jmh-core
${jmh-core.version}
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh-core.version}
+
com.ibm.icu
icu4j
${icu4j.version}
+
+ com.google.guava
+ guava
+ ${guava.version}
+
com.vdurmont
@@ -71,23 +81,6 @@
-
- org.apache.maven.plugins
- maven-dependency-plugin
-
-
- copy-dependencies
- prepare-package
-
- copy-dependencies
-
-
- ${project.build.directory}/libs
-
-
-
-
-
org.apache.maven.plugins
maven-compiler-plugin
@@ -109,6 +102,7 @@
3.6.1
1.19
61.1
+ 26.0-jre