diff --git a/algorithms-miscellaneous-3/README.md b/algorithms-miscellaneous-3/README.md index 4dd4b66ff2..7a83a97c5b 100644 --- a/algorithms-miscellaneous-3/README.md +++ b/algorithms-miscellaneous-3/README.md @@ -4,3 +4,4 @@ - [Implementing Simple State Machines with Java Enums](https://www.baeldung.com/java-enum-simple-state-machine) - [Converting Between Roman and Arabic Numerals in Java](http://www.baeldung.com/java-convert-roman-arabic) - [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity) +- [Checking If a List Is Sorted in Java](https://www.baeldung.com/java-check-if-list-sorted) diff --git a/algorithms-miscellaneous-3/pom.xml b/algorithms-miscellaneous-3/pom.xml index c4017144c8..3cebdd09ac 100644 --- a/algorithms-miscellaneous-3/pom.xml +++ b/algorithms-miscellaneous-3/pom.xml @@ -18,6 +18,18 @@ ${org.assertj.core.version} test + + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + + + + com.google.guava + guava + ${guava.version} + @@ -34,6 +46,7 @@ 3.9.0 + 4.3 + 28.0-jre - \ No newline at end of file diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/Employee.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/Employee.java new file mode 100644 index 0000000000..796932728b --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/Employee.java @@ -0,0 +1,34 @@ +package com.baeldung.algorithms.checksortedlist; + +public class Employee { + + long id; + + String name; + + public Employee() { + } + + public Employee(long id, String name) { + super(); + this.id = id; + this.name = name; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/SortedListChecker.java b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/SortedListChecker.java new file mode 100644 index 0000000000..ab6eb6bc14 --- /dev/null +++ b/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/checksortedlist/SortedListChecker.java @@ -0,0 +1,87 @@ +package com.baeldung.algorithms.checksortedlist; + +import static org.apache.commons.collections4.CollectionUtils.isEmpty; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import com.google.common.collect.Comparators; +import com.google.common.collect.Ordering;; + +public class SortedListChecker { + + private SortedListChecker() { + throw new AssertionError(); + } + + public static boolean checkIfSortedUsingIterativeApproach(List listOfStrings) { + if (isEmpty(listOfStrings) || listOfStrings.size() == 1) { + return true; + } + + Iterator iter = listOfStrings.iterator(); + String current, previous = iter.next(); + while (iter.hasNext()) { + current = iter.next(); + if (previous.compareTo(current) > 0) { + return false; + } + previous = current; + } + return true; + } + + public static boolean checkIfSortedUsingIterativeApproach(List employees, Comparator employeeComparator) { + if (isEmpty(employees) || employees.size() == 1) { + return true; + } + + Iterator iter = employees.iterator(); + Employee current, previous = iter.next(); + while (iter.hasNext()) { + current = iter.next(); + if (employeeComparator.compare(previous, current) > 0) { + return false; + } + previous = current; + } + return true; + } + + public static boolean checkIfSortedUsingRecursion(List listOfStrings) { + return isSortedRecursive(listOfStrings, listOfStrings.size()); + } + + public static boolean isSortedRecursive(List listOfStrings, int index) { + if (index < 2) { + return true; + } else if (listOfStrings.get(index - 2) + .compareTo(listOfStrings.get(index - 1)) > 0) { + return false; + } else { + return isSortedRecursive(listOfStrings, index - 1); + } + } + + public static boolean checkIfSortedUsingOrderingClass(List listOfStrings) { + return Ordering. natural() + .isOrdered(listOfStrings); + } + + public static boolean checkIfSortedUsingOrderingClass(List employees, Comparator employeeComparator) { + return Ordering.from(employeeComparator) + .isOrdered(employees); + } + + public static boolean checkIfSortedUsingOrderingClassHandlingNull(List listOfStrings) { + return Ordering. natural() + .nullsLast() + .isOrdered(listOfStrings); + } + + public static boolean checkIfSortedUsingComparators(List listOfStrings) { + return Comparators.isInOrder(listOfStrings, Comparator. naturalOrder()); + } + +} diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/checksortedlist/SortedListCheckerUnitTest.java b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/checksortedlist/SortedListCheckerUnitTest.java new file mode 100644 index 0000000000..44c4388e6c --- /dev/null +++ b/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/checksortedlist/SortedListCheckerUnitTest.java @@ -0,0 +1,106 @@ +package com.baeldung.algorithms.checksortedlist; + +import static com.baeldung.algorithms.checksortedlist.SortedListChecker.checkIfSortedUsingComparators; +import static com.baeldung.algorithms.checksortedlist.SortedListChecker.checkIfSortedUsingIterativeApproach; +import static com.baeldung.algorithms.checksortedlist.SortedListChecker.checkIfSortedUsingOrderingClass; +import static com.baeldung.algorithms.checksortedlist.SortedListChecker.checkIfSortedUsingRecursion; +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +public class SortedListCheckerUnitTest { + + private List sortedListOfString; + private List unsortedListOfString; + private List singletonList; + + private List employeesSortedByName; + private List employeesNotSortedByName; + + @Before + public void setUp() { + sortedListOfString = asList("Canada", "HK", "LA", "NJ", "NY"); + unsortedListOfString = asList("LA", "HK", "NJ", "NY", "Canada"); + singletonList = Collections.singletonList("NY"); + + employeesSortedByName = asList(new Employee(1L, "John"), new Employee(2L, "Kevin"), new Employee(3L, "Mike")); + employeesNotSortedByName = asList(new Employee(1L, "Kevin"), new Employee(2L, "John"), new Employee(3L, "Mike")); + } + + @Test + public void givenSortedList_whenUsingIterativeApproach_thenReturnTrue() { + assertThat(checkIfSortedUsingIterativeApproach(sortedListOfString)).isTrue(); + } + + @Test + public void givenSingleElementList_whenUsingIterativeApproach_thenReturnTrue() { + assertThat(checkIfSortedUsingIterativeApproach(singletonList)).isTrue(); + } + + @Test + public void givenUnsortedList_whenUsingIterativeApproach_thenReturnFalse() { + assertThat(checkIfSortedUsingIterativeApproach(unsortedListOfString)).isFalse(); + } + + @Test + public void givenSortedListOfEmployees_whenUsingIterativeApproach_thenReturnTrue() { + assertThat(checkIfSortedUsingIterativeApproach(employeesSortedByName, Comparator.comparing(Employee::getName))).isTrue(); + } + + @Test + public void givenUnsortedListOfEmployees_whenUsingIterativeApproach_thenReturnFalse() { + assertThat(checkIfSortedUsingIterativeApproach(employeesNotSortedByName, Comparator.comparing(Employee::getName))).isFalse(); + } + + @Test + public void givenSortedList_whenUsingRecursion_thenReturnTrue() { + assertThat(checkIfSortedUsingRecursion(sortedListOfString)).isTrue(); + } + + @Test + public void givenSingleElementList_whenUsingRecursion_thenReturnTrue() { + assertThat(checkIfSortedUsingRecursion(singletonList)).isTrue(); + } + + @Test + public void givenUnsortedList_whenUsingRecursion_thenReturnFalse() { + assertThat(checkIfSortedUsingRecursion(unsortedListOfString)).isFalse(); + } + + @Test + public void givenSortedList_whenUsingGuavaOrdering_thenReturnTrue() { + assertThat(checkIfSortedUsingOrderingClass(sortedListOfString)).isTrue(); + } + + @Test + public void givenUnsortedList_whenUsingGuavaOrdering_thenReturnFalse() { + assertThat(checkIfSortedUsingOrderingClass(unsortedListOfString)).isFalse(); + } + + @Test + public void givenSortedListOfEmployees_whenUsingGuavaOrdering_thenReturnTrue() { + assertThat(checkIfSortedUsingOrderingClass(employeesSortedByName, Comparator.comparing(Employee::getName))).isTrue(); + } + + @Test + public void givenUnsortedListOfEmployees_whenUsingGuavaOrdering_thenReturnFalse() { + assertThat(checkIfSortedUsingOrderingClass(employeesNotSortedByName, Comparator.comparing(Employee::getName))).isFalse(); + } + + @Test + public void givenSortedList_whenUsingGuavaComparators_thenReturnTrue() { + assertThat(checkIfSortedUsingComparators(sortedListOfString)).isTrue(); + } + + @Test + public void givenUnsortedList_whenUsingGuavaComparators_thenReturnFalse() { + assertThat(checkIfSortedUsingComparators(unsortedListOfString)).isFalse(); + } + +} diff --git a/autovalue/pom.xml b/autovalue/pom.xml index 3ec2d26b35..a10e8ef055 100644 --- a/autovalue/pom.xml +++ b/autovalue/pom.xml @@ -29,6 +29,12 @@ + + com.google.auto.service + auto-service + ${auto-service.version} + true + com.google.inject @@ -40,6 +46,7 @@ 1.3 1.0-beta5 + 1.0-rc5 4.2.0 diff --git a/autovalue/src/main/java/com/baeldung/autoservice/BingTranslationServiceProvider.java b/autovalue/src/main/java/com/baeldung/autoservice/BingTranslationServiceProvider.java new file mode 100644 index 0000000000..86d42e80fa --- /dev/null +++ b/autovalue/src/main/java/com/baeldung/autoservice/BingTranslationServiceProvider.java @@ -0,0 +1,14 @@ +package com.baeldung.autoservice; + +import com.google.auto.service.AutoService; + +import java.util.Locale; + +@AutoService(TranslationService.class) +public class BingTranslationServiceProvider implements TranslationService { + @Override + public String translate(String message, Locale from, Locale to) { + // implementation details + return message + " (translated by Bing)"; + } +} diff --git a/autovalue/src/main/java/com/baeldung/autoservice/GoogleTranslationServiceProvider.java b/autovalue/src/main/java/com/baeldung/autoservice/GoogleTranslationServiceProvider.java new file mode 100644 index 0000000000..0bf91ee5ec --- /dev/null +++ b/autovalue/src/main/java/com/baeldung/autoservice/GoogleTranslationServiceProvider.java @@ -0,0 +1,14 @@ +package com.baeldung.autoservice; + +import com.google.auto.service.AutoService; + +import java.util.Locale; + +@AutoService(TranslationService.class) +public class GoogleTranslationServiceProvider implements TranslationService { + @Override + public String translate(String message, Locale from, Locale to) { + // implementation details + return message + " (translated by Google)"; + } +} diff --git a/autovalue/src/main/java/com/baeldung/autoservice/TranslationService.java b/autovalue/src/main/java/com/baeldung/autoservice/TranslationService.java new file mode 100644 index 0000000000..580db46cd1 --- /dev/null +++ b/autovalue/src/main/java/com/baeldung/autoservice/TranslationService.java @@ -0,0 +1,7 @@ +package com.baeldung.autoservice; + +import java.util.Locale; + +public interface TranslationService { + String translate(String message, Locale from, Locale to); +} \ No newline at end of file diff --git a/autovalue/src/test/java/com/baeldung/autoservice/TranslationServiceUnitTest.java b/autovalue/src/test/java/com/baeldung/autoservice/TranslationServiceUnitTest.java new file mode 100644 index 0000000000..9e1bd6d291 --- /dev/null +++ b/autovalue/src/test/java/com/baeldung/autoservice/TranslationServiceUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.autoservice; + +import com.baeldung.autoservice.TranslationService; +import org.junit.Before; +import org.junit.Test; + +import java.util.ServiceLoader; +import java.util.stream.StreamSupport; + +import static org.junit.Assert.assertEquals; + +public class TranslationServiceUnitTest { + + private ServiceLoader loader; + + @Before + public void setUp() { + loader = ServiceLoader.load(TranslationService.class); + } + + @Test + public void whenServiceLoaderLoads_thenLoadsAllProviders() { + long count = StreamSupport.stream(loader.spliterator(), false).count(); + assertEquals(2, count); + } + + @Test + public void whenServiceLoaderLoadsGoogleService_thenGoogleIsLoaded() { + TranslationService googleService = StreamSupport.stream(loader.spliterator(), false) + .filter(p -> p.getClass().getSimpleName().equals("GoogleTranslationServiceProvider")) + .findFirst() + .get(); + + String message = "message"; + assertEquals(message + " (translated by Google)", googleService.translate(message, null, null)); + } +} \ No newline at end of file diff --git a/core-groovy-2/README.md b/core-groovy-2/README.md index 1d35669cd7..d6fc6fc2f7 100644 --- a/core-groovy-2/README.md +++ b/core-groovy-2/README.md @@ -5,4 +5,5 @@ - [String Matching in Groovy](http://www.baeldung.com/) - [Template Engines in Groovy](https://www.baeldung.com/groovy-template-engines) - [Groovy def Keyword](https://www.baeldung.com/groovy-def-keyword) -- [Pattern Matching in Strings in Groovy](https://www.baeldung.com/groovy-pattern-matching) \ No newline at end of file +- [Pattern Matching in Strings in Groovy](https://www.baeldung.com/groovy-pattern-matching) +- [Working with XML in Groovy](https://www.baeldung.com/groovy-xml) \ No newline at end of file diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/forEach/ReverseList.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/forEach/ReverseList.java new file mode 100644 index 0000000000..b2ce77a9f6 --- /dev/null +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/forEach/ReverseList.java @@ -0,0 +1,84 @@ +package com.baeldung.forEach; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.function.Consumer; + +class ReverseList extends ArrayList { + + List list = Arrays.asList("A", "B", "C", "D"); + + Consumer removeElement = s -> { + System.out.println(s + " " + list.size()); + if (s != null && s.equals("A")) { + list.remove("D"); + } + }; + + @Override + public Iterator iterator() { + + final int startIndex = this.size() - 1; + final List list = this; + return new Iterator() { + + int currentIndex = startIndex; + + @Override + public boolean hasNext() { + return currentIndex >= 0; + } + + @Override + public String next() { + String next = list.get(currentIndex); + currentIndex--; + return next; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + + public void forEach(Consumer action) { + for (String s : this) { + action.accept(s); + } + } + + public void iterateParallel() { + list.forEach(System.out::print); + System.out.print(" "); + list.parallelStream().forEach(System.out::print); + } + + public void iterateReverse() { + List myList = new ReverseList(); + myList.addAll(list); + myList.forEach(System.out::print); + System.out.print(" "); + myList.stream().forEach(System.out::print); + } + + public void removeInCollectionForEach() { + list.forEach(removeElement); + } + + public void removeInStreamForEach() { + list.stream().forEach(removeElement); + } + + public static void main(String[] argv) { + + ReverseList collectionForEach = new ReverseList(); + collectionForEach.iterateParallel(); + collectionForEach.iterateReverse(); + collectionForEach.removeInCollectionForEach(); + collectionForEach.removeInStreamForEach(); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-8-2/src/main/java/com/baeldung/stream/SkipLimitComparison.java b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/stream/SkipLimitComparison.java new file mode 100644 index 0000000000..65f12ada45 --- /dev/null +++ b/core-java-modules/core-java-8-2/src/main/java/com/baeldung/stream/SkipLimitComparison.java @@ -0,0 +1,46 @@ +package com.baeldung.stream; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class SkipLimitComparison { + + public static void main(String[] args) { + skipExample(); + limitExample(); + limitInfiniteStreamExample(); + getEvenNumbers(10, 10).stream() + .forEach(System.out::println); + } + + public static void skipExample() { + Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + .filter(i -> i % 2 == 0) + .skip(2) + .forEach(i -> System.out.print(i + " ")); + } + + public static void limitExample() { + Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + .filter(i -> i % 2 == 0) + .limit(2) + .forEach(i -> System.out.print(i + " ")); + } + + public static void limitInfiniteStreamExample() { + Stream.iterate(0, i -> i + 1) + .filter(i -> i % 2 == 0) + .limit(10) + .forEach(System.out::println); + } + + private static List getEvenNumbers(int offset, int limit) { + return Stream.iterate(0, i -> i + 1) + .filter(i -> i % 2 == 0) + .skip(offset) + .limit(limit) + .collect(Collectors.toList()); + } + +} diff --git a/core-java-modules/core-java-exceptions/pom.xml b/core-java-modules/core-java-exceptions/pom.xml index 51c4e51341..37f65882c3 100644 --- a/core-java-modules/core-java-exceptions/pom.xml +++ b/core-java-modules/core-java-exceptions/pom.xml @@ -1,26 +1,35 @@ - 4.0.0 - com.baeldung.exception.numberformat - core-java-exceptions - 0.0.1-SNAPSHOT - core-java-exceptions + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + com.baeldung.exception.numberformat + core-java-exceptions + 0.0.1-SNAPSHOT + core-java-exceptions - - com.baeldung - parent-java - 0.0.1-SNAPSHOT - ../../parent-java - + + com.baeldung + parent-java + 0.0.1-SNAPSHOT + ../../parent-java + - - - junit - junit - 4.12 - test - - + + 3.9 + + + + + junit + junit + 4.12 + test + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + diff --git a/core-java-modules/core-java/src/main/java/com/baeldung/exceptions/RootCauseFinder.java b/core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/RootCauseFinder.java similarity index 100% rename from core-java-modules/core-java/src/main/java/com/baeldung/exceptions/RootCauseFinder.java rename to core-java-modules/core-java-exceptions/src/main/java/com/baeldung/exceptions/RootCauseFinder.java diff --git a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/error/ErrorGeneratorUnitTest.java b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/error/ErrorGeneratorUnitTest.java index de56fb7113..6dcd0d72e0 100644 --- a/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/error/ErrorGeneratorUnitTest.java +++ b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exception/error/ErrorGeneratorUnitTest.java @@ -1,7 +1,6 @@ -package com.baeldung.error; +package com.baeldung.exception.error; import org.junit.Assert; -import org.junit.Before; import org.junit.Test; public class ErrorGeneratorUnitTest { diff --git a/core-java-modules/core-java/src/test/java/com/baeldung/exceptions/RootCauseFinderUnitTest.java b/core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/RootCauseFinderUnitTest.java similarity index 100% rename from core-java-modules/core-java/src/test/java/com/baeldung/exceptions/RootCauseFinderUnitTest.java rename to core-java-modules/core-java-exceptions/src/test/java/com/baeldung/exceptions/RootCauseFinderUnitTest.java diff --git a/core-java-modules/core-java-lambdas/README.MD b/core-java-modules/core-java-lambdas/README.MD deleted file mode 100644 index 31790ffbb1..0000000000 --- a/core-java-modules/core-java-lambdas/README.MD +++ /dev/null @@ -1,3 +0,0 @@ -### Relevant Articles - -- [Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?](https://www.baeldung.com/java-lambda-effectively-final-local-variables) diff --git a/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/rawtype/RawTypeDemo.java b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/rawtype/RawTypeDemo.java new file mode 100644 index 0000000000..e358219d24 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-2/src/main/java/com/baeldung/rawtype/RawTypeDemo.java @@ -0,0 +1,25 @@ +package com.baeldung.rawtype; + +import java.util.ArrayList; +import java.util.List; + +public class RawTypeDemo { + + public static void main(String[] args) { + RawTypeDemo rawTypeDemo = new RawTypeDemo(); + rawTypeDemo.methodA(); + } + + public void methodA() { + // parameterized type + List listStr = new ArrayList<>(); + listStr.add("Hello Folks!"); + methodB(listStr); + String s = listStr.get(1); // ClassCastException at run time + } + + public void methodB(List rawList) { // Inexpressive raw type + rawList.add(1); // Unsafe operation + } + +} diff --git a/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/breakloop/LoopBreaking.java b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/breakloop/LoopBreaking.java new file mode 100644 index 0000000000..90b99f57cb --- /dev/null +++ b/core-java-modules/core-java-lang-syntax/src/main/java/com/baeldung/breakloop/LoopBreaking.java @@ -0,0 +1,47 @@ +package com.baeldung.breakloop; + +public class LoopBreaking { + + public String simpleBreak() { + String result = ""; + for (int outerCounter = 0; outerCounter < 2; outerCounter++) { + result += "outer" + outerCounter; + for (int innerCounter = 0; innerCounter < 2; innerCounter++) { + result += "inner" + innerCounter; + if (innerCounter == 0) { + break; + } + } + } + return result; + } + + public String labelBreak() { + String result = ""; + myBreakLabel: + for (int outerCounter = 0; outerCounter < 2; outerCounter++) { + result += "outer" + outerCounter; + for (int innerCounter = 0; innerCounter < 2; innerCounter++) { + result += "inner" + innerCounter; + if (innerCounter == 0) { + break myBreakLabel; + } + } + } + return result; + } + + public String usingReturn() { + String result = ""; + for (int outerCounter = 0; outerCounter < 2; outerCounter++) { + result += "outer" + outerCounter; + for (int innerCounter = 0; innerCounter < 2; innerCounter++) { + result += "inner" + innerCounter; + if (innerCounter == 0) { + return result; + } + } + } + return "failed"; + } +} diff --git a/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/breakloop/LoopBreakingUnitTest.java b/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/breakloop/LoopBreakingUnitTest.java new file mode 100644 index 0000000000..c4b6573c86 --- /dev/null +++ b/core-java-modules/core-java-lang-syntax/src/test/java/com/baeldung/breakloop/LoopBreakingUnitTest.java @@ -0,0 +1,25 @@ +package com.baeldung.breakloop; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class LoopBreakingUnitTest { + + private LoopBreaking loopBreaking = new LoopBreaking(); + + @Test + void whenUsingBreak_shouldBreakInnerLoop() { + assertEquals("outer0inner0outer1inner0", loopBreaking.simpleBreak()); + } + + @Test + void whenUsingLabeledBreak_shouldBreakInnerLoopAndOuterLoop() { + assertEquals("outer0inner0", loopBreaking.labelBreak()); + } + + @Test + void whenUsingReturn_shouldBreakInnerLoopAndOuterLoop() { + assertEquals("outer0inner0", loopBreaking.usingReturn()); + } +} \ No newline at end of file diff --git a/easy-random/pom.xml b/easy-random/pom.xml new file mode 100644 index 0000000000..61f0ed2cd4 --- /dev/null +++ b/easy-random/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + easy-random + easy-random + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + + + + org.jeasy + easy-random-core + 4.0.0 + + + + \ No newline at end of file diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/Department.java b/easy-random/src/main/java/org/baeldung/easy/random/model/Department.java new file mode 100644 index 0000000000..ee4dc82771 --- /dev/null +++ b/easy-random/src/main/java/org/baeldung/easy/random/model/Department.java @@ -0,0 +1,17 @@ +package org.baeldung.easy.random.model; + +import java.util.StringJoiner; + +public class Department { + private String depName; + + public Department(String depName) { + this.depName = depName; + } + + @Override + public String toString() { + return new StringJoiner(", ", Department.class.getSimpleName() + "[", "]").add("depName='" + depName + "'") + .toString(); + } +} diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/Employee.java b/easy-random/src/main/java/org/baeldung/easy/random/model/Employee.java new file mode 100644 index 0000000000..ef63642ca2 --- /dev/null +++ b/easy-random/src/main/java/org/baeldung/easy/random/model/Employee.java @@ -0,0 +1,70 @@ +package org.baeldung.easy.random.model; + +import java.util.*; + +public class Employee { + + private long id; + private String firstName; + private String lastName; + private Department department; + private Collection coworkers; + private Map quarterGrades; + + public Employee(long id, String firstName, String lastName, Department department) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.department = department; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + Employee employee = (Employee) o; + return id == employee.id; + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public long getId() { + return id; + } + + public Department getDepartment() { + return department; + } + + public Collection getCoworkers() { + return Collections.unmodifiableCollection(coworkers); + } + + public Map getQuarterGrades() { + return Collections.unmodifiableMap(quarterGrades); + } + + @Override + public String toString() { + return new StringJoiner(", ", Employee.class.getSimpleName() + "[", "]").add("id=" + id) + .add("firstName='" + firstName + "'") + .add("lastName='" + lastName + "'") + .add("department=" + department) + .add("coworkers size=" + ((coworkers == null) ? 0 : coworkers.size())) + .add("quarterGrades=" + quarterGrades) + .toString(); + } +} diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/Grade.java b/easy-random/src/main/java/org/baeldung/easy/random/model/Grade.java new file mode 100644 index 0000000000..cb979be3b8 --- /dev/null +++ b/easy-random/src/main/java/org/baeldung/easy/random/model/Grade.java @@ -0,0 +1,22 @@ +package org.baeldung.easy.random.model; + +import java.util.StringJoiner; + +public class Grade { + + private int grade; + + public Grade(int grade) { + this.grade = grade; + } + + public int getGrade() { + return grade; + } + + @Override + public String toString() { + return new StringJoiner(", ", Grade.class.getSimpleName() + "[", "]").add("grade=" + grade) + .toString(); + } +} diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/Person.java b/easy-random/src/main/java/org/baeldung/easy/random/model/Person.java new file mode 100644 index 0000000000..c941499993 --- /dev/null +++ b/easy-random/src/main/java/org/baeldung/easy/random/model/Person.java @@ -0,0 +1,30 @@ +package org.baeldung.easy.random.model; + +import java.util.StringJoiner; + +public class Person { + + private String firstName; + private String lastName; + private Integer age; + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public Integer getAge() { + return age; + } + + @Override + public String toString() { + return new StringJoiner(", ", Person.class.getSimpleName() + "[", "]").add("firstName='" + firstName + "'") + .add("lastName='" + lastName + "'") + .add("age=" + age) + .toString(); + } +} diff --git a/easy-random/src/main/java/org/baeldung/easy/random/model/YearQuarter.java b/easy-random/src/main/java/org/baeldung/easy/random/model/YearQuarter.java new file mode 100644 index 0000000000..c2868f09b8 --- /dev/null +++ b/easy-random/src/main/java/org/baeldung/easy/random/model/YearQuarter.java @@ -0,0 +1,50 @@ +package org.baeldung.easy.random.model; + +import java.time.LocalDate; +import java.util.Objects; +import java.util.StringJoiner; + +public class YearQuarter { + + private LocalDate startDate; + private LocalDate endDate; + + public YearQuarter(LocalDate startDate) { + this.startDate = startDate; + autoAdjustEndDate(); + } + + private void autoAdjustEndDate() { + endDate = startDate.plusMonths(3L); + } + + public LocalDate getStartDate() { + return startDate; + } + + public LocalDate getEndDate() { + return endDate; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + YearQuarter quarter = (YearQuarter) o; + return Objects.equals(startDate, quarter.startDate) && Objects.equals(endDate, quarter.endDate); + } + + @Override + public int hashCode() { + return Objects.hash(startDate, endDate); + } + + @Override + public String toString() { + return new StringJoiner(", ", YearQuarter.class.getSimpleName() + "[", "]").add("startDate=" + startDate) + .add("endDate=" + endDate) + .toString(); + } +} diff --git a/easy-random/src/main/java/org/baeldung/easy/random/randomizer/YearQuarterRandomizer.java b/easy-random/src/main/java/org/baeldung/easy/random/randomizer/YearQuarterRandomizer.java new file mode 100644 index 0000000000..05232ffcbc --- /dev/null +++ b/easy-random/src/main/java/org/baeldung/easy/random/randomizer/YearQuarterRandomizer.java @@ -0,0 +1,18 @@ +package org.baeldung.easy.random.randomizer; + +import org.baeldung.easy.random.model.YearQuarter; +import org.jeasy.random.api.Randomizer; + +import java.time.LocalDate; +import java.time.Month; + +public class YearQuarterRandomizer implements Randomizer { + + private LocalDate date = LocalDate.of(1990, Month.SEPTEMBER, 25); + + @Override + public YearQuarter getRandomValue() { + date = date.plusMonths(3); + return new YearQuarter(date); + } +} diff --git a/easy-random/src/test/java/org/baeldung/easy/random/EasyRandomUnitTest.java b/easy-random/src/test/java/org/baeldung/easy/random/EasyRandomUnitTest.java new file mode 100644 index 0000000000..9f7a23db66 --- /dev/null +++ b/easy-random/src/test/java/org/baeldung/easy/random/EasyRandomUnitTest.java @@ -0,0 +1,63 @@ +package org.baeldung.easy.random; + +import org.baeldung.easy.random.model.Employee; +import org.baeldung.easy.random.model.Person; +import org.baeldung.easy.random.model.YearQuarter; +import org.baeldung.easy.random.randomizer.YearQuarterRandomizer; +import org.jeasy.random.EasyRandom; +import org.jeasy.random.EasyRandomParameters; +import org.jeasy.random.FieldPredicates; +import org.jeasy.random.TypePredicates; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.*; + +class EasyRandomUnitTest { + + @Test + void givenDefaultConfiguration_thenGenerateSingleObject() { + EasyRandom generator = new EasyRandom(); + Person person = generator.nextObject(Person.class); + + assertNotNull(person.getAge()); + assertNotNull(person.getFirstName()); + assertNotNull(person.getLastName()); + } + + @Test + void givenDefaultConfiguration_thenGenerateObjectsList() { + EasyRandom generator = new EasyRandom(); + List persons = generator.objects(Person.class, 5) + .collect(Collectors.toList()); + + assertEquals(5, persons.size()); + } + + @Test + void givenCustomConfiguration_thenGenerateSingleEmployee() { + EasyRandomParameters parameters = new EasyRandomParameters(); + parameters.stringLengthRange(3, 3); + parameters.collectionSizeRange(5, 5); + parameters.excludeField(FieldPredicates.named("lastName").and(FieldPredicates.inClass(Employee.class))); + parameters.excludeType(TypePredicates.inPackage("not.existing.pkg")); + parameters.randomize(YearQuarter.class, new YearQuarterRandomizer()); + + EasyRandom generator = new EasyRandom(parameters); + Employee employee = generator.nextObject(Employee.class); + + assertEquals(3, employee.getFirstName().length()); + assertEquals(5, employee.getCoworkers().size()); + assertEquals(5, employee.getQuarterGrades().size()); + assertNotNull(employee.getDepartment()); + + assertNull(employee.getLastName()); + + for (YearQuarter key : employee.getQuarterGrades().keySet()) { + assertEquals(key.getStartDate(), key.getEndDate().minusMonths(3L)); + } + } + +} diff --git a/java-collections-conversions/src/test/java/com/baeldung/convertiteratortolist/ConvertIteratorToListServiceUnitTest.java b/java-collections-conversions/src/test/java/com/baeldung/convert/iteratortolist/ConvertIteratorToListServiceUnitTest.java similarity index 98% rename from java-collections-conversions/src/test/java/com/baeldung/convertiteratortolist/ConvertIteratorToListServiceUnitTest.java rename to java-collections-conversions/src/test/java/com/baeldung/convert/iteratortolist/ConvertIteratorToListServiceUnitTest.java index 4d6cba7d27..ced2ddcfc0 100644 --- a/java-collections-conversions/src/test/java/com/baeldung/convertiteratortolist/ConvertIteratorToListServiceUnitTest.java +++ b/java-collections-conversions/src/test/java/com/baeldung/convert/iteratortolist/ConvertIteratorToListServiceUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.convertiteratortolist; +package com.baeldung.convert.iteratortolist; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; diff --git a/java-dates-2/pom.xml b/java-dates-2/pom.xml index 9307a794b9..2f861ff5f4 100644 --- a/java-dates-2/pom.xml +++ b/java-dates-2/pom.xml @@ -20,6 +20,13 @@ joda-time ${joda-time.version} + + + + commons-validator + commons-validator + 1.6 + diff --git a/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidator.java b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidator.java new file mode 100644 index 0000000000..b774edab43 --- /dev/null +++ b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidator.java @@ -0,0 +1,5 @@ +package com.baeldung.date.validation; + +public interface DateValidator { + boolean isValid(String dateStr); +} diff --git a/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingApacheValidator.java b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingApacheValidator.java new file mode 100644 index 0000000000..f7b2f48d2d --- /dev/null +++ b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingApacheValidator.java @@ -0,0 +1,11 @@ +package com.baeldung.date.validation; + +import org.apache.commons.validator.GenericValidator; + +public class DateValidatorUsingApacheValidator implements DateValidator { + + @Override + public boolean isValid(String dateStr) { + return GenericValidator.isDate(dateStr, "yyyy-MM-dd", true); + } +} diff --git a/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingDateFormat.java b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingDateFormat.java new file mode 100644 index 0000000000..eb0fbdb086 --- /dev/null +++ b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingDateFormat.java @@ -0,0 +1,25 @@ +package com.baeldung.date.validation; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; + +public class DateValidatorUsingDateFormat implements DateValidator { + private String dateFormat; + + public DateValidatorUsingDateFormat(String dateFormat) { + this.dateFormat = dateFormat; + } + + @Override + public boolean isValid(String dateStr) { + DateFormat sdf = new SimpleDateFormat(this.dateFormat); + sdf.setLenient(false); + try { + sdf.parse(dateStr); + } catch (ParseException e) { + return false; + } + return true; + } +} diff --git a/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingDateTimeFormatter.java b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingDateTimeFormatter.java new file mode 100644 index 0000000000..0f68baf06e --- /dev/null +++ b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingDateTimeFormatter.java @@ -0,0 +1,22 @@ +package com.baeldung.date.validation; + +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +public class DateValidatorUsingDateTimeFormatter implements DateValidator { + private DateTimeFormatter dateFormatter; + + public DateValidatorUsingDateTimeFormatter(DateTimeFormatter dateFormatter) { + this.dateFormatter = dateFormatter; + } + + @Override + public boolean isValid(String dateStr) { + try { + this.dateFormatter.parse(dateStr); + } catch (DateTimeParseException e) { + return false; + } + return true; + } +} diff --git a/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingLocalDate.java b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingLocalDate.java new file mode 100644 index 0000000000..f04c2e4185 --- /dev/null +++ b/java-dates-2/src/main/java/com/baeldung/date/validation/DateValidatorUsingLocalDate.java @@ -0,0 +1,23 @@ +package com.baeldung.date.validation; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; + +public class DateValidatorUsingLocalDate implements DateValidator { + private DateTimeFormatter dateFormatter; + + public DateValidatorUsingLocalDate(DateTimeFormatter dateFormatter) { + this.dateFormatter = dateFormatter; + } + + @Override + public boolean isValid(String dateStr) { + try { + LocalDate.parse(dateStr, this.dateFormatter); + } catch (DateTimeParseException e) { + return false; + } + return true; + } +} diff --git a/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingApacheValidatorUnitTest.java b/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingApacheValidatorUnitTest.java new file mode 100644 index 0000000000..daa464722a --- /dev/null +++ b/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingApacheValidatorUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.date.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.apache.commons.validator.GenericValidator; +import org.junit.Test; + +public class DateValidatorUsingApacheValidatorUnitTest { + + @Test + public void whenValidDatePassed_ThenTrue() { + assertTrue(GenericValidator.isDate("2019-02-28", "yyyy-MM-dd", true)); + } + + @Test + public void whenInvalidDatePassed_ThenFalse() { + assertFalse(GenericValidator.isDate("2019-02-29", "yyyy-MM-dd", true)); + } +} diff --git a/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingDateFormatUnitTest.java b/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingDateFormatUnitTest.java new file mode 100644 index 0000000000..9b86b3381c --- /dev/null +++ b/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingDateFormatUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.date.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class DateValidatorUsingDateFormatUnitTest { + + @Test + public void givenValidator_whenValidDatePassed_ThenTrue() { + DateValidator validator = new DateValidatorUsingDateFormat("MM/dd/yyyy"); + + assertTrue(validator.isValid("02/28/2019")); + } + + @Test + public void givenValidator_whenInvalidDatePassed_ThenFalse() { + DateValidator validator = new DateValidatorUsingDateFormat("MM/dd/yyyy"); + + assertFalse(validator.isValid("02/30/2019")); + } +} diff --git a/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingDateTimeFormatterUnitTest.java b/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingDateTimeFormatterUnitTest.java new file mode 100644 index 0000000000..368b04f8e3 --- /dev/null +++ b/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingDateTimeFormatterUnitTest.java @@ -0,0 +1,32 @@ +package com.baeldung.date.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.time.format.DateTimeFormatter; +import java.time.format.ResolverStyle; +import java.util.Locale; + +import org.junit.Test; + +public class DateValidatorUsingDateTimeFormatterUnitTest { + + @Test + public void givenValidator_whenValidDatePassed_ThenTrue() { + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.US) + .withResolverStyle(ResolverStyle.STRICT); + DateValidator validator = new DateValidatorUsingDateTimeFormatter(dateFormatter); + + assertTrue(validator.isValid("2019-02-28")); + } + + @Test + public void givenValidator_whenInValidDatePassed_ThenFalse() { + DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.US) + .withResolverStyle(ResolverStyle.STRICT); + DateValidator validator = new DateValidatorUsingDateTimeFormatter(dateFormatter); + + assertFalse(validator.isValid("2019-02-30")); + } + +} diff --git a/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingLocalDateUnitTest.java b/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingLocalDateUnitTest.java new file mode 100644 index 0000000000..63296359db --- /dev/null +++ b/java-dates-2/src/test/java/com/baeldung/date/validation/DateValidatorUsingLocalDateUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.date.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.time.format.DateTimeFormatter; + +import org.junit.Test; + +public class DateValidatorUsingLocalDateUnitTest { + + @Test + public void givenValidator_whenValidDatePassed_ThenTrue() { + DateTimeFormatter dateFormatter = DateTimeFormatter.BASIC_ISO_DATE; + DateValidator validator = new DateValidatorUsingLocalDate(dateFormatter); + + assertTrue(validator.isValid("20190228")); + } + + @Test + public void givenValidator_whenInValidDatePassed_ThenFalse() { + DateTimeFormatter dateFormatter = DateTimeFormatter.BASIC_ISO_DATE; + DateValidator validator = new DateValidatorUsingLocalDate(dateFormatter); + + assertFalse(validator.isValid("20190230")); + } +} diff --git a/java-numbers/src/main/java/com/baeldung/random/SecureRandomDemo.java b/java-numbers/src/main/java/com/baeldung/random/SecureRandomDemo.java new file mode 100644 index 0000000000..02f815f5a7 --- /dev/null +++ b/java-numbers/src/main/java/com/baeldung/random/SecureRandomDemo.java @@ -0,0 +1,36 @@ +package com.baeldung.random; + +import java.security.SecureRandom; +import java.security.NoSuchAlgorithmException; +import java.util.stream.IntStream; +import java.util.stream.LongStream; +import java.util.stream.DoubleStream; + +public interface SecureRandomDemo { + + public static void generateSecureRandomValues() { + SecureRandom sr = new SecureRandom(); + + int randomInt = sr.nextInt(); + long randomLong = sr.nextLong(); + float randomFloat = sr.nextFloat(); + double randomDouble = sr.nextDouble(); + boolean randomBoolean = sr.nextBoolean(); + + IntStream randomIntStream = sr.ints(); + LongStream randomLongStream = sr.longs(); + DoubleStream randomDoubleStream = sr.doubles(); + + byte[] values = new byte[124]; + sr.nextBytes(values); + } + + public static SecureRandom getSecureRandomForAlgorithm(String algorithm) throws NoSuchAlgorithmException { + if (algorithm == null || algorithm.isEmpty()) { + return new SecureRandom(); + } + + return SecureRandom.getInstance(algorithm); + } + +} diff --git a/java-streams-2/pom.xml b/java-streams-2/pom.xml index 3e08e2f432..f7a0379ac5 100644 --- a/java-streams-2/pom.xml +++ b/java-streams-2/pom.xml @@ -4,7 +4,7 @@ com.baeldung.javastreams2 javastreams2 1.0 - Stream Reduce + javastreams2 jar @@ -42,8 +42,8 @@ UTF-8 - 1.8 - 1.8 + 1.9 + 1.9 3.11.1 \ No newline at end of file diff --git a/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomForEach.java b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomForEach.java new file mode 100644 index 0000000000..1f8866b16c --- /dev/null +++ b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomForEach.java @@ -0,0 +1,32 @@ +package com.baeldung.breakforeach; + +import java.util.Spliterator; +import java.util.function.BiConsumer; +import java.util.stream.Stream; + +public class CustomForEach { + + public static class Breaker { + private boolean shouldBreak = false; + + public void stop() { + shouldBreak = true; + } + + boolean get() { + return shouldBreak; + } + } + + public static void forEach(Stream stream, BiConsumer consumer) { + Spliterator spliterator = stream.spliterator(); + boolean hadNext = true; + Breaker breaker = new Breaker(); + + while (hadNext && !breaker.get()) { + hadNext = spliterator.tryAdvance(elem -> { + consumer.accept(elem, breaker); + }); + } + } +} diff --git a/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomSpliterator.java b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomSpliterator.java new file mode 100644 index 0000000000..cfe4bedac3 --- /dev/null +++ b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomSpliterator.java @@ -0,0 +1,31 @@ +package com.baeldung.breakforeach; + +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class CustomSpliterator extends Spliterators.AbstractSpliterator { + + private Spliterator splitr; + private Predicate predicate; + private boolean isMatched = true; + + public CustomSpliterator(Spliterator splitr, Predicate predicate) { + super(splitr.estimateSize(), 0); + this.splitr = splitr; + this.predicate = predicate; + } + + @Override + public boolean tryAdvance(Consumer consumer) { + boolean hadNext = splitr.tryAdvance(elem -> { + if (predicate.test(elem) && isMatched) { + consumer.accept(elem); + } else { + isMatched = false; + } + }); + return hadNext && isMatched; + } +} \ No newline at end of file diff --git a/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomTakeWhile.java b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomTakeWhile.java new file mode 100644 index 0000000000..05574f9ae6 --- /dev/null +++ b/java-streams-2/src/main/java/com/baeldung/breakforeach/CustomTakeWhile.java @@ -0,0 +1,14 @@ +package com.baeldung.breakforeach; + +import java.util.function.Predicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class CustomTakeWhile { + + public static Stream takeWhile(Stream stream, Predicate predicate) { + CustomSpliterator customSpliterator = new CustomSpliterator<>(stream.spliterator(), predicate); + return StreamSupport.stream(customSpliterator, false); + } + +} diff --git a/java-streams-2/src/main/java/com/baeldung/breakforeach/TakeWhileExample.java b/java-streams-2/src/main/java/com/baeldung/breakforeach/TakeWhileExample.java new file mode 100644 index 0000000000..1838ae5fb7 --- /dev/null +++ b/java-streams-2/src/main/java/com/baeldung/breakforeach/TakeWhileExample.java @@ -0,0 +1,26 @@ +package com.baeldung.breakforeach; + +import java.util.List; +import java.util.stream.Stream; + +import static java.util.Arrays.asList; + +public class TakeWhileExample { + + public static void takeWhileJava9() { + Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck") + .takeWhile(n -> n.length() % 2 != 0) + .forEach(System.out::println); // cat, dog + } + + public static void plainForLoopWithBreak() { + List list = asList("cat", "dog", "elephant", "fox", "rabbit", "duck"); + for (int i = 0; i < list.size(); i++) { + String item = list.get(i); + if (item.length() % 2 == 0) { + break; + } + System.out.println(item); + } + } +} \ No newline at end of file diff --git a/java-streams-2/src/test/java/com/baeldung/breakforeach/BreakFromStreamForEachUnitTest.java b/java-streams-2/src/test/java/com/baeldung/breakforeach/BreakFromStreamForEachUnitTest.java new file mode 100644 index 0000000000..23653c0a39 --- /dev/null +++ b/java-streams-2/src/test/java/com/baeldung/breakforeach/BreakFromStreamForEachUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.breakforeach; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; + +public class BreakFromStreamForEachUnitTest { + + @Test + public void whenCustomTakeWhileIsCalled_ThenCorrectItemsAreReturned() { + Stream initialStream = Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck"); + + List result = CustomTakeWhile.takeWhile(initialStream, x -> x.length() % 2 != 0) + .collect(Collectors.toList()); + + assertEquals(asList("cat", "dog"), result); + } + + @Test + public void whenCustomForEachIsCalled_ThenCorrectItemsAreReturned() { + Stream initialStream = Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck"); + List result = new ArrayList<>(); + + CustomForEach.forEach(initialStream, (elem, breaker) -> { + if (elem.length() % 2 == 0) { + breaker.stop(); + } else { + result.add(elem); + } + }); + + assertEquals(asList("cat", "dog"), result); + } + +} diff --git a/java-streams/src/test/java/com/baeldung/intstreams/conversion/IntStreamsConversionsUnitTest.java b/java-streams-2/src/test/java/com/baeldung/convert/intstreams/IntStreamsConversionsUnitTest.java similarity index 96% rename from java-streams/src/test/java/com/baeldung/intstreams/conversion/IntStreamsConversionsUnitTest.java rename to java-streams-2/src/test/java/com/baeldung/convert/intstreams/IntStreamsConversionsUnitTest.java index 6cd773e634..3f2fd1641e 100644 --- a/java-streams/src/test/java/com/baeldung/intstreams/conversion/IntStreamsConversionsUnitTest.java +++ b/java-streams-2/src/test/java/com/baeldung/convert/intstreams/IntStreamsConversionsUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.intstreams.conversion; +package com.baeldung.convert.intstreams; import org.junit.Test; diff --git a/java-strings-2/pom.xml b/java-strings-2/pom.xml index 9c27429139..7342953d15 100755 --- a/java-strings-2/pom.xml +++ b/java-strings-2/pom.xml @@ -57,6 +57,26 @@ commons-text ${commons-text.version} + + javax.validation + validation-api + 2.0.0.Final + + + org.hibernate.validator + hibernate-validator + 6.0.2.Final + + + javax.el + javax.el-api + 3.0.0 + + + org.glassfish.web + javax.el + 2.2.6 + @@ -86,7 +106,7 @@ 3.8.1 61.1 - 27.0.1-jre + 28.0-jre 1.4 diff --git a/java-strings-2/src/main/java/com/baeldung/string/emptystrings/EmptyStringCheck.java b/java-strings-2/src/main/java/com/baeldung/string/emptystrings/EmptyStringCheck.java new file mode 100644 index 0000000000..6d3234a4ec --- /dev/null +++ b/java-strings-2/src/main/java/com/baeldung/string/emptystrings/EmptyStringCheck.java @@ -0,0 +1,8 @@ +package com.baeldung.string.emptystrings; + +class EmptyStringCheck { + + boolean isEmptyString(String string) { + return string == null || string.isEmpty(); + } +} diff --git a/java-strings-2/src/main/java/com/baeldung/string/emptystrings/Java5EmptyStringCheck.java b/java-strings-2/src/main/java/com/baeldung/string/emptystrings/Java5EmptyStringCheck.java new file mode 100644 index 0000000000..096b83acea --- /dev/null +++ b/java-strings-2/src/main/java/com/baeldung/string/emptystrings/Java5EmptyStringCheck.java @@ -0,0 +1,8 @@ +package com.baeldung.string.emptystrings; + +class Java5EmptyStringCheck { + + boolean isEmptyString(String string) { + return string == null || string.length() == 0; + } +} diff --git a/java-strings-2/src/main/java/com/baeldung/string/emptystrings/PlainJavaBlankStringCheck.java b/java-strings-2/src/main/java/com/baeldung/string/emptystrings/PlainJavaBlankStringCheck.java new file mode 100644 index 0000000000..26e281c9b7 --- /dev/null +++ b/java-strings-2/src/main/java/com/baeldung/string/emptystrings/PlainJavaBlankStringCheck.java @@ -0,0 +1,8 @@ +package com.baeldung.string.emptystrings; + +class PlainJavaBlankStringCheck { + + boolean isBlankString(String string) { + return string == null || string.trim().isEmpty(); + } +} diff --git a/java-strings-2/src/main/java/com/baeldung/string/emptystrings/SomeClassWithValidations.java b/java-strings-2/src/main/java/com/baeldung/string/emptystrings/SomeClassWithValidations.java new file mode 100644 index 0000000000..8c484efb43 --- /dev/null +++ b/java-strings-2/src/main/java/com/baeldung/string/emptystrings/SomeClassWithValidations.java @@ -0,0 +1,14 @@ +package com.baeldung.string.emptystrings; + +import javax.validation.constraints.Pattern; + +class SomeClassWithValidations { + + @Pattern(regexp = "\\A(?!\\s*\\Z).+") + private String someString; + + SomeClassWithValidations setSomeString(String someString) { + this.someString = someString; + return this; + } +} diff --git a/java-strings-2/src/main/java/com/baeldung/string/multiline/MultiLineString.java b/java-strings-2/src/main/java/com/baeldung/string/multiline/MultiLineString.java new file mode 100644 index 0000000000..1bde2dcb63 --- /dev/null +++ b/java-strings-2/src/main/java/com/baeldung/string/multiline/MultiLineString.java @@ -0,0 +1,67 @@ +package com.baeldung.string.multiline; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Paths; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; + +public class MultiLineString { + + String newLine = System.getProperty("line.separator"); + + public String stringConcatenation() { + return "Get busy living" + .concat(newLine) + .concat("or") + .concat(newLine) + .concat("get busy dying.") + .concat(newLine) + .concat("--Stephen King"); + } + + public String stringJoin() { + return String.join(newLine, + "Get busy living", + "or", + "get busy dying.", + "--Stephen King"); + } + + public String stringBuilder() { + return new StringBuilder() + .append("Get busy living") + .append(newLine) + .append("or") + .append(newLine) + .append("get busy dying.") + .append(newLine) + .append("--Stephen King") + .toString(); + } + + public String stringWriter() { + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + printWriter.println("Get busy living"); + printWriter.println("or"); + printWriter.println("get busy dying."); + printWriter.println("--Stephen King"); + return stringWriter.toString(); + } + + public String guavaJoiner() { + return Joiner.on(newLine).join(ImmutableList.of("Get busy living", + "or", + "get busy dying.", + "--Stephen King")); + } + + public String loadFromFile() throws IOException { + return new String(Files.readAllBytes(Paths.get("src/main/resources/stephenking.txt"))); + } + +} diff --git a/java-strings-2/src/main/java/com/baeldung/string/repetition/SubstringRepetition.java b/java-strings-2/src/main/java/com/baeldung/string/repetition/SubstringRepetition.java new file mode 100644 index 0000000000..466ce9146b --- /dev/null +++ b/java-strings-2/src/main/java/com/baeldung/string/repetition/SubstringRepetition.java @@ -0,0 +1,29 @@ +package com.baeldung.string.repetition; + +public class SubstringRepetition { + + public static boolean containsOnlySubstrings(String string) { + + if (string.length() < 2) { + return false; + } + + StringBuilder substr = new StringBuilder(); + for (int i = 0; i < string.length() / 2; i++) { + substr.append(string.charAt(i)); + + String clearedFromSubstrings = string.replaceAll(substr.toString(), ""); + + if (clearedFromSubstrings.length() == 0) { + return true; + } + } + + return false; + } + + public static boolean containsOnlySubstringsEfficient(String string) { + + return ((string + string).indexOf(string, 1) != string.length()); + } +} diff --git a/java-strings-2/src/main/java/com/baeldung/string/reverse/ReverseStringExamples.java b/java-strings-2/src/main/java/com/baeldung/string/reverse/ReverseStringExamples.java new file mode 100644 index 0000000000..1a58d09598 --- /dev/null +++ b/java-strings-2/src/main/java/com/baeldung/string/reverse/ReverseStringExamples.java @@ -0,0 +1,56 @@ +package com.baeldung.string.reverse; + +import org.apache.commons.lang3.StringUtils; + +public class ReverseStringExamples { + + public static String reverse(String input) { + if (input == null) { + return null; + } + + String output = ""; + + for (int i = input.length() - 1; i >= 0; i--) { + output = output + input.charAt(i); + } + + return output; + } + + public static String reverseUsingStringBuilder(String input) { + if (input == null) { + return null; + } + + StringBuilder output = new StringBuilder(input).reverse(); + + return output.toString(); + } + + public static String reverseUsingApacheCommons(String input) { + return StringUtils.reverse(input); + } + + public static String reverseTheOrderOfWords(String sentence) { + if (sentence == null) { + return null; + } + + StringBuilder output = new StringBuilder(); + String[] words = sentence.split(" "); + + for (int i = words.length - 1; i >= 0; i--) { + output.append(words[i]); + output.append(" "); + } + + return output.toString() + .trim(); + } + + public static String reverseTheOrderOfWordsUsingApacheCommons(String sentence) { + return StringUtils.reverseDelimited(sentence, ' '); + } + +} diff --git a/java-strings-2/src/main/resources/stephenking.txt b/java-strings-2/src/main/resources/stephenking.txt new file mode 100644 index 0000000000..f31b4a28bd --- /dev/null +++ b/java-strings-2/src/main/resources/stephenking.txt @@ -0,0 +1,4 @@ +Get busy living +or +get busy dying. +--Stephen King \ No newline at end of file diff --git a/java-strings-2/src/test/java/com/baeldung/string/MultiLineStringUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/MultiLineStringUnitTest.java new file mode 100644 index 0000000000..b458fae79b --- /dev/null +++ b/java-strings-2/src/test/java/com/baeldung/string/MultiLineStringUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.string; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import com.baeldung.string.multiline.MultiLineString; + +public class MultiLineStringUnitTest { + + + @Test + public void whenCompareMultiLineStrings_thenTheyAreAllTheSame() throws IOException { + MultiLineString ms = new MultiLineString(); + assertEquals(ms.stringConcatenation(), ms.stringJoin()); + assertEquals(ms.stringJoin(), ms.stringBuilder()); + assertEquals(ms.stringBuilder(), ms.guavaJoiner()); + assertEquals(ms.guavaJoiner(), ms.loadFromFile()); + } + +} diff --git a/java-strings-2/src/test/java/com/baeldung/string/emptystrings/EmptyStringsUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/emptystrings/EmptyStringsUnitTest.java new file mode 100644 index 0000000000..96b1d681dd --- /dev/null +++ b/java-strings-2/src/test/java/com/baeldung/string/emptystrings/EmptyStringsUnitTest.java @@ -0,0 +1,142 @@ +package com.baeldung.string.emptystrings; + +import static org.hamcrest.Matchers.iterableWithSize; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.Set; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; + +import com.google.common.base.Strings; + +public class EmptyStringsUnitTest { + + private String emptyString = ""; + private String blankString = " \n\t "; + private String nonEmptyString = " someString "; + + /* + * EmptyStringCheck + */ + @Test + public void givenSomeEmptyString_thenEmptyStringCheckIsEmptyStringReturnsTrue() { + assertTrue(new EmptyStringCheck().isEmptyString(emptyString)); + } + + @Test + public void givenSomeNonEmptyString_thenEmptyStringCheckIsEmptyStringReturnsFalse() { + assertFalse(new EmptyStringCheck().isEmptyString(nonEmptyString)); + } + + @Test + public void givenSomeBlankString_thenEmptyStringCheckIsEmptyStringReturnsFalse() { + assertFalse(new EmptyStringCheck().isEmptyString(blankString)); + } + + /* + * Java5EmptyStringCheck + */ + @Test + public void givenSomeEmptyString_thenJava5EmptyStringCheckIsEmptyStringReturnsTrue() { + assertTrue(new Java5EmptyStringCheck().isEmptyString(emptyString)); + } + + @Test + public void givenSomeNonEmptyString_thenJava5EmptyStringCheckIsEmptyStringReturnsFalse() { + assertFalse(new Java5EmptyStringCheck().isEmptyString(nonEmptyString)); + } + + @Test + public void givenSomeBlankString_thenJava5EmptyStringCheckIsEmptyStringReturnsFalse() { + assertFalse(new Java5EmptyStringCheck().isEmptyString(blankString)); + } + + /* + * PlainJavaBlankStringCheck + */ + @Test + public void givenSomeEmptyString_thenPlainJavaBlankStringCheckIsBlankStringReturnsTrue() { + assertTrue(new PlainJavaBlankStringCheck().isBlankString(emptyString)); + } + + @Test + public void givenSomeNonEmptyString_thenPlainJavaBlankStringCheckIsBlankStringReturnsFalse() { + assertFalse(new PlainJavaBlankStringCheck().isBlankString(nonEmptyString)); + } + + @Test + public void givenSomeBlankString_thenPlainJavaBlankStringCheckIsBlankStringReturnsTrue() { + assertTrue(new PlainJavaBlankStringCheck().isBlankString(blankString)); + } + + /* + * Apache Commons Lang StringUtils + */ + @Test + public void givenSomeEmptyString_thenStringUtilsIsBlankReturnsTrue() { + assertTrue(StringUtils.isBlank(emptyString)); + } + + @Test + public void givenSomeNonEmptyString_thenStringUtilsIsBlankReturnsFalse() { + assertFalse(StringUtils.isBlank(nonEmptyString)); + } + + @Test + public void givenSomeBlankString_thenStringUtilsIsBlankReturnsTrue() { + assertTrue(StringUtils.isBlank(blankString)); + } + + /* + * Google Guava Strings + */ + @Test + public void givenSomeEmptyString_thenStringsIsNullOrEmptyStringReturnsTrue() { + assertTrue(Strings.isNullOrEmpty(emptyString)); + } + + @Test + public void givenSomeNonEmptyString_thenStringsIsNullOrEmptyStringReturnsFalse() { + assertFalse(Strings.isNullOrEmpty(nonEmptyString)); + } + + @Test + public void givenSomeBlankString_thenStringsIsNullOrEmptyStringReturnsFalse() { + assertFalse(Strings.isNullOrEmpty(blankString)); + } + + /* + * Bean Validation + */ + private ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + private Validator validator = factory.getValidator(); + + @Test + public void givenSomeEmptyString_thenBeanValidationReturnsViolations() { + SomeClassWithValidations someClassWithValidations = new SomeClassWithValidations().setSomeString(emptyString); + Set> violations = validator.validate(someClassWithValidations); + assertThat(violations, iterableWithSize(1)); + } + + @Test + public void givenSomeNonEmptyString_thenBeanValidationValidatesWithoutViolations() { + SomeClassWithValidations someClassWithValidations = new SomeClassWithValidations().setSomeString(nonEmptyString); + Set> violations = validator.validate(someClassWithValidations); + assertThat(violations, iterableWithSize(0)); + } + + @Test + public void givenSomeBlankString_thenBeanValidationReturnsViolations() { + SomeClassWithValidations someClassWithValidations = new SomeClassWithValidations().setSomeString(blankString); + Set> violations = validator.validate(someClassWithValidations); + assertThat(violations, iterableWithSize(1)); + } +} diff --git a/java-strings-2/src/test/java/com/baeldung/string/repetition/SubstringRepetitionUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/repetition/SubstringRepetitionUnitTest.java new file mode 100644 index 0000000000..f382a24a7f --- /dev/null +++ b/java-strings-2/src/test/java/com/baeldung/string/repetition/SubstringRepetitionUnitTest.java @@ -0,0 +1,45 @@ +package com.baeldung.string.repetition; + +import static com.baeldung.string.repetition.SubstringRepetition.*; +import static org.junit.Assert.*; + +import org.junit.Test; + +public class SubstringRepetitionUnitTest { + + private String validString = "aa"; + private String validStringTwo = "ababab"; + private String validStringThree = "baeldungbaeldung"; + + private String invalidString = "aca"; + private String invalidStringTwo = "ababa"; + private String invalidStringThree = "baeldungnonrepeatedbaeldung"; + + @Test + public void givenValidStrings_whenCheckIfContainsOnlySubstrings_thenReturnsTrue() { + assertTrue(containsOnlySubstrings(validString)); + assertTrue(containsOnlySubstrings(validStringTwo)); + assertTrue(containsOnlySubstrings(validStringThree)); + } + + @Test + public void givenInvalidStrings_whenCheckIfContainsOnlySubstrings_thenReturnsFalse() { + assertFalse(containsOnlySubstrings(invalidString)); + assertFalse(containsOnlySubstrings(invalidStringTwo)); + assertFalse(containsOnlySubstrings(invalidStringThree)); + } + + @Test + public void givenValidStrings_whenCheckEfficientlyIfContainsOnlySubstrings_thenReturnsTrue() { + assertTrue(containsOnlySubstringsEfficient(validString)); + assertTrue(containsOnlySubstringsEfficient(validStringTwo)); + assertTrue(containsOnlySubstringsEfficient(validStringThree)); + } + + @Test + public void givenInvalidStrings_whenCheckEfficientlyIfContainsOnlySubstrings_thenReturnsFalse() { + assertFalse(containsOnlySubstringsEfficient(invalidString)); + assertFalse(containsOnlySubstringsEfficient(invalidStringTwo)); + assertFalse(containsOnlySubstringsEfficient(invalidStringThree)); + } +} diff --git a/java-strings-2/src/test/java/com/baeldung/string/reverse/ReverseStringExamplesUnitTest.java b/java-strings-2/src/test/java/com/baeldung/string/reverse/ReverseStringExamplesUnitTest.java new file mode 100644 index 0000000000..020ead02db --- /dev/null +++ b/java-strings-2/src/test/java/com/baeldung/string/reverse/ReverseStringExamplesUnitTest.java @@ -0,0 +1,70 @@ +package com.baeldung.string.reverse; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ReverseStringExamplesUnitTest { + + private static final String STRING_INPUT = "cat"; + private static final String STRING_INPUT_REVERSED = "tac"; + private static final String SENTENCE = "The quick brown fox jumps over the lazy dog"; + private static final String REVERSED_WORDS_SENTENCE = "dog lazy the over jumps fox brown quick The"; + + @Test + public void whenReverseIsCalled_ThenCorrectStringIsReturned() { + String reversed = ReverseStringExamples.reverse(STRING_INPUT); + String reversedNull = ReverseStringExamples.reverse(null); + String reversedEmpty = ReverseStringExamples.reverse(StringUtils.EMPTY); + + assertEquals(STRING_INPUT_REVERSED, reversed); + assertEquals(null, reversedNull); + assertEquals(StringUtils.EMPTY, reversedEmpty); + } + + @Test + public void whenReverseUsingStringBuilderIsCalled_ThenCorrectStringIsReturned() throws Exception { + String reversed = ReverseStringExamples.reverseUsingStringBuilder(STRING_INPUT); + String reversedNull = ReverseStringExamples.reverseUsingStringBuilder(null); + String reversedEmpty = ReverseStringExamples.reverseUsingStringBuilder(StringUtils.EMPTY); + + assertEquals(STRING_INPUT_REVERSED, reversed); + assertEquals(null, reversedNull); + assertEquals(StringUtils.EMPTY, reversedEmpty); + } + + @Test + public void whenReverseUsingApacheCommonsIsCalled_ThenCorrectStringIsReturned() throws Exception { + String reversed = ReverseStringExamples.reverseUsingApacheCommons(STRING_INPUT); + String reversedNull = ReverseStringExamples.reverseUsingApacheCommons(null); + String reversedEmpty = ReverseStringExamples.reverseUsingApacheCommons(StringUtils.EMPTY); + + assertEquals(STRING_INPUT_REVERSED, reversed); + assertEquals(null, reversedNull); + assertEquals(StringUtils.EMPTY, reversedEmpty); + } + + @Test + public void whenReverseTheOrderOfWordsIsCalled_ThenCorrectStringIsReturned() { + String reversed = ReverseStringExamples.reverseTheOrderOfWords(SENTENCE); + String reversedNull = ReverseStringExamples.reverseTheOrderOfWords(null); + String reversedEmpty = ReverseStringExamples.reverseTheOrderOfWords(StringUtils.EMPTY); + + assertEquals(REVERSED_WORDS_SENTENCE, reversed); + assertEquals(null, reversedNull); + assertEquals(StringUtils.EMPTY, reversedEmpty); + } + + @Test + public void whenReverseTheOrderOfWordsUsingApacheCommonsIsCalled_ThenCorrectStringIsReturned() { + String reversed = ReverseStringExamples.reverseTheOrderOfWordsUsingApacheCommons(SENTENCE); + String reversedNull = ReverseStringExamples.reverseTheOrderOfWordsUsingApacheCommons(null); + String reversedEmpty = ReverseStringExamples.reverseTheOrderOfWordsUsingApacheCommons(StringUtils.EMPTY); + + assertEquals(REVERSED_WORDS_SENTENCE, reversed); + assertEquals(null, reversedNull); + assertEquals(StringUtils.EMPTY, reversedEmpty); + } + +} diff --git a/libraries-2/README.md b/libraries-2/README.md index 8243b9f82c..cdeed10b3f 100644 --- a/libraries-2/README.md +++ b/libraries-2/README.md @@ -4,4 +4,4 @@ - [A Guide to jBPM with Java](https://www.baeldung.com/jbpm-java) - [Guide to Classgraph Library](https://www.baeldung.com/classgraph) - [Create a Java Command Line Program with Picocli](https://www.baeldung.com/java-picocli-create-command-line-program) - +- [Guide to Java Parallel Collectors Library](https://www.baeldung.com/java-parallel-collectors) diff --git a/libraries-2/pom.xml b/libraries-2/pom.xml index 32f3f23812..efcb03f528 100644 --- a/libraries-2/pom.xml +++ b/libraries-2/pom.xml @@ -1,113 +1,154 @@ - - 4.0.0 - libraries2 - libraries2 - - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - - - - - jboss-public-repository-group - JBoss Public Repository Group - http://repository.jboss.org/nexus/content/groups/public/ - - true - never - - - true - daily - - - - - - - org.assertj - assertj-core - ${assertj.version} - - - io.github.classgraph - classgraph - ${classgraph.version} - - - org.jbpm - jbpm-test - ${jbpm.version} - - - info.picocli - picocli - ${picocli.version} - - - org.springframework.boot - spring-boot-starter - ${spring-boot-starter.version} - - - net.openhft - chronicle-map - ${chronicle.map.version} - - - com.sun.java - tools - - - - - - - com.squareup.okhttp3 - okhttp - 3.14.2 - - - - com.fasterxml.jackson.core - jackson-databind - 2.9.9 - - - - com.google.code.gson - gson - 2.8.5 - - - - com.squareup.okhttp3 - mockwebserver - 3.14.2 - test - - - - edu.uci.ics - crawler4j - ${crawler4j.version} - - - - - - 3.6.2 - 4.8.28 - 6.0.0.Final - 3.9.6 - 3.17.2 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + libraries2 + libraries2 + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + + + + jboss-public-repository-group + JBoss Public Repository Group + http://repository.jboss.org/nexus/content/groups/public/ + + true + never + + + true + daily + + + + + + org.mapdb + mapdb + ${mapdb.version} + + + com.pivovarit + parallel-collectors + 1.1.0 + + + org.assertj + assertj-core + ${assertj.version} + + + io.github.classgraph + classgraph + ${classgraph.version} + + + org.jbpm + jbpm-test + ${jbpm.version} + + + info.picocli + picocli + ${picocli.version} + + + org.ejml + ejml-all + ${ejml.version} + + + org.nd4j + nd4j-native + ${nd4j.version} + + + org.la4j + la4j + ${la4j.version} + + + colt + colt + ${colt.version} + + + org.springframework.boot + spring-boot-starter + ${spring-boot-starter.version} + + + net.openhft + chronicle-map + ${chronicle.map.version} + + + com.sun.java + tools + + + + + + com.squareup.okhttp3 + okhttp + 3.14.2 + + + com.fasterxml.jackson.core + jackson-databind + 2.9.9 + + + com.google.code.gson + gson + 2.8.5 + + + com.squareup.okhttp3 + mockwebserver + 3.14.2 + test + + + edu.uci.ics + crawler4j + ${crawler4j.version} + + + com.github.jknack + handlebars + 4.1.2 + + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + + + + 3.0.7 + 3.6.2 + 4.8.28 + 6.0.0.Final + 3.9.6 + 3.17.2 4.4.0 - 2.1.4.RELEASE - + 2.1.4.RELEASE + 0.38 + 1.0.0-beta4 + 1.2.0 + 0.6.0 + 1.19 + diff --git a/libraries-2/src/test/java/com/baeldung/handlebars/BasicUsageUnitTest.java b/libraries-2/src/test/java/com/baeldung/handlebars/BasicUsageUnitTest.java new file mode 100644 index 0000000000..3eb325dbb6 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/handlebars/BasicUsageUnitTest.java @@ -0,0 +1,109 @@ +package com.baeldung.handlebars; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.github.jknack.handlebars.Handlebars; +import com.github.jknack.handlebars.Template; +import com.github.jknack.handlebars.io.ClassPathTemplateLoader; +import com.github.jknack.handlebars.io.TemplateLoader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; + +/** + * Showcases the tag usage and different template loading mechanisms. + * + * @author isaolmez + */ +public class BasicUsageUnitTest { + + @Test + public void whenThereIsNoTemplateFile_ThenCompilesInline() throws IOException { + Handlebars handlebars = new Handlebars(); + Template template = handlebars.compileInline("Hi {{this}}!"); + + String templateString = template.apply("Baeldung"); + + assertThat(templateString).isEqualTo("Hi Baeldung!"); + } + + @Test + public void whenParameterMapIsSupplied_thenDisplays() throws IOException { + Handlebars handlebars = new Handlebars(); + Template template = handlebars.compileInline("Hi {{name}}!"); + Map parameterMap = new HashMap<>(); + parameterMap.put("name", "Baeldung"); + + String templateString = template.apply(parameterMap); + + assertThat(templateString).isEqualTo("Hi Baeldung!"); + } + + @Test + public void whenParameterObjectIsSupplied_ThenDisplays() throws IOException { + Handlebars handlebars = new Handlebars(); + Template template = handlebars.compileInline("Hi {{name}}!"); + Person person = new Person(); + person.setName("Baeldung"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("Hi Baeldung!"); + } + + @Test + public void whenMultipleParametersAreSupplied_ThenDisplays() throws IOException { + Handlebars handlebars = new Handlebars(); + Template template = handlebars.compileInline("Hi {{name}}! This is {{topic}}."); + Map parameterMap = new HashMap<>(); + parameterMap.put("name", "Baeldung"); + parameterMap.put("topic", "Handlebars"); + + String templateString = template.apply(parameterMap); + + assertThat(templateString).isEqualTo("Hi Baeldung! This is Handlebars."); + } + + @Test + public void whenNoLoaderIsGiven_ThenSearchesClasspath() throws IOException { + Handlebars handlebars = new Handlebars(); + Template template = handlebars.compile("greeting"); + Person person = getPerson("Baeldung"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("Hi Baeldung!"); + } + + @Test + public void whenClasspathTemplateLoaderIsGiven_ThenSearchesClasspathWithPrefixSuffix() throws IOException { + TemplateLoader loader = new ClassPathTemplateLoader("/handlebars", ".html"); + Handlebars handlebars = new Handlebars(loader); + Template template = handlebars.compile("greeting"); + Person person = getPerson("Baeldung"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("Hi Baeldung!"); + } + + @Test + public void whenMultipleLoadersAreGiven_ThenSearchesSequentially() throws IOException { + TemplateLoader firstLoader = new ClassPathTemplateLoader("/handlebars", ".html"); + TemplateLoader secondLoader = new ClassPathTemplateLoader("/templates", ".html"); + Handlebars handlebars = new Handlebars().with(firstLoader, secondLoader); + Template template = handlebars.compile("greeting"); + Person person = getPerson("Baeldung"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("Hi Baeldung!"); + } + + private Person getPerson(String name) { + Person person = new Person(); + person.setName(name); + return person; + } +} diff --git a/libraries-2/src/test/java/com/baeldung/handlebars/BuiltinHelperUnitTest.java b/libraries-2/src/test/java/com/baeldung/handlebars/BuiltinHelperUnitTest.java new file mode 100644 index 0000000000..6749f7fe0a --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/handlebars/BuiltinHelperUnitTest.java @@ -0,0 +1,106 @@ +package com.baeldung.handlebars; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.github.jknack.handlebars.Handlebars; +import com.github.jknack.handlebars.Template; +import com.github.jknack.handlebars.io.ClassPathTemplateLoader; +import com.github.jknack.handlebars.io.TemplateLoader; +import java.io.IOException; +import org.junit.Test; + +/** + * Showcases the built-in template helpers. + * + * @author isaolmez + */ +public class BuiltinHelperUnitTest { + + private TemplateLoader templateLoader = new ClassPathTemplateLoader("/handlebars", ".html"); + + @Test + public void whenUsedWith_ThenContextChanges() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + Template template = handlebars.compile("with"); + Person person = getPerson("Baeldung"); + person.getAddress().setStreet("World"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("\n

I live in World

\n"); + } + + @Test + public void whenUsedWithMustacheStyle_ThenContextChanges() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + Template template = handlebars.compile("with_mustache"); + Person person = getPerson("Baeldung"); + person.getAddress().setStreet("World"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("\n

I live in World

\n"); + } + + @Test + public void whenUsedEach_ThenIterates() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + Template template = handlebars.compile("each"); + Person person = getPerson("Baeldung"); + Person friend1 = getPerson("Java"); + Person friend2 = getPerson("Spring"); + person.getFriends().add(friend1); + person.getFriends().add(friend2); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("\nJava is my friend.\n" + + "\nSpring is my friend.\n"); + } + + @Test + public void whenUsedEachMustacheStyle_ThenIterates() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + Template template = handlebars.compile("each_mustache"); + Person person = getPerson("Baeldung"); + Person friend1 = getPerson("Java"); + Person friend2 = getPerson("Spring"); + person.getFriends().add(friend1); + person.getFriends().add(friend2); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("\nJava is my friend.\n" + + "\nSpring is my friend.\n"); + } + + @Test + public void whenUsedIf_ThenPutsCondition() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + Template template = handlebars.compile("if"); + Person person = getPerson("Baeldung"); + person.setBusy(true); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("\n

Baeldung is busy.

\n"); + } + + @Test + public void whenUsedIfMustacheStyle_ThenPutsCondition() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + Template template = handlebars.compile("if_mustache"); + Person person = getPerson("Baeldung"); + person.setBusy(true); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("\n

Baeldung is busy.

\n"); + } + + private Person getPerson(String name) { + Person person = new Person(); + person.setName(name); + return person; + } +} diff --git a/libraries-2/src/test/java/com/baeldung/handlebars/CustomHelperUnitTest.java b/libraries-2/src/test/java/com/baeldung/handlebars/CustomHelperUnitTest.java new file mode 100644 index 0000000000..a3c6667654 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/handlebars/CustomHelperUnitTest.java @@ -0,0 +1,59 @@ +package com.baeldung.handlebars; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.github.jknack.handlebars.Handlebars; +import com.github.jknack.handlebars.Helper; +import com.github.jknack.handlebars.Options; +import com.github.jknack.handlebars.Template; +import com.github.jknack.handlebars.io.ClassPathTemplateLoader; +import com.github.jknack.handlebars.io.TemplateLoader; +import java.io.IOException; +import org.junit.Test; + +/** + * Showcases implementing a custom template helper. + * + * @author isaolmez + */ +public class CustomHelperUnitTest { + + private TemplateLoader templateLoader = new ClassPathTemplateLoader("/handlebars", ".html"); + + @Test + public void whenHelperIsCreated_ThenCanRegister() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + handlebars.registerHelper("isBusy", new Helper() { + @Override + public Object apply(Person context, Options options) throws IOException { + String busyString = context.isBusy() ? "busy" : "available"; + return context.getName() + " - " + busyString; + } + }); + Template template = handlebars.compile("person"); + Person person = getPerson("Baeldung"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("Baeldung - busy"); + } + + @Test + public void whenHelperSourceIsCreated_ThenCanRegister() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + handlebars.registerHelpers(new HelperSource()); + Template template = handlebars.compile("person"); + Person person = getPerson("Baeldung"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("Baeldung - busy"); + } + + private Person getPerson(String name) { + Person person = new Person(); + person.setName(name); + person.setBusy(true); + return person; + } +} diff --git a/libraries-2/src/test/java/com/baeldung/handlebars/HelperSource.java b/libraries-2/src/test/java/com/baeldung/handlebars/HelperSource.java new file mode 100644 index 0000000000..b98786c029 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/handlebars/HelperSource.java @@ -0,0 +1,9 @@ +package com.baeldung.handlebars; + +public class HelperSource { + + public String isBusy(Person context) { + String busyString = context.isBusy() ? "busy" : "available"; + return context.getName() + " - " + busyString; + } +} diff --git a/libraries-2/src/test/java/com/baeldung/handlebars/Person.java b/libraries-2/src/test/java/com/baeldung/handlebars/Person.java new file mode 100644 index 0000000000..9ddc0fdffb --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/handlebars/Person.java @@ -0,0 +1,58 @@ +package com.baeldung.handlebars; + +import java.util.ArrayList; +import java.util.List; + +public class Person { + + private String name; + private boolean busy; + private Address address = new Address(); + private List friends = new ArrayList<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isBusy() { + return busy; + } + + public void setBusy(boolean busy) { + this.busy = busy; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public List getFriends() { + return friends; + } + + public void setFriends(List friends) { + this.friends = friends; + } + + public static class Address { + + private String street; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/handlebars/ReusingTemplatesUnitTest.java b/libraries-2/src/test/java/com/baeldung/handlebars/ReusingTemplatesUnitTest.java new file mode 100644 index 0000000000..36f78f486e --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/handlebars/ReusingTemplatesUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.handlebars; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.github.jknack.handlebars.Handlebars; +import com.github.jknack.handlebars.Template; +import com.github.jknack.handlebars.io.ClassPathTemplateLoader; +import com.github.jknack.handlebars.io.TemplateLoader; +import java.io.IOException; +import org.junit.Test; + +/** + * Showcases reusing the existing templates. + * + * @author isaolmez + */ +public class ReusingTemplatesUnitTest { + + private TemplateLoader templateLoader = new ClassPathTemplateLoader("/handlebars", ".html"); + + @Test + public void whenOtherTemplateIsReferenced_ThenCanReuse() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + Template template = handlebars.compile("page"); + Person person = new Person(); + person.setName("Baeldung"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("

Hi Baeldung!

\n

This is the page Baeldung

"); + } + + @Test + public void whenBlockIsDefined_ThenCanOverrideWithPartial() throws IOException { + Handlebars handlebars = new Handlebars(templateLoader); + Template template = handlebars.compile("simplemessage"); + Person person = new Person(); + person.setName("Baeldung"); + + String templateString = template.apply(person); + + assertThat(templateString).isEqualTo("\n\n" + + "\n" + + "\n This is the intro\n\n" + + "\n Hi there!\n\n" + + "\n" + + ""); + } +} diff --git a/libraries-2/src/test/java/com/baeldung/mapdb/CollectionsUnitTest.java b/libraries-2/src/test/java/com/baeldung/mapdb/CollectionsUnitTest.java new file mode 100644 index 0000000000..6f5141b054 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/mapdb/CollectionsUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.mapdb; + +import org.junit.Test; +import org.mapdb.DB; +import org.mapdb.DBMaker; +import org.mapdb.Serializer; + +import java.util.NavigableSet; + +import static junit.framework.Assert.assertEquals; + +public class CollectionsUnitTest { + + @Test + public void givenSetCreatedInDB_whenMultipleElementsAdded_checkOnlyOneExists() { + + DB db = DBMaker.memoryDB().make(); + + NavigableSet set = db. + treeSet("mySet") + .serializer(Serializer.STRING) + .createOrOpen(); + + String myString = "Baeldung!"; + + set.add(myString); + set.add(myString); + + assertEquals(1, set.size()); + + db.close(); + } +} diff --git a/libraries-2/src/test/java/com/baeldung/mapdb/HTreeMapUnitTest.java b/libraries-2/src/test/java/com/baeldung/mapdb/HTreeMapUnitTest.java new file mode 100644 index 0000000000..3b7cac04fb --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/mapdb/HTreeMapUnitTest.java @@ -0,0 +1,38 @@ +package com.baeldung.mapdb; + +import org.jetbrains.annotations.NotNull; +import org.junit.Test; +import org.mapdb.*; + +import java.io.IOException; + +import static junit.framework.Assert.assertEquals; + +public class HTreeMapUnitTest { + + @Test + public void givenValidDB_whenHTreeMapAddedToAndRetrieved_CheckedRetrievalCorrect() { + + DB db = DBMaker.memoryDB().make(); + + HTreeMap hTreeMap = db + .hashMap("myTreMap") + .keySerializer(Serializer.STRING) + .valueSerializer(Serializer.STRING) + .create(); + + hTreeMap.put("key1", "value1"); + hTreeMap.put("key2", "value2"); + + assertEquals(2, hTreeMap.size()); + + //add another value with the same key + + hTreeMap.put("key1", "value3"); + + assertEquals(2, hTreeMap.size()); + assertEquals("value3", hTreeMap.get("key1")); + + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/mapdb/HelloBaeldungUnitTest.java b/libraries-2/src/test/java/com/baeldung/mapdb/HelloBaeldungUnitTest.java new file mode 100644 index 0000000000..952efd0639 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/mapdb/HelloBaeldungUnitTest.java @@ -0,0 +1,49 @@ +package com.baeldung.mapdb; + +import org.junit.Test; +import org.mapdb.DB; +import org.mapdb.DBMaker; +import org.mapdb.HTreeMap; + +import java.util.concurrent.ConcurrentMap; + +import static junit.framework.Assert.assertEquals; + +public class HelloBaeldungUnitTest { + + @Test + public void givenInMemoryDBInstantiateCorrectly_whenDataSavedAndRetrieved_checkRetrievalCorrect() { + + DB db = DBMaker.memoryDB().make(); + + String welcomeMessageKey = "Welcome Message"; + String welcomeMessageString = "Hello Baeldung!"; + + HTreeMap myMap = db.hashMap("myMap").createOrOpen(); + myMap.put(welcomeMessageKey, welcomeMessageString); + + String welcomeMessageFromDB = (String) myMap.get(welcomeMessageKey); + + db.close(); + + assertEquals(welcomeMessageString, welcomeMessageFromDB); + } + + @Test + public void givenInFileDBInstantiateCorrectly_whenDataSavedAndRetrieved_checkRetrievalCorrect() { + + DB db = DBMaker.fileDB("file.db").make(); + + String welcomeMessageKey = "Welcome Message"; + String welcomeMessageString = "Hello Baeldung!"; + + HTreeMap myMap = db.hashMap("myMap").createOrOpen(); + myMap.put(welcomeMessageKey, welcomeMessageString); + + String welcomeMessageFromDB = (String) myMap.get(welcomeMessageKey); + + db.close(); + + assertEquals(welcomeMessageString, welcomeMessageFromDB); + } +} diff --git a/libraries-2/src/test/java/com/baeldung/mapdb/InMemoryModesUnitTest.java b/libraries-2/src/test/java/com/baeldung/mapdb/InMemoryModesUnitTest.java new file mode 100644 index 0000000000..9c53f9c792 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/mapdb/InMemoryModesUnitTest.java @@ -0,0 +1,62 @@ +package com.baeldung.mapdb; + +import org.junit.Test; +import org.mapdb.DB; +import org.mapdb.DBMaker; +import org.mapdb.HTreeMap; +import org.mapdb.Serializer; + +import static junit.framework.Assert.assertEquals; + +public class InMemoryModesUnitTest { + + @Test + public void givenDBCreatedOnHeap_whenUsed_checkUsageCorrect() { + + DB heapDB = DBMaker.heapDB().make(); + + HTreeMap map = heapDB + .hashMap("myMap") + .keySerializer(Serializer.INTEGER) + .valueSerializer(Serializer.STRING) + .createOrOpen(); + + map.put(1, "ONE"); + + assertEquals("ONE", map.get(1)); + + } + + @Test + public void givenDBCreatedBaseOnByteArray_whenUsed_checkUsageCorrect() { + + DB heapDB = DBMaker.memoryDB().make(); + + HTreeMap map = heapDB + .hashMap("myMap") + .keySerializer(Serializer.INTEGER) + .valueSerializer(Serializer.STRING) + .createOrOpen(); + + map.put(1, "ONE"); + + assertEquals("ONE", map.get(1)); + } + + @Test + public void givenDBCreatedBaseOnDirectByteBuffer_whenUsed_checkUsageCorrect() { + + DB heapDB = DBMaker.memoryDirectDB().make(); + + HTreeMap map = heapDB + .hashMap("myMap") + .keySerializer(Serializer.INTEGER) + .valueSerializer(Serializer.STRING) + .createOrOpen(); + + map.put(1, "ONE"); + + assertEquals("ONE", map.get(1)); + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/mapdb/SortedTableMapUnitTest.java b/libraries-2/src/test/java/com/baeldung/mapdb/SortedTableMapUnitTest.java new file mode 100644 index 0000000000..83ba917393 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/mapdb/SortedTableMapUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.mapdb; + +import org.junit.Test; +import org.mapdb.Serializer; +import org.mapdb.SortedTableMap; +import org.mapdb.volume.MappedFileVol; +import org.mapdb.volume.Volume; + +import static junit.framework.Assert.assertEquals; + +public class SortedTableMapUnitTest { + + private static final String VOLUME_LOCATION = "sortedTableMapVol.db"; + + @Test + public void givenValidSortedTableMapSetup_whenQueried_checkValuesCorrect() { + + //create memory mapped volume, readonly false + Volume vol = MappedFileVol.FACTORY.makeVolume(VOLUME_LOCATION, false); + + //create sink to feed the map with data + SortedTableMap.Sink sink = + SortedTableMap.create( + vol, + Serializer.INTEGER, + Serializer.STRING + ).createFromSink(); + + //add content + for(int i = 0; i < 100; i++){ + sink.put(i, "Value " + Integer.toString(i)); + } + + sink.create(); + + //now open in read-only mode + Volume openVol = MappedFileVol.FACTORY.makeVolume(VOLUME_LOCATION, true); + + SortedTableMap sortedTableMap = SortedTableMap.open( + openVol, + Serializer.INTEGER, + Serializer.STRING + ); + + assertEquals(100, sortedTableMap.size()); + } +} diff --git a/libraries-2/src/test/java/com/baeldung/mapdb/TransactionsUnitTest.java b/libraries-2/src/test/java/com/baeldung/mapdb/TransactionsUnitTest.java new file mode 100644 index 0000000000..4de9db10e8 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/mapdb/TransactionsUnitTest.java @@ -0,0 +1,41 @@ +package com.baeldung.mapdb; + +import org.junit.Test; +import org.mapdb.DB; +import org.mapdb.DBMaker; +import org.mapdb.Serializer; + +import java.util.NavigableSet; + +import static junit.framework.Assert.assertEquals; + +public class TransactionsUnitTest { + + @Test + public void givenValidDBSetup_whenTransactionCommittedAndRolledBack_checkPreviousStateAchieved() { + + DB db = DBMaker.memoryDB().transactionEnable().make(); + + NavigableSet set = db + .treeSet("mySet") + .serializer(Serializer.STRING) + .createOrOpen(); + + set.add("One"); + set.add("Two"); + + db.commit(); + + assertEquals(2, set.size()); + + set.add("Three"); + + assertEquals(3, set.size()); + + db.rollback(); + + assertEquals(2, set.size()); + + db.close(); + } +} diff --git a/libraries-2/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java b/libraries-2/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java new file mode 100644 index 0000000000..1e3b183aa7 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/matrices/MatrixMultiplicationBenchmarking.java @@ -0,0 +1,9 @@ +package com.baeldung.matrices; + +public class MatrixMultiplicationBenchmarking { + + public static void main(String[] args) throws Exception { + org.openjdk.jmh.Main.main(args); + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java b/libraries-2/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java new file mode 100644 index 0000000000..05944e7b3a --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/matrices/apache/RealMatrixUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.matrices.apache; + +import org.apache.commons.math3.linear.Array2DRowRealMatrix; +import org.apache.commons.math3.linear.RealMatrix; +import org.junit.jupiter.api.Test; +import org.openjdk.jmh.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; + +@BenchmarkMode(Mode.AverageTime) +@Fork(value = 2) +@Warmup(iterations = 5) +@Measurement(iterations = 10) +public class RealMatrixUnitTest { + + @Test + @Benchmark + public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + RealMatrix firstMatrix = new Array2DRowRealMatrix( + new double[][] { + new double[] {1d, 5d}, + new double[] {2d, 3d}, + new double[] {1d ,7d} + } + ); + + RealMatrix secondMatrix = new Array2DRowRealMatrix( + new double[][] { + new double[] {1d, 2d, 3d, 7d}, + new double[] {5d, 2d, 8d, 1d} + } + ); + + RealMatrix expected = new Array2DRowRealMatrix( + new double[][] { + new double[] {26d, 12d, 43d, 12d}, + new double[] {17d, 10d, 30d, 17d}, + new double[] {36d, 16d, 59d, 14d} + } + ); + + RealMatrix actual = firstMatrix.multiply(secondMatrix); + + assertThat(actual).isEqualTo(expected); + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java b/libraries-2/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java new file mode 100644 index 0000000000..fb4a419eb0 --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/matrices/colt/DoubleMatrix2DUnitTest.java @@ -0,0 +1,51 @@ +package com.baeldung.matrices.colt; + +import cern.colt.matrix.DoubleFactory2D; +import cern.colt.matrix.DoubleMatrix2D; +import cern.colt.matrix.linalg.Algebra; +import org.junit.jupiter.api.Test; +import org.openjdk.jmh.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; + +@BenchmarkMode(Mode.AverageTime) +@Fork(value = 2) +@Warmup(iterations = 5) +@Measurement(iterations = 10) +public class DoubleMatrix2DUnitTest { + + @Test + @Benchmark + public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + DoubleFactory2D doubleFactory2D = DoubleFactory2D.dense; + + DoubleMatrix2D firstMatrix = doubleFactory2D.make( + new double[][] { + new double[] {1d, 5d}, + new double[] {2d, 3d}, + new double[] {1d ,7d} + } + ); + + DoubleMatrix2D secondMatrix = doubleFactory2D.make( + new double[][] { + new double[] {1d, 2d, 3d, 7d}, + new double[] {5d, 2d, 8d, 1d} + } + ); + + DoubleMatrix2D expected = doubleFactory2D.make( + new double[][] { + new double[] {26d, 12d, 43d, 12d}, + new double[] {17d, 10d, 30d, 17d}, + new double[] {36d, 16d, 59d, 14d} + } + ); + + Algebra algebra = new Algebra(); + DoubleMatrix2D actual = algebra.mult(firstMatrix, secondMatrix); + + assertThat(actual).isEqualTo(expected); + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java b/libraries-2/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java new file mode 100644 index 0000000000..b025266a1d --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/matrices/ejml/SimpleMatrixUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.matrices.ejml; + +import org.ejml.simple.SimpleMatrix; +import org.junit.jupiter.api.Test; +import org.openjdk.jmh.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; + +@BenchmarkMode(Mode.AverageTime) +@Fork(value = 2) +@Warmup(iterations = 5) +@Measurement(iterations = 10) +public class SimpleMatrixUnitTest { + + @Test + @Benchmark + public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + SimpleMatrix firstMatrix = new SimpleMatrix( + new double[][] { + new double[] {1d, 5d}, + new double[] {2d, 3d}, + new double[] {1d ,7d} + } + ); + + SimpleMatrix secondMatrix = new SimpleMatrix( + new double[][] { + new double[] {1d, 2d, 3d, 7d}, + new double[] {5d, 2d, 8d, 1d} + } + ); + + SimpleMatrix expected = new SimpleMatrix( + new double[][] { + new double[] {26d, 12d, 43d, 12d}, + new double[] {17d, 10d, 30d, 17d}, + new double[] {36d, 16d, 59d, 14d} + } + ); + + SimpleMatrix actual = firstMatrix.mult(secondMatrix); + + assertThat(actual).matches(m -> m.isIdentical(expected, 0d)); + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java b/libraries-2/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java new file mode 100644 index 0000000000..be9e483d5b --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/matrices/homemade/HomemadeMatrixUnitTest.java @@ -0,0 +1,58 @@ +package com.baeldung.matrices.homemade; + +import org.junit.jupiter.api.Test; +import org.openjdk.jmh.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; + +@BenchmarkMode(Mode.AverageTime) +@Fork(value = 2) +@Warmup(iterations = 5) +@Measurement(iterations = 10) +public class HomemadeMatrixUnitTest { + + @Test + @Benchmark + public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + double[][] firstMatrix = { + new double[]{1d, 5d}, + new double[]{2d, 3d}, + new double[]{1d, 7d} + }; + + double[][] secondMatrix = { + new double[]{1d, 2d, 3d, 7d}, + new double[]{5d, 2d, 8d, 1d} + }; + + double[][] expected = { + new double[]{26d, 12d, 43d, 12d}, + new double[]{17d, 10d, 30d, 17d}, + new double[]{36d, 16d, 59d, 14d} + }; + + double[][] actual = multiplyMatrices(firstMatrix, secondMatrix); + + assertThat(actual).isEqualTo(expected); + } + + private double[][] multiplyMatrices(double[][] firstMatrix, double[][] secondMatrix) { + double[][] result = new double[firstMatrix.length][secondMatrix[0].length]; + + for (int row = 0; row < result.length; row++) { + for (int col = 0; col < result[row].length; col++) { + result[row][col] = multiplyMatricesCell(firstMatrix, secondMatrix, row, col); + } + } + + return result; + } + + private double multiplyMatricesCell(double[][] firstMatrix, double[][] secondMatrix, int row, int col) { + double cell = 0; + for (int i = 0; i < secondMatrix.length; i++) { + cell += firstMatrix[row][i] * secondMatrix[i][col]; + } + return cell; + } +} diff --git a/libraries-2/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java b/libraries-2/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java new file mode 100644 index 0000000000..afb84ff3db --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/matrices/la4j/Basic2DMatrixUnitTest.java @@ -0,0 +1,47 @@ +package com.baeldung.matrices.la4j; + +import org.junit.jupiter.api.Test; +import org.la4j.Matrix; +import org.la4j.matrix.dense.Basic2DMatrix; +import org.openjdk.jmh.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; + +@BenchmarkMode(Mode.AverageTime) +@Fork(value = 2) +@Warmup(iterations = 5) +@Measurement(iterations = 10) +public class Basic2DMatrixUnitTest { + + @Test + @Benchmark + public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + Matrix firstMatrix = new Basic2DMatrix( + new double[][]{ + new double[]{1d, 5d}, + new double[]{2d, 3d}, + new double[]{1d, 7d} + } + ); + + Matrix secondMatrix = new Basic2DMatrix( + new double[][]{ + new double[]{1d, 2d, 3d, 7d}, + new double[]{5d, 2d, 8d, 1d} + } + ); + + Matrix expected = new Basic2DMatrix( + new double[][]{ + new double[]{26d, 12d, 43d, 12d}, + new double[]{17d, 10d, 30d, 17d}, + new double[]{36d, 16d, 59d, 14d} + } + ); + + Matrix actual = firstMatrix.multiply(secondMatrix); + + assertThat(actual).isEqualTo(expected); + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java b/libraries-2/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java new file mode 100644 index 0000000000..fb3030bccf --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/matrices/nd4j/INDArrayUnitTest.java @@ -0,0 +1,46 @@ +package com.baeldung.matrices.nd4j; + +import org.junit.jupiter.api.Test; +import org.nd4j.linalg.api.ndarray.INDArray; +import org.nd4j.linalg.factory.Nd4j; +import org.openjdk.jmh.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; + +@BenchmarkMode(Mode.AverageTime) +@Fork(value = 2) +@Warmup(iterations = 5) +@Measurement(iterations = 10) +public class INDArrayUnitTest { + + @Test + public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() { + INDArray firstMatrix = Nd4j.create( + new double[][]{ + new double[]{1d, 5d}, + new double[]{2d, 3d}, + new double[]{1d, 7d} + } + ); + + INDArray secondMatrix = Nd4j.create( + new double[][] { + new double[] {1d, 2d, 3d, 7d}, + new double[] {5d, 2d, 8d, 1d} + } + ); + + INDArray expected = Nd4j.create( + new double[][] { + new double[] {26d, 12d, 43d, 12d}, + new double[] {17d, 10d, 30d, 17d}, + new double[] {36d, 16d, 59d, 14d} + } + ); + + INDArray actual = firstMatrix.mmul(secondMatrix); + + assertThat(actual).isEqualTo(expected); + } + +} diff --git a/libraries-2/src/test/java/com/baeldung/parallel_collectors/ParallelCollectorsUnitTest.java b/libraries-2/src/test/java/com/baeldung/parallel_collectors/ParallelCollectorsUnitTest.java new file mode 100644 index 0000000000..adc753a8ad --- /dev/null +++ b/libraries-2/src/test/java/com/baeldung/parallel_collectors/ParallelCollectorsUnitTest.java @@ -0,0 +1,168 @@ +package com.baeldung.parallel_collectors; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; + +import static com.pivovarit.collectors.ParallelCollectors.parallel; +import static com.pivovarit.collectors.ParallelCollectors.parallelOrdered; +import static com.pivovarit.collectors.ParallelCollectors.parallelToCollection; +import static com.pivovarit.collectors.ParallelCollectors.parallelToList; +import static com.pivovarit.collectors.ParallelCollectors.parallelToMap; +import static com.pivovarit.collectors.ParallelCollectors.parallelToStream; + +public class ParallelCollectorsUnitTest { + + @Test + public void shouldProcessInParallelWithStreams() { + List ids = Arrays.asList(1, 2, 3); + + List results = ids.parallelStream() + .map(i -> fetchById(i)) + .collect(Collectors.toList()); + + System.out.println(results); + } + + @Test + public void shouldProcessInParallelWithParallelCollectors() { + ExecutorService executor = Executors.newFixedThreadPool(10); + + List ids = Arrays.asList(1, 2, 3); + + CompletableFuture> results = ids.stream() + .collect(parallelToList(i -> fetchById(i), executor, 4)); + + System.out.println(results.join()); + } + + @Test + public void shouldCollectToList() { + ExecutorService executor = Executors.newFixedThreadPool(10); + + List ids = Arrays.asList(1, 2, 3); + + List results = ids.stream() + .collect(parallelToList(i -> fetchById(i), executor, 4)) + .join(); + + System.out.println(results); // [user-1, user-2, user-3] + } + + @Test + public void shouldCollectToCollection() { + ExecutorService executor = Executors.newFixedThreadPool(10); + + List ids = Arrays.asList(1, 2, 3); + + List results = ids.stream() + .collect(parallelToCollection(i -> fetchById(i), LinkedList::new, executor, 4)) + .join(); + + System.out.println(results); // [user-1, user-2, user-3] + } + + @Test + public void shouldCollectToStream() { + ExecutorService executor = Executors.newFixedThreadPool(10); + + List ids = Arrays.asList(1, 2, 3); + + Map> results = ids.stream() + .collect(parallelToStream(i -> fetchById(i), executor, 4)) + .thenApply(stream -> stream.collect(Collectors.groupingBy(i -> i.length()))) + .join(); + + System.out.println(results); // [user-1, user-2, user-3] + } + + @Test + public void shouldStreamInCompletionOrder() { + ExecutorService executor = Executors.newFixedThreadPool(10); + + List ids = Arrays.asList(1, 2, 3); + + ids.stream() + .collect(parallel(i -> fetchByIdWithRandomDelay(i), executor, 4)) + .forEach(System.out::println); + } + + @Test + public void shouldStreamInOriginalOrder() { + ExecutorService executor = Executors.newFixedThreadPool(10); + + List ids = Arrays.asList(1, 2, 3); + + ids.stream() + .collect(parallelOrdered(i -> fetchByIdWithRandomDelay(i), executor, 4)) + .forEach(System.out::println); + } + + @Test + public void shouldCollectToMap() { + ExecutorService executor = Executors.newFixedThreadPool(10); + + List ids = Arrays.asList(1, 2, 3); + + Map results = ids.stream() + .collect(parallelToMap(i -> i, i -> fetchById(i), executor, 4)) + .join(); + + System.out.println(results); // {1=user-1, 2=user-2, 3=user-3} + } + + @Test + public void shouldCollectToTreeMap() { + ExecutorService executor = Executors.newFixedThreadPool(10); + + List ids = Arrays.asList(1, 2, 3); + + Map results = ids.stream() + .collect(parallelToMap(i -> i, i -> fetchById(i), TreeMap::new, executor, 4)) + .join(); + + System.out.println(results); // {1=user-1, 2=user-2, 3=user-3} + } + + @Test + public void shouldCollectToTreeMapAndResolveClashes() { + ExecutorService executor = Executors.newFixedThreadPool(10); + + List ids = Arrays.asList(1, 2, 3); + + Map results = ids.stream() + .collect(parallelToMap(i -> i, i -> fetchById(i), TreeMap::new, (s1, s2) -> s1, executor, 4)) + .join(); + + System.out.println(results); // {1=user-1, 2=user-2, 3=user-3} + } + + private static String fetchById(int id) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + // ignore shamelessly + } + + return "user-" + id; + } + + private static String fetchByIdWithRandomDelay(int id) { + try { + Thread.sleep(ThreadLocalRandom.current().nextInt(1000)); + } catch (InterruptedException e) { + // ignore shamelessly + } + + return "user-" + id; + } +} diff --git a/libraries-2/src/test/resources/greeting.hbs b/libraries-2/src/test/resources/greeting.hbs new file mode 100644 index 0000000000..71a8266bce --- /dev/null +++ b/libraries-2/src/test/resources/greeting.hbs @@ -0,0 +1 @@ +Hi {{name}}! \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/each.html b/libraries-2/src/test/resources/handlebars/each.html new file mode 100644 index 0000000000..1570311bfc --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/each.html @@ -0,0 +1,3 @@ +{{#each friends}} +{{name}} is my friend. +{{/each}} \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/each_mustache.html b/libraries-2/src/test/resources/handlebars/each_mustache.html new file mode 100644 index 0000000000..1570311bfc --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/each_mustache.html @@ -0,0 +1,3 @@ +{{#each friends}} +{{name}} is my friend. +{{/each}} \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/greeting.html b/libraries-2/src/test/resources/handlebars/greeting.html new file mode 100644 index 0000000000..71a8266bce --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/greeting.html @@ -0,0 +1 @@ +Hi {{name}}! \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/header.html b/libraries-2/src/test/resources/handlebars/header.html new file mode 100644 index 0000000000..80cca699e4 --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/header.html @@ -0,0 +1 @@ +

Hi {{name}}!

\ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/if.html b/libraries-2/src/test/resources/handlebars/if.html new file mode 100644 index 0000000000..ebdc724f66 --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/if.html @@ -0,0 +1,5 @@ +{{#if busy}} +

{{name}} is busy.

+{{else}} +

{{name}} is not busy.

+{{/if}} \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/if_mustache.html b/libraries-2/src/test/resources/handlebars/if_mustache.html new file mode 100644 index 0000000000..d75f5fa8f9 --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/if_mustache.html @@ -0,0 +1,5 @@ +{{#if busy}} +

{{name}} is busy.

+{{^}} +

{{name}} is not busy.

+{{/if}} \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/messagebase.html b/libraries-2/src/test/resources/handlebars/messagebase.html new file mode 100644 index 0000000000..7ee3257e06 --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/messagebase.html @@ -0,0 +1,9 @@ + + +{{#block "intro"}} + This is the intro +{{/block}} +{{#block "message"}} +{{/block}} + + \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/page.html b/libraries-2/src/test/resources/handlebars/page.html new file mode 100644 index 0000000000..27b20737f3 --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/page.html @@ -0,0 +1,2 @@ +{{>header}} +

This is the page {{name}}

\ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/person.html b/libraries-2/src/test/resources/handlebars/person.html new file mode 100644 index 0000000000..9df7850f60 --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/person.html @@ -0,0 +1 @@ +{{#isBusy this}}{{/isBusy}} \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/simplemessage.html b/libraries-2/src/test/resources/handlebars/simplemessage.html new file mode 100644 index 0000000000..3b3a01980a --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/simplemessage.html @@ -0,0 +1,4 @@ +{{#partial "message" }} + Hi there! +{{/partial}} +{{> messagebase}} \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/with.html b/libraries-2/src/test/resources/handlebars/with.html new file mode 100644 index 0000000000..90077b4835 --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/with.html @@ -0,0 +1,3 @@ +{{#with address}} +

I live in {{street}}

+{{/with}} \ No newline at end of file diff --git a/libraries-2/src/test/resources/handlebars/with_mustache.html b/libraries-2/src/test/resources/handlebars/with_mustache.html new file mode 100644 index 0000000000..3adf6a7556 --- /dev/null +++ b/libraries-2/src/test/resources/handlebars/with_mustache.html @@ -0,0 +1,3 @@ +{{#address}} +

I live in {{street}}

+{{/address}} \ No newline at end of file diff --git a/libraries-server/pom.xml b/libraries-server/pom.xml index a6ead8fb31..72794729a5 100644 --- a/libraries-server/pom.xml +++ b/libraries-server/pom.xml @@ -65,7 +65,7 @@ ${junit.version} test - + org.apache.tomcat @@ -96,6 +96,19 @@ smack-java7 ${smack.version} + + + + org.nanohttpd + nanohttpd + ${nanohttpd.version} + + + org.nanohttpd + nanohttpd-nanolets + ${nanohttpd.version} + + @@ -107,7 +120,8 @@ 4.1 8.5.24 4.3.1 - 1.2.0 + 1.2.0 + 2.3.1 \ No newline at end of file diff --git a/libraries-server/src/main/java/com/baeldung/nanohttpd/ApplicationController.java b/libraries-server/src/main/java/com/baeldung/nanohttpd/ApplicationController.java new file mode 100644 index 0000000000..2fa54c3ae2 --- /dev/null +++ b/libraries-server/src/main/java/com/baeldung/nanohttpd/ApplicationController.java @@ -0,0 +1,38 @@ +package com.baeldung.nanohttpd; + +import fi.iki.elonen.NanoHTTPD; +import fi.iki.elonen.router.RouterNanoHTTPD; + +import java.io.IOException; + +public class ApplicationController extends RouterNanoHTTPD { + + ApplicationController() throws IOException { + super(8072); + addMappings(); + start(NanoHTTPD.SOCKET_READ_TIMEOUT, false); + } + + @Override + public void addMappings() { + addRoute("/", IndexHandler.class); + addRoute("/users", UserHandler.class); + } + + public static class UserHandler extends DefaultHandler { + @Override + public String getText() { + return "UserA, UserB, UserC"; + } + + @Override + public String getMimeType() { + return MIME_PLAINTEXT; + } + + @Override + public Response.IStatus getStatus() { + return Response.Status.OK; + } + } +} \ No newline at end of file diff --git a/libraries-server/src/main/java/com/baeldung/nanohttpd/ItemGetController.java b/libraries-server/src/main/java/com/baeldung/nanohttpd/ItemGetController.java new file mode 100644 index 0000000000..4a9c48fbfd --- /dev/null +++ b/libraries-server/src/main/java/com/baeldung/nanohttpd/ItemGetController.java @@ -0,0 +1,22 @@ +package com.baeldung.nanohttpd; + +import fi.iki.elonen.NanoHTTPD; + +import java.io.IOException; + +public class ItemGetController extends NanoHTTPD { + + ItemGetController() throws IOException { + super(8071); + start(NanoHTTPD.SOCKET_READ_TIMEOUT, false); + } + + @Override + public Response serve(IHTTPSession session) { + if (session.getMethod() == Method.GET) { + String itemIdRequestParam = session.getParameters().get("itemId").get(0); + return newFixedLengthResponse("Requested itemId = " + itemIdRequestParam); + } + return newFixedLengthResponse(Response.Status.NOT_FOUND, MIME_PLAINTEXT, "The requested resource does not exist"); + } +} \ No newline at end of file diff --git a/libraries-server/src/test/java/com/baeldung/nanohttpd/ApplicationControllerUnitTest.java b/libraries-server/src/test/java/com/baeldung/nanohttpd/ApplicationControllerUnitTest.java new file mode 100644 index 0000000000..003f6ee3b7 --- /dev/null +++ b/libraries-server/src/test/java/com/baeldung/nanohttpd/ApplicationControllerUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.nanohttpd; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.HttpClientBuilder; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.*; + +public class ApplicationControllerUnitTest { + + private static final String BASE_URL = "http://localhost:8072/"; + private static final HttpClient CLIENT = HttpClientBuilder.create().build(); + + @BeforeClass + public static void setUp() throws IOException { + new ApplicationController(); + } + + @Test + public void givenServer_whenRootRouteRequested_thenHelloWorldReturned() throws IOException { + HttpResponse response = CLIENT.execute(new HttpGet(BASE_URL)); + assertTrue(IOUtils.toString(response.getEntity().getContent()).contains("Hello world!")); + assertEquals(200, response.getStatusLine().getStatusCode()); + } + + @Test + public void givenServer_whenUsersRequested_thenThenAllUsersReturned() throws IOException { + HttpResponse response = CLIENT.execute(new HttpGet(BASE_URL + "users")); + assertEquals("UserA, UserB, UserC", IOUtils.toString(response.getEntity().getContent())); + } +} \ No newline at end of file diff --git a/libraries-server/src/test/java/com/baeldung/nanohttpd/ItemGetControllerUnitTest.java b/libraries-server/src/test/java/com/baeldung/nanohttpd/ItemGetControllerUnitTest.java new file mode 100644 index 0000000000..3a4f0a4d98 --- /dev/null +++ b/libraries-server/src/test/java/com/baeldung/nanohttpd/ItemGetControllerUnitTest.java @@ -0,0 +1,37 @@ +package com.baeldung.nanohttpd; + +import static org.junit.Assert.*; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.HttpClientBuilder; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.IOException; + +public class ItemGetControllerUnitTest { + + private static final String URL = "http://localhost:8071"; + private static final HttpClient CLIENT = HttpClientBuilder.create().build(); + + @BeforeClass + public static void setUp() throws IOException { + new ItemGetController(); + } + + @Test + public void givenServer_whenDoingGet_thenParamIsReadCorrectly() throws IOException { + HttpResponse response = CLIENT.execute(new HttpGet(URL + "?itemId=1234")); + assertEquals("Requested itemId = 1234", IOUtils.toString(response.getEntity().getContent())); + } + + @Test + public void givenServer_whenDoingPost_then404IsReturned() throws IOException { + HttpResponse response = CLIENT.execute(new HttpPost(URL)); + assertEquals(404, response.getStatusLine().getStatusCode()); + } +} \ No newline at end of file diff --git a/libraries/pom.xml b/libraries/pom.xml index 7823732224..886dd3c4a2 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -19,6 +19,9 @@ ${typesafe-akka.version} + + + com.typesafe.akka akka-testkit_2.12 @@ -837,6 +840,7 @@ 1.4.196 1.0 + 4.5.3 2.9.7 2.92 diff --git a/persistence-modules/jpa-hibernate-cascade-type/pom.xml b/persistence-modules/jpa-hibernate-cascade-type/pom.xml new file mode 100644 index 0000000000..8cfc2a5fa2 --- /dev/null +++ b/persistence-modules/jpa-hibernate-cascade-type/pom.xml @@ -0,0 +1,71 @@ + + + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + ../../ + + + jpa-hibernate-cascade-type + 4.0.0 + 1.0.0-SNAPSHOT + + + + org.hibernate + hibernate-core + ${hibernate.version} + + + org.assertj + assertj-core + ${assertj-core.version} + test + + + com.h2database + h2 + ${h2.version} + + + + org.hibernate + hibernate-validator + ${hibernate-validator.version} + + + javax.el + javax.el-api + ${javax.el-api.version} + + + org.glassfish + javax.el + ${org.glassfish.javax.el.version} + + + + + jpa-hibernate-cascade-type + + + src/test/resources + true + + + + + + 5.4.3.Final + 3.12.2 + 6.0.17.Final + 3.0.0 + 3.0.1-b11 + 1.8 + 1.8 + + + \ No newline at end of file diff --git a/persistence-modules/jpa-hibernate-cascade-type/src/main/java/com/baeldung/cascading/HibernateUtil.java b/persistence-modules/jpa-hibernate-cascade-type/src/main/java/com/baeldung/cascading/HibernateUtil.java new file mode 100644 index 0000000000..700c289e38 --- /dev/null +++ b/persistence-modules/jpa-hibernate-cascade-type/src/main/java/com/baeldung/cascading/HibernateUtil.java @@ -0,0 +1,45 @@ +package com.baeldung.cascading; + +import com.baeldung.cascading.domain.Address; +import com.baeldung.cascading.domain.Person; +import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Configuration; +import org.hibernate.service.ServiceRegistry; + +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; + +public class HibernateUtil { + private static SessionFactory sessionFactory; + + public static SessionFactory getSessionFactory() { + try { + Properties properties = getProperties(); + Configuration configuration = new Configuration(); + configuration.setProperties(properties); + configuration.addAnnotatedClass(Person.class); + configuration.addAnnotatedClass(Address.class); + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() + .applySettings(configuration.getProperties()).build(); + sessionFactory = configuration.buildSessionFactory(serviceRegistry); + return sessionFactory; + } catch (IOException e) { + e.printStackTrace(); + } + return sessionFactory; + } + + private static Properties getProperties() throws IOException { + Properties properties = new Properties(); + URL propertiesURL = Thread.currentThread() + .getContextClassLoader() + .getResource("hibernate.properties"); + try (FileInputStream inputStream = new FileInputStream(propertiesURL.getFile())) { + properties.load(inputStream); + } + return properties; + } +} diff --git a/persistence-modules/jpa-hibernate-cascade-type/src/main/java/com/baeldung/cascading/domain/Address.java b/persistence-modules/jpa-hibernate-cascade-type/src/main/java/com/baeldung/cascading/domain/Address.java new file mode 100644 index 0000000000..a16b0f81b6 --- /dev/null +++ b/persistence-modules/jpa-hibernate-cascade-type/src/main/java/com/baeldung/cascading/domain/Address.java @@ -0,0 +1,64 @@ +package com.baeldung.cascading.domain; + +import javax.persistence.*; + +@Entity +public class Address { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private int id; + private String street; + private int houseNumber; + private String city; + private int zipCode; + @ManyToOne(fetch = FetchType.LAZY) + private Person person; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public Person getPerson() { + return person; + } + + public void setPerson(Person person) { + this.person = person; + } + + public String getStreet() { + return street; + } + + public int getHouseNumber() { + return houseNumber; + } + + public void setHouseNumber(int houseNumber) { + this.houseNumber = houseNumber; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public int getZipCode() { + return zipCode; + } + + public void setZipCode(int zipCode) { + this.zipCode = zipCode; + } + + public void setStreet(String street) { + this.street = street; + } +} diff --git a/persistence-modules/jpa-hibernate-cascade-type/src/main/java/com/baeldung/cascading/domain/Person.java b/persistence-modules/jpa-hibernate-cascade-type/src/main/java/com/baeldung/cascading/domain/Person.java new file mode 100644 index 0000000000..9ca61323b3 --- /dev/null +++ b/persistence-modules/jpa-hibernate-cascade-type/src/main/java/com/baeldung/cascading/domain/Person.java @@ -0,0 +1,38 @@ +package com.baeldung.cascading.domain; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class Person { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private int id; + private String name; + @OneToMany(mappedBy = "person", cascade = CascadeType.ALL) + private List
addresses; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public List
getAddresses() { + return addresses; + } + + public void setAddresses(List
addresses) { + this.addresses = addresses; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/jpa-hibernate-cascade-type/src/test/java/com/baeldung/cascading/CasCadeTypeUnitTest.java b/persistence-modules/jpa-hibernate-cascade-type/src/test/java/com/baeldung/cascading/CasCadeTypeUnitTest.java new file mode 100644 index 0000000000..a196bdac12 --- /dev/null +++ b/persistence-modules/jpa-hibernate-cascade-type/src/test/java/com/baeldung/cascading/CasCadeTypeUnitTest.java @@ -0,0 +1,169 @@ +package com.baeldung.cascading; + +import com.baeldung.cascading.domain.Address; +import com.baeldung.cascading.domain.Person; +import org.assertj.core.api.Assertions; +import org.hibernate.*; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Arrays; + +public class CasCadeTypeUnitTest { + private static SessionFactory sessionFactory; + private Session session; + private Transaction transaction; + + @BeforeClass + public static void beforeTests() { + sessionFactory = HibernateUtil.getSessionFactory(); + } + + @Before + public void setUp() { + session = sessionFactory.openSession(); + transaction = session.beginTransaction(); + } + + @After + public void tearDown() { + transaction.rollback(); + session.close(); + } + + @Test + public void testPersist() { + Person person = new Person(); + Address address = new Address(); + address.setPerson(person); + person.setAddresses(Arrays.asList(address)); + session.persist(person); + session.flush(); + session.clear(); + } + + @Test + public void testMerge() { + int addressId; + Person person = buildPerson("devender"); + Address address = buildAddress(person); + person.setAddresses(Arrays.asList(address)); + session.persist(person); + session.flush(); + addressId = address.getId(); + session.clear(); + + Address savedAddressEntity = session.find(Address.class, addressId); + Person savedPersonEntity = savedAddressEntity.getPerson(); + savedPersonEntity.setName("devender kumar"); + savedAddressEntity.setHouseNumber(24); + session.merge(savedPersonEntity); + session.flush(); + } + + @Test + public void testRemove() { + int personId; + Person person = buildPerson("devender"); + Address address = buildAddress(person); + person.setAddresses(Arrays.asList(address)); + session.persist(person); + session.flush(); + personId = person.getId(); + session.clear(); + + Person savedPersonEntity = session.find(Person.class, personId); + session.remove(savedPersonEntity); + session.flush(); + } + + @Test + public void testDetach() { + Person person = buildPerson("devender"); + Address address = buildAddress(person); + person.setAddresses(Arrays.asList(address)); + session.persist(person); + session.flush(); + Assertions.assertThat(session.contains(person)).isTrue(); + Assertions.assertThat(session.contains(address)).isTrue(); + + session.detach(person); + Assertions.assertThat(session.contains(person)).isFalse(); + Assertions.assertThat(session.contains(address)).isFalse(); + } + + @Test + public void testLock() { + Person person = buildPerson("devender"); + Address address = buildAddress(person); + person.setAddresses(Arrays.asList(address)); + session.persist(person); + session.flush(); + Assertions.assertThat(session.contains(person)).isTrue(); + Assertions.assertThat(session.contains(address)).isTrue(); + + session.detach(person); + Assertions.assertThat(session.contains(person)).isFalse(); + Assertions.assertThat(session.contains(address)).isFalse(); + session.unwrap(Session.class) + .buildLockRequest(new LockOptions(LockMode.NONE)) + .lock(person); + + Assertions.assertThat(session.contains(person)).isTrue(); + Assertions.assertThat(session.contains(address)).isTrue(); + } + + @Test + public void testRefresh() { + Person person = buildPerson("devender"); + Address address = buildAddress(person); + person.setAddresses(Arrays.asList(address)); + session.persist(person); + session.flush(); + person.setName("Devender Kumar"); + address.setHouseNumber(24); + session.refresh(person); + Assertions.assertThat(person.getName()).isEqualTo("devender"); + Assertions.assertThat(address.getHouseNumber()).isEqualTo(23); + } + + @Test + public void testReplicate() { + Person person = buildPerson("devender"); + person.setId(2); + Address address = buildAddress(person); + address.setId(2); + person.setAddresses(Arrays.asList(address)); + session.unwrap(Session.class).replicate(person, ReplicationMode.OVERWRITE); + session.flush(); + Assertions.assertThat(person.getId()).isEqualTo(2); + Assertions.assertThat(address.getId()).isEqualTo(2); + } + + @Test + public void testSaveOrUpdate() { + Person person = buildPerson("devender"); + Address address = buildAddress(person); + person.setAddresses(Arrays.asList(address)); + session.saveOrUpdate(person); + session.flush(); + } + + private Address buildAddress(Person person) { + Address address = new Address(); + address.setCity("Berlin"); + address.setHouseNumber(23); + address.setStreet("Zeughofstraße"); + address.setZipCode(123001); + address.setPerson(person); + return address; + } + + private Person buildPerson(String name) { + Person person = new Person(); + person.setName(name); + return person; + } +} diff --git a/persistence-modules/jpa-hibernate-cascade-type/src/test/resources/hibernate.properties b/persistence-modules/jpa-hibernate-cascade-type/src/test/resources/hibernate.properties new file mode 100644 index 0000000000..c22da2496b --- /dev/null +++ b/persistence-modules/jpa-hibernate-cascade-type/src/test/resources/hibernate.properties @@ -0,0 +1,10 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1 +hibernate.connection.username=sa +hibernate.connection.autocommit=true +jdbc.password= + +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop + diff --git a/persistence-modules/pom.xml b/persistence-modules/pom.xml index e6d883334f..390bcc9d51 100644 --- a/persistence-modules/pom.xml +++ b/persistence-modules/pom.xml @@ -57,5 +57,6 @@ spring-hibernate4 spring-jpa spring-persistence-simple + jpa-hibernate-cascade-type diff --git a/pom.xml b/pom.xml index 9760e06bc1..d67622feb7 100644 --- a/pom.xml +++ b/pom.xml @@ -422,6 +422,7 @@ drools dubbo + easy-random ethereum feign @@ -464,7 +465,7 @@ java-rmi java-spi java-streams - java-streams-2 + java-strings java-strings-2 java-vavr-stream @@ -659,6 +660,7 @@ spring-cloud-data-flow spring-core + spring-core-2 spring-cucumber spring-data-rest @@ -1145,7 +1147,7 @@ java-rmi java-spi java-streams - java-streams-2 + java-strings java-strings-2 java-vavr-stream @@ -1323,6 +1325,7 @@ spring-cloud-data-flow spring-core + spring-core-2 spring-cucumber spring-data-rest diff --git a/spring-5-data-reactive/README.md b/spring-5-data-reactive/README.md index f8886ac18b..f3205c23bc 100644 --- a/spring-5-data-reactive/README.md +++ b/spring-5-data-reactive/README.md @@ -6,3 +6,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring ### Relevant Articles - [Reactive Flow with MongoDB, Kotlin, and Spring WebFlux](http://www.baeldung.com/kotlin-mongodb-spring-webflux) - [Spring Data Reactive Repositories with MongoDB](http://www.baeldung.com/spring-data-mongodb-reactive) +- [Spring Data MongoDB Tailable Cursors](https://www.baeldung.com/spring-data-mongodb-tailable-cursors) diff --git a/spring-5-data-reactive/pom.xml b/spring-5-data-reactive/pom.xml index aa73cf11ae..8c16851de0 100644 --- a/spring-5-data-reactive/pom.xml +++ b/spring-5-data-reactive/pom.xml @@ -63,6 +63,11 @@ spring-boot-starter-test test + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + test + diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/LogsCounterApplication.java b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/LogsCounterApplication.java new file mode 100644 index 0000000000..8b2511a8f3 --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/LogsCounterApplication.java @@ -0,0 +1,11 @@ +package com.baeldung.tailablecursor; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class LogsCounterApplication { + public static void main(String[] args) { + SpringApplication.run(LogsCounterApplication.class, args); + } +} diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/domain/Log.java b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/domain/Log.java new file mode 100644 index 0000000000..717a367751 --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/domain/Log.java @@ -0,0 +1,21 @@ +package com.baeldung.tailablecursor.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +@Data +@Document +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class Log { + @Id + private String id; + private String service; + private LogLevel level; + private String message; +} diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/domain/LogLevel.java b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/domain/LogLevel.java new file mode 100644 index 0000000000..6826fbffd3 --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/domain/LogLevel.java @@ -0,0 +1,5 @@ +package com.baeldung.tailablecursor.domain; + +public enum LogLevel { + ERROR, WARN, INFO +} diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/repository/LogsRepository.java b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/repository/LogsRepository.java new file mode 100644 index 0000000000..dce11c548c --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/repository/LogsRepository.java @@ -0,0 +1,12 @@ +package com.baeldung.tailablecursor.repository; + +import com.baeldung.tailablecursor.domain.Log; +import com.baeldung.tailablecursor.domain.LogLevel; +import org.springframework.data.mongodb.repository.Tailable; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import reactor.core.publisher.Flux; + +public interface LogsRepository extends ReactiveCrudRepository { + @Tailable + Flux findByLevel(LogLevel level); +} diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/ErrorLogsCounter.java b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/ErrorLogsCounter.java new file mode 100644 index 0000000000..c243e64f97 --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/ErrorLogsCounter.java @@ -0,0 +1,62 @@ +package com.baeldung.tailablecursor.service; + +import com.baeldung.tailablecursor.domain.Log; +import com.baeldung.tailablecursor.domain.LogLevel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.mapping.Document; +import org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer; +import org.springframework.data.mongodb.core.messaging.MessageListener; +import org.springframework.data.mongodb.core.messaging.MessageListenerContainer; +import org.springframework.data.mongodb.core.messaging.TailableCursorRequest; + +import javax.annotation.PreDestroy; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; + +@Slf4j +public class ErrorLogsCounter implements LogsCounter { + + private static final String LEVEL_FIELD_NAME = "level"; + + private final String collectionName; + private final MessageListenerContainer container; + + private final AtomicInteger counter = new AtomicInteger(); + + public ErrorLogsCounter(MongoTemplate mongoTemplate, + String collectionName) { + this.collectionName = collectionName; + this.container = new DefaultMessageListenerContainer(mongoTemplate); + + container.start(); + TailableCursorRequest request = getTailableCursorRequest(); + container.register(request, Log.class); + } + + @SuppressWarnings("unchecked") + private TailableCursorRequest getTailableCursorRequest() { + MessageListener listener = message -> { + log.info("ERROR log received: {}", message.getBody()); + counter.incrementAndGet(); + }; + + return TailableCursorRequest.builder() + .collection(collectionName) + .filter(query(where(LEVEL_FIELD_NAME).is(LogLevel.ERROR))) + .publishTo(listener) + .build(); + } + + @Override + public int count() { + return counter.get(); + } + + @PreDestroy + public void close() { + container.stop(); + } +} diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/InfoLogsCounter.java b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/InfoLogsCounter.java new file mode 100644 index 0000000000..29301bffec --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/InfoLogsCounter.java @@ -0,0 +1,36 @@ +package com.baeldung.tailablecursor.service; + +import com.baeldung.tailablecursor.domain.Log; +import com.baeldung.tailablecursor.domain.LogLevel; +import com.baeldung.tailablecursor.repository.LogsRepository; +import lombok.extern.slf4j.Slf4j; +import reactor.core.Disposable; +import reactor.core.publisher.Flux; + +import javax.annotation.PreDestroy; +import java.util.concurrent.atomic.AtomicInteger; + +@Slf4j +public class InfoLogsCounter implements LogsCounter { + + private final AtomicInteger counter = new AtomicInteger(); + private final Disposable subscription; + + public InfoLogsCounter(LogsRepository repository) { + Flux stream = repository.findByLevel(LogLevel.INFO); + this.subscription = stream.subscribe(logEntity -> { + log.info("INFO log received: " + logEntity); + counter.incrementAndGet(); + }); + } + + @Override + public int count() { + return this.counter.get(); + } + + @PreDestroy + public void close() { + this.subscription.dispose(); + } +} diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/LogsCounter.java b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/LogsCounter.java new file mode 100644 index 0000000000..e14a3eadd7 --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/LogsCounter.java @@ -0,0 +1,5 @@ +package com.baeldung.tailablecursor.service; + +public interface LogsCounter { + int count(); +} diff --git a/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/WarnLogsCounter.java b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/WarnLogsCounter.java new file mode 100644 index 0000000000..2dff8e8e40 --- /dev/null +++ b/spring-5-data-reactive/src/main/java/com/baeldung/tailablecursor/service/WarnLogsCounter.java @@ -0,0 +1,41 @@ +package com.baeldung.tailablecursor.service; + +import com.baeldung.tailablecursor.domain.Log; +import com.baeldung.tailablecursor.domain.LogLevel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import reactor.core.Disposable; +import reactor.core.publisher.Flux; + +import javax.annotation.PreDestroy; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.springframework.data.mongodb.core.query.Criteria.where; +import static org.springframework.data.mongodb.core.query.Query.query; + +@Slf4j +public class WarnLogsCounter implements LogsCounter { + + private static final String LEVEL_FIELD_NAME = "level"; + + private final AtomicInteger counter = new AtomicInteger(); + private final Disposable subscription; + + public WarnLogsCounter(ReactiveMongoOperations template) { + Flux stream = template.tail(query(where(LEVEL_FIELD_NAME).is(LogLevel.WARN)), Log.class); + subscription = stream.subscribe(logEntity -> { + log.warn("WARN log received: " + logEntity); + counter.incrementAndGet(); + }); + } + + @Override + public int count() { + return counter.get(); + } + + @PreDestroy + public void close() { + subscription.dispose(); + } +} diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/tailablecursor/service/ErrorLogsCounterManualTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/tailablecursor/service/ErrorLogsCounterManualTest.java new file mode 100644 index 0000000000..5e20d3ec79 --- /dev/null +++ b/spring-5-data-reactive/src/test/java/com/baeldung/tailablecursor/service/ErrorLogsCounterManualTest.java @@ -0,0 +1,112 @@ +package com.baeldung.tailablecursor.service; + +import com.baeldung.tailablecursor.domain.Log; +import com.baeldung.tailablecursor.domain.LogLevel; +import com.mongodb.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.mongodb.client.model.CreateCollectionOptions; +import de.flapdoodle.embed.mongo.MongodExecutable; +import de.flapdoodle.embed.mongo.MongodProcess; +import de.flapdoodle.embed.mongo.MongodStarter; +import de.flapdoodle.embed.mongo.config.MongodConfigBuilder; +import de.flapdoodle.embed.mongo.config.Net; +import de.flapdoodle.embed.mongo.distribution.Version; +import de.flapdoodle.embed.process.runtime.Network; +import org.bson.Document; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.util.SocketUtils; + +import java.io.IOException; +import java.util.stream.IntStream; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class ErrorLogsCounterManualTest { + + private static final String SERVER = "localhost"; + private static final int PORT = SocketUtils.findAvailableTcpPort(10000); + private static final String DB_NAME = "test"; + private static final String COLLECTION_NAME = Log.class.getName().toLowerCase(); + + private static final MongodStarter starter = MongodStarter.getDefaultInstance(); + private static final int MAX_DOCUMENTS_IN_COLLECTION = 3; + + private ErrorLogsCounter errorLogsCounter; + private MongodExecutable mongodExecutable; + private MongodProcess mongoDaemon; + private MongoDatabase db; + + @Before + public void setup() throws Exception { + MongoTemplate mongoTemplate = initMongoTemplate(); + + MongoCollection collection = createCappedCollection(); + + persistDocument(collection, -1, LogLevel.ERROR, "my-service", "Initial log"); + + errorLogsCounter = new ErrorLogsCounter(mongoTemplate, COLLECTION_NAME); + Thread.sleep(1000L); // wait for initialization + } + + private MongoTemplate initMongoTemplate() throws IOException { + mongodExecutable = starter.prepare(new MongodConfigBuilder() + .version(Version.Main.PRODUCTION) + .net(new Net(SERVER, PORT, Network.localhostIsIPv6())) + .build()); + mongoDaemon = mongodExecutable.start(); + + MongoClient mongoClient = new MongoClient(SERVER, PORT); + db = mongoClient.getDatabase(DB_NAME); + + return new MongoTemplate(mongoClient, DB_NAME); + } + + private MongoCollection createCappedCollection() { + db.createCollection(COLLECTION_NAME, new CreateCollectionOptions() + .capped(true) + .sizeInBytes(100000) + .maxDocuments(MAX_DOCUMENTS_IN_COLLECTION)); + return db.getCollection(COLLECTION_NAME); + } + + private void persistDocument(MongoCollection collection, + int i, LogLevel level, String service, String message) { + Document logMessage = new Document(); + logMessage.append("_id", i); + logMessage.append("level", level.toString()); + logMessage.append("service", service); + logMessage.append("message", message); + collection.insertOne(logMessage); + } + + @After + public void tearDown() { + errorLogsCounter.close(); + mongoDaemon.stop(); + mongodExecutable.stop(); + } + + @Test + public void whenErrorLogsArePersisted_thenTheyAreReceivedByLogsCounter() throws Exception { + MongoCollection collection = db.getCollection(COLLECTION_NAME); + + IntStream.range(1, 10) + .forEach(i -> persistDocument(collection, + i, + i > 5 ? LogLevel.ERROR : LogLevel.INFO, + "service" + i, + "Message from service " + i) + ); + + Thread.sleep(1000L); // wait to receive all messages from the reactive mongodb driver + + assertThat(collection.countDocuments(), is((long) MAX_DOCUMENTS_IN_COLLECTION)); + assertThat(errorLogsCounter.count(), is(5)); + } + +} diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/tailablecursor/service/InfoLogsCounterManualTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/tailablecursor/service/InfoLogsCounterManualTest.java new file mode 100644 index 0000000000..cd8bd68257 --- /dev/null +++ b/spring-5-data-reactive/src/test/java/com/baeldung/tailablecursor/service/InfoLogsCounterManualTest.java @@ -0,0 +1,75 @@ +package com.baeldung.tailablecursor.service; + +import com.baeldung.tailablecursor.LogsCounterApplication; +import com.baeldung.tailablecursor.domain.Log; +import com.baeldung.tailablecursor.domain.LogLevel; +import com.baeldung.tailablecursor.repository.LogsRepository; +import lombok.extern.slf4j.Slf4j; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.mongodb.core.CollectionOptions; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; +import org.springframework.test.context.junit4.SpringRunner; +import reactor.core.publisher.Flux; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = LogsCounterApplication.class) +@Slf4j +public class InfoLogsCounterManualTest { + @Autowired + private LogsRepository repository; + + @Autowired + private ReactiveMongoTemplate template; + + @Before + public void setUp() { + createCappedCollectionUsingReactiveMongoTemplate(template); + + persistDocument(Log.builder() + .level(LogLevel.INFO) + .service("Service 2") + .message("Initial INFO message") + .build()); + } + + private void createCappedCollectionUsingReactiveMongoTemplate(ReactiveMongoTemplate reactiveMongoTemplate) { + reactiveMongoTemplate.dropCollection(Log.class).block(); + reactiveMongoTemplate.createCollection(Log.class, CollectionOptions.empty() + .maxDocuments(5) + .size(1024 * 1024L) + .capped()).block(); + } + + private void persistDocument(Log log) { + repository.save(log).block(); + } + + @Test + public void wheInfoLogsArePersisted_thenTheyAreReceivedByLogsCounter() throws Exception { + InfoLogsCounter infoLogsCounter = new InfoLogsCounter(repository); + + Thread.sleep(1000L); // wait for initialization + + Flux.range(0,10) + .map(i -> Log.builder() + .level(i > 5 ? LogLevel.WARN : LogLevel.INFO) + .service("some-service") + .message("some log message") + .build()) + .map(entity -> repository.save(entity).subscribe()) + .blockLast(); + + Thread.sleep(1000L); // wait to receive all messages from the reactive mongodb driver + + assertThat(infoLogsCounter.count(), is(7)); + infoLogsCounter.close(); + } +} \ No newline at end of file diff --git a/spring-5-data-reactive/src/test/java/com/baeldung/tailablecursor/service/WarnLogsCounterManualTest.java b/spring-5-data-reactive/src/test/java/com/baeldung/tailablecursor/service/WarnLogsCounterManualTest.java new file mode 100644 index 0000000000..79d94b6784 --- /dev/null +++ b/spring-5-data-reactive/src/test/java/com/baeldung/tailablecursor/service/WarnLogsCounterManualTest.java @@ -0,0 +1,75 @@ +package com.baeldung.tailablecursor.service; + +import com.baeldung.tailablecursor.LogsCounterApplication; +import com.baeldung.tailablecursor.domain.Log; +import com.baeldung.tailablecursor.domain.LogLevel; +import com.baeldung.tailablecursor.repository.LogsRepository; +import lombok.extern.slf4j.Slf4j; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.mongodb.core.CollectionOptions; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; +import org.springframework.test.context.junit4.SpringRunner; +import reactor.core.publisher.Flux; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = LogsCounterApplication.class) +@Slf4j +public class WarnLogsCounterManualTest { + @Autowired + private LogsRepository repository; + + @Autowired + private ReactiveMongoTemplate template; + + @Before + public void setUp() { + createCappedCollectionUsingReactiveMongoTemplate(template); + + persistDocument(Log.builder() + .level(LogLevel.WARN) + .service("Service 1") + .message("Initial Warn message") + .build()); + } + + private void createCappedCollectionUsingReactiveMongoTemplate(ReactiveMongoTemplate reactiveMongoTemplate) { + reactiveMongoTemplate.dropCollection(Log.class).block(); + reactiveMongoTemplate.createCollection(Log.class, CollectionOptions.empty() + .maxDocuments(5) + .size(1024 * 1024L) + .capped()).block(); + } + + private void persistDocument(Log log) { + repository.save(log).block(); + } + + @Test + public void whenWarnLogsArePersisted_thenTheyAreReceivedByLogsCounter() throws Exception { + WarnLogsCounter warnLogsCounter = new WarnLogsCounter(template); + + Thread.sleep(1000L); // wait for initialization + + Flux.range(0,10) + .map(i -> Log.builder() + .level(i > 5 ? LogLevel.WARN : LogLevel.INFO) + .service("some-service") + .message("some log message") + .build()) + .map(entity -> repository.save(entity).subscribe()) + .blockLast(); + + Thread.sleep(1000L); // wait to receive all messages from the reactive mongodb driver + + assertThat(warnLogsCounter.count(), is(5)); + warnLogsCounter.close(); + } +} \ No newline at end of file diff --git a/spring-all/src/main/java/org/baeldung/primary/Config.java b/spring-all/src/main/java/org/baeldung/primary/Config.java index b39f2b9db3..bdcfe019e6 100644 --- a/spring-all/src/main/java/org/baeldung/primary/Config.java +++ b/spring-all/src/main/java/org/baeldung/primary/Config.java @@ -10,13 +10,13 @@ import org.springframework.context.annotation.Primary; public class Config { @Bean - public Employee JohnEmployee(){ + public Employee johnEmployee(){ return new Employee("John"); } @Bean @Primary - public Employee TonyEmployee(){ + public Employee tonyEmployee(){ return new Employee("Tony"); } } diff --git a/spring-boot-testing/src/test/resources/application-test.properties b/spring-boot-testing/src/test/resources/application-test.properties new file mode 100644 index 0000000000..a2c9b6d480 --- /dev/null +++ b/spring-boot-testing/src/test/resources/application-test.properties @@ -0,0 +1,2 @@ +# test properties +spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration \ No newline at end of file diff --git a/spring-boot-testing/src/test/resources/application.properties b/spring-boot-testing/src/test/resources/application.properties new file mode 100644 index 0000000000..9a8b496a8b --- /dev/null +++ b/spring-boot-testing/src/test/resources/application.properties @@ -0,0 +1,3 @@ +# security +spring.security.user.name=john +spring.security.user.password=123 \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/properties/AdditionalConfiguration.java b/spring-boot/src/main/java/org/baeldung/properties/AdditionalConfiguration.java new file mode 100644 index 0000000000..499666c143 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/AdditionalConfiguration.java @@ -0,0 +1,14 @@ +package org.baeldung.properties; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties(AdditionalProperties.class) +public class AdditionalConfiguration { + + @Autowired + private AdditionalProperties additionalProperties; + +} diff --git a/spring-boot/src/main/java/org/baeldung/properties/AdditionalProperties.java b/spring-boot/src/main/java/org/baeldung/properties/AdditionalProperties.java new file mode 100644 index 0000000000..64e39b1475 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/AdditionalProperties.java @@ -0,0 +1,26 @@ +package org.baeldung.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "additional") +public class AdditionalProperties { + + private String unit; + private int max; + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public int getMax() { + return max; + } + + public void setMax(int max) { + this.max = max; + } +} diff --git a/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java b/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java index 395d68060b..7b8f2c3411 100644 --- a/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java +++ b/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java @@ -5,11 +5,14 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication -@ComponentScan(basePackageClasses = { ConfigProperties.class, JsonProperties.class, CustomJsonProperties.class }) +@ComponentScan(basePackageClasses = {ConfigProperties.class, + JsonProperties.class, + CustomJsonProperties.class, + AdditionalConfiguration.class}) public class ConfigPropertiesDemoApplication { public static void main(String[] args) { new SpringApplicationBuilder(ConfigPropertiesDemoApplication.class).initializers(new JsonPropertyContextInitializer()) - .run(); + .run(); } } diff --git a/spring-boot/src/test/java/com/baeldung/properties/ConfigPropertiesIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/properties/ConfigPropertiesIntegrationTest.java index 3a4b6551b1..8f07b2da35 100644 --- a/spring-boot/src/test/java/com/baeldung/properties/ConfigPropertiesIntegrationTest.java +++ b/spring-boot/src/test/java/com/baeldung/properties/ConfigPropertiesIntegrationTest.java @@ -1,5 +1,6 @@ package com.baeldung.properties; +import org.baeldung.properties.AdditionalProperties; import org.baeldung.properties.ConfigProperties; import org.baeldung.properties.ConfigPropertiesDemoApplication; import org.junit.Assert; @@ -18,6 +19,9 @@ public class ConfigPropertiesIntegrationTest { @Autowired private ConfigProperties properties; + @Autowired + private AdditionalProperties additionalProperties; + @Test public void whenSimplePropertyQueriedthenReturnsProperty() throws Exception { Assert.assertTrue("From address is read as null!", properties.getFrom() != null); @@ -42,4 +46,10 @@ public class ConfigPropertiesIntegrationTest { Assert.assertTrue("Incorrectly bound object property!", properties.getCredentials().getUsername().equals("john")); Assert.assertTrue("Incorrectly bound object property!", properties.getCredentials().getPassword().equals("password")); } + + @Test + public void whenAdditionalPropertyQueriedthenReturnsProperty() { + Assert.assertTrue(additionalProperties.getUnit().equals("km")); + Assert.assertTrue(additionalProperties.getMax() == 100); + } } diff --git a/spring-boot/src/test/resources/configprops-test.properties b/spring-boot/src/test/resources/configprops-test.properties index ea11f2159e..5eed93a22b 100644 --- a/spring-boot/src/test/resources/configprops-test.properties +++ b/spring-boot/src/test/resources/configprops-test.properties @@ -20,3 +20,7 @@ mail.credentials.authMethod=SHA1 #Bean method properties item.name=Test item name item.size=21 + +#Additional properties +additional.unit=km +additional.max=100 diff --git a/spring-core-2/pom.xml b/spring-core-2/pom.xml new file mode 100644 index 0000000000..8e4c539e3b --- /dev/null +++ b/spring-core-2/pom.xml @@ -0,0 +1,60 @@ + + + + com.baeldung + parent-spring-5 + 0.0.1-SNAPSHOT + ../parent-spring-5 + + 4.0.0 + + spring-core-2 + + + + org.springframework + spring-beans + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-core + ${spring.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit.jupiter.version} + test + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.1 + + + + + + 5.1.4.RELEASE + 5.0.2 + + + \ No newline at end of file diff --git a/spring-core-2/src/main/java/com/baeldung/getbean/AnnotationConfig.java b/spring-core-2/src/main/java/com/baeldung/getbean/AnnotationConfig.java new file mode 100644 index 0000000000..12e3ab55e3 --- /dev/null +++ b/spring-core-2/src/main/java/com/baeldung/getbean/AnnotationConfig.java @@ -0,0 +1,22 @@ +package com.baeldung.getbean; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +@Configuration +class AnnotationConfig { + + @Bean(name = {"tiger", "kitty"}) + @Scope(value = "prototype") + Tiger getTiger(String name) { + return new Tiger(name); + } + + @Bean(name = "lion") + Lion getLion() { + return new Lion("Hardcoded lion name"); + } + + interface Animal {} +} diff --git a/spring-core-2/src/main/java/com/baeldung/getbean/Lion.java b/spring-core-2/src/main/java/com/baeldung/getbean/Lion.java new file mode 100644 index 0000000000..96c569aeb9 --- /dev/null +++ b/spring-core-2/src/main/java/com/baeldung/getbean/Lion.java @@ -0,0 +1,13 @@ +package com.baeldung.getbean; + +class Lion implements AnnotationConfig.Animal { + private String name; + + Lion(String name) { + this.name = name; + } + + String getName() { + return name; + } +} diff --git a/spring-core-2/src/main/java/com/baeldung/getbean/Tiger.java b/spring-core-2/src/main/java/com/baeldung/getbean/Tiger.java new file mode 100644 index 0000000000..85b9626c79 --- /dev/null +++ b/spring-core-2/src/main/java/com/baeldung/getbean/Tiger.java @@ -0,0 +1,13 @@ +package com.baeldung.getbean; + +class Tiger implements AnnotationConfig.Animal { + private String name; + + Tiger(String name) { + this.name = name; + } + + String getName() { + return name; + } +} diff --git a/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByNameAndTypeUnitTest.java b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByNameAndTypeUnitTest.java new file mode 100644 index 0000000000..e06804c28e --- /dev/null +++ b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByNameAndTypeUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.getbean; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.BeanNotOfRequiredTypeException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class GetBeanByNameAndTypeUnitTest { + private ApplicationContext context; + + @BeforeAll + void setup() { + context = new AnnotationConfigApplicationContext(AnnotationConfig.class); + } + + @Test + void whenSpecifiedMatchingNameAndType_thenShouldReturnRelatedBean() { + Lion lion = context.getBean("lion", Lion.class); + + assertEquals("Hardcoded lion name", lion.getName()); + } + + @Test + void whenSpecifiedNotMatchingNameAndType_thenShouldThrowException() { + assertThrows(BeanNotOfRequiredTypeException.class, () -> context.getBean("lion", Tiger.class)); + } +} diff --git a/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByNameUnitTest.java b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByNameUnitTest.java new file mode 100644 index 0000000000..4d6d77e39d --- /dev/null +++ b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByNameUnitTest.java @@ -0,0 +1,40 @@ +package com.baeldung.getbean; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class GetBeanByNameUnitTest { + private ApplicationContext context; + + @BeforeAll + void setup() { + context = new AnnotationConfigApplicationContext(AnnotationConfig.class); + } + + @Test + void whenGivenExistingBeanName_shouldReturnThatBean() { + Object lion = context.getBean("lion"); + + assertEquals(lion.getClass(), Lion.class); + } + + @Test + void whenGivenNonExistingBeanName_shouldThrowException() { + assertThrows(NoSuchBeanDefinitionException.class, () -> context.getBean("non-existing")); + } + + @Test + void whenCastingToWrongType_thenShouldThrowException() { + assertThrows(ClassCastException.class, () -> { + Tiger tiger = (Tiger) context.getBean("lion"); + }); + } +} diff --git a/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByNameWithConstructorParametersUnitTest.java b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByNameWithConstructorParametersUnitTest.java new file mode 100644 index 0000000000..32d37e4ff2 --- /dev/null +++ b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByNameWithConstructorParametersUnitTest.java @@ -0,0 +1,44 @@ +package com.baeldung.getbean; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.UnsatisfiedDependencyException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class GetBeanByNameWithConstructorParametersUnitTest { + private ApplicationContext context; + + @BeforeAll + void setup() { + context = new AnnotationConfigApplicationContext(AnnotationConfig.class); + } + + @Test + void whenGivenCorrectName_thenShouldReturnBeanWithSpecifiedName() { + Tiger tiger = (Tiger) context.getBean("tiger", "Siberian"); + + assertEquals("Siberian", tiger.getName()); + } + + @Test + void whenGivenCorrectNameOrAlias_shouldReturnBeanWithSpecifiedName() { + Tiger tiger = (Tiger) context.getBean("tiger", "Siberian"); + Tiger secondTiger = (Tiger) context.getBean("tiger", "Striped"); + + assertEquals("Siberian", tiger.getName()); + assertEquals("Striped", secondTiger.getName()); + } + + @Test + void whenNoArgumentSpecifiedForPrototypeBean_thenShouldThrowException() { + assertThrows(UnsatisfiedDependencyException.class, () -> { + Tiger tiger = (Tiger) context.getBean("tiger"); + }); + } +} diff --git a/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByTypeUnitTest.java b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByTypeUnitTest.java new file mode 100644 index 0000000000..a4d4ab732b --- /dev/null +++ b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByTypeUnitTest.java @@ -0,0 +1,33 @@ +package com.baeldung.getbean; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.NoUniqueBeanDefinitionException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class GetBeanByTypeUnitTest { + private ApplicationContext context; + + @BeforeAll + void setup() { + context = new AnnotationConfigApplicationContext(AnnotationConfig.class); + } + + @Test + void whenGivenExistingUniqueType_thenShouldReturnRelatedBean() { + Lion lion = context.getBean(Lion.class); + + assertNotNull(lion); + } + + @Test + void whenGivenAmbiguousType_thenShouldThrowException() { + assertThrows(NoUniqueBeanDefinitionException.class, () -> context.getBean(AnnotationConfig.Animal.class)); + } +} diff --git a/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByTypeWithConstructorParametersUnitTest.java b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByTypeWithConstructorParametersUnitTest.java new file mode 100644 index 0000000000..08bcb92145 --- /dev/null +++ b/spring-core-2/src/test/java/com/baeldung/getbean/GetBeanByTypeWithConstructorParametersUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.getbean; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class GetBeanByTypeWithConstructorParametersUnitTest { + private ApplicationContext context; + + @BeforeAll + void setup() { + context = new AnnotationConfigApplicationContext(AnnotationConfig.class); + } + + @Test + void whenGivenExistingTypeAndValidParameters_thenShouldReturnRelatedBean() { + Tiger tiger = context.getBean(Tiger.class, "Shere Khan"); + + assertEquals("Shere Khan", tiger.getName()); + } +} diff --git a/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java b/spring-data-rest/src/main/java/com/baeldung/books/SpringDataRestApplication.java similarity index 91% rename from spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java rename to spring-data-rest/src/main/java/com/baeldung/books/SpringDataRestApplication.java index 702acb5b65..097a6aabd7 100644 --- a/spring-data-rest/src/main/java/com/baeldung/SpringDataRestApplication.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/SpringDataRestApplication.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.books; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/spring-data-rest/src/main/java/com/baeldung/config/DbConfig.java b/spring-data-rest/src/main/java/com/baeldung/books/config/DbConfig.java similarity index 94% rename from spring-data-rest/src/main/java/com/baeldung/config/DbConfig.java rename to spring-data-rest/src/main/java/com/baeldung/books/config/DbConfig.java index 3ca728ec94..20008eb583 100644 --- a/spring-data-rest/src/main/java/com/baeldung/config/DbConfig.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/config/DbConfig.java @@ -1,4 +1,4 @@ -package com.baeldung.config; +package com.baeldung.books.config; import java.util.Properties; @@ -16,7 +16,7 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; @Configuration -@EnableJpaRepositories(basePackages = "com.baeldung.repositories") +@EnableJpaRepositories(basePackages = "com.baeldung.books.repositories") // @PropertySource("persistence-h2.properties") // @PropertySource("persistence-hsqldb.properties") // @PropertySource("persistence-derby.properties") @@ -40,7 +40,7 @@ public class DbConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "com.baeldung.models" }); + em.setPackagesToScan(new String[] { "com.baeldung.books.models" }); em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); em.setJpaProperties(additionalProperties()); return em; diff --git a/spring-data-rest/src/main/java/com/baeldung/config/MvcConfig.java b/spring-data-rest/src/main/java/com/baeldung/books/config/MvcConfig.java similarity index 85% rename from spring-data-rest/src/main/java/com/baeldung/config/MvcConfig.java rename to spring-data-rest/src/main/java/com/baeldung/books/config/MvcConfig.java index 9d0d3a6687..69e984ad06 100644 --- a/spring-data-rest/src/main/java/com/baeldung/config/MvcConfig.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/config/MvcConfig.java @@ -1,13 +1,14 @@ -package com.baeldung.config; +package com.baeldung.books.config; -import com.baeldung.events.AuthorEventHandler; -import com.baeldung.events.BookEventHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import com.baeldung.books.events.AuthorEventHandler; +import com.baeldung.books.events.BookEventHandler; + @Configuration @EnableWebMvc public class MvcConfig implements WebMvcConfigurer { diff --git a/spring-data-rest/src/main/java/com/baeldung/config/RestConfig.java b/spring-data-rest/src/main/java/com/baeldung/books/config/RestConfig.java similarity index 86% rename from spring-data-rest/src/main/java/com/baeldung/config/RestConfig.java rename to spring-data-rest/src/main/java/com/baeldung/books/config/RestConfig.java index 47cb95693b..1c6f04331e 100644 --- a/spring-data-rest/src/main/java/com/baeldung/config/RestConfig.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/config/RestConfig.java @@ -1,7 +1,8 @@ -package com.baeldung.config; +package com.baeldung.books.config; + +import com.baeldung.books.models.WebsiteUser; +import com.baeldung.books.projections.CustomBook; -import com.baeldung.models.WebsiteUser; -import com.baeldung.projections.CustomBook; import org.springframework.context.annotation.Configuration; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.data.rest.core.mapping.ExposureConfiguration; diff --git a/spring-data-rest/src/main/java/com/baeldung/config/ValidatorEventRegister.java b/spring-data-rest/src/main/java/com/baeldung/books/config/ValidatorEventRegister.java similarity index 94% rename from spring-data-rest/src/main/java/com/baeldung/config/ValidatorEventRegister.java rename to spring-data-rest/src/main/java/com/baeldung/books/config/ValidatorEventRegister.java index 632ad9183a..bbaf9a2771 100644 --- a/spring-data-rest/src/main/java/com/baeldung/config/ValidatorEventRegister.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/config/ValidatorEventRegister.java @@ -1,4 +1,4 @@ -package com.baeldung.config; +package com.baeldung.books.config; import java.util.Arrays; import java.util.List; diff --git a/spring-data-rest/src/main/java/com/baeldung/dialect/SQLiteDialect.java b/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteDialect.java similarity index 98% rename from spring-data-rest/src/main/java/com/baeldung/dialect/SQLiteDialect.java rename to spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteDialect.java index 4512f7d34d..6e840eec43 100644 --- a/spring-data-rest/src/main/java/com/baeldung/dialect/SQLiteDialect.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteDialect.java @@ -1,4 +1,4 @@ -package com.baeldung.dialect; +package com.baeldung.books.dialect; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.identity.IdentityColumnSupport; diff --git a/spring-data-rest/src/main/java/com/baeldung/dialect/SQLiteIdentityColumnSupport.java b/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteIdentityColumnSupport.java similarity index 94% rename from spring-data-rest/src/main/java/com/baeldung/dialect/SQLiteIdentityColumnSupport.java rename to spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteIdentityColumnSupport.java index cf6e3a9a97..682d82c6f1 100644 --- a/spring-data-rest/src/main/java/com/baeldung/dialect/SQLiteIdentityColumnSupport.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/dialect/SQLiteIdentityColumnSupport.java @@ -1,4 +1,4 @@ -package com.baeldung.dialect; +package com.baeldung.books.dialect; import org.hibernate.MappingException; import org.hibernate.dialect.identity.IdentityColumnSupportImpl; diff --git a/spring-data-rest/src/main/java/com/baeldung/events/AuthorEventHandler.java b/spring-data-rest/src/main/java/com/baeldung/books/events/AuthorEventHandler.java similarity index 89% rename from spring-data-rest/src/main/java/com/baeldung/events/AuthorEventHandler.java rename to spring-data-rest/src/main/java/com/baeldung/books/events/AuthorEventHandler.java index 485dc8e221..b390a529ba 100644 --- a/spring-data-rest/src/main/java/com/baeldung/events/AuthorEventHandler.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/events/AuthorEventHandler.java @@ -1,9 +1,10 @@ -package com.baeldung.events; +package com.baeldung.books.events; -import com.baeldung.models.Author; -import com.baeldung.models.Book; import org.springframework.data.rest.core.annotation.*; +import com.baeldung.books.models.Author; +import com.baeldung.books.models.Book; + import java.util.logging.Logger; @RepositoryEventHandler diff --git a/spring-data-rest/src/main/java/com/baeldung/events/BookEventHandler.java b/spring-data-rest/src/main/java/com/baeldung/books/events/BookEventHandler.java similarity index 86% rename from spring-data-rest/src/main/java/com/baeldung/events/BookEventHandler.java rename to spring-data-rest/src/main/java/com/baeldung/books/events/BookEventHandler.java index 36ae62b926..0afb3a6279 100644 --- a/spring-data-rest/src/main/java/com/baeldung/events/BookEventHandler.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/events/BookEventHandler.java @@ -1,13 +1,15 @@ -package com.baeldung.events; +package com.baeldung.books.events; import java.util.logging.Logger; -import com.baeldung.models.Author; -import com.baeldung.models.Book; + import org.apache.commons.logging.Log; import org.springframework.data.rest.core.annotation.HandleAfterDelete; import org.springframework.data.rest.core.annotation.HandleBeforeCreate; import org.springframework.data.rest.core.annotation.RepositoryEventHandler; +import com.baeldung.books.models.Author; +import com.baeldung.books.models.Book; + @RepositoryEventHandler public class BookEventHandler { Logger logger = Logger.getLogger("Class BookEventHandler"); diff --git a/spring-data-rest/src/main/java/com/baeldung/exception/handlers/RestResponseEntityExceptionHandler.java b/spring-data-rest/src/main/java/com/baeldung/books/exception/handlers/RestResponseEntityExceptionHandler.java similarity index 94% rename from spring-data-rest/src/main/java/com/baeldung/exception/handlers/RestResponseEntityExceptionHandler.java rename to spring-data-rest/src/main/java/com/baeldung/books/exception/handlers/RestResponseEntityExceptionHandler.java index a3ef91f6d6..4a961e5250 100644 --- a/spring-data-rest/src/main/java/com/baeldung/exception/handlers/RestResponseEntityExceptionHandler.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/exception/handlers/RestResponseEntityExceptionHandler.java @@ -1,4 +1,4 @@ -package com.baeldung.exception.handlers; +package com.baeldung.books.exception.handlers; import org.springframework.data.rest.core.RepositoryConstraintViolationException; import org.springframework.http.HttpHeaders; diff --git a/spring-data-rest/src/main/java/com/baeldung/models/Address.java b/spring-data-rest/src/main/java/com/baeldung/books/models/Address.java similarity index 96% rename from spring-data-rest/src/main/java/com/baeldung/models/Address.java rename to spring-data-rest/src/main/java/com/baeldung/books/models/Address.java index 713af58ae6..3c36db0f3c 100644 --- a/spring-data-rest/src/main/java/com/baeldung/models/Address.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/models/Address.java @@ -1,4 +1,4 @@ -package com.baeldung.models; +package com.baeldung.books.models; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/spring-data-rest/src/main/java/com/baeldung/models/Author.java b/spring-data-rest/src/main/java/com/baeldung/books/models/Author.java similarity index 97% rename from spring-data-rest/src/main/java/com/baeldung/models/Author.java rename to spring-data-rest/src/main/java/com/baeldung/books/models/Author.java index 3f43af9c47..aec2e62ebf 100644 --- a/spring-data-rest/src/main/java/com/baeldung/models/Author.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/models/Author.java @@ -1,4 +1,4 @@ -package com.baeldung.models; +package com.baeldung.books.models; import java.util.List; diff --git a/spring-data-rest/src/main/java/com/baeldung/models/Book.java b/spring-data-rest/src/main/java/com/baeldung/books/models/Book.java similarity index 97% rename from spring-data-rest/src/main/java/com/baeldung/models/Book.java rename to spring-data-rest/src/main/java/com/baeldung/books/models/Book.java index 07b0d08b84..7451b04b3b 100644 --- a/spring-data-rest/src/main/java/com/baeldung/models/Book.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/models/Book.java @@ -1,4 +1,4 @@ -package com.baeldung.models; +package com.baeldung.books.models; import java.util.List; diff --git a/spring-data-rest/src/main/java/com/baeldung/models/Library.java b/spring-data-rest/src/main/java/com/baeldung/books/models/Library.java similarity index 97% rename from spring-data-rest/src/main/java/com/baeldung/models/Library.java rename to spring-data-rest/src/main/java/com/baeldung/books/models/Library.java index 091975f5d0..5f95169a9b 100644 --- a/spring-data-rest/src/main/java/com/baeldung/models/Library.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/models/Library.java @@ -1,4 +1,4 @@ -package com.baeldung.models; +package com.baeldung.books.models; import java.util.List; diff --git a/spring-data-rest/src/main/java/com/baeldung/models/Subject.java b/spring-data-rest/src/main/java/com/baeldung/books/models/Subject.java similarity index 94% rename from spring-data-rest/src/main/java/com/baeldung/models/Subject.java rename to spring-data-rest/src/main/java/com/baeldung/books/models/Subject.java index 4e5fa82148..11a4425fdd 100644 --- a/spring-data-rest/src/main/java/com/baeldung/models/Subject.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/models/Subject.java @@ -1,4 +1,4 @@ -package com.baeldung.models; +package com.baeldung.books.models; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/spring-data-rest/src/main/java/com/baeldung/models/WebsiteUser.java b/spring-data-rest/src/main/java/com/baeldung/books/models/WebsiteUser.java similarity index 95% rename from spring-data-rest/src/main/java/com/baeldung/models/WebsiteUser.java rename to spring-data-rest/src/main/java/com/baeldung/books/models/WebsiteUser.java index 4eb9773e36..e632623019 100644 --- a/spring-data-rest/src/main/java/com/baeldung/models/WebsiteUser.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/models/WebsiteUser.java @@ -1,4 +1,4 @@ -package com.baeldung.models; +package com.baeldung.books.models; import javax.persistence.Entity; import javax.persistence.GeneratedValue; diff --git a/spring-data-rest/src/main/java/com/baeldung/projections/CustomBook.java b/spring-data-rest/src/main/java/com/baeldung/books/projections/CustomBook.java similarity index 77% rename from spring-data-rest/src/main/java/com/baeldung/projections/CustomBook.java rename to spring-data-rest/src/main/java/com/baeldung/books/projections/CustomBook.java index 3dc6938f5c..5fe78c869d 100644 --- a/spring-data-rest/src/main/java/com/baeldung/projections/CustomBook.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/projections/CustomBook.java @@ -1,12 +1,12 @@ -package com.baeldung.projections; +package com.baeldung.books.projections; import java.util.List; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.rest.core.config.Projection; -import com.baeldung.models.Author; -import com.baeldung.models.Book; +import com.baeldung.books.models.Author; +import com.baeldung.books.models.Book; @Projection(name = "customBook", types = { Book.class }) public interface CustomBook { diff --git a/spring-data-rest/src/main/java/com/baeldung/repositories/AddressRepository.java b/spring-data-rest/src/main/java/com/baeldung/books/repositories/AddressRepository.java similarity index 62% rename from spring-data-rest/src/main/java/com/baeldung/repositories/AddressRepository.java rename to spring-data-rest/src/main/java/com/baeldung/books/repositories/AddressRepository.java index 1cc7527e80..5e3900f439 100644 --- a/spring-data-rest/src/main/java/com/baeldung/repositories/AddressRepository.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/repositories/AddressRepository.java @@ -1,8 +1,8 @@ -package com.baeldung.repositories; +package com.baeldung.books.repositories; import org.springframework.data.repository.CrudRepository; -import com.baeldung.models.Address; +import com.baeldung.books.models.Address; public interface AddressRepository extends CrudRepository { diff --git a/spring-data-rest/src/main/java/com/baeldung/repositories/AuthorRepository.java b/spring-data-rest/src/main/java/com/baeldung/books/repositories/AuthorRepository.java similarity index 62% rename from spring-data-rest/src/main/java/com/baeldung/repositories/AuthorRepository.java rename to spring-data-rest/src/main/java/com/baeldung/books/repositories/AuthorRepository.java index 2d470367ef..837e13b1d2 100644 --- a/spring-data-rest/src/main/java/com/baeldung/repositories/AuthorRepository.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/repositories/AuthorRepository.java @@ -1,8 +1,8 @@ -package com.baeldung.repositories; +package com.baeldung.books.repositories; import org.springframework.data.repository.CrudRepository; -import com.baeldung.models.Author; +import com.baeldung.books.models.Author; public interface AuthorRepository extends CrudRepository { diff --git a/spring-data-rest/src/main/java/com/baeldung/repositories/BookRepository.java b/spring-data-rest/src/main/java/com/baeldung/books/repositories/BookRepository.java similarity index 67% rename from spring-data-rest/src/main/java/com/baeldung/repositories/BookRepository.java rename to spring-data-rest/src/main/java/com/baeldung/books/repositories/BookRepository.java index eee44f35d4..5d7e277526 100644 --- a/spring-data-rest/src/main/java/com/baeldung/repositories/BookRepository.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/repositories/BookRepository.java @@ -1,10 +1,10 @@ -package com.baeldung.repositories; +package com.baeldung.books.repositories; import org.springframework.data.repository.CrudRepository; import org.springframework.data.rest.core.annotation.RepositoryRestResource; -import com.baeldung.models.Book; -import com.baeldung.projections.CustomBook; +import com.baeldung.books.models.Book; +import com.baeldung.books.projections.CustomBook; @RepositoryRestResource(excerptProjection = CustomBook.class) public interface BookRepository extends CrudRepository { diff --git a/spring-data-rest/src/main/java/com/baeldung/repositories/LibraryRepository.java b/spring-data-rest/src/main/java/com/baeldung/books/repositories/LibraryRepository.java similarity index 62% rename from spring-data-rest/src/main/java/com/baeldung/repositories/LibraryRepository.java rename to spring-data-rest/src/main/java/com/baeldung/books/repositories/LibraryRepository.java index c00787f03c..92518339a0 100644 --- a/spring-data-rest/src/main/java/com/baeldung/repositories/LibraryRepository.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/repositories/LibraryRepository.java @@ -1,8 +1,8 @@ -package com.baeldung.repositories; +package com.baeldung.books.repositories; import org.springframework.data.repository.CrudRepository; -import com.baeldung.models.Library; +import com.baeldung.books.models.Library; public interface LibraryRepository extends CrudRepository { diff --git a/spring-data-rest/src/main/java/com/baeldung/repositories/SubjectRepository.java b/spring-data-rest/src/main/java/com/baeldung/books/repositories/SubjectRepository.java similarity index 85% rename from spring-data-rest/src/main/java/com/baeldung/repositories/SubjectRepository.java rename to spring-data-rest/src/main/java/com/baeldung/books/repositories/SubjectRepository.java index 76e34b0799..187b01f222 100644 --- a/spring-data-rest/src/main/java/com/baeldung/repositories/SubjectRepository.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/repositories/SubjectRepository.java @@ -1,11 +1,12 @@ -package com.baeldung.repositories; +package com.baeldung.books.repositories; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.query.Param; import org.springframework.data.rest.core.annotation.RestResource; -import com.baeldung.models.Subject; + +import com.baeldung.books.models.Subject; public interface SubjectRepository extends PagingAndSortingRepository { diff --git a/spring-data-rest/src/main/java/com/baeldung/repositories/UserRepository.java b/spring-data-rest/src/main/java/com/baeldung/books/repositories/UserRepository.java similarity index 91% rename from spring-data-rest/src/main/java/com/baeldung/repositories/UserRepository.java rename to spring-data-rest/src/main/java/com/baeldung/books/repositories/UserRepository.java index a3fed1c318..f0823338bc 100644 --- a/spring-data-rest/src/main/java/com/baeldung/repositories/UserRepository.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/repositories/UserRepository.java @@ -1,11 +1,12 @@ -package com.baeldung.repositories; +package com.baeldung.books.repositories; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.data.rest.core.annotation.RepositoryRestResource; import org.springframework.data.rest.core.annotation.RestResource; import org.springframework.web.bind.annotation.CrossOrigin; -import com.baeldung.models.WebsiteUser; + +import com.baeldung.books.models.WebsiteUser; @CrossOrigin @RepositoryRestResource(collectionResourceRel = "users", path = "users") diff --git a/spring-data-rest/src/main/java/com/baeldung/validators/WebsiteUserValidator.java b/spring-data-rest/src/main/java/com/baeldung/books/validators/WebsiteUserValidator.java similarity index 87% rename from spring-data-rest/src/main/java/com/baeldung/validators/WebsiteUserValidator.java rename to spring-data-rest/src/main/java/com/baeldung/books/validators/WebsiteUserValidator.java index 0380332708..ad7511c2ba 100644 --- a/spring-data-rest/src/main/java/com/baeldung/validators/WebsiteUserValidator.java +++ b/spring-data-rest/src/main/java/com/baeldung/books/validators/WebsiteUserValidator.java @@ -1,10 +1,10 @@ -package com.baeldung.validators; +package com.baeldung.books.validators; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; -import com.baeldung.models.WebsiteUser; +import com.baeldung.books.models.WebsiteUser; @Component("beforeCreateWebsiteUserValidator") public class WebsiteUserValidator implements Validator { diff --git a/spring-data-rest/src/test/java/com/baeldung/events/AuthorEventHandlerUnitTest.java b/spring-data-rest/src/test/java/com/baeldung/books/events/AuthorEventHandlerUnitTest.java similarity index 86% rename from spring-data-rest/src/test/java/com/baeldung/events/AuthorEventHandlerUnitTest.java rename to spring-data-rest/src/test/java/com/baeldung/books/events/AuthorEventHandlerUnitTest.java index c01d5882a0..719c4d7c86 100644 --- a/spring-data-rest/src/test/java/com/baeldung/events/AuthorEventHandlerUnitTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/books/events/AuthorEventHandlerUnitTest.java @@ -1,6 +1,8 @@ -package com.baeldung.events; +package com.baeldung.books.events; + +import com.baeldung.books.events.AuthorEventHandler; +import com.baeldung.books.models.Author; -import com.baeldung.models.Author; import org.junit.Test; import org.mockito.Mockito; import org.springframework.data.rest.core.annotation.RepositoryEventHandler; diff --git a/spring-data-rest/src/test/java/com/baeldung/events/BookEventHandlerUnitTest.java b/spring-data-rest/src/test/java/com/baeldung/books/events/BookEventHandlerUnitTest.java similarity index 81% rename from spring-data-rest/src/test/java/com/baeldung/events/BookEventHandlerUnitTest.java rename to spring-data-rest/src/test/java/com/baeldung/books/events/BookEventHandlerUnitTest.java index d6b8b3b25e..4b9d77afa2 100644 --- a/spring-data-rest/src/test/java/com/baeldung/events/BookEventHandlerUnitTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/books/events/BookEventHandlerUnitTest.java @@ -1,7 +1,9 @@ -package com.baeldung.events; +package com.baeldung.books.events; + +import com.baeldung.books.events.BookEventHandler; +import com.baeldung.books.models.Author; +import com.baeldung.books.models.Book; -import com.baeldung.models.Author; -import com.baeldung.models.Book; import org.junit.Test; import org.mockito.Mockito; diff --git a/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java b/spring-data-rest/src/test/java/com/baeldung/books/projections/SpringDataProjectionLiveTest.java similarity index 91% rename from spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java rename to spring-data-rest/src/test/java/com/baeldung/books/projections/SpringDataProjectionLiveTest.java index 274ae3bc1d..98b5831b96 100644 --- a/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionLiveTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/books/projections/SpringDataProjectionLiveTest.java @@ -1,4 +1,4 @@ -package com.baeldung.projection; +package com.baeldung.books.projections; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -16,11 +16,11 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.SpringDataRestApplication; -import com.baeldung.models.Author; -import com.baeldung.models.Book; -import com.baeldung.repositories.AuthorRepository; -import com.baeldung.repositories.BookRepository; +import com.baeldung.books.SpringDataRestApplication; +import com.baeldung.books.models.Author; +import com.baeldung.books.models.Book; +import com.baeldung.books.repositories.AuthorRepository; +import com.baeldung.books.repositories.BookRepository; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) diff --git a/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/books/validator/SpringDataRestValidatorIntegrationTest.java similarity index 97% rename from spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java rename to spring-data-rest/src/test/java/com/baeldung/books/validator/SpringDataRestValidatorIntegrationTest.java index 6da76d6a33..75733475e7 100644 --- a/spring-data-rest/src/test/java/com/baeldung/validator/SpringDataRestValidatorIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/books/validator/SpringDataRestValidatorIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.validator; +package com.baeldung.books.validator; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -19,8 +19,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.context.WebApplicationContext; -import com.baeldung.SpringDataRestApplication; -import com.baeldung.models.WebsiteUser; +import com.baeldung.books.SpringDataRestApplication; +import com.baeldung.books.models.WebsiteUser; import com.fasterxml.jackson.databind.ObjectMapper; @RunWith(SpringJUnit4ClassRunner.class) diff --git a/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java index e1aff7e09d..d7ef361783 100644 --- a/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java +++ b/spring-data-rest/src/test/java/com/baeldung/springdatawebsupport/application/test/UserControllerIntegrationTest.java @@ -42,7 +42,7 @@ public class UserControllerIntegrationTest { @Test public void whenGetRequestToUserEndPointWithNameRequestParameter_thenCorrectResponse() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get("/user").param("name", "John").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()) + mockMvc.perform(MockMvcRequestBuilders.get("/users").param("name", "John").contentType(MediaType.APPLICATION_JSON_UTF8)).andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(MockMvcResultMatchers.jsonPath("$['content'][0].['name']").value("John")); } diff --git a/spring-data-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-data-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java index 0380e3dc2f..c2682855b8 100644 --- a/spring-data-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-data-rest/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -5,7 +5,7 @@ import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.SpringDataRestApplication; +import com.baeldung.books.SpringDataRestApplication; @RunWith(SpringRunner.class) @SpringBootTest(classes = SpringDataRestApplication.class) diff --git a/spring-thymeleaf-2/pom.xml b/spring-thymeleaf-2/pom.xml new file mode 100644 index 0000000000..bc1147cb14 --- /dev/null +++ b/spring-thymeleaf-2/pom.xml @@ -0,0 +1,40 @@ + + 4.0.0 + spring-thymeleaf-2 + spring-thymeleaf-2 + war + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + 1.8 + 1.8 + + + + + + org.apache.maven.plugins + maven-war-plugin + + + spring-thymeleaf-2 + + diff --git a/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/Application.java b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/Application.java new file mode 100644 index 0000000000..2ccca82497 --- /dev/null +++ b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/Application.java @@ -0,0 +1,11 @@ +package com.baeldung.thymeleaf; + +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); + } +} diff --git a/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/enums/Color.java b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/enums/Color.java new file mode 100644 index 0000000000..9e223d1323 --- /dev/null +++ b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/enums/Color.java @@ -0,0 +1,22 @@ +package com.baeldung.thymeleaf.enums; + +public enum Color { + BLACK("Black"), + BLUE("Blue"), + RED("Red"), + YELLOW("Yellow"), + GREEN("Green"), + ORANGE("Orange"), + PURPLE("Purple"), + WHITE("White"); + + private final String displayValue; + + private Color(String displayValue) { + this.displayValue = displayValue; + } + + public String getDisplayValue() { + return displayValue; + } +} diff --git a/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/enums/Widget.java b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/enums/Widget.java new file mode 100644 index 0000000000..dc6504c3bc --- /dev/null +++ b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/enums/Widget.java @@ -0,0 +1,27 @@ +package com.baeldung.thymeleaf.enums; + +public class Widget { + private String name; + private Color color; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } + + @Override + public String toString() { + return "Widget [name=" + name + ", color=" + color + "]"; + } +} diff --git a/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/enums/WidgetController.java b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/enums/WidgetController.java new file mode 100644 index 0000000000..c66464d75b --- /dev/null +++ b/spring-thymeleaf-2/src/main/java/com/baeldung/thymeleaf/enums/WidgetController.java @@ -0,0 +1,23 @@ +package com.baeldung.thymeleaf.enums; + +import javax.validation.Valid; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.ui.Model; + +@Controller +public class WidgetController { + @GetMapping("/widget/add") + public String addWidget(@ModelAttribute Widget widget) { + return "enums/new"; + } + + @PostMapping("/widget/add") + public String saveWidget(@Valid Widget widget, Model model) { + model.addAttribute("widget", widget); + return "enums/view"; + } +} diff --git a/spring-thymeleaf-2/src/main/resources/templates/enums/new.html b/spring-thymeleaf-2/src/main/resources/templates/enums/new.html new file mode 100644 index 0000000000..7ac4665171 --- /dev/null +++ b/spring-thymeleaf-2/src/main/resources/templates/enums/new.html @@ -0,0 +1,19 @@ + + + + +Enums in Thymeleaf + + +
+

Add New Widget

+ + + + + +
+ + \ No newline at end of file diff --git a/spring-thymeleaf-2/src/main/resources/templates/enums/view.html b/spring-thymeleaf-2/src/main/resources/templates/enums/view.html new file mode 100644 index 0000000000..f766f66277 --- /dev/null +++ b/spring-thymeleaf-2/src/main/resources/templates/enums/view.html @@ -0,0 +1,30 @@ + + + + +Enums in Thymeleaf + + +

View Widget

+
+ + +
+
+ + +
+
+ This color screams danger. +
+
+ Green is for go. +
+
+ Alert + Warning + Caution + All Good +
+ + \ No newline at end of file diff --git a/testing-modules/junit-5-advanced/src/test/java/com/baeldung/displayname/ReplaceUnderscoresGeneratorUnitTest.java b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/displayname/ReplaceUnderscoresGeneratorUnitTest.java new file mode 100644 index 0000000000..d6e023cfe8 --- /dev/null +++ b/testing-modules/junit-5-advanced/src/test/java/com/baeldung/displayname/ReplaceUnderscoresGeneratorUnitTest.java @@ -0,0 +1,20 @@ +package com.baeldung.displayname; + +import org.junit.jupiter.api.*; + +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +class ReplaceUnderscoresGeneratorUnitTest { + + @Nested + class when_doing_something { + + @Test + void then_should_happen_something() { + } + + @Test + @DisplayName("@DisplayName takes precedence over generation") + void override_generator() { + } + } +} diff --git a/testing-modules/spring-testing/README.md b/testing-modules/spring-testing/README.md index 8eb282643a..07888d7cdf 100644 --- a/testing-modules/spring-testing/README.md +++ b/testing-modules/spring-testing/README.md @@ -4,3 +4,4 @@ - [A Quick Guide to @TestPropertySource](https://www.baeldung.com/spring-test-property-source) - [Guide to ReflectionTestUtils for Unit Testing](https://www.baeldung.com/spring-reflection-test-utils) - [How to Test the @Scheduled Annotation](https://www.baeldung.com/spring-testing-scheduled-annotation) +- [Override properties in Spring]() \ No newline at end of file diff --git a/testing-modules/spring-testing/pom.xml b/testing-modules/spring-testing/pom.xml index 10d34f169b..0eca9b6a7e 100644 --- a/testing-modules/spring-testing/pom.xml +++ b/testing-modules/spring-testing/pom.xml @@ -26,7 +26,6 @@ org.springframework.boot spring-boot-starter LATEST - test org.springframework.boot diff --git a/testing-modules/spring-testing/src/main/java/com/baeldung/overrideproperties/Application.java b/testing-modules/spring-testing/src/main/java/com/baeldung/overrideproperties/Application.java new file mode 100644 index 0000000000..ac215bf78e --- /dev/null +++ b/testing-modules/spring-testing/src/main/java/com/baeldung/overrideproperties/Application.java @@ -0,0 +1,11 @@ +package com.baeldung.overrideproperties; + +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); + } +} diff --git a/testing-modules/spring-testing/src/main/java/com/baeldung/overrideproperties/resolver/PropertySourceResolver.java b/testing-modules/spring-testing/src/main/java/com/baeldung/overrideproperties/resolver/PropertySourceResolver.java new file mode 100644 index 0000000000..074092b7df --- /dev/null +++ b/testing-modules/spring-testing/src/main/java/com/baeldung/overrideproperties/resolver/PropertySourceResolver.java @@ -0,0 +1,24 @@ +package com.baeldung.overrideproperties.resolver; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class PropertySourceResolver { + + private final String firstProperty; + private final String secondProperty; + + public PropertySourceResolver(@Value("${example.firstProperty}") String firstProperty, @Value("${example.secondProperty}") String secondProperty) { + this.firstProperty = firstProperty; + this.secondProperty = secondProperty; + } + + public String getFirstProperty() { + return firstProperty; + } + + public String getSecondProperty() { + return secondProperty; + } +} diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java new file mode 100644 index 0000000000..9b692edd7b --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ContextPropertySourceResolverIntegrationTest.java @@ -0,0 +1,27 @@ +package com.baeldung.overrideproperties; + +import com.baeldung.overrideproperties.resolver.PropertySourceResolver; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@ContextConfiguration(initializers = PropertyOverrideContextInitializer.class, classes = Application.class) +public class ContextPropertySourceResolverIntegrationTest { + + @Autowired private PropertySourceResolver propertySourceResolver; + + @Test + public void shouldContext_overridePropertyValues() { + final String firstProperty = propertySourceResolver.getFirstProperty(); + final String secondProperty = propertySourceResolver.getSecondProperty(); + + assertEquals(PropertyOverrideContextInitializer.PROPERTY_FIRST_VALUE, firstProperty); + assertEquals("contextFile", secondProperty); + } + +} \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java new file mode 100644 index 0000000000..95d83420b7 --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/ProfilePropertySourceResolverIntegrationTest.java @@ -0,0 +1,29 @@ +package com.baeldung.overrideproperties; + +import com.baeldung.overrideproperties.resolver.PropertySourceResolver; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@SpringBootTest +@ActiveProfiles("test") +public class ProfilePropertySourceResolverIntegrationTest { + + @Autowired private PropertySourceResolver propertySourceResolver; + + @Test + public void shouldProfiledProperty_overridePropertyValues() { + final String firstProperty = propertySourceResolver.getFirstProperty(); + final String secondProperty = propertySourceResolver.getSecondProperty(); + + assertEquals("profile", firstProperty); + assertEquals("file", secondProperty); + } + +} \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java new file mode 100644 index 0000000000..a8c4267c5c --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/PropertyOverrideContextInitializer.java @@ -0,0 +1,17 @@ +package com.baeldung.overrideproperties; + +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.test.context.support.TestPropertySourceUtils; + +public class PropertyOverrideContextInitializer implements ApplicationContextInitializer { + + static final String PROPERTY_FIRST_VALUE = "contextClass"; + + @Override + public void initialize(ConfigurableApplicationContext configurableApplicationContext) { + TestPropertySourceUtils.addInlinedPropertiesToEnvironment(configurableApplicationContext, "example.firstProperty=" + PROPERTY_FIRST_VALUE); + + TestPropertySourceUtils.addPropertiesFilesToEnvironment(configurableApplicationContext, "context-override-application.properties"); + } +} diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java new file mode 100644 index 0000000000..573a46dd5f --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/SpringBootPropertySourceResolverIntegrationTest.java @@ -0,0 +1,26 @@ +package com.baeldung.overrideproperties; + +import com.baeldung.overrideproperties.resolver.PropertySourceResolver; +import org.junit.Assert; +import org.junit.Test; +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; + +@RunWith(SpringRunner.class) +@SpringBootTest(properties = { "example.firstProperty=annotation" }) +public class SpringBootPropertySourceResolverIntegrationTest { + + @Autowired private PropertySourceResolver propertySourceResolver; + + @Test + public void shouldSpringBootTestAnnotation_overridePropertyValues() { + final String firstProperty = propertySourceResolver.getFirstProperty(); + final String secondProperty = propertySourceResolver.getSecondProperty(); + + Assert.assertEquals("annotation", firstProperty); + Assert.assertEquals("file", secondProperty); + } + +} \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java new file mode 100644 index 0000000000..c724713854 --- /dev/null +++ b/testing-modules/spring-testing/src/test/java/com/baeldung/overrideproperties/TestResourcePropertySourceResolverIntegrationTest.java @@ -0,0 +1,27 @@ +package com.baeldung.overrideproperties; + +import com.baeldung.overrideproperties.resolver.PropertySourceResolver; +import org.junit.Test; +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 static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class TestResourcePropertySourceResolverIntegrationTest { + + @Autowired private PropertySourceResolver propertySourceResolver; + + @Test + public void shouldTestResourceFile_overridePropertyValues() { + final String firstProperty = propertySourceResolver.getFirstProperty(); + final String secondProperty = propertySourceResolver.getSecondProperty(); + + assertEquals("file", firstProperty); + assertEquals("file", secondProperty); + } + +} \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/resources/application-test.properties b/testing-modules/spring-testing/src/test/resources/application-test.properties new file mode 100644 index 0000000000..54c5bda7e8 --- /dev/null +++ b/testing-modules/spring-testing/src/test/resources/application-test.properties @@ -0,0 +1,2 @@ +# override properties +example.firstProperty=profile \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/resources/application.properties b/testing-modules/spring-testing/src/test/resources/application.properties new file mode 100644 index 0000000000..6c74aa2995 --- /dev/null +++ b/testing-modules/spring-testing/src/test/resources/application.properties @@ -0,0 +1,3 @@ +# override properties +example.firstProperty=file +example.secondProperty=file \ No newline at end of file diff --git a/testing-modules/spring-testing/src/test/resources/context-override-application.properties b/testing-modules/spring-testing/src/test/resources/context-override-application.properties new file mode 100644 index 0000000000..c39e5d3966 --- /dev/null +++ b/testing-modules/spring-testing/src/test/resources/context-override-application.properties @@ -0,0 +1 @@ +example.secondProperty=contextFile \ No newline at end of file