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/string/AppendCharAtPositionX.java b/core-java/src/main/java/com/baeldung/string/AppendCharAtPositionX.java
new file mode 100644
index 0000000000..bebffe52f1
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/string/AppendCharAtPositionX.java
@@ -0,0 +1,45 @@
+/**
+ *
+ */
+package com.baeldung.string;
+
+/**
+ * @author swpraman
+ *
+ */
+public class AppendCharAtPositionX {
+
+ public String addCharUsingCharArray(String str, char ch, int position) {
+ validate(str, position);
+ int len = str.length();
+ char[] updatedArr = new char[len + 1];
+ str.getChars(0, position, updatedArr, 0);
+ updatedArr[position] = ch;
+ str.getChars(position, len, updatedArr, position + 1);
+ return new String(updatedArr);
+ }
+
+ public String addCharUsingSubstring(String str, char ch, int position) {
+ validate(str, position);
+ return str.substring(0, position) + ch + str.substring(position);
+ }
+
+ public String addCharUsingStringBuilder(String str, char ch, int position) {
+ validate(str, position);
+ StringBuilder sb = new StringBuilder(str);
+ sb.insert(position, ch);
+ return sb.toString();
+ }
+
+ private void validate(String str, int position) {
+ if (str == null) {
+ throw new IllegalArgumentException("Str should not be null");
+ }
+ int len = str.length();
+ if (position < 0 || position > len) {
+ throw new IllegalArgumentException("position[" + position + "] should be "
+ + "in the range 0.." + len + " for string " + str);
+ }
+ }
+
+}
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/synthetic/BridgeMethodDemo.java b/core-java/src/main/java/com/baeldung/synthetic/BridgeMethodDemo.java
new file mode 100644
index 0000000000..bdf6684f78
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/synthetic/BridgeMethodDemo.java
@@ -0,0 +1,23 @@
+package com.baeldung.synthetic;
+
+import java.util.Comparator;
+
+/**
+ * Class which contains a synthetic bridge method.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class BridgeMethodDemo implements Comparator {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public int compare(Integer o1, Integer o2) {
+ return 0;
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/synthetic/SyntheticConstructorDemo.java b/core-java/src/main/java/com/baeldung/synthetic/SyntheticConstructorDemo.java
new file mode 100644
index 0000000000..d3d75ac05e
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/synthetic/SyntheticConstructorDemo.java
@@ -0,0 +1,34 @@
+package com.baeldung.synthetic;
+
+/**
+ * Wrapper for a class which contains a synthetic constructor.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class SyntheticConstructorDemo {
+
+ /**
+ * We need to instantiate the {@link NestedClass} using a private
+ * constructor from the enclosing instance in order to generate a synthetic
+ * constructor.
+ */
+ private NestedClass nestedClass = new NestedClass();
+
+ /**
+ * Class which contains a synthetic constructor.
+ *
+ * @author Donato Rimenti
+ *
+ */
+ class NestedClass {
+
+ /**
+ * In order to generate a synthetic constructor, this class must have a
+ * private constructor.
+ */
+ private NestedClass() {
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/synthetic/SyntheticFieldDemo.java b/core-java/src/main/java/com/baeldung/synthetic/SyntheticFieldDemo.java
new file mode 100644
index 0000000000..1813e03953
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/synthetic/SyntheticFieldDemo.java
@@ -0,0 +1,22 @@
+package com.baeldung.synthetic;
+
+/**
+ * Wrapper for a class which contains a synthetic field reference to the outer
+ * class.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class SyntheticFieldDemo {
+
+ /**
+ * Class which contains a synthetic field reference to the outer class.
+ *
+ * @author Donato Rimenti
+ *
+ */
+ class NestedClass {
+
+ }
+
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/synthetic/SyntheticMethodDemo.java b/core-java/src/main/java/com/baeldung/synthetic/SyntheticMethodDemo.java
new file mode 100644
index 0000000000..59be4e1429
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/synthetic/SyntheticMethodDemo.java
@@ -0,0 +1,48 @@
+package com.baeldung.synthetic;
+
+/**
+ * Wrapper for a class which contains two synthetic methods accessors to a
+ * private field.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class SyntheticMethodDemo {
+
+ /**
+ * Class which contains two synthetic methods accessors to a private field.
+ *
+ * @author Donato Rimenti
+ *
+ */
+ class NestedClass {
+
+ /**
+ * Field for which will be generated synthetic methods accessors. It's
+ * important that this field is private for this purpose.
+ */
+ private String nestedField;
+ }
+
+ /**
+ * Gets the private nested field. We need to read the nested field in order
+ * to generate the synthetic getter.
+ *
+ * @return the {@link NestedClass#nestedField}
+ */
+ public String getNestedField() {
+ return new NestedClass().nestedField;
+ }
+
+ /**
+ * Sets the private nested field. We need to write the nested field in order
+ * to generate the synthetic setter.
+ *
+ * @param nestedField
+ * the {@link NestedClass#nestedField}
+ */
+ public void setNestedField(String nestedField) {
+ new NestedClass().nestedField = nestedField;
+ }
+
+}
\ No newline at end of file
diff --git a/core-java/src/main/java/com/baeldung/throwsexception/PersonRepository.java b/core-java/src/main/java/com/baeldung/throwsexception/PersonRepository.java
index a3e69b7f6f..7d8345c3c1 100644
--- a/core-java/src/main/java/com/baeldung/throwsexception/PersonRepository.java
+++ b/core-java/src/main/java/com/baeldung/throwsexception/PersonRepository.java
@@ -1,16 +1,10 @@
package com.baeldung.throwsexception;
-import javax.annotation.Nullable;
import java.sql.SQLException;
import java.util.List;
public class PersonRepository {
- @Nullable
- public String findNameById(String id) {
- return id == null ? null : "Name";
- }
-
public List findAll() throws SQLException {
throw new SQLException();
}
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/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/string/AppendCharAtPositionXUnitTest.java b/core-java/src/test/java/com/baeldung/string/AppendCharAtPositionXUnitTest.java
new file mode 100644
index 0000000000..2cdf6145d3
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/string/AppendCharAtPositionXUnitTest.java
@@ -0,0 +1,110 @@
+/**
+ *
+ */
+package com.baeldung.string;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+/**
+ * @author swpraman
+ *
+ */
+public class AppendCharAtPositionXUnitTest {
+
+ private AppendCharAtPositionX appendCharAtPosition = new AppendCharAtPositionX();
+ private String word = "Titanc";
+ private char letter = 'i';
+
+ @Test
+ public void whenUsingCharacterArrayAndCharacterAddedAtBeginning_shouldAddCharacter() {
+ assertEquals("iTitanc", appendCharAtPosition.addCharUsingCharArray(word, letter, 0));
+ }
+
+ @Test
+ public void whenUsingSubstringAndCharacterAddedAtBeginning_shouldAddCharacter() {
+ assertEquals("iTitanc", appendCharAtPosition.addCharUsingSubstring(word, letter, 0));
+ }
+
+ @Test
+ public void whenUsingStringBuilderAndCharacterAddedAtBeginning_shouldAddCharacter() {
+ assertEquals("iTitanc", appendCharAtPosition.addCharUsingStringBuilder(word, letter, 0));
+ }
+
+ @Test
+ public void whenUsingCharacterArrayAndCharacterAddedAtMiddle_shouldAddCharacter() {
+ assertEquals("Titianc", appendCharAtPosition.addCharUsingCharArray(word, letter, 3));
+ }
+
+ @Test
+ public void whenUsingSubstringAndCharacterAddedAtMiddle_shouldAddCharacter() {
+ assertEquals("Titianc", appendCharAtPosition.addCharUsingSubstring(word, letter, 3));
+ }
+
+ @Test
+ public void whenUsingStringBuilderAndCharacterAddedAtMiddle_shouldAddCharacter() {
+ assertEquals("Titianc", appendCharAtPosition.addCharUsingStringBuilder(word, letter, 3));
+ }
+
+ @Test
+ public void whenUsingCharacterArrayAndCharacterAddedAtEnd_shouldAddCharacter() {
+ assertEquals("Titanci", appendCharAtPosition.addCharUsingCharArray(word, letter, word.length()));
+ }
+
+ @Test
+ public void whenUsingSubstringAndCharacterAddedAtEnd_shouldAddCharacter() {
+ assertEquals("Titanci", appendCharAtPosition.addCharUsingSubstring(word, letter, word.length()));
+ }
+
+ @Test
+ public void whenUsingStringBuilderAndCharacterAddedAtEnd_shouldAddCharacter() {
+ assertEquals("Titanci", appendCharAtPosition.addCharUsingStringBuilder(word, letter, word.length()));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenUsingCharacterArrayAndCharacterAddedAtNegativePosition_shouldThrowException() {
+ appendCharAtPosition.addCharUsingStringBuilder(word, letter, -1);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenUsingSubstringAndCharacterAddedAtNegativePosition_shouldThrowException() {
+ appendCharAtPosition.addCharUsingStringBuilder(word, letter, -1);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenUsingStringBuilderAndCharacterAddedAtNegativePosition_shouldThrowException() {
+ appendCharAtPosition.addCharUsingStringBuilder(word, letter, -1);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenUsingCharacterArrayAndCharacterAddedAtInvalidPosition_shouldThrowException() {
+ appendCharAtPosition.addCharUsingStringBuilder(word, letter, word.length() + 2);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenUsingSubstringAndCharacterAddedAtInvalidPosition_shouldThrowException() {
+ appendCharAtPosition.addCharUsingStringBuilder(word, letter, word.length() + 2);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenUsingStringBuilderAndCharacterAddedAtInvalidPosition_shouldThrowException() {
+ appendCharAtPosition.addCharUsingStringBuilder(word, letter, word.length() + 2);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenUsingCharacterArrayAndCharacterAddedAtPositionXAndStringIsNull_shouldThrowException() {
+ appendCharAtPosition.addCharUsingStringBuilder(null, letter, 3);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenUsingSubstringAndCharacterAddedAtPositionXAndStringIsNull_shouldThrowException() {
+ appendCharAtPosition.addCharUsingStringBuilder(null, letter, 3);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void whenUsingStringBuilderAndCharacterAddedAtPositionXAndStringIsNull_shouldThrowException() {
+ appendCharAtPosition.addCharUsingStringBuilder(null, letter, 3);
+ }
+
+}
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/synthetic/SyntheticUnitTest.java b/core-java/src/test/java/com/baeldung/synthetic/SyntheticUnitTest.java
new file mode 100644
index 0000000000..20f7647f48
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/synthetic/SyntheticUnitTest.java
@@ -0,0 +1,99 @@
+package com.baeldung.synthetic;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link SyntheticFieldDemo}, {@link SyntheticMethodDemo},
+ * {@link SyntheticConstructorDemo} and {@link BridgeMethodDemo} classes.
+ *
+ * @author Donato Rimenti
+ *
+ */
+public class SyntheticUnitTest {
+
+ /**
+ * Tests that the {@link SyntheticMethodDemo.NestedClass} contains two synthetic
+ * methods.
+ */
+ @Test
+ public void givenSyntheticMethod_whenIsSinthetic_thenTrue() {
+ // Checks that the nested class contains exactly two synthetic methods.
+ Method[] methods = SyntheticMethodDemo.NestedClass.class.getDeclaredMethods();
+ Assert.assertEquals("This class should contain only two methods", 2, methods.length);
+
+ for (Method m : methods) {
+ System.out.println("Method: " + m.getName() + ", isSynthetic: " + m.isSynthetic());
+ Assert.assertTrue("All the methods of this class should be synthetic", m.isSynthetic());
+ }
+ }
+
+ /**
+ * Tests that {@link SyntheticConstructorDemo.NestedClass} contains a synthetic
+ * constructor.
+ */
+ @Test
+ public void givenSyntheticConstructor_whenIsSinthetic_thenTrue() {
+ // Checks that the nested class contains exactly a synthetic
+ // constructor.
+ int syntheticConstructors = 0;
+ Constructor>[] constructors = SyntheticConstructorDemo.NestedClass.class.getDeclaredConstructors();
+ Assert.assertEquals("This class should contain only two constructors", 2, constructors.length);
+
+ for (Constructor> c : constructors) {
+ System.out.println("Constructor: " + c.getName() + ", isSynthetic: " + c.isSynthetic());
+
+ // Counts the synthetic constructors.
+ if (c.isSynthetic()) {
+ syntheticConstructors++;
+ }
+ }
+
+ // Checks that there's exactly one synthetic constructor.
+ Assert.assertEquals(1, syntheticConstructors);
+ }
+
+ /**
+ * Tests that {@link SyntheticFieldDemo.NestedClass} contains a synthetic field.
+ */
+ @Test
+ public void givenSyntheticField_whenIsSinthetic_thenTrue() {
+ // This class should contain exactly one synthetic field.
+ Field[] fields = SyntheticFieldDemo.NestedClass.class.getDeclaredFields();
+ Assert.assertEquals("This class should contain only one field", 1, fields.length);
+
+ for (Field f : fields) {
+ System.out.println("Field: " + f.getName() + ", isSynthetic: " + f.isSynthetic());
+ Assert.assertTrue("All the fields of this class should be synthetic", f.isSynthetic());
+ }
+ }
+
+ /**
+ * Tests that {@link BridgeMethodDemo} contains a synthetic bridge method.
+ */
+ @Test
+ public void givenBridgeMethod_whenIsBridge_thenTrue() {
+ // This class should contain exactly one synthetic bridge method.
+ int syntheticMethods = 0;
+ Method[] methods = BridgeMethodDemo.class.getDeclaredMethods();
+ for (Method m : methods) {
+ System.out.println(
+ "Method: " + m.getName() + ", isSynthetic: " + m.isSynthetic() + ", isBridge: " + m.isBridge());
+
+ // Counts the synthetic methods and checks that they are also bridge
+ // methods.
+ if (m.isSynthetic()) {
+ syntheticMethods++;
+ Assert.assertTrue("The synthetic method in this class should also be a bridge method", m.isBridge());
+ }
+ }
+
+ // Checks that there's exactly one synthetic bridge method.
+ Assert.assertEquals("There should be exactly 1 synthetic bridge method in this class", 1, syntheticMethods);
+ }
+
+}
\ No newline at end of file
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 a86359c02f..0894a57320 100644
--- a/core-kotlin/pom.xml
+++ b/core-kotlin/pom.xml
@@ -3,26 +3,15 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
core-kotlin
- 1.0-SNAPSHOT
jar
com.baeldung
- parent-modules
+ parent-kotlin
1.0.0-SNAPSHOT
+ ../parent-kotlin
-
-
- jcenter
- http://jcenter.bintray.com
-
-
- kotlin-ktor
- https://dl.bintray.com/kotlin/ktor/
-
-
-
org.apache.commons
@@ -35,66 +24,6 @@
${junit.platform.version}
test
-
- org.jetbrains.kotlin
- kotlin-stdlib
- ${kotlin-stdlib.version}
-
-
- org.jetbrains.kotlin
- kotlin-stdlib-jdk8
- ${kotlin-stdlib.version}
-
-
- khttp
- khttp
- ${khttp.version}
-
-
- org.jetbrains.kotlin
- kotlin-test-junit
- ${kotlin-test-junit.version}
- test
-
-
- org.jetbrains.kotlin
- kotlin-reflect
- ${kotlin-reflect.version}
-
-
- org.jetbrains.kotlinx
- kotlinx-coroutines-core
- ${kotlinx.version}
-
-
- 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
-
-
- com.nhaarman
- mockito-kotlin
- ${mockito-kotlin.version}
- test
-
-
- com.github.salomonbrys.kodein
- kodein
- ${kodein.version}
-
org.assertj
assertj-core
@@ -102,142 +31,45 @@
test
- com.beust
- klaxon
- ${klaxon.version}
+ com.h2database
+ h2
+ ${h2database.version}
- io.ktor
- ktor-server-netty
- ${ktor.io.version}
+ com.github.kittinunf.fuel
+ fuel
+ ${fuel.version}
- io.ktor
- ktor-gson
- ${ktor.io.version}
+ com.github.kittinunf.fuel
+ fuel-gson
+ ${fuel.version}
- ch.qos.logback
- logback-classic
- 1.2.1
- test
+ com.github.kittinunf.fuel
+ fuel-rxjava
+ ${fuel.version}
+
+
+ com.github.kittinunf.fuel
+ fuel-coroutines
+ ${fuel.version}
+
+
+ nl.komponents.kovenant
+ kovenant
+ 3.3.0
+ pom
-
-
-
- org.jetbrains.kotlin
- kotlin-maven-plugin
- ${kotlin-maven-plugin.version}
-
-
- compile
-
- compile
-
-
-
- ${project.basedir}/src/main/kotlin
- ${project.basedir}/src/main/java
-
-
-
-
- test-compile
-
- test-compile
-
-
-
- ${project.basedir}/src/test/kotlin
- ${project.basedir}/src/test/java
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- ${maven-compiler-plugin.version}
-
- ${java.version}
- ${java.version}
-
-
-
-
- default-compile
- none
-
-
-
- default-testCompile
- none
-
-
- java-compile
- compile
-
- compile
-
-
-
- java-test-compile
- test-compile
-
- testCompile
-
-
-
-
-
- maven-failsafe-plugin
- ${maven-failsafe-plugin.version}
-
-
- org.junit.platform
- junit-platform-surefire-provider
- ${junit.platform.version}
-
-
-
-
- junit5
-
- integration-test
- verify
-
-
-
- **/*Test5.java
-
-
-
-
-
-
-
-
- UTF-8
- 1.2.60
- 1.2.60
- 1.2.60
- 1.2.60
- 0.22.5
- 0.9.2
- 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
+ 1.15.0
-
\ No newline at end of file
+
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/fuel/Interceptors.kt b/core-kotlin/src/main/kotlin/com/baeldung/fuel/Interceptors.kt
new file mode 100644
index 0000000000..377ef979dc
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/fuel/Interceptors.kt
@@ -0,0 +1,11 @@
+package com.baeldung.fuel
+
+import com.github.kittinunf.fuel.core.Request
+
+fun tokenInterceptor() = {
+ next: (Request) -> Request ->
+ { req: Request ->
+ req.header(mapOf("Authorization" to "Bearer AbCdEf123456"))
+ next(req)
+ }
+}
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/fuel/Post.kt b/core-kotlin/src/main/kotlin/com/baeldung/fuel/Post.kt
new file mode 100644
index 0000000000..035dfe7aa0
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/fuel/Post.kt
@@ -0,0 +1,15 @@
+package com.baeldung.fuel
+
+import com.github.kittinunf.fuel.core.ResponseDeserializable
+import com.google.gson.Gson
+
+data class Post(var userId:Int,
+ var id:Int,
+ var title:String,
+ var body:String){
+
+
+ class Deserializer : ResponseDeserializable> {
+ override fun deserialize(content: String): Array = Gson().fromJson(content, Array::class.java)
+ }
+}
\ No newline at end of file
diff --git a/core-kotlin/src/main/kotlin/com/baeldung/fuel/PostRoutingAPI.kt b/core-kotlin/src/main/kotlin/com/baeldung/fuel/PostRoutingAPI.kt
new file mode 100644
index 0000000000..8238c41e56
--- /dev/null
+++ b/core-kotlin/src/main/kotlin/com/baeldung/fuel/PostRoutingAPI.kt
@@ -0,0 +1,42 @@
+package com.baeldung.fuel
+
+import com.github.kittinunf.fuel.core.Method
+import com.github.kittinunf.fuel.util.FuelRouting
+
+sealed class PostRoutingAPI : FuelRouting {
+
+ override val basePath = "https://jsonplaceholder.typicode.com"
+
+ class posts(val id: String, override val body: String?): PostRoutingAPI()
+
+ class comments(val postId: String, override val body: String?): PostRoutingAPI()
+
+ override val method: Method
+ get() {
+ return when(this) {
+ is PostRoutingAPI.posts -> Method.GET
+ is PostRoutingAPI.comments -> Method.GET
+ }
+ }
+
+ override val path: String
+ get() {
+ return when(this) {
+ is PostRoutingAPI.posts -> "/posts"
+ is PostRoutingAPI.comments -> "/comments"
+ }
+ }
+
+ override val params: List>?
+ get() {
+ return when(this) {
+ is PostRoutingAPI.posts -> listOf("id" to this.id)
+ is PostRoutingAPI.comments -> listOf("postId" to this.postId)
+ }
+ }
+
+ override val headers: Map?
+ get() {
+ return null
+ }
+}
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/builder/BuilderPatternUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/builder/BuilderPatternUnitTest.kt
index 17f5a43479..a6687b6e0a 100644
--- a/core-kotlin/src/test/kotlin/com/baeldung/builder/BuilderPatternUnitTest.kt
+++ b/core-kotlin/src/test/kotlin/com/baeldung/builder/BuilderPatternUnitTest.kt
@@ -93,6 +93,7 @@ internal class BuilderPatternUnitTest {
Assertions.assertNull(foodOrder.fish)
}
+
@Test
fun whenBuildingFoodOrderApplySettingValues_thenFieldsNotNull() {
diff --git a/core-kotlin/src/test/kotlin/com/baeldung/fuel/FuelHttpUnitTest.kt b/core-kotlin/src/test/kotlin/com/baeldung/fuel/FuelHttpUnitTest.kt
new file mode 100644
index 0000000000..f0f9267618
--- /dev/null
+++ b/core-kotlin/src/test/kotlin/com/baeldung/fuel/FuelHttpUnitTest.kt
@@ -0,0 +1,286 @@
+package com.baeldung.fuel
+
+import awaitObjectResult
+import awaitStringResponse
+import com.github.kittinunf.fuel.Fuel
+import com.github.kittinunf.fuel.core.FuelManager
+import com.github.kittinunf.fuel.core.Request
+import com.github.kittinunf.fuel.core.interceptors.cUrlLoggingRequestInterceptor
+import com.github.kittinunf.fuel.gson.responseObject
+import com.github.kittinunf.fuel.httpGet
+import com.github.kittinunf.fuel.rx.rx_object
+import com.google.gson.Gson
+import kotlinx.coroutines.experimental.runBlocking
+import org.junit.jupiter.api.Assertions
+import org.junit.jupiter.api.Test
+import java.io.File
+import java.util.concurrent.CountDownLatch
+
+internal class FuelHttpUnitTest {
+
+ @Test
+ fun whenMakingAsyncHttpGetRequest_thenResponseNotNullAndErrorNullAndStatusCode200() {
+
+ val latch = CountDownLatch(1)
+
+ "http://httpbin.org/get".httpGet().response{
+ request, response, result ->
+
+ val (data, error) = result
+
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(200,response.statusCode)
+
+ latch.countDown()
+ }
+
+ latch.await()
+
+ }
+
+ @Test
+ fun whenMakingSyncHttpGetRequest_thenResponseNotNullAndErrorNullAndStatusCode200() {
+
+ val (request, response, result) = "http://httpbin.org/get".httpGet().response()
+ val (data, error) = result
+
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(200,response.statusCode)
+
+ }
+
+ @Test
+ fun whenMakingSyncHttpGetURLEncodedRequest_thenResponseNotNullAndErrorNullAndStatusCode200() {
+
+ val (request, response, result) =
+ "https://jsonplaceholder.typicode.com/posts"
+ .httpGet(listOf("id" to "1")).response()
+ val (data, error) = result
+
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(200,response.statusCode)
+
+ }
+
+ @Test
+ fun whenMakingAsyncHttpPostRequest_thenResponseNotNullAndErrorNullAndStatusCode200() {
+
+ val latch = CountDownLatch(1)
+
+ Fuel.post("http://httpbin.org/post").response{
+ request, response, result ->
+
+ val (data, error) = result
+
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(200,response.statusCode)
+
+ latch.countDown()
+ }
+
+ latch.await()
+
+ }
+
+ @Test
+ fun whenMakingSyncHttpPostRequest_thenResponseNotNullAndErrorNullAndStatusCode200() {
+
+ val (request, response, result) = Fuel.post("http://httpbin.org/post").response()
+ val (data, error) = result
+
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(200,response.statusCode)
+ }
+
+ @Test
+ fun whenMakingSyncHttpPostRequestwithBody_thenResponseNotNullAndErrorNullAndStatusCode200() {
+
+ val (request, response, result) = Fuel.post("https://jsonplaceholder.typicode.com/posts")
+ .body("{ \"title\" : \"foo\",\"body\" : \"bar\",\"id\" : \"1\"}")
+ .response()
+
+ val (data, error) = result
+
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(201,response.statusCode)
+ }
+
+ @Test
+ fun givenFuelInstance_whenMakingSyncHttpGetRequest_thenResponseNotNullAndErrorNullAndStatusCode200() {
+
+ FuelManager.instance.basePath = "http://httpbin.org"
+ FuelManager.instance.baseHeaders = mapOf("OS" to "macOS High Sierra")
+
+ FuelManager.instance.addRequestInterceptor(cUrlLoggingRequestInterceptor())
+ FuelManager.instance.addRequestInterceptor(tokenInterceptor())
+
+
+ val (request, response, result) = "/get"
+ .httpGet().response()
+ val (data, error) = result
+
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(200,response.statusCode)
+ }
+
+ @Test
+ fun givenInterceptors_whenMakingSyncHttpGetRequest_thenResponseNotNullAndErrorNullAndStatusCode200() {
+
+ FuelManager.instance.basePath = "http://httpbin.org"
+ FuelManager.instance.addRequestInterceptor(cUrlLoggingRequestInterceptor())
+ FuelManager.instance.addRequestInterceptor(tokenInterceptor())
+
+ val (request, response, result) = "/get"
+ .httpGet().response()
+ val (data, error) = result
+
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(200,response.statusCode)
+ }
+
+ @Test
+ fun whenDownloadFile_thenCreateFileResponseNotNullAndErrorNullAndStatusCode200() {
+
+ Fuel.download("http://httpbin.org/bytes/32768").destination { response, url ->
+ File.createTempFile("temp", ".tmp")
+ }.response{
+ request, response, result ->
+
+ val (data, error) = result
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(200,response.statusCode)
+ }
+ }
+
+ @Test
+ fun whenDownloadFilewithProgressHandler_thenCreateFileResponseNotNullAndErrorNullAndStatusCode200() {
+
+ val (request, response, result) = Fuel.download("http://httpbin.org/bytes/327680")
+ .destination { response, url -> File.createTempFile("temp", ".tmp")
+ }.progress { readBytes, totalBytes ->
+ val progress = readBytes.toFloat() / totalBytes.toFloat()
+ }.response ()
+
+ val (data, error) = result
+ Assertions.assertNull(error)
+ Assertions.assertNotNull(data)
+ Assertions.assertEquals(200,response.statusCode)
+
+
+ }
+
+ @Test
+ fun whenMakeGetRequest_thenDeserializePostwithGson() {
+
+ val latch = CountDownLatch(1)
+
+ "https://jsonplaceholder.typicode.com/posts/1".httpGet().responseObject { _,_, result ->
+ val post = result.component1()
+ Assertions.assertEquals(1, post?.userId)
+ latch.countDown()
+ }
+
+ latch.await()
+
+ }
+
+ @Test
+ fun whenMakePOSTRequest_thenSerializePostwithGson() {
+
+ val post = Post(1,1, "Lorem", "Lorem Ipse dolor sit amet")
+
+ val (request, response, result) = Fuel.post("https://jsonplaceholder.typicode.com/posts")
+ .header("Content-Type" to "application/json")
+ .body(Gson().toJson(post).toString())
+ .response()
+
+ Assertions.assertEquals(201,response.statusCode)
+
+ }
+
+ @Test
+ fun whenMakeGETRequestWithRxJava_thenDeserializePostwithGson() {
+
+ val latch = CountDownLatch(1)
+
+
+ "https://jsonplaceholder.typicode.com/posts?id=1"
+ .httpGet().rx_object(Post.Deserializer()).subscribe{
+ res, throwable ->
+
+ val post = res.component1()
+ Assertions.assertEquals(1, post?.get(0)?.userId)
+ latch.countDown()
+ }
+
+ latch.await()
+
+ }
+
+ @Test
+ fun whenMakeGETRequestUsingCoroutines_thenResponseStatusCode200() {
+
+ runBlocking {
+ val (request, response, result) = Fuel.get("http://httpbin.org/get").awaitStringResponse()
+
+ result.fold({ data ->
+ Assertions.assertEquals(200, response.statusCode)
+
+ }, { error -> })
+ }
+
+ }
+
+ @Test
+ fun whenMakeGETRequestUsingCoroutines_thenDeserializeResponse() {
+
+
+ runBlocking {
+ Fuel.get("https://jsonplaceholder.typicode.com/posts?id=1").awaitObjectResult(Post.Deserializer())
+ .fold({ data ->
+ Assertions.assertEquals(1, data.get(0).userId)
+ }, { error -> })
+ }
+
+ }
+
+ @Test
+ fun whenMakeGETPostRequestUsingRoutingAPI_thenDeserializeResponse() {
+
+ val latch = CountDownLatch(1)
+
+ Fuel.request(PostRoutingAPI.posts("1",null))
+ .responseObject(Post.Deserializer()) {
+ request, response, result ->
+ Assertions.assertEquals(1, result.component1()?.get(0)?.userId)
+ latch.countDown()
+ }
+
+ latch.await()
+ }
+
+ @Test
+ fun whenMakeGETCommentRequestUsingRoutingAPI_thenResponseStausCode200() {
+
+ val latch = CountDownLatch(1)
+
+ Fuel.request(PostRoutingAPI.comments("1",null))
+ .responseString { request, response, result ->
+ Assertions.assertEquals(200, response.statusCode)
+ latch.countDown()
+ }
+
+ latch.await()
+ }
+
+
+}
\ 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/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/couchbase/pom.xml b/couchbase/pom.xml
index f6397fe309..4f0f8787ca 100644
--- a/couchbase/pom.xml
+++ b/couchbase/pom.xml
@@ -3,11 +3,11 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.baeldung
- couchbase-sdk
+ couchbase
0.1-SNAPSHOT
jar
couchbase
- Couchbase SDK Tutorials
+ Couchbase Tutorials
com.baeldung
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/drools/pom.xml b/drools/pom.xml
index 631bc8c792..009ac8acec 100644
--- a/drools/pom.xml
+++ b/drools/pom.xml
@@ -48,12 +48,18 @@
poi-ooxml
${apache-poi-version}
+
+ org.optaplanner
+ optaplanner-core
+ ${opta-planner-version}
+
4.4.6
7.4.1.Final
3.13
+ 7.10.0.Final
diff --git a/drools/src/main/java/com/baeldung/drools/optaplanner/CourseSchedule.java b/drools/src/main/java/com/baeldung/drools/optaplanner/CourseSchedule.java
new file mode 100644
index 0000000000..7b2ba117a1
--- /dev/null
+++ b/drools/src/main/java/com/baeldung/drools/optaplanner/CourseSchedule.java
@@ -0,0 +1,63 @@
+package com.baeldung.drools.optaplanner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
+import org.optaplanner.core.api.domain.solution.PlanningScore;
+import org.optaplanner.core.api.domain.solution.PlanningSolution;
+import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
+import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
+import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@PlanningSolution
+public class CourseSchedule {
+
+ Logger logger = LoggerFactory.getLogger("CourseSchedule");
+
+ private List roomList;
+ private List periodList;
+ private List lectureList;
+ private HardSoftScore score;
+
+ public CourseSchedule(){
+ roomList = new ArrayList<>();
+ periodList = new ArrayList<>();
+ lectureList = new ArrayList<>();
+ }
+
+ @ValueRangeProvider(id = "availableRooms")
+ @ProblemFactCollectionProperty
+ public List getRoomList() {
+ return roomList;
+ }
+
+ @ValueRangeProvider(id = "availablePeriods")
+ @ProblemFactCollectionProperty
+ public List getPeriodList() {
+ return periodList;
+ }
+
+ @PlanningEntityCollectionProperty
+ public List getLectureList() {
+ return lectureList;
+ }
+
+ @PlanningScore
+ public HardSoftScore getScore() {
+ return score;
+ }
+
+ public void setScore(HardSoftScore score) {
+ this.score = score;
+ }
+
+ public void printCourseSchedule() {
+ lectureList.stream()
+ .map(c -> "Lecture in Room " + c.getRoomNumber().toString() + " during Period " + c.getPeriod().toString())
+ .forEach(k -> logger.info(k));
+ }
+
+}
diff --git a/drools/src/main/java/com/baeldung/drools/optaplanner/Lecture.java b/drools/src/main/java/com/baeldung/drools/optaplanner/Lecture.java
new file mode 100644
index 0000000000..193cdb08b1
--- /dev/null
+++ b/drools/src/main/java/com/baeldung/drools/optaplanner/Lecture.java
@@ -0,0 +1,30 @@
+package com.baeldung.drools.optaplanner;
+
+import org.optaplanner.core.api.domain.entity.PlanningEntity;
+import org.optaplanner.core.api.domain.variable.PlanningVariable;
+
+@PlanningEntity
+public class Lecture {
+
+ private Integer roomNumber;
+ private Integer period;
+
+ @PlanningVariable(valueRangeProviderRefs = {"availablePeriods"})
+ public Integer getPeriod() {
+ return period;
+ }
+
+ @PlanningVariable(valueRangeProviderRefs = {"availableRooms"})
+ public Integer getRoomNumber() {
+ return roomNumber;
+ }
+
+ public void setPeriod(Integer period) {
+ this.period = period;
+ }
+
+ public void setRoomNumber(Integer roomNumber) {
+ this.roomNumber = roomNumber;
+ }
+
+}
diff --git a/drools/src/main/java/com/baeldung/drools/optaplanner/ScoreCalculator.java b/drools/src/main/java/com/baeldung/drools/optaplanner/ScoreCalculator.java
new file mode 100644
index 0000000000..86501cdccd
--- /dev/null
+++ b/drools/src/main/java/com/baeldung/drools/optaplanner/ScoreCalculator.java
@@ -0,0 +1,32 @@
+package com.baeldung.drools.optaplanner;
+
+import java.util.HashSet;
+
+import org.optaplanner.core.api.score.Score;
+import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScore;
+import org.optaplanner.core.impl.score.director.easy.EasyScoreCalculator;
+
+public class ScoreCalculator implements EasyScoreCalculator {
+
+ @Override
+ public Score calculateScore(CourseSchedule courseSchedule) {
+ int hardScore = 0;
+ int softScore = 0;
+
+ HashSet occupiedRooms = new HashSet<>();
+ for (Lecture lecture : courseSchedule.getLectureList()) {
+ if(lecture.getPeriod() != null && lecture.getRoomNumber() != null) {
+ String roomInUse = lecture.getPeriod().toString() + ":" + lecture.getRoomNumber().toString();
+ if (occupiedRooms.contains(roomInUse)) {
+ hardScore += -1;
+ } else {
+ occupiedRooms.add(roomInUse);
+ }
+ } else {
+ hardScore += -1;
+ }
+ }
+
+ return HardSoftScore.valueOf(hardScore, softScore);
+ }
+}
diff --git a/drools/src/main/resources/courseSchedule.drl b/drools/src/main/resources/courseSchedule.drl
new file mode 100644
index 0000000000..35dd57df84
--- /dev/null
+++ b/drools/src/main/resources/courseSchedule.drl
@@ -0,0 +1,14 @@
+package com.baeldung.drools.optaplanner
+
+import com.baeldung.drools.optaplanner.Lecture;
+import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder;
+
+global HardSoftScoreHolder scoreHolder;
+
+rule "noNullRoomPeriod"
+ when
+ Lecture( roomNumber == null );
+ Lecture( period == null );
+ then
+ scoreHolder.addHardConstraintMatch(kcontext, -1);
+end
\ No newline at end of file
diff --git a/drools/src/main/resources/courseScheduleSolverConfigDrools.xml b/drools/src/main/resources/courseScheduleSolverConfigDrools.xml
new file mode 100644
index 0000000000..7cf95fdcd3
--- /dev/null
+++ b/drools/src/main/resources/courseScheduleSolverConfigDrools.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ courseSchedule.drl
+
+
+
+ 10
+
+
\ No newline at end of file
diff --git a/drools/src/main/resources/courseScheduleSolverConfiguration.xml b/drools/src/main/resources/courseScheduleSolverConfiguration.xml
new file mode 100644
index 0000000000..dfedb8f2fd
--- /dev/null
+++ b/drools/src/main/resources/courseScheduleSolverConfiguration.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ com.baeldung.drools.optaplanner.ScoreCalculator
+
+
+
+ 10
+
+
\ No newline at end of file
diff --git a/drools/src/test/java/com/baeldung/drools/optaplanner/OptaPlannerUnitTest.java b/drools/src/test/java/com/baeldung/drools/optaplanner/OptaPlannerUnitTest.java
new file mode 100644
index 0000000000..1880e30b86
--- /dev/null
+++ b/drools/src/test/java/com/baeldung/drools/optaplanner/OptaPlannerUnitTest.java
@@ -0,0 +1,49 @@
+package com.baeldung.drools.optaplanner;
+
+import java.util.Arrays;
+
+import org.junit.Assert;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.optaplanner.core.api.solver.Solver;
+import org.optaplanner.core.api.solver.SolverFactory;
+
+public class OptaPlannerUnitTest {
+
+ static CourseSchedule unsolvedCourseSchedule;
+
+ @BeforeAll
+ public static void setUp() {
+
+ unsolvedCourseSchedule = new CourseSchedule();
+
+ for(int i = 0; i < 10; i++){
+ unsolvedCourseSchedule.getLectureList().add(new Lecture());
+ }
+
+ unsolvedCourseSchedule.getPeriodList().addAll(Arrays.asList(new Integer[] { 1, 2, 3 }));
+ unsolvedCourseSchedule.getRoomList().addAll(Arrays.asList(new Integer[] { 1, 2 }));
+ }
+
+ @Test
+ public void test_whenCustomJavaSolver() {
+
+ SolverFactory solverFactory = SolverFactory.createFromXmlResource("courseScheduleSolverConfiguration.xml");
+ Solver solver = solverFactory.buildSolver();
+ CourseSchedule solvedCourseSchedule = solver.solve(unsolvedCourseSchedule);
+
+ Assert.assertNotNull(solvedCourseSchedule.getScore());
+ Assert.assertEquals(-4, solvedCourseSchedule.getScore().getHardScore());
+ }
+
+ @Test
+ public void test_whenDroolsSolver() {
+
+ SolverFactory solverFactory = SolverFactory.createFromXmlResource("courseScheduleSolverConfigDrools.xml");
+ Solver solver = solverFactory.buildSolver();
+ CourseSchedule solvedCourseSchedule = solver.solve(unsolvedCourseSchedule);
+
+ Assert.assertNotNull(solvedCourseSchedule.getScore());
+ Assert.assertEquals(0, solvedCourseSchedule.getScore().getHardScore());
+ }
+}
diff --git a/ejb/ejb-client/pom.xml b/ejb/ejb-client/pom.xml
index 44112a4396..6231030cec 100755
--- a/ejb/ejb-client/pom.xml
+++ b/ejb/ejb-client/pom.xml
@@ -16,7 +16,6 @@
org.wildfly
wildfly-ejb-client-bom
pom
- import
com.baeldung.ejb
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/ejb/pom.xml b/ejb/pom.xml
index a188d43272..4cb700d087 100755
--- a/ejb/pom.xml
+++ b/ejb/pom.xml
@@ -17,7 +17,6 @@
ejb-remote
- ejb-client
ejb-session-beans
diff --git a/ejb/wildfly/pom.xml b/ejb/wildfly/pom.xml
index 7159096f3c..53d10a90ed 100644
--- a/ejb/wildfly/pom.xml
+++ b/ejb/wildfly/pom.xml
@@ -2,9 +2,10 @@
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.wildfly
- wildfly-example
+ wildfly
0.0.1-SNAPSHOT
pom
+ wildfly
com.baeldung.ejb
diff --git a/ejb/wildfly/wildfly-mdb/pom.xml b/ejb/wildfly/wildfly-mdb/pom.xml
index 0b2ec7d5a3..186ddc50c0 100644
--- a/ejb/wildfly/wildfly-mdb/pom.xml
+++ b/ejb/wildfly/wildfly-mdb/pom.xml
@@ -1,8 +1,9 @@
4.0.0
- widlfly-mdb
-
+ wildfly-mdb
+ wildfly-mdb
+
com.baeldung.wildfly
wildfly-example
diff --git a/enterprise-patterns/README.md b/enterprise-patterns/README.md
deleted file mode 100644
index ff12555376..0000000000
--- a/enterprise-patterns/README.md
+++ /dev/null
@@ -1 +0,0 @@
-## Relevant articles:
diff --git a/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/AuditFilter.java b/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/AuditFilter.java
deleted file mode 100644
index d24c0a94b3..0000000000
--- a/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/AuditFilter.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.baeldung.enterprise.patterns.front.controller.filters;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-import java.io.IOException;
-
-public class AuditFilter extends BaseFilter {
- @Override
- public void doFilter(
- ServletRequest request,
- ServletResponse response,
- FilterChain chain
- ) throws IOException, ServletException {
- HttpServletRequest httpServletRequest = (HttpServletRequest) request;
- HttpSession session = httpServletRequest.getSession(false);
- if (session != null && session.getAttribute("username") != null) {
- request.setAttribute("username", session.getAttribute("username"));
- }
- chain.doFilter(request, response);
- }
-}
diff --git a/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/VisitorCounterFilter.java b/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/VisitorCounterFilter.java
deleted file mode 100644
index 0ae7cd73fd..0000000000
--- a/enterprise-patterns/intercepting-filter-pattern/src/main/java/com/baeldung/enterprise/patterns/front/controller/filters/VisitorCounterFilter.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.baeldung.enterprise.patterns.front.controller.filters;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.annotation.WebFilter;
-import java.io.IOException;
-
-@WebFilter(servletNames = "front-controller")
-public class VisitorCounterFilter extends BaseFilter {
- private int counter;
-
- @Override
- public void doFilter(
- ServletRequest request,
- ServletResponse response,
- FilterChain chain
- ) throws IOException, ServletException {
- request.setAttribute("counter", ++counter);
- chain.doFilter(request, response);
- }
-}
diff --git a/enterprise-patterns/pom.xml b/enterprise-patterns/pom.xml
deleted file mode 100644
index ffd0b66aad..0000000000
--- a/enterprise-patterns/pom.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
- 4.0.0
- com.baeldung.enterprise.patterns
- enterprise-patterns-parent
- pom
-
-
- com.baeldung
- parent-modules
- 1.0.0-SNAPSHOT
-
-
-
- spring-dispatcher-servlet
-
-
-
diff --git a/feign/pom.xml b/feign/pom.xml
index 29c2a784bc..ea645383c1 100644
--- a/feign/pom.xml
+++ b/feign/pom.xml
@@ -3,7 +3,8 @@
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.feign
- feign-client
+ feign
+ feign
com.baeldung
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/google-web-toolkit/pom.xml b/google-web-toolkit/pom.xml
index b2f7cab355..db9ce2eac0 100644
--- a/google-web-toolkit/pom.xml
+++ b/google-web-toolkit/pom.xml
@@ -6,10 +6,11 @@
4.0.0
com.baeldung
- google_web_toolkit
+ google-web-toolkit
war
1.0-SNAPSHOT
-
+ google-web-toolkit
+
com.baeldung
parent-modules
diff --git a/grpc/pom.xml b/grpc/pom.xml
index 218e2df008..949f26d376 100644
--- a/grpc/pom.xml
+++ b/grpc/pom.xml
@@ -1,11 +1,11 @@
4.0.0
- grpc
- grpc-demo
+ grpc
0.0.1-SNAPSHOT
jar
-
+ grpc
+
com.baeldung
parent-modules
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/remote-debugging/pom.xml b/guest/remote-debugging/pom.xml
index 67fed3f1a1..974421de97 100644
--- a/guest/remote-debugging/pom.xml
+++ b/guest/remote-debugging/pom.xml
@@ -3,9 +3,10 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.stackify
- java-remote-debugging
+ remote-debugging
0.0.1-SNAPSHOT
war
+ remote-debugging
org.springframework.boot
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..b67ab7115f 100644
--- a/hibernate5/README.md
+++ b/hibernate5/README.md
@@ -13,3 +13,5 @@
- [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)
+- [@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/joincolumn/Address.java b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Address.java
new file mode 100644
index 0000000000..8b0a51858d
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Address.java
@@ -0,0 +1,34 @@
+package com.baeldung.hibernate.joincolumn;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class Address {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ @Column(name = "ZIP")
+ private String zipCode;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getZipCode() {
+ return zipCode;
+ }
+
+ public void setZipCode(String zipCode) {
+ this.zipCode = zipCode;
+ }
+}
\ No newline at end of file
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java
new file mode 100644
index 0000000000..a91fb3b4c9
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Email.java
@@ -0,0 +1,47 @@
+package com.baeldung.hibernate.joincolumn;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+
+@Entity
+public class Email {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ private String address;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "employee_id")
+ private Employee employee;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public Employee getEmployee() {
+ return employee;
+ }
+
+ public void setEmployee(Employee employee) {
+ this.employee = employee;
+ }
+}
\ No newline at end of file
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Employee.java b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Employee.java
new file mode 100644
index 0000000000..3fbdb3820e
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Employee.java
@@ -0,0 +1,36 @@
+package com.baeldung.hibernate.joincolumn;
+
+import java.util.List;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+
+@Entity
+public class Employee {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ @OneToMany(fetch = FetchType.LAZY, mappedBy = "employee")
+ private List emails;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public List getEmails() {
+ return emails;
+ }
+
+ public void setEmails(List emails) {
+ this.emails = emails;
+ }
+}
\ No newline at end of file
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java
new file mode 100644
index 0000000000..e5b9dc06bc
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/joincolumn/Office.java
@@ -0,0 +1,41 @@
+package com.baeldung.hibernate.joincolumn;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.ManyToOne;
+
+@Entity
+public class Office {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumns({
+ @JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
+ @JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP")
+ })
+ private Address address;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+}
\ No newline at end of file
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/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/joincolumn/JoinColumnIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java
new file mode 100644
index 0000000000..8246a2b01e
--- /dev/null
+++ b/hibernate5/src/test/java/com/baeldung/hibernate/joincolumn/JoinColumnIntegrationTest.java
@@ -0,0 +1,57 @@
+package com.baeldung.hibernate.joincolumn;
+
+import com.baeldung.hibernate.HibernateUtil;
+import java.io.IOException;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class JoinColumnIntegrationTest {
+
+ private Session session;
+ private Transaction transaction;
+
+ @Before
+ public void setUp() throws IOException {
+ session = HibernateUtil.getSessionFactory("hibernate-spatial.properties")
+ .openSession();
+ transaction = session.beginTransaction();
+ }
+
+ @After
+ public void tearDown() {
+ transaction.rollback();
+ session.close();
+ }
+
+ @Test
+ public void givenOfficeEntity_setAddress_shouldPersist() {
+ Office office = new Office();
+
+ Address address = new Address();
+ address.setZipCode("11-111");
+ office.setAddress(address);
+
+ session.save(office);
+ session.flush();
+ session.clear();
+ }
+
+ @Test
+ public void givenEmployeeEntity_setEmails_shouldPersist() {
+ Employee employee = new Employee();
+
+ Email email = new Email();
+ email.setAddress("example@email.com");
+ email.setEmployee(employee);
+
+ session.save(employee);
+ session.flush();
+ session.clear();
+ }
+
+}
\ No newline at end of file
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/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 3fcbca1ebd..9592e11961 100644
--- a/jackson/pom.xml
+++ b/jackson/pom.xml
@@ -1,7 +1,6 @@
4.0.0
- com.baeldung
jackson
0.1-SNAPSHOT
jackson
@@ -119,17 +118,16 @@
- 2.9.4
+ 2.9.6
- 19.0
- 3.5
- 2.9.6
- 2.8.0
- 4.1
+ 3.8
+ 2.10
+ 2.8.5
+ 4.2
- 3.0.1
- 3.6.1
+ 3.1.1
+ 3.11.0
diff --git a/java-dates/.gitignore b/java-dates/.gitignore
new file mode 100644
index 0000000000..3de4cc647e
--- /dev/null
+++ b/java-dates/.gitignore
@@ -0,0 +1,26 @@
+*.class
+
+0.*
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+.resourceCache
+
+# Packaged files #
+*.jar
+*.war
+*.ear
+
+# Files generated by integration tests
+*.txt
+backup-pom.xml
+/bin/
+/temp
+
+#IntelliJ specific
+.idea/
+*.iml
\ No newline at end of file
diff --git a/java-dates/README.md b/java-dates/README.md
new file mode 100644
index 0000000000..54843f90ee
--- /dev/null
+++ b/java-dates/README.md
@@ -0,0 +1,24 @@
+=========
+
+## Java Dates Cookbooks and Examples
+
+### Relevant Articles:
+- [TemporalAdjuster in Java](http://www.baeldung.com/java-temporal-adjuster)
+- [Handling Daylight Savings Time in Java](http://www.baeldung.com/java-daylight-savings)
+- [Period and Duration in Java](http://www.baeldung.com/java-period-duration)
+- [Difference Between Two Dates in Java](http://www.baeldung.com/java-date-difference)
+- [RegEx for matching Date Pattern in Java](http://www.baeldung.com/java-date-regular-expressions)
+- [Migrating to the New Java 8 Date Time API](http://www.baeldung.com/migrating-to-java-8-date-time-api)
+- [Introduction to the Java 8 Date/Time API](http://www.baeldung.com/java-8-date-time-intro)
+- [Get the Current Date, Time and Timestamp in Java 8](http://www.baeldung.com/current-date-time-and-timestamp-in-java-8)
+- [Get Date Without Time in Java](http://www.baeldung.com/java-date-without-time)
+- [How to Get All Dates Between Two Dates?](http://www.baeldung.com/java-between-dates)
+- [Convert Date to LocalDate or LocalDateTime and Back](http://www.baeldung.com/java-date-to-localdate-and-localdatetime)
+- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones)
+- [Extracting Year, Month and Day from Date in Java](http://www.baeldung.com/java-year-month-day)
+- [Guide to java.util.GregorianCalendar](http://www.baeldung.com/java-gregorian-calendar)
+- [Measure Elapsed Time in Java](http://www.baeldung.com/java-measure-elapsed-time)
+- [How to Get the Start and the End of a Day using Java](http://www.baeldung.com/java-day-start-end)
+- [Calculate Age in Java](http://www.baeldung.com/java-get-age)
+- [Increment Date in Java](http://www.baeldung.com/java-increment-date)
+- [Add Hours To a Date In Java](http://www.baeldung.com/java-add-hours-date)
\ No newline at end of file
diff --git a/java-dates/pom.xml b/java-dates/pom.xml
new file mode 100644
index 0000000000..13e2a077e1
--- /dev/null
+++ b/java-dates/pom.xml
@@ -0,0 +1,86 @@
+
+ 4.0.0
+ com.baeldung
+ java-dates
+ 0.1.0-SNAPSHOT
+ jar
+ java-dates
+
+
+ com.baeldung
+ parent-java
+ 0.0.1-SNAPSHOT
+ ../parent-java
+
+
+
+
+ org.apache.commons
+ commons-lang3
+ ${commons-lang3.version}
+
+
+ log4j
+ log4j
+ ${log4j.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ provided
+
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ joda-time
+ joda-time
+ ${joda-time.version}
+
+
+ com.darwinsys
+ hirondelle-date4j
+ RELEASE
+ test
+
+
+
+
+ java-dates
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven-compiler-plugin.version}
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+
+
+
+
+
+
+
+ 3.5
+ 1.16.12
+ 2.10
+
+ 3.6.1
+ 9
+ 9
+
+
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/core-java/src/main/java/com/baeldung/date/DateWithoutTime.java b/java-dates/src/main/java/com/baeldung/date/DateWithoutTime.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/date/DateWithoutTime.java
rename to java-dates/src/main/java/com/baeldung/date/DateWithoutTime.java
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/AddHoursToDate.java b/java-dates/src/main/java/com/baeldung/datetime/AddHoursToDate.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/AddHoursToDate.java
rename to java-dates/src/main/java/com/baeldung/datetime/AddHoursToDate.java
diff --git a/core-java/src/main/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValues.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValues.java
rename to java-dates/src/main/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValues.java
diff --git a/core-java/src/main/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValues.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValues.java
rename to java-dates/src/main/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValues.java
diff --git a/core-java/src/main/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValues.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValues.java
rename to java-dates/src/main/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValues.java
diff --git a/core-java/src/main/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValues.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValues.java
rename to java-dates/src/main/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValues.java
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/README.md b/java-dates/src/main/java/com/baeldung/datetime/README.md
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/README.md
rename to java-dates/src/main/java/com/baeldung/datetime/README.md
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java b/java-dates/src/main/java/com/baeldung/datetime/UseDuration.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/UseDuration.java
rename to java-dates/src/main/java/com/baeldung/datetime/UseDuration.java
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java b/java-dates/src/main/java/com/baeldung/datetime/UseLocalDate.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/UseLocalDate.java
rename to java-dates/src/main/java/com/baeldung/datetime/UseLocalDate.java
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java b/java-dates/src/main/java/com/baeldung/datetime/UseLocalDateTime.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/UseLocalDateTime.java
rename to java-dates/src/main/java/com/baeldung/datetime/UseLocalDateTime.java
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java b/java-dates/src/main/java/com/baeldung/datetime/UseLocalTime.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/UseLocalTime.java
rename to java-dates/src/main/java/com/baeldung/datetime/UseLocalTime.java
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java b/java-dates/src/main/java/com/baeldung/datetime/UsePeriod.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/UsePeriod.java
rename to java-dates/src/main/java/com/baeldung/datetime/UsePeriod.java
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java b/java-dates/src/main/java/com/baeldung/datetime/UseToInstant.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/UseToInstant.java
rename to java-dates/src/main/java/com/baeldung/datetime/UseToInstant.java
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java b/java-dates/src/main/java/com/baeldung/datetime/UseZonedDateTime.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/UseZonedDateTime.java
rename to java-dates/src/main/java/com/baeldung/datetime/UseZonedDateTime.java
diff --git a/core-java/src/main/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValues.java b/java-dates/src/main/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValues.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValues.java
rename to java-dates/src/main/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValues.java
diff --git a/core-java-8/src/main/java/com/baeldung/datetime/modify/DateIncrementer.java b/java-dates/src/main/java/com/baeldung/datetime/modify/DateIncrementer.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/datetime/modify/DateIncrementer.java
rename to java-dates/src/main/java/com/baeldung/datetime/modify/DateIncrementer.java
diff --git a/core-java/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java b/java-dates/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java
rename to java-dates/src/main/java/com/baeldung/gregorian/calendar/GregorianCalendarExample.java
diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java b/java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java
similarity index 100%
rename from core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java
rename to java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateConverter.java
diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java b/java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java
similarity index 100%
rename from core-java-9/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java
rename to java-dates/src/main/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverter.java
diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java b/java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java
similarity index 100%
rename from core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java
rename to java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverter.java
diff --git a/core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java b/java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java
similarity index 100%
rename from core-java-9/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java
rename to java-dates/src/main/java/com/baeldung/java9/datetime/LocalDateToDateConverter.java
diff --git a/core-java-9/src/main/java/com/baeldung/java9/time/TimeApi.java b/java-dates/src/main/java/com/baeldung/java9/time/TimeApi.java
similarity index 100%
rename from core-java-9/src/main/java/com/baeldung/java9/time/TimeApi.java
rename to java-dates/src/main/java/com/baeldung/java9/time/TimeApi.java
diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/DateMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/DateMatcher.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/regexp/datepattern/DateMatcher.java
rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/DateMatcher.java
diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/FormattedDateMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/FormattedDateMatcher.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/regexp/datepattern/FormattedDateMatcher.java
rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/FormattedDateMatcher.java
diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/RangedDateMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/RangedDateMatcher.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/regexp/datepattern/RangedDateMatcher.java
rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/RangedDateMatcher.java
diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java
rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcher.java
diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcher.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcher.java
rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcher.java
diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java
rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcher.java
diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcher.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcher.java
rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcher.java
diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcher.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcher.java
rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcher.java
diff --git a/core-java/src/main/java/com/baeldung/regexp/datepattern/optmization/OptimizedMatcher.java b/java-dates/src/main/java/com/baeldung/regexp/datepattern/optmization/OptimizedMatcher.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/regexp/datepattern/optmization/OptimizedMatcher.java
rename to java-dates/src/main/java/com/baeldung/regexp/datepattern/optmization/OptimizedMatcher.java
diff --git a/core-java-8/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java b/java-dates/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java
rename to java-dates/src/main/java/com/baeldung/temporaladjuster/CustomTemporalAdjuster.java
diff --git a/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java b/java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java
rename to java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplay.java
diff --git a/core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java b/java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java
similarity index 100%
rename from core-java-8/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java
rename to java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayApp.java
diff --git a/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java b/java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java
rename to java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7.java
diff --git a/core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java b/java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java
similarity index 100%
rename from core-java/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java
rename to java-dates/src/main/java/com/baeldung/timezonedisplay/TimezoneDisplayJava7App.java
diff --git a/enterprise-patterns/intercepting-filter-pattern/src/main/resources/logback.xml b/java-dates/src/main/resources/logback.xml
similarity index 100%
rename from enterprise-patterns/intercepting-filter-pattern/src/main/resources/logback.xml
rename to java-dates/src/main/resources/logback.xml
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/libraries/src/test/java/com/baeldung/date/DateDiffUnitTest.java b/java-dates/src/test/java/com/baeldung/date/DateDiffUnitTest.java
similarity index 100%
rename from libraries/src/test/java/com/baeldung/date/DateDiffUnitTest.java
rename to java-dates/src/test/java/com/baeldung/date/DateDiffUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/date/DateWithoutTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/date/DateWithoutTimeUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/date/DateWithoutTimeUnitTest.java
rename to java-dates/src/test/java/com/baeldung/date/DateWithoutTimeUnitTest.java
diff --git a/libraries/src/test/java/com/baeldung/date/StringToDateUnitTest.java b/java-dates/src/test/java/com/baeldung/date/StringToDateUnitTest.java
similarity index 100%
rename from libraries/src/test/java/com/baeldung/date/StringToDateUnitTest.java
rename to java-dates/src/test/java/com/baeldung/date/StringToDateUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/ConversionExample.java b/java-dates/src/test/java/com/baeldung/dateapi/ConversionExample.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/dateapi/ConversionExample.java
rename to java-dates/src/test/java/com/baeldung/dateapi/ConversionExample.java
diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/JavaDurationUnitTest.java b/java-dates/src/test/java/com/baeldung/dateapi/JavaDurationUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/dateapi/JavaDurationUnitTest.java
rename to java-dates/src/test/java/com/baeldung/dateapi/JavaDurationUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/JavaPeriodUnitTest.java b/java-dates/src/test/java/com/baeldung/dateapi/JavaPeriodUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/dateapi/JavaPeriodUnitTest.java
rename to java-dates/src/test/java/com/baeldung/dateapi/JavaPeriodUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java
rename to java-dates/src/test/java/com/baeldung/dateapi/JavaUtilTimeUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/AddHoursToDateUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValuesUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValuesUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/DateExtractYearMonthDayIntegerValuesUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValuesUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValuesUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/LocalDateExtractYearMonthDayIntegerValuesUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValuesUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValuesUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/LocalDateTimeExtractYearMonthDayIntegerValuesUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValuesUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValuesUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/OffsetDateTimeExtractYearMonthDayIntegerValuesUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/UseLocalDateTimeUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/UseLocalDateUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/UseLocalTimeUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/UsePeriodUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseTimeZoneUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseTimeZoneUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/datetime/UseTimeZoneUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/UseTimeZoneUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/UseZonedDateTimeUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValuesUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValuesUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValuesUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/ZonedDateTimeExtractYearMonthDayIntegerValuesUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/datetime/modify/DateIncrementerUnitTest.java b/java-dates/src/test/java/com/baeldung/datetime/modify/DateIncrementerUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/datetime/modify/DateIncrementerUnitTest.java
rename to java-dates/src/test/java/com/baeldung/datetime/modify/DateIncrementerUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesUnitTest.java b/java-dates/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesUnitTest.java
rename to java-dates/src/test/java/com/baeldung/dst/DaylightSavingTimeExamplesUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesUnitTest.java b/java-dates/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesUnitTest.java
rename to java-dates/src/test/java/com/baeldung/dst/DaylightSavingTimeJavaTimeExamplesUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java b/java-dates/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java
rename to java-dates/src/test/java/com/baeldung/gregorian/calendar/GregorianCalendarTester.java
diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java b/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterUnitTest.java
similarity index 98%
rename from core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java
rename to java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterUnitTest.java
index ab69bba359..f7f07500f1 100644
--- a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterTest.java
+++ b/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateConverterUnitTest.java
@@ -20,7 +20,7 @@ import com.baeldung.java9.datetime.DateToLocalDateConverter;
* @author abialas
*
*/
-public class DateToLocalDateConverterTest {
+public class DateToLocalDateConverterUnitTest {
@Test
public void shouldReturn10thNovember2010WhenConvertViaInstant() {
diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java b/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterUnitTest.java
similarity index 98%
rename from core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java
rename to java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterUnitTest.java
index 97c70ee5ac..9ad29ea673 100644
--- a/core-java-9/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterTest.java
+++ b/java-dates/src/test/java/com/baeldung/java9/datetime/DateToLocalDateTimeConverterUnitTest.java
@@ -20,7 +20,7 @@ import com.baeldung.java9.datetime.DateToLocalDateTimeConverter;
* @author abialas
*
*/
-public class DateToLocalDateTimeConverterTest {
+public class DateToLocalDateTimeConverterUnitTest {
@Test
public void shouldReturn10thNovember2010time8hour20minWhenConvertViaInstant() {
diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterTest.java b/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterUnitTest.java
similarity index 97%
rename from core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterTest.java
rename to java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterUnitTest.java
index 2c6898381f..e5a541c546 100644
--- a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterTest.java
+++ b/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateTimeToDateConverterUnitTest.java
@@ -18,7 +18,7 @@ import org.junit.Test;
* @author abialas
*
*/
-public class LocalDateTimeToDateConverterTest {
+public class LocalDateTimeToDateConverterUnitTest {
@Test
public void shouldReturn10thNovember2010time8hour20minWhenConvertViaInstant() {
diff --git a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterTest.java b/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterUnitTest.java
similarity index 96%
rename from core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterTest.java
rename to java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterUnitTest.java
index 7f20d5d2d2..4e4dd20f2f 100644
--- a/core-java-9/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterTest.java
+++ b/java-dates/src/test/java/com/baeldung/java9/datetime/LocalDateToDateConverterUnitTest.java
@@ -18,7 +18,7 @@ import org.junit.Test;
* @author abialas
*
*/
-public class LocalDateToDateConverterTest {
+public class LocalDateToDateConverterUnitTest {
@Test
public void shouldReturn10thNovember2010WhenConvertViaInstant() {
diff --git a/core-java-9/src/test/java/com/baeldung/java9/time/TimeApiTest.java b/java-dates/src/test/java/com/baeldung/java9/time/TimeApiUnitTest.java
similarity index 98%
rename from core-java-9/src/test/java/com/baeldung/java9/time/TimeApiTest.java
rename to java-dates/src/test/java/com/baeldung/java9/time/TimeApiUnitTest.java
index a024db19a8..8813870c2b 100644
--- a/core-java-9/src/test/java/com/baeldung/java9/time/TimeApiTest.java
+++ b/java-dates/src/test/java/com/baeldung/java9/time/TimeApiUnitTest.java
@@ -8,7 +8,7 @@ import java.util.List;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
-public class TimeApiTest {
+public class TimeApiUnitTest {
@Test
public void givenGetDatesBetweenWithUsingJava7_WhenStartEndDate_thenDatesList() {
diff --git a/libraries/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java
similarity index 100%
rename from libraries/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java
rename to java-dates/src/test/java/com/baeldung/jodatime/JodaTimeUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/FormattedDateMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/FormattedDateMatcherUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/regexp/datepattern/FormattedDateMatcherUnitTest.java
rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/FormattedDateMatcherUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/RangedDateMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/RangedDateMatcherUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/regexp/datepattern/RangedDateMatcherUnitTest.java
rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/RangedDateMatcherUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcherUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcherUnitTest.java
rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/February29thMatcherUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcherUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcherUnitTest.java
rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/FebruaryGeneralMatcherUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcherUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcherUnitTest.java
rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/GregorianDateMatcherUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcherUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcherUnitTest.java
rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf30DaysMatcherUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcherUnitTest.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcherUnitTest.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcherUnitTest.java
rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/MonthsOf31DaysMatcherUnitTest.java
diff --git a/core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java b/java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java
similarity index 100%
rename from core-java/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java
rename to java-dates/src/test/java/com/baeldung/regexp/datepattern/gregorian/testhelper/GregorianDateTestHelper.java
diff --git a/core-java-8/src/test/java/com/baeldung/temporaladjusters/CustomTemporalAdjusterUnitTest.java b/java-dates/src/test/java/com/baeldung/temporaladjusters/CustomTemporalAdjusterUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/temporaladjusters/CustomTemporalAdjusterUnitTest.java
rename to java-dates/src/test/java/com/baeldung/temporaladjusters/CustomTemporalAdjusterUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/temporaladjusters/TemporalAdjustersUnitTest.java b/java-dates/src/test/java/com/baeldung/temporaladjusters/TemporalAdjustersUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/temporaladjusters/TemporalAdjustersUnitTest.java
rename to java-dates/src/test/java/com/baeldung/temporaladjusters/TemporalAdjustersUnitTest.java
diff --git a/core-java-8/src/test/java/com/baeldung/time/ElapsedTimeUnitTest.java b/java-dates/src/test/java/com/baeldung/time/ElapsedTimeUnitTest.java
similarity index 100%
rename from core-java-8/src/test/java/com/baeldung/time/ElapsedTimeUnitTest.java
rename to java-dates/src/test/java/com/baeldung/time/ElapsedTimeUnitTest.java
diff --git a/jsonb/.gitignore b/java-dates/src/test/resources/.gitignore
similarity index 88%
rename from jsonb/.gitignore
rename to java-dates/src/test/resources/.gitignore
index dec013dfa4..83c05e60c8 100644
--- a/jsonb/.gitignore
+++ b/java-dates/src/test/resources/.gitignore
@@ -1,5 +1,6 @@
+*.class
+
#folders#
-.idea
/target
/neoDb*
/data
diff --git a/java-difference-date/src/test/java/com/baeldung/DateDiffTest.java b/java-difference-date/src/test/java/com/baeldung/DateDiffUnitTest.java
similarity index 98%
rename from java-difference-date/src/test/java/com/baeldung/DateDiffTest.java
rename to java-difference-date/src/test/java/com/baeldung/DateDiffUnitTest.java
index 4203f7ef38..2c5323be6f 100644
--- a/java-difference-date/src/test/java/com/baeldung/DateDiffTest.java
+++ b/java-difference-date/src/test/java/com/baeldung/DateDiffUnitTest.java
@@ -14,7 +14,7 @@ import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
-public class DateDiffTest {
+public class DateDiffUnitTest {
@Test
public void givenTwoDatesBeforeJava8_whenDifferentiating_thenWeGetSix() throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH);
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/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 351c33ecc0..e4670c268d 100644
--- a/java-streams/pom.xml
+++ b/java-streams/pom.xml
@@ -1,7 +1,6 @@
4.0.0
- com.baeldung
java-streams
0.1.0-SNAPSHOT
jar
@@ -15,6 +14,18 @@
+
+
+ org.openjdk.jmh
+ jmh-core
+ ${jmh.version}
+
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh.version}
+ provided
+
org.apache.commons
commons-lang3
@@ -75,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
@@ -107,10 +101,11 @@
+ 1.21
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/java-streams/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java b/java-streams/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java
index 2c88dc5ec7..67954f0bba 100644
--- a/java-streams/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java
+++ b/java-streams/src/test/java/com/baeldung/stream/PrimitiveStreamsUnitTest.java
@@ -1,15 +1,14 @@
package com.baeldung.stream;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
-import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import org.junit.Test;
public class PrimitiveStreamsUnitTest {
@@ -17,7 +16,7 @@ public class PrimitiveStreamsUnitTest {
@Test
public void givenAnArrayOfIntegersWhenMinIsCalledThenCorrectMinIsReturned() {
- int[] integers = new int[] {20, 98, 12, 7, 35};
+ int[] integers = new int[] { 20, 98, 12, 7, 35 };
int min = streams.min(integers); // returns 7
assertEquals(7, min);
@@ -66,19 +65,14 @@ public class PrimitiveStreamsUnitTest {
@Test
public void givenAnArrayWhenSumIsCalledThenTheCorrectSumIsReturned() {
- int sum = Stream.of(33,45)
- .mapToInt(i -> i)
- .sum();
+ int sum = Stream.of(33, 45).mapToInt(i -> i).sum();
assertEquals(78, sum);
}
@Test
public void givenAnIntStreamThenGetTheEvenIntegers() {
- List evenInts = IntStream.rangeClosed(1, 10)
- .filter(i -> i % 2 == 0)
- .boxed()
- .collect(Collectors.toList());
+ List evenInts = IntStream.rangeClosed(1, 10).filter(i -> i % 2 == 0).boxed().collect(Collectors.toList());
List expected = IntStream.of(2, 4, 6, 8, 10).boxed().collect(Collectors.toList());
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 87%
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 202fe00017..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,7 +1,8 @@
-package com.baeldung.collection;
+package com.baeldung.stream;
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.junit.Assert;
@@ -35,8 +36,9 @@ public class StreamOperateAndRemoveUnitTest {
@Test
public void givenAListOf10Items_whenOperateAndRemoveQualifiedItemsUsingRemoveIf_thenListContains5Items() {
- itemList.stream().filter(item -> item.isQualified()).forEach(item -> item.operate());
- itemList.removeIf(item -> item.isQualified());
+ final Predicate- isQualified = item -> item.isQualified();
+ itemList.stream().filter(isQualified).forEach(item -> item.operate());
+ itemList.removeIf(isQualified);
Assert.assertEquals(5, itemList.size());
}
diff --git a/testing-modules/streams-ordering/src/test/java/benchmarking/TestBenchmark.java b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java
similarity index 97%
rename from testing-modules/streams-ordering/src/test/java/benchmarking/TestBenchmark.java
rename to java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java
index a3e99e6465..656a6d95f9 100644
--- a/testing-modules/streams-ordering/src/test/java/benchmarking/TestBenchmark.java
+++ b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java
@@ -1,4 +1,4 @@
-package benchmarking;
+package com.baeldung.streamordering;
import org.junit.Test;
import org.openjdk.jmh.annotations.*;
@@ -15,10 +15,9 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
-public class TestBenchmark
+public class BenchmarkManualTest
{
- @Test
public void
launchBenchmark() throws Exception {
@@ -94,4 +93,4 @@ public class TestBenchmark
for (int i = 0; i < 1000; i++)
bh.consume (list.get (i));
}
-}
\ No newline at end of file
+}
diff --git a/testing-modules/streams-ordering/src/test/java/StreamsOrderingTest.java b/java-streams/src/test/java/com/baeldung/streamordering/StreamsOrderingUnitTest.java
similarity index 96%
rename from testing-modules/streams-ordering/src/test/java/StreamsOrderingTest.java
rename to java-streams/src/test/java/com/baeldung/streamordering/StreamsOrderingUnitTest.java
index b657911780..43a233d353 100644
--- a/testing-modules/streams-ordering/src/test/java/StreamsOrderingTest.java
+++ b/java-streams/src/test/java/com/baeldung/streamordering/StreamsOrderingUnitTest.java
@@ -1,3 +1,5 @@
+package com.baeldung.streamordering;
+
import org.junit.Before;
import org.junit.Test;
@@ -10,10 +12,9 @@ import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
+public class StreamsOrderingUnitTest {
-public class StreamsOrderingTest {
-
- Logger logger = Logger.getLogger( StreamsOrderingTest.class.getName());
+ Logger logger = Logger.getLogger( StreamsOrderingUnitTest.class.getName());
@Before
public void setUp() throws Exception {
diff --git a/java-strings/README.md b/java-strings/README.md
index d5b9b45b20..249f1a351a 100644
--- a/java-strings/README.md
+++ b/java-strings/README.md
@@ -24,4 +24,9 @@
- [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)
+- [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 86b8924c4b..b1ba49b33a 100644
--- a/java-strings/pom.xml
+++ b/java-strings/pom.xml
@@ -47,11 +47,28 @@
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
+ emoji-java
+ 4.0.0
+
+
@@ -64,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
@@ -102,6 +102,7 @@
3.6.1
1.19
61.1
+ 26.0-jre