Merge remote-tracking branch 'upstream/master' into BAEL-2981

# Conflicts:
#	libraries-2/pom.xml
This commit is contained in:
isaolmez 2019-06-24 23:16:39 +03:00
commit db931fd553
66 changed files with 2341 additions and 122 deletions

View File

@ -0,0 +1,78 @@
package com.baeldung.folding;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Calculate a hash value for the strings using the folding technique.
*
* The implementation serves only to the illustration purposes and is far
* from being the most efficient.
*
* @author A.Shcherbakov
*
*/
public class FoldingHash {
/**
* Calculate the hash value of a given string.
*
* @param str Assume it is not null
* @param groupSize the group size in the folding technique
* @param maxValue defines a max value that the hash may acquire (exclusive)
* @return integer value from 0 (inclusive) to maxValue (exclusive)
*/
public int hash(String str, int groupSize, int maxValue) {
final int[] codes = this.toAsciiCodes(str);
return IntStream.range(0, str.length())
.filter(i -> i % groupSize == 0)
.mapToObj(i -> extract(codes, i, groupSize))
.map(block -> concatenate(block))
.reduce(0, (a, b) -> (a + b) % maxValue);
}
/**
* Returns a new array of given length whose elements are take from
* the original one starting from the offset.
*
* If the original array has not enough elements, the returning array will contain
* element from the offset till the end of the original array.
*
* @param numbers original array. Assume it is not null.
* @param offset index of the element to start from. Assume it is less than the size of the array
* @param length max size of the resulting array
* @return
*/
public int[] extract(int[] numbers, int offset, int length) {
final int defect = numbers.length - (offset + length);
final int s = defect < 0 ? length + defect : length;
int[] result = new int[s];
for (int index = 0; index < s; index++) {
result[index] = numbers[index + offset];
}
return result;
}
/**
* Concatenate the numbers into a single number as if they were strings.
* Assume that the procedure does not suffer from the overflow.
* @param numbers integers to concatenate
* @return
*/
public int concatenate(int[] numbers) {
final String merged = IntStream.of(numbers)
.mapToObj(number -> "" + number)
.collect(Collectors.joining());
return Integer.parseInt(merged, 10);
}
/**
* Convert the string into its characters' ASCII codes.
* @param str input string
* @return
*/
private int[] toAsciiCodes(String str) {
return str.chars()
.toArray();
}
}

View File

@ -0,0 +1,17 @@
package com.baeldung.folding;
/**
* Code snippet for article "A Guide to the Folding Technique".
*
* @author A.Shcherbakov
*
*/
public class Main {
public static void main(String... arg) {
FoldingHash hasher = new FoldingHash();
final String str = "Java language";
System.out.println(hasher.hash(str, 2, 100_000));
System.out.println(hasher.hash(str, 3, 1_000));
}
}

View File

@ -0,0 +1,54 @@
package com.baeldung.folding;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class FoldingHashUnitTest {
@Test
public void givenStringJavaLanguage_whenSize2Capacity100000_then48933() throws Exception {
final FoldingHash hasher = new FoldingHash();
final int value = hasher.hash("Java language", 2, 100_000);
assertEquals(value, 48933);
}
@Test
public void givenStringVaJaLanguage_whenSize2Capacity100000_thenSameAsJavaLanguage() throws Exception {
final FoldingHash hasher = new FoldingHash();
final int java = hasher.hash("Java language", 2, 100_000);
final int vaja = hasher.hash("vaJa language", 2, 100_000);
assertTrue(java == vaja);
}
@Test
public void givenSingleElementArray_whenOffset0Size2_thenSingleElement() throws Exception {
final FoldingHash hasher = new FoldingHash();
final int[] value = hasher.extract(new int[] { 5 }, 0, 2);
assertArrayEquals(new int[] { 5 }, value);
}
@Test
public void givenFiveElementArray_whenOffset0Size3_thenFirstThreeElements() throws Exception {
final FoldingHash hasher = new FoldingHash();
final int[] value = hasher.extract(new int[] { 1, 2, 3, 4, 5 }, 0, 3);
assertArrayEquals(new int[] { 1, 2, 3 }, value);
}
@Test
public void givenFiveElementArray_whenOffset1Size2_thenTwoElements() throws Exception {
final FoldingHash hasher = new FoldingHash();
final int[] value = hasher.extract(new int[] { 1, 2, 3, 4, 5 }, 1, 2);
assertArrayEquals(new int[] { 2, 3 }, value);
}
@Test
public void givenFiveElementArray_whenOffset2SizeTooBig_thenElementsToTheEnd() throws Exception {
final FoldingHash hasher = new FoldingHash();
final int[] value = hasher.extract(new int[] { 1, 2, 3, 4, 5 }, 2, 2000);
assertArrayEquals(new int[] { 3, 4, 5 }, value);
}
}

View File

