capitalCountryMap = HashBiMap.create();
+ capitalCountryMap.put("Berlin", "Germany");
+ capitalCountryMap.put("Cape Town", "South Africa");
+ capitalCountryMap.put("Pretoria", "South Africa");
+ assertEquals("Berlin", capitalCountryMap.inverse().get("Germany"));
+ }
+
+}
diff --git a/core-java-concurrency/src/main/java/com/baeldung/concurrent/yield/ThreadYield.java b/core-java-concurrency/src/main/java/com/baeldung/concurrent/yield/ThreadYield.java
new file mode 100644
index 0000000000..b31a04015f
--- /dev/null
+++ b/core-java-concurrency/src/main/java/com/baeldung/concurrent/yield/ThreadYield.java
@@ -0,0 +1,17 @@
+package com.baeldung.concurrent.yield;
+
+public class ThreadYield {
+ public static void main(String[] args) {
+ Runnable r = () -> {
+ int counter = 0;
+ while (counter < 2) {
+ System.out.println(Thread.currentThread()
+ .getName());
+ counter++;
+ Thread.yield();
+ }
+ };
+ new Thread(r).start();
+ new Thread(r).start();
+ }
+}
diff --git a/core-java-io/pom.xml b/core-java-io/pom.xml
index bc71fb8838..cf3e950cb8 100644
--- a/core-java-io/pom.xml
+++ b/core-java-io/pom.xml
@@ -1,7 +1,6 @@
4.0.0
- com.baeldung
core-java-io
0.1.0-SNAPSHOT
jar
@@ -166,36 +165,6 @@
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- **/*LiveTest.java
- **/*IntegrationTest.java
- **/*IntTest.java
- **/*LongRunningUnitTest.java
- **/*ManualTest.java
-
- true
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
- ${spring-boot-maven-plugin.version}
-
-
-
- repackage
-
-
- spring-boot
- org.baeldung.executable.ExecutableMavenJar
-
-
-
-
org.codehaus.mojo
exec-maven-plugin
@@ -229,32 +198,6 @@
integration
-
- org.apache.maven.plugins
- maven-surefire-plugin
-
-
- integration-test
-
- test
-
-
-
- **/*ManualTest.java
-
-
- **/*IntegrationTest.java
- **/*IntTest.java
-
-
-
-
-
-
- json
-
-
-
org.codehaus.mojo
exec-maven-plugin
@@ -310,14 +253,11 @@
1.7.0
- 1.8
- 1.8
3.0.0-M1
2.4.0
2.1.0.1
1.19
2.4.5
- 2.0.4.RELEASE
\ No newline at end of file
diff --git a/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java b/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java
index 7da71a093d..42147b07db 100644
--- a/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java
+++ b/core-java-io/src/main/java/com/baeldung/zip/ZipDirectory.java
@@ -24,6 +24,13 @@ public class ZipDirectory {
return;
}
if (fileToZip.isDirectory()) {
+ if (fileName.endsWith("/")) {
+ zipOut.putNextEntry(new ZipEntry(fileName));
+ zipOut.closeEntry();
+ } else {
+ zipOut.putNextEntry(new ZipEntry(fileName + "/"));
+ zipOut.closeEntry();
+ }
final File[] children = fileToZip.listFiles();
for (final File childFile : children) {
zipFile(childFile, fileName + "/" + childFile.getName(), zipOut);
diff --git a/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java b/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java
index 7968967679..6a020f5eae 100644
--- a/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java
+++ b/core-java-io/src/test/java/com/baeldung/file/FileOperationsManualTest.java
@@ -1,6 +1,7 @@
package com.baeldung.file;
import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
import org.hamcrest.CoreMatchers;
import org.hamcrest.Matchers;
import org.junit.Test;
@@ -120,4 +121,14 @@ public class FileOperationsManualTest {
return resultStringBuilder.toString();
}
+
+ @Test
+ public void givenFileName_whenUsingIOUtils_thenFileData() throws IOException {
+ String expectedData = "This is a content of the file";
+
+ FileInputStream fis = new FileInputStream("src/test/resources/fileToRead.txt");
+ String data = IOUtils.toString(fis, "UTF-8");
+
+ assertEquals(expectedData, data.trim());
+ }
}
\ No newline at end of file
diff --git a/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleUnitTest.java b/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java
similarity index 96%
rename from core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleUnitTest.java
rename to core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java
index 803d8881b4..caa7049475 100644
--- a/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleUnitTest.java
+++ b/core-java-io/src/test/java/com/baeldung/symlink/SymLinkExampleManualTest.java
@@ -9,7 +9,7 @@ import java.nio.file.Paths;
import org.junit.Test;
-public class SymLinkExampleUnitTest {
+public class SymLinkExampleManualTest {
@Test
public void whenUsingFiles_thenCreateSymbolicLink() throws IOException {
diff --git a/core-java/src/main/java/com/baeldung/decimalformat/DoubletoString.java b/core-java/src/main/java/com/baeldung/decimalformat/DoubletoString.java
deleted file mode 100644
index 87d10a3548..0000000000
--- a/core-java/src/main/java/com/baeldung/decimalformat/DoubletoString.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.baeldung.decimalformat;
-
- import java.math.RoundingMode;
- import java.text.DecimalFormat;
- import java.text.NumberFormat;
- import java.util.Locale;
-
- public class DoubletoString {
-
- public static void main(String[] args) {
-
- double doubleValue = 345.56;
-
- System.out.println(String.valueOf((int) doubleValue));
-
- System.out.println(String.format("%.0f", doubleValue));
-
- doubleValue = Math.floor(doubleValue);
- DecimalFormat df = new DecimalFormat("#");
- df.setRoundingMode(RoundingMode.FLOOR);
- System.out.println(df.format(doubleValue));
-
- Locale enlocale = new Locale("en", "US");
- String pattern = "###,##";
- df = (DecimalFormat) NumberFormat.getNumberInstance(enlocale);
- df.applyPattern(pattern);
- String format = df.format(doubleValue);
- System.out.println(format);
-
- Locale dalocale = new Locale("da", "DK");
- df = (DecimalFormat) NumberFormat.getNumberInstance(dalocale);
- df.applyPattern(pattern);
- System.out.println(df.format(doubleValue));
-
-
- }
-
- }
diff --git a/core-java/src/main/java/com/baeldung/doubles/SplitFloatingPointNumbers.java b/core-java/src/main/java/com/baeldung/doubles/SplitFloatingPointNumbers.java
new file mode 100644
index 0000000000..a28ac3d5a1
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/doubles/SplitFloatingPointNumbers.java
@@ -0,0 +1,40 @@
+package com.baeldung.doubles;
+
+import java.math.BigDecimal;
+
+public class SplitFloatingPointNumbers {
+
+ public static void main(String[] args) {
+
+ double doubleNumber = 24.04;
+ splitUsingFloatingTypes(doubleNumber);
+ splitUsingString(doubleNumber);
+ splitUsingBigDecimal(doubleNumber);
+ }
+
+ private static void splitUsingFloatingTypes(double doubleNumber) {
+ System.out.println("Using Floating Point Arithmetics:");
+ int intPart = (int) doubleNumber;
+ System.out.println("Double Number: "+doubleNumber);
+ System.out.println("Integer Part: "+ intPart);
+ System.out.println("Decimal Part: "+ (doubleNumber - intPart));
+ }
+
+ private static void splitUsingString(double doubleNumber) {
+ System.out.println("Using String Operations:");
+ String doubleAsString = String.valueOf(doubleNumber);
+ int indexOfDecimal = doubleAsString.indexOf(".");
+ System.out.println("Double Number: "+doubleNumber);
+ System.out.println("Integer Part: "+ doubleAsString.substring(0, indexOfDecimal));
+ System.out.println("Decimal Part: "+ doubleAsString.substring(indexOfDecimal));
+ }
+
+ private static void splitUsingBigDecimal(double doubleNumber) {
+ System.out.println("Using BigDecimal Operations:");
+ BigDecimal bigDecimal = new BigDecimal(String.valueOf(doubleNumber));
+ int intValue = bigDecimal.intValue();
+ System.out.println("Double Number: "+bigDecimal.toPlainString());
+ System.out.println("Integer Part: "+intValue);
+ System.out.println("Decimal Part: "+bigDecimal.subtract(new BigDecimal(intValue)).toPlainString());
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/heapdump/HeapDump.java b/core-java/src/main/java/com/baeldung/heapdump/HeapDump.java
new file mode 100644
index 0000000000..8cce20de8d
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/heapdump/HeapDump.java
@@ -0,0 +1,25 @@
+package com.baeldung.heapdump;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+
+import javax.management.MBeanServer;
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.nio.file.Paths;
+
+public class HeapDump {
+
+ public static void dumpHeap(String filePath, boolean live) throws IOException {
+ MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+ HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(
+ server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
+ mxBean.dumpHeap(filePath, live);
+ }
+
+ public static void main(String[] args) throws IOException {
+ String file = Paths.get("dump.hprof").toFile().getPath();
+
+ dumpHeap(file, true);
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java
new file mode 100644
index 0000000000..e2259e4249
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/passwordhashing/PBKDF2Hasher.java
@@ -0,0 +1,149 @@
+package com.baeldung.passwordhashing;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+/**
+ * Hash passwords for storage, and test passwords against password tokens.
+ *
+ * Instances of this class can be used concurrently by multiple threads.
+ *
+ * @author erickson
+ * @see StackOverflow
+ */
+public final class PBKDF2Hasher
+{
+
+ /**
+ * Each token produced by this class uses this identifier as a prefix.
+ */
+ public static final String ID = "$31$";
+
+ /**
+ * The minimum recommended cost, used by default
+ */
+ public static final int DEFAULT_COST = 16;
+
+ private static final String ALGORITHM = "PBKDF2WithHmacSHA1";
+
+ private static final int SIZE = 128;
+
+ private static final Pattern layout = Pattern.compile("\\$31\\$(\\d\\d?)\\$(.{43})");
+
+ private final SecureRandom random;
+
+ private final int cost;
+
+ public PBKDF2Hasher()
+ {
+ this(DEFAULT_COST);
+ }
+
+ /**
+ * Create a password manager with a specified cost
+ *
+ * @param cost the exponential computational cost of hashing a password, 0 to 30
+ */
+ public PBKDF2Hasher(int cost)
+ {
+ iterations(cost); /* Validate cost */
+ this.cost = cost;
+ this.random = new SecureRandom();
+ }
+
+ private static int iterations(int cost)
+ {
+ if ((cost < 0) || (cost > 30))
+ throw new IllegalArgumentException("cost: " + cost);
+ return 1 << cost;
+ }
+
+ /**
+ * Hash a password for storage.
+ *
+ * @return a secure authentication token to be stored for later authentication
+ */
+ public String hash(char[] password)
+ {
+ byte[] salt = new byte[SIZE / 8];
+ random.nextBytes(salt);
+ byte[] dk = pbkdf2(password, salt, 1 << cost);
+ byte[] hash = new byte[salt.length + dk.length];
+ System.arraycopy(salt, 0, hash, 0, salt.length);
+ System.arraycopy(dk, 0, hash, salt.length, dk.length);
+ Base64.Encoder enc = Base64.getUrlEncoder().withoutPadding();
+ return ID + cost + '$' + enc.encodeToString(hash);
+ }
+
+ /**
+ * Authenticate with a password and a stored password token.
+ *
+ * @return true if the password and token match
+ */
+ public boolean checkPassword(char[] password, String token)
+ {
+ Matcher m = layout.matcher(token);
+ if (!m.matches())
+ throw new IllegalArgumentException("Invalid token format");
+ int iterations = iterations(Integer.parseInt(m.group(1)));
+ byte[] hash = Base64.getUrlDecoder().decode(m.group(2));
+ byte[] salt = Arrays.copyOfRange(hash, 0, SIZE / 8);
+ byte[] check = pbkdf2(password, salt, iterations);
+ int zero = 0;
+ for (int idx = 0; idx < check.length; ++idx)
+ zero |= hash[salt.length + idx] ^ check[idx];
+ return zero == 0;
+ }
+
+ private static byte[] pbkdf2(char[] password, byte[] salt, int iterations)
+ {
+ KeySpec spec = new PBEKeySpec(password, salt, iterations, SIZE);
+ try {
+ SecretKeyFactory f = SecretKeyFactory.getInstance(ALGORITHM);
+ return f.generateSecret(spec).getEncoded();
+ }
+ catch (NoSuchAlgorithmException ex) {
+ throw new IllegalStateException("Missing algorithm: " + ALGORITHM, ex);
+ }
+ catch (InvalidKeySpecException ex) {
+ throw new IllegalStateException("Invalid SecretKeyFactory", ex);
+ }
+ }
+
+ /**
+ * Hash a password in an immutable {@code String}.
+ *
+ * Passwords should be stored in a {@code char[]} so that it can be filled
+ * with zeros after use instead of lingering on the heap and elsewhere.
+ *
+ * @deprecated Use {@link #hash(char[])} instead
+ */
+ @Deprecated
+ public String hash(String password)
+ {
+ return hash(password.toCharArray());
+ }
+
+ /**
+ * Authenticate with a password in an immutable {@code String} and a stored
+ * password token.
+ *
+ * @deprecated Use {@link #checkPassword(char[],String)} instead.
+ * @see #hash(String)
+ */
+ @Deprecated
+ public boolean checkPassword(String password, String token)
+ {
+ return checkPassword(password.toCharArray(), token);
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java
new file mode 100644
index 0000000000..4f5337f963
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/passwordhashing/SHA512Hasher.java
@@ -0,0 +1,35 @@
+package com.baeldung.passwordhashing;
+
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+
+/** A really simple SHA_512 Encryption example.
+ *
+ */
+public class SHA512Hasher {
+
+ public String hash(String passwordToHash, byte[] salt){
+ String generatedPassword = null;
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-512");
+ md.update(salt);
+ byte[] bytes = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i< bytes.length ;i++){
+ sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
+ }
+ generatedPassword = sb.toString();
+ }
+ catch (NoSuchAlgorithmException e){
+ e.printStackTrace();
+ }
+ return generatedPassword;
+ }
+
+ public boolean checkPassword(String hash, String attempt, byte[] salt){
+ String generatedHash = hash(attempt, salt);
+ return hash.equals(generatedHash);
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java b/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java
new file mode 100644
index 0000000000..36c9b65070
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/passwordhashing/SimplePBKDF2Hasher.java
@@ -0,0 +1,18 @@
+package com.baeldung.passwordhashing;
+
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import java.security.spec.KeySpec;
+
+/** A really simple SimplePBKDF2 Encryption example.
+ *
+ */
+public class SimplePBKDF2Hasher {
+
+ public static String hashSimple(String password, byte[] salt) throws Exception{
+ KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
+ SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+ byte[] hash = f.generateSecret(spec).getEncoded();
+ return String.valueOf(hash);
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java b/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java
new file mode 100644
index 0000000000..69e151bfcb
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/switchstatement/SwitchStatement.java
@@ -0,0 +1,70 @@
+package com.baeldung.switchstatement;
+
+public class SwitchStatement {
+
+ public String exampleOfIF(String animal) {
+
+ String result;
+
+ if (animal.equals("DOG") || animal.equals("CAT")) {
+ result = "domestic animal";
+ } else if (animal.equals("TIGER")) {
+ result = "wild animal";
+ } else {
+ result = "unknown animal";
+ }
+ return result;
+ }
+
+ public String exampleOfSwitch(String animal) {
+
+ String result;
+
+ switch (animal) {
+ case "DOG":
+ case "CAT":
+ result = "domestic animal";
+ break;
+ case "TIGER":
+ result = "wild animal";
+ break;
+ default:
+ result = "unknown animal";
+ break;
+ }
+ return result;
+ }
+
+ public String forgetBreakInSwitch(String animal) {
+
+ String result;
+
+ switch (animal) {
+
+ case "DOG":
+ System.out.println("domestic animal");
+ result = "domestic animal";
+
+ default:
+ System.out.println("unknown animal");
+ result = "unknown animal";
+
+ }
+ return result;
+ }
+
+ public String constantCaseValue(String animal) {
+
+ String result = "";
+
+ final String dog = "DOG";
+
+ switch (animal) {
+
+ case dog:
+ result = "domestic animal";
+ }
+ return result;
+ }
+
+}
diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java
new file mode 100644
index 0000000000..fb92eb8d0d
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetDateTimeExample.java
@@ -0,0 +1,13 @@
+package com.baeldung.zoneddatetime;
+
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+
+public class OffsetDateTimeExample {
+
+ public OffsetDateTime getCurrentTimeByZoneOffset(String offset) {
+ ZoneOffset zoneOffSet= ZoneOffset.of(offset);
+ OffsetDateTime date = OffsetDateTime.now(zoneOffSet);
+ return date;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java
new file mode 100644
index 0000000000..58e2d4d5ad
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/zoneddatetime/OffsetTimeExample.java
@@ -0,0 +1,13 @@
+package com.baeldung.zoneddatetime;
+
+import java.time.OffsetTime;
+import java.time.ZoneOffset;
+
+public class OffsetTimeExample {
+
+ public OffsetTime getCurrentTimeByZoneOffset(String offset) {
+ ZoneOffset zoneOffSet = ZoneOffset.of(offset);
+ OffsetTime time = OffsetTime.now(zoneOffSet);
+ return time;
+ }
+}
diff --git a/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java b/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java
new file mode 100644
index 0000000000..b54b8c5225
--- /dev/null
+++ b/core-java/src/main/java/com/baeldung/zoneddatetime/ZoneDateTimeExample.java
@@ -0,0 +1,21 @@
+package com.baeldung.zoneddatetime;
+
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+
+public class ZoneDateTimeExample {
+
+ public ZonedDateTime getCurrentTimeByZoneId(String region) {
+ ZoneId zone = ZoneId.of(region);
+ ZonedDateTime date = ZonedDateTime.now(zone);
+ return date;
+ }
+
+ public ZonedDateTime convertZonedDateTime(ZonedDateTime sourceDate, String destZone) {
+
+ ZoneId destZoneId = ZoneId.of(destZone);
+ ZonedDateTime destDate = sourceDate.withZoneSameInstant(destZoneId);
+
+ return destDate;
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java b/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java
new file mode 100644
index 0000000000..8e90725c77
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/passwordhashing/PBKDF2HasherUnitTest.java
@@ -0,0 +1,41 @@
+package com.baeldung.passwordhashing;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+public class PBKDF2HasherUnitTest {
+
+ private PBKDF2Hasher mPBKDF2Hasher;
+
+ @Before
+ public void setUp() throws Exception {
+ mPBKDF2Hasher = new PBKDF2Hasher();
+ }
+
+ @Test
+ public void givenCorrectMessageAndHash_whenAuthenticated_checkAuthenticationSucceeds() throws Exception {
+ String message1 = "password123";
+
+ String hash1 = mPBKDF2Hasher.hash(message1.toCharArray());
+
+ assertTrue(mPBKDF2Hasher.checkPassword(message1.toCharArray(), hash1));
+
+ }
+
+ @Test
+ public void givenWrongMessage_whenAuthenticated_checkAuthenticationFails() throws Exception {
+ String message1 = "password123";
+
+ String hash1 = mPBKDF2Hasher.hash(message1.toCharArray());
+
+ String wrongPasswordAttempt = "IamWrong";
+
+ assertFalse(mPBKDF2Hasher.checkPassword(wrongPasswordAttempt.toCharArray(), hash1));
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java b/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java
new file mode 100644
index 0000000000..3acfb0ba9d
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/passwordhashing/SHA512HasherUnitTest.java
@@ -0,0 +1,70 @@
+package com.baeldung.passwordhashing;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.security.SecureRandom;
+
+import static org.junit.Assert.*;
+
+/**
+ * Created by PhysicsSam on 06-Sep-18.
+ */
+public class SHA512HasherUnitTest {
+
+ private SHA512Hasher hasher;
+ private SecureRandom secureRandom;
+
+ @Before
+ public void setUp() throws Exception {
+ hasher = new SHA512Hasher();
+ secureRandom = new SecureRandom();
+ }
+
+ @Test
+ public void givenSamePasswordAndSalt_whenHashed_checkResultingHashesAreEqual() throws Exception {
+
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+
+ String hash1 = hasher.hash("password", salt);
+ String hash2 = hasher.hash("password", salt);
+
+ assertEquals(hash1, hash2);
+
+ }
+
+ @Test
+ public void givenSamePasswordAndDifferentSalt_whenHashed_checkResultingHashesNotEqual() throws Exception {
+
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+ String hash1 = hasher.hash("password", salt);
+ //generate a second salt
+ byte[] secondSalt = new byte[16];
+ String hash2 = hasher.hash("password", secondSalt);
+
+ assertNotEquals(hash1, hash2);
+
+ }
+
+ @Test
+ public void givenPredefinedHash_whenCorrectAttemptGiven_checkAuthenticationSucceeds() throws Exception {
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+
+ String originalHash = hasher.hash("password123", salt);
+
+ assertTrue(hasher.checkPassword(originalHash, "password123", salt));
+ }
+
+ @Test
+ public void givenPredefinedHash_whenIncorrectAttemptGiven_checkAuthenticationFails() throws Exception {
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+
+ String originalHash = hasher.hash("password123", salt);
+
+ assertFalse(hasher.checkPassword(originalHash, "password124", salt));
+ }
+}
\ No newline at end of file
diff --git a/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java
new file mode 100644
index 0000000000..8dbfcaf5e7
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsManualTest.java
@@ -0,0 +1,100 @@
+package com.baeldung.removingdecimals;
+
+import org.junit.Test;
+import org.openjdk.jmh.annotations.*;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This benchmark compares some of the approaches to formatting a floating-point
+ * value into a {@link String} while removing the decimal part.
+ *
+ * To run, simply run the {@link RemovingDecimalsManualTest#runBenchmarks()} test
+ * at the end of this class.
+ *
+ * The benchmark takes about 15 minutes to run. Since it is using {@link Mode#Throughput},
+ * higher numbers mean better performance.
+ */
+@BenchmarkMode(Mode.Throughput)
+@Warmup(iterations = 5)
+@Measurement(iterations = 20)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@State(Scope.Benchmark)
+public class RemovingDecimalsManualTest {
+ @Param(value = {"345.56", "345345345.56", "345345345345345345.56"}) double doubleValue;
+
+ NumberFormat nf;
+ DecimalFormat df;
+
+ @Setup
+ public void readyFormatters() {
+ nf = NumberFormat.getInstance();
+ nf.setMaximumFractionDigits(0);
+ df = new DecimalFormat("#,###");
+ }
+
+ @Benchmark
+ public String whenCastToInt_thenValueIsTruncated() {
+ return String.valueOf((int) doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingStringFormat_thenValueIsRounded() {
+ return String.format("%.0f", doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingNumberFormat_thenValueIsRounded() {
+ nf.setRoundingMode(RoundingMode.HALF_UP);
+ return nf.format(doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingNumberFormatWithFloor_thenValueIsTruncated() {
+ nf.setRoundingMode(RoundingMode.FLOOR);
+ return nf.format(doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingDecimalFormat_thenValueIsRounded() {
+ df.setRoundingMode(RoundingMode.HALF_UP);
+ return df.format(doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingDecimalFormatWithFloor_thenValueIsTruncated() {
+ df.setRoundingMode(RoundingMode.FLOOR);
+ return df.format(doubleValue);
+ }
+
+ @Benchmark
+ public String whenUsingBigDecimalDoubleValue_thenValueIsTruncated() {
+ BigDecimal big = new BigDecimal(doubleValue);
+ big = big.setScale(0, RoundingMode.FLOOR);
+ return big.toString();
+ }
+
+ @Benchmark
+ public String whenUsingBigDecimalDoubleValueWithHalfUp_thenValueIsRounded() {
+ BigDecimal big = new BigDecimal(doubleValue);
+ big = big.setScale(0, RoundingMode.HALF_UP);
+ return big.toString();
+ }
+
+ @Test
+ public void runBenchmarks() throws Exception {
+ Options options = new OptionsBuilder()
+ .include(this.getClass().getSimpleName()).threads(1)
+ .forks(1).shouldFailOnError(true).shouldDoGC(true)
+ .jvmArgs("-server").build();
+
+ new Runner(options).run();
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java
new file mode 100644
index 0000000000..2f634b553b
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/removingdecimals/RemovingDecimalsUnitTest.java
@@ -0,0 +1,95 @@
+package com.baeldung.removingdecimals;
+
+import org.junit.Test;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+/**
+ * Tests that demonstrate some different approaches for formatting a
+ * floating-point value into a {@link String} while removing the decimal part.
+ */
+public class RemovingDecimalsUnitTest {
+ private final double doubleValue = 345.56;
+
+ @Test
+ public void whenCastToInt_thenValueIsTruncated() {
+ String truncated = String.valueOf((int) doubleValue);
+ assertEquals("345", truncated);
+ }
+
+ @Test
+ public void givenALargeDouble_whenCastToInt_thenValueIsNotTruncated() {
+ double outOfIntRange = 6_000_000_000.56;
+ String truncationAttempt = String.valueOf((int) outOfIntRange);
+ assertNotEquals("6000000000", truncationAttempt);
+ }
+
+ @Test
+ public void whenUsingStringFormat_thenValueIsRounded() {
+ String rounded = String.format("%.0f", doubleValue);
+ assertEquals("346", rounded);
+ }
+
+ @Test
+ public void givenALargeDouble_whenUsingStringFormat_thenValueIsStillRounded() {
+ double outOfIntRange = 6_000_000_000.56;
+ String rounded = String.format("%.0f", outOfIntRange);
+ assertEquals("6000000001", rounded);
+ }
+
+ @Test
+ public void whenUsingNumberFormat_thenValueIsRounded() {
+ NumberFormat nf = NumberFormat.getInstance();
+ nf.setMaximumFractionDigits(0);
+ nf.setRoundingMode(RoundingMode.HALF_UP);
+ String rounded = nf.format(doubleValue);
+ assertEquals("346", rounded);
+ }
+
+ @Test
+ public void whenUsingNumberFormatWithFloor_thenValueIsTruncated() {
+ NumberFormat nf = NumberFormat.getInstance();
+ nf.setMaximumFractionDigits(0);
+ nf.setRoundingMode(RoundingMode.FLOOR);
+ String truncated = nf.format(doubleValue);
+ assertEquals("345", truncated);
+ }
+
+ @Test
+ public void whenUsingDecimalFormat_thenValueIsRounded() {
+ DecimalFormat df = new DecimalFormat("#,###");
+ df.setRoundingMode(RoundingMode.HALF_UP);
+ String rounded = df.format(doubleValue);
+ assertEquals("346", rounded);
+ }
+
+ @Test
+ public void whenUsingDecimalFormatWithFloor_thenValueIsTruncated() {
+ DecimalFormat df = new DecimalFormat("#,###");
+ df.setRoundingMode(RoundingMode.FLOOR);
+ String truncated = df.format(doubleValue);
+ assertEquals("345", truncated);
+ }
+
+ @Test
+ public void whenUsingBigDecimalDoubleValue_thenValueIsTruncated() {
+ BigDecimal big = new BigDecimal(doubleValue);
+ big = big.setScale(0, RoundingMode.FLOOR);
+ String truncated = big.toString();
+ assertEquals("345", truncated);
+ }
+
+ @Test
+ public void whenUsingBigDecimalDoubleValueWithHalfUp_thenValueIsRounded() {
+ BigDecimal big = new BigDecimal(doubleValue);
+ big = big.setScale(0, RoundingMode.HALF_UP);
+ String truncated = big.toString();
+ assertEquals("346", truncated);
+ }
+}
diff --git a/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java b/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java
new file mode 100644
index 0000000000..e8ac645531
--- /dev/null
+++ b/core-java/src/test/java/com/baeldung/switchstatement/SwitchStatementUnitTest.java
@@ -0,0 +1,38 @@
+package com.baeldung.switchstatement;
+
+import org.junit.Test;
+
+import org.junit.Assert;
+
+public class SwitchStatementUnitTest {
+ private SwitchStatement s = new SwitchStatement();
+
+
+ @Test
+ public void whenDog_thenDomesticAnimal() {
+
+ String animal = "DOG";
+ Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal));
+ }
+
+ @Test
+ public void whenNoBreaks_thenGoThroughBlocks() {
+ String animal = "DOG";
+ Assert.assertEquals("unknown animal", s.forgetBreakInSwitch(animal));
+ }
+
+ @Test(expected=NullPointerException.class)
+ public void whenSwitchAgumentIsNull_thenNullPointerException() {
+ String animal = null;
+ Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal));
+ }
+
+
+ @Test
+ public void whenCompareStrings_thenByEqual() {
+ String animal = new String("DOG");
+ Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal));
+ }
+
+
+}
diff --git a/core-java/src/test/java/com/baeldung/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/pom.xml b/core-kotlin/pom.xml
index 70cbd67645..0894a57320 100644
--- a/core-kotlin/pom.xml
+++ b/core-kotlin/pom.xml
@@ -55,6 +55,12 @@
fuel-coroutines
${fuel.version}
+
+ nl.komponents.kovenant
+ kovenant
+ 3.3.0
+ pom
+
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/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/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/BatchEmployee.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/BatchEmployee.java
new file mode 100644
index 0000000000..00643ab3dd
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/BatchEmployee.java
@@ -0,0 +1,56 @@
+package com.baeldung.hibernate.proxy;
+
+import org.hibernate.annotations.BatchSize;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Entity
+@BatchSize(size = 5)
+public class BatchEmployee implements Serializable {
+
+ @Id
+ @GeneratedValue (strategy = GenerationType.SEQUENCE)
+ private Long id;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ private Boss boss;
+
+ @Column(name = "name")
+ private String name;
+
+ @Column(name = "surname")
+ private String surname;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Boss getBoss() {
+ return boss;
+ }
+
+ public void setBoss(Boss boss) {
+ this.boss = boss;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSurname() {
+ return surname;
+ }
+
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+}
diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Boss.java b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Boss.java
new file mode 100644
index 0000000000..b6e01814d0
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Boss.java
@@ -0,0 +1,49 @@
+package com.baeldung.hibernate.proxy;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Entity
+public class Boss implements Serializable {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private Long id;
+
+ @Column(name = "name")
+ private String name;
+
+ @Column(name = "surname")
+ private String surname;
+
+ public Boss() { }
+
+ public Boss(String name, String surname) {
+ this.name = name;
+ this.surname = surname;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSurname() {
+ return surname;
+ }
+
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+}
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..6bc64c35ef
--- /dev/null
+++ b/hibernate5/src/main/java/com/baeldung/hibernate/proxy/Employee.java
@@ -0,0 +1,53 @@
+package com.baeldung.hibernate.proxy;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+@Entity
+public class Employee implements Serializable {
+
+ @Id
+ @GeneratedValue (strategy = GenerationType.SEQUENCE)
+ private Long id;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ private Boss boss;
+
+ @Column(name = "name")
+ private String name;
+
+ @Column(name = "surname")
+ private String surname;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public Boss getBoss() {
+ return boss;
+ }
+
+ public void setBoss(Boss boss) {
+ this.boss = boss;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getSurname() {
+ return surname;
+ }
+
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+}
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..e6ad0432bd
--- /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(Boss.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/proxy/HibernateProxyUnitTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java
new file mode 100644
index 0000000000..fa41797dd2
--- /dev/null
+++ b/hibernate5/src/test/java/com/baeldung/hibernate/proxy/HibernateProxyUnitTest.java
@@ -0,0 +1,75 @@
+package com.baeldung.hibernate.proxy;
+
+import org.hibernate.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.junit.Assert.fail;
+
+public class HibernateProxyUnitTest {
+
+ private Session session;
+
+ @Before
+ public void init(){
+ try {
+ session = HibernateUtil.getSessionFactory("hibernate.properties")
+ .openSession();
+ } catch (HibernateException | IOException e) {
+ fail("Failed to initiate Hibernate Session [Exception:" + e.toString() + "]");
+ }
+
+ Boss boss = new Boss("Eduard", "Freud");
+ session.save(boss);
+ }
+
+ @After
+ public void close(){
+ if(session != null) {
+ session.close();
+ }
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void givenAnInexistentEmployeeId_whenUseGetMethod_thenReturnNull() {
+ Employee employee = session.get(Employee.class, new Long(14));
+ assertNull(employee);
+ employee.getId();
+ }
+
+ @Test
+ public void givenAnInexistentEmployeeId_whenUseLoadMethod_thenReturnAProxy() {
+ Employee employee = session.load(Employee.class, new Long(14));
+ assertNotNull(employee);
+ }
+
+ @Test
+ public void givenABatchEmployeeList_whenSaveOne_thenSaveTheWholeBatch() {
+ Transaction transaction = session.beginTransaction();
+
+ for (long i = 1; i <= 5; i++) {
+ Employee employee = new Employee();
+ employee.setName("Employee " + i);
+ session.save(employee);
+ }
+
+ //After this line is possible to see all the insertions in the logs
+ session.flush();
+ session.clear();
+ transaction.commit();
+
+ transaction = session.beginTransaction();
+
+ List employeeList = session.createQuery("from Employee")
+ .setCacheMode(CacheMode.IGNORE).getResultList();
+
+ assertEquals(employeeList.size(), 5);
+ transaction.commit();
+ }
+}
diff --git a/java-streams/pom.xml b/java-streams/pom.xml
index 023a5f695b..e4670c268d 100644
--- a/java-streams/pom.xml
+++ b/java-streams/pom.xml
@@ -105,7 +105,7 @@
3.5
1.16.12
0.9.0
- 1.13
+ 1.15
0.6.5
2.10
diff --git a/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java b/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java
new file mode 100644
index 0000000000..1b64c8924a
--- /dev/null
+++ b/java-streams/src/test/java/com/baeldung/protonpack/ProtonpackUnitTest.java
@@ -0,0 +1,209 @@
+package com.baeldung.protonpack;
+
+import com.codepoetics.protonpack.Indexed;
+import com.codepoetics.protonpack.StreamUtils;
+import com.codepoetics.protonpack.collectors.CollectorUtils;
+import com.codepoetics.protonpack.collectors.NonUniqueValueException;
+import com.codepoetics.protonpack.selectors.Selector;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.util.Arrays.asList;
+import static java.util.Arrays.stream;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
+@SuppressWarnings("unchecked")
+public class ProtonpackUnitTest {
+ @Test
+ public void whenTakeWhile_thenTakenWhile() {
+ Stream streamOfInt = Stream.iterate(1, i -> i + 1);
+ List result = StreamUtils.takeWhile(streamOfInt, i -> i < 5).collect(Collectors.toList());
+ assertThat(result).contains(1, 2, 3, 4);
+ }
+
+ @Test
+ public void whenTakeUntil_thenTakenUntil() {
+ Stream streamOfInt = Stream.iterate(1, i -> i + 1);
+ List result = StreamUtils.takeUntil(streamOfInt, i -> i > 50).collect(Collectors.toList());
+ assertThat(result).contains(10, 20, 30, 40);
+ }
+
+ @Test
+ public void givenMultipleStream_whenZipped_thenZipped() {
+ String[] clubs = { "Juventus", "Barcelona", "Liverpool", "PSG" };
+ String[] players = { "Ronaldo", "Messi", "Salah" };
+ Set zippedFrom2Sources = StreamUtils.zip(stream(clubs), stream(players), (club, player) -> club + " " + player)
+ .collect(Collectors.toSet());
+ assertThat(zippedFrom2Sources).contains("Juventus Ronaldo", "Barcelona Messi", "Liverpool Salah");
+
+ String[] leagues = { "Serie A", "La Liga", "Premier League" };
+ Set zippedFrom3Sources = StreamUtils.zip(stream(clubs), stream(players), stream(leagues),
+ (club, player, league) -> club + " " + player + " " + league).collect(Collectors.toSet());
+ assertThat(zippedFrom3Sources).contains("Juventus Ronaldo Serie A", "Barcelona Messi La Liga",
+ "Liverpool Salah Premier League");
+ }
+
+ @Test
+ public void whenZippedWithIndex_thenZippedWithIndex() {
+ Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool");
+ Set> zipsWithIndex = StreamUtils.zipWithIndex(streamOfClubs).collect(Collectors.toSet());
+ assertThat(zipsWithIndex).contains(Indexed.index(0, "Juventus"), Indexed.index(1, "Barcelona"),
+ Indexed.index(2, "Liverpool"));
+ }
+
+ @Test
+ public void givenMultipleStream_whenMerged_thenMerged() {
+ Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool", "PSG");
+ Stream streamOfPlayers = Stream.of("Ronaldo", "Messi", "Salah");
+ Stream streamOfLeagues = Stream.of("Serie A", "La Liga", "Premier League");
+
+ Set merged = StreamUtils.merge(() -> "", (valOne, valTwo) -> valOne + " " + valTwo, streamOfClubs,
+ streamOfPlayers, streamOfLeagues).collect(Collectors.toSet());
+
+ assertThat(merged).contains(" Juventus Ronaldo Serie A", " Barcelona Messi La Liga", " Liverpool Salah Premier League",
+ " PSG");
+ }
+
+ @Test
+ public void givenMultipleStream_whenMergedToList_thenMergedToList() {
+ Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "PSG");
+ Stream streamOfPlayers = Stream.of("Ronaldo", "Messi");
+
+ List> mergedListOfList = StreamUtils.mergeToList(streamOfClubs, streamOfPlayers)
+ .collect(Collectors.toList());
+ assertThat(mergedListOfList.get(0)).isInstanceOf(List.class);
+ assertThat(mergedListOfList.get(0)).containsExactly("Juventus", "Ronaldo");
+ assertThat(mergedListOfList.get(1)).containsExactly("Barcelona", "Messi");
+ assertThat(mergedListOfList.get(2)).containsExactly("PSG");
+ }
+
+ @Test
+ public void givenMultipleStream_whenInterleaved_thenInterleaved() {
+ Stream streamOfClubs = Stream.of("Juventus", "Barcelona", "Liverpool");
+ Stream streamOfPlayers = Stream.of("Ronaldo", "Messi");
+ Stream streamOfLeagues = Stream.of("Serie A", "La Liga");
+
+ AtomicInteger counter = new AtomicInteger(0);
+ Selector roundRobinSelector = (o) -> {
+ Object[] vals = (Object[]) o;
+ while (counter.get() >= vals.length || vals[counter.get()] == null) {
+ if (counter.incrementAndGet() >= vals.length)
+ counter.set(0);
+ }
+ return counter.getAndIncrement();
+ };
+ Stream interleavedStream = StreamUtils.interleave(roundRobinSelector, streamOfClubs, streamOfPlayers,
+ streamOfLeagues);
+ List interleavedList = interleavedStream.collect(Collectors.toList());
+ assertThat(interleavedList).containsExactly("Juventus", "Ronaldo", "Serie A", "Barcelona", "Messi", "La Liga",
+ "Liverpool");
+ }
+
+ @Test
+ public void whenSkippedUntil_thenSkippedUntil() {
+ Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ List skippedUntilGreaterThan5 = StreamUtils.skipUntil(stream(numbers), i -> i > 5).collect(Collectors.toList());
+ assertThat(skippedUntilGreaterThan5).containsExactly(6, 7, 8, 9, 10);
+
+ List skippedUntilLessThanEquals5 = StreamUtils.skipUntil(stream(numbers), i -> i <= 5)
+ .collect(Collectors.toList());
+ assertThat(skippedUntilLessThanEquals5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ }
+
+ @Test
+ public void whenSkippedWhile_thenSkippedWhile() {
+ Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+ List skippedWhileLessThanEquals5 = StreamUtils.skipWhile(stream(numbers), i -> i <= 5)
+ .collect(Collectors.toList());
+ assertThat(skippedWhileLessThanEquals5).containsExactly(6, 7, 8, 9, 10);
+
+ List skippedWhileGreaterThan5 = StreamUtils.skipWhile(stream(numbers), i -> i > 5).collect(Collectors.toList());
+ assertThat(skippedWhileGreaterThan5).containsExactly(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+ }
+
+ @Test
+ public void givenFibonacciGenerator_whenUnfolded_thenUnfolded() {
+ AtomicInteger lastValue = new AtomicInteger(0);
+ Function> fibonacciGenerator = (i) -> (i < 10) ?
+ Optional.of(i + lastValue.getAndSet(i)) :
+ Optional.empty();
+
+ List fib = StreamUtils.unfold(1, fibonacciGenerator).collect(Collectors.toList());
+ assertThat(fib).containsExactly(1, 1, 2, 3, 5, 8, 13);
+ }
+
+ @Test
+ public void whenWindowed_thenWindowed() {
+ Integer[] numbers = { 1, 2, 3, 4, 5, 6, 7 };
+
+ List> windowedWithSkip1 = StreamUtils.windowed(stream(numbers), 3, 1).collect(Collectors.toList());
+ assertThat(windowedWithSkip1).containsExactly(asList(1, 2, 3), asList(2, 3, 4), asList(3, 4, 5), asList(4, 5, 6),
+ asList(5, 6, 7));
+
+ List> windowedWithSkip2 = StreamUtils.windowed(stream(numbers), 3, 2).collect(Collectors.toList());
+ assertThat(windowedWithSkip2).containsExactly(asList(1, 2, 3), asList(3, 4, 5), asList(5, 6, 7));
+ }
+
+ @Test
+ public void whenAggregated_thenAggregated() {
+ Integer[] numbers = { 1, 2, 2, 3, 4, 4, 4, 5 };
+ List> aggregated = StreamUtils.aggregate(stream(numbers), (int1, int2) -> int1.compareTo(int2) == 0)
+ .collect(Collectors.toList());
+ assertThat(aggregated).containsExactly(asList(1), asList(2, 2), asList(3), asList(4, 4, 4), asList(5));
+
+ List> aggregatedFixSize = StreamUtils.aggregate(stream(numbers), 5).collect(Collectors.toList());
+ assertThat(aggregatedFixSize).containsExactly(asList(1, 2, 2, 3, 4), asList(4, 4, 5));
+ }
+
+ @Test
+ public void whenGroupedRun_thenGroupedRun() {
+ Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 };
+ List> grouped = StreamUtils.groupRuns(stream(numbers)).collect(Collectors.toList());
+ assertThat(grouped).containsExactly(asList(1, 1), asList(2), asList(3), asList(4, 4), asList(5));
+
+ Integer[] numbers2 = { 1, 2, 3, 1 };
+ List> grouped2 = StreamUtils.groupRuns(stream(numbers2)).collect(Collectors.toList());
+ assertThat(grouped2).containsExactly(asList(1), asList(2), asList(3), asList(1));
+ }
+
+ @Test
+ public void whenAggregatedOnListCondition_thenAggregatedOnListCondition() {
+ Integer[] numbers = { 1, 1, 2, 3, 4, 4, 5 };
+ Stream> aggregated = StreamUtils.aggregateOnListCondition(stream(numbers),
+ (currentList, nextInt) -> currentList.stream().mapToInt(Integer::intValue).sum() + nextInt <= 5);
+ assertThat(aggregated).containsExactly(asList(1, 1, 2), asList(3), asList(4), asList(4), asList(5));
+ }
+
+ @Test
+ public void givenProjectionFunction_whenMaxedBy_thenMaxedBy() {
+ Stream clubs = Stream.of("Juventus", "Barcelona", "PSG");
+ Optional longestName = clubs.collect(CollectorUtils.maxBy(String::length));
+ assertThat(longestName.get()).isEqualTo("Barcelona");
+ }
+
+ @Test
+ public void givenStreamOfMultipleElem_whenUniqueCollector_thenValueReturned() {
+ Stream singleElement = Stream.of(1);
+ Optional unique = singleElement.collect(CollectorUtils.unique());
+ assertThat(unique.get()).isEqualTo(1);
+
+ }
+
+ @Test
+ public void givenStreamOfMultipleElem_whenUniqueCollector_thenExceptionThrown() {
+ Stream multipleElement = Stream.of(1, 2, 3);
+ assertThatExceptionOfType(NonUniqueValueException.class).isThrownBy(() -> {
+ multipleElement.collect(CollectorUtils.unique());
+ });
+ }
+
+}
diff --git a/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkUnitTest.java b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java
similarity index 98%
rename from java-streams/src/test/java/com/baeldung/streamordering/BenchmarkUnitTest.java
rename to java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java
index ba1cb1f726..656a6d95f9 100644
--- a/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkUnitTest.java
+++ b/java-streams/src/test/java/com/baeldung/streamordering/BenchmarkManualTest.java
@@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
-public class BenchmarkUnitTest
+public class BenchmarkManualTest
{
public void
diff --git a/java-strings/pom.xml b/java-strings/pom.xml
index 2afe18f07a..b1ba49b33a 100644
--- a/java-strings/pom.xml
+++ b/java-strings/pom.xml
@@ -47,11 +47,21 @@
jmh-core
${jmh-core.version}
+
+ org.openjdk.jmh
+ jmh-generator-annprocess
+ ${jmh-core.version}
+
com.ibm.icu
icu4j
${icu4j.version}
+
+ com.google.guava
+ guava
+ ${guava.version}
+
com.vdurmont
@@ -92,6 +102,7 @@
3.6.1
1.19
61.1
+ 26.0-jre
\ No newline at end of file
diff --git a/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java b/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java
index 085be66801..cdbba1ef53 100644
--- a/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java
+++ b/java-strings/src/main/java/com/baeldung/string/JoinerSplitter.java
@@ -2,6 +2,7 @@ package com.baeldung.string;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -32,5 +33,12 @@ public class JoinerSplitter {
.mapToObj(item -> (char) item)
.collect(Collectors.toList());
}
+
+ public static Map arrayToMap(String[] arrayOfString) {
+ return Arrays.asList(arrayOfString)
+ .stream()
+ .map(str -> str.split(":"))
+ .collect(Collectors.toMap(str -> str[0], str -> str[1]));
+ }
}
diff --git a/java-strings/src/main/java/com/baeldung/string/StringPerformance.java b/java-strings/src/main/java/com/baeldung/string/StringPerformance.java
new file mode 100644
index 0000000000..4873bd320c
--- /dev/null
+++ b/java-strings/src/main/java/com/baeldung/string/StringPerformance.java
@@ -0,0 +1,163 @@
+package com.baeldung.string;
+
+import org.apache.commons.lang3.StringUtils;
+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.util.List;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.SingleShotTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Measurement(batchSize = 10000, iterations = 10)
+@Warmup(batchSize = 10000, iterations = 10)
+public class StringPerformance extends StringPerformanceHints {
+
+ @Benchmark
+ public String benchmarkStringDynamicConcat() {
+ return dynamicConcat();
+ }
+
+ @Benchmark
+ public StringBuilder benchmarkStringBuilder() {
+ StringBuilder stringBuilder = new StringBuilder(result);
+ stringBuilder.append(baeldung);
+ return stringBuilder;
+ }
+
+ @Benchmark
+ public StringBuffer benchmarkStringBuffer() {
+ StringBuffer stringBuffer = new StringBuffer(result);
+ stringBuffer.append(baeldung);
+ return stringBuffer;
+ }
+
+ @Benchmark
+ public String benchmarkStringConstructor() {
+ return stringConstructor();
+ }
+
+ @Benchmark
+ public String benchmarkStringLiteral() {
+ return stringLiteral();
+ }
+
+ @Benchmark
+ public String benchmarkStringFormat_s() {
+ return stringFormat_s();
+ }
+
+ @Benchmark
+ public String benchmarkStringConcat() {
+ return stringConcat();
+ }
+
+ @Benchmark
+ public String benchmarkStringIntern() {
+ return stringIntern();
+ }
+
+ @Benchmark
+ public String benchmarkStringReplace() {
+ return longString.replace("average", " average !!!");
+ }
+
+ @Benchmark
+ public String benchmarkStringUtilsReplace() {
+ return StringUtils.replace(longString, "average", " average !!!");
+ }
+
+ @Benchmark
+ public List benchmarkGuavaSplitter() {
+ return guavaSplitter();
+ }
+
+ @Benchmark
+ public String [] benchmarkStringSplit() {
+ return stringSplit();
+ }
+
+ @Benchmark
+ public String [] benchmarkStringSplitPattern() {
+ return stringSplitPattern();
+ }
+
+ @Benchmark
+ public List benchmarkStringTokenizer() {
+ return stringTokenizer();
+ }
+
+ @Benchmark
+ public List benchmarkStringIndexOf() {
+ return stringIndexOf();
+ }
+
+
+ @Benchmark
+ public String benchmarkIntegerToString() {
+ return stringIntegerToString();
+ }
+
+ @Benchmark
+ public String benchmarkStringValueOf() {
+ return stringValueOf();
+ }
+
+
+ @Benchmark
+ public String benchmarkStringConvertPlus() {
+ return stringConvertPlus();
+ }
+
+ @Benchmark
+ public String benchmarkStringFormat_d() {
+ return stringFormat_d();
+ }
+
+ @Benchmark
+ public boolean benchmarkStringEquals() {
+ return stringEquals();
+ }
+
+
+ @Benchmark
+ public boolean benchmarkStringEqualsIgnoreCase() {
+ return stringEqualsIgnoreCase();
+ }
+
+ @Benchmark
+ public boolean benchmarkStringMatches() {
+ return stringIsMatch();
+ }
+
+ @Benchmark
+ public boolean benchmarkPrecompiledMatches() {
+ return precompiledMatches();
+ }
+
+ @Benchmark
+ public int benchmarkStringCompareTo() {
+ return stringCompareTo();
+ }
+
+ @Benchmark
+ public boolean benchmarkStringIsEmpty() {
+ return stringIsEmpty();
+ }
+
+ @Benchmark
+ public boolean benchmarkStringLengthZero() {
+ return stringLengthZero();
+ }
+
+ public static void main(String[] args) throws Exception {
+ Options options = new OptionsBuilder()
+ .include(StringPerformance.class.getSimpleName()).threads(1)
+ .forks(1).shouldFailOnError(true)
+ .shouldDoGC(true)
+ .jvmArgs("-server").build();
+ new Runner(options).run();
+ }
+}
diff --git a/java-strings/src/main/java/com/baeldung/string/StringPerformanceHints.java b/java-strings/src/main/java/com/baeldung/string/StringPerformanceHints.java
new file mode 100644
index 0000000000..509222136f
--- /dev/null
+++ b/java-strings/src/main/java/com/baeldung/string/StringPerformanceHints.java
@@ -0,0 +1,133 @@
+package com.baeldung.string;
+
+import com.google.common.base.Splitter;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.regex.Pattern;
+
+@State(Scope.Thread)
+public class StringPerformanceHints {
+
+ protected String baeldung = "baeldung";
+ protected String longString = "Hello baeldung, I am a bit longer than other Strings";
+ protected String formatString = "hello %s, nice to meet you";
+ protected String formatDigit = "%d";
+ protected String emptyString = " ";
+ protected String result = "";
+
+ protected int sampleNumber = 100;
+
+ protected Pattern spacePattern = Pattern.compile(emptyString);
+ protected Pattern longPattern = Pattern.compile(longString);
+ protected List stringSplit = new ArrayList<>();
+ protected List stringTokenizer = new ArrayList<>();
+
+ protected String dynamicConcat() {
+ result += baeldung;
+ return result;
+ }
+
+ protected String stringConstructor() {
+ return new String(baeldung);
+ }
+
+ protected String stringLiteral() {
+ result = baeldung;
+ return result;
+ }
+
+ protected String stringFormat_s() {
+ return String.format(formatString, baeldung);
+ }
+
+ protected String stringFormat_d() {
+ return String.format(formatDigit, sampleNumber);
+ }
+
+ protected String stringConcat() {
+ result = result.concat(baeldung);
+ return result;
+ }
+
+ protected List stringTokenizer() {
+ StringTokenizer st = new StringTokenizer(longString);
+ while (st.hasMoreTokens()) {
+ stringTokenizer.add(st.nextToken());
+ }
+ return stringTokenizer;
+ }
+
+ protected List stringIndexOf() {
+ int pos = 0, end;
+ while ((end = longString.indexOf(' ', pos)) >= 0) {
+ stringSplit.add(longString.substring(pos, end));
+ pos = end + 1;
+ }
+ return stringSplit;
+ }
+
+ protected String stringIntegerToString() {
+ return Integer.toString(sampleNumber);
+ }
+
+ protected String stringValueOf() {
+ return String.valueOf(sampleNumber);
+ }
+
+
+ protected String stringConvertPlus() {
+ return sampleNumber + "";
+ }
+
+
+ protected boolean stringEquals() {
+ return longString.equals(baeldung);
+ }
+
+
+ protected boolean stringEqualsIgnoreCase() {
+ return longString.equalsIgnoreCase(baeldung);
+ }
+
+ protected boolean stringIsMatch() {
+ return longString.matches(baeldung);
+ }
+
+ protected boolean precompiledMatches() {
+ return longPattern.matcher(baeldung).matches();
+ }
+
+ protected int stringCompareTo() {
+ return longString.compareTo(baeldung);
+ }
+
+ protected boolean stringIsEmpty() {
+ return longString.isEmpty();
+ }
+
+ protected boolean stringLengthZero() {
+ return longString.length() == 0;
+ }
+
+ protected String [] stringSplitPattern() {
+ return spacePattern.split(longString, 0);
+ }
+
+ protected String [] stringSplit() {
+ return longString.split(emptyString);
+ }
+
+ protected List guavaSplitter() {
+ return Splitter.on(" ").trimResults()
+ .omitEmptyStrings()
+ .splitToList(longString);
+ }
+
+ protected String stringIntern() {
+ return baeldung.intern();
+ }
+}
diff --git a/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java b/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java
index 8901bcf9db..a9488e27a4 100644
--- a/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java
+++ b/java-strings/src/test/java/com/baeldung/string/JoinerSplitterUnitTest.java
@@ -3,7 +3,9 @@ package com.baeldung.string;
import org.junit.Test;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import static org.junit.Assert.assertEquals;
@@ -62,5 +64,20 @@ public class JoinerSplitterUnitTest {
assertEquals(result, expectation);
}
+
+ @Test
+ public void givenStringArray_transformedToStream_convertToMap() {
+
+ String[] programming_languages = new String[] {"language:java","os:linux","editor:emacs"};
+
+ Map expectation=new HashMap<>();
+ expectation.put("language", "java");
+ expectation.put("os", "linux");
+ expectation.put("editor", "emacs");
+
+ Map result = JoinerSplitter.arrayToMap(programming_languages);
+ assertEquals(result, expectation);
+
+ }
}
diff --git a/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java b/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java
index 3859a2b26b..6157640a4a 100644
--- a/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java
+++ b/java-strings/src/test/java/com/baeldung/string/SplitUnitTest.java
@@ -2,10 +2,11 @@ package com.baeldung.string;
import static org.assertj.core.api.Assertions.assertThat;
+import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import com.google.common.base.Splitter;
@@ -54,4 +55,18 @@ public class SplitUnitTest {
assertThat(resultList)
.containsExactly("car", "jeep", "scooter");
}
+
+ @Test
+ public void givenStringContainsSpaces_whenSplitAndTrim_thenReturnsArray_using_Regex() {
+ assertThat(" car , jeep, scooter ".trim()
+ .split("\\s*,\\s*")).containsExactly("car", "jeep", "scooter");
+
+ }
+
+ @Test
+ public void givenStringContainsSpaces_whenSplitAndTrim_thenReturnsArray_using_java_8() {
+ assertThat(Arrays.stream(" car , jeep, scooter ".split(","))
+ .map(String::trim)
+ .toArray(String[]::new)).containsExactly("car", "jeep", "scooter");
+ }
}
diff --git a/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java b/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java
new file mode 100644
index 0000000000..17b13f89de
--- /dev/null
+++ b/java-strings/src/test/java/com/baeldung/string/StringEmptyUnitTest.java
@@ -0,0 +1,51 @@
+package com.baeldung.string;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString;
+import static org.hamcrest.text.IsEmptyString.isEmptyString;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.commons.lang3.StringUtils;
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+
+import com.google.common.base.Strings;
+
+public class StringEmptyUnitTest {
+
+ private String text = "baeldung";
+
+ @Test
+ public void givenAString_whenCheckedForEmptyUsingJunit_shouldAssertSuccessfully() {
+ assertTrue(!text.isEmpty());
+ assertFalse(text.isEmpty());
+ assertNotEquals("", text);
+ assertNotSame("", text);
+ }
+
+ @Test
+ public void givenAString_whenCheckedForEmptyUsingHamcrest_shouldAssertSuccessfully() {
+ assertThat(text, not(isEmptyString()));
+ assertThat(text, not(isEmptyOrNullString()));
+ }
+
+ @Test
+ public void givenAString_whenCheckedForEmptyUsingCommonsLang_shouldAssertSuccessfully() {
+ assertTrue(StringUtils.isNotBlank(text));
+ }
+
+ @Test
+ public void givenAString_whenCheckedForEmptyUsingAssertJ_shouldAssertSuccessfully() {
+ Assertions.assertThat(text).isNotEmpty();
+ }
+
+ @Test
+ public void givenAString_whenCheckedForEmptyUsingGuava_shouldAssertSuccessfully() {
+ assertFalse(Strings.isNullOrEmpty(text));
+ }
+
+}
diff --git a/jersey/pom.xml b/jersey/pom.xml
index e248f9cf90..b55bdc5330 100644
--- a/jersey/pom.xml
+++ b/jersey/pom.xml
@@ -39,6 +39,11 @@
jersey-mvc-freemarker
${jersey.version}
+
+ org.glassfish.jersey.ext
+ jersey-bean-validation
+ ${jersey.version}
+
org.glassfish.jersey.test-framework
jersey-test-framework-core
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java b/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java
index d4744066c4..b6b9853aae 100644
--- a/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java
+++ b/jersey/src/main/java/com/baeldung/jersey/server/config/ViewApplicationConfig.java
@@ -1,12 +1,14 @@
package com.baeldung.jersey.server.config;
import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.server.mvc.freemarker.FreemarkerMvcFeature;
public class ViewApplicationConfig extends ResourceConfig {
public ViewApplicationConfig() {
packages("com.baeldung.jersey.server");
+ property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
property(FreemarkerMvcFeature.TEMPLATE_BASE_PATH, "templates/freemarker");
register(FreemarkerMvcFeature.class);;
}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/constraints/SerialNumber.java b/jersey/src/main/java/com/baeldung/jersey/server/constraints/SerialNumber.java
new file mode 100644
index 0000000000..ca49797e31
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/constraints/SerialNumber.java
@@ -0,0 +1,35 @@
+package com.baeldung.jersey.server.constraints;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.regex.Pattern;
+
+import javax.validation.Constraint;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.Payload;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = { SerialNumber.Validator.class })
+public @interface SerialNumber {
+
+ String message()
+
+ default "Fruit serial number is not valid";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+
+ public class Validator implements ConstraintValidator {
+ @Override
+ public void initialize(final SerialNumber serial) {
+ }
+
+ @Override
+ public boolean isValid(final String serial, final ConstraintValidatorContext constraintValidatorContext) {
+ final String serialNumRegex = "^\\d{3}-\\d{3}-\\d{4}$";
+ return Pattern.matches(serialNumRegex, serial);
+ }
+ }
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java b/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java
index 30620e331d..c55362487b 100644
--- a/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java
+++ b/jersey/src/main/java/com/baeldung/jersey/server/model/Fruit.java
@@ -1,20 +1,57 @@
package com.baeldung.jersey.server.model;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Size;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
public class Fruit {
- private final String name;
- private final String colour;
+ @Min(value = 10, message = "Fruit weight must be 10 or greater")
+ private Integer weight;
+ @Size(min = 5, max = 200)
+ private String name;
+ @Size(min = 5, max = 200)
+ private String colour;
+ private String serial;
+
+ public Fruit() {
+ }
public Fruit(String name, String colour) {
this.name = name;
this.colour = colour;
}
-
+
public String getName() {
return name;
}
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setColour(String colour) {
+ this.colour = colour;
+ }
public String getColour() {
return colour;
}
+
+ public Integer getWeight() {
+ return weight;
+ }
+
+ public void setWeight(Integer weight) {
+ this.weight = weight;
+ }
+
+ public String getSerial() {
+ return serial;
+ }
+
+ public void setSerial(String serial) {
+ this.serial = serial;
+ }
}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/providers/FruitExceptionMapper.java b/jersey/src/main/java/com/baeldung/jersey/server/providers/FruitExceptionMapper.java
new file mode 100644
index 0000000000..cea61c897b
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/server/providers/FruitExceptionMapper.java
@@ -0,0 +1,26 @@
+package com.baeldung.jersey.server.providers;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ConstraintViolationException;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ExceptionMapper;
+
+public class FruitExceptionMapper implements ExceptionMapper {
+
+ @Override
+ public Response toResponse(final ConstraintViolationException exception) {
+ return Response.status(Response.Status.BAD_REQUEST)
+ .entity(prepareMessage(exception))
+ .type("text/plain")
+ .build();
+ }
+
+ private String prepareMessage(ConstraintViolationException exception) {
+ final StringBuilder message = new StringBuilder();
+ for (ConstraintViolation> cv : exception.getConstraintViolations()) {
+ message.append(cv.getPropertyPath() + " " + cv.getMessage() + "\n");
+ }
+ return message.toString();
+ }
+
+}
diff --git a/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java b/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java
index 4e1fa4aa11..ee34cdd3ca 100644
--- a/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java
+++ b/jersey/src/main/java/com/baeldung/jersey/server/rest/FruitResource.java
@@ -5,7 +5,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -15,7 +21,9 @@ import org.glassfish.jersey.server.mvc.ErrorTemplate;
import org.glassfish.jersey.server.mvc.Template;
import org.glassfish.jersey.server.mvc.Viewable;
+import com.baeldung.jersey.server.constraints.SerialNumber;
import com.baeldung.jersey.server.model.Fruit;
+import com.baeldung.jersey.service.SimpleStorageService;
@Path("/fruit")
public class FruitResource {
@@ -52,4 +60,49 @@ public class FruitResource {
return name;
}
+ @POST
+ @Path("/create")
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ public void createFruit(
+ @NotNull(message = "Fruit name must not be null") @FormParam("name") String name,
+ @NotNull(message = "Fruit colour must not be null") @FormParam("colour") String colour) {
+
+ Fruit fruit = new Fruit(name, colour);
+ SimpleStorageService.storeFruit(fruit);
+ }
+
+ @PUT
+ @Path("/update")
+ @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+ public void updateFruit(@SerialNumber @FormParam("serial") String serial) {
+ Fruit fruit = new Fruit();
+ fruit.setSerial(serial);
+ SimpleStorageService.storeFruit(fruit);
+ }
+
+ @POST
+ @Path("/create")
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void createFruit(@Valid Fruit fruit) {
+ SimpleStorageService.storeFruit(fruit);
+ }
+
+ @GET
+ @Valid
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/search/{name}")
+ public Fruit findFruitByName(@PathParam("name") String name) {
+ return SimpleStorageService.findByName(name);
+ }
+
+ @GET
+ @Produces(MediaType.TEXT_HTML)
+ @Path("/exception")
+ @Valid
+ public Fruit exception() {
+ Fruit fruit = new Fruit();
+ fruit.setName("a");
+ fruit.setColour("b");
+ return fruit;
+ }
}
diff --git a/jersey/src/main/java/com/baeldung/jersey/service/SimpleStorageService.java b/jersey/src/main/java/com/baeldung/jersey/service/SimpleStorageService.java
new file mode 100644
index 0000000000..e21dd584a1
--- /dev/null
+++ b/jersey/src/main/java/com/baeldung/jersey/service/SimpleStorageService.java
@@ -0,0 +1,25 @@
+package com.baeldung.jersey.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.baeldung.jersey.server.model.Fruit;
+
+public class SimpleStorageService {
+
+ private static final Map fruits = new HashMap();
+
+ public static void storeFruit(final Fruit fruit) {
+ fruits.put(fruit.getName(), fruit);
+ }
+
+ public static Fruit findByName(final String name) {
+ return fruits.entrySet()
+ .stream()
+ .filter(map -> name.equals(map.getKey()))
+ .map(map -> map.getValue())
+ .findFirst()
+ .get();
+ }
+
+}
diff --git a/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java b/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java
index a0b6daed51..2eeb5710cb 100644
--- a/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java
+++ b/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java
@@ -2,41 +2,116 @@ package com.baeldung.jersey.server.rest;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
+import javax.ws.rs.core.Form;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
import org.glassfish.jersey.test.JerseyTest;
-import org.junit.Assert;
+import org.glassfish.jersey.test.TestProperties;
import org.junit.Test;
import com.baeldung.jersey.server.config.ViewApplicationConfig;
+import com.baeldung.jersey.server.model.Fruit;
+import com.baeldung.jersey.server.providers.FruitExceptionMapper;
public class FruitResourceIntegrationTest extends JerseyTest {
@Override
protected Application configure() {
- return new ViewApplicationConfig();
+ enable(TestProperties.LOG_TRAFFIC);
+ enable(TestProperties.DUMP_ENTITY);
+
+ ViewApplicationConfig config = new ViewApplicationConfig();
+ config.register(FruitExceptionMapper.class);
+ return config;
}
@Test
- public void testAllFruit() {
+ public void givenGetAllFruit_whenCorrectRequest_thenAllTemplateInvoked() {
final String response = target("/fruit/all").request()
.get(String.class);
- Assert.assertThat(response, allOf(containsString("banana"), containsString("apple"), containsString("kiwi")));
+ assertThat(response, allOf(containsString("banana"), containsString("apple"), containsString("kiwi")));
}
@Test
- public void testIndex() {
+ public void givenGetFruit_whenCorrectRequest_thenIndexTemplateInvoked() {
final String response = target("/fruit").request()
.get(String.class);
- Assert.assertThat(response, containsString("Welcome Fruit Index Page!"));
+ assertThat(response, containsString("Welcome Fruit Index Page!"));
}
@Test
- public void testErrorTemplate() {
+ public void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() {
final String response = target("/fruit/orange").request()
.get(String.class);
- Assert.assertThat(response, containsString("Error - Fruit not found: orange!"));
+ assertThat(response, containsString("Error - Fruit not found: orange!"));
+ }
+
+ @Test
+ public void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() {
+ Form form = new Form();
+ form.param("name", "apple");
+ form.param("colour", null);
+ Response response = target("fruit/create").request(MediaType.APPLICATION_FORM_URLENCODED)
+ .post(Entity.form(form));
+
+ assertEquals("Http Response should be 400 ", 400, response.getStatus());
+ assertThat(response.readEntity(String.class), containsString("Fruit colour must not be null"));
+ }
+
+ @Test
+ public void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() {
+ Form form = new Form();
+ form.param("serial", "2345-2345");
+
+ Response response = target("fruit/update").request(MediaType.APPLICATION_FORM_URLENCODED)
+ .put(Entity.form(form));
+
+ assertEquals("Http Response should be 400 ", 400, response.getStatus());
+ assertThat(response.readEntity(String.class), containsString("Fruit serial number is not valid"));
+ }
+
+ @Test
+ public void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() {
+ Fruit fruit = new Fruit("Blueberry", "purple");
+ fruit.setWeight(1);
+
+ Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE)
+ .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE));
+
+ assertEquals("Http Response should be 400 ", 400, response.getStatus());
+ assertThat(response.readEntity(String.class), containsString("Fruit weight must be 10 or greater"));
+ }
+
+ @Test
+ public void givenFruitExists_whenSearching_thenResponseContainsFruit() {
+ Fruit fruit = new Fruit();
+ fruit.setName("strawberry");
+ fruit.setWeight(20);
+ Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE)
+ .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE));
+
+ assertEquals("Http Response should be 204 ", 204, response.getStatus());
+
+ final String json = target("fruit/search/strawberry").request()
+ .get(String.class);
+ assertThat(json, containsString("{\"name\":\"strawberry\",\"weight\":20}"));
+ }
+
+ @Test
+ public void givenFruit_whenFruitIsInvalid_thenReponseContainsCustomExceptions() {
+ final Response response = target("fruit/exception").request()
+ .get();
+
+ assertEquals("Http Response should be 400 ", 400, response.getStatus());
+ String responseString = response.readEntity(String.class);
+ assertThat(responseString, containsString("exception..colour size must be between 5 and 200"));
+ assertThat(responseString, containsString("exception..name size must be between 5 and 200"));
}
}
diff --git a/kotlin-libraries/README.md b/kotlin-libraries/README.md
index ce30c71792..30c4d03ded 100644
--- a/kotlin-libraries/README.md
+++ b/kotlin-libraries/README.md
@@ -6,5 +6,4 @@
- [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 with Ktor](http://www.baeldung.com/kotlin-ktor)
-- [Idiomatic Logging in Kotlin](http://www.baeldung.com/kotlin-logging)
-- [Guide to the Kotlin Exposed Framework](https://www.baeldung.com/kotlin-exposed-persistence)
\ No newline at end of file
+- [Guide to the Kotlin Exposed Framework](https://www.baeldung.com/kotlin-exposed-persistence)
diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml
index 2b83328295..5b34a903ce 100644
--- a/libraries-data/pom.xml
+++ b/libraries-data/pom.xml
@@ -147,7 +147,6 @@
jmapper-core
${jmapper.version}
-
org.apache.crunch
@@ -185,7 +184,72 @@
-
+
+ org.apache.flink
+ flink-connector-kafka-0.11_2.11
+ ${flink.version}
+
+
+ org.apache.flink
+ flink-streaming-java_2.11
+ ${flink.version}
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+ ${jackson.version}
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+
+
+ org.apache.flink
+ flink-core
+ ${flink.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.apache.flink
+ flink-java
+ ${flink.version}
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+ org.apache.flink
+ flink-test-utils_2.11
+ ${flink.version}
+ test
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+
+
+ org.awaitility
+ awaitility
+ ${awaitility.version}
+ test
+
+
+ org.awaitility
+ awaitility-proxy
+ ${awaitility.version}
+ test
+
+
@@ -336,6 +400,10 @@
2.4.0
2.8.2
1.1.0
+ 1.5.0
+ 2.8.5
+ 3.0.0
+ 3.6.2
3.8.4
1.8
3.0.0
diff --git a/libraries/src/main/java/com/baeldung/flink/FlinkDataPipeline.java b/libraries-data/src/main/java/com/baeldung/flink/FlinkDataPipeline.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/FlinkDataPipeline.java
rename to libraries-data/src/main/java/com/baeldung/flink/FlinkDataPipeline.java
diff --git a/libraries/src/main/java/com/baeldung/flink/LineSplitter.java b/libraries-data/src/main/java/com/baeldung/flink/LineSplitter.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/LineSplitter.java
rename to libraries-data/src/main/java/com/baeldung/flink/LineSplitter.java
diff --git a/libraries/src/main/java/com/baeldung/flink/WordCount.java b/libraries-data/src/main/java/com/baeldung/flink/WordCount.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/WordCount.java
rename to libraries-data/src/main/java/com/baeldung/flink/WordCount.java
diff --git a/libraries/src/main/java/com/baeldung/flink/connector/Consumers.java b/libraries-data/src/main/java/com/baeldung/flink/connector/Consumers.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/connector/Consumers.java
rename to libraries-data/src/main/java/com/baeldung/flink/connector/Consumers.java
diff --git a/libraries/src/main/java/com/baeldung/flink/connector/Producers.java b/libraries-data/src/main/java/com/baeldung/flink/connector/Producers.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/connector/Producers.java
rename to libraries-data/src/main/java/com/baeldung/flink/connector/Producers.java
diff --git a/libraries/src/main/java/com/baeldung/flink/model/Backup.java b/libraries-data/src/main/java/com/baeldung/flink/model/Backup.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/model/Backup.java
rename to libraries-data/src/main/java/com/baeldung/flink/model/Backup.java
diff --git a/libraries/src/main/java/com/baeldung/flink/model/InputMessage.java b/libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java
similarity index 99%
rename from libraries/src/main/java/com/baeldung/flink/model/InputMessage.java
rename to libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java
index 183fa69c11..b3f75256ae 100644
--- a/libraries/src/main/java/com/baeldung/flink/model/InputMessage.java
+++ b/libraries-data/src/main/java/com/baeldung/flink/model/InputMessage.java
@@ -18,7 +18,6 @@ public class InputMessage {
public String getSender() {
return sender;
}
-
public void setSender(String sender) {
this.sender = sender;
}
diff --git a/libraries/src/main/java/com/baeldung/flink/operator/BackupAggregator.java b/libraries-data/src/main/java/com/baeldung/flink/operator/BackupAggregator.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/operator/BackupAggregator.java
rename to libraries-data/src/main/java/com/baeldung/flink/operator/BackupAggregator.java
diff --git a/libraries/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java b/libraries-data/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java
rename to libraries-data/src/main/java/com/baeldung/flink/operator/InputMessageTimestampAssigner.java
diff --git a/libraries/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java b/libraries-data/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java
rename to libraries-data/src/main/java/com/baeldung/flink/operator/WordsCapitalizer.java
diff --git a/libraries/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java b/libraries-data/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java
similarity index 100%
rename from libraries/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java
rename to libraries-data/src/main/java/com/baeldung/flink/schema/BackupSerializationSchema.java
diff --git a/libraries/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java b/libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java
similarity index 89%
rename from libraries/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java
rename to libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java
index 1df456bbe5..9aaf8b9877 100644
--- a/libraries/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java
+++ b/libraries-data/src/main/java/com/baeldung/flink/schema/InputMessageDeserializationSchema.java
@@ -1,8 +1,6 @@
package com.baeldung.flink.schema;
import com.baeldung.flink.model.InputMessage;
-import com.fasterxml.jackson.annotation.JsonAutoDetect;
-import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.apache.flink.api.common.serialization.DeserializationSchema;
diff --git a/libraries/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java
similarity index 100%
rename from libraries/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java
rename to libraries-data/src/test/java/com/baeldung/flink/BackupCreatorIntegrationTest.java
diff --git a/libraries/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java
similarity index 100%
rename from libraries/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java
rename to libraries-data/src/test/java/com/baeldung/flink/WordCapitalizerIntegrationTest.java
diff --git a/libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java
similarity index 100%
rename from libraries/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java
rename to libraries-data/src/test/java/com/baeldung/flink/WordCountIntegrationTest.java
diff --git a/libraries-security/.gitignore b/libraries-security/.gitignore
new file mode 100644
index 0000000000..71881ad3ca
--- /dev/null
+++ b/libraries-security/.gitignore
@@ -0,0 +1,14 @@
+*.class
+
+#folders#
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
+/bin/
diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml
new file mode 100644
index 0000000000..a57f029702
--- /dev/null
+++ b/libraries-security/pom.xml
@@ -0,0 +1,51 @@
+
+
+ 4.0.0
+ libraries-security
+ libraries-security
+ jar
+
+
+ com.baeldung
+ parent-boot-1
+ 0.0.1-SNAPSHOT
+ ../parent-boot-1
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.security.oauth
+ spring-security-oauth2
+ 2.3.3.RELEASE
+
+
+
+ com.github.scribejava
+ scribejava-apis
+ ${scribejava.version}
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+ 4.12
+ 2.0.4.RELEASE
+ 5.6.0
+
+
+
+
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java b/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java
new file mode 100644
index 0000000000..bb86c497b0
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java
@@ -0,0 +1,15 @@
+package com.baeldung.scribejava;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+
+@SpringBootApplication
+public class ScribejavaApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ScribejavaApplication.class, args);
+ }
+
+
+}
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/api/MyApi.java b/libraries-security/src/main/java/com/baeldung/scribejava/api/MyApi.java
new file mode 100644
index 0000000000..cf073d3035
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/api/MyApi.java
@@ -0,0 +1,27 @@
+package com.baeldung.scribejava.api;
+
+import com.github.scribejava.core.builder.api.DefaultApi20;
+
+public class MyApi extends DefaultApi20 {
+
+ private MyApi() {
+ }
+
+ private static class InstanceHolder {
+ private static final MyApi INSTANCE = new MyApi();
+ }
+
+ public static MyApi instance() {
+ return InstanceHolder.INSTANCE;
+ }
+
+ @Override
+ public String getAccessTokenEndpoint() {
+ return "http://localhost:8080/oauth/token";
+ }
+
+ @Override
+ protected String getAuthorizationBaseUrl() {
+ return null;
+ }
+}
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/GoogleController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/GoogleController.java
new file mode 100644
index 0000000000..ffe4f0cc8a
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/GoogleController.java
@@ -0,0 +1,49 @@
+package com.baeldung.scribejava.controller;
+
+import com.baeldung.scribejava.service.GoogleService;
+import com.github.scribejava.core.model.OAuth2AccessToken;
+import com.github.scribejava.core.model.OAuthRequest;
+import com.github.scribejava.core.model.Response;
+import com.github.scribejava.core.model.Verb;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+
+@RestController
+public class GoogleController {
+
+ @Autowired
+ private GoogleService service;
+
+
+ @GetMapping(value ="/me/google")
+ public void me(HttpServletResponse response){
+ String auth = service.getService().getAuthorizationUrl();
+
+ response.setHeader("Location", auth);
+ response.setStatus(302);
+
+ }
+
+ @GetMapping(value = "/auth/google")
+ public String google(@RequestParam String code, HttpServletResponse servletResponse){
+
+ try {
+ OAuth2AccessToken token = service.getService().getAccessToken(code);
+
+ OAuthRequest request = new OAuthRequest(Verb.GET, "https://www.googleapis.com/oauth2/v1/userinfo?alt=json");
+ service.getService().signRequest(token, request);
+ Response response = service.getService().execute(request);
+ return response.getBody();
+
+ }catch (Exception e){
+ servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ }
+
+ return null;
+ }
+
+}
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/TwitterController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/TwitterController.java
new file mode 100644
index 0000000000..bfcd6d960c
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/TwitterController.java
@@ -0,0 +1,57 @@
+package com.baeldung.scribejava.controller;
+
+import com.baeldung.scribejava.service.TwitterService;
+import com.github.scribejava.core.model.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Scanner;
+import java.util.concurrent.ExecutionException;
+
+@RestController
+public class TwitterController {
+
+ @Autowired
+ private TwitterService service;
+
+
+ @GetMapping(value ="/me/twitter")
+ public String me(HttpServletResponse servletResponse){
+ try {
+ OAuth1RequestToken requestToken = service.getService().getRequestToken();
+
+ String auth = service.getService().getAuthorizationUrl(requestToken);
+
+ Runtime runtime = Runtime.getRuntime();
+ try {
+ runtime.exec("rundll32 url.dll,FileProtocolHandler " + auth);
+ } catch (IOException e) {
+ servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return null;
+ }
+
+ System.out.println("Insert twitter code:");
+ Scanner in = new Scanner(System.in);
+
+ String oauthverifier = in.nextLine();
+
+ final OAuth1AccessToken accessToken = service.getService().getAccessToken(requestToken,oauthverifier);
+
+ OAuthRequest request = new OAuthRequest(Verb.GET, "https://api.twitter.com/1.1/account/verify_credentials.json");
+ service.getService().signRequest(accessToken, request);
+ Response response = service.getService().execute(request);
+ return response.getBody();
+
+ } catch (IOException | InterruptedException | ExecutionException e) {
+ servletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ }
+
+ return null;
+ }
+
+
+
+}
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/UserController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/UserController.java
new file mode 100644
index 0000000000..68a11250de
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/UserController.java
@@ -0,0 +1,46 @@
+package com.baeldung.scribejava.controller;
+
+import com.baeldung.scribejava.service.MyService;
+import com.github.scribejava.core.model.OAuth2AccessToken;
+import com.github.scribejava.core.model.OAuthRequest;
+import com.github.scribejava.core.model.Response;
+import com.github.scribejava.core.model.Verb;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.security.Principal;
+
+@RestController(value = "/user")
+public class UserController {
+
+ @Autowired
+ private MyService service;
+
+ @GetMapping("/me/myapi")
+ public String me(@RequestParam String username, @RequestParam String password, HttpServletResponse responsehttp) {
+
+ try {
+ OAuth2AccessToken token = service.getService().getAccessTokenPasswordGrant(username, password);
+
+ OAuthRequest request = new OAuthRequest(Verb.GET, "http://localhost:8080/me");
+ service.getService().signRequest(token, request);
+ Response response = service.getService().execute(request);
+
+ return response.getBody();
+
+ } catch (Exception e) {
+ responsehttp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ }
+
+ return null;
+
+ }
+
+ @GetMapping("/me")
+ public Principal user(Principal principal) {
+ return principal;
+ }
+}
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/oauth/AuthServiceConfig.java b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/AuthServiceConfig.java
new file mode 100644
index 0000000000..2c7162399b
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/AuthServiceConfig.java
@@ -0,0 +1,45 @@
+package com.baeldung.scribejava.oauth;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
+
+
+@Configuration
+@EnableAuthorizationServer
+public class AuthServiceConfig extends AuthorizationServerConfigurerAdapter {
+
+ @Autowired
+ @Qualifier("authenticationManagerBean")
+ private AuthenticationManager authenticationManager;
+
+ @Override
+ public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
+ oauthServer.tokenKeyAccess("permitAll()")
+ .checkTokenAccess("isAuthenticated()");
+ }
+
+ @Override
+ public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
+ clients.inMemory()
+ .withClient("baeldung_api_key")
+ .secret("baeldung_api_secret")
+ .authorizedGrantTypes("password","refresh_token")
+ .scopes("read","write").autoApprove(true);
+ }
+
+ @Override
+ public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
+ endpoints
+ .authenticationManager(authenticationManager)
+ .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
+ }
+
+}
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/oauth/WebSecurityConfig.java b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/WebSecurityConfig.java
new file mode 100644
index 0000000000..7aa51400ea
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/oauth/WebSecurityConfig.java
@@ -0,0 +1,53 @@
+package com.baeldung.scribejava.oauth;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
+
+@Configuration
+@EnableResourceServer
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .headers().frameOptions().disable()
+ .and()
+ .csrf().disable();
+ }
+
+ @Override
+ protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+ auth.inMemoryAuthentication()
+ .withUser("baeldung")
+ .password("scribejava")
+ .roles("USER");
+ }
+
+ @Override
+ @Bean
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ return super.authenticationManagerBean();
+ }
+
+
+ @EnableResourceServer
+ @Configuration
+ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
+
+ @Override
+ public void configure(HttpSecurity http) throws Exception {
+ http
+ .authorizeRequests()
+ .antMatchers("/user/me").authenticated()
+ .and()
+ .csrf().disable();
+ }
+ }
+
+}
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/service/GoogleService.java b/libraries-security/src/main/java/com/baeldung/scribejava/service/GoogleService.java
new file mode 100644
index 0000000000..fbcc39763c
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/service/GoogleService.java
@@ -0,0 +1,31 @@
+package com.baeldung.scribejava.service;
+
+import com.github.scribejava.apis.GoogleApi20;
+import com.github.scribejava.core.builder.ServiceBuilder;
+import com.github.scribejava.core.oauth.OAuth20Service;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+@Component
+public class GoogleService {
+
+ private OAuth20Service service;
+ private final String API_KEY = "api_key";
+ private final String API_SECRET = "api_secret";
+ private final String SCOPE = "https://www.googleapis.com/auth/userinfo.email";
+ private final String CALLBACK = "http://localhost:8080/auth/google";
+
+ @PostConstruct
+ private void init(){
+ this.service = new ServiceBuilder(API_KEY)
+ .apiSecret(API_SECRET)
+ .scope(SCOPE)
+ .callback(CALLBACK)
+ .build(GoogleApi20.instance());
+ }
+
+
+ public OAuth20Service getService() {
+ return service;
+ }
+}
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/service/MyService.java b/libraries-security/src/main/java/com/baeldung/scribejava/service/MyService.java
new file mode 100644
index 0000000000..739c82172c
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/service/MyService.java
@@ -0,0 +1,29 @@
+package com.baeldung.scribejava.service;
+
+import com.baeldung.scribejava.api.MyApi;
+import com.github.scribejava.core.builder.ServiceBuilder;
+import com.github.scribejava.core.oauth.OAuth20Service;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+@Component
+public class MyService {
+
+ private OAuth20Service service;
+ private final String API_KEY = "baeldung_api_key";
+ private final String API_SECRET = "baeldung_api_secret";
+
+ @PostConstruct
+ private void init(){
+ this.service = new ServiceBuilder(API_KEY)
+ .apiSecret(API_SECRET)
+ .scope("read write")
+ .build(MyApi.instance());
+ }
+
+
+ public OAuth20Service getService() {
+ return service;
+ }
+}
diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/service/TwitterService.java b/libraries-security/src/main/java/com/baeldung/scribejava/service/TwitterService.java
new file mode 100644
index 0000000000..df49f74679
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/scribejava/service/TwitterService.java
@@ -0,0 +1,29 @@
+package com.baeldung.scribejava.service;
+
+import com.github.scribejava.apis.TwitterApi;
+import com.github.scribejava.core.builder.ServiceBuilder;
+import com.github.scribejava.core.oauth.OAuth10aService;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+@Component
+public class TwitterService {
+
+ private final String API_KEY = "api_key";
+ private final String API_SECRET = "api_secret";
+ private OAuth10aService service;
+
+ @PostConstruct
+ private void init(){
+ this.service = new ServiceBuilder(API_KEY)
+ .apiSecret(API_SECRET)
+ .build(TwitterApi.instance());
+ }
+
+ public OAuth10aService getService(){
+ return service;
+ }
+
+
+}
diff --git a/libraries-security/src/main/resources/application.properties b/libraries-security/src/main/resources/application.properties
new file mode 100644
index 0000000000..71c6176533
--- /dev/null
+++ b/libraries-security/src/main/resources/application.properties
@@ -0,0 +1 @@
+security.oauth2.resource.filter-order = 3
\ No newline at end of file
diff --git a/libraries-security/src/test/java/com/baeldung/scribejava/ScribejavaUnitTest.java b/libraries-security/src/test/java/com/baeldung/scribejava/ScribejavaUnitTest.java
new file mode 100644
index 0000000000..6565a5b085
--- /dev/null
+++ b/libraries-security/src/test/java/com/baeldung/scribejava/ScribejavaUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.scribejava;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ScribejavaUnitTest {
+
+ @Test
+ public void contextLoad(){
+
+ }
+
+}
diff --git a/libraries/pom.xml b/libraries/pom.xml
index 1a88acfb7b..91c54b6113 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -154,45 +154,7 @@
commons-dbutils
${commons.dbutils.version}
-
- org.apache.flink
- flink-connector-kafka-0.11_2.11
- ${flink.version}
-
-
- org.apache.flink
- flink-streaming-java_2.11
- ${flink.version}
-
-
- org.apache.flink
- flink-core
- ${flink.version}
-
-
- commons-logging
- commons-logging
-
-
-
-
- org.apache.flink
- flink-java
- ${flink.version}
-
-
- commons-logging
- commons-logging
-
-
-
-
- org.apache.flink
- flink-test-utils_2.11
- ${flink.version}
- test
-
org.apache.commons
commons-math3
@@ -239,11 +201,7 @@
jackson-databind
${jackson.version}
-
- com.fasterxml.jackson.datatype
- jackson-datatype-jsr310
- ${jackson.version}
-
+
org.datanucleus
@@ -900,7 +858,6 @@
4.5.3
2.5
- 1.5.0
2.8.5
2.92
1.9.26
@@ -933,7 +890,7 @@
2.5.5
1.23.0
v4-rev493-1.21.0
- 1.0.0
+ 2.0.0
1.7.0
3.0.14
2.2.0
diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/application/Application.java b/libraries/src/main/java/com/baeldung/commons/lang3/application/Application.java
new file mode 100644
index 0000000000..7d4316e3ec
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/commons/lang3/application/Application.java
@@ -0,0 +1,8 @@
+package com.baeldung.commons.lang3.application;
+
+public class Application {
+
+ public static void main(String[] args) {
+
+ }
+}
diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/beans/User.java b/libraries/src/main/java/com/baeldung/commons/lang3/beans/User.java
new file mode 100644
index 0000000000..68aab46c33
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/commons/lang3/beans/User.java
@@ -0,0 +1,25 @@
+package com.baeldung.commons.lang3.beans;
+
+public class User {
+
+ private final String name;
+ private final String email;
+
+ public User(String name, String email) {
+ this.name = name;
+ this.email = email;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" + "name=" + name + ", email=" + email + '}';
+ }
+}
diff --git a/libraries/src/main/java/com/baeldung/commons/lang3/beans/UserInitializer.java b/libraries/src/main/java/com/baeldung/commons/lang3/beans/UserInitializer.java
new file mode 100644
index 0000000000..ae5d80244c
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/commons/lang3/beans/UserInitializer.java
@@ -0,0 +1,11 @@
+package com.baeldung.commons.lang3.beans;
+
+import org.apache.commons.lang3.concurrent.LazyInitializer;
+
+public class UserInitializer extends LazyInitializer {
+
+ @Override
+ protected User initialize() {
+ return new User("John", "john@domain.com");
+ }
+}
diff --git a/libraries/src/main/java/com/baeldung/kafka/TransactionalMessageProducer.java b/libraries/src/main/java/com/baeldung/kafka/TransactionalMessageProducer.java
new file mode 100644
index 0000000000..15488bbaf4
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/kafka/TransactionalMessageProducer.java
@@ -0,0 +1,56 @@
+package com.baeldung.kafka;
+
+import org.apache.kafka.clients.producer.KafkaProducer;
+import org.apache.kafka.clients.producer.ProducerRecord;
+import org.apache.kafka.common.KafkaException;
+
+import java.util.Properties;
+import java.util.stream.Stream;
+
+import static org.apache.kafka.clients.consumer.ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG;
+import static org.apache.kafka.clients.producer.ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG;
+import static org.apache.kafka.clients.producer.ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG;
+import static org.apache.kafka.clients.producer.ProducerConfig.TRANSACTIONAL_ID_CONFIG;
+import static org.apache.kafka.clients.producer.ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG;
+
+public class TransactionalMessageProducer {
+
+ private static final String DATA_MESSAGE_1 = "Put any space separated data here for count";
+ private static final String DATA_MESSAGE_2 = "Output will contain count of every word in the message";
+
+ public static void main(String[] args) {
+
+ KafkaProducer producer = createKafkaProducer();
+
+ producer.initTransactions();
+
+ try{
+
+ producer.beginTransaction();
+
+ Stream.of(DATA_MESSAGE_1, DATA_MESSAGE_2).forEach(s -> producer.send(
+ new ProducerRecord("input", null, s)));
+
+ producer.commitTransaction();
+
+ }catch (KafkaException e){
+
+ producer.abortTransaction();
+
+ }
+
+ }
+
+ private static KafkaProducer createKafkaProducer() {
+
+ Properties props = new Properties();
+ props.put(BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
+ props.put(ENABLE_IDEMPOTENCE_CONFIG, "true");
+ props.put(TRANSACTIONAL_ID_CONFIG, "prod-0");
+ props.put(KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+ props.put(VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+
+ return new KafkaProducer(props);
+
+ }
+}
diff --git a/libraries/src/main/java/com/baeldung/kafka/TransactionalWordCount.java b/libraries/src/main/java/com/baeldung/kafka/TransactionalWordCount.java
new file mode 100644
index 0000000000..0563ba6684
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/kafka/TransactionalWordCount.java
@@ -0,0 +1,105 @@
+package com.baeldung.kafka;
+
+import org.apache.kafka.clients.consumer.ConsumerRecord;
+import org.apache.kafka.clients.consumer.ConsumerRecords;
+import org.apache.kafka.clients.consumer.KafkaConsumer;
+import org.apache.kafka.clients.consumer.OffsetAndMetadata;
+import org.apache.kafka.clients.producer.KafkaProducer;
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.apache.kafka.clients.producer.ProducerRecord;
+import org.apache.kafka.common.KafkaException;
+import org.apache.kafka.common.TopicPartition;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.time.Duration.ofSeconds;
+import static java.util.Collections.singleton;
+import static org.apache.kafka.clients.consumer.ConsumerConfig.*;
+import static org.apache.kafka.clients.consumer.ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG;
+import static org.apache.kafka.clients.producer.ProducerConfig.*;
+
+public class TransactionalWordCount {
+
+ private static final String CONSUMER_GROUP_ID = "my-group-id";
+ private static final String OUTPUT_TOPIC = "output";
+ private static final String INPUT_TOPIC = "input";
+
+ public static void main(String[] args) {
+
+ KafkaConsumer consumer = createKafkaConsumer();
+ KafkaProducer producer = createKafkaProducer();
+
+ producer.initTransactions();
+
+ try {
+
+ while (true) {
+
+ ConsumerRecords records = consumer.poll(ofSeconds(60));
+
+ Map wordCountMap = records.records(new TopicPartition(INPUT_TOPIC, 0))
+ .stream()
+ .flatMap(record -> Stream.of(record.value().split(" ")))
+ .map(word -> Tuple.of(word, 1))
+ .collect(Collectors.toMap(tuple -> tuple.getKey(), t1 -> t1.getValue(), (v1, v2) -> v1 + v2));
+
+ producer.beginTransaction();
+
+ wordCountMap.forEach((key, value) -> producer.send(new ProducerRecord(OUTPUT_TOPIC, key, value.toString())));
+
+ Map offsetsToCommit = new HashMap<>();
+
+ for (TopicPartition partition : records.partitions()) {
+ List> partitionedRecords = records.records(partition);
+ long offset = partitionedRecords.get(partitionedRecords.size() - 1).offset();
+
+ offsetsToCommit.put(partition, new OffsetAndMetadata(offset + 1));
+ }
+
+ producer.sendOffsetsToTransaction(offsetsToCommit, CONSUMER_GROUP_ID);
+ producer.commitTransaction();
+
+ }
+
+ } catch (KafkaException e) {
+
+ producer.abortTransaction();
+
+ }
+
+
+ }
+
+ private static KafkaConsumer createKafkaConsumer() {
+ Properties props = new Properties();
+ props.put(BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
+ props.put(GROUP_ID_CONFIG, CONSUMER_GROUP_ID);
+ props.put(ENABLE_AUTO_COMMIT_CONFIG, "false");
+ props.put(ISOLATION_LEVEL_CONFIG, "read_committed");
+ props.put(KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
+ props.put(VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
+
+ KafkaConsumer consumer = new KafkaConsumer<>(props);
+ consumer.subscribe(singleton(INPUT_TOPIC));
+ return consumer;
+ }
+
+ private static KafkaProducer createKafkaProducer() {
+
+ Properties props = new Properties();
+ props.put(BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
+ props.put(ENABLE_IDEMPOTENCE_CONFIG, "true");
+ props.put(TRANSACTIONAL_ID_CONFIG, "prod-1");
+ props.put(KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+ props.put(VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
+
+ return new KafkaProducer(props);
+
+ }
+
+}
diff --git a/libraries/src/main/java/com/baeldung/kafka/Tuple.java b/libraries/src/main/java/com/baeldung/kafka/Tuple.java
new file mode 100644
index 0000000000..883de4ba21
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/kafka/Tuple.java
@@ -0,0 +1,24 @@
+package com.baeldung.kafka;
+
+public class Tuple {
+
+ private String key;
+ private Integer value;
+
+ private Tuple(String key, Integer value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public static Tuple of(String key, Integer value){
+ return new Tuple(key,value);
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public Integer getValue() {
+ return value;
+ }
+}
diff --git a/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java b/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java
index 76d044ca60..086f32677e 100644
--- a/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java
+++ b/libraries/src/main/java/com/baeldung/opencsv/examples/sync/BeanExamples.java
@@ -18,16 +18,19 @@ import java.util.List;
public class BeanExamples {
public static List beanBuilderExample(Path path, Class clazz) {
+ ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy();
+ return beanBuilderExample(path, clazz, ms);
+ }
+
+ public static List beanBuilderExample(Path path, Class clazz, MappingStrategy ms) {
CsvTransfer csvTransfer = new CsvTransfer();
try {
- ColumnPositionMappingStrategy ms = new ColumnPositionMappingStrategy();
ms.setType(clazz);
Reader reader = Files.newBufferedReader(path);
- CsvToBean cb = new CsvToBeanBuilder(reader)
- .withType(clazz)
- .withMappingStrategy(ms)
- .build();
+ CsvToBean cb = new CsvToBeanBuilder(reader).withType(clazz)
+ .withMappingStrategy(ms)
+ .build();
csvTransfer.setCsvList(cb.parse());
reader.close();
@@ -40,11 +43,10 @@ public class BeanExamples {
public static String writeCsvFromBean(Path path) {
try {
- Writer writer = new FileWriter(path.toString());
+ Writer writer = new FileWriter(path.toString());
- StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer)
- .withSeparator(CSVWriter.DEFAULT_SEPARATOR)
- .build();
+ StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer).withSeparator(CSVWriter.DEFAULT_SEPARATOR)
+ .build();
List list = new ArrayList<>();
list.add(new WriteExampleBean("Test1", "sfdsf", "fdfd"));
diff --git a/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java b/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java
index e46d8654a2..64e13a277e 100644
--- a/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java
+++ b/libraries/src/test/java/com/baeldung/commons/collections/BidiMapUnitTest.java
@@ -42,4 +42,13 @@ public class BidiMapUnitTest {
map.put("key1", "value1");
assertEquals(map.getKey("value1"), "key1");
}
+
+ @Test
+ public void givenKeyValue_whenAddValue_thenReplaceFirstKey() {
+ BidiMap map = new DualHashBidiMap<>();
+ map.put("key1", "value1");
+ map.put("key2", "value1");
+ assertEquals(map.size(), 1);
+ assertFalse(map.containsKey("key1"));
+ }
}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ArrayUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ArrayUtilsUnitTest.java
new file mode 100644
index 0000000000..5eba736b4a
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ArrayUtilsUnitTest.java
@@ -0,0 +1,84 @@
+package com.baeldung.commons.lang3.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.commons.lang3.ArrayUtils;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class ArrayUtilsUnitTest {
+
+ @Test
+ public void givenArrayUtilsClass_whenCalledtoString_thenCorrect() {
+ String[] array = {"a", "b", "c"};
+ assertThat(ArrayUtils.toString(array)).isEqualTo("{a,b,c}");
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCalledtoStringIfArrayisNull_thenCorrect() {
+ String[] array = null;
+ assertThat(ArrayUtils.toString(array, "Array is null")).isEqualTo("Array is null");
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCalledhashCode_thenCorrect() {
+ String[] array = {"a", "b", "c"};
+ assertThat(ArrayUtils.hashCode(array)).isEqualTo(997619);
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCalledtoMap_thenCorrect() {
+ String[][] array = {{"1", "one", }, {"2", "two", }, {"3", "three"}};
+ Map map = new HashMap();
+ map.put("1", "one");
+ map.put("2", "two");
+ map.put("3", "three");
+ assertThat(ArrayUtils.toMap(array)).isEqualTo(map);
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCallednullToEmptyStringArray_thenCorrect() {
+ String[] array = null;
+ assertThat(ArrayUtils.nullToEmpty(array)).isEmpty();
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCallednullToEmptyObjectArray_thenCorrect() {
+ Object[] array = null;
+ assertThat(ArrayUtils.nullToEmpty(array)).isEmpty();
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCalledsubarray_thenCorrect() {
+ int[] array = {1, 2, 3};
+ int[] expected = {1};
+ assertThat(ArrayUtils.subarray(array, 0, 1)).isEqualTo(expected);
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCalledisSameLength_thenCorrect() {
+ int[] array1 = {1, 2, 3};
+ int[] array2 = {1, 2, 3};
+ assertThat(ArrayUtils.isSameLength(array1, array2)).isTrue();
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCalledreverse_thenCorrect() {
+ int[] array1 = {1, 2, 3};
+ int[] array2 = {3, 2, 1};
+ ArrayUtils.reverse(array1);
+ assertThat(array1).isEqualTo(array2);
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCalledIndexOf_thenCorrect() {
+ int[] array = {1, 2, 3};
+ assertThat(ArrayUtils.indexOf(array, 1, 0)).isEqualTo(0);
+ }
+
+ @Test
+ public void givenArrayUtilsClass_whenCalledcontains_thenCorrect() {
+ int[] array = {1, 2, 3};
+ assertThat(ArrayUtils.contains(array, 1)).isTrue();
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/BasicThreadFactoryUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/BasicThreadFactoryUnitTest.java
new file mode 100644
index 0000000000..f32980269a
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/BasicThreadFactoryUnitTest.java
@@ -0,0 +1,18 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.concurrent.BasicThreadFactory;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class BasicThreadFactoryUnitTest {
+
+ @Test
+ public void givenBasicThreadFactoryInstance_whenCalledBuilder_thenCorrect() {
+ BasicThreadFactory factory = new BasicThreadFactory.Builder()
+ .namingPattern("workerthread-%d")
+ .daemon(true)
+ .priority(Thread.MAX_PRIORITY)
+ .build();
+ assertThat(factory).isInstanceOf(BasicThreadFactory.class);
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ConstructorUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ConstructorUtilsUnitTest.java
new file mode 100644
index 0000000000..f55f239d75
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ConstructorUtilsUnitTest.java
@@ -0,0 +1,28 @@
+package com.baeldung.commons.lang3.test;
+
+import com.baeldung.commons.lang3.beans.User;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import org.apache.commons.lang3.reflect.ConstructorUtils;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class ConstructorUtilsUnitTest {
+
+ @Test
+ public void givenConstructorUtilsClass_whenCalledgetAccessibleConstructor_thenCorrect() {
+ assertThat(ConstructorUtils.getAccessibleConstructor(User.class, String.class, String.class)).isInstanceOf(Constructor.class);
+ }
+
+ @Test
+ public void givenConstructorUtilsClass_whenCalledinvokeConstructor_thenCorrect() throws Exception {
+ assertThat(ConstructorUtils.invokeConstructor(User.class, "name", "email")).isInstanceOf(User.class);
+ }
+
+ @Test
+ public void givenConstructorUtilsClass_whenCalledinvokeExactConstructor_thenCorrect() throws Exception {
+ String[] args = {"name", "email"};
+ Class[] parameterTypes= {String.class, String.class};
+ assertThat(ConstructorUtils.invokeExactConstructor(User.class, args, parameterTypes)).isInstanceOf(User.class);
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/FieldUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/FieldUtilsUnitTest.java
new file mode 100644
index 0000000000..8abb373e30
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/FieldUtilsUnitTest.java
@@ -0,0 +1,60 @@
+package com.baeldung.commons.lang3.test;
+
+import com.baeldung.commons.lang3.beans.User;
+import org.apache.commons.lang3.reflect.FieldUtils;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class FieldUtilsUnitTest {
+
+ private static User user;
+
+ @BeforeClass
+ public static void setUpUserInstance() {
+ user = new User("Julie", "julie@domain.com");
+ }
+
+ @Test
+ public void givenFieldUtilsClass_whenCalledgetField_thenCorrect() {
+ assertThat(FieldUtils.getField(User.class, "name", true).getName()).isEqualTo("name");
+ }
+
+ @Test
+ public void givenFieldUtilsClass_whenCalledgetFieldForceAccess_thenCorrect() {
+ assertThat(FieldUtils.getField(User.class, "name", true).getName()).isEqualTo("name");
+ }
+
+ @Test
+ public void givenFieldUtilsClass_whenCalledgetDeclaredFieldForceAccess_thenCorrect() {
+ assertThat(FieldUtils.getDeclaredField(User.class, "name", true).getName()).isEqualTo("name");
+ }
+
+ @Test
+ public void givenFieldUtilsClass_whenCalledgetAllField_thenCorrect() {
+ assertThat(FieldUtils.getAllFields(User.class).length).isEqualTo(2);
+ }
+
+ @Test
+ public void givenFieldUtilsClass_whenCalledreadField_thenCorrect() throws IllegalAccessException {
+ assertThat(FieldUtils.readField(user, "name", true)).isEqualTo("Julie");
+ }
+
+ @Test
+ public void givenFieldUtilsClass_whenCalledreadDeclaredField_thenCorrect() throws IllegalAccessException {
+ assertThat(FieldUtils.readDeclaredField(user, "name", true)).isEqualTo("Julie");
+ }
+
+ @Test
+ public void givenFieldUtilsClass_whenCalledwriteField_thenCorrect() throws IllegalAccessException {
+ FieldUtils.writeField(user, "name", "Julie", true);
+ assertThat(FieldUtils.readField(user, "name", true)).isEqualTo("Julie");
+
+ }
+
+ @Test
+ public void givenFieldUtilsClass_whenCalledwriteDeclaredField_thenCorrect() throws IllegalAccessException {
+ FieldUtils.writeDeclaredField(user, "name", "Julie", true);
+ assertThat(FieldUtils.readField(user, "name", true)).isEqualTo("Julie");
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/FractionUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/FractionUnitTest.java
new file mode 100644
index 0000000000..1a5094a16d
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/FractionUnitTest.java
@@ -0,0 +1,34 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.math.Fraction;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class FractionUnitTest {
+
+ @Test
+ public void givenFractionClass_whenCalledgetFraction_thenCorrect() {
+ assertThat(Fraction.getFraction(5, 6)).isInstanceOf(Fraction.class);
+ }
+
+ @Test
+ public void givenTwoFractionInstances_whenCalledadd_thenCorrect() {
+ Fraction fraction1 = Fraction.getFraction(1, 4);
+ Fraction fraction2 = Fraction.getFraction(3, 4);
+ assertThat(fraction1.add(fraction2).toString()).isEqualTo("1/1");
+ }
+
+ @Test
+ public void givenTwoFractionInstances_whenCalledsubstract_thenCorrect() {
+ Fraction fraction1 = Fraction.getFraction(3, 4);
+ Fraction fraction2 = Fraction.getFraction(1, 4);
+ assertThat(fraction1.subtract(fraction2).toString()).isEqualTo("1/2");
+ }
+
+ @Test
+ public void givenTwoFractionInstances_whenCalledmultiply_thenCorrect() {
+ Fraction fraction1 = Fraction.getFraction(3, 4);
+ Fraction fraction2 = Fraction.getFraction(1, 4);
+ assertThat(fraction1.multiplyBy(fraction2).toString()).isEqualTo("3/16");
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/HashCodeBuilderUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/HashCodeBuilderUnitTest.java
new file mode 100644
index 0000000000..bbd24c8207
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/HashCodeBuilderUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class HashCodeBuilderUnitTest {
+
+ @Test
+ public void givenHashCodeBuilderInstance_whenCalledtoHashCode_thenCorrect() {
+ int hashcode = new HashCodeBuilder(17, 37)
+ .append("John")
+ .append("john@domain.com")
+ .toHashCode();
+ assertThat(hashcode).isEqualTo(1269178828);
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutablePairUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutablePairUnitTest.java
new file mode 100644
index 0000000000..28ed8d2514
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutablePairUnitTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class ImmutablePairUnitTest {
+
+ private static ImmutablePair immutablePair;
+
+ @BeforeClass
+ public static void setUpImmutablePairInstance() {
+ immutablePair = new ImmutablePair<>("leftElement", "rightElement");
+ }
+
+ @Test
+ public void givenImmutablePairInstance_whenCalledgetLeft_thenCorrect() {
+ assertThat(immutablePair.getLeft()).isEqualTo("leftElement");
+ }
+
+ @Test
+ public void givenImmutablePairInstance_whenCalledgetRight_thenCorrect() {
+ assertThat(immutablePair.getRight()).isEqualTo("rightElement");
+ }
+
+ @Test
+ public void givenImmutablePairInstance_whenCalledof_thenCorrect() {
+ assertThat(ImmutablePair.of("leftElement", "rightElement")).isInstanceOf(ImmutablePair.class);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void givenImmutablePairInstance_whenCalledSetValue_thenThrowUnsupportedOperationException() {
+ immutablePair.setValue("newValue");
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutableTripleUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutableTripleUnitTest.java
new file mode 100644
index 0000000000..a9dd3fa7c0
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/ImmutableTripleUnitTest.java
@@ -0,0 +1,31 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.tuple.ImmutableTriple;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class ImmutableTripleUnitTest {
+
+ private static ImmutableTriple immutableTriple;
+
+ @BeforeClass
+ public static void setUpImmutableTripleInstance() {
+ immutableTriple = new ImmutableTriple<>("leftElement", "middleElement", "rightElement");
+ }
+
+ @Test
+ public void givenImmutableTripleInstance_whenCalledgetLeft_thenCorrect() {
+ assertThat(immutableTriple.getLeft()).isEqualTo("leftElement");
+ }
+
+ @Test
+ public void givenImmutableTripleInstance_whenCalledgetMiddle_thenCorrect() {
+ assertThat(immutableTriple.getMiddle()).isEqualTo("middleElement");
+ }
+
+ @Test
+ public void givenImmutableInstance_whenCalledgetRight_thenCorrect() {
+ assertThat(immutableTriple.getRight()).isEqualTo("rightElement");
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/LazyInitializerUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/LazyInitializerUnitTest.java
new file mode 100644
index 0000000000..a08399f8de
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/LazyInitializerUnitTest.java
@@ -0,0 +1,16 @@
+package com.baeldung.commons.lang3.test;
+
+import com.baeldung.commons.lang3.beans.User;
+import com.baeldung.commons.lang3.beans.UserInitializer;
+import org.apache.commons.lang3.concurrent.ConcurrentException;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class LazyInitializerUnitTest {
+
+ @Test
+ public void givenLazyInitializerInstance_whenCalledget_thenCorrect() throws ConcurrentException {
+ UserInitializer userInitializer = new UserInitializer();
+ assertThat(userInitializer.get()).isInstanceOf(User.class);
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/MethodUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/MethodUtilsUnitTest.java
new file mode 100644
index 0000000000..5e1d15f2f8
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/MethodUtilsUnitTest.java
@@ -0,0 +1,15 @@
+package com.baeldung.commons.lang3.test;
+
+import com.baeldung.commons.lang3.beans.User;
+import java.lang.reflect.Method;
+import org.apache.commons.lang3.reflect.MethodUtils;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class MethodUtilsUnitTest {
+
+ @Test
+ public void givenMethodUtilsClass_whenCalledgetAccessibleMethod_thenCorrect() {
+ assertThat(MethodUtils.getAccessibleMethod(User.class, "getName")).isInstanceOf(Method.class);
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/MutableObjectUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutableObjectUnitTest.java
new file mode 100644
index 0000000000..02041f51e8
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutableObjectUnitTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.mutable.MutableObject;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class MutableObjectUnitTest {
+
+ private static MutableObject mutableObject;
+
+ @BeforeClass
+ public static void setUpMutableObject() {
+ mutableObject = new MutableObject("Initial value");
+ }
+
+ @Test
+ public void givenMutableObject_whenCalledgetValue_thenCorrect() {
+ assertThat(mutableObject.getValue()).isInstanceOf(String.class);
+ }
+
+ @Test
+ public void givenMutableObject_whenCalledsetValue_thenCorrect() {
+ mutableObject.setValue("Another value");
+ assertThat(mutableObject.getValue()).isEqualTo("Another value");
+ }
+
+ @Test
+ public void givenMutableObject_whenCalledtoString_thenCorrect() {
+ assertThat(mutableObject.toString()).isEqualTo("Another value");
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/MutablePairUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutablePairUnitTest.java
new file mode 100644
index 0000000000..174ec70c4d
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/MutablePairUnitTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.tuple.MutablePair;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class MutablePairUnitTest {
+
+ private static MutablePair mutablePair;
+
+ @BeforeClass
+ public static void setUpMutablePairInstance() {
+ mutablePair = new MutablePair<>("leftElement", "rightElement");
+ }
+
+ @Test
+ public void givenMutablePairInstance_whenCalledgetLeft_thenCorrect() {
+ assertThat(mutablePair.getLeft()).isEqualTo("leftElement");
+ }
+
+ @Test
+ public void givenMutablePairInstance_whenCalledgetRight_thenCorrect() {
+ assertThat(mutablePair.getRight()).isEqualTo("rightElement");
+ }
+
+ @Test
+ public void givenMutablePairInstance_whenCalledsetLeft_thenCorrect() {
+ mutablePair.setLeft("newLeftElement");
+ assertThat(mutablePair.getLeft()).isEqualTo("newLeftElement");
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/NumberUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/NumberUtilsUnitTest.java
new file mode 100644
index 0000000000..bdf254a102
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/NumberUtilsUnitTest.java
@@ -0,0 +1,46 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.math.NumberUtils;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class NumberUtilsUnitTest {
+
+ @Test
+ public void givenNumberUtilsClass_whenCalledcompareWithIntegers_thenCorrect() {
+ assertThat(NumberUtils.compare(1, 1)).isEqualTo(0);
+ }
+
+ @Test
+ public void givenNumberUtilsClass_whenCalledcompareWithLongs_thenCorrect() {
+ assertThat(NumberUtils.compare(1L, 1L)).isEqualTo(0);
+ }
+
+ @Test
+ public void givenNumberUtilsClass_whenCalledcreateNumber_thenCorrect() {
+ assertThat(NumberUtils.createNumber("123456")).isEqualTo(123456);
+ }
+
+ @Test
+ public void givenNumberUtilsClass_whenCalledisDigits_thenCorrect() {
+ assertThat(NumberUtils.isDigits("123456")).isTrue();
+ }
+
+ @Test
+ public void givenNumberUtilsClass_whenCallemaxwithIntegerArray_thenCorrect() {
+ int[] array = {1, 2, 3, 4, 5, 6};
+ assertThat(NumberUtils.max(array)).isEqualTo(6);
+ }
+
+ @Test
+ public void givenNumberUtilsClass_whenCalleminwithIntegerArray_thenCorrect() {
+ int[] array = {1, 2, 3, 4, 5, 6};
+ assertThat(NumberUtils.min(array)).isEqualTo(1);
+ }
+
+ @Test
+ public void givenNumberUtilsClass_whenCalleminwithByteArray_thenCorrect() {
+ byte[] array = {1, 2, 3, 4, 5, 6};
+ assertThat(NumberUtils.min(array)).isEqualTo((byte) 1);
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/StringUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/StringUtilsUnitTest.java
new file mode 100644
index 0000000000..ab39ba7bd9
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/StringUtilsUnitTest.java
@@ -0,0 +1,73 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.StringUtils;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class StringUtilsUnitTest {
+
+ @Test
+ public void givenStringUtilsClass_whenCalledisBlank_thenCorrect() {
+ assertThat(StringUtils.isBlank(" ")).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledisEmpty_thenCorrect() {
+ assertThat(StringUtils.isEmpty("")).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledisAllLowerCase_thenCorrect() {
+ assertThat(StringUtils.isAllLowerCase("abd")).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledisAllUpperCase_thenCorrect() {
+ assertThat(StringUtils.isAllUpperCase("ABC")).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledisMixedCase_thenCorrect() {
+ assertThat(StringUtils.isMixedCase("abC")).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledisAlpha_thenCorrect() {
+ assertThat(StringUtils.isAlpha("abc")).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledisAlphanumeric_thenCorrect() {
+ assertThat(StringUtils.isAlphanumeric("abc123")).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledcontains_thenCorrect() {
+ assertThat(StringUtils.contains("abc", "ab")).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledcontainsAny_thenCorrect() {
+ assertThat(StringUtils.containsAny("abc", 'a', 'b', 'c')).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledcontainsIgnoreCase_thenCorrect() {
+ assertThat(StringUtils.containsIgnoreCase("abc", "ABC")).isTrue();
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledswapCase_thenCorrect() {
+ assertThat(StringUtils.swapCase("abc")).isEqualTo("ABC");
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalledreverse_thenCorrect() {
+ assertThat(StringUtils.reverse("abc")).isEqualTo("cba");
+ }
+
+ @Test
+ public void givenStringUtilsClass_whenCalleddifference_thenCorrect() {
+ assertThat(StringUtils.difference("abc", "abd")).isEqualTo("d");
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/SystemsUtilsUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/SystemsUtilsUnitTest.java
new file mode 100644
index 0000000000..0efe97f912
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/SystemsUtilsUnitTest.java
@@ -0,0 +1,25 @@
+package com.baeldung.commons.lang3.test;
+
+import java.io.File;
+import org.apache.commons.lang3.JavaVersion;
+import org.apache.commons.lang3.SystemUtils;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.Test;
+
+public class SystemsUtilsUnitTest {
+
+ @Test
+ public void givenSystemUtilsClass_whenCalledgetJavaHome_thenCorrect() {
+ assertThat(SystemUtils.getJavaHome()).isEqualTo(new File("/usr/lib/jvm/java-8-oracle/jre"));
+ }
+
+ @Test
+ public void givenSystemUtilsClass_whenCalledgetUserHome_thenCorrect() {
+ assertThat(SystemUtils.getUserHome()).isEqualTo(new File("/home/travis"));
+ }
+
+ @Test
+ public void givenSystemUtilsClass_whenCalledisJavaVersionAtLeast_thenCorrect() {
+ assertThat(SystemUtils.isJavaVersionAtLeast(JavaVersion.JAVA_RECENT)).isTrue();
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/commons/lang3/test/TripleUnitTest.java b/libraries/src/test/java/com/baeldung/commons/lang3/test/TripleUnitTest.java
new file mode 100644
index 0000000000..7d506bbbab
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/commons/lang3/test/TripleUnitTest.java
@@ -0,0 +1,31 @@
+package com.baeldung.commons.lang3.test;
+
+import org.apache.commons.lang3.tuple.Triple;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TripleUnitTest {
+
+ private static Triple triple;
+
+ @BeforeClass
+ public static void setUpTripleInstance() {
+ triple = Triple.of("leftElement", "middleElement", "rightElement");
+ }
+
+ @Test
+ public void givenTripleInstance_whenCalledgetLeft_thenCorrect() {
+ assertThat(triple.getLeft()).isEqualTo("leftElement");
+ }
+
+ @Test
+ public void givenTripleInstance_whenCalledgetMiddle_thenCorrect() {
+ assertThat(triple.getMiddle()).isEqualTo("middleElement");
+ }
+
+ @Test
+ public void givenTripleInstance_whenCalledgetRight_thenCorrect() {
+ assertThat(triple.getRight()).isEqualTo("rightElement");
+ }
+}
diff --git a/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java b/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java
index 4406494d30..e61f4158a7 100644
--- a/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java
+++ b/libraries/src/test/java/com/baeldung/kafkastreams/KafkaStreamsLiveTest.java
@@ -4,10 +4,12 @@ import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.common.serialization.Serde;
import org.apache.kafka.common.serialization.Serdes;
import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.StreamsConfig;
+import org.apache.kafka.streams.Topology;
import org.apache.kafka.streams.kstream.KStream;
-import org.apache.kafka.streams.kstream.KStreamBuilder;
import org.apache.kafka.streams.kstream.KTable;
+import org.apache.kafka.streams.kstream.Produced;
import org.apache.kafka.test.TestUtils;
import org.junit.Ignore;
import org.junit.Test;
@@ -36,20 +38,20 @@ public class KafkaStreamsLiveTest {
streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getAbsolutePath());
// when
- KStreamBuilder builder = new KStreamBuilder();
+ StreamsBuilder builder = new StreamsBuilder();
KStream textLines = builder.stream(inputTopic);
Pattern pattern = Pattern.compile("\\W+", Pattern.UNICODE_CHARACTER_CLASS);
KTable wordCounts = textLines.flatMapValues(value -> Arrays.asList(pattern.split(value.toLowerCase()))).groupBy((key, word) -> word).count();
- wordCounts.foreach((word, count) -> System.out.println("word: " + word + " -> " + count));
+ textLines.foreach((word, count) -> System.out.println("word: " + word + " -> " + count));
String outputTopic = "outputTopic";
final Serde stringSerde = Serdes.String();
- final Serde longSerde = Serdes.Long();
- wordCounts.to(stringSerde, longSerde, outputTopic);
+ final Serde longSerde = Serdes.String();
+ textLines.to(outputTopic, Produced.with(stringSerde,longSerde));
- KafkaStreams streams = new KafkaStreams(builder, streamsConfiguration);
+ KafkaStreams streams = new KafkaStreams(new Topology(), streamsConfiguration);
streams.start();
// then
diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBoolean.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBoolean.java
new file mode 100644
index 0000000000..2191396e5d
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBoolean.java
@@ -0,0 +1,15 @@
+package com.baeldung.lombok.getter;
+
+
+import lombok.Getter;
+
+/**
+ * Related Article Sections:
+ * 4. Using @Getter on a Boolean Field
+ *
+ */
+public class GetterBoolean {
+
+ @Getter
+ private Boolean running = true;
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitive.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitive.java
new file mode 100644
index 0000000000..5601f85b8b
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitive.java
@@ -0,0 +1,16 @@
+package com.baeldung.lombok.getter;
+
+
+import lombok.Getter;
+
+/**
+ * Related Article Sections:
+ * 3. Using @Getter on a boolean Field
+ *
+ */
+public class GetterBooleanPrimitive {
+
+ @Getter
+ private boolean running;
+
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitiveSameAccessor.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitiveSameAccessor.java
new file mode 100644
index 0000000000..af29a33c20
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanPrimitiveSameAccessor.java
@@ -0,0 +1,18 @@
+package com.baeldung.lombok.getter;
+
+
+import lombok.Getter;
+
+/**
+ * Related Article Sections:
+ * 3.2. Two boolean Fields With the Same Accessor Name
+ *
+ */
+public class GetterBooleanPrimitiveSameAccessor {
+
+ @Getter
+ boolean running = true;
+
+ @Getter
+ boolean isRunning = false;
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanSameAccessor.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanSameAccessor.java
new file mode 100644
index 0000000000..d972273b71
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanSameAccessor.java
@@ -0,0 +1,13 @@
+package com.baeldung.lombok.getter;
+
+import lombok.Getter;
+
+/**
+ * Related Article Sections:
+ * 3.1. A boolean Field Having the Same Name With Its Accessor
+ *
+ */
+public class GetterBooleanSameAccessor {
+ @Getter
+ private boolean isRunning = true;
+}
diff --git a/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanType.java b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanType.java
new file mode 100644
index 0000000000..0d3b9a928a
--- /dev/null
+++ b/lombok/src/main/java/com/baeldung/lombok/getter/GetterBooleanType.java
@@ -0,0 +1,15 @@
+package com.baeldung.lombok.getter;
+
+
+import lombok.Getter;
+
+/**
+ * Related Article Sections:
+ * 4. Using @Getter on a Boolean Field
+ *
+ */
+public class GetterBooleanType {
+
+ @Getter
+ private Boolean running = true;
+}
diff --git a/lombok/src/test/java/com/baeldung/lombok/getter/GetterBooleanUnitTest.java b/lombok/src/test/java/com/baeldung/lombok/getter/GetterBooleanUnitTest.java
new file mode 100644
index 0000000000..632594d575
--- /dev/null
+++ b/lombok/src/test/java/com/baeldung/lombok/getter/GetterBooleanUnitTest.java
@@ -0,0 +1,34 @@
+package com.baeldung.lombok.getter;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class GetterBooleanUnitTest {
+
+ @Test
+ public void whenBasicBooleanField_thenMethodNamePrefixedWithIsFollowedByFieldName() {
+ GetterBooleanPrimitive lombokExamples = new GetterBooleanPrimitive();
+ assertFalse(lombokExamples.isRunning());
+ }
+
+ @Test
+ public void whenBooleanFieldPrefixedWithIs_thenMethodNameIsSameAsFieldName() {
+ GetterBooleanSameAccessor lombokExamples = new GetterBooleanSameAccessor();
+ assertTrue(lombokExamples.isRunning());
+ }
+
+ @Test
+ public void whenTwoBooleanFieldsCauseNamingConflict_thenLombokMapsToFirstDeclaredField() {
+ GetterBooleanPrimitiveSameAccessor lombokExamples = new GetterBooleanPrimitiveSameAccessor();
+ assertTrue(lombokExamples.isRunning() == lombokExamples.running);
+ assertFalse(lombokExamples.isRunning() == lombokExamples.isRunning);
+ }
+
+ @Test
+ public void whenFieldOfBooleanType_thenLombokPrefixesMethodWithGetInsteadOfIs() {
+ GetterBooleanType lombokExamples = new GetterBooleanType();
+ assertTrue(lombokExamples.getRunning());
+ }
+}
diff --git a/metrics/pom.xml b/metrics/pom.xml
index 86f197240b..9cf1ec588f 100644
--- a/metrics/pom.xml
+++ b/metrics/pom.xml
@@ -84,6 +84,13 @@
spectator-api
${spectator-api.version}
+
+
+ org.assertj
+ assertj-core
+ test
+
+
diff --git a/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java
index e7f3d7ec72..689e23ad6d 100644
--- a/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java
+++ b/metrics/src/test/java/com/baeldung/metrics/micrometer/MicrometerAtlasIntegrationTest.java
@@ -1,8 +1,12 @@
package com.baeldung.metrics.micrometer;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.within;
+import static org.assertj.core.api.Assertions.withinPercentage;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.collection.IsMapContaining.hasEntry;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import io.micrometer.atlas.AtlasMeterRegistry;
@@ -31,8 +35,10 @@ import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
+import org.assertj.core.data.Percentage;
import org.junit.Before;
import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
import com.netflix.spectator.atlas.AtlasConfig;
@@ -156,7 +162,8 @@ public class MicrometerAtlasIntegrationTest {
timer.record(30, TimeUnit.MILLISECONDS);
assertTrue(2 == timer.count());
- assertTrue(50 > timer.totalTime(TimeUnit.MILLISECONDS) && 45 <= timer.totalTime(TimeUnit.MILLISECONDS));
+
+ assertThat(timer.totalTime(TimeUnit.MILLISECONDS)).isBetween(40.0, 55.0);
}
@Test
@@ -173,7 +180,7 @@ public class MicrometerAtlasIntegrationTest {
}
long timeElapsed = longTaskTimer.stop(currentTaskId);
- assertTrue(timeElapsed / (int) 1e6 == 2);
+ assertEquals(2L, timeElapsed/((int) 1e6),1L);
}
@Test
diff --git a/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java b/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java
index 134c3c91cf..b8a5b93e49 100644
--- a/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java
+++ b/metrics/src/test/java/com/baeldung/metrics/servo/AtlasObserverLiveTest.java
@@ -27,6 +27,9 @@ import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
+/**
+ * Atlas server needs to be up and running for this live test to work.
+ */
public class AtlasObserverLiveTest {
private final String atlasUri = "http://localhost:7101/api/v1";
diff --git a/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java b/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java
index d810de155a..92bbd615b9 100644
--- a/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java
+++ b/metrics/src/test/java/com/baeldung/metrics/servo/MetricTypeManualTest.java
@@ -109,20 +109,20 @@ public class MetricTypeManualTest {
.build(), MILLISECONDS);
Stopwatch stopwatch = timer.start();
- MILLISECONDS.sleep(1);
- timer.record(2, MILLISECONDS);
+ SECONDS.sleep(1);
+ timer.record(2, SECONDS);
stopwatch.stop();
- assertEquals("timer should count 1 millisecond", 1, timer
+ assertEquals("timer should count 1 second", 1000, timer
.getValue()
- .intValue());
- assertEquals("timer should count 3 millisecond in total", 3, timer.getTotalTime()
- .intValue());
+ .intValue(),1000);
+ assertEquals("timer should count 3 second in total", 3000, timer.getTotalTime()
+ .intValue(),1000);
assertEquals("timer should record 2 updates", 2, timer
.getCount()
.intValue());
- assertEquals("timer should have max 2", 2, timer.getMax(), 0.01);
+ assertEquals("timer should have max 2", 2000, timer.getMax(), 0.01);
}
@Test
@@ -161,7 +161,6 @@ public class MetricTypeManualTest {
}
@Test
- //==
public void givenStatsTimer_whenExecuteTask_thenStatsCalculated() throws Exception {
System.setProperty("netflix.servo", "1000");
StatsTimer timer = new StatsTimer(MonitorConfig
@@ -178,21 +177,21 @@ public class MetricTypeManualTest {
.build(), MILLISECONDS);
Stopwatch stopwatch = timer.start();
- MILLISECONDS.sleep(1);
- timer.record(3, MILLISECONDS);
+ SECONDS.sleep(1);
+ timer.record(3, SECONDS);
stopwatch.stop();
stopwatch = timer.start();
- timer.record(6, MILLISECONDS);
- MILLISECONDS.sleep(2);
+ timer.record(6, SECONDS);
+ SECONDS.sleep(2);
stopwatch.stop();
- assertEquals("timer should count 12 milliseconds in total", 12, timer.getTotalTime());
- assertEquals("timer should count 12 milliseconds in total", 12, timer.getTotalMeasurement());
+ assertEquals("timer should count 12 seconds in total", 12000, timer.getTotalTime(),500);
+ assertEquals("timer should count 12 seconds in total", 12000, timer.getTotalMeasurement(),500);
assertEquals("timer should record 4 updates", 4, timer.getCount());
- assertEquals("stats timer value time-cost/update should be 2", 3, timer
+ assertEquals("stats timer value time-cost/update should be 2", 3000, timer
.getValue()
- .intValue());
+ .intValue(),500);
final Map metricMap = timer
.getMonitors()
@@ -235,4 +234,4 @@ public class MetricTypeManualTest {
assertEquals("information collected", informational.getValue());
}
-}
+}
\ No newline at end of file
diff --git a/optaplanner/README.md b/optaplanner/README.md
new file mode 100644
index 0000000000..d793be1f2a
--- /dev/null
+++ b/optaplanner/README.md
@@ -0,0 +1,3 @@
+### Relevant articles
+
+- [Guide to OptaPlanner](https://www.baeldung.com/opta-planner)
diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java
index 78c4116c67..ec0d4bca3c 100644
--- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java
+++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/PersistenceJPAConfig.java
@@ -78,9 +78,9 @@ public class PersistenceJPAConfig {
final Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
- hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache"));
- hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache"));
- // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
+ hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", "false");
+
+
return hibernateProperties;
}
diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java
index 1c8ce5400f..cf6e69eb39 100644
--- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java
+++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/config/WebInitializer.java
@@ -5,7 +5,7 @@ import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatche
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class>[] getRootConfigClasses() {
- return new Class[] { PersistenceJNDIConfig.class };
+ return new Class[] { PersistenceJPAConfig.class };
}
@Override
diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepository.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepository.java
similarity index 71%
rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepository.java
rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepository.java
index af30ae461e..114cf48c7c 100644
--- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepository.java
+++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepository.java
@@ -1,6 +1,6 @@
-package org.baeldung.persistence.criteria.repository;
+package org.baeldung.persistence.dao;
-import org.baeldung.persistence.criteria.model.Book;
+import org.baeldung.persistence.model.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepositoryCustom.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryCustom.java
similarity index 58%
rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepositoryCustom.java
rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryCustom.java
index 35330cfa3c..b939907572 100644
--- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookRepositoryCustom.java
+++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryCustom.java
@@ -1,8 +1,8 @@
-package org.baeldung.persistence.criteria.repository;
+package org.baeldung.persistence.dao;
import java.util.List;
-import org.baeldung.persistence.criteria.model.Book;
+import org.baeldung.persistence.model.Book;
public interface BookRepositoryCustom {
diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/dao/BookRepositoryImpl.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryImpl.java
similarity index 87%
rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/dao/BookRepositoryImpl.java
rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryImpl.java
index f782d69e1e..6e9aa998d7 100644
--- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/dao/BookRepositoryImpl.java
+++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookRepositoryImpl.java
@@ -1,4 +1,4 @@
-package org.baeldung.persistence.criteria.dao;
+package org.baeldung.persistence.dao;
import java.util.ArrayList;
import java.util.List;
@@ -10,8 +10,7 @@ import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
-import org.baeldung.persistence.criteria.model.Book;
-import org.baeldung.persistence.criteria.repository.BookRepositoryCustom;
+import org.baeldung.persistence.model.Book;
import org.springframework.stereotype.Repository;
@Repository
diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookService.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookService.java
similarity index 63%
rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookService.java
rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookService.java
index 7b1aff857e..88b769e9bf 100644
--- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookService.java
+++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookService.java
@@ -1,12 +1,12 @@
-package org.baeldung.persistence.criteria.repository;
+package org.baeldung.persistence.dao;
-import static org.baeldung.persistence.criteria.repository.BookSpecifications.hasAuthor;
-import static org.baeldung.persistence.criteria.repository.BookSpecifications.titleContains;
+import static org.baeldung.persistence.dao.BookSpecifications.hasAuthor;
+import static org.baeldung.persistence.dao.BookSpecifications.titleContains;
import static org.springframework.data.jpa.domain.Specifications.where;
import java.util.List;
-import org.baeldung.persistence.criteria.model.Book;
+import org.baeldung.persistence.model.Book;
import org.springframework.stereotype.Service;
@Service
diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookSpecifications.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookSpecifications.java
similarity index 78%
rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookSpecifications.java
rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookSpecifications.java
index 392b750977..ed9540060d 100644
--- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/repository/BookSpecifications.java
+++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/dao/BookSpecifications.java
@@ -1,6 +1,6 @@
-package org.baeldung.persistence.criteria.repository;
+package org.baeldung.persistence.dao;
-import org.baeldung.persistence.criteria.model.Book;
+import org.baeldung.persistence.model.Book;
import org.springframework.data.jpa.domain.Specification;
public class BookSpecifications {
diff --git a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/model/Book.java b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Book.java
similarity index 91%
rename from persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/model/Book.java
rename to persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Book.java
index beb6c0190c..754bd179d1 100644
--- a/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/criteria/model/Book.java
+++ b/persistence-modules/spring-jpa/src/main/java/org/baeldung/persistence/model/Book.java
@@ -1,4 +1,4 @@
-package org.baeldung.persistence.criteria.model;
+package org.baeldung.persistence.model;
import javax.persistence.Entity;
import javax.persistence.Id;
diff --git a/persistence-modules/spring-jpa/src/main/resources/persistence.xml b/persistence-modules/spring-jpa/src/main/resources/persistence.xml
index 65bad29cdc..6304fa0a65 100644
--- a/persistence-modules/spring-jpa/src/main/resources/persistence.xml
+++ b/persistence-modules/spring-jpa/src/main/resources/persistence.xml
@@ -21,8 +21,6 @@
${hibernate.hbm2ddl.auto}
${hibernate.dialect}
- ${hibernate.cache.use_second_level_cache}
- ${hibernate.cache.use_query_cache}
diff --git a/pom.xml b/pom.xml
index 7a7e2d7f64..4ffd9ba4a4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -405,9 +405,10 @@
json
jsoup
testing-modules/junit-5
- jws
+
libraries
libraries-data
+ libraries-security
libraries-server
linkrest
logging-modules/log-mdc
@@ -470,7 +471,7 @@
spring-boot-persistence
spring-boot-security
spring-boot-mvc
- spring-boot-vue
+ spring-boot-vue
spring-boot-logging-log4j2
spring-cloud-data-flow
spring-cloud
@@ -604,6 +605,80 @@
jnosql
spring-boot-angular-ecommerce
jta
+
+ java-websocket
+ activejdbc
+
+
+ apache-bval
+ apache-shiro
+ apache-spark
+
+ checker-plugin
+
+
+ core-java-sun
+ custom-pmd
+ dagger
+ data-structures
+ dubbo
+
+
+
+
+ jni
+ jooby
+
+
+
+ ratpack
+
+ spring-boot-autoconfiguration
+ spring-boot-custom-starter
+ spring-boot-jasypt
+
+ spring-data-rest-querydsl
+
+ spring-mobile
+
+ spring-mvc-simple
+
+ spring-rest-hal-browser
+ spring-rest-shell
+ spring-rest-template
+ spring-roo
+ spring-security-stormpath
+ sse-jaxrs
+
+ stripe
+
+ Twitter4J
+ wicket
+ xstream
+ cas/cas-secured-app
+ cas/cas-server
+
+
+
+
+
+
+
+
+
+
+
+
+ jenkins/hello-world
+
+
+
+ spring-boot-custom-starter/greeter
+ spring-boot-h2/spring-boot-h2-database
+
+
+
+
@@ -847,7 +922,80 @@
-
+
+ java-websocket
+
+
+
+ apache-bval
+ apache-shiro
+ apache-spark
+
+ checker-plugin
+
+
+ core-java-sun
+ custom-pmd
+ dagger
+ data-structures
+ dubbo
+
+
+
+
+ jni
+ jooby
+
+
+
+ ratpack
+
+ spring-boot-autoconfiguration
+ spring-boot-custom-starter
+
+
+ spring-data-rest-querydsl
+
+ spring-mobile
+
+ spring-mvc-simple
+
+ spring-rest-hal-browser
+ spring-rest-shell
+ spring-rest-template
+ spring-roo
+ spring-security-stormpath
+ sse-jaxrs
+
+ stripe
+
+
+ wicket
+ xstream
+ cas/cas-secured-app
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jenkins/hello-world
+
+
+
+ spring-boot-custom-starter/greeter
+ spring-boot-h2/spring-boot-h2-database
+
+
+
+
diff --git a/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java b/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java
index 56650ba306..e3060b8e02 100644
--- a/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java
+++ b/reactor-core/src/test/java/com/baeldung/reactor/ReactorIntegrationTest.java
@@ -37,14 +37,14 @@ public class ReactorIntegrationTest {
Flux.just(1, 2, 3, 4)
.log()
.map(i -> i * 2)
- .zipWith(Flux.range(0, Integer.MAX_VALUE).log(), (two, one) -> String.format("First Flux: %d, Second Flux: %d", one, two))
+ .zipWith(Flux.range(0, Integer.MAX_VALUE).log(), (one, two) -> String.format("First Flux: %d, Second Flux: %d", one, two))
.subscribe(elements::add);
assertThat(elements).containsExactly(
- "First Flux: 0, Second Flux: 2",
- "First Flux: 1, Second Flux: 4",
- "First Flux: 2, Second Flux: 6",
- "First Flux: 3, Second Flux: 8");
+ "First Flux: 2, Second Flux: 0",
+ "First Flux: 4, Second Flux: 1",
+ "First Flux: 6, Second Flux: 2",
+ "First Flux: 8, Second Flux: 3");
}
@Test
diff --git a/spring-4/pom.xml b/spring-4/pom.xml
index cf10f64aa2..78939bba95 100644
--- a/spring-4/pom.xml
+++ b/spring-4/pom.xml
@@ -71,10 +71,8 @@
- UTF-8
1.0.1
1.16.18
- 1.8
1.4.197
diff --git a/spring-5/pom.xml b/spring-5/pom.xml
index 9f60b8a364..293edb5bda 100644
--- a/spring-5/pom.xml
+++ b/spring-5/pom.xml
@@ -1,5 +1,6 @@
-
4.0.0
com.baeldung
@@ -134,7 +135,26 @@
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ ${maven-surefire-plugin.version}
+
+ methods
+ true
+
+ **/*IntegrationTest.java
+ **/*IntTest.java
+ **/*LongRunningUnitTest.java
+ **/*ManualTest.java
+ **/JdbcTest.java
+ **/*LiveTest.java
+
+
+
+
@@ -142,6 +162,8 @@
1.5.6
4.1
${project.build.directory}/generated-snippets
+ 2.21.0
+
diff --git a/spring-all/pom.xml b/spring-all/pom.xml
index c4c4cf7963..bab2e431ec 100644
--- a/spring-all/pom.xml
+++ b/spring-all/pom.xml
@@ -45,6 +45,15 @@
spring-shell
${org.springframework.shell.version}
+
+ org.springframework
+ spring-websocket
+
+
+ org.springframework
+ spring-messaging
+
+
org.springframework
@@ -190,7 +199,24 @@
-
+
+
+ dev
+
+ true
+
+
+ dev
+
+
+
+ prod
+
+ prod
+
+
+
+
org.baeldung.sample.App
diff --git a/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java b/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java
index eb5543e3db..2d1905ee9c 100644
--- a/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java
+++ b/spring-all/src/main/java/org/baeldung/profiles/SpringProfilesConfig.java
@@ -2,9 +2,11 @@ package org.baeldung.profiles;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
@Configuration
@ComponentScan("org.baeldung.profiles")
+@PropertySource(value = "classpath:application.properties")
public class SpringProfilesConfig {
}
diff --git a/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java
index 73df386aff..9257a3aa3a 100644
--- a/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java
+++ b/spring-all/src/main/java/org/baeldung/scopes/ScopesController.java
@@ -13,21 +13,36 @@ import org.springframework.web.bind.annotation.RequestMapping;
public class ScopesController {
public static final Logger LOG = LoggerFactory.getLogger(ScopesController.class);
- @Resource(name = "requestMessage")
- HelloMessageGenerator requestMessage;
+ @Resource(name = "requestScopedBean")
+ HelloMessageGenerator requestScopedBean;
- @Resource(name = "sessionMessage")
- HelloMessageGenerator sessionMessage;
+ @Resource(name = "sessionScopedBean")
+ HelloMessageGenerator sessionScopedBean;
- @RequestMapping("/scopes")
- public String getScopes(final Model model) {
- LOG.info("Request Message:" + requestMessage.getMessage());
- LOG.info("Session Message" + sessionMessage.getMessage());
- requestMessage.setMessage("Good morning!");
- sessionMessage.setMessage("Good afternoon!");
- model.addAttribute("requestMessage", requestMessage.getMessage());
- model.addAttribute("sessionMessage", sessionMessage.getMessage());
+ @Resource(name = "applicationScopedBean")
+ HelloMessageGenerator applicationScopedBean;
+
+ @RequestMapping("/scopes/request")
+ public String getRequestScopeMessage(final Model model) {
+ model.addAttribute("previousMessage", requestScopedBean.getMessage());
+ requestScopedBean.setMessage("Request Scope Message!");
+ model.addAttribute("currentMessage", requestScopedBean.getMessage());
return "scopesExample";
}
+ @RequestMapping("/scopes/session")
+ public String getSessionScopeMessage(final Model model) {
+ model.addAttribute("previousMessage", sessionScopedBean.getMessage());
+ sessionScopedBean.setMessage("Session Scope Message!");
+ model.addAttribute("currentMessage", sessionScopedBean.getMessage());
+ return "scopesExample";
+ }
+
+ @RequestMapping("/scopes/application")
+ public String getApplicationScopeMessage(final Model model) {
+ model.addAttribute("previousMessage", applicationScopedBean.getMessage());
+ applicationScopedBean.setMessage("Application Scope Message!");
+ model.addAttribute("currentMessage", applicationScopedBean.getMessage());
+ return "scopesExample";
+ }
}
diff --git a/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java
index fb34725508..b5fe494ee2 100644
--- a/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java
+++ b/spring-all/src/main/java/org/baeldung/spring/config/ScopesConfig.java
@@ -27,19 +27,25 @@ public class ScopesConfig {
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
- public HelloMessageGenerator requestMessage() {
+ public HelloMessageGenerator requestScopedBean() {
return new HelloMessageGenerator();
}
@Bean
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
- public HelloMessageGenerator sessionMessage() {
+ public HelloMessageGenerator sessionScopedBean() {
return new HelloMessageGenerator();
}
@Bean
@Scope(value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)
- public HelloMessageGenerator globalSessionMessage() {
+ public HelloMessageGenerator applicationScopedBean() {
+ return new HelloMessageGenerator();
+ }
+
+ @Bean
+ @Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
+ public HelloMessageGenerator websocketScopedBean() {
return new HelloMessageGenerator();
}
diff --git a/spring-all/src/main/resources/application.properties b/spring-all/src/main/resources/application.properties
new file mode 100644
index 0000000000..cbfe3f2df2
--- /dev/null
+++ b/spring-all/src/main/resources/application.properties
@@ -0,0 +1 @@
+spring.profiles.active=@spring.profiles.active@
\ No newline at end of file
diff --git a/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp b/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp
index 7974cf0220..0946f1b5ef 100644
--- a/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp
+++ b/spring-all/src/main/webapp/WEB-INF/view/scopesExample.jsp
@@ -2,9 +2,9 @@
- Bean Scopes Examples
-
- Request Message: ${requestMessage }
- Session Message: ${sessionMessage }
+ Bean Scopes Examples
+
Previous Message: ${previousMessage }
+
Current Message: ${currentMessage }
+