Merge branch 'master' of https://github.com/eugenp/tutorials into future-vavr

This commit is contained in:
Ahmed Tawila 2017-12-04 00:10:17 +02:00
commit 31a0f7b817
8 changed files with 649 additions and 257 deletions

View File

@ -1,258 +1,276 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>core-java-8</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>core-java-8</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<!-- utils -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>${commons-math3.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${avaitility.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>core-java-8</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archiveBaseDirectory>${project.basedir}</archiveBaseDirectory>
<archive>
<manifest>
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
<attachToBuild>true</attachToBuild>
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>integration</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>**/*ManualTest.java</exclude>
</excludes>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<test.mime>json</test.mime>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<!-- util -->
<guava.version>21.0</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-math3.version>3.6.1</commons-math3.version>
<commons-io.version>2.5</commons-io.version>
<commons-collections4.version>4.1</commons-collections4.version>
<collections-generic.version>4.01</collections-generic.version>
<commons-codec.version>1.10</commons-codec.version>
<lombok.version>1.16.12</lombok.version>
<!-- testing -->
<assertj.version>3.6.1</assertj.version>
<avaitility.version>1.7.0</avaitility.version>
</properties>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>core-java-8</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>core-java-8</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<!-- utils -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>${commons-math3.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.awaitility</groupId>
<artifactId>awaitility</artifactId>
<version>${avaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.19</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-bytecode</artifactId>
<version>1.19</version>
</dependency>
</dependencies>
<build>
<finalName>core-java-8</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archiveBaseDirectory>${project.basedir}</archiveBaseDirectory>
<archive>
<manifest>
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<executions>
<execution>
<configuration>
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
<attachToBuild>true</attachToBuild>
<filename>${project.build.finalName}-onejar.${project.packaging}</filename>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>org.baeldung.executable.ExecutableMavenJar</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>integration</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<excludes>
<exclude>**/*ManualTest.java</exclude>
</excludes>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<test.mime>json</test.mime>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<!-- util -->
<guava.version>21.0</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-math3.version>3.6.1</commons-math3.version>
<commons-io.version>2.5</commons-io.version>
<commons-collections4.version>4.1</commons-collections4.version>
<collections-generic.version>4.01</collections-generic.version>
<commons-codec.version>1.10</commons-codec.version>
<lombok.version>1.16.12</lombok.version>
<!-- testing -->
<assertj.version>3.6.1</assertj.version>
<avaitility.version>1.7.0</avaitility.version>
</properties>
</project>

View File

@ -0,0 +1,45 @@
package com.baeldung.counter;
import java.util.HashMap;
import java.util.Map;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Mode;
import com.baeldung.counter.CounterUtil.MutableInteger;
@Fork(value = 1, warmups = 3)
@BenchmarkMode(Mode.All)
public class CounterStatistics {
private static final Map<String, Integer> counterMap = new HashMap<>();
private static final Map<String, MutableInteger> counterWithMutableIntMap = new HashMap<>();
private static final Map<String, int[]> counterWithIntArrayMap = new HashMap<>();
private static final Map<String, Long> counterWithLongWrapperMap = new HashMap<>();
@Benchmark
public void wrapperAsCounter() {
CounterUtil.counterWithWrapperObject(counterMap);
}
@Benchmark
public void lambdaExpressionWithWrapper() {
CounterUtil.counterWithLambdaAndWrapper(counterWithLongWrapperMap);
}
@Benchmark
public void mutableIntegerAsCounter() {
CounterUtil.counterWithMutableInteger(counterWithMutableIntMap);
}
@Benchmark
public void primitiveArrayAsCounter() {
CounterUtil.counterWithPrimitiveArray(counterWithIntArrayMap);
}
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
}

View File

@ -0,0 +1,53 @@
package com.baeldung.counter;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
import org.junit.Test;
import com.baeldung.counter.CounterUtil.MutableInteger;
public class CounterTest {
@Test
public void whenMapWithWrapperAsCounter_runsSuccessfully() {
Map<String, Integer> counterMap = new HashMap<>();
CounterUtil.counterWithWrapperObject(counterMap);
assertEquals(3, counterMap.get("China")
.intValue());
assertEquals(2, counterMap.get("India")
.intValue());
}
@Test
public void whenMapWithLambdaAndWrapperCounter_runsSuccessfully() {
Map<String, Long> counterMap = new HashMap<>();
CounterUtil.counterWithLambdaAndWrapper(counterMap);
assertEquals(3l, counterMap.get("China")
.longValue());
assertEquals(2l, counterMap.get("India")
.longValue());
}
@Test
public void whenMapWithMutableIntegerCounter_runsSuccessfully() {
Map<String, MutableInteger> counterMap = new HashMap<>();
CounterUtil.counterWithMutableInteger(counterMap);
assertEquals(3, counterMap.get("China")
.getCount());
assertEquals(2, counterMap.get("India")
.getCount());
}
@Test
public void whenMapWithPrimitiveArray_runsSuccessfully() {
Map<String, int[]> counterMap = new HashMap<>();
CounterUtil.counterWithPrimitiveArray(counterMap);
assertEquals(3, counterMap.get("China")[0]);
assertEquals(2, counterMap.get("India")[0]);
}
}

View File

@ -0,0 +1,61 @@
package com.baeldung.counter;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CounterUtil {
private final static String[] COUNTRY_NAMES = { "China", "Australia", "India", "USA", "USSR", "UK", "China", "France", "Poland", "Austria", "India", "USA", "Egypt", "China" };
public static void counterWithWrapperObject(Map<String, Integer> counterMap) {
for (String country : COUNTRY_NAMES) {
counterMap.compute(country, (k, v) -> v == null ? 1 : v + 1);
}
}
public static void counterWithLambdaAndWrapper(Map<String, Long> counterMap) {
counterMap.putAll(Stream.of(COUNTRY_NAMES)
.parallel()
.collect(Collectors.groupingBy(k -> k, Collectors.counting())));
}
public static class MutableInteger {
int count;
public MutableInteger(int count) {
this.count = count;
}
public void increment() {
this.count++;
}
public int getCount() {
return this.count;
}
}
public static void counterWithMutableInteger(Map<String, MutableInteger> counterMap) {
for (String country : COUNTRY_NAMES) {
MutableInteger oldValue = counterMap.get(country);
if (oldValue != null) {
oldValue.increment();
} else {
counterMap.put(country, new MutableInteger(1));
}
}
}
public static void counterWithPrimitiveArray(Map<String, int[]> counterMap) {
for (String country : COUNTRY_NAMES) {
int[] oldCounter = counterMap.get(country);
if (oldCounter != null) {
oldCounter[0] += 1;
} else {
counterMap.put(country, new int[] { 1 });
}
}
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.kotlin
import org.junit.Assert
import org.junit.Test
class ExtensionMethods {
@Test
fun simpleExtensionMethod() {
fun String.escapeForXml() : String {
return this
.replace("&", "&amp;")
.replace("<", "&lt;")
.replace(">", "&gt;")
}
Assert.assertEquals("Nothing", "Nothing".escapeForXml())
Assert.assertEquals("&lt;Tag&gt;", "<Tag>".escapeForXml())
Assert.assertEquals("a&amp;b", "a&b".escapeForXml())
}
@Test
fun genericExtensionMethod() {
fun <T> T.concatAsString(b: T) : String {
return this.toString() + b.toString()
}
Assert.assertEquals("12", "1".concatAsString("2"))
Assert.assertEquals("12", 1.concatAsString(2))
// This doesn't compile
// Assert.assertEquals("12", 1.concatAsString(2.0))
}
@Test
fun infixExtensionMethod() {
infix fun Number.toPowerOf(exponent: Number): Double {
return Math.pow(this.toDouble(), exponent.toDouble())
}
Assert.assertEquals(9.0, 3 toPowerOf 2, 0.1)
Assert.assertEquals(3.0, 9 toPowerOf 0.5, 0.1)
}
@Test
fun operatorExtensionMethod() {
operator fun List<Int>.times(by: Int): List<Int> {
return this.map { it * by }
}
Assert.assertEquals(listOf(2, 4, 6), listOf(1, 2, 3) * 2)
}
}

View File

@ -0,0 +1,104 @@
package org.baeldung.bddmockito;
import static org.junit.Assert.fail;
import static org.mockito.BDDMockito.*;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
public class BDDMockitoTest {
PhoneBookService phoneBookService;
PhoneBookRepository phoneBookRepository;
String momContactName = "Mom";
String momPhoneNumber = "01234";
String xContactName = "x";
String tooLongPhoneNumber = "01111111111111";
@Before
public void init() {
phoneBookRepository = Mockito.mock(PhoneBookRepository.class);
phoneBookService = new PhoneBookService(phoneBookRepository);
}
@Test
public void givenValidContactName_whenSearchInPhoneBook_thenRetunPhoneNumber() {
given(phoneBookRepository.contains(momContactName)).willReturn(true);
given(phoneBookRepository.getPhoneNumberByContactName(momContactName))
.will((InvocationOnMock invocation) -> {
if(invocation.getArgument(0).equals(momContactName)) {
return momPhoneNumber;
} else {
return null;
}
});
String phoneNumber = phoneBookService.search(momContactName);
then(phoneBookRepository).should().contains(momContactName);
then(phoneBookRepository).should().getPhoneNumberByContactName(momContactName);
Assert.assertEquals(phoneNumber, momPhoneNumber);
}
@Test
public void givenInvalidContactName_whenSearch_thenRetunNull() {
given(phoneBookRepository.contains(xContactName)).willReturn(false);
String phoneNumber = phoneBookService.search(xContactName);
then(phoneBookRepository).should().contains(xContactName);
then(phoneBookRepository).should(never()).getPhoneNumberByContactName(xContactName);
Assert.assertEquals(phoneNumber, null);
}
@Test
public void givenValidContactNameAndPhoneNumber_whenRegister_thenSucceed() {
given(phoneBookRepository.contains(momContactName)).willReturn(false);
phoneBookService.register(momContactName, momPhoneNumber);
verify(phoneBookRepository).insert(momContactName, momPhoneNumber);
}
@Test
public void givenEmptyPhoneNumber_whenRegister_thenFail() {
given(phoneBookRepository.contains(momContactName)).willReturn(false);
phoneBookService.register(xContactName, "");
then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber);
}
@Test
public void givenLongPhoneNumber_whenRegister_thenFail() {
given(phoneBookRepository.contains(xContactName)).willReturn(false);
willThrow(new RuntimeException())
.given(phoneBookRepository).insert(any(String.class), eq(tooLongPhoneNumber));
try {
phoneBookService.register(xContactName, tooLongPhoneNumber);
fail("Should throw exception");
} catch (RuntimeException ex) { }
then(phoneBookRepository).should(never()).insert(momContactName, tooLongPhoneNumber);
}
@Test
public void givenExistentContactName_whenRegister_thenFail() {
given(phoneBookRepository.contains(momContactName))
.willThrow(new RuntimeException("Name already exist"));
try {
phoneBookService.register(momContactName, momPhoneNumber);
fail("Should throw exception");
} catch(Exception ex) { }
then(phoneBookRepository).should(never()).insert(momContactName, momPhoneNumber);
}
}

View File

@ -0,0 +1,26 @@
package org.baeldung.bddmockito;
public interface PhoneBookRepository {
/**
* Insert phone record
* @param name Contact name
* @param phone Phone number
*/
void insert(String name, String phone);
/**
* Search for contact phone number
* @param name Contact name
* @return phone number
*/
String getPhoneNumberByContactName(String name);
/**
* Check if the phonebook contains this contact
* @param name Contact name
* @return true if this contact name exists
*/
boolean contains(String name);
}

View File

@ -0,0 +1,34 @@
package org.baeldung.bddmockito;
public class PhoneBookService {
private PhoneBookRepository phoneBookRepository;
public PhoneBookService(PhoneBookRepository phoneBookRepository) {
this.phoneBookRepository = phoneBookRepository;
}
/**
* Register a contact
* @param name Contact name
* @param phone Phone number
*/
public void register(String name, String phone) {
if(!name.isEmpty() && !phone.isEmpty() && !phoneBookRepository.contains(name)) {
phoneBookRepository.insert(name, phone);
}
}
/**
* Search for a phone number by contact name
* @param name Contact name
* @return Phone number
*/
public String search(String name) {
if(!name.isEmpty() && phoneBookRepository.contains(name)) {
return phoneBookRepository.getPhoneNumberByContactName(name);
}
return null;
}
}