@ -29,6 +29,12 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>${auto-service.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
@ -40,6 +46,7 @@
<properties>
<auto-value.version>1.3</auto-value.version>
<auto-factory.version>1.0-beta5</auto-factory.version>
<auto-service.version>1.0-rc5</auto-service.version>
<guice.version>4.2.0</guice.version>
</properties>

View File

@ -0,0 +1,14 @@
package com.baeldung.autoservice;
import com.google.auto.service.AutoService;
import java.util.Locale;
@AutoService(TranslationService.class)
public class BingTranslationServiceProvider implements TranslationService {
@Override
public String translate(String message, Locale from, Locale to) {
// implementation details
return message + " (translated by Bing)";
}
}

View File

@ -0,0 +1,14 @@
package com.baeldung.autoservice;
import com.google.auto.service.AutoService;
import java.util.Locale;
@AutoService(TranslationService.class)
public class GoogleTranslationServiceProvider implements TranslationService {
@Override
public String translate(String message, Locale from, Locale to) {
// implementation details
return message + " (translated by Google)";
}
}

View File

@ -0,0 +1,7 @@
package com.baeldung.autoservice;
import java.util.Locale;
public interface TranslationService {
String translate(String message, Locale from, Locale to);
}

View File

@ -0,0 +1,37 @@
package com.baeldung.autoservice;
import com.baeldung.autoservice.TranslationService;
import org.junit.Before;
import org.junit.Test;
import java.util.ServiceLoader;
import java.util.stream.StreamSupport;
import static org.junit.Assert.assertEquals;
public class TranslationServiceUnitTest {
private ServiceLoader<TranslationService> loader;
@Before
public void setUp() {
loader = ServiceLoader.load(TranslationService.class);
}
@Test
public void whenServiceLoaderLoads_thenLoadsAllProviders() {
long count = StreamSupport.stream(loader.spliterator(), false).count();
assertEquals(2, count);
}
@Test
public void whenServiceLoaderLoadsGoogleService_thenGoogleIsLoaded() {
TranslationService googleService = StreamSupport.stream(loader.spliterator(), false)
.filter(p -> p.getClass().getSimpleName().equals("GoogleTranslationServiceProvider"))
.findFirst()
.get();
String message = "message";
assertEquals(message + " (translated by Google)", googleService.translate(message, null, null));
}
}

View File

@ -0,0 +1,46 @@
package com.baeldung.stream;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SkipLimitComparison {
public static void main(String[] args) {
skipExample();
limitExample();
limitInfiniteStreamExample();
getEvenNumbers(10, 10).stream()
.forEach(System.out::println);
}
public static void skipExample() {
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.filter(i -> i % 2 == 0)
.skip(2)
.forEach(i -> System.out.print(i + " "));
}
public static void limitExample() {
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.filter(i -> i % 2 == 0)
.limit(2)
.forEach(i -> System.out.print(i + " "));
}
public static void limitInfiniteStreamExample() {
Stream.iterate(0, i -> i + 1)
.filter(i -> i % 2 == 0)
.limit(10)
.forEach(System.out::println);
}
private static List<Integer> getEvenNumbers(int offset, int limit) {
return Stream.iterate(0, i -> i + 1)
.filter(i -> i % 2 == 0)
.skip(offset)
.limit(limit)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,84 @@
package com.baeldung.forEach;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
class ReverseList extends ArrayList<String> {
List<String> list = Arrays.asList("A", "B", "C", "D");
Consumer<String> removeElement = s -> {
System.out.println(s + " " + list.size());
if (s != null && s.equals("A")) {
list.remove("D");
}
};
@Override
public Iterator<String> iterator() {
final int startIndex = this.size() - 1;
final List<String> list = this;
return new Iterator<String>() {
int currentIndex = startIndex;
@Override
public boolean hasNext() {
return currentIndex >= 0;
}
@Override
public String next() {
String next = list.get(currentIndex);
currentIndex--;
return next;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public void forEach(Consumer<? super String> action) {
for (String s : this) {
action.accept(s);
}
}
public void iterateParallel() {
list.forEach(System.out::print);
System.out.print(" ");
list.parallelStream().forEach(System.out::print);
}
public void iterateReverse() {
List<String> myList = new ReverseList();
myList.addAll(list);
myList.forEach(System.out::print);
System.out.print(" ");
myList.stream().forEach(System.out::print);
}
public void removeInCollectionForEach() {
list.forEach(removeElement);
}
public void removeInStreamForEach() {
list.stream().forEach(removeElement);
}
public static void main(String[] argv) {
ReverseList collectionForEach = new ReverseList();
collectionForEach.iterateParallel();
collectionForEach.iterateReverse();
collectionForEach.removeInCollectionForEach();
collectionForEach.removeInStreamForEach();
}
}

View File

@ -1,26 +1,35 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.exception.numberformat</groupId>
<artifactId>core-java-exceptions</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>core-java-exceptions</name>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.exception.numberformat</groupId>
<artifactId>core-java-exceptions</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>core-java-exceptions</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-java</relativePath>
</parent>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../parent-java</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<commons-lang3.version>3.9</commons-lang3.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,7 +1,6 @@
package com.baeldung.error;
package com.baeldung.exception.error;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ErrorGeneratorUnitTest {

View File

@ -1,3 +0,0 @@
### Relevant Articles
- [Why Do Local Variables Used in Lambdas Have to Be Final or Effectively Final?](https://www.baeldung.com/java-lambda-effectively-final-local-variables)

View File

@ -0,0 +1,25 @@
package com.baeldung.rawtype;
import java.util.ArrayList;
import java.util.List;
public class RawTypeDemo {
public static void main(String[] args) {
RawTypeDemo rawTypeDemo = new RawTypeDemo();
rawTypeDemo.methodA();
}
public void methodA() {
// parameterized type
List<String> listStr = new ArrayList<>();
listStr.add("Hello Folks!");
methodB(listStr);
String s = listStr.get(1); // ClassCastException at run time
}
public void methodB(List rawList) { // Inexpressive raw type
rawList.add(1); // Unsafe operation
}
}

View File

@ -0,0 +1,100 @@
package com.baeldung.convertiteratortolist;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.apache.commons.collections4.IteratorUtils;
import org.junit.Before;
import org.junit.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
public class ConvertIteratorToListServiceUnitTest {
Iterator<Integer> iterator;
@Before
public void setUp() throws Exception {
iterator = Arrays.asList(1, 2, 3)
.iterator();
}
@Test
public void givenAnIterator_whenConvertIteratorToListUsingWhileLoop_thenReturnAList() {
List<Integer> actualList = new ArrayList<Integer>();
// Convert Iterator to List using while loop dsf
while (iterator.hasNext()) {
actualList.add(iterator.next());
}
assertThat(actualList, hasSize(3));
assertThat(actualList, containsInAnyOrder(1, 2, 3));
}
@Test
public void givenAnIterator_whenConvertIteratorToListAfterJava8_thenReturnAList() {
List<Integer> actualList = new ArrayList<Integer>();
// Convert Iterator to List using Java 8
iterator.forEachRemaining(actualList::add);
assertThat(actualList, hasSize(3));
assertThat(actualList, containsInAnyOrder(1, 2, 3));
}
@Test
public void givenAnIterator_whenConvertIteratorToListJava8Stream_thenReturnAList() {
// Convert iterator to iterable
Iterable<Integer> iterable = () -> iterator;
// Extract List from stream
List<Integer> actualList = StreamSupport
.stream(iterable.spliterator(), false)
.collect(Collectors.toList());
assertThat(actualList, hasSize(3));
assertThat(actualList, containsInAnyOrder(1, 2, 3));
}
@Test
public void givenAnIterator_whenConvertIteratorToImmutableListWithGuava_thenReturnAList() {
// Convert Iterator to an Immutable list using Guava library in Java
List<Integer> actualList = ImmutableList.copyOf(iterator);
assertThat(actualList, hasSize(3));
assertThat(actualList, containsInAnyOrder(1, 2, 3));
}
@Test
public void givenAnIterator_whenConvertIteratorToMutableListWithGuava_thenReturnAList() {
// Convert Iterator to a mutable list using Guava library in Java
List<Integer> actualList = Lists.newArrayList(iterator);
assertThat(actualList, hasSize(3));
assertThat(actualList, containsInAnyOrder(1, 2, 3));
}
@Test
public void givenAnIterator_whenConvertIteratorToMutableListWithApacheCommons_thenReturnAList() {
// Convert Iterator to a mutable list using Apache Commons library in Java
List<Integer> actualList = IteratorUtils.toList(iterator);
assertThat(actualList, hasSize(3));
assertThat(actualList, containsInAnyOrder(1, 2, 3));
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.intstreams.conversion;
import org.junit.Test;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static org.assertj.core.api.Assertions.assertThat;
public class IntStreamsConversionsUnitTest {
@Test
public void intStreamToArray() {
int[] first50EvenNumbers = IntStream.iterate(0, i -> i + 2)
.limit(50)
.toArray();
assertThat(first50EvenNumbers).hasSize(50);
assertThat(first50EvenNumbers[2]).isEqualTo(4);
}
@Test
public void intStreamToList() {
List<Integer> first50IntegerNumbers = IntStream.range(0, 50)
.boxed()
.collect(Collectors.toList());
assertThat(first50IntegerNumbers).hasSize(50);
assertThat(first50IntegerNumbers.get(2)).isEqualTo(2);
}
@Test
public void intStreamToString() {
String first3numbers = IntStream.of(0, 1, 2)
.mapToObj(String::valueOf)
.collect(Collectors.joining(", ", "[", "]"));
assertThat(first3numbers).isEqualTo("[0, 1, 2]");
}
}

View File

@ -1,113 +1,156 @@
<?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">
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>
<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>
<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>
<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>
<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>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<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.la4j</groupId>
<artifactId>la4j</artifactId>
<version>${la4j.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.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>
<groupId>colt</groupId>
<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>
<!-- 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>
<dependency>
<groupId>com.github.jknack</groupId>
<artifactId>handlebars</artifactId>
<version>4.1.2</version>
</dependency>
</dependencies>
</dependency>
<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>
<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>
</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>
</properties>
<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>
</properties>
</project>

View File

@ -0,0 +1,9 @@
package com.baeldung.matrices;
public class MatrixMultiplicationBenchmarking {
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.matrices.apache;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.RealMatrix;
import org.junit.jupiter.api.Test;
import org.openjdk.jmh.annotations.*;
import static org.assertj.core.api.Assertions.assertThat;
@BenchmarkMode(Mode.AverageTime)
@Fork(value = 2)
@Warmup(iterations = 5)
@Measurement(iterations = 10)
public class RealMatrixUnitTest {
@Test
@Benchmark
public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
RealMatrix firstMatrix = new Array2DRowRealMatrix(
new double[][] {
new double[] {1d, 5d},
new double[] {2d, 3d},
new double[] {1d ,7d}
}
);
RealMatrix secondMatrix = new Array2DRowRealMatrix(
new double[][] {
new double[] {1d, 2d, 3d, 7d},
new double[] {5d, 2d, 8d, 1d}
}
);
RealMatrix expected = new Array2DRowRealMatrix(
new double[][] {
new double[] {26d, 12d, 43d, 12d},
new double[] {17d, 10d, 30d, 17d},
new double[] {36d, 16d, 59d, 14d}
}
);
RealMatrix actual = firstMatrix.multiply(secondMatrix);
assertThat(actual).isEqualTo(expected);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.matrices.colt;
import cern.colt.matrix.DoubleFactory2D;
import cern.colt.matrix.DoubleMatrix2D;
import cern.colt.matrix.linalg.Algebra;
import org.junit.jupiter.api.Test;
import org.openjdk.jmh.annotations.*;
import static org.assertj.core.api.Assertions.assertThat;
@BenchmarkMode(Mode.AverageTime)
@Fork(value = 2)
@Warmup(iterations = 5)
@Measurement(iterations = 10)
public class DoubleMatrix2DUnitTest {
@Test
@Benchmark
public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
DoubleFactory2D doubleFactory2D = DoubleFactory2D.dense;
DoubleMatrix2D firstMatrix = doubleFactory2D.make(
new double[][] {
new double[] {1d, 5d},
new double[] {2d, 3d},
new double[] {1d ,7d}
}
);
DoubleMatrix2D secondMatrix = doubleFactory2D.make(
new double[][] {
new double[] {1d, 2d, 3d, 7d},
new double[] {5d, 2d, 8d, 1d}
}
);
DoubleMatrix2D expected = doubleFactory2D.make(
new double[][] {
new double[] {26d, 12d, 43d, 12d},
new double[] {17d, 10d, 30d, 17d},
new double[] {36d, 16d, 59d, 14d}
}
);
Algebra algebra = new Algebra();
DoubleMatrix2D actual = algebra.mult(firstMatrix, secondMatrix);
assertThat(actual).isEqualTo(expected);
}
}

View File

@ -0,0 +1,46 @@
package com.baeldung.matrices.ejml;
import org.ejml.simple.SimpleMatrix;
import org.junit.jupiter.api.Test;
import org.openjdk.jmh.annotations.*;
import static org.assertj.core.api.Assertions.assertThat;
@BenchmarkMode(Mode.AverageTime)
@Fork(value = 2)
@Warmup(iterations = 5)
@Measurement(iterations = 10)
public class SimpleMatrixUnitTest {
@Test
@Benchmark
public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
SimpleMatrix firstMatrix = new SimpleMatrix(
new double[][] {
new double[] {1d, 5d},
new double[] {2d, 3d},
new double[] {1d ,7d}
}
);
SimpleMatrix secondMatrix = new SimpleMatrix(
new double[][] {
new double[] {1d, 2d, 3d, 7d},
new double[] {5d, 2d, 8d, 1d}
}
);
SimpleMatrix expected = new SimpleMatrix(
new double[][] {
new double[] {26d, 12d, 43d, 12d},
new double[] {17d, 10d, 30d, 17d},
new double[] {36d, 16d, 59d, 14d}
}
);
SimpleMatrix actual = firstMatrix.mult(secondMatrix);
assertThat(actual).matches(m -> m.isIdentical(expected, 0d));
}
}

View File

@ -0,0 +1,58 @@
package com.baeldung.matrices.homemade;
import org.junit.jupiter.api.Test;
import org.openjdk.jmh.annotations.*;
import static org.assertj.core.api.Assertions.assertThat;
@BenchmarkMode(Mode.AverageTime)
@Fork(value = 2)
@Warmup(iterations = 5)
@Measurement(iterations = 10)
public class HomemadeMatrixUnitTest {
@Test
@Benchmark
public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
double[][] firstMatrix = {
new double[]{1d, 5d},
new double[]{2d, 3d},
new double[]{1d, 7d}
};
double[][] secondMatrix = {
new double[]{1d, 2d, 3d, 7d},
new double[]{5d, 2d, 8d, 1d}
};
double[][] expected = {
new double[]{26d, 12d, 43d, 12d},
new double[]{17d, 10d, 30d, 17d},
new double[]{36d, 16d, 59d, 14d}
};
double[][] actual = multiplyMatrices(firstMatrix, secondMatrix);
assertThat(actual).isEqualTo(expected);
}
private double[][] multiplyMatrices(double[][] firstMatrix, double[][] secondMatrix) {
double[][] result = new double[firstMatrix.length][secondMatrix[0].length];
for (int row = 0; row < result.length; row++) {
for (int col = 0; col < result[row].length; col++) {
result[row][col] = multiplyMatricesCell(firstMatrix, secondMatrix, row, col);
}
}
return result;
}
private double multiplyMatricesCell(double[][] firstMatrix, double[][] secondMatrix, int row, int col) {
double cell = 0;
for (int i = 0; i < secondMatrix.length; i++) {
cell += firstMatrix[row][i] * secondMatrix[i][col];
}
return cell;
}
}

View File

@ -0,0 +1,47 @@
package com.baeldung.matrices.la4j;
import org.junit.jupiter.api.Test;
import org.la4j.Matrix;
import org.la4j.matrix.dense.Basic2DMatrix;
import org.openjdk.jmh.annotations.*;
import static org.assertj.core.api.Assertions.assertThat;
@BenchmarkMode(Mode.AverageTime)
@Fork(value = 2)
@Warmup(iterations = 5)
@Measurement(iterations = 10)
public class Basic2DMatrixUnitTest {
@Test
@Benchmark
public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
Matrix firstMatrix = new Basic2DMatrix(
new double[][]{
new double[]{1d, 5d},
new double[]{2d, 3d},
new double[]{1d, 7d}
}
);
Matrix secondMatrix = new Basic2DMatrix(
new double[][]{
new double[]{1d, 2d, 3d, 7d},
new double[]{5d, 2d, 8d, 1d}
}
);
Matrix expected = new Basic2DMatrix(
new double[][]{
new double[]{26d, 12d, 43d, 12d},
new double[]{17d, 10d, 30d, 17d},
new double[]{36d, 16d, 59d, 14d}
}
);
Matrix actual = firstMatrix.multiply(secondMatrix);
assertThat(actual).isEqualTo(expected);
}
}

View File

@ -0,0 +1,46 @@
package com.baeldung.matrices.nd4j;
import org.junit.jupiter.api.Test;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.factory.Nd4j;
import org.openjdk.jmh.annotations.*;
import static org.assertj.core.api.Assertions.assertThat;
@BenchmarkMode(Mode.AverageTime)
@Fork(value = 2)
@Warmup(iterations = 5)
@Measurement(iterations = 10)
public class INDArrayUnitTest {
@Test
public void givenTwoMatrices_whenMultiply_thenMultiplicatedMatrix() {
INDArray firstMatrix = Nd4j.create(
new double[][]{
new double[]{1d, 5d},
new double[]{2d, 3d},
new double[]{1d, 7d}
}
);
INDArray secondMatrix = Nd4j.create(
new double[][] {
new double[] {1d, 2d, 3d, 7d},
new double[] {5d, 2d, 8d, 1d}
}
);
INDArray expected = Nd4j.create(
new double[][] {
new double[] {26d, 12d, 43d, 12d},
new double[] {17d, 10d, 30d, 17d},
new double[] {36d, 16d, 59d, 14d}
}
);
INDArray actual = firstMatrix.mmul(secondMatrix);
assertThat(actual).isEqualTo(expected);
}
}

View File

@ -96,6 +96,19 @@
<artifactId>smack-java7</artifactId>
<version>${smack.version}</version>
</dependency>
<!-- NanoHTTPD -->
<dependency>
<groupId>org.nanohttpd</groupId>
<artifactId>nanohttpd</artifactId>
<version>${nanohttpd.version}</version>
</dependency>
<dependency>
<groupId>org.nanohttpd</groupId>
<artifactId>nanohttpd-nanolets</artifactId>
<version>${nanohttpd.version}</version>
</dependency>
</dependencies>
<properties>
@ -108,6 +121,7 @@
<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>
</properties>
</project>

View File

@ -0,0 +1,38 @@
package com.baeldung.nanohttpd;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.router.RouterNanoHTTPD;
import java.io.IOException;
public class ApplicationController extends RouterNanoHTTPD {
ApplicationController() throws IOException {
super(8072);
addMappings();
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
}
@Override
public void addMappings() {
addRoute("/", IndexHandler.class);
addRoute("/users", UserHandler.class);
}
public static class UserHandler extends DefaultHandler {
@Override
public String getText() {
return "UserA, UserB, UserC";
}
@Override
public String getMimeType() {
return MIME_PLAINTEXT;
}
@Override
public Response.IStatus getStatus() {
return Response.Status.OK;
}
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung.nanohttpd;
import fi.iki.elonen.NanoHTTPD;
import java.io.IOException;
public class ItemGetController extends NanoHTTPD {
ItemGetController() throws IOException {
super(8071);
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
}
@Override
public Response serve(IHTTPSession session) {
if (session.getMethod() == Method.GET) {
String itemIdRequestParam = session.getParameters().get("itemId").get(0);
return newFixedLengthResponse("Requested itemId = " + itemIdRequestParam);
}
return newFixedLengthResponse(Response.Status.NOT_FOUND, MIME_PLAINTEXT, "The requested resource does not exist");
}
}

View File

@ -0,0 +1,37 @@
package com.baeldung.nanohttpd;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import static org.junit.Assert.*;
public class ApplicationControllerUnitTest {
private static final String BASE_URL = "http://localhost:8072/";
private static final HttpClient CLIENT = HttpClientBuilder.create().build();
@BeforeClass
public static void setUp() throws IOException {
new ApplicationController();
}
@Test
public void givenServer_whenRootRouteRequested_thenHelloWorldReturned() throws IOException {
HttpResponse response = CLIENT.execute(new HttpGet(BASE_URL));
assertTrue(IOUtils.toString(response.getEntity().getContent()).contains("Hello world!"));
assertEquals(200, response.getStatusLine().getStatusCode());
}
@Test
public void givenServer_whenUsersRequested_thenThenAllUsersReturned() throws IOException {
HttpResponse response = CLIENT.execute(new HttpGet(BASE_URL + "users"));
assertEquals("UserA, UserB, UserC", IOUtils.toString(response.getEntity().getContent()));
}
}

View File

@ -0,0 +1,37 @@
package com.baeldung.nanohttpd;
import static org.junit.Assert.*;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
public class ItemGetControllerUnitTest {
private static final String URL = "http://localhost:8071";
private static final HttpClient CLIENT = HttpClientBuilder.create().build();
@BeforeClass
public static void setUp() throws IOException {
new ItemGetController();
}
@Test
public void givenServer_whenDoingGet_thenParamIsReadCorrectly() throws IOException {
HttpResponse response = CLIENT.execute(new HttpGet(URL + "?itemId=1234"));
assertEquals("Requested itemId = 1234", IOUtils.toString(response.getEntity().getContent()));
}
@Test
public void givenServer_whenDoingPost_then404IsReturned() throws IOException {
HttpResponse response = CLIENT.execute(new HttpPost(URL));
assertEquals(404, response.getStatusLine().getStatusCode());
}
}

View File

@ -0,0 +1 @@
This is a parent module for projects that want to take advantage of the latest Spring Boot improvements/features.

View File

@ -0,0 +1,91 @@
<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>parent-boot-performance</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>parent-boot-performance</name>
<packaging>pom</packaging>
<description>Parent for all modules that want to take advantage of the latest Spring Boot improvements/features. Current version: 2.2</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<rest-assured.version>3.1.0</rest-assured.version>
<!-- plugins -->
<thin.version>1.0.21.RELEASE</thin.version>
<spring-boot.version>2.2.0.M3</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>${start-class}</mainClass>
<!-- this is necessary as we're not using the Boot parent -->
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<profiles>
<profile>
<id>thin-jar</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<!-- The following enables the "thin jar" deployment option. -->
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>${thin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -19,6 +19,11 @@
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@ -47,6 +52,58 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>3.3.3</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<outputDirectory>target/metamodel</outputDirectory>
<processors>
<processor>org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor</processor>
</processors>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>target/metamodel</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<hibernate.version>5.4.0.Final</hibernate.version>
<eclipselink.version>2.7.4-RC1</eclipselink.version>

View File

@ -0,0 +1,79 @@
package com.baeldung.jpa.queryparams;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "employees")
public class Employee {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "employee_number", unique = true)
private String empNumber;
@Column(name = "employee_name")
private String name;
@Column(name = "employee_age")
private int age;
public Employee() {
super();
}
public Employee(Long id, String empNumber) {
super();
this.id = id;
this.empNumber = empNumber;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getEmpNumber() {
return empNumber;
}
public void setEmpNumber(String empNumber) {
this.empNumber = empNumber;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}

View File

@ -224,4 +224,26 @@
value="products_jpa.sql" />
</properties>
</persistence-unit>
<persistence-unit name="jpa-h2-queryparams" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.baeldung.jpa.queryparams.Employee</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver"
value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:h2:mem:test" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="javax.persistence.jdbc.password" value="" />
<property name="hibernate.dialect"
value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="show_sql" value="true" />
<property name="hibernate.temp.use_jdbc_metadata_defaults"
value="false" />
<property name="javax.persistence.sql-load-script-source"
value="employees2.sql" />
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,109 @@
package com.baeldung.jpa.queryparams;
import java.util.Arrays;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.ParameterExpression;
import javax.persistence.criteria.Root;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* JPAQueryParamsTest class tests.
*
* @author gmlopez.mackinnon@gmail.com
*/
public class JPAQueryParamsUnitTest {
private static EntityManager entityManager;
@BeforeClass
public static void setup() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-h2-queryparams");
entityManager = factory.createEntityManager();
}
@Test
public void givenEmpNumber_whenUsingPositionalParameter_thenReturnExpectedEmployee() {
TypedQuery<Employee> query = entityManager.createQuery("SELECT e FROM Employee e WHERE e.empNumber = ?1", Employee.class);
String empNumber = "A123";
Employee employee = query.setParameter(1, empNumber)
.getSingleResult();
Assert.assertNotNull("Employee not found", employee);
}
@Test
public void givenEmpNumberList_whenUsingPositionalParameter_thenReturnExpectedEmployee() {
TypedQuery<Employee> query = entityManager.createQuery("SELECT e FROM Employee e WHERE e.empNumber IN (?1)", Employee.class);
List<String> empNumbers = Arrays.asList("A123", "A124");
List<Employee> employees = query.setParameter(1, empNumbers)
.getResultList();
Assert.assertNotNull("Employees not found", employees);
Assert.assertFalse("Employees not found", employees.isEmpty());
}
@Test
public void givenEmpNumber_whenUsingNamedParameter_thenReturnExpectedEmployee() {
TypedQuery<Employee> query = entityManager.createQuery("SELECT e FROM Employee e WHERE e.empNumber = :number", Employee.class);
String empNumber = "A123";
Employee employee = query.setParameter("number", empNumber)
.getSingleResult();
Assert.assertNotNull("Employee not found", employee);
}
@Test
public void givenEmpNumberList_whenUsingNamedParameter_thenReturnExpectedEmployee() {
TypedQuery<Employee> query = entityManager.createQuery("SELECT e FROM Employee e WHERE e.empNumber IN (:numbers)", Employee.class);
List<String> empNumbers = Arrays.asList("A123", "A124");
List<Employee> employees = query.setParameter("numbers", empNumbers)
.getResultList();
Assert.assertNotNull("Employees not found", employees);
Assert.assertFalse("Employees not found", employees.isEmpty());
}
@Test
public void givenEmpNameAndEmpAge_whenUsingTwoNamedParameters_thenReturnExpectedEmployees() {
TypedQuery<Employee> query = entityManager.createQuery("SELECT e FROM Employee e WHERE e.name = :name AND e.age = :empAge", Employee.class);
String empName = "John Doe";
int empAge = 55;
List<Employee> employees = query.setParameter("name", empName)
.setParameter("empAge", empAge)
.getResultList();
Assert.assertNotNull("Employees not found!", employees);
Assert.assertTrue("Employees not found!", !employees.isEmpty());
}
@Test
public void givenEmpNumber_whenUsingCriteriaQuery_thenReturnExpectedEmployee() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> cQuery = cb.createQuery(Employee.class);
Root<Employee> c = cQuery.from(Employee.class);
ParameterExpression<String> paramEmpNumber = cb.parameter(String.class);
cQuery.select(c)
.where(cb.equal(c.get(Employee_.empNumber), paramEmpNumber));
TypedQuery<Employee> query = entityManager.createQuery(cQuery);
String empNumber = "A123";
query.setParameter(paramEmpNumber, empNumber);
Employee employee = query.getSingleResult();
Assert.assertNotNull("Employee not found!", employee);
}
@Test
public void givenEmpNumber_whenUsingLiteral_thenReturnExpectedEmployee() {
String empNumber = "A123";
TypedQuery<Employee> query = entityManager.createQuery("SELECT e FROM Employee e WHERE e.empNumber = '" + empNumber + "'", Employee.class);
Employee employee = query.getSingleResult();
Assert.assertNotNull("Employee not found!", employee);
}
}

View File

@ -0,0 +1,2 @@
INSERT INTO employees (employee_number, employee_name, employee_age) VALUES ('111', 'John Doe', 55);
INSERT INTO employees (employee_number, employee_name, employee_age) VALUES ('A123', 'John Doe Junior', 25);

View File

@ -14,6 +14,8 @@ if (!JavaVersion.current().java8Compatible) {
apply plugin: "io.ratpack.ratpack-java"
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'io.ratpack.ratpack-groovy'
repositories {
jcenter()

View File

@ -26,11 +26,21 @@
<artifactId>ratpack-core</artifactId>
<version>${ratpack.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-sql</artifactId>
<version>${groovy.sql.version}</version>
</dependency>
<dependency>
<groupId>io.ratpack</groupId>
<artifactId>ratpack-hikari</artifactId>
<version>${ratpack.version}</version>
</dependency>
<dependency>
<groupId>io.ratpack</groupId>
<artifactId>ratpack-groovy-test</artifactId>
<version>${ratpack.test.latest.version}</version>
</dependency>
<dependency>
<groupId>io.ratpack</groupId>
<artifactId>ratpack-hystrix</artifactId>
@ -91,6 +101,7 @@
<httpclient.version>4.5.3</httpclient.version>
<httpcore.version>4.4.6</httpcore.version>
<hystrix.version>1.5.12</hystrix.version>
<groovy.sql.version>2.4.15</groovy.sql.version>
<ratpack.test.latest.version>1.6.1</ratpack.test.latest.version>
</properties>
</project>

View File

@ -0,0 +1,76 @@
package com.baeldung;
@Grab('io.ratpack:ratpack-groovy:1.6.1')
import static ratpack.groovy.Groovy.ratpack
import com.baeldung.model.User
import com.google.common.reflect.TypeToken
import ratpack.exec.Promise
import ratpack.handling.Context
import ratpack.jackson.Jackson
import groovy.sql.Sql
import java.sql.Connection
import java.sql.PreparedStatement
import java.sql.ResultSet
import ratpack.hikari.HikariModule
import javax.sql.DataSource;
ratpack {
serverConfig { port(5050) }
bindings {
module(HikariModule) { config ->
config.dataSourceClassName = 'org.h2.jdbcx.JdbcDataSource'
config.addDataSourceProperty('URL', "jdbc:h2:mem:devDB;INIT=RUNSCRIPT FROM 'classpath:/User.sql'")
}
}
handlers {
get { render 'Hello World from Ratpack with Groovy!!' }
get("greet/:name") { Context ctx ->
render "Hello " + ctx.getPathTokens().get("name") + "!!!"
}
get("data") {
render Jackson.json([title: "Mr", name: "Norman", country: "USA"])
}
post("user") {
Promise<User> user = parse(Jackson.fromJson(User))
user.then { u -> render u.name }
}
get('fetchUserName/:id') { Context ctx ->
Connection connection = ctx.get(DataSource.class).getConnection()
PreparedStatement queryStatement = connection.prepareStatement("SELECT NAME FROM USER WHERE ID=?")
queryStatement.setInt(1, Integer.parseInt(ctx.getPathTokens().get("id")))
ResultSet resultSet = queryStatement.executeQuery()
resultSet.next()
render resultSet.getString(1)
}
get('fetchUsers') {
def db = [url:'jdbc:h2:mem:devDB']
def sql = Sql.newInstance(db.url, db.user, db.password)
def users = sql.rows("SELECT * FROM USER");
render(Jackson.json(users))
}
post('addUser') {
parse(Jackson.fromJson(User))
.then { u ->
def db = [url:'jdbc:h2:mem:devDB']
Sql sql = Sql.newInstance(db.url, db.user, db.password)
sql.executeInsert("INSERT INTO USER VALUES (?,?,?,?)", [
u.id,
u.title,
u.name,
u.country
])
render "User $u.name inserted"
}
}
}
}

View File

@ -0,0 +1,12 @@
package com.baeldung;
public class RatpackGroovyApp {
public static void main(String[] args) {
File file = new File("src/main/groovy/com/baeldung/Ratpack.groovy");
def shell = new GroovyShell()
shell.evaluate(file)
}
}

View File

@ -0,0 +1,9 @@
package com.baeldung.model
class User {
long id
String title
String name
String country
}

View File

@ -0,0 +1,10 @@
DROP TABLE IF EXISTS USER;
CREATE TABLE USER (
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
TITLE VARCHAR(255),
NAME VARCHAR(255),
COUNTRY VARCHAR(255)
);
INSERT INTO USER VALUES(1,'Mr','Norman Potter', 'USA');
INSERT INTO USER VALUES(2,'Miss','Ketty Smith', 'FRANCE');

View File

@ -0,0 +1,46 @@
package com.baeldung;
import ratpack.groovy.Groovy
import ratpack.groovy.test.GroovyRatpackMainApplicationUnderTest;
import ratpack.test.http.TestHttpClient;
import ratpack.test.ServerBackedApplicationUnderTest;
import org.junit.Test;
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import ratpack.test.MainClassApplicationUnderTest
class RatpackGroovySpec {
ServerBackedApplicationUnderTest ratpackGroovyApp = new MainClassApplicationUnderTest(RatpackGroovyApp.class)
@Delegate TestHttpClient client = TestHttpClient.testHttpClient(ratpackGroovyApp)
@Test
void "test if app is started"() {
when:
get("")
then:
assert response.statusCode == 200
assert response.body.text == "Hello World from Ratpack with Groovy!!"
}
@Test
void "test greet with name"() {
when:
get("greet/Lewis")
then:
assert response.statusCode == 200
assert response.body.text == "Hello Lewis!!!"
}
@Test
void "test fetchUsers"() {
when:
get("fetchUsers")
then:
assert response.statusCode == 200
assert response.body.text == '[{"ID":1,"TITLE":"Mr","NAME":"Norman Potter","COUNTRY":"USA"},{"ID":2,"TITLE":"Miss","NAME":"Ketty Smith","COUNTRY":"FRANCE"}]'
}
}

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(l -> {
log.info("INFO log received: " + l);
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.ReactiveMongoTemplate;
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(ReactiveMongoTemplate template) {
Flux<Log> stream = template.tail(query(where(LEVEL_FIELD_NAME).is(LogLevel.WARN)), Log.class);
subscription = stream.subscribe(l -> {
log.warn("WARN log received: " + l);
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();
}
}

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 WarnLogsCounterManualTest {
@Autowired
private LogsRepository repository;
@Autowired
private ReactiveMongoTemplate template;
@Before
public void setUp() {
createCappedCollectionUsingReactiveMongoTemplate(template);
persistDocument(Log.builder()
.level(LogLevel.WARN)
.service("Service 1")
.message("Initial Warn message")
.build());
}
private void createCappedCollectionUsingReactiveMongoTemplate(ReactiveMongoTemplate reactiveMongoTemplate) {
reactiveMongoTemplate.dropCollection(Log.class).block();
reactiveMongoTemplate.createCollection(Log.class, CollectionOptions.empty()
.maxDocuments(5)
.size(1024 * 1024L)
.capped()).block();
}
private void persistDocument(Log log) {
repository.save(log).block();
}
@Test
public void whenWarnLogsArePersisted_thenTheyAreReceivedByLogsCounter() throws Exception {
WarnLogsCounter warnLogsCounter = new WarnLogsCounter(template);
Thread.sleep(1000L); // wait for initialization
Flux.range(0,10)
.map(i -> Log.builder()
.level(i > 5 ? LogLevel.WARN : LogLevel.INFO)
.service("some-service")
.message("some log message")
.build())
.map(entity -> repository.save(entity).subscribe())
.blockLast();
Thread.sleep(1000L); // wait to receive all messages from the reactive mongodb driver
assertThat(warnLogsCounter.count(), is(5));
warnLogsCounter.close();
}
}

View File

@ -0,0 +1,45 @@
<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>spring-boot-performance</artifactId>
<name>spring-boot-performance</name>
<packaging>war</packaging>
<description>This is a simple Spring Boot application taking advantage of the latest Spring Boot improvements/features. Current version: 2.2</description>
<parent>
<artifactId>parent-boot-performance</artifactId>
<groupId>com.baeldung</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-performance</relativePath>
</parent>
<properties>
<!-- The main class to start by executing java -jar -->
<start-class>com.baeldung.lazyinitialization.Application</start-class>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<finalName>spring-boot-performance</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,32 @@
package com.baeldung.lazyinitialization;
import com.baeldung.lazyinitialization.services.Writer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class Application {
@Bean("writer1")
public Writer getWriter1() {
return new Writer("Writer 1");
}
@Bean("writer2")
public Writer getWriter2() {
return new Writer("Writer 2");
}
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
System.out.println("Application context initialized!!!");
Writer writer1 = ctx.getBean("writer1", Writer.class);
writer1.write("First message");
Writer writer2 = ctx.getBean("writer2", Writer.class);
writer2.write("Second message");
}
}

View File

@ -0,0 +1,16 @@
package com.baeldung.lazyinitialization.services;
public class Writer {
private final String writerId;
public Writer(String writerId) {
this.writerId = writerId;
System.out.println(writerId + " initialized!!!");
}
public void write(String message) {
System.out.println(writerId + ": " + message);
}
}

View File

@ -0,0 +1,3 @@
spring:
main:
lazy-initialization: true

View File

@ -140,6 +140,13 @@
<artifactId>handlebars</artifactId>
<version>${handlebars.version}</version>
</dependency>
<!-- commons.io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
@ -208,6 +215,9 @@
<!-- Maven plugins -->
<yuicompressor-maven-plugin.version>1.5.1</yuicompressor-maven-plugin.version>
<!-- commons.io -->
<commons.io.version>2.5</commons.io.version>
</properties>
</project>

View File

@ -0,0 +1,15 @@
package com.baeldung.loadresourceasstring;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LoadResourceConfig {
@Bean
public String resourceString() {
return ResourceReader.readFileToString("resource.txt");
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.loadresourceasstring;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.FileCopyUtils;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UncheckedIOException;
import static java.nio.charset.StandardCharsets.UTF_8;
public class ResourceReader {
public static String readFileToString(String path) {
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource(path);
return asString(resource);
}
public static String asString(Resource resource) {
try (Reader reader = new InputStreamReader(resource.getInputStream(), UTF_8)) {
return FileCopyUtils.copyToString(reader);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}

View File

@ -0,0 +1 @@
This is a resource text file. This file will be loaded as a resource and use its contents as a string.

View File

@ -0,0 +1,57 @@
package com.baeldung.loadresourceasstring;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.util.FileCopyUtils;
import java.io.InputStreamReader;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = LoadResourceConfig.class)
public class LoadResourceAsStringIntegrationTest {
private static final String EXPECTED_RESOURCE_VALUE = "This is a resource text file. This file will be loaded as a " + "resource and use its contents as a string.";
@Value("#{T(com.baeldung.loadresourceasstring.ResourceReader).readFileToString('classpath:resource.txt')}")
private String resourceStringUsingSpel;
@Autowired
@Qualifier("resourceString")
private String resourceString;
@Autowired
private ResourceLoader resourceLoader;
@Test
public void givenUsingResourceLoadAndFileCopyUtils_whenConvertingAResourceToAString_thenCorrect() {
Resource resource = resourceLoader.getResource("classpath:resource.txt");
assertEquals(EXPECTED_RESOURCE_VALUE, ResourceReader.asString(resource));
}
@Test
public void givenUsingResourceStringBean_whenConvertingAResourceToAString_thenCorrect() {
assertEquals(EXPECTED_RESOURCE_VALUE, resourceString);
}
@Test
public void givenUsingSpel_whenConvertingAResourceToAString_thenCorrect() {
assertEquals(EXPECTED_RESOURCE_VALUE, resourceStringUsingSpel);
}
}