Skip to content

Commit 631275e

Browse files
Merge branch 'eugenp:master' into master
2 parents 23c3c29 + 06b8452 commit 631275e

File tree

818 files changed

+15088
-892
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

818 files changed

+15088
-892
lines changed

.gitignore

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ dependency-reduced-pom.xml
6161
*.dylib
6262
*.dll
6363

64-
xml/src/test/resources/example_dom4j_new.xml
65-
xml/src/test/resources/example_dom4j_updated.xml
66-
xml/src/test/resources/example_jaxb_new.xml
64+
xml-modules/xml/src/test/resources/example_dom4j_new.xml
65+
xml-modules/xml/src/test/resources/example_dom4j_updated.xml
66+
xml-modules/xml/src/test/resources/example_jaxb_new.xml
6767
core-java-io/hard_link.txt
6868
core-java-io/target_link.txt
6969
core-java/src/main/java/com/baeldung/manifest/MANIFEST.MF
@@ -99,7 +99,7 @@ customers.xml
9999
apache-cxf/cxf-aegis/baeldung.xml
100100
testing-modules/report-*.json
101101

102-
libraries-2/*.db
102+
libraries-4/*.db
103103

104104
apache-spark/data/output
105105
logs/
@@ -140,6 +140,7 @@ persistence-modules/neo4j/data/**
140140
/microservices-modules/micronaut-reactive/.micronaut/test-resources/test-resources.properties
141141
/libraries-security/src/main/resources/home/upload/test_file_SCP.txt
142142
/libraries-security/src/main/resources/home/upload/test_file_SFTP.txt
143+
/libraries-security/decryptedFile
143144
/libraries-data-io/src/test/resources/protocols/gson_user.json
144145
/libraries-io/src/main/resources/application.csv
145146
/libraries-io/src/main/resources/application2.csv
@@ -149,7 +150,7 @@ persistence-modules/neo4j/data/**
149150
/core-java-modules/core-java-io-conversions-3/src/test/resources/xlsxToCsv_output.csv
150151
/core-java-modules/core-java-io-5/output.txt
151152
/core-java-modules/core-java-io-apis-2/sample.txt
152-
/persistence-modules/core-java-persistence-3/test.mv.db
153+
/persistence-modules/core-java-persistence/test.mv.db
153154
/apache-libraries/src/main/java/com/baeldung/apache/avro/
154155
/apache-libraries-2/cars.avro
155156

@@ -160,4 +161,9 @@ persistence-modules/neo4j/data/**
160161
/spring-cloud-modules/spring-cloud-bootstrap/gateway/src/main/resources/static/home/server/*
161162

162163
/web-modules/linkrest/src/main/java/com/baeldung/cayenne/auto/_Department.java
163-
/web-modules/linkrest/src/main/java/com/baeldung/cayenne/auto/_Employee.java
164+
/web-modules/linkrest/src/main/java/com/baeldung/cayenne/auto/_Employee.java
165+
166+
#log4j
167+
logging-modules/log4j/app-dynamic-log.log
168+
logging-modules/logback/conditional.log
169+
logging-modules/logback/filtered.log

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ Profile-based segregation
3636

3737
We use Maven build profiles to segregate the huge list of individual projects in our repository.
3838

39-
The projects are broadly divided into 6 lists: default, default-jdk17, default-jdk22, default-jdk23, default-jdk8 and default-heavy.
39+
The projects are broadly divided into 8 lists: default, default-jdk17, default-jdk22, default-jdk23, default-jdk24, default-jdk25, default-jdk8 and default-heavy.
4040

4141
Next, they are segregated further based on the tests that we want to execute.
4242

4343
We also have a parents profile to build only parent modules.
4444

45-
Therefore, we have a total of 13 profiles:
45+
Therefore, we have a total of 17 profiles:
4646

4747
| Profile | Includes | Type of test enabled |
4848
|-------------------|-----------------------------|----------------------|
@@ -54,6 +54,10 @@ Therefore, we have a total of 13 profiles:
5454
| integration-jdk22 | JDK22 projects | *IntegrationTest |
5555
| default-jdk23 | JDK23 projects | *UnitTest |
5656
| integration-jdk23 | JDK23 projects | *IntegrationTest |
57+
| default-jdk24 | JDK24 projects | *UnitTest |
58+
| integration-jdk24 | JDK24 projects | *IntegrationTest |
59+
| default-jdk25 | JDK25 projects | *UnitTest |
60+
| integration-jdk25 | JDK25 projects | *IntegrationTest |
5761
| default-heavy | Heavy/long running projects | *UnitTest |
5862
| integration-heavy | Heavy/long running projects | *IntegrationTest |
5963
| default-jdk8 | JDK8 projects | *UnitTest |
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.baeldung.algorithms.bcdtodecimal;
2+
3+
public class BCDtoDecimalConverter {
4+
/**
5+
* Converts a single packed BCD byte to an integer.
6+
* Each byte represents two decimal digits.
7+
*
8+
* @param bcdByte The BCD byte to convert.
9+
* @return The decimal integer value.
10+
* @throws IllegalArgumentException if any nibble contains a non-BCD value (>9).
11+
*/
12+
public static int convertPackedByte(byte bcdByte) {
13+
int resultDecimal;
14+
int upperNibble = (bcdByte >> 4) & 0x0F;
15+
int lowerNibble = bcdByte & 0x0F;
16+
if (upperNibble > 9 || lowerNibble > 9) {
17+
throw new IllegalArgumentException(
18+
String.format("Invalid BCD format: byte 0x%02X contains non-decimal digit.", bcdByte)
19+
);
20+
}
21+
resultDecimal = upperNibble * 10 + lowerNibble;
22+
return resultDecimal;
23+
}
24+
25+
/**
26+
* Converts a BCD byte array to a long decimal value.
27+
* Each byte in the array iis mapped to a packed BCD byte,
28+
* representing two BCD nibbles.
29+
*
30+
* @param bcdArray The array of BCD bytes.
31+
* @return The combined long decimal value.
32+
* @throws IllegalArgumentException if any nibble contains a non-BCD value (>9).
33+
*/
34+
public static long convertPackedByteArray(byte[] bcdArray) {
35+
long resultDecimal = 0;
36+
for (byte bcd : bcdArray) {
37+
int upperNibble = (bcd >> 4) & 0x0F;
38+
int lowerNibble = bcd & 0x0F;
39+
40+
if (upperNibble > 9 || lowerNibble > 9) {
41+
throw new IllegalArgumentException("Invalid BCD format: nibble contains non-decimal digit.");
42+
}
43+
44+
resultDecimal = resultDecimal * 100 + (upperNibble * 10 + lowerNibble);
45+
}
46+
return resultDecimal;
47+
}
48+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.baeldung.algorithms.sumoftwosquares;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
public class NumberAsSumOfTwoSquares {
7+
8+
private static final Logger LOGGER = LoggerFactory.getLogger(NumberAsSumOfTwoSquares.class);
9+
10+
/**
11+
* Checks if a non-negative integer n can be written as the
12+
* sum of two squares i.e. (a^2 + b^2)
13+
* This implementation is based on Fermat's theorem on sums of two squares.
14+
*
15+
* @param n The number to check (must be non-negative).
16+
* @return true if n can be written as a sum of two squares, false otherwise.
17+
*/
18+
public static boolean isSumOfTwoSquares(int n) {
19+
if (n < 0) {
20+
LOGGER.warn("Input must be non-negative. Returning false for n = {}", n);
21+
return false;
22+
}
23+
if (n == 0) {
24+
return true; // 0 = 0^2 + 0^2
25+
}
26+
27+
// 1. Reduce n to an odd number if n is even.
28+
while (n % 2 == 0) {
29+
n /= 2;
30+
}
31+
32+
// 2. Iterate through odd prime factors starting from 3
33+
for (int i = 3; i * i <= n; i += 2) {
34+
// 2a. Find the exponent of the factor i
35+
int count = 0;
36+
while (n % i == 0) {
37+
count++;
38+
n /= i;
39+
}
40+
41+
// 2b. Check the condition from Fermat's theorem
42+
// If i is of form 4k+3 (i % 4 == 3) and has an odd exponent
43+
if (i % 4 == 3 && count % 2 != 0) {
44+
LOGGER.debug("Failing condition: factor {} (form 4k+3) has odd exponent {}", i, count);
45+
return false;
46+
}
47+
}
48+
49+
// 3. Handle the last remaining factor (which is prime if > 1)
50+
// If n itself is a prime of the form 4k+3, its exponent is 1 (odd).
51+
if (n % 4 == 3) {
52+
LOGGER.debug("Failing condition: remaining factor {} is of form 4k+3", n);
53+
return false;
54+
}
55+
56+
// 4. All 4k+3 primes had even exponents.
57+
return true;
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* Package to host code for calculating three types of angle difference
3+
*/
4+
package com.baeldung.algorithms.twoanglesdifference;
5+
6+
public class AngleDifferenceCalculator {
7+
8+
/**
9+
* Normalizes an angle to be within the range [0, 360).
10+
*
11+
* @param angle The angle in degrees.
12+
* @return The normalized angle.
13+
*/
14+
public static double normalizeAngle(double angle) {
15+
return (angle % 360 + 360) % 360;
16+
}
17+
18+
/**
19+
* Calculates the absolute difference between two angles.
20+
*
21+
* @param angle1 The first angle in degrees.
22+
* @param angle2 The second angle in degrees.
23+
* @return The absolute difference in degrees.
24+
*/
25+
public static double absoluteDifference(double angle1, double angle2) {
26+
return Math.abs(angle1 - angle2);
27+
}
28+
29+
/**
30+
* Calculates the shortest difference between two angles.
31+
*
32+
* @param angle1 The first angle in degrees.
33+
* @param angle2 The second angle in degrees.
34+
* @return The shortest difference in degrees (0 to 180).
35+
*/
36+
public static double shortestDifference(double angle1, double angle2) {
37+
double diff = absoluteDifference(normalizeAngle(angle1), normalizeAngle(angle2));
38+
return Math.min(diff, 360 - diff);
39+
}
40+
41+
/**
42+
* Calculates the signed shortest difference between two angles.
43+
* A positive result indicates counter-clockwise rotation, a negative result indicates clockwise.
44+
*
45+
* @param angle1 The first angle in degrees.
46+
* @param angle2 The second angle in degrees.
47+
* @return The signed shortest difference in degrees (-180 to 180).
48+
*/
49+
public static double signedShortestDifference(double angle1, double angle2) {
50+
double normalizedAngle1 = normalizeAngle(angle1);
51+
double normalizedAngle2 = normalizeAngle(angle2);
52+
double diff = normalizedAngle2 - normalizedAngle1;
53+
54+
if (diff > 180) {
55+
return diff - 360;
56+
} else if (diff < -180) {
57+
return diff + 360;
58+
} else {
59+
return diff;
60+
}
61+
}
62+
}
63+
64+
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package com.baeldung.algorithms.bcdtodecimal;
2+
3+
import org.junit.jupiter.api.Test;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertThrows;
6+
7+
public class BCDtoDecimalConverterTest {
8+
9+
// 1. Tests for convertPackedByte(byte bcdByte)
10+
11+
@Test
12+
void testConvertPackedByteValidValues() {
13+
// Test 05 (0x05) ->
14+
assertEquals(5, BCDtoDecimalConverter.convertPackedByte((byte) 0x05));
15+
16+
// Test 22 (0x22) -> 22
17+
assertEquals(22, BCDtoDecimalConverter.convertPackedByte((byte) 0x22));
18+
19+
// Test 97 (0x97) -> 97
20+
assertEquals(97, BCDtoDecimalConverter.convertPackedByte((byte) 0x097));
21+
}
22+
23+
@Test
24+
void testConvertPackedByteInvalidUpperNibbleThrowsException() {
25+
// Test Upper nibble is A (1010), Lower nibble is 1 (0001) -> 0xA1
26+
byte invalidByte = (byte) 0xA1;
27+
assertThrows(IllegalArgumentException.class, () -> BCDtoDecimalConverter.convertPackedByte(invalidByte),
28+
"Received non-BCD upper nibble (A). Provide valid BCD nibbles (0-9).");
29+
}
30+
31+
@Test
32+
void testConvertPackedByteBothInvalidThrowsException() {
33+
// test Upper nibble is B, Lower nibble is E -> 0xBE
34+
byte invalidByte = (byte) 0xBE;
35+
assertThrows(IllegalArgumentException.class,
36+
() -> BCDtoDecimalConverter.convertPackedByte(invalidByte),
37+
"Received both nibbles as non-BCD. Provide valid BCD nibbles (0-9)."
38+
);
39+
}
40+
41+
// -------------------------------------------------------------------------
42+
43+
// 2. Tests for convertPackedByteArray(byte[] bcdArray)
44+
45+
@Test
46+
void testConvertPackedByteArrayValidValues() {
47+
// Test 0 -> [0x00]
48+
assertEquals(0L, BCDtoDecimalConverter.convertPackedByteArray(new byte[]{(byte) 0x00}));
49+
50+
// Test 99 -> [0x99]
51+
assertEquals(99L, BCDtoDecimalConverter.convertPackedByteArray(new byte[]{(byte) 0x99}));
52+
53+
// Test 1234 -> [0x12, 0x34]
54+
byte[] bcd1234 = {(byte) 0x12, (byte) 0x34};
55+
assertEquals(1234L, BCDtoDecimalConverter.convertPackedByteArray(bcd1234));
56+
57+
// Test 12345678 -> [0x12, 0x34, 0x56, 0x78]
58+
byte[] bcdLarge = {(byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78};
59+
assertEquals(12345678L, BCDtoDecimalConverter.convertPackedByteArray(bcdLarge));
60+
}
61+
62+
@Test
63+
void testConvertPackedByteArrayEmptyArray() {
64+
// Test empty array -> 0
65+
assertEquals(0L, BCDtoDecimalConverter.convertPackedByteArray(new byte[]{}));
66+
}
67+
68+
@Test
69+
void testConvertPackedByteArrayMaximumSafeLong() {
70+
// Test a large number that fits within a long (18 digits)
71+
// 999,999,999,999,999,999 (18 nines)
72+
byte[] bcdMax = {(byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99};
73+
assertEquals(999999999999999999L, BCDtoDecimalConverter.convertPackedByteArray(bcdMax));
74+
}
75+
76+
@Test
77+
void testConvertPackedByteArrayInvalidNibbleThrowsException() {
78+
// Contains 0x1A (A is an invalid BCD digit)
79+
byte[] bcdInvalid = {(byte) 0x12, (byte) 0x1A, (byte) 0x34};
80+
assertThrows(IllegalArgumentException.class,
81+
() -> BCDtoDecimalConverter.convertPackedByteArray(bcdInvalid),
82+
"Received array containing an invalid BCD byte. Provide valid BCD nibbles (0-9)."
83+
);
84+
}
85+
86+
@Test
87+
void testConvertPackedByteArray_InvalidFirstByteThrowsException() {
88+
// Invalid BCD byte at the start
89+
byte[] bcdInvalid = {(byte) 0xF0, (byte) 0x12};
90+
assertThrows(IllegalArgumentException.class,
91+
() -> BCDtoDecimalConverter.convertPackedByteArray(bcdInvalid),
92+
"Received first byte as an invalid BCD byte. Provide valid BCD nibbles (0-9)."
93+
);
94+
}
95+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.baeldung.algorithms.sumoftwosquares;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.DisplayName;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
import static org.junit.jupiter.api.Assertions.assertFalse;
7+
8+
9+
class NumberAsSumOfTwoSquaresUnitTest {
10+
11+
@Test
12+
@DisplayName("Given input number can be expressed as a sum of squares, when checked, then returns true")
13+
void givenNumberIsSumOfSquares_whenCheckIsCalled_thenReturnsTrue() {
14+
// Simple cases
15+
assertTrue(NumberAsSumOfTwoSquares.isSumOfTwoSquares(0)); // 0^2 + 0^2
16+
assertTrue(NumberAsSumOfTwoSquares.isSumOfTwoSquares(1)); // 1^2 + 0^2
17+
assertTrue(NumberAsSumOfTwoSquares.isSumOfTwoSquares(5)); // 1^2 + 2^2
18+
assertTrue(NumberAsSumOfTwoSquares.isSumOfTwoSquares(8)); // 2^2 + 2^2
19+
20+
// Cases from Fermat theorem
21+
assertTrue(NumberAsSumOfTwoSquares.isSumOfTwoSquares(50)); // 2 * 5^2. No 4k+3 primes.
22+
assertTrue(NumberAsSumOfTwoSquares.isSumOfTwoSquares(45)); // 3^2 * 5. 4k+3 prime (3) has even exp.
23+
assertTrue(NumberAsSumOfTwoSquares.isSumOfTwoSquares(18)); // 2 * 3^2. 4k+3 prime (3) has even exp.
24+
}
25+
26+
@Test
27+
@DisplayName("Given input number can't be expressed as a sum of squares, when checked, then returns false")
28+
void givenNumberIsNotSumOfSquares_whenCheckIsCalled_thenReturnsFalse() {
29+
// Simple cases
30+
assertFalse(NumberAsSumOfTwoSquares.isSumOfTwoSquares(3)); // 3 (4k+3, exp 1)
31+
assertFalse(NumberAsSumOfTwoSquares.isSumOfTwoSquares(6)); // 2 * 3 (3 has exp 1)
32+
assertFalse(NumberAsSumOfTwoSquares.isSumOfTwoSquares(7)); // 7 (4k+3, exp 1)
33+
assertFalse(NumberAsSumOfTwoSquares.isSumOfTwoSquares(11)); // 11 (4k+3, exp 1)
34+
35+
// Cases from theorem
36+
assertFalse(NumberAsSumOfTwoSquares.isSumOfTwoSquares(12)); // 2^2 * 3 (3 has exp 1)
37+
assertFalse(NumberAsSumOfTwoSquares.isSumOfTwoSquares(21)); // 3 * 7 (both 3 and 7 have exp 1)
38+
assertFalse(NumberAsSumOfTwoSquares.isSumOfTwoSquares(28)); // 2^2 * 7 (7 has exp 1)
39+
}
40+
41+
@Test
42+
@DisplayName("Given input number is negative, when checked, then returns false")
43+
void givenNegativeNumber_whenCheckIsCalled_thenReturnsFalse() {
44+
assertFalse(NumberAsSumOfTwoSquares.isSumOfTwoSquares(-1)); // Negatives as hygiene
45+
assertFalse(NumberAsSumOfTwoSquares.isSumOfTwoSquares(-10)); // Negatives as hygiene
46+
}
47+
}

0 commit comments

Comments
 (0)