Merge branch 'master' into master
This commit is contained in:
commit
983fc309f4
|
@ -5,4 +5,5 @@
|
|||
- [Getting Pixel Array From Image in Java](https://www.baeldung.com/java-getting-pixel-array-from-image)
|
||||
- [Calculate Distance Between Two Coordinates in Java](https://www.baeldung.com/java-find-distance-between-points)
|
||||
- [Rotate Arrays in Java](https://www.baeldung.com/java-rotate-arrays)
|
||||
- [Find Missing Number From a Given Array in Java](https://www.baeldung.com/java-array-find-missing-number)
|
||||
- More articles: [[<-- prev]](/algorithms-miscellaneous-6)
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
package com.baeldung.algorithms.weightedaverage;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collector;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class WeightedAverageUnitTest {
|
||||
|
||||
private List<Values> values = Arrays.asList(
|
||||
new Values(1, 10),
|
||||
new Values(3, 20),
|
||||
new Values(5, 30),
|
||||
new Values(7, 50),
|
||||
new Values(9, 40)
|
||||
);
|
||||
|
||||
private Double expected = 6.2;
|
||||
|
||||
@Test
|
||||
void twoPass() {
|
||||
double top = values.stream()
|
||||
.mapToDouble(v -> v.value * v.weight)
|
||||
.sum();
|
||||
double bottom = values.stream()
|
||||
.mapToDouble(v -> v.weight)
|
||||
.sum();
|
||||
|
||||
double result = top / bottom;
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void onePass() {
|
||||
double top = 0;
|
||||
double bottom = 0;
|
||||
|
||||
for (Values v : values) {
|
||||
top += (v.value * v.weight);
|
||||
bottom += v.weight;
|
||||
}
|
||||
|
||||
double result = top / bottom;
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void expanding() {
|
||||
double result = values.stream()
|
||||
.flatMap(v -> Collections.nCopies(v.weight, v.value).stream())
|
||||
.mapToInt(v -> v)
|
||||
.average()
|
||||
.getAsDouble();
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void reduce() {
|
||||
class WeightedAverage {
|
||||
final double top;
|
||||
final double bottom;
|
||||
|
||||
public WeightedAverage(double top, double bottom) {
|
||||
this.top = top;
|
||||
this.bottom = bottom;
|
||||
}
|
||||
|
||||
double average() {
|
||||
return top / bottom;
|
||||
}
|
||||
}
|
||||
|
||||
double result = values.stream()
|
||||
.reduce(new WeightedAverage(0, 0),
|
||||
(acc, next) -> new WeightedAverage(
|
||||
acc.top + (next.value * next.weight),
|
||||
acc.bottom + next.weight),
|
||||
(left, right) -> new WeightedAverage(
|
||||
left.top + right.top,
|
||||
left.bottom + right.bottom))
|
||||
.average();
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void customCollector() {
|
||||
class WeightedAverage implements Collector<Values, WeightedAverage.RunningTotals, Double> {
|
||||
class RunningTotals {
|
||||
double top;
|
||||
double bottom;
|
||||
|
||||
public RunningTotals() {
|
||||
this.top = 0;
|
||||
this.bottom = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Supplier<RunningTotals> supplier() {
|
||||
return RunningTotals::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiConsumer<RunningTotals, Values> accumulator() {
|
||||
return (current, next) -> {
|
||||
current.top += (next.value * next.weight);
|
||||
current.bottom += next.weight;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryOperator<RunningTotals> combiner() {
|
||||
return (left, right) -> {
|
||||
left.top += right.top;
|
||||
left.bottom += right.bottom;
|
||||
|
||||
return left;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<RunningTotals, Double> finisher() {
|
||||
return rt -> rt.top / rt.bottom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Characteristics> characteristics() {
|
||||
return Collections.singleton(Characteristics.UNORDERED);
|
||||
}
|
||||
}
|
||||
|
||||
double result = values.stream()
|
||||
.collect(new WeightedAverage());
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
private static class Values {
|
||||
int value;
|
||||
int weight;
|
||||
|
||||
public Values(int value, int weight) {
|
||||
this.value = value;
|
||||
this.weight = weight;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,3 +15,4 @@ You can build the project from the command line using: *mvn clean install*, or i
|
|||
- [bootstrap-server in Kafka Configuration](https://www.baeldung.com/java-kafka-bootstrap-server)
|
||||
- [Introduction to Apache Kafka](https://www.baeldung.com/apache-kafka)
|
||||
- [Ensuring Message Ordering in Kafka: Strategies and Configurations](https://www.baeldung.com/kafka-message-ordering)
|
||||
- [Read Multiple Messages with Apache Kafka](https://www.baeldung.com/kafka-read-multiple-messages)
|
||||
|
|
|
@ -9,4 +9,5 @@
|
|||
- [Round the Date in Java](https://www.baeldung.com/java-round-the-date)
|
||||
- [Representing Furthest Possible Date in Java](https://www.baeldung.com/java-date-represent-max)
|
||||
- [Retrieving Unix Time in Java](https://www.baeldung.com/java-retrieve-unix-time)
|
||||
- [Calculate Months Between Two Dates in Java](https://www.baeldung.com/java-months-difference-two-dates)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1)
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.daterangeoverlap;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Interval;
|
||||
|
||||
public class DateRangeOverlapChecker {
|
||||
|
||||
public static boolean isOverlapUsingCalendarAndDuration(Calendar start1, Calendar end1, Calendar start2, Calendar end2) {
|
||||
long overlap = Math.min(end1.getTimeInMillis(), end2.getTimeInMillis()) - Math.max(start1.getTimeInMillis(), start2.getTimeInMillis());
|
||||
return overlap >= 0;
|
||||
}
|
||||
|
||||
public static boolean isOverlapUsingLocalDateAndDuration(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) {
|
||||
long overlap = Math.min(end1.toEpochDay(), end2.toEpochDay()) - Math.max(start1.toEpochDay(), start2.toEpochDay());
|
||||
return overlap >= 0;
|
||||
}
|
||||
|
||||
public static boolean isOverlapUsingJodaTime(DateTime start1, DateTime end1, DateTime start2, DateTime end2) {
|
||||
Interval interval1 = new Interval(start1, end1);
|
||||
Interval interval2 = new Interval(start2, end2);
|
||||
return interval1.overlaps(interval2);
|
||||
}
|
||||
|
||||
public static boolean isOverlapUsingCalendarAndCondition(Calendar start1, Calendar end1, Calendar start2, Calendar end2) {
|
||||
return !(end1.before(start2) || start1.after(end2));
|
||||
}
|
||||
|
||||
public static boolean isOverlapUsingLocalDateAndCondition(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) {
|
||||
return !(end1.isBefore(start2) || start1.isAfter(end2));
|
||||
}
|
||||
|
||||
public static boolean isOverlapUsingCalendarAndFindMin(Calendar start1, Calendar end1, Calendar start2, Calendar end2) {
|
||||
long overlap1 = Math.min(end1.getTimeInMillis() - start1.getTimeInMillis(), end1.getTimeInMillis() - start2.getTimeInMillis());
|
||||
long overlap2 = Math.min(end2.getTimeInMillis() - start2.getTimeInMillis(), end2.getTimeInMillis() - start1.getTimeInMillis());
|
||||
return Math.min(overlap1, overlap2) / (24 * 60 * 60 * 1000) >= 0;
|
||||
}
|
||||
|
||||
public static boolean isOverlapUsingLocalDateAndFindMin(LocalDate start1, LocalDate end1, LocalDate start2, LocalDate end2) {
|
||||
long overlap1 = Math.min(end1.toEpochDay() - start1.toEpochDay(), end1.toEpochDay() - start2.toEpochDay());
|
||||
long overlap2 = Math.min(end2.toEpochDay() - start2.toEpochDay(), end2.toEpochDay() - start1.toEpochDay());
|
||||
return Math.min(overlap1, overlap2) >= 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
package com.baeldung.daterangeoverlap;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DateRangeOverlapCheckerUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenPartialOverlappingRanges_thenReturnsTrue() {
|
||||
Calendar start1 = Calendar.getInstance();
|
||||
start1.set(2024, 11, 15);
|
||||
Calendar end1 = Calendar.getInstance();
|
||||
end1.set(2024, 11, 20);
|
||||
|
||||
Calendar start2 = Calendar.getInstance();
|
||||
start2.set(2024, 11, 18);
|
||||
Calendar end2 = Calendar.getInstance();
|
||||
end2.set(2024, 11, 22);
|
||||
|
||||
LocalDate startLD1 = LocalDate.of(2024, 12, 15);
|
||||
LocalDate endLD1 = LocalDate.of(2024, 12, 20);
|
||||
|
||||
LocalDate startLD2 = LocalDate.of(2024, 12, 18);
|
||||
LocalDate endLD2 = LocalDate.of(2024, 12, 22);
|
||||
|
||||
DateTime startJT1 = new DateTime(2024, 12, 15, 0, 0);
|
||||
DateTime endJT1 = new DateTime(2024, 12, 20, 0, 0);
|
||||
|
||||
DateTime startJT2 = new DateTime(2024, 12, 18, 0, 0);
|
||||
DateTime endJT2 = new DateTime(2024, 12, 22, 0, 0);
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndDuration(start1, end1, start2, end2));
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndDuration(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndCondition(start1, end1, start2, end2));
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndCondition(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndFindMin(start1, end1, start2, end2));
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndFindMin(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingJodaTime(startJT1, endJT1, startJT2, endJT2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFullOverlappingRanges_thenReturnsTrue() {
|
||||
Calendar start1 = Calendar.getInstance();
|
||||
start1.set(2024, 11, 15);
|
||||
Calendar end1 = Calendar.getInstance();
|
||||
end1.set(2024, 11, 20);
|
||||
|
||||
Calendar start2 = Calendar.getInstance();
|
||||
start2.set(2024, 11, 16);
|
||||
Calendar end2 = Calendar.getInstance();
|
||||
end2.set(2024, 11, 18);
|
||||
|
||||
LocalDate startLD1 = LocalDate.of(2024, 12, 15);
|
||||
LocalDate endLD1 = LocalDate.of(2024, 12, 20);
|
||||
|
||||
LocalDate startLD2 = LocalDate.of(2024, 12, 16);
|
||||
LocalDate endLD2 = LocalDate.of(2024, 12, 18);
|
||||
|
||||
DateTime startJT1 = new DateTime(2024, 12, 15, 0, 0);
|
||||
DateTime endJT1 = new DateTime(2024, 12, 20, 0, 0);
|
||||
|
||||
DateTime startJT2 = new DateTime(2024, 12, 16, 0, 0);
|
||||
DateTime endJT2 = new DateTime(2024, 12, 18, 0, 0);
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndDuration(start1, end1, start2, end2));
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndDuration(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndCondition(start1, end1, start2, end2));
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndCondition(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndFindMin(start1, end1, start2, end2));
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndFindMin(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingJodaTime(startJT1, endJT1, startJT2, endJT2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenConsecutiveRanges_thenReturnsFalse() {
|
||||
Calendar start1 = Calendar.getInstance();
|
||||
start1.set(2024, 11, 15);
|
||||
Calendar end1 = Calendar.getInstance();
|
||||
end1.set(2024, 11, 20);
|
||||
|
||||
Calendar start2 = Calendar.getInstance();
|
||||
start2.set(2024, 11, 21);
|
||||
Calendar end2 = Calendar.getInstance();
|
||||
end2.set(2024, 11, 24);
|
||||
|
||||
LocalDate startLD1 = LocalDate.of(2024, 12, 15);
|
||||
LocalDate endLD1 = LocalDate.of(2024, 12, 20);
|
||||
|
||||
LocalDate startLD2 = LocalDate.of(2024, 12, 21);
|
||||
LocalDate endLD2 = LocalDate.of(2024, 12, 24);
|
||||
|
||||
DateTime startJT1 = new DateTime(2024, 12, 15, 0, 0);
|
||||
DateTime endJT1 = new DateTime(2024, 12, 20, 0, 0);
|
||||
|
||||
DateTime startJT2 = new DateTime(2024, 12, 21, 0, 0);
|
||||
DateTime endJT2 = new DateTime(2024, 12, 24, 0, 0);
|
||||
|
||||
assertFalse(DateRangeOverlapChecker.isOverlapUsingCalendarAndDuration(start1, end1, start2, end2));
|
||||
assertFalse(DateRangeOverlapChecker.isOverlapUsingLocalDateAndDuration(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertFalse(DateRangeOverlapChecker.isOverlapUsingCalendarAndCondition(start1, end1, start2, end2));
|
||||
assertFalse(DateRangeOverlapChecker.isOverlapUsingLocalDateAndCondition(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertFalse(DateRangeOverlapChecker.isOverlapUsingCalendarAndFindMin(start1, end1, start2, end2));
|
||||
assertFalse(DateRangeOverlapChecker.isOverlapUsingLocalDateAndFindMin(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertFalse(DateRangeOverlapChecker.isOverlapUsingJodaTime(startJT1, endJT1, startJT2, endJT2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenZeroRangeRanges_thenReturnsTrue() {
|
||||
Calendar start1 = Calendar.getInstance();
|
||||
start1.set(2024, 11, 15);
|
||||
Calendar end1 = Calendar.getInstance();
|
||||
end1.set(2024, 11, 20);
|
||||
|
||||
Calendar start2 = Calendar.getInstance();
|
||||
start2.set(2024, 11, 20);
|
||||
Calendar end2 = Calendar.getInstance();
|
||||
end2.set(2024, 11, 20);
|
||||
|
||||
LocalDate startLD1 = LocalDate.of(2024, 12, 15);
|
||||
LocalDate endLD1 = LocalDate.of(2024, 12, 20);
|
||||
|
||||
LocalDate startLD2 = LocalDate.of(2024, 12, 20);
|
||||
LocalDate endLD2 = LocalDate.of(2024, 12, 20);
|
||||
|
||||
DateTime startJT1 = new DateTime(2024, 12, 15, 0, 0);
|
||||
DateTime endJT1 = new DateTime(2024, 12, 20, 0, 0);
|
||||
|
||||
DateTime startJT2 = new DateTime(2024, 12, 20, 0, 0);
|
||||
DateTime endJT2 = new DateTime(2024, 12, 20, 0, 0);
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndDuration(start1, end1, start2, end2));
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndDuration(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndCondition(start1, end1, start2, end2));
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndCondition(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingCalendarAndFindMin(start1, end1, start2, end2));
|
||||
assertTrue(DateRangeOverlapChecker.isOverlapUsingLocalDateAndFindMin(startLD1, endLD1, startLD2, endLD2));
|
||||
|
||||
//the overlaps method considers two intervals as overlapping only if they have a non-zero duration.
|
||||
assertFalse(DateRangeOverlapChecker.isOverlapUsingJodaTime(startJT1, endJT1, startJT2, endJT2));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.array.conversions;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ByteArrayToPrimitiveByteArrayUnitTest {
|
||||
private static final byte[] EXPECTED_ARRAY_VALUES = {65, 66, 67, 68};
|
||||
private static final Byte[] BYTE_ARRAY = {65, 66, 67, 68};
|
||||
|
||||
@Test
|
||||
public void givenByteArray_whenConvertingUsingByteValue_thenGiveExpectedResult() {
|
||||
byte[] newByteArray = new byte[BYTE_ARRAY.length];
|
||||
for (int i = 0; i < BYTE_ARRAY.length; i++) {
|
||||
newByteArray[i] = BYTE_ARRAY[i].byteValue();
|
||||
}
|
||||
assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenByteArray_whenConvertingUsingUnboxing_thenGiveExpectedResult() {
|
||||
byte[] newByteArray = new byte[BYTE_ARRAY.length];
|
||||
for (int i = 0; i < BYTE_ARRAY.length; i++) {
|
||||
newByteArray[i] = BYTE_ARRAY[i];
|
||||
}
|
||||
assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenByteArray_whenConvertingArrayUtils_thenGiveExpectedResult() {
|
||||
byte[] newByteArray = ArrayUtils.toPrimitive(BYTE_ARRAY);
|
||||
|
||||
assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.baeldung.array.conversions;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class PrimitiveByteArrayToByteArrayUnitTest {
|
||||
private static final byte[] PRIMITIVE_BYTE_ARRAY = {65, 66, 67, 68};
|
||||
private static final Byte[] EXPECTED_ARRAY_VALUES = {65, 66, 67, 68};
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveByteArray_whenConvertingUsingByteValueOf_thenGiveExpectedResult() {
|
||||
Byte[] newByteArray = new Byte[PRIMITIVE_BYTE_ARRAY.length];
|
||||
for (int i = 0; i < PRIMITIVE_BYTE_ARRAY.length; i++) {
|
||||
newByteArray[i] = Byte.valueOf(PRIMITIVE_BYTE_ARRAY[i]);
|
||||
}
|
||||
assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveByteArray_whenConvertingUsingAutoboxing_thenGiveExpectedResult() {
|
||||
Byte[] newByteArray = new Byte[PRIMITIVE_BYTE_ARRAY.length];
|
||||
for (int i = 0; i < PRIMITIVE_BYTE_ARRAY.length; i++) {
|
||||
newByteArray[i] = PRIMITIVE_BYTE_ARRAY[i];
|
||||
}
|
||||
assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveByteArray_whenConvertingUsingAutoboxingAndArraysSetAll_thenGiveExpectedResult() {
|
||||
Byte[] newByteArray = new Byte[PRIMITIVE_BYTE_ARRAY.length];
|
||||
Arrays.setAll(newByteArray, n -> PRIMITIVE_BYTE_ARRAY[n]);
|
||||
|
||||
assertThat(newByteArray)
|
||||
.containsExactly(EXPECTED_ARRAY_VALUES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPrimitiveByteArray_whenConvertingUsingArrayUtils_thenGiveExpectedResult() {
|
||||
Byte[] newByteArray = ArrayUtils.toObject(PRIMITIVE_BYTE_ARRAY);
|
||||
|
||||
assertThat(newByteArray).containsExactly(EXPECTED_ARRAY_VALUES);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.baeldung.unicodechar;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class UnicodeCharFromCodePointHexStringUnitTest {
|
||||
private static final String U_CHECK = "✅"; // U+2705
|
||||
private static final String U_STRONG = "强"; // U+5F3A
|
||||
|
||||
|
||||
@Test
|
||||
void whenEscapeUAndNumberInString_thenGetExpectedUnicodeStr() {
|
||||
String check = "\u2705";
|
||||
assertEquals(U_CHECK, check);
|
||||
|
||||
String strong = "\u5F3A";
|
||||
assertEquals(U_STRONG, strong);
|
||||
|
||||
// "A" U+0041
|
||||
assertEquals("A", "\u0041");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void whenConcatUAndNumberAsString_thenDoNotGetExpectedUnicodeStr() {
|
||||
String check = "\\u" + "2705";
|
||||
assertEquals("\\u2705", check);
|
||||
|
||||
String strong = "\\u" + "5F3A";
|
||||
assertEquals("\\u5F3A", strong);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void whenCastHexCodePointToCharAndConvertCharToString_thenGetExpectedUnicodeStr() {
|
||||
|
||||
int codePoint = Integer.parseInt("2705", 16); //Decimal int: 9989
|
||||
char[] checkChar = Character.toChars(codePoint);
|
||||
String check = String.valueOf(checkChar);
|
||||
assertEquals(U_CHECK, check);
|
||||
|
||||
// For Java 11 and later versions
|
||||
// assertEquals(U_CHECK, Character.toString(codePoint));
|
||||
|
||||
codePoint = Integer.parseInt("5F3A", 16); //Decimal int: 24378
|
||||
char[] strongChar = Character.toChars(codePoint);
|
||||
String strong = String.valueOf(strongChar);
|
||||
assertEquals(U_STRONG, strong);
|
||||
|
||||
// For Java 11 and later versions
|
||||
// assertEquals(U_STRONG, Character.toString(codePoint));
|
||||
}
|
||||
|
||||
String stringFromCodePointHex(String codePointHex) {
|
||||
int codePoint = Integer.parseInt(codePointHex, 16);
|
||||
|
||||
// For Java 11 and later versions: return Character.toString(codePoint)
|
||||
|
||||
char[] chars = Character.toChars(codePoint);
|
||||
return String.valueOf(chars);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingstringFromCodePointHex_thenGetExpectedUnicodeStr() {
|
||||
assertEquals("A", stringFromCodePointHex("0041"));
|
||||
assertEquals(U_CHECK, stringFromCodePointHex("2705"));
|
||||
assertEquals(U_STRONG, stringFromCodePointHex("5F3A"));
|
||||
}
|
||||
}
|
|
@ -11,4 +11,6 @@
|
|||
- [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide)
|
||||
- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray)
|
||||
- [Time Complexity of Java Collections Sort in Java](https://www.baeldung.com/java-time-complexity-collections-sort)
|
||||
- [Check if List Contains at Least One Enum](https://www.baeldung.com/java-list-check-enum-presence)
|
||||
- [Comparison of for Loops and Iterators](https://www.baeldung.com/java-for-loops-vs-iterators)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-collections-4)
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
## Relevant Articles
|
||||
- [Check if a List Contains a String Element While Ignoring Case](https://www.baeldung.com/java-list-search-case-insensitive)
|
||||
- [Removing the Last Node in a Linked List](https://www.baeldung.com/java-linked-list-remove-last-element)
|
||||
- [Call a Method on Each Element of a List in Java](https://www.baeldung.com/java-call-method-each-list-item)
|
||||
- [Sorting One List Based on Another List in Java](https://www.baeldung.com/java-sorting-one-list-using-another)
|
||||
|
|
|
@ -12,4 +12,5 @@ This module contains articles about basic Java concurrency
|
|||
- [How to Get the Number of Threads in a Java Process](https://www.baeldung.com/java-get-number-of-threads)
|
||||
- [Set the Name of a Thread in Java](https://www.baeldung.com/java-set-thread-name)
|
||||
- [Thread vs. Single Thread Executor Service](https://www.baeldung.com/java-single-thread-executor-service)
|
||||
- [Difference Between a Future and a Promise in Java](https://www.baeldung.com/java-future-vs-promise-comparison)
|
||||
- [[<-- Prev]](../core-java-concurrency-basic)[[Next -->]](../core-java-concurrency-basic-3)
|
||||
|
|
|
@ -13,4 +13,5 @@ This module contains articles about basic Java concurrency.
|
|||
- [Retry Logic with CompletableFuture](https://www.baeldung.com/java-completablefuture-retry-logic)
|
||||
- [Convert From List of CompletableFuture to CompletableFuture List](https://www.baeldung.com/java-completablefuture-list-convert)
|
||||
- [Synchronize a Static Variable Among Different Threads](https://www.baeldung.com/java-synchronize-static-variable-different-threads)
|
||||
- [Difference Between execute() and submit() in Executor Service](https://www.baeldung.com/java-execute-vs-submit-executor-service)
|
||||
- [[<-- Prev]](../core-java-concurrency-basic-2)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
## Core Date Operations (Part 4)
|
||||
This module contains articles about date operations in Java.
|
||||
|
||||
### Relevant Articles:
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-date-operations-4</artifactId>
|
||||
<name>core-java-date-operations-4</name>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${joda-time.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<joda-time.version>2.12.6</joda-time.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,46 @@
|
|||
package com.baeldung.calculateweekdays;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class CalculateWeekdays {
|
||||
|
||||
public long getWorkingDaysWithStream(LocalDate start, LocalDate end){
|
||||
return start.datesUntil(end)
|
||||
.map(LocalDate::getDayOfWeek)
|
||||
.filter(day -> !Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY).contains(day))
|
||||
.count();
|
||||
}
|
||||
|
||||
public long getWorkingDaysWithoutStream(LocalDate start, LocalDate end) {
|
||||
boolean startOnWeekend = false;
|
||||
|
||||
// If starting at the weekend, move to following Monday
|
||||
if(start.getDayOfWeek().getValue() > 5){
|
||||
start = start.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
|
||||
startOnWeekend = true;
|
||||
}
|
||||
boolean endOnWeekend = false;
|
||||
// If ending at the weekend, move to previous Friday
|
||||
if(end.getDayOfWeek().getValue() > 5){
|
||||
end = end.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
|
||||
endOnWeekend = true;
|
||||
}
|
||||
// Cover case where starting on Saturday and ending following Sunday
|
||||
if(start.isAfter(end)){
|
||||
return 0;
|
||||
}
|
||||
// Get total weeks
|
||||
long weeks = ChronoUnit.WEEKS.between(start, end);
|
||||
|
||||
long addValue = startOnWeekend || endOnWeekend ? 1 : 0;
|
||||
|
||||
// Add on days that did not make up a full week
|
||||
return ( weeks * 5 ) + ( end.getDayOfWeek().getValue() - start.getDayOfWeek().getValue() ) + addValue;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package com.baeldung.calculateweekdays;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class CalculateWeekdaysUnitTest {
|
||||
|
||||
// Start Saturday end following Sunday (answer is 0)
|
||||
LocalDate startTomorrow = LocalDate.of(2023, 12, 2);
|
||||
LocalDate endTomorrow = LocalDate.of(2023, 12, 3);
|
||||
|
||||
// Three week gap with midweek start and finish (answer is 17)
|
||||
LocalDate startThreeWeeks = LocalDate.of(2023, 11, 28);
|
||||
LocalDate endThreeWeeks = LocalDate.of(2023, 12, 21);
|
||||
|
||||
// Three week gap with midweek start and weekend finish (answer is 17)
|
||||
LocalDate startThreeWeeks2 = LocalDate.of(2023, 11, 6);
|
||||
LocalDate endThreeWeeks2 = LocalDate.of(2023, 12, 30);
|
||||
|
||||
// Week gap start and end on weekend (answer is 40)
|
||||
LocalDate startThreeWeeksWeekend = LocalDate.of(2023, 12, 2);
|
||||
LocalDate endThreeWeeksWeekend = LocalDate.of(2023, 12, 9);
|
||||
|
||||
@Test
|
||||
void givenTwoDaysOnSameWeekend_whenUsingStreams_thenCalculateWeekdays(){
|
||||
CalculateWeekdays c = new CalculateWeekdays();
|
||||
long result = c.getWorkingDaysWithStream(startTomorrow, endTomorrow);
|
||||
assertEquals(0, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenTwoDaysOnSameWeekend_whenUsingMaths_thenCalculateWeekdays(){
|
||||
CalculateWeekdays c = new CalculateWeekdays();
|
||||
long result = c.getWorkingDaysWithoutStream(startTomorrow, endTomorrow);
|
||||
assertEquals(0, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAThreeWeekGapMidweekDates_whenUsingStreams_thenCalculateWeekdays(){
|
||||
CalculateWeekdays c = new CalculateWeekdays();
|
||||
long result = c.getWorkingDaysWithStream(startThreeWeeks, endThreeWeeks);
|
||||
assertEquals(17, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenAThreeWeekGapMidweekDates_whenUsingMaths_thenCalculateWeekdays(){
|
||||
CalculateWeekdays c = new CalculateWeekdays();
|
||||
long result = c.getWorkingDaysWithoutStream(startThreeWeeks, endThreeWeeks);
|
||||
assertEquals(17, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenThreeWeekGapMidweekAndWeekendDates_whenUsingStreams_thenCalculateWeekdays(){
|
||||
CalculateWeekdays c = new CalculateWeekdays();
|
||||
long result = c.getWorkingDaysWithStream(startThreeWeeksWeekend, endThreeWeeksWeekend);
|
||||
assertEquals(5, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenThreeWeekGapMidweekAndWeekendDates_whenUsingMaths_thenCalculateWeekdays(){
|
||||
CalculateWeekdays c = new CalculateWeekdays();
|
||||
long result = c.getWorkingDaysWithoutStream(startThreeWeeksWeekend, endThreeWeeksWeekend);
|
||||
assertEquals(5, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenThreeWeekGapWeekendDates_whenUsingStreams_thenCalculateWeekdays(){
|
||||
CalculateWeekdays c = new CalculateWeekdays();
|
||||
long result = c.getWorkingDaysWithStream(startThreeWeeks2, endThreeWeeks2);
|
||||
assertEquals(40, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenThreeWeekGapWeekendDates_whenUsingMaths_thenCalculateWeekdays(){
|
||||
CalculateWeekdays c = new CalculateWeekdays();
|
||||
long result = c.getWorkingDaysWithoutStream(startThreeWeeks2, endThreeWeeks2);
|
||||
assertEquals(40, result);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.baeldung.longtodate;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.Instant;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class LongToDateUnitTest {
|
||||
|
||||
@Test
|
||||
void givenLongValue_whenUsingInstantClass_thenConvert() {
|
||||
Instant expectedDate = Instant.parse("2020-09-08T12:16:40Z");
|
||||
long seconds = 1599567400L;
|
||||
|
||||
Instant date = Instant.ofEpochSecond(seconds);
|
||||
|
||||
assertEquals(expectedDate, date);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenLongValue_whenUsingLocalDateClass_thenConvert() {
|
||||
LocalDate expectedDate = LocalDate.of(2023, 10, 17);
|
||||
long epochDay = 19647L;
|
||||
|
||||
LocalDate date = LocalDate.ofEpochDay(epochDay);
|
||||
|
||||
assertEquals(expectedDate, date);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenLongValue_whenUsingDateClass_thenConvert() throws ParseException {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
Date expectedDate = dateFormat.parse("2023-07-15 22:00:00");
|
||||
long milliseconds = 1689458400000L;
|
||||
|
||||
Date date = new Date(milliseconds);
|
||||
|
||||
assertEquals(expectedDate, date);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenLongValue_whenUsingCalendarClass_thenConvert() throws ParseException {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
Date expectedDate = dateFormat.parse("2023-07-15 22:00:00");
|
||||
long milliseconds = 1689458400000L;
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
calendar.setTimeInMillis(milliseconds);
|
||||
|
||||
assertEquals(expectedDate, calendar.getTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenLongValue_whenUsingJodaTimeLocalDateClass_thenConvert() {
|
||||
org.joda.time.LocalDate expectedDate = new org.joda.time.LocalDate(2023, 7, 15);
|
||||
long milliseconds = 1689458400000L;
|
||||
|
||||
org.joda.time.LocalDate date = new org.joda.time.LocalDate(milliseconds, DateTimeZone.UTC);
|
||||
|
||||
assertEquals(expectedDate, date);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
## Java Date/time conversion Cookbooks and Examples
|
||||
|
||||
This module contains articles about converting between Java date and time objects.
|
||||
|
||||
### Relevant Articles:
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-datetime-conversion-2</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<name>core-java-datetime-conversion-2</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${joda-time.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.msarhan</groupId>
|
||||
<artifactId>ummalqura-calendar</artifactId>
|
||||
<version>${ummalqura-calendar.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>core-java-datetime-conversion-2</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<joda-time.version>2.12.5</joda-time.version>
|
||||
<ummalqura-calendar.version>2.0.2</ummalqura-calendar.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -12,3 +12,4 @@ This module contains articles about converting between Java date and time object
|
|||
- [Convert Epoch Time to LocalDate and LocalDateTime](https://www.baeldung.com/java-convert-epoch-localdate)
|
||||
- [Convert Timestamp String to Long in Java](https://www.baeldung.com/java-convert-timestamp-string-long)
|
||||
- [Convert Long Timestamp to LocalDateTime in Java](https://www.baeldung.com/java-convert-long-timestamp-localdatetime)
|
||||
- [Convert Joda-Time DateTime to Date and Vice Versa](https://www.baeldung.com/java-convert-joda-time-datetime-to-date)
|
||||
|
|
|
@ -25,12 +25,6 @@
|
|||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.msarhan</groupId>
|
||||
<artifactId>ummalqura-calendar</artifactId>
|
||||
<version>${ummalqura-calendar.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -51,7 +45,6 @@
|
|||
|
||||
<properties>
|
||||
<joda-time.version>2.12.5</joda-time.version>
|
||||
<ummalqura-calendar.version>2.0.2</ummalqura-calendar.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -6,5 +6,6 @@ This module contains articles about core Java input and output (IO)
|
|||
- [Get File Extension From MIME Type in Java](https://www.baeldung.com/java-mime-type-file-extension)
|
||||
- [How to Remove Line Breaks From a File in Java](https://www.baeldung.com/java-file-remove-line-breaks)
|
||||
- [Difference Between ZipFile and ZipInputStream in Java](https://www.baeldung.com/java-zipfile-vs-zipinputstream)
|
||||
- [How to Write Strings to OutputStream in Java](https://www.baeldung.com/java-write-string-outputstream)
|
||||
- [[<-- Prev]](/core-java-modules/core-java-io-4)
|
||||
|
||||
|
|
|
@ -9,3 +9,5 @@ This module contains articles about core Java input/output(IO) APIs.
|
|||
- [Converting Relative to Absolute Paths in Java](https://www.baeldung.com/java-from-relative-to-absolute-paths)
|
||||
- [Detect EOF in Java](https://www.baeldung.com/java-file-detect-end-of-file)
|
||||
- [PrintWriter vs. FileWriter in Java](https://www.baeldung.com/java-printwriter-filewriter-difference)
|
||||
- [Read Input Character-by-Character in Java](https://www.baeldung.com/java-read-input-character)
|
||||
- [Difference Between flush() and close() in Java FileWriter](https://www.baeldung.com/java-filewriter-flush-vs-close)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
FROM maven:3.9-amazoncorretto-17
|
||||
WORKDIR /app
|
||||
COPY /src/test/java/com/baeldung/setenvironment/SettingDockerEnvironmentVariableUnitTest.java \
|
||||
./src/test/java/com/baeldung/setenvironment/
|
||||
COPY /docker-pom.xml ./
|
||||
ENV CUSTOM_DOCKER_ENV_VARIABLE=TRUE
|
||||
ENTRYPOINT mvn -f docker-pom.xml test
|
|
@ -10,4 +10,6 @@ This module contains articles about core features in the Java language
|
|||
- [Stop Executing Further Code in Java](https://www.baeldung.com/java-stop-running-code)
|
||||
- [Using the Apache Commons Lang 3 for Comparing Objects in Java](https://www.baeldung.com/java-apache-commons-lang-3-compare-objects)
|
||||
- [Return First Non-null Value in Java](https://www.baeldung.com/java-first-non-null)
|
||||
- [Compress and Uncompress Byte Array Using Deflater/Inflater](https://www.baeldung.com/java-compress-uncompress-byte-array)
|
||||
- [Static Final Variables in Java](https://www.baeldung.com/java-static-final-variables)
|
||||
- [What Is the Error: “Non-static method cannot be referenced from a static context”?](https://www.baeldung.com/java-non-static-method-cannot-be-referenced-from-a-static-context)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-lang-6</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
<version>${testcontainers.junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${testcontainers.junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<testcontainers.junit.version>1.19.3</testcontainers.junit.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -33,6 +33,25 @@
|
|||
<artifactId>jmh-generator-annprocess</artifactId>
|
||||
<version>${jmh.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit-pioneer</groupId>
|
||||
<artifactId>junit-pioneer</artifactId>
|
||||
<version>${junit.pioneer.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
<version>${testcontaienr.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${testcontaienr.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
@ -53,6 +72,8 @@
|
|||
<version>${jmh.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
<source>14</source>
|
||||
<target>14</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
@ -61,6 +82,8 @@
|
|||
<properties>
|
||||
<mapstruct.version>1.6.0.Beta1</mapstruct.version>
|
||||
<jmh.version>1.37</jmh.version>
|
||||
<junit.pioneer.version>2.2.0</junit.pioneer.version>
|
||||
<testcontaienr.version>1.19.3</testcontaienr.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,44 @@
|
|||
package com.baeldung.setenvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Tag;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
|
||||
class SettingChildProcessEnvironmentVariableUnitTest {
|
||||
|
||||
public static final String ENVIRONMENT_VARIABLE_NAME = "test";
|
||||
public static final String ENVIRONMENT_VARIABLE_VALUE = "Hello World";
|
||||
public static final String CHILD_PROCESS_CONDITION = "CHILD_PROCESS_TEST";
|
||||
public static final String CHILD_PROCESS_VALUE = "true";
|
||||
public static final String CHILD_PROCESS_TAG = "child_process";
|
||||
public static final String TAG = String.format("-Dgroups=%s", CHILD_PROCESS_TAG);
|
||||
private final String testClass = String.format("-Dtest=%s", getClass().getName());
|
||||
private final String[] arguments = {"mvn", "test", TAG, testClass};
|
||||
|
||||
@Test
|
||||
void givenChildProcessTestRunner_whenRunTheTest_thenAllSucceed()
|
||||
throws IOException, InterruptedException {
|
||||
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||
processBuilder.inheritIO();
|
||||
|
||||
Map<String, String> environment = processBuilder.environment();
|
||||
environment.put(CHILD_PROCESS_CONDITION, CHILD_PROCESS_VALUE);
|
||||
environment.put(ENVIRONMENT_VARIABLE_NAME, ENVIRONMENT_VARIABLE_VALUE);
|
||||
Process process = processBuilder.command(arguments).start();
|
||||
|
||||
int errorCode = process.waitFor();
|
||||
assertThat(errorCode).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledIfEnvironmentVariable(named = CHILD_PROCESS_CONDITION, matches = CHILD_PROCESS_VALUE)
|
||||
@Tag(CHILD_PROCESS_TAG)
|
||||
void givenChildProcess_whenGetEnvironmentVariable_thenReturnsCorrectValue() {
|
||||
String actual = System.getenv(ENVIRONMENT_VARIABLE_NAME);
|
||||
assertThat(actual).isEqualTo(ENVIRONMENT_VARIABLE_VALUE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.setenvironment;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
|
||||
class SettingDockerEnvironmentVariableUnitTest {
|
||||
|
||||
public static final String ENV_VARIABLE_NAME = "CUSTOM_DOCKER_ENV_VARIABLE";
|
||||
public static final String ENV_VARIABLE_VALUE = "TRUE";
|
||||
|
||||
@Test
|
||||
@EnabledIfEnvironmentVariable(named = ENV_VARIABLE_NAME, matches = ENV_VARIABLE_VALUE)
|
||||
void givenDockerEnvironment_whenGetEnvironmentVariable_thenReturnsCorrectValue() {
|
||||
String actual = System.getenv(ENV_VARIABLE_NAME);
|
||||
assertEquals(ENV_VARIABLE_VALUE, actual);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package com.baeldung.setenvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledForJreRange;
|
||||
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.junitpioneer.jupiter.SetEnvironmentVariable;
|
||||
|
||||
class SettingSameProcessEnvironmentVariableUnitTest {
|
||||
|
||||
private static final String PROCESS_ENVIRONMENT = "java.lang.ProcessEnvironment";
|
||||
private static final String ENVIRONMENT = "theUnmodifiableEnvironment";
|
||||
private static final String SOURCE_MAP = "m";
|
||||
private static final Object STATIC_METHOD = null;
|
||||
private static final Class<?> UMODIFIABLE_MAP_CLASS
|
||||
= Collections.unmodifiableMap(Collections.emptyMap()).getClass();
|
||||
private static final Class<?> MAP_CLASS = Map.class;
|
||||
public static final String ENV_VARIABLE_NAME = "test";
|
||||
public static final String ENV_VARIABLE_VALUE = "Hello World";
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({ENV_VARIABLE_VALUE + "," + ENV_VARIABLE_NAME})
|
||||
@EnabledForJreRange(max = JRE.JAVA_16)
|
||||
void givenReflexiveAccess_whenGetSourceMap_thenSuccessfullyModifyVariables(String environmentVariable, String value)
|
||||
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
|
||||
Map<String, String> modifiableEnvironment = getModifiableEnvironment();
|
||||
assertThat(modifiableEnvironment).isNotNull();
|
||||
|
||||
modifiableEnvironment.put(environmentVariable, value);
|
||||
String actual = modifiableEnvironment.get(environmentVariable);
|
||||
assertThat(actual).isEqualTo(value);
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnabledIfEnvironmentVariable(named = "PATH", matches = ".*",
|
||||
disabledReason = "The test relies on the presence of PATH variable")
|
||||
void givenOS_whenGetPath_thenVariableIsPresent() {
|
||||
String classPath = System.getenv("PATH");
|
||||
assertThat(classPath).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenOS_whenGetEnv_thenVariablesArePresent() {
|
||||
Map<String, String> environment = System.getenv();
|
||||
assertThat(environment).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SetEnvironmentVariable(key = ENV_VARIABLE_NAME, value = ENV_VARIABLE_VALUE)
|
||||
@EnabledForJreRange(max = JRE.JAVA_16)
|
||||
void givenVariableSet_whenGetEnvironmentVariable_thenReturnsCorrectValue() {
|
||||
String actual = System.getenv(ENV_VARIABLE_NAME);
|
||||
assertThat(actual).isEqualTo(ENV_VARIABLE_VALUE);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Map<String, String> getModifiableEnvironment()
|
||||
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
|
||||
Class<?> environmentClass = Class.forName(PROCESS_ENVIRONMENT);
|
||||
Field environmentField = environmentClass.getDeclaredField(ENVIRONMENT);
|
||||
assertThat(environmentField).isNotNull();
|
||||
environmentField.setAccessible(true);
|
||||
|
||||
Object unmodifiableEnvironmentMap = environmentField.get(STATIC_METHOD);
|
||||
assertThat(unmodifiableEnvironmentMap).isNotNull();
|
||||
assertThat(unmodifiableEnvironmentMap).isInstanceOf(UMODIFIABLE_MAP_CLASS);
|
||||
|
||||
Field underlyingMapField = unmodifiableEnvironmentMap.getClass().getDeclaredField(SOURCE_MAP);
|
||||
underlyingMapField.setAccessible(true);
|
||||
Object underlyingMap = underlyingMapField.get(unmodifiableEnvironmentMap);
|
||||
assertThat(underlyingMap).isNotNull();
|
||||
assertThat(underlyingMap).isInstanceOf(MAP_CLASS);
|
||||
|
||||
return (Map<String, String>) underlyingMap;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.setenvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
import org.testcontainers.images.builder.ImageFromDockerfile;
|
||||
|
||||
class SettingTestcontainerVariableUnitTest {
|
||||
|
||||
public static final String CONTAINER_REPORT_FILE = "/app/target/surefire-reports/TEST-com.baeldung.setenvironment.SettingDockerEnvironmentVariableUnitTest.xml";
|
||||
public static final String HOST_REPORT_FILE = "./container-test-report.xml";
|
||||
public static final String DOCKERFILE = "./Dockerfile";
|
||||
|
||||
@Test
|
||||
@Disabled("Requires working Docker environment ")
|
||||
void givenTestcontainerEnvironment_whenGetEnvironmentVariable_thenReturnsCorrectValue() {
|
||||
Path dockerfilePath = Paths.get(DOCKERFILE);
|
||||
GenericContainer container = new GenericContainer(
|
||||
new ImageFromDockerfile().withDockerfile(dockerfilePath));
|
||||
assertThat(container).isNotNull();
|
||||
container.start();
|
||||
while (container.isRunning()) {
|
||||
// Busy spin
|
||||
}
|
||||
container.copyFileFromContainer(CONTAINER_REPORT_FILE, HOST_REPORT_FILE);
|
||||
}
|
||||
}
|
|
@ -13,4 +13,5 @@
|
|||
- [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency)
|
||||
- [Clamp Function in Java](https://www.baeldung.com/java-clamp-function)
|
||||
- [Creating a Magic Square in Java](https://www.baeldung.com/java-magic-square)
|
||||
- [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line)
|
||||
- More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2)
|
||||
|
|
|
@ -10,3 +10,4 @@ This module contains articles about generics in Java
|
|||
- [Java Warning “unchecked conversion”](https://www.baeldung.com/java-unchecked-conversion)
|
||||
- [Java Warning “Unchecked Cast”](https://www.baeldung.com/java-warning-unchecked-cast)
|
||||
- [What Does the Holder<T> Class Do in Java?](https://www.baeldung.com/java-holder-class)
|
||||
- [Determine the Class of a Generic Type in Java](https://www.baeldung.com/java-generic-type-find-class-runtime)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package com.baeldung.urlnormalization;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.apache.commons.validator.routines.UrlValidator;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class URLNormalizationUnitTest {
|
||||
String originalUrl = "https://www.example.com:8080/path/to/resource?param1=value1¶m2=value2#fragment";
|
||||
String expectedNormalizedUrl = "https://www.example.com:8080/path/to/resource";
|
||||
|
||||
@Test
|
||||
public void givenOriginalUrl_whenUsingApacheCommonsValidator_thenValidatedAndMaybeManuallyNormalized() {
|
||||
UrlValidator urlValidator = new UrlValidator();
|
||||
if (urlValidator.isValid(originalUrl)) {
|
||||
String normalizedUri = originalUrl.split("\\?")[0];
|
||||
assertEquals(expectedNormalizedUrl, normalizedUri);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid URL: " + originalUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenOriginalUrl_whenUsingJavaURIClass_thenNormalizedUrl() throws URISyntaxException {
|
||||
URI uri = new URI(originalUrl);
|
||||
URI normalizedUri = new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), null, null);
|
||||
String normalizedUrl = normalizedUri.toString();
|
||||
assertEquals(expectedNormalizedUrl, normalizedUrl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenOriginalUrl_whenUsingRegularExpression_thenNormalizedUrl() throws URISyntaxException, UnsupportedEncodingException {
|
||||
String regex = "^(https?://[^/]+/[^?#]+)";
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(originalUrl);
|
||||
|
||||
if (matcher.find()) {
|
||||
String normalizedUrl = matcher.group(1);
|
||||
assertEquals(expectedNormalizedUrl, normalizedUrl);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid URL: " + originalUrl);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
## Relevant Articles
|
||||
- [Check if a double Is an Integer in Java](https://www.baeldung.com/java-check-double-integer)
|
||||
- [Print a Double Value Without Scientific Notation in Java](https://www.baeldung.com/java-print-double-number-no-scientific-notation)
|
||||
|
|
|
@ -7,3 +7,4 @@
|
|||
- [Convert Positive Integer to Negative and Vice Versa in Java](https://www.baeldung.com/java-negating-integer)
|
||||
- [Rounding Up a Number to Nearest Multiple of 5 in Java](https://www.baeldung.com/java-round-nearest-multiple-five)
|
||||
- [Convert byte to int Type in Java](https://www.baeldung.com/java-byte-to-int-conversion)
|
||||
- [Converting Integer to BigDecimal in Java](https://www.baeldung.com/java-integer-bigdecimal-conversion)
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package com.baeldung.oom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@Disabled
|
||||
class OomCrashUnitTest {
|
||||
|
||||
public static final Runnable MEMORY_LEAK = () -> {
|
||||
List<byte[]> list = new ArrayList<>();
|
||||
while (true) {
|
||||
list.add(tenMegabytes());
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
void givenMemoryLeakCode_whenRunInsideThread_thenMainAppDoestFail() throws InterruptedException {
|
||||
Thread memoryLeakThread = new Thread(MEMORY_LEAK);
|
||||
memoryLeakThread.start();
|
||||
memoryLeakThread.join();
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMemoryLeakCode_whenRunSeveralTimesInsideThread_thenMainAppDoestFail() throws InterruptedException {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Thread memoryLeakThread = new Thread(MEMORY_LEAK);
|
||||
memoryLeakThread.start();
|
||||
memoryLeakThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenBadExample_whenUseItInProductionCode_thenQuestionedByEmployerAndProbablyFired()
|
||||
throws InterruptedException {
|
||||
Thread npeThread = new Thread(() -> {
|
||||
String nullString = null;
|
||||
try {
|
||||
nullString.isEmpty();
|
||||
} catch (NullPointerException e) {
|
||||
throw new OutOfMemoryError(e.getMessage());
|
||||
}
|
||||
});
|
||||
npeThread.start();
|
||||
npeThread.join();
|
||||
}
|
||||
|
||||
private static byte[] tenMegabytes() {
|
||||
return new byte[1024 * 1014 * 10];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
### Relevant Articles:
|
||||
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-regex-2)
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-regex-3</artifactId>
|
||||
<name>core-java-regex-3</name>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.core-java-modules</groupId>
|
||||
<artifactId>core-java-modules</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,53 @@
|
|||
package com.baeldung.passwordvalidation;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class PasswordValidationUsingRegexUnitTest {
|
||||
String password = "Baeldung20@";
|
||||
|
||||
@Test
|
||||
public void givenStringPassword_whenUsingDynamicPasswordValidationRules_thenCheckIfPasswordValid() {
|
||||
boolean result = false;
|
||||
try {
|
||||
if (password != null) {
|
||||
String MIN_LENGTH = "8";
|
||||
String MAX_LENGTH = "20";
|
||||
boolean SPECIAL_CHAR_NEEDED = false;
|
||||
|
||||
String ONE_DIGIT = "(?=.*[0-9])";
|
||||
String LOWER_CASE = "(?=.*[a-z])";
|
||||
String UPPER_CASE = "(?=.*[A-Z])";
|
||||
String SPECIAL_CHAR = SPECIAL_CHAR_NEEDED ? "(?=.*[@#$%^&+=])" : "";
|
||||
String NO_SPACE = "(?=\\S+$)";
|
||||
|
||||
String MIN_MAX_CHAR = ".{" + MIN_LENGTH + "," + MAX_LENGTH + "}";
|
||||
String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR;
|
||||
|
||||
assertTrue(password.matches(PATTERN));
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
fail("Exception occurred: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStringPassword_whenUsingRegulaExpressions_thenCheckIfPasswordValid() {
|
||||
|
||||
|
||||
String regExpn =
|
||||
"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,20}$";
|
||||
|
||||
Pattern pattern = Pattern.compile(regExpn, Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(password);
|
||||
|
||||
assertTrue(matcher.matches());
|
||||
}
|
||||
|
||||
}
|
|
@ -6,4 +6,5 @@ This module contains articles about core Java Security
|
|||
- [Check if Certificate Is Self-Signed or CA-Signed With Java](https://www.baeldung.com/java-check-certificate-sign)
|
||||
- [Extract CN From X509 Certificate in Java](https://www.baeldung.com/java-extract-common-name-x509-certificate)
|
||||
- [Check Certificate Name and Alias in Keystore File](https://www.baeldung.com/java-keystore-check-certificate-name-alias)
|
||||
- [Using a Custom TrustStore in Java](https://www.baeldung.com/java-custom-truststore)
|
||||
- More articles: [[<-- prev]](/core-java-modules/core-java-security-3)
|
||||
|
|
|
@ -4,3 +4,4 @@ This module contains articles about string-related algorithms.
|
|||
|
||||
### Relevant Articles:
|
||||
- [Rotating a Java String By n Characters](https://www.baeldung.com/java-rotate-string-by-n-characters)
|
||||
- [Remove Characters From a String That Are in the Other String](https://www.baeldung.com/java-strings-character-difference)
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
- [Split Java String Into Key-Value Pairs](https://www.baeldung.com/java-split-string-map)
|
||||
- [How to Center Text Output in Java](https://www.baeldung.com/java-center-text-output)
|
||||
- [How to Convert an Object to String](https://www.baeldung.com/java-object-string-representation)
|
||||
- [Convert String to long or Long in Java](https://www.baeldung.com/java-convert-string-to-long)
|
||||
- [Convert String to long or Long in Java](https://www.baeldung.com/java-convert-string-long)
|
||||
|
|
|
@ -7,3 +7,7 @@
|
|||
- [Check if a String Contains a Number Value in Java](https://www.baeldung.com/java-string-number-presence)
|
||||
- [Difference Between String isEmpty() and isBlank()](https://www.baeldung.com/java-string-isempty-vs-isblank)
|
||||
- [String’s Maximum Length in Java](https://www.baeldung.com/java-strings-maximum-length)
|
||||
- [Java’s String.length() and String.getBytes().length](https://www.baeldung.com/java-string-length-vs-getbytes-length)
|
||||
- [Replace Non-Printable Unicode Characters in Java](https://www.baeldung.com/java-replace-non-printable-unicode-characters)
|
||||
- [Check If a Java StringBuilder Object Contains a Character](https://www.baeldung.com/java-check-stringbuilder-object-contains-character)
|
||||
- [UTF-8 Validation in Java](https://www.baeldung.com/java-utf-8-validation)
|
||||
|
|
|
@ -18,7 +18,7 @@ public class CheckIfStringContainsInvalidEncodedCharactersUnitTest {
|
|||
String regexPattern = "[^\\x00-\\x7F]+";
|
||||
Pattern pattern = Pattern.compile(regexPattern);
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
assertTrue(matcher.find() ? true : false);
|
||||
assertTrue(matcher.find());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -28,6 +28,6 @@ public class CheckIfStringContainsInvalidEncodedCharactersUnitTest {
|
|||
for (byte b : bytes) {
|
||||
found = (b & 0xFF) > 127 ? true : found;
|
||||
}
|
||||
assertTrue(found ? true : false);
|
||||
assertTrue(found);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,3 +8,4 @@ This module contains articles about the sun package
|
|||
- [Guide to sun.misc.Unsafe](http://www.baeldung.com/java-unsafe)
|
||||
- [Why Is sun.misc.Unsafe.park Actually Unsafe?](https://www.baeldung.com/java-sun-misc-unsafe-park-reason)
|
||||
- [Sharing Memory Between JVMs](https://www.baeldung.com/java-sharing-memory-between-jvms)
|
||||
- [Parse Java Source Code and Extract Methods](https://www.baeldung.com/java-parse-code-extract-methods)
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-java-string-swing</artifactId>
|
||||
<name>core-java-string-swing</name>
|
||||
<artifactId>core-java-swing</artifactId>
|
||||
<name>core-java-swing</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
|
|
|
@ -7,3 +7,4 @@ This module contains articles about the measurement of time in Java.
|
|||
- [Measure Elapsed Time in Java](http://www.baeldung.com/java-measure-elapsed-time)
|
||||
- [Overriding System Time for Testing in Java](https://www.baeldung.com/java-override-system-time)
|
||||
- [Java Timer](http://www.baeldung.com/java-timer-and-timertask)
|
||||
- [Java System.currentTimeMillis() Vs. System.nanoTime()](https://www.baeldung.com/java-system-currenttimemillis-vs-system-nanotime)
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
<module>core-java-datetime-string-2</module>
|
||||
<module>core-java-date-operations-2</module>
|
||||
<module>core-java-date-operations-3</module>
|
||||
<module>core-java-date-operations-4</module>
|
||||
<module>core-java-documentation</module>
|
||||
<module>core-java-exceptions</module>
|
||||
<module>core-java-exceptions-2</module>
|
||||
|
@ -199,6 +200,7 @@
|
|||
<module>core-java-string-operations-7</module>
|
||||
<module>core-java-regex</module>
|
||||
<module>core-java-regex-2</module>
|
||||
<module>core-java-regex-3</module>
|
||||
<module>core-java-uuid</module>
|
||||
<module>core-java-collections-maps-6</module>
|
||||
<module>core-java-records</module>
|
||||
|
@ -209,6 +211,7 @@
|
|||
<module>core-java-collections-set</module>
|
||||
<module>core-java-date-operations-1</module>
|
||||
<module>core-java-datetime-conversion</module>
|
||||
<module>core-java-datetime-conversion-2</module>
|
||||
<module>core-java-httpclient</module>
|
||||
<module>java-native</module>
|
||||
<module>java-rmi</module>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
</dependencyManagement>
|
||||
|
||||
<properties>
|
||||
<guava.version>32.1.3-jre</guava.version>
|
||||
<guava.version>33.0.0-jre</guava.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -49,7 +49,7 @@
|
|||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<guava.version>32.1.3-jre</guava.version>
|
||||
<guava.version>33.0.0-jre</guava.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -5,3 +5,4 @@ This module contains articles about JSON Conversions
|
|||
### Relevant Articles:
|
||||
- [Convert JSON Array to Java List](https://www.baeldung.com/java-convert-json-array-to-list)
|
||||
- [Reading JSON Documents as Maps and Comparing Them](https://www.baeldung.com/java-json-maps-comparison)
|
||||
- [Convert Byte Array to JSON and Vice Versa in Java](https://www.baeldung.com/java-json-byte-array-conversion)
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-boot-2</artifactId>
|
||||
<artifactId>parent-boot-3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../parent-boot-2</relativePath>
|
||||
<relativePath>../parent-boot-3</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -159,6 +159,11 @@
|
|||
<artifactId>ebean-api</artifactId>
|
||||
<version>${ebean.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
<version>${jakarta.xml.bind.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -290,22 +295,24 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<ebean.plugin.version>11.11.2</ebean.plugin.version>
|
||||
<ebean.plugin.version>13.25.2</ebean.plugin.version>
|
||||
<reladomo.version>18.1.0</reladomo.version>
|
||||
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
|
||||
<maven-antrun-plugin.version>1.8</maven-antrun-plugin.version>
|
||||
<ormlite.version>6.1</ormlite.version>
|
||||
<datanucleus.version>6.0.3</datanucleus.version>
|
||||
<datanucleus.version>6.0.6</datanucleus.version>
|
||||
<datanucleus-api.version>6.0.1</datanucleus-api.version>
|
||||
<datanucleus-maven-plugin.version>6.0.0-release</datanucleus-maven-plugin.version>
|
||||
<datanucleus-jdo-query.version>6.0.1</datanucleus-jdo-query.version>
|
||||
<javax.jdo.version>3.2.1</javax.jdo.version>
|
||||
<HikariCP.version>5.1.0</HikariCP.version>
|
||||
<ebean.version>13.15.2</ebean.version>
|
||||
<debezium.version>2.1.3.Final</debezium.version>
|
||||
<debezium.version>2.5.0.Final</debezium.version>
|
||||
<flexy-pool.version>2.2.3</flexy-pool.version>
|
||||
<testcontainers-version>1.17.6</testcontainers-version>
|
||||
<testcontainers-version>1.19.3</testcontainers-version>
|
||||
<mapdb.version>3.0.8</mapdb.version>
|
||||
<jakarta.xml.bind.version>4.0.1</jakarta.xml.bind.version>
|
||||
<spring-boot.repackage.skip>true</spring-boot.repackage.skip> <!-- to avoid repackaging of the jar -->
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -2,7 +2,7 @@ package com.baeldung.libraries.jdo;
|
|||
|
||||
import javax.jdo.annotations.PersistenceCapable;
|
||||
import javax.jdo.annotations.PrimaryKey;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import jakarta.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
@PersistenceCapable()
|
||||
public class ProductXML {
|
||||
|
|
|
@ -3,12 +3,13 @@ package com.baeldung.libraries.jdo.xml;
|
|||
import javax.jdo.annotations.Element;
|
||||
import javax.jdo.annotations.PersistenceCapable;
|
||||
import javax.jdo.annotations.PrimaryKey;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.xml.bind.annotation.XmlAttribute;
|
||||
import jakarta.xml.bind.annotation.XmlElement;
|
||||
import jakarta.xml.bind.annotation.XmlElementWrapper;
|
||||
|
||||
@PersistenceCapable(schema = "/myproduct/people", table = "person")
|
||||
public class AnnotadedPerson {
|
||||
@XmlAttribute
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
||||
.idea/
|
||||
target/
|
|
@ -0,0 +1,13 @@
|
|||
# Event Driven Microservices using Conductor
|
||||
|
||||
This is an example project showing how to build event driven applications using [Conductor](https://github.com/conductor-oss/conductor)
|
||||
|
||||
# Pre-requisites
|
||||
1. Docker
|
||||
2. Running conductor server
|
||||
|
||||
**Start the conductor server**
|
||||
|
||||
```shell
|
||||
docker run --init -p 8080:8080 -p 1234:5000 conductoross/conductor-standalone:3.15.0
|
||||
```
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<groupId>io.orkes.demo</groupId>
|
||||
<artifactId>event-driven-microservice</artifactId>
|
||||
<version>0.1</version>
|
||||
|
||||
<name>event-driven-microservice</name>
|
||||
<description>Demo Project for Orkes Conductor on Spring Boot</description>
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.orkes.conductor</groupId>
|
||||
<artifactId>orkes-conductor-client</artifactId>
|
||||
<version>${conductor.client.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${spring.webmvc.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<conductor.client.version>2.0.8</conductor.client.version>
|
||||
<spring.webmvc.version>2.1.0</spring.webmvc.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,28 @@
|
|||
package io.orkes.demo.banking;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.netflix.conductor.common.config.ObjectMapperProvider;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages = { "io.orkes" })
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
// ObjectMapper instance used for JSON serialization - can be modified to configure additional modules
|
||||
@Bean
|
||||
public ObjectMapper getObjectMapper() {
|
||||
return new ObjectMapperProvider().getObjectMapper();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package io.orkes.demo.banking.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import io.orkes.demo.banking.pojos.DepositDetail;
|
||||
import io.orkes.demo.banking.service.FraudCheckService;
|
||||
import io.orkes.demo.banking.service.WorkflowService;
|
||||
import io.orkes.demo.banking.workers.FraudCheckResult;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@RestController
|
||||
public class APIController {
|
||||
|
||||
private final FraudCheckService fraudCheckService;
|
||||
|
||||
private final WorkflowService workflowService;
|
||||
|
||||
@PostMapping(value = "/triggerDeposit", produces = "application/json")
|
||||
public ResponseEntity<FraudCheckResult> triggerDeposit(@RequestBody DepositDetail depositDetail) {
|
||||
log.info("Checking for fraud: {}", depositDetail);
|
||||
return ResponseEntity.ok(fraudCheckService.checkForFraud(depositDetail));
|
||||
}
|
||||
|
||||
// docs-marker-start-1
|
||||
@PostMapping(value = "/checkForFraud", produces = "application/json")
|
||||
public Map<String, Object> checkForFraud(@RequestBody DepositDetail depositDetail) throws Exception {
|
||||
log.info("Checking if fraud check is required for: {}", depositDetail);
|
||||
return workflowService.executeWorkflow(depositDetail);
|
||||
}
|
||||
|
||||
// docs-marker-end-1
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package io.orkes.demo.banking.pojos;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DepositDetail {
|
||||
|
||||
private String accountId;
|
||||
private BigDecimal amount;
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package io.orkes.demo.banking.service;
|
||||
|
||||
import static io.orkes.demo.banking.workers.FraudCheckResult.Result.FAIL;
|
||||
import static io.orkes.demo.banking.workers.FraudCheckResult.Result.PASS;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import io.orkes.demo.banking.pojos.DepositDetail;
|
||||
import io.orkes.demo.banking.workers.FraudCheckResult;
|
||||
|
||||
@Service
|
||||
public class FraudCheckService {
|
||||
|
||||
public FraudCheckResult checkForFraud(DepositDetail depositDetail) {
|
||||
FraudCheckResult fcr = new FraudCheckResult();
|
||||
if (depositDetail.getAmount()
|
||||
.compareTo(BigDecimal.valueOf(100000)) > 0) {
|
||||
fcr.setResult(FAIL);
|
||||
fcr.setReason("Amount too large");
|
||||
} else {
|
||||
fcr.setResult(PASS);
|
||||
fcr.setReason("All good!");
|
||||
}
|
||||
return fcr;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package io.orkes.demo.banking.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.netflix.conductor.common.metadata.workflow.StartWorkflowRequest;
|
||||
|
||||
import io.orkes.conductor.client.WorkflowClient;
|
||||
import io.orkes.conductor.common.model.WorkflowRun;
|
||||
import io.orkes.demo.banking.pojos.DepositDetail;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@Service
|
||||
public class WorkflowService {
|
||||
|
||||
private final WorkflowClient workflowClient;
|
||||
|
||||
/**
|
||||
* Starts the workflow execution asynchronously
|
||||
* @param depositDetail
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Object> startDepositWorkflow(DepositDetail depositDetail) {
|
||||
StartWorkflowRequest request = new StartWorkflowRequest();
|
||||
request.setName("microservice_orchestration");
|
||||
Map<String, Object> inputData = new HashMap<>();
|
||||
inputData.put("amount", depositDetail.getAmount());
|
||||
inputData.put("accountId", depositDetail.getAccountId());
|
||||
request.setInput(inputData);
|
||||
|
||||
String workflowId = workflowClient.startWorkflow(request);
|
||||
log.info("Workflow id: {}", workflowId);
|
||||
return Map.of("workflowId", workflowId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the workflow, waits for it to complete and returns the output of the workflow
|
||||
* @param depositDetail
|
||||
* @return
|
||||
* @throws ExecutionException
|
||||
* @throws InterruptedException
|
||||
* @throws TimeoutException
|
||||
*/
|
||||
public Map<String, Object> executeWorkflow(DepositDetail depositDetail) throws ExecutionException, InterruptedException, TimeoutException {
|
||||
StartWorkflowRequest request = new StartWorkflowRequest();
|
||||
request.setName("microservice_orchestration");
|
||||
request.setVersion(1);
|
||||
Map<String, Object> inputData = new HashMap<>();
|
||||
inputData.put("amount", depositDetail.getAmount());
|
||||
inputData.put("accountId", depositDetail.getAccountId());
|
||||
request.setInput(inputData);
|
||||
|
||||
CompletableFuture<WorkflowRun> workflowRun = workflowClient.executeWorkflow(request, UUID.randomUUID()
|
||||
.toString(), 10);
|
||||
log.info("Workflow id: {}", workflowRun);
|
||||
|
||||
return workflowRun.get(10, TimeUnit.SECONDS)
|
||||
.getOutput();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package io.orkes.demo.banking.workers;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.netflix.conductor.sdk.workflow.task.InputParam;
|
||||
import com.netflix.conductor.sdk.workflow.task.WorkerTask;
|
||||
|
||||
import io.orkes.demo.banking.pojos.DepositDetail;
|
||||
import io.orkes.demo.banking.service.FraudCheckService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ConductorWorkers {
|
||||
|
||||
private final FraudCheckService fraudCheckService;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param amount
|
||||
* @return Given the amount, the service check if the fraud check should done before executing the transaction
|
||||
*/
|
||||
@WorkerTask(value = "fraud-check-required")
|
||||
public FraudCheckResult simpleWorker(@InputParam("amount") BigDecimal amount) {
|
||||
DepositDetail dd = new DepositDetail();
|
||||
dd.setAmount(amount);
|
||||
return fraudCheckService.checkForFraud(dd);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package io.orkes.demo.banking.workers;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FraudCheckResult {
|
||||
|
||||
public enum Result {
|
||||
PASS,
|
||||
FAIL;
|
||||
}
|
||||
|
||||
private Result result;
|
||||
private String reason;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
# swagger-ui custom path
|
||||
springdoc.swagger-ui.path=/swagger-ui.html
|
||||
management.endpoints.enabled-by-default=false
|
||||
management.endpoint.info.enabled=false
|
||||
server.port=8081
|
||||
# If you want to use Orkes Playground, then change the server url to https://play.orkes.io/api/
|
||||
# Obtain key and secret by logging into
|
||||
# and navigating to applications menu, create an application and generate key/secret
|
||||
conductor.security.client.key-id=CHANGE_ME
|
||||
conductor.security.client.secret=CHANGE_ME
|
||||
conductor.server.url=https://play.orkes.io/api/
|
|
@ -0,0 +1,14 @@
|
|||
package io.orkes.demo.banking;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class ApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<code_scheme name="baeldung-formatter" version="173">
|
||||
<option name="RIGHT_MARGIN" value="260"/>
|
||||
<option name="FORMATTER_TAGS_ENABLED" value="true"/>
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="SPACE_AFTER_CLOSING_ANGLE_BRACKET_IN_TYPE_ARGUMENT" value="true"/>
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="100"/>
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="100"/>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="" withSubpackages="true" static="true"/>
|
||||
<emptyLine/>
|
||||
<package name="java" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="javax" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="org" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="com" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="false"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ENABLE_JAVADOC_FORMATTING" value="false"/>
|
||||
</JavaCodeStyleSettings>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="RIGHT_MARGIN" value="160"/>
|
||||
<option name="KEEP_LINE_BREAKS" value="false"/>
|
||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false"/>
|
||||
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
|
||||
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
|
||||
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1"/>
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
|
||||
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true"/>
|
||||
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true"/>
|
||||
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
|
||||
<option name="CALL_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
|
||||
<option name="RESOURCE_LIST_WRAP" value="5"/>
|
||||
<option name="EXTENDS_LIST_WRAP" value="1"/>
|
||||
<option name="THROWS_LIST_WRAP" value="1"/>
|
||||
<option name="EXTENDS_KEYWORD_WRAP" value="1"/>
|
||||
<option name="THROWS_KEYWORD_WRAP" value="1"/>
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="2"/>
|
||||
<option name="BINARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="TERNARY_OPERATION_WRAP" value="1"/>
|
||||
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true"/>
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="1"/>
|
||||
<option name="IF_BRACE_FORCE" value="3"/>
|
||||
<option name="DOWHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="WHILE_BRACE_FORCE" value="3"/>
|
||||
<option name="FOR_BRACE_FORCE" value="3"/>
|
||||
<option name="ENUM_CONSTANTS_WRAP" value="2"/>
|
||||
<option name="KEEP_BUILDER_METHODS_INDENTS" value="true"/>
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
|
||||
<option name="SMART_TABS" value="true"/>
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<groups/>
|
||||
<rules/>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
|
@ -22,6 +22,7 @@
|
|||
<module>msf4j</module>
|
||||
<module>open-liberty</module>
|
||||
<module>rest-express</module>
|
||||
<module>event-driven-microservice</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
|
@ -2,3 +2,4 @@
|
|||
- [Memento Design Pattern in Java](https://www.baeldung.com/java-memento-design-pattern)
|
||||
- [Difference Between Fluent Interface and Builder Pattern in Java](https://www.baeldung.com/java-fluent-interface-vs-builder-pattern)
|
||||
- [Smart Batching in Java](https://www.baeldung.com/java-smart-batching)
|
||||
- [Convert Null Value to a Default Value in Java](https://www.baeldung.com/java-convert-null-default-value)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.builder.inheritance.withgenerics;
|
||||
|
||||
public class Car extends Vehicle {
|
||||
|
||||
private String make;
|
||||
private String model;
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public Car(Builder builder) {
|
||||
super(builder);
|
||||
this.make = builder.make;
|
||||
this.model = builder.model;
|
||||
}
|
||||
|
||||
public String getMake() {
|
||||
return make;
|
||||
}
|
||||
|
||||
public static class Builder<T extends Builder<T>> extends Vehicle.Builder<T> {
|
||||
|
||||
protected String make;
|
||||
protected String model;
|
||||
|
||||
public T make(String make) {
|
||||
this.make = make;
|
||||
return self();
|
||||
}
|
||||
|
||||
public T model(String model) {
|
||||
this.model = model;
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Car build() {
|
||||
return new Car(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.builder.inheritance.withgenerics;
|
||||
|
||||
public class ElectricCar extends Car {
|
||||
private String batteryType;
|
||||
|
||||
public String getBatteryType() {
|
||||
return batteryType;
|
||||
}
|
||||
|
||||
public ElectricCar(Builder builder) {
|
||||
super(builder);
|
||||
this.batteryType = builder.batteryType;
|
||||
}
|
||||
|
||||
public static class Builder<T extends Builder<T>> extends Car.Builder<T> {
|
||||
protected String batteryType;
|
||||
|
||||
public T batteryType(String batteryType) {
|
||||
this.batteryType = batteryType;
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElectricCar build() {
|
||||
return new ElectricCar(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.baeldung.builder.inheritance.withgenerics;
|
||||
|
||||
public class Vehicle {
|
||||
|
||||
private String colour;
|
||||
private String fuelType;
|
||||
|
||||
public Vehicle(Builder builder) {
|
||||
this.colour = builder.colour;
|
||||
this.fuelType = builder.fuelType;
|
||||
}
|
||||
|
||||
public String getColour() {
|
||||
return colour;
|
||||
}
|
||||
|
||||
public String getFuelType() {
|
||||
return fuelType;
|
||||
}
|
||||
|
||||
public static class Builder<T extends Builder> {
|
||||
|
||||
protected String colour;
|
||||
protected String fuelType;
|
||||
|
||||
T self() {
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public T colour(String colour) {
|
||||
this.colour = colour;
|
||||
return self();
|
||||
}
|
||||
|
||||
public T fuelType(String fuelType) {
|
||||
this.fuelType = fuelType;
|
||||
return self();
|
||||
}
|
||||
|
||||
public Vehicle build() {
|
||||
return new Vehicle(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.baeldung.builder.inheritance.withoutgenerics;
|
||||
|
||||
public class Car extends Vehicle {
|
||||
|
||||
private String make;
|
||||
private String model;
|
||||
|
||||
public String getMake() {
|
||||
return make;
|
||||
}
|
||||
|
||||
public String getModel() {
|
||||
return model;
|
||||
}
|
||||
|
||||
public Car(CarBuilder builder) {
|
||||
super(builder);
|
||||
this.make = builder.make;
|
||||
this.model = builder.model;
|
||||
}
|
||||
|
||||
public static class CarBuilder extends VehicleBuilder {
|
||||
|
||||
protected String make;
|
||||
protected String model;
|
||||
|
||||
@Override
|
||||
public CarBuilder colour(String colour) {
|
||||
this.colour = colour;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CarBuilder fuelType(String fuelType) {
|
||||
this.fuelType = fuelType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CarBuilder make(String make) {
|
||||
this.make = make;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CarBuilder model(String model) {
|
||||
this.model = model;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Car build() {
|
||||
return new Car(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.builder.inheritance.withoutgenerics;
|
||||
|
||||
public class Vehicle {
|
||||
|
||||
private String fuelType;
|
||||
private String colour;
|
||||
|
||||
public String getFuelType() {
|
||||
return fuelType;
|
||||
}
|
||||
|
||||
public String getColour() {
|
||||
return colour;
|
||||
}
|
||||
|
||||
public Vehicle(VehicleBuilder builder) {
|
||||
this.colour = builder.colour;
|
||||
this.fuelType = builder.fuelType;
|
||||
|
||||
}
|
||||
|
||||
public static class VehicleBuilder {
|
||||
|
||||
protected String fuelType;
|
||||
protected String colour;
|
||||
|
||||
public VehicleBuilder fuelType(String fuelType) {
|
||||
this.fuelType = fuelType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VehicleBuilder colour(String colour) {
|
||||
this.colour = colour;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vehicle build() {
|
||||
return new Vehicle(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
@startuml
|
||||
'https://plantuml.com/class-diagram
|
||||
'skinparam Handwritten true
|
||||
skinparam ClassBorderColor black/#63b175
|
||||
skinparam BackgroundColor #fdf8f6
|
||||
skinparam class {
|
||||
ArrowColor #63b175
|
||||
}
|
||||
|
||||
hide empty methods
|
||||
hide empty attributes
|
||||
|
||||
class Vehicle {
|
||||
+fuelType : String
|
||||
+colour : String
|
||||
}
|
||||
|
||||
class VehicleBuilder {
|
||||
+fuelType : String
|
||||
+colour : String
|
||||
+build() : Vehicle
|
||||
+fuelType(String fuelType) : VehicleBuilder
|
||||
+colour(String colour) : VehicleBuilder
|
||||
}
|
||||
class Car {
|
||||
+make : String
|
||||
+model : String
|
||||
}
|
||||
class CarBuilder {
|
||||
+make : String
|
||||
+model : String
|
||||
+build() : Car
|
||||
+make(String make): CarBuilder
|
||||
+model(String make): CarBuilder
|
||||
}
|
||||
|
||||
class ElectricCar {
|
||||
+batteryType : String
|
||||
|
||||
}
|
||||
|
||||
class ElectricCarBuilder {
|
||||
+batteryType : String
|
||||
+build() : ElectricCar
|
||||
+batteryType(String batteryType): ElectricCarBuilder
|
||||
}
|
||||
CarBuilder -left-|> VehicleBuilder: extends
|
||||
ElectricCarBuilder -left-|> CarBuilder: extends
|
||||
VehicleBuilder -down-> Vehicle: builds
|
||||
CarBuilder -down-> Car:builds
|
||||
ElectricCarBuilder -down-> ElectricCar: builds
|
||||
|
||||
Vehicle <|-right- Car: extends
|
||||
Car <|-right- ElectricCar: extends
|
||||
|
||||
@enduml
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.builder.inheritance.withoutgenerics;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class BuilderInheritanceUnitTest {
|
||||
|
||||
@Test
|
||||
void givenNonGenericImpl_whenBuild_thenReturnObject() {
|
||||
Car car = new Car.CarBuilder().colour("red")
|
||||
.fuelType("Petrol")
|
||||
.make("Ford")
|
||||
.model("F")
|
||||
.build();
|
||||
assertEquals("red", car.getColour());
|
||||
assertEquals("Ford", car.getMake());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baledung.builder.inheritance.withgenerics;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.baeldung.builder.inheritance.withgenerics.Car;
|
||||
import com.baeldung.builder.inheritance.withgenerics.ElectricCar;
|
||||
|
||||
public class BuilderInheritanceUnitTest {
|
||||
|
||||
@Test
|
||||
void givenGenericImpl_whenBuild_thenReturnObject() {
|
||||
Car.Builder<?> carBuilder1 = new Car.Builder();
|
||||
Car car = carBuilder1.colour("red")
|
||||
.fuelType("Petrol")
|
||||
.make("Ford")
|
||||
.model("F")
|
||||
.build();
|
||||
|
||||
ElectricCar.Builder<?> ElectricCarBuilder = new ElectricCar.Builder();
|
||||
ElectricCar eCar = ElectricCarBuilder.make("Mercedes")
|
||||
.colour("White")
|
||||
.model("G")
|
||||
.fuelType("Electric")
|
||||
.batteryType("Lithium")
|
||||
.build();
|
||||
|
||||
assertEquals("red", car.getColour());
|
||||
assertEquals("Ford", car.getMake());
|
||||
|
||||
assertEquals("Electric", eCar.getFuelType());
|
||||
assertEquals("Lithium", eCar.getBatteryType());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
### Relevant Articles:
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>monkey-patching</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<name>monkey-patching</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>patterns-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.monkey.patching;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.monkey.patching.aop;
|
||||
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverter;
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverterImpl;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class BeanConfiguration {
|
||||
|
||||
@Bean
|
||||
public MoneyConverter moneyConverter() {
|
||||
return new MoneyConverterImpl();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.monkey.patching.aop;
|
||||
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.After;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class LoggingAspect {
|
||||
|
||||
@Before("execution(* com.baeldung.monkey.patching.converter.MoneyConverter.convertEURtoUSD(..))")
|
||||
public void beforeConvertEURtoUSD(JoinPoint joinPoint) {
|
||||
System.out.println("Before method: " + joinPoint.getSignature().getName());
|
||||
}
|
||||
|
||||
@After("execution(* com.baeldung.monkey.patching.converter.MoneyConverter.convertEURtoUSD(..))")
|
||||
public void afterConvertEURtoUSD(JoinPoint joinPoint) {
|
||||
System.out.println("After method: " + joinPoint.getSignature().getName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.baeldung.monkey.patching.converter;
|
||||
|
||||
public interface MoneyConverter {
|
||||
double convertEURtoUSD(double amount);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.monkey.patching.converter;
|
||||
|
||||
public class MoneyConverterImpl implements MoneyConverter {
|
||||
|
||||
private final double conversionRate;
|
||||
|
||||
public MoneyConverterImpl() {
|
||||
this.conversionRate = 1.10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double convertEURtoUSD(double amount) {
|
||||
return amount * conversionRate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.monkey.patching.decorator;
|
||||
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverter;
|
||||
|
||||
public class MoneyConverterDecorator implements MoneyConverter {
|
||||
|
||||
private final MoneyConverter moneyConverter;
|
||||
|
||||
public MoneyConverterDecorator(MoneyConverter moneyConverter) {
|
||||
this.moneyConverter = moneyConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double convertEURtoUSD(double amount) {
|
||||
|
||||
System.out.println("Before method: convertEURtoUSD");
|
||||
double result = moneyConverter.convertEURtoUSD(amount);
|
||||
System.out.println("After method: convertEURtoUSD");
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.monkey.patching.proxy;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class LoggingInvocationHandler implements InvocationHandler {
|
||||
|
||||
private final Object target;
|
||||
|
||||
public LoggingInvocationHandler(Object target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
System.out.println("Before method: " + method.getName());
|
||||
Object result = method.invoke(target, args);
|
||||
System.out.println("After method: " + method.getName());
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.monkey.patching.aop;
|
||||
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverter;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@SpringBootTest
|
||||
@RunWith(SpringRunner.class)
|
||||
public class LoggingAspectIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MoneyConverter moneyConverter;
|
||||
|
||||
@Test
|
||||
public void whenMethodCalled_thenSurroundedByLogs() {
|
||||
ByteArrayOutputStream logOutputStream = new ByteArrayOutputStream();
|
||||
System.setOut(new PrintStream(logOutputStream));
|
||||
|
||||
double result = moneyConverter.convertEURtoUSD(10);
|
||||
|
||||
Assertions.assertEquals(11, result);
|
||||
String logOutput = logOutputStream.toString();
|
||||
assertTrue(logOutput.contains("Before method: convertEURtoUSD"));
|
||||
assertTrue(logOutput.contains("After method: convertEURtoUSD"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.monkey.patching.converter;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
class MoneyConverterUnitTest {
|
||||
|
||||
@Test
|
||||
void whenMoneyConverter_thenResultIsCorrect() {
|
||||
MoneyConverterImpl moneyConverter = new MoneyConverterImpl();
|
||||
|
||||
double result = moneyConverter.convertEURtoUSD(10);
|
||||
|
||||
assertEquals(11, result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.monkey.patching.decorator;
|
||||
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverter;
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverterImpl;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class MoneyConverterDecoratorUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenMethodCalled_thenSurroundedByLogs() {
|
||||
ByteArrayOutputStream logOutputStream = new ByteArrayOutputStream();
|
||||
System.setOut(new PrintStream(logOutputStream));
|
||||
MoneyConverter moneyConverter = new MoneyConverterDecorator(new MoneyConverterImpl());
|
||||
|
||||
double result = moneyConverter.convertEURtoUSD(10);
|
||||
|
||||
Assertions.assertEquals(11, result);
|
||||
String logOutput = logOutputStream.toString();
|
||||
assertTrue(logOutput.contains("Before method: convertEURtoUSD"));
|
||||
assertTrue(logOutput.contains("After method: convertEURtoUSD"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.baeldung.monkey.patching.proxy;
|
||||
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverter;
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverterImpl;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class LoggingInvocationHandlerUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenMethodCalled_thenSurroundedByLogs() {
|
||||
ByteArrayOutputStream logOutputStream = new ByteArrayOutputStream();
|
||||
System.setOut(new PrintStream(logOutputStream));
|
||||
MoneyConverter moneyConverter = new MoneyConverterImpl();
|
||||
MoneyConverter proxy = (MoneyConverter) Proxy.newProxyInstance(
|
||||
MoneyConverter.class.getClassLoader(),
|
||||
new Class[]{MoneyConverter.class},
|
||||
new LoggingInvocationHandler(moneyConverter)
|
||||
);
|
||||
|
||||
double result = proxy.convertEURtoUSD(10);
|
||||
|
||||
Assertions.assertEquals(11, result);
|
||||
String logOutput = logOutputStream.toString();
|
||||
assertTrue(logOutput.contains("Before method: convertEURtoUSD"));
|
||||
assertTrue(logOutput.contains("After method: convertEURtoUSD"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.monkey.patching.reflection;
|
||||
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverter;
|
||||
import com.baeldung.monkey.patching.converter.MoneyConverterImpl;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class ReflectionUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenPrivateField_whenUsingReflection_thenBehaviorCanBeChanged() throws IllegalAccessException, NoSuchFieldException {
|
||||
MoneyConverter moneyConvertor = new MoneyConverterImpl();
|
||||
|
||||
Field conversionRate = MoneyConverterImpl.class.getDeclaredField("conversionRate");
|
||||
conversionRate.setAccessible(true);
|
||||
conversionRate.set(moneyConvertor, 1.2);
|
||||
double result = moneyConvertor.convertEURtoUSD(10);
|
||||
|
||||
assertEquals(12, result);
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@
|
|||
<module>idd</module>
|
||||
<module>intercepting-filter</module>
|
||||
<module>solid</module>
|
||||
<module>monkey-patching</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -7,3 +7,4 @@
|
|||
- [EntityNotFoundException in Hibernate](https://www.baeldung.com/hibernate-entitynotfoundexception)
|
||||
- [Hibernate’s “Not-Null Property References a Null or Transient Value” Error](https://www.baeldung.com/hibernate-not-null-error)
|
||||
- [Hibernate’s “Detached Entity Passed to Persist” Error](https://www.baeldung.com/hibernate-detached-entity-passed-to-persist)
|
||||
- [Fixing Hibernate QueryException: Named Parameter Not Bound](https://www.baeldung.com/hibernate-queryexception-named-parameter-not-bound-fix)
|
||||
|
|
|
@ -97,8 +97,6 @@
|
|||
<module>spring-data-mongodb-2</module>
|
||||
<module>spring-data-mongodb-reactive</module>
|
||||
<module>spring-data-redis</module>
|
||||
<!-- Moved to JDK9+ profiles-->
|
||||
<!-- <module>spring-data-rest</module>-->
|
||||
<module>spring-data-rest-2</module>
|
||||
<module>spring-data-rest-querydsl</module>
|
||||
<module>spring-data-solr</module>
|
||||
|
|
|
@ -57,11 +57,6 @@
|
|||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -81,7 +76,6 @@
|
|||
<db.util.version>1.0.7</db.util.version>
|
||||
<hypersistence-utils.version>3.7.0</hypersistence-utils.version>
|
||||
<jackson.version>2.16.0</jackson.version>
|
||||
<lombok.version>1.18.28</lombok.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -50,7 +50,7 @@ public class Service<S> extends ParametrizationAware<S> {
|
|||
public int getUserByIdWithFunction(Long id, ToIntFunction<S> function) {
|
||||
|
||||
Optional<S> optionalUser = repository.findById(id);
|
||||
if(optionalUser.isPresent()) {
|
||||
if (optionalUser.isPresent()) {
|
||||
return function.applyAsInt(optionalUser.get());
|
||||
} else {
|
||||
return 0;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue