Merge branch 'master' into master

This commit is contained in:
Eric Martin 2019-07-04 16:00:21 -05:00 committed by GitHub
commit dc00405a28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
168 changed files with 4174 additions and 209 deletions

View File

@ -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)

View File

@ -18,6 +18,18 @@
<version>${org.assertj.core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
</dependencies>
<build>
@ -34,6 +46,7 @@
<properties>
<org.assertj.core.version>3.9.0</org.assertj.core.version>
<commons-collections4.version>4.3</commons-collections4.version>
<guava.version>28.0-jre</guava.version>
</properties>
</project>

View File

@ -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;
}
}

View File

@ -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<String> listOfStrings) {
if (isEmpty(listOfStrings) || listOfStrings.size() == 1) {
return true;
}
Iterator<String> 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<Employee> employees, Comparator<Employee> employeeComparator) {
if (isEmpty(employees) || employees.size() == 1) {
return true;
}
Iterator<Employee> 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<String> listOfStrings) {
return isSortedRecursive(listOfStrings, listOfStrings.size());
}
public static boolean isSortedRecursive(List<String> 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<String> listOfStrings) {
return Ordering.<String> natural()
.isOrdered(listOfStrings);
}
public static boolean checkIfSortedUsingOrderingClass(List<Employee> employees, Comparator<Employee> employeeComparator) {
return Ordering.from(employeeComparator)
.isOrdered(employees);
}
public static boolean checkIfSortedUsingOrderingClassHandlingNull(List<String> listOfStrings) {
return Ordering.<String> natural()
.nullsLast()
.isOrdered(listOfStrings);
}
public static boolean checkIfSortedUsingComparators(List<String> listOfStrings) {
return Comparators.isInOrder(listOfStrings, Comparator.<String> naturalOrder());
}
}

View File

@ -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<String> sortedListOfString;
private List<String> unsortedListOfString;
private List<String> singletonList;
private List<Employee> employeesSortedByName;
private List<Employee> 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();
}
}

View File

@ -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)
- [Pattern Matching in Strings in Groovy](https://www.baeldung.com/groovy-pattern-matching)
- [Working with XML in Groovy](https://www.baeldung.com/groovy-xml)

View File

@ -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";
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

23
easy-random/pom.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>easy-random</artifactId>
<name>easy-random</name>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-random-core</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
</project>

View File

@ -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();
}
}

View File

@ -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<Employee> coworkers;
private Map<YearQuarter, Grade> 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<Employee> getCoworkers() {
return Collections.unmodifiableCollection(coworkers);
}
public Map<YearQuarter, Grade> 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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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<YearQuarter> {
private LocalDate date = LocalDate.of(1990, Month.SEPTEMBER, 25);
@Override
public YearQuarter getRandomValue() {
date = date.plusMonths(3);
return new YearQuarter(date);
}
}

View File

@ -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<Person> 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));
}
}
}

View File

@ -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;

View File

@ -20,6 +20,13 @@
<artifactId>joda-time</artifactId>
<version>${joda-time.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-validator/commons-validator -->
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.6</version>
</dependency>
<!-- test scoped -->
<dependency>

View File

@ -0,0 +1,5 @@
package com.baeldung.date.validation;
public interface DateValidator {
boolean isValid(String dateStr);
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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));
}
}

View File

@ -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"));
}
}

View File

@ -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"));
}
}

View File

@ -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"));
}
}

View File

@ -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);
}
}

View File

@ -4,7 +4,7 @@
<groupId>com.baeldung.javastreams2</groupId>
<artifactId>javastreams2</artifactId>
<version>1.0</version>
<name>Stream Reduce</name>
<name>javastreams2</name>
<packaging>jar</packaging>
<parent>
@ -42,8 +42,8 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.9</maven.compiler.source>
<maven.compiler.target>1.9</maven.compiler.target>
<assertj.version>3.11.1</assertj.version>
</properties>
</project>

View File

@ -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 <T> void forEach(Stream<T> stream, BiConsumer<T, Breaker> consumer) {
Spliterator<T> spliterator = stream.spliterator();
boolean hadNext = true;
Breaker breaker = new Breaker();
while (hadNext && !breaker.get()) {
hadNext = spliterator.tryAdvance(elem -> {
consumer.accept(elem, breaker);
});
}
}
}

View File

@ -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<T> extends Spliterators.AbstractSpliterator<T> {
private Spliterator<T> splitr;
private Predicate<T> predicate;
private boolean isMatched = true;
public CustomSpliterator(Spliterator<T> splitr, Predicate<T> predicate) {
super(splitr.estimateSize(), 0);
this.splitr = splitr;
this.predicate = predicate;
}
@Override
public boolean tryAdvance(Consumer<? super T> consumer) {
boolean hadNext = splitr.tryAdvance(elem -> {
if (predicate.test(elem) && isMatched) {
consumer.accept(elem);
} else {
isMatched = false;
}
});
return hadNext && isMatched;
}
}

View File

@ -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 <T> Stream<T> takeWhile(Stream<T> stream, Predicate<T> predicate) {
CustomSpliterator<T> customSpliterator = new CustomSpliterator<>(stream.spliterator(), predicate);
return StreamSupport.stream(customSpliterator, false);
}
}

View File

@ -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<String> 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);
}
}
}

View File

@ -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<String> initialStream = Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck");
List<String> result = CustomTakeWhile.takeWhile(initialStream, x -> x.length() % 2 != 0)
.collect(Collectors.toList());
assertEquals(asList("cat", "dog"), result);
}
@Test
public void whenCustomForEachIsCalled_ThenCorrectItemsAreReturned() {
Stream<String> initialStream = Stream.of("cat", "dog", "elephant", "fox", "rabbit", "duck");
List<String> result = new ArrayList<>();
CustomForEach.forEach(initialStream, (elem, breaker) -> {
if (elem.length() % 2 == 0) {
breaker.stop();
} else {
result.add(elem);
}
});
assertEquals(asList("cat", "dog"), result);
}
}

View File

@ -1,4 +1,4 @@
package com.baeldung.intstreams.conversion;
package com.baeldung.convert.intstreams;
import org.junit.Test;

View File

@ -57,6 +57,26 @@
<artifactId>commons-text</artifactId>
<version>${commons-text.version}</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.6</version>
</dependency>
</dependencies>
@ -86,7 +106,7 @@
<properties>
<commons-lang3.version>3.8.1</commons-lang3.version>
<icu4j.version>61.1</icu4j.version>
<guava.version>27.0.1-jre</guava.version>
<guava.version>28.0-jre</guava.version>
<commons-text.version>1.4</commons-text.version>
</properties>

View File

@ -0,0 +1,8 @@
package com.baeldung.string.emptystrings;
class EmptyStringCheck {
boolean isEmptyString(String string) {
return string == null || string.isEmpty();
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.string.emptystrings;
class Java5EmptyStringCheck {
boolean isEmptyString(String string) {
return string == null || string.length() == 0;
}
}

View File

@ -0,0 +1,8 @@
package com.baeldung.string.emptystrings;
class PlainJavaBlankStringCheck {
boolean isBlankString(String string) {
return string == null || string.trim().isEmpty();
}
}

View File

@ -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;
}
}

View File

@ -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")));
}
}

View File

@ -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());
}
}

View File

@ -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, ' ');
}
}

View File

@ -0,0 +1,4 @@
Get busy living
or
get busy dying.
--Stephen King

View File

@ -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());
}
}

View File

@ -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<ConstraintViolation<SomeClassWithValidations>> violations = validator.validate(someClassWithValidations);
assertThat(violations, iterableWithSize(1));
}
@Test
public void givenSomeNonEmptyString_thenBeanValidationValidatesWithoutViolations() {
SomeClassWithValidations someClassWithValidations = new SomeClassWithValidations().setSomeString(nonEmptyString);
Set<ConstraintViolation<SomeClassWithValidations>> violations = validator.validate(someClassWithValidations);
assertThat(violations, iterableWithSize(0));
}
@Test
public void givenSomeBlankString_thenBeanValidationReturnsViolations() {
SomeClassWithValidations someClassWithValidations = new SomeClassWithValidations().setSomeString(blankString);
Set<ConstraintViolation<SomeClassWithValidations>> violations = validator.validate(someClassWithValidations);
assertThat(violations, iterableWithSize(1));
}
}

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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)

View File

@ -1,65 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>libraries2</artifactId>
<name>libraries2</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Repository Group</name>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
</dependency>
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>${classgraph.version}</version>
</dependency>
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-test</artifactId>
<version>${jbpm.version}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>${picocli.version}</version>
</dependency>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>libraries2</artifactId>
<name>libraries2</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Repository Group</name>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.mapdb</groupId>
<artifactId>mapdb</artifactId>
<version>${mapdb.version}</version>
</dependency>
<dependency>
<groupId>com.pivovarit</groupId>
<artifactId>parallel-collectors</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
</dependency>
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>${classgraph.version}</version>
</dependency>
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-test</artifactId>
<version>${jbpm.version}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>${picocli.version}</version>
</dependency>
<dependency>
<groupId>org.ejml</groupId>
<artifactId>ejml-all</artifactId>
<version>${ejml.version}</version>
</dependency>
<dependency>
<groupId>org.nd4j</groupId>
<artifactId>nd4j-native</artifactId>
<version>${nd4j.version}</version>
</dependency>
<dependency>
<groupId>org.nd4j</groupId>
<artifactId>nd4j-native</artifactId>
<version>${nd4j.version}</version>
</dependency>
<dependency>
<groupId>org.la4j</groupId>
<artifactId>la4j</artifactId>
@ -70,88 +76,85 @@
<artifactId>colt</artifactId>
<version>${colt.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>net.openhft</groupId>
<artifactId>chronicle-map</artifactId>
<version>${chronicle.map.version}</version>
<exclusions>
<exclusion>
<groupId>com.sun.java</groupId>
<artifactId>tools</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Dependencies for response decoder with okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>3.14.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>net.openhft</groupId>
<artifactId>chronicle-map</artifactId>
<version>${chronicle.map.version}</version>
<exclusions>
<exclusion>
<groupId>com.sun.java</groupId>
<artifactId>tools</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Dependencies for response decoder with okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>3.14.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>edu.uci.ics</groupId>
<artifactId>crawler4j</artifactId>
<version>${crawler4j.version}</version>
</dependency>
<!-- Benchmarking -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</dependency>
</dependency>
<dependency>
<groupId>com.github.jknack</groupId>
<artifactId>handlebars</artifactId>
<version>4.1.2</version>
</dependency>
<!-- Benchmarking -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh.version}</version>
</dependency>
<dependency>
<groupId>org.apache.mesos</groupId>
<artifactId>mesos</artifactId>
<version>${mesos.library.version}</version>
</dependency>
</dependencies>
<properties>
<assertj.version>3.6.2</assertj.version>
<classgraph.version>4.8.28</classgraph.version>
<jbpm.version>6.0.0.Final</jbpm.version>
<picocli.version>3.9.6</picocli.version>
<chronicle.map.version>3.17.2</chronicle.map.version>
<crawler4j.version>4.4.0</crawler4j.version>
<spring-boot-starter.version>2.1.4.RELEASE</spring-boot-starter.version>
<mesos.library.version>0.28.3</mesos.library.version>
<ejml.version>0.38</ejml.version>
<nd4j.version>1.0.0-beta4</nd4j.version>
<colt.version>1.2.0</colt.version>
<la4j.version>0.6.0</la4j.version>
<jmh.version>1.19</jmh.version>
</properties>
</dependencies>
<properties>
<mapdb.version>3.0.7</mapdb.version>
<assertj.version>3.6.2</assertj.version>
<classgraph.version>4.8.28</classgraph.version>
<jbpm.version>6.0.0.Final</jbpm.version>
<picocli.version>3.9.6</picocli.version>
<chronicle.map.version>3.17.2</chronicle.map.version>
<crawler4j.version>4.4.0</crawler4j.version>
<spring-boot-starter.version>2.1.4.RELEASE</spring-boot-starter.version>
<ejml.version>0.38</ejml.version>
<nd4j.version>1.0.0-beta4</nd4j.version>
<colt.version>1.2.0</colt.version>
<la4j.version>0.6.0</la4j.version>
<jmh.version>1.19</jmh.version>
<mesos.library.version>0.28.3</mesos.library.version>
</properties>
</project>

View File

@ -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<String, String> 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<String, String> 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;
}
}

View File

@ -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<h4>I live in World</h4>\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<h4>I live in World</h4>\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("\n<span>Java is my friend.</span>\n"
+ "\n<span>Spring is my friend.</span>\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("\n<span>Java is my friend.</span>\n"
+ "\n<span>Spring is my friend.</span>\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<h4>Baeldung is busy.</h4>\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<h4>Baeldung is busy.</h4>\n");
}
private Person getPerson(String name) {
Person person = new Person();
person.setName(name);
return person;
}
}

View File

@ -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<Person>() {
@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;
}
}

View File

@ -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;
}
}

View File

@ -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<Person> 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<Person> getFriends() {
return friends;
}
public void setFriends(List<Person> friends) {
this.friends = friends;
}
public static class Address {
private String street;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
}

View File

@ -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("<h4>Hi Baeldung!</h4>\n<p>This is the page Baeldung</p>");
}
@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<html>\n"
+ "<body>\n"
+ "\n This is the intro\n\n"
+ "\n Hi there!\n\n"
+ "</body>\n"
+ "</html>");
}
}

View File

@ -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<String> set = db.
treeSet("mySet")
.serializer(Serializer.STRING)
.createOrOpen();
String myString = "Baeldung!";
set.add(myString);
set.add(myString);
assertEquals(1, set.size());
db.close();
}
}

View File

@ -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<String, String> 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"));
}
}

View File

@ -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);
}
}

View File

@ -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<Integer, String> 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<Integer, String> 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<Integer, String> map = heapDB
.hashMap("myMap")
.keySerializer(Serializer.INTEGER)
.valueSerializer(Serializer.STRING)
.createOrOpen();
map.put(1, "ONE");
assertEquals("ONE", map.get(1));
}
}

View File

@ -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<Integer, String> 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<Integer, String> sortedTableMap = SortedTableMap.open(
openVol,
Serializer.INTEGER,
Serializer.STRING
);
assertEquals(100, sortedTableMap.size());
}
}

View File

@ -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<String> 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();
}
}

View File

@ -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<Integer> ids = Arrays.asList(1, 2, 3);
List<String> results = ids.parallelStream()
.map(i -> fetchById(i))
.collect(Collectors.toList());
System.out.println(results);
}
@Test
public void shouldProcessInParallelWithParallelCollectors() {
ExecutorService executor = Executors.newFixedThreadPool(10);
List<Integer> ids = Arrays.asList(1, 2, 3);
CompletableFuture<List<String>> 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<Integer> ids = Arrays.asList(1, 2, 3);
List<String> 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<Integer> ids = Arrays.asList(1, 2, 3);
List<String> 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<Integer> ids = Arrays.asList(1, 2, 3);
Map<Integer, List<String>> 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<Integer> 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<Integer> 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<Integer> ids = Arrays.asList(1, 2, 3);
Map<Integer, String> 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<Integer> ids = Arrays.asList(1, 2, 3);
Map<Integer, String> 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<Integer> ids = Arrays.asList(1, 2, 3);
Map<Integer, String> 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;
}
}

View File

@ -0,0 +1 @@
Hi {{name}}!

View File

@ -0,0 +1,3 @@
{{#each friends}}
<span>{{name}} is my friend.</span>
{{/each}}

View File

@ -0,0 +1,3 @@
{{#each friends}}
<span>{{name}} is my friend.</span>
{{/each}}

View File

@ -0,0 +1 @@
Hi {{name}}!

View File

@ -0,0 +1 @@
<h4>Hi {{name}}!</h4>

View File

@ -0,0 +1,5 @@
{{#if busy}}
<h4>{{name}} is busy.</h4>
{{else}}
<h4>{{name}} is not busy.</h4>
{{/if}}

View File

@ -0,0 +1,5 @@
{{#if busy}}
<h4>{{name}} is busy.</h4>
{{^}}
<h4>{{name}} is not busy.</h4>
{{/if}}

View File

@ -0,0 +1,9 @@
<html>
<body>
{{#block "intro"}}
This is the intro
{{/block}}
{{#block "message"}}
{{/block}}
</body>
</html>

View File

@ -0,0 +1,2 @@
{{>header}}
<p>This is the page {{name}}</p>

View File

@ -0,0 +1 @@
{{#isBusy this}}{{/isBusy}}

View File

@ -0,0 +1,4 @@
{{#partial "message" }}
Hi there!
{{/partial}}
{{> messagebase}}

View File

@ -0,0 +1,3 @@
{{#with address}}
<h4>I live in {{street}}</h4>
{{/with}}

View File

@ -0,0 +1,3 @@
{{#address}}
<h4>I live in {{street}}</h4>
{{/address}}

View File

@ -65,7 +65,7 @@
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- tomcat -->
<dependency>
<groupId>org.apache.tomcat</groupId>
@ -120,8 +120,8 @@
<commons.collections.version>4.1</commons.collections.version>
<tomcat.version>8.5.24</tomcat.version>
<smack.version>4.3.1</smack.version>
<eclipse.paho.client.mqttv3.version>1.2.0</eclipse.paho.client.mqttv3.version>
<nanohttpd.version>2.3.1</nanohttpd.version>
<eclipse.paho.client.mqttv3.version>1.2.0</eclipse.paho.client.mqttv3.version>
<nanohttpd.version>2.3.1</nanohttpd.version>
</properties>
</project>

View File

@ -19,6 +19,9 @@
<version>${typesafe-akka.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-testkit_2.12</artifactId>
@ -837,6 +840,7 @@
<h2.version>1.4.196</h2.version>
<jnats.version>1.0</jnats.version>
<httpclient.version>4.5.3</httpclient.version>
<jackson.version>2.9.7</jackson.version>
<neuroph.version>2.92</neuroph.version>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<artifactId>jpa-hibernate-cascade-type</artifactId>
<modelVersion>4.0.0</modelVersion>
<version>1.0.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<!-- validation -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>${javax.el-api.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>${org.glassfish.javax.el.version}</version>
</dependency>
</dependencies>
<build>
<finalName>jpa-hibernate-cascade-type</finalName>
<resources>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<properties>
<hibernate.version>5.4.3.Final</hibernate.version>
<assertj-core.version>3.12.2</assertj-core.version>
<hibernate-validator.version>6.0.17.Final</hibernate-validator.version>
<javax.el-api.version>3.0.0</javax.el-api.version>
<org.glassfish.javax.el.version>3.0.1-b11</org.glassfish.javax.el.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<Address> addresses;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public List<Address> getAddresses() {
return addresses;
}
public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -57,5 +57,6 @@
<module>spring-hibernate4</module>
<module>spring-jpa</module>
<module>spring-persistence-simple</module>
<module>jpa-hibernate-cascade-type</module>
</modules>
</project>

View File

@ -422,6 +422,7 @@
<module>drools</module>
<module>dubbo</module>
<module>easy-random</module>
<module>ethereum</module>
<module>feign</module>
@ -464,7 +465,7 @@
<module>java-rmi</module>
<module>java-spi</module>
<module>java-streams</module>
<module>java-streams-2</module>
<!-- <module>java-streams-2</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 -->
<module>java-strings</module>
<module>java-strings-2</module>
<module>java-vavr-stream</module>
@ -659,6 +660,7 @@
<module>spring-cloud-data-flow</module>
<module>spring-core</module>
<module>spring-core-2</module>
<module>spring-cucumber</module>
<module>spring-data-rest</module>
@ -1145,7 +1147,7 @@
<module>java-rmi</module>
<module>java-spi</module>
<module>java-streams</module>
<module>java-streams-2</module>
<!-- <module>java-streams-2</module> --> <!-- We haven't upgraded to java 9. Fixing in BAEL-10841 -->
<module>java-strings</module>
<module>java-strings-2</module>
<module>java-vavr-stream</module>
@ -1323,6 +1325,7 @@
<module>spring-cloud-data-flow</module>
<module>spring-core</module>
<module>spring-core-2</module>
<module>spring-cucumber</module>
<module>spring-data-rest</module>

View File

@ -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)

View File

@ -63,6 +63,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -0,0 +1,5 @@
package com.baeldung.tailablecursor.domain;
public enum LogLevel {
ERROR, WARN, INFO
}

View File

@ -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<Log, String> {
@Tailable
Flux<Log> findByLevel(LogLevel level);
}

View File

@ -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<Log> request = getTailableCursorRequest();
container.register(request, Log.class);
}
@SuppressWarnings("unchecked")
private TailableCursorRequest<Log> getTailableCursorRequest() {
MessageListener<Document, Log> 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();
}
}

View File

@ -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<Log> 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();
}
}

View File

@ -0,0 +1,5 @@
package com.baeldung.tailablecursor.service;
public interface LogsCounter {
int count();
}

View File

@ -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<Log> 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();
}
}

View File

@ -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<Document> 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<Document> 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<Document> 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<Document> 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));
}
}

View File

@ -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();
}
}

Some files were not shown because too many files have changed in this diff Show More