Merge branch 'master' into BAEL-2940_component_scan

This commit is contained in:
Loredana Crusoveanu 2019-07-17 14:10:01 +03:00 committed by GitHub
commit fba662c12a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
415 changed files with 8206 additions and 1719 deletions

4
.gitignore vendored
View File

@ -1,4 +1,5 @@
*/bin/* */bin/*
bin/
*.class *.class
@ -21,6 +22,9 @@
*.iws *.iws
out/ out/
# VSCode
.vscode/
# Mac # Mac
.DS_Store .DS_Store

View File

@ -6,4 +6,4 @@
- [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity) - [Practical Java Examples of the Big O Notation](http://www.baeldung.com/java-algorithm-complexity)
- [Checking If a List Is Sorted in Java](https://www.baeldung.com/java-check-if-list-sorted) - [Checking If a List Is Sorted in Java](https://www.baeldung.com/java-check-if-list-sorted)
- [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle) - [Checking if a Java Graph has a Cycle](https://www.baeldung.com/java-graph-has-a-cycle)
- [A Guide to the Folding Technique](https://www.baeldung.com/folding-hashing-technique) - [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)

View File

@ -10,10 +10,10 @@
<description>Sample Olingo 2 Project</description> <description>Sample Olingo 2 Project</description>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <artifactId>parent-boot-2</artifactId>
<artifactId>spring-boot-starter-parent</artifactId> <groupId>com.baeldung</groupId>
<version>2.1.3.RELEASE</version> <version>0.0.1-SNAPSHOT</version>
<relativePath /> <!-- lookup parent from repository --> <relativePath>../../parent-boot-2</relativePath>
</parent> </parent>
<dependencies> <dependencies>
@ -82,7 +82,6 @@
</build> </build>
<properties> <properties>
<java.version>1.8</java.version>
<olingo2.version>2.0.11</olingo2.version> <olingo2.version>2.0.11</olingo2.version>
</properties> </properties>

View File

@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest @SpringBootTest
public class Olingo2SampleApplicationTests { public class Olingo2SampleApplicationUnitTest {
@Test @Test
public void contextLoads() { public void contextLoads() {

View File

@ -7,6 +7,13 @@
<version>0.0.1</version> <version>0.0.1</version>
<name>apache-pulsar</name> <name>apache-pulsar</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.apache.pulsar</groupId> <groupId>org.apache.pulsar</groupId>

View File

@ -7,7 +7,7 @@ import org.apache.pulsar.client.api.Message;
import org.apache.pulsar.client.api.PulsarClient; import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.SubscriptionType; import org.apache.pulsar.client.api.SubscriptionType;
public class ConsumerTest { public class ConsumerUnitTest {
private static final String SERVICE_URL = "pulsar://localhost:6650"; private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "test-topic"; private static final String TOPIC_NAME = "test-topic";

View File

@ -11,7 +11,7 @@ import org.apache.pulsar.client.api.PulsarClientException;
import java.io.IOException; import java.io.IOException;
import java.util.stream.IntStream; import java.util.stream.IntStream;
public class ProducerTest { public class ProducerUnitTest {
private static final String SERVICE_URL = "pulsar://localhost:6650"; private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "test-topic"; private static final String TOPIC_NAME = "test-topic";

View File

@ -10,7 +10,7 @@ import org.apache.pulsar.client.api.SubscriptionType;
import java.util.stream.IntStream; import java.util.stream.IntStream;
public class ExclusiveSubscriptionTest { public class ExclusiveSubscriptionUnitTest {
private static final String SERVICE_URL = "pulsar://localhost:6650"; private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "test-topic"; private static final String TOPIC_NAME = "test-topic";
private static final String SUBSCRIPTION_NAME = "test-subscription"; private static final String SUBSCRIPTION_NAME = "test-subscription";

View File

@ -11,7 +11,7 @@ import org.apache.pulsar.client.api.SubscriptionType;
import java.util.stream.IntStream; import java.util.stream.IntStream;
public class FailoverSubscriptionTest { public class FailoverSubscriptionUnitTest {
private static final String SERVICE_URL = "pulsar://localhost:6650"; private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "failover-subscription-test-topic"; private static final String TOPIC_NAME = "failover-subscription-test-topic";
private static final String SUBSCRIPTION_NAME = "test-subscription"; private static final String SUBSCRIPTION_NAME = "test-subscription";

View File

@ -112,7 +112,6 @@
</repositories> </repositories>
<properties> <properties>
<commons-io.version>2.5</commons-io.version>
<aws-lambda-java-events.version>1.3.0</aws-lambda-java-events.version> <aws-lambda-java-events.version>1.3.0</aws-lambda-java-events.version>
<aws-lambda-java-core.version>1.1.0</aws-lambda-java-core.version> <aws-lambda-java-core.version>1.1.0</aws-lambda-java-core.version>
<gson.version>2.8.0</gson.version> <gson.version>2.8.0</gson.version>

View File

@ -175,8 +175,6 @@
<junit.platform.version>1.0.0</junit.platform.version> <junit.platform.version>1.0.0</junit.platform.version>
<hsqldb.version>2.4.0</hsqldb.version> <hsqldb.version>2.4.0</hsqldb.version>
<spock-core.version>1.1-groovy-2.4</spock-core.version> <spock-core.version>1.1-groovy-2.4</spock-core.version>
<commons-lang3.version>3.9</commons-lang3.version>
<java.version>1.8</java.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version> <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<logback.version>1.2.3</logback.version> <logback.version>1.2.3</logback.version>
<groovy.version>2.5.7</groovy.version> <groovy.version>2.5.7</groovy.version>

View File

@ -0,0 +1,52 @@
package com.baeldung.concatenate
class Wonder {
String numOfWonder = 'seven'
String operator_plus() {
return 'The ' + numOfWonder + ' wonders of the world'
}
String operator_left() {
return 'The ' << numOfWonder << ' wonders of ' << 'the world'
}
String interpolation_one() {
return "The $numOfWonder wonders of the world"
}
String interpolation_two() {
return "The ${numOfWonder} wonders of the world"
}
String multilineString() {
return """
There are $numOfWonder wonders of the world.
Can you name them all?
1. The Great Pyramid of Giza
2. Hanging Gardens of Babylon
3. Colossus of Rhode
4. Lighthouse of Alexendra
5. Temple of Artemis
6. Status of Zeus at Olympia
7. Mausoleum at Halicarnassus
"""
}
String method_concat() {
return 'The '.concat(numOfWonder).concat(' wonders of the world')
}
String method_builder() {
return new StringBuilder()
.append('The ').append(numOfWonder).append(' wonders of the world')
}
String method_buffer() {
return new StringBuffer()
.append('The ').append(numOfWonder).append(' wonders of the world')
}
}

View File

@ -0,0 +1,69 @@
package com.baeldung.concatenate
import org.junit.Before
import org.junit.Test
import static org.junit.Assert.*
class WonderUnitTest {
static final String EXPECTED_SINGLE_LINE = "The seven wonders of the world"
Wonder wonder
@Before
void before() {
wonder = new Wonder()
}
@Test
void whenUsingOperatorPlus_thenConcatCorrectly() {
assertEquals(EXPECTED_SINGLE_LINE, wonder.operator_plus())
}
@Test
void whenUsingOperatorLeft_thenConcatCorrectly() {
assertEquals(EXPECTED_SINGLE_LINE, wonder.operator_left())
}
@Test
void whenUsingInterpolationOne_thenConcatCorrectly() {
assertEquals(EXPECTED_SINGLE_LINE, wonder.interpolation_one())
}
@Test
void whenUsingInterpolationTwo_thenConcatCorrectly() {
assertEquals(EXPECTED_SINGLE_LINE, wonder.interpolation_two())
}
@Test
void whenUsingMultiline_thenConcatCorrectly() {
def expectedMultiline = """
There are seven wonders of the world.
Can you name them all?
1. The Great Pyramid of Giza
2. Hanging Gardens of Babylon
3. Colossus of Rhode
4. Lighthouse of Alexendra
5. Temple of Artemis
6. Status of Zeus at Olympia
7. Mausoleum at Halicarnassus
"""
assertEquals(expectedMultiline, wonder.multilineString())
}
@Test
void whenUsingMethodConcat_thenConcatCorrectly() {
assertEquals(EXPECTED_SINGLE_LINE, wonder.method_concat())
}
@Test
void whenUsingMethodBuilder_thenConcatCorrectly() {
assertEquals(EXPECTED_SINGLE_LINE, wonder.method_builder())
}
@Test
void whenUsingMethodBuffer_thenConcatCorrectly() {
assertEquals(EXPECTED_SINGLE_LINE, wonder.method_buffer())
}
}

View File

@ -0,0 +1,3 @@
## Relevant articles:
- [Negate a Predicate Method Reference with Java 11](https://www.baeldung.com/java-negate-predicate-method-reference)

View File

@ -0,0 +1,3 @@
## Relevant articles:
- [String API Updates in Java 12](https://www.baeldung.com/java12-string-api)

View File

@ -175,7 +175,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<commons-math3.version>3.6.1</commons-math3.version> <commons-math3.version>3.6.1</commons-math3.version>
<commons-collections4.version>4.1</commons-collections4.version> <commons-collections4.version>4.1</commons-collections4.version>
<collections-generic.version>4.01</collections-generic.version> <collections-generic.version>4.01</collections-generic.version>

View File

@ -0,0 +1,71 @@
package com.baeldung.array;
import com.baeldung.arraycopy.model.Employee;
public class SortedArrayChecker {
boolean isSorted(int[] array, int length) {
if (array == null || length < 2)
return true;
if (array[length - 2] > array[length - 1])
return false;
return isSorted(array, length - 1);
}
boolean isSorted(int[] array) {
for (int i = 0; i < array.length - 1; i++) {
if (array[i] > array[i + 1])
return false;
}
return true;
}
boolean isSorted(String[] array, int length) {
if (array == null || length < 2)
return true;
if (array[length - 2].compareTo(array[length - 1]) > 0)
return false;
return isSorted(array, length - 1);
}
boolean isSorted(String[] array) {
for (int i = 0; i < array.length - 1; ++i) {
if (array[i].compareTo(array[i + 1]) > 0)
return false;
}
return true;
}
boolean isSortedByName(Employee[] array) {
for (int i = 0; i < array.length - 1; ++i) {
if (array[i].getName().compareTo(array[i + 1].getName()) > 0)
return false;
}
return true;
}
boolean isSortedByAge(Employee[] array) {
for (int i = 0; i < array.length - 1; ++i) {
if (array[i].getAge() > (array[i + 1].getAge()))
return false;
}
return true;
}
boolean isSortedByAge(Employee[] array, int length) {
if (array == null || length < 2)
return true;
if (array[length - 2].getAge() > array[length - 1].getAge())
return false;
return isSortedByAge(array, length - 1);
}
}

View File

@ -6,6 +6,7 @@ public class Employee implements Serializable {
private static final long serialVersionUID = -2454619097207585825L; private static final long serialVersionUID = -2454619097207585825L;
private int id; private int id;
private String name; private String name;
private int age;
public Employee() { public Employee() {
} }
@ -15,10 +16,24 @@ public class Employee implements Serializable {
this.name = name; this.name = name;
} }
public Employee(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public int getId() { public int getId() {
return id; return id;
} }
public void setAge(int age) {
this.age = age;
}
public void setId(int id) { public void setId(int id) {
this.id = id; this.id = id;
} }

View File

@ -0,0 +1,73 @@
package com.baeldung.array;
import com.baeldung.arraycopy.model.Employee;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
class SortedArrayCheckerUnitTest {
private static final int[] INTEGER_SORTED = {1, 3, 5, 7, 9};
private static final int[] INTEGER_NOT_SORTED = {1, 3, 11, 7};
private static final String[] STRING_SORTED = {"abc", "cde", "fgh"};
private static final String[] STRING_NOT_SORTED = {"abc", "fgh", "cde", "ijk"};
private final Employee[] EMPLOYEES_SORTED_BY_NAME = {
new Employee(1, "Carlos", 26),
new Employee(2, "Daniel", 31),
new Employee(3, "Marta", 27)};
private final Employee[] EMPLOYEES_NOT_SORTED_BY_NAME = {
new Employee(1, "Daniel", 31),
new Employee(2, "Carlos", 26),
new Employee(3, "Marta", 27)};
private final Employee[] EMPLOYEES_SORTED_BY_AGE = {
new Employee(1, "Carlos", 26),
new Employee(2, "Marta", 27),
new Employee(3, "Daniel", 31)};
private final Employee[] EMPLOYEES_NOT_SORTED_BY_AGE = {
new Employee(1, "Marta", 27),
new Employee(2, "Carlos", 26),
new Employee(3, "Daniel", 31)};
private SortedArrayChecker sortedArrayChecker;
@Before
public void setup() {
sortedArrayChecker = new SortedArrayChecker();
}
@Test
public void givenIntegerArray_thenReturnIfItIsSortedOrNot() {
assertThat(sortedArrayChecker.isSorted(INTEGER_SORTED)).isEqualTo(true);
assertThat(sortedArrayChecker.isSorted(INTEGER_NOT_SORTED)).isEqualTo(false);
assertThat(sortedArrayChecker.isSorted(INTEGER_SORTED, INTEGER_SORTED.length)).isEqualTo(true);
assertThat(sortedArrayChecker.isSorted(INTEGER_NOT_SORTED, INTEGER_NOT_SORTED.length)).isEqualTo(false);
}
@Test
public void givenStringArray_thenReturnIfItIsSortedOrNot() {
assertThat(sortedArrayChecker.isSorted(STRING_SORTED)).isEqualTo(true);
assertThat(sortedArrayChecker.isSorted(STRING_NOT_SORTED)).isEqualTo(false);
assertThat(sortedArrayChecker.isSorted(STRING_SORTED, STRING_SORTED.length)).isEqualTo(true);
assertThat(sortedArrayChecker.isSorted(STRING_NOT_SORTED, STRING_NOT_SORTED.length)).isEqualTo(false);
}
@Test
public void givenEmployeeArray_thenReturnIfItIsSortedOrNot() {
assertThat(sortedArrayChecker.isSortedByName(EMPLOYEES_SORTED_BY_NAME)).isEqualTo(true);
assertThat(sortedArrayChecker.isSortedByName(EMPLOYEES_NOT_SORTED_BY_NAME)).isEqualTo(false);
assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_SORTED_BY_AGE)).isEqualTo(true);
assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_NOT_SORTED_BY_AGE)).isEqualTo(false);
assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_SORTED_BY_AGE, EMPLOYEES_SORTED_BY_AGE.length)).isEqualTo(true);
assertThat(sortedArrayChecker.isSortedByAge(EMPLOYEES_NOT_SORTED_BY_AGE, EMPLOYEES_NOT_SORTED_BY_AGE.length)).isEqualTo(false);
}
}

View File

@ -72,7 +72,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<guava.version>21.0</guava.version> <guava.version>21.0</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-math3.version>3.6.1</commons-math3.version> <commons-math3.version>3.6.1</commons-math3.version>
<commons-collections4.version>4.1</commons-collections4.version> <commons-collections4.version>4.1</commons-collections4.version>
<collections-generic.version>4.01</collections-generic.version> <collections-generic.version>4.01</collections-generic.version>

View File

@ -17,3 +17,4 @@
- [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable) - [Runnable vs. Callable in Java](http://www.baeldung.com/java-runnable-callable)
- [What is Thread-Safety and How to Achieve it?](https://www.baeldung.com/java-thread-safety) - [What is Thread-Safety and How to Achieve it?](https://www.baeldung.com/java-thread-safety)
- [How to Start a Thread in Java](https://www.baeldung.com/java-start-thread) - [How to Start a Thread in Java](https://www.baeldung.com/java-start-thread)
- [How to Delay Code Execution in Java](https://www.baeldung.com/java-delay-code-execution)

View File

@ -45,8 +45,6 @@
</build> </build>
<properties> <properties>
<!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<!-- testing --> <!-- testing -->
<assertj.version>3.6.1</assertj.version> <assertj.version>3.6.1</assertj.version>
<avaitility.version>1.7.0</avaitility.version> <avaitility.version>1.7.0</avaitility.version>

View File

@ -62,7 +62,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<guava.version>21.0</guava.version> <guava.version>21.0</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-math3.version>3.6.1</commons-math3.version> <commons-math3.version>3.6.1</commons-math3.version>
<commons-collections4.version>4.1</commons-collections4.version> <commons-collections4.version>4.1</commons-collections4.version>
<collections-generic.version>4.01</collections-generic.version> <collections-generic.version>4.01</collections-generic.version>

View File

@ -0,0 +1,3 @@
## Relevant articles:
- [Will an Error Be Caught by Catch Block in Java?](https://www.baeldung.com/java-error-catch)

View File

@ -248,7 +248,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<bouncycastle.version>1.55</bouncycastle.version> <bouncycastle.version>1.55</bouncycastle.version>
<commons-codec.version>1.10</commons-codec.version> <commons-codec.version>1.10</commons-codec.version>
<commons-math3.version>3.6.1</commons-math3.version> <commons-math3.version>3.6.1</commons-math3.version>

View File

@ -35,7 +35,6 @@
</dependencies> </dependencies>
<properties> <properties>
<commons-lang3.version>3.5</commons-lang3.version>
<assertj.version>3.6.1</assertj.version> <assertj.version>3.6.1</assertj.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,3 @@
## 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

@ -75,13 +75,7 @@
</build> </build>
<properties> <properties>
<!-- marshalling -->
<jackson.version>2.8.5</jackson.version>
<gson.version>2.8.2</gson.version> <gson.version>2.8.2</gson.version>
<!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<!-- testing --> <!-- testing -->
<assertj-core.version>3.10.0</assertj-core.version> <assertj-core.version>3.10.0</assertj-core.version>
<equalsverifier.version>3.0.3</equalsverifier.version> <equalsverifier.version>3.0.3</equalsverifier.version>

View File

@ -76,9 +76,6 @@
<properties> <properties>
<gson.version>2.8.2</gson.version> <gson.version>2.8.2</gson.version>
<!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<javax.mail.version>1.5.0-b01</javax.mail.version> <javax.mail.version>1.5.0-b01</javax.mail.version>
<!-- testing --> <!-- testing -->

View File

@ -42,8 +42,6 @@
<properties> <properties>
<javax.mail.version>1.5.0-b01</javax.mail.version> <javax.mail.version>1.5.0-b01</javax.mail.version>
<commons-io.version>2.5</commons-io.version>
<commons-lang3.version>3.5</commons-lang3.version>
<springframework.spring-web.version>4.3.4.RELEASE</springframework.spring-web.version> <springframework.spring-web.version>4.3.4.RELEASE</springframework.spring-web.version>
</properties> </properties>
</project> </project>

View File

@ -19,12 +19,12 @@
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<version>${h2database.version}</version> <version>${h2.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>${jackson.databind.version}</version> <version>${jackson.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
@ -48,7 +48,5 @@
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<hibernate.core.version>5.4.0.Final</hibernate.core.version> <hibernate.core.version>5.4.0.Final</hibernate.core.version>
<h2database.version>1.4.197</h2database.version>
<jackson.databind.version>2.9.8</jackson.databind.version>
</properties> </properties>
</project> </project>

View File

@ -68,7 +68,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<commons-collections4.version>4.1</commons-collections4.version> <commons-collections4.version>4.1</commons-collections4.version>
<collections-generic.version>4.01</collections-generic.version> <collections-generic.version>4.01</collections-generic.version>

View File

@ -23,11 +23,4 @@
</dependencies> </dependencies>
<properties>
<!-- util -->
<commons-lang3.version>3.8.1</commons-lang3.version>
</properties>
</project> </project>

View File

@ -43,7 +43,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<commons-lang3.version>3.8.1</commons-lang3.version>
<bouncycastle.version>1.60</bouncycastle.version> <bouncycastle.version>1.60</bouncycastle.version>
<commons-codec.version>1.11</commons-codec.version> <commons-codec.version>1.11</commons-codec.version>

View File

@ -264,7 +264,6 @@
<!-- util --> <!-- util -->
<guava.version>23.0</guava.version> <guava.version>23.0</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<bouncycastle.version>1.55</bouncycastle.version> <bouncycastle.version>1.55</bouncycastle.version>
<commons-codec.version>1.10</commons-codec.version> <commons-codec.version>1.10</commons-codec.version>
<commons-math3.version>3.6.1</commons-math3.version> <commons-math3.version>3.6.1</commons-math3.version>

View File

@ -113,7 +113,7 @@
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<version>${h2database.version}</version> <version>${h2.version}</version>
</dependency> </dependency>
<!-- instrumentation --> <!-- instrumentation -->
<dependency> <dependency>
@ -453,8 +453,6 @@
<gson.version>2.8.2</gson.version> <gson.version>2.8.2</gson.version>
<!-- util --> <!-- util -->
<commons-lang3.version>3.9</commons-lang3.version>
<commons-io.version>2.5</commons-io.version>
<commons-math3.version>3.6.1</commons-math3.version> <commons-math3.version>3.6.1</commons-math3.version>
<decimal4j.version>1.0.3</decimal4j.version> <decimal4j.version>1.0.3</decimal4j.version>
<unix4j.version>0.4</unix4j.version> <unix4j.version>0.4</unix4j.version>
@ -471,7 +469,6 @@
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version> <maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
<javamoney.moneta.version>1.1</javamoney.moneta.version> <javamoney.moneta.version>1.1</javamoney.moneta.version>
<h2database.version>1.4.197</h2database.version>
<esapi.version>2.1.0.1</esapi.version> <esapi.version>2.1.0.1</esapi.version>
<jmh-core.version>1.19</jmh-core.version> <jmh-core.version>1.19</jmh-core.version>

View File

@ -1,15 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <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> <modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.daomodule</groupId>
<artifactId>daomodule</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<parent> <parent>
<groupId>com.baeldung.multimodulemavenproject</groupId> <groupId>com.baeldung.multimodulemavenproject</groupId>
<artifactId>multimodulemavenproject</artifactId> <artifactId>multimodulemavenproject</artifactId>
<version>1.0</version> <version>1.0</version>
</parent> </parent>
<groupId>com.baeldung.daomodule</groupId>
<artifactId>daomodule</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<build> <build>
<plugins> <plugins>

View File

@ -22,7 +22,7 @@
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId> <artifactId>junit-jupiter</artifactId>
<version>${junit.jupiter.version}</version> <version>${junit-jupiter.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -88,7 +88,7 @@
<properties> <properties>
<kotlin.version>1.3.30</kotlin.version> <kotlin.version>1.3.30</kotlin.version>
<junit.jupiter.version>5.4.2</junit.jupiter.version> <junit-jupiter.version>5.4.2</junit-jupiter.version>
<mockito.version>2.27.0</mockito.version> <mockito.version>2.27.0</mockito.version>
<byte-buddy.version>1.9.12</byte-buddy.version> <byte-buddy.version>1.9.12</byte-buddy.version>
<assertj.version>3.10.0</assertj.version> <assertj.version>3.10.0</assertj.version>

View File

@ -39,7 +39,7 @@
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<version>${h2database.version}</version> <version>${h2.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.kittinunf.fuel</groupId> <groupId>com.github.kittinunf.fuel</groupId>
@ -76,11 +76,9 @@
<properties> <properties>
<commons-math3.version>3.6.1</commons-math3.version> <commons-math3.version>3.6.1</commons-math3.version>
<commons-lang3.version>3.8.1</commons-lang3.version>
<junit.platform.version>1.1.1</junit.platform.version> <junit.platform.version>1.1.1</junit.platform.version>
<junit.vintage.version>5.2.0</junit.vintage.version> <junit.vintage.version>5.2.0</junit.vintage.version>
<assertj.version>3.10.0</assertj.version> <assertj.version>3.10.0</assertj.version>
<h2database.version>1.4.197</h2database.version>
<fuel.version>1.15.0</fuel.version> <fuel.version>1.15.0</fuel.version>
<kovenant.version>3.3.0</kovenant.version> <kovenant.version>3.3.0</kovenant.version>
<injekt-core.version>1.16.1</injekt-core.version> <injekt-core.version>1.16.1</injekt-core.version>

View File

@ -69,7 +69,6 @@
<properties> <properties>
<couchbase.client.version>2.5.0</couchbase.client.version> <couchbase.client.version>2.5.0</couchbase.client.version>
<spring-framework.version>4.3.5.RELEASE</spring-framework.version> <spring-framework.version>4.3.5.RELEASE</spring-framework.version>
<commons-lang3.version>3.5</commons-lang3.version>
</properties> </properties>
</project> </project>

View File

@ -8,6 +8,12 @@
<packaging>jar</packaging> <packaging>jar</packaging>
<url>http://maven.apache.org</url> <url>http://maven.apache.org</url>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>net.sourceforge.pmd</groupId> <groupId>net.sourceforge.pmd</groupId>

View File

@ -115,7 +115,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<disruptor.version>3.3.6</disruptor.version> <disruptor.version>3.3.6</disruptor.version>
<!-- testing --> <!-- testing -->
<testng.version>6.10</testng.version> <testng.version>6.10</testng.version>

View File

@ -26,7 +26,6 @@
</dependencies> </dependencies>
<properties> <properties>
<commons-lang3.version>3.5</commons-lang3.version>
<dozer.version>5.5.1</dozer.version> <dozer.version>5.5.1</dozer.version>
</properties> </properties>

View File

@ -8,6 +8,13 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<name>flyway-cdi-extension</name> <name>flyway-cdi-extension</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>javax.enterprise</groupId> <groupId>javax.enterprise</groupId>
@ -51,6 +58,5 @@
<flyway-core.version>5.1.4</flyway-core.version> <flyway-core.version>5.1.4</flyway-core.version>
<tomcat-jdbc.version>8.5.33</tomcat-jdbc.version> <tomcat-jdbc.version>8.5.33</tomcat-jdbc.version>
<javax.annotation-api.version>1.3.2</javax.annotation-api.version> <javax.annotation-api.version>1.3.2</javax.annotation-api.version>
<h2.version>1.4.197</h2.version>
</properties> </properties>
</project> </project>

View File

@ -64,7 +64,6 @@
<!-- marshalling --> <!-- marshalling -->
<gson.version>2.8.0</gson.version> <gson.version>2.8.0</gson.version>
<!-- util --> <!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<commons-collections4.version>4.1</commons-collections4.version> <commons-collections4.version>4.1</commons-collections4.version>
<joda-time.version>2.9.6</joda-time.version> <joda-time.version>2.9.6</joda-time.version>
</properties> </properties>

View File

@ -55,7 +55,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<guava.version>24.0-jre</guava.version> <guava.version>24.0-jre</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-collections4.version>4.1</commons-collections4.version> <commons-collections4.version>4.1</commons-collections4.version>
<!-- testing --> <!-- testing -->

View File

@ -49,7 +49,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<guava.version>24.0-jre</guava.version> <guava.version>24.0-jre</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<!-- testing --> <!-- testing -->
<assertj.version>3.6.1</assertj.version> <assertj.version>3.6.1</assertj.version>

View File

@ -297,7 +297,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<guava.version>19.0</guava.version> <guava.version>19.0</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-codec.version>1.10</commons-codec.version> <commons-codec.version>1.10</commons-codec.version>
<httpasyncclient.version>4.1.4</httpasyncclient.version> <httpasyncclient.version>4.1.4</httpasyncclient.version>
<!-- testing --> <!-- testing -->
@ -305,7 +304,6 @@
<httpcore.version>4.4.11</httpcore.version> <httpcore.version>4.4.11</httpcore.version>
<httpclient.version>4.5.8</httpclient.version> <!-- 4.3.6 --> <!-- 4.4-beta1 --> <httpclient.version>4.5.8</httpclient.version> <!-- 4.3.6 --> <!-- 4.4-beta1 -->
<!-- maven plugins --> <!-- maven plugins -->
<maven-war-plugin.version>2.6</maven-war-plugin.version>
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version> <cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
</properties> </properties>

View File

@ -120,7 +120,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<guava.version>19.0</guava.version> <guava.version>19.0</guava.version>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-codec.version>1.10</commons-codec.version> <commons-codec.version>1.10</commons-codec.version>
<httpasyncclient.version>4.1.4</httpasyncclient.version> <httpasyncclient.version>4.1.4</httpasyncclient.version>
<!-- testing --> <!-- testing -->

View File

@ -65,7 +65,6 @@
<hystrix-core.version>1.5.8</hystrix-core.version> <hystrix-core.version>1.5.8</hystrix-core.version>
<rxjava-core.version>0.20.7</rxjava-core.version> <rxjava-core.version>0.20.7</rxjava-core.version>
<!-- maven plugins --> <!-- maven plugins -->
<maven-war-plugin.version>2.6</maven-war-plugin.version>
<maven-resources-plugin.version>2.7</maven-resources-plugin.version> <maven-resources-plugin.version>2.7</maven-resources-plugin.version>
<hystrix-metrics-event-stream.version>1.5.8</hystrix-metrics-event-stream.version> <hystrix-metrics-event-stream.version>1.5.8</hystrix-metrics-event-stream.version>
<hystrix-dashboard.version>1.5.8</hystrix-dashboard.version> <hystrix-dashboard.version>1.5.8</hystrix-dashboard.version>

View File

@ -0,0 +1,126 @@
package com.baeldung.jackson.json.compare;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.Comparator;
import org.junit.Test;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.NumericNode;
import com.fasterxml.jackson.databind.node.TextNode;
public class JsonCompareUnitTest {
@Test
public void givenTwoSameJsonDataObjects_whenCompared_thenAreEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\", \"age\": 34 }}";
String s2 = "{\"employee\": {\"id\": \"1212\",\"age\": 34, \"fullName\": \"John Miles\" }}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
assertEquals(actualObj1, actualObj2);
}
@Test
public void givenTwoSameNestedJsonDataObjects_whenCompared_thenEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}";
String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"contact\":{\"email\": \"john@xyz.com\",\"phone\": \"9999999999\"} }}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
assertEquals(actualObj1, actualObj2);
}
@Test
public void givenTwoSameListJsonDataObjects_whenCompared_thenEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"skills\":[\"Java\", \"C++\", \"Python\"] }}";
String s2 = "{\"employee\": {\"id\": \"1212\",\"fullName\": \"John Miles\",\"age\": 34, \"skills\":[\"Java\", \"C++\", \"Python\"] }}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
assertEquals(actualObj1, actualObj2);
}
@Test
public void givenTwoJsonDataObjects_whenComparedUsingCustomNumericNodeComparator_thenEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"name\": \"John\",\"score\":5.0}";
String s2 = "{\"name\": \"John\",\"score\":5}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
NumericNodeComparator cmp = new NumericNodeComparator();
assertNotEquals(actualObj1, actualObj2);
assertTrue(actualObj1.equals(cmp, actualObj2));
}
public class NumericNodeComparator implements Comparator<JsonNode> {
@Override
public int compare(JsonNode o1, JsonNode o2) {
if (o1.equals(o2)) {
return 0;
}
if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)) {
Double d1 = ((NumericNode) o1).asDouble();
Double d2 = ((NumericNode) o2).asDouble();
if (d1.compareTo(d2) == 0) {
return 0;
}
}
return 1;
}
}
@Test
public void givenTwoJsonDataObjects_whenComparedUsingCustomTextNodeComparator_thenEqual() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String s1 = "{\"name\": \"JOHN\",\"score\":5}";
String s2 = "{\"name\": \"John\",\"score\":5}";
JsonNode actualObj1 = mapper.readTree(s1);
JsonNode actualObj2 = mapper.readTree(s2);
TextNodeComparator cmp = new TextNodeComparator();
assertNotEquals(actualObj1, actualObj2);
assertTrue(actualObj1.equals(cmp, actualObj2));
}
public class TextNodeComparator implements Comparator<JsonNode> {
@Override
public int compare(JsonNode o1, JsonNode o2) {
if (o1.equals(o2)) {
return 0;
}
if ((o1 instanceof TextNode) && (o2 instanceof TextNode)) {
String s1 = ((TextNode) o1).asText();
String s2 = ((TextNode) o2).asText();
if (s1.equalsIgnoreCase(s2)) {
return 0;
}
}
return 1;
}
}
}

View File

@ -118,7 +118,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<commons-lang3.version>3.8</commons-lang3.version>
<joda-time.version>2.10</joda-time.version> <joda-time.version>2.10</joda-time.version>
<gson.version>2.8.5</gson.version> <gson.version>2.8.5</gson.version>
<commons-collections4.version>4.2</commons-collections4.version> <commons-collections4.version>4.2</commons-collections4.version>

View File

@ -118,7 +118,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<commons-lang3.version>3.8</commons-lang3.version>
<joda-time.version>2.10</joda-time.version> <joda-time.version>2.10</joda-time.version>
<gson.version>2.8.5</gson.version> <gson.version>2.8.5</gson.version>
<commons-collections4.version>4.2</commons-collections4.version> <commons-collections4.version>4.2</commons-collections4.version>

View File

@ -33,7 +33,6 @@
</dependencies> </dependencies>
<properties> <properties>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-collections4.version>4.1</commons-collections4.version> <commons-collections4.version>4.1</commons-collections4.version>
<assertj.version>3.6.1</assertj.version> <assertj.version>3.6.1</assertj.version>
</properties> </properties>

View File

@ -54,7 +54,6 @@
<trove4j.version>3.0.2</trove4j.version> <trove4j.version>3.0.2</trove4j.version>
<fastutil.version>8.1.0</fastutil.version> <fastutil.version>8.1.0</fastutil.version>
<colt.version>1.2.0</colt.version> <colt.version>1.2.0</colt.version>
<commons-lang3.version>3.8.1</commons-lang3.version>
<assertj.version>3.11.1</assertj.version> <assertj.version>3.11.1</assertj.version>
</properties> </properties>

View File

@ -44,7 +44,6 @@
</dependencies> </dependencies>
<properties> <properties>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-collections4.version>4.1</commons-collections4.version> <commons-collections4.version>4.1</commons-collections4.version>
<collections-generic.version>4.01</collections-generic.version> <collections-generic.version>4.01</collections-generic.version>
<avaitility.version>1.7.0</avaitility.version> <avaitility.version>1.7.0</avaitility.version>

View File

@ -74,8 +74,6 @@
</build> </build>
<properties> <properties>
<!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<joda-time.version>2.10</joda-time.version> <joda-time.version>2.10</joda-time.version>
<!-- testing --> <!-- testing -->
<assertj.version>3.6.1</assertj.version> <assertj.version>3.6.1</assertj.version>

View File

@ -72,8 +72,6 @@
<javaee-version>8.0</javaee-version> <javaee-version>8.0</javaee-version>
<liberty-maven-plugin.version>2.3</liberty-maven-plugin.version> <liberty-maven-plugin.version>2.3</liberty-maven-plugin.version>
<openliberty-runtime.version>18.0.0.1</openliberty-runtime.version> <openliberty-runtime.version>18.0.0.1</openliberty-runtime.version>
<maven-war-plugin.version>3.2.2</maven-war-plugin.version>
</properties> </properties>
</project> </project>

26
java-numbers-2/.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
*.class
0.*
#folders#
/target
/neoDb*
/data
/src/main/webapp/WEB-INF/classes
*/META-INF/*
.resourceCache
# Packaged files #
*.jar
*.war
*.ear
# Files generated by integration tests
*.txt
backup-pom.xml
/bin/
/temp
#IntelliJ specific
.idea/
*.iml

135
java-numbers-2/pom.xml Normal file
View File

@ -0,0 +1,135 @@
<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>java-numbers-2</artifactId>
<version>0.1.0-SNAPSHOT</version>
<name>java-numbers-2</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-java</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>${jmh-core.version}</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh-generator.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>${commons-math3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.decimal4j</groupId>
<artifactId>decimal4j</artifactId>
<version>${decimal4j.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>java-numbers-2</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</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>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
</execution>
</executions>
<configuration>
<systemPropertyVariables>
<test.mime>json</test.mime>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<commons-math3.version>3.6.1</commons-math3.version>
<decimal4j.version>1.0.3</decimal4j.version>
<commons-lang3.version>3.5</commons-lang3.version>
<assertj.version>3.6.1</assertj.version>
<org.slf4j.version>1.7.21</org.slf4j.version>
<logback.version>1.1.7</logback.version>
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
<maven-javadoc-plugin.version>3.0.0-M1</maven-javadoc-plugin.version>
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
</properties>
</project>

View File

@ -0,0 +1,68 @@
package com.baeldung.lossyconversion;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.jupiter.api.Test;
public class ConversionTechniquesUnitTest {
@Test
public void testPrimitiveConversion() {
long longNum = 24;
short shortNum = (short) longNum;
assertEquals(24, shortNum);
double doubleNum = 15.6;
int integerNum = (int) doubleNum;
assertEquals(15, integerNum);
long largeLongNum = 32768;
short minShortNum = (short) largeLongNum;
assertEquals(-32768, minShortNum);
long smallLongNum = -32769;
short maxShortNum = (short) smallLongNum;
assertEquals(32767, maxShortNum);
long maxLong = Long.MAX_VALUE;
int minInt = (int) maxLong;
assertEquals(-1, minInt);
long minLong = Long.MIN_VALUE;
int maxInt = (int) minLong;
assertEquals(0, maxInt);
}
@Test
public void testWrapperToPrimitiveConversion() {
Float floatNum = 17.564f;
long longNum = floatNum.longValue();
assertEquals(17, longNum);
Double doubleNum = 15.9999;
longNum = doubleNum.longValue();
assertEquals(15, longNum);
}
@Test
public void testWrapperToPrimitiveConversionUsingMathRound() {
Double doubleNum = 15.9999;
long longNum = Math.round(doubleNum);
assertEquals(16, longNum);
}
@Test
public void testWrapperConversion() {
Double doubleNum = 10.3;
double dbl = doubleNum.doubleValue(); //unboxing
int intgr = (int) dbl; //downcasting
Integer intNum = Integer.valueOf(intgr);
assertEquals(Integer.valueOf(10), intNum);
}
}

View File

@ -121,7 +121,6 @@
<properties> <properties>
<commons-math3.version>3.6.1</commons-math3.version> <commons-math3.version>3.6.1</commons-math3.version>
<decimal4j.version>1.0.3</decimal4j.version> <decimal4j.version>1.0.3</decimal4j.version>
<commons-lang3.version>3.5</commons-lang3.version>
<assertj.version>3.6.1</assertj.version> <assertj.version>3.6.1</assertj.version>

View File

@ -106,7 +106,6 @@
<properties> <properties>
<!-- util --> <!-- util -->
<commons-lang3.version>3.5</commons-lang3.version>
<vavr.version>0.9.0</vavr.version> <vavr.version>0.9.0</vavr.version>
<protonpack.version>1.15</protonpack.version> <protonpack.version>1.15</protonpack.version>
<streamex.version>0.6.5</streamex.version> <streamex.version>0.6.5</streamex.version>

View File

@ -4,3 +4,4 @@
- [Check If a String Contains a Substring](https://www.baeldung.com/java-string-contains-substring) - [Check If a String Contains a Substring](https://www.baeldung.com/java-string-contains-substring)
- [Removing Stopwords from a String in Java](https://www.baeldung.com/java-string-remove-stopwords) - [Removing Stopwords from a String in Java](https://www.baeldung.com/java-string-remove-stopwords)
- [Blank and Empty Strings in Java](https://www.baeldung.com/java-blank-empty-strings) - [Blank and Empty Strings in Java](https://www.baeldung.com/java-blank-empty-strings)
- [String Initialization in Java](https://www.baeldung.com/java-string-initialization)

View File

@ -88,7 +88,6 @@
<assertj.version>3.9.1</assertj.version> <assertj.version>3.9.1</assertj.version>
<mockito.version>2.21.0</mockito.version> <mockito.version>2.21.0</mockito.version>
<commons-fileupload.version>1.3.3</commons-fileupload.version> <commons-fileupload.version>1.3.3</commons-fileupload.version>
<commons-io.version>2.6</commons-io.version>
<javax.servlet-api.version>4.0.1</javax.servlet-api.version> <javax.servlet-api.version>4.0.1</javax.servlet-api.version>
</properties> </properties>
</project> </project>

View File

@ -130,8 +130,6 @@
<!-- maven plugins --> <!-- maven plugins -->
<jaxb2-maven-plugin.version>2.3</jaxb2-maven-plugin.version> <jaxb2-maven-plugin.version>2.3</jaxb2-maven-plugin.version>
<istack-commons-runtime.version>3.0.2</istack-commons-runtime.version> <istack-commons-runtime.version>3.0.2</istack-commons-runtime.version>
<commons-io.version>2.5</commons-io.version>
<commons-lang3.version>3.5</commons-lang3.version>
<lifecycle-mapping-plugin.version>1.0.0</lifecycle-mapping-plugin.version> <lifecycle-mapping-plugin.version>1.0.0</lifecycle-mapping-plugin.version>
<javax.activation.version>1.1</javax.activation.version> <javax.activation.version>1.1</javax.activation.version>

View File

@ -519,11 +519,9 @@
<tyrus.version>1.13</tyrus.version> <tyrus.version>1.13</tyrus.version>
<jersey.version>2.25</jersey.version> <jersey.version>2.25</jersey.version>
<arquillian-glassfish.version>1.0.0.Final</arquillian-glassfish.version> <arquillian-glassfish.version>1.0.0.Final</arquillian-glassfish.version>
<maven-war-plugin.version>2.6</maven-war-plugin.version>
<org.springframework.security.version>4.2.3.RELEASE</org.springframework.security.version> <org.springframework.security.version>4.2.3.RELEASE</org.springframework.security.version>
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version> <maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
<taglibs.standard.version>1.1.2</taglibs.standard.version> <taglibs.standard.version>1.1.2</taglibs.standard.version>
<commons-io.version>2.4</commons-io.version>
<com.sun.faces.jsf.version>2.2.14</com.sun.faces.jsf.version> <com.sun.faces.jsf.version>2.2.14</com.sun.faces.jsf.version>
<httpclient.version>4.5</httpclient.version> <httpclient.version>4.5</httpclient.version>
<arquillian-drone-bom.version>2.0.1.Final</arquillian-drone-bom.version> <arquillian-drone-bom.version>2.0.1.Final</arquillian-drone-bom.version>

1
jee-kotlin/README.md Normal file
View File

@ -0,0 +1 @@
### Relevant Articles:

286
jee-kotlin/pom.xml Normal file
View File

@ -0,0 +1,286 @@
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>jee-kotlin</artifactId>
<name>jee-kotlin</name>
<packaging>war</packaging>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee-api.version}</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<version>${arquillian_core.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-depchain</artifactId>
<version>${shrinkwrap.version}</version>
<type>pom</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-rest-client-impl-jersey</artifactId>
<version>${arquillian-rest-client.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<configuration>
<jvmTarget>1.8</jvmTarget>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<warSourceDirectory>webapp</warSourceDirectory>
<warName>kotlin</warName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>${arquillian_core.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-drone-bom</artifactId>
<version>${arquillian-drone-bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>wildfly-managed-arquillian</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-arquillian-container-embedded</artifactId>
<version>${wildfly.version}</version>
</dependency>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-embedded</artifactId>
<version>${wildfly.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- You need the maven dependency plugin to download locally a zip with the server,
unless you provide your own, it will download under the /target directory -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<executions>
<execution>
<id>unpack</id>
<phase>process-test-classes</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-dist</artifactId>
<version>${wildfly.version}</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>target</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<!-- Fork every test because it will launch a separate AS instance -->
<forkMode>always</forkMode>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<jboss.home>${project.basedir}/target/wildfly-${wildfly.version}</jboss.home>
<module.path>${project.basedir}/target/wildfly-${wildfly.version}/modules</module.path>
</systemPropertyVariables>
<redirectTestOutputToFile>false</redirectTestOutputToFile>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>wildfly-remote-arquillian</id>
<dependencies>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${resteasy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>${resteasy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-json-p-provider</artifactId>
<version>${resteasy.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wildfly.arquillian</groupId>
<artifactId>wildfly-arquillian-container-remote</artifactId>
<version>2.2.0.Final</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<failOnMissingWebXml>false</failOnMissingWebXml>
<javaee-api.version>8.0</javaee-api.version>
<kotlin.version>1.3.41</kotlin.version>
<kotlin.code.style>official</kotlin.code.style>
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
<wildfly.version>8.2.1.Final</wildfly.version>
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
<maven-dependency-plugin.version>3.1.1</maven-dependency-plugin.version>
<arquillian_core.version>1.4.1.Final</arquillian_core.version>
<arquillian-drone-bom.version>2.0.1.Final</arquillian-drone-bom.version>
<arquillian-rest-client.version>1.0.0.Alpha4</arquillian-rest-client.version>
<resteasy.version>3.8.0.Final</resteasy.version>
<shrinkwrap.version>3.1.3</shrinkwrap.version>
</properties>
</project>

View File

@ -0,0 +1,22 @@
package com.baeldung.jeekotlin.entity
import com.fasterxml.jackson.annotation.JsonProperty
import javax.persistence.*
@Entity
data class Student constructor (
@SequenceGenerator(name = "student_id_seq", sequenceName = "student_id_seq", allocationSize = 1)
@GeneratedValue(generator = "student_id_seq", strategy = GenerationType.SEQUENCE)
@Id
var id: Long?,
var firstName: String,
var lastName: String
) {
constructor() : this(null, "", "")
constructor(firstName: String, lastName: String) : this(null, firstName, lastName)
}

View File

@ -0,0 +1,9 @@
package com.baeldung.jeekotlin.rest
import javax.ws.rs.ApplicationPath
import javax.ws.rs.core.Application
@ApplicationPath("/")
class ApplicationConfig : Application() {
override fun getClasses() = setOf(StudentResource::class.java)
}

View File

@ -0,0 +1,42 @@
package com.baeldung.jeekotlin.rest
import com.baeldung.jeekotlin.entity.Student
import com.baeldung.jeekotlin.service.StudentService
import javax.inject.Inject
import javax.ws.rs.*
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response
@Path("/student")
open class StudentResource {
@Inject
private lateinit var service: StudentService
@POST
open fun create(student: Student): Response {
service.create(student)
return Response.ok().build()
}
@GET
@Path("/{id}")
open fun read(@PathParam("id") id: Long): Response {
val student = service.read(id)
return Response.ok(student, MediaType.APPLICATION_JSON_TYPE).build()
}
@PUT
open fun update(student: Student): Response {
service.update(student)
return Response.ok(student, MediaType.APPLICATION_JSON_TYPE).build()
}
@DELETE
@Path("/{id}")
open fun delete(@PathParam("id") id: Long): Response {
service.delete(id)
return Response.noContent().build()
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.jeekotlin.service
import com.baeldung.jeekotlin.entity.Student
import javax.ejb.Stateless
import javax.persistence.EntityManager
import javax.persistence.PersistenceContext
@Stateless
open class StudentService {
@PersistenceContext
private lateinit var entityManager: EntityManager
open fun create(student: Student) = entityManager.persist(student)
open fun read(id: Long): Student? = entityManager.find(Student::class.java, id)
open fun update(student: Student) = entityManager.merge(student)
open fun delete(id: Long) = entityManager.remove(read(id))
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="pu" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
<class>com.enpy.entity.Student</class>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>

View File

@ -0,0 +1,108 @@
package com.baeldung.jeekotlin;
import com.baeldung.jeekotlin.entity.Student;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.Filters;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URISyntaxException;
import java.net.URL;
import static org.junit.Assert.assertEquals;
@RunWith(Arquillian.class)
public class StudentResourceIntegrationTest {
@Deployment
public static WebArchive createDeployment() {
JavaArchive[] kotlinRuntime = Maven.configureResolver()
.workOffline()
.withMavenCentralRepo(true)
.withClassPathResolution(true)
.loadPomFromFile("pom.xml")
.resolve("org.jetbrains.kotlin:kotlin-stdlib")
.withTransitivity()
.as(JavaArchive.class);
return ShrinkWrap.create(WebArchive.class, "kotlin.war")
.addPackages(true, Filters.exclude(".*Test*"),
"com.baeldung.jeekotlin"
)
.addAsLibraries(kotlinRuntime)
.addAsResource("META-INF/persistence.xml")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
@Test
@RunAsClient
public void when_post__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
String student = new ObjectMapper().writeValueAsString(new Student("firstName", "lastName"));
WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
Response response = webTarget
.path("/student")
.request(MediaType.APPLICATION_JSON)
.post(Entity.json(student));
assertEquals(200, response.getStatus());
}
@Test
@RunAsClient
public void when_get__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
Response response = webTarget
.path("/student/1")
.request(MediaType.APPLICATION_JSON)
.get();
assertEquals(200, response.getStatus());
}
@Test
@RunAsClient
public void when_put__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
Student student = new Student("firstName", "lastName");
student.setId(1L);
String studentJson = new ObjectMapper().writeValueAsString(student);
WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
Response response = webTarget
.path("/student")
.request(MediaType.APPLICATION_JSON)
.put(Entity.json(studentJson));
assertEquals(200, response.getStatus());
}
@Test
@RunAsClient
public void when_delete__then_return_ok(@ArquillianResource URL url) throws URISyntaxException, JsonProcessingException {
WebTarget webTarget = ClientBuilder.newClient().target(url.toURI());
Response response = webTarget
.path("/student/1")
.request()
.delete();
assertEquals(204, response.getStatus());
}
}

View File

@ -0,0 +1,22 @@
<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="wildfly-managed">
<configuration>
<property name="jbossHome">target/wildfly-8.2.1.Final</property>
<property name="serverConfig">standalone.xml</property>
<property name="outputToConsole">true</property>
<property name="managementPort">9990</property>
</configuration>
</container>
<container qualifier="wildfly-remote" default="true">
<configuration>
<property name="managementAddress">127.0.0.1</property>
<property name="managementPort">9990</property>
<property name="username">admin</property>
<property name="password">pass</property>
<property name="allowConnectingToRunningServer">true</property>
</configuration>
</container>
</arquillian>

View File

@ -80,7 +80,6 @@
<properties> <properties>
<jersey.version>2.26</jersey.version> <jersey.version>2.26</jersey.version>
<maven-war-plugin.version>3.2.0</maven-war-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -99,9 +99,6 @@
<com.sun.faces.version>2.2.14</com.sun.faces.version> <com.sun.faces.version>2.2.14</com.sun.faces.version>
<javax.el.version>3.0.0</javax.el.version> <javax.el.version>3.0.0</javax.el.version>
<!-- maven plugins -->
<maven-war-plugin.version>2.6</maven-war-plugin.version>
<primefaces.version>6.2</primefaces.version> <primefaces.version>6.2</primefaces.version>
</properties> </properties>

View File

@ -83,7 +83,6 @@
<properties> <properties>
<maven-jar-plugin.version>3.0.2</maven-jar-plugin.version> <maven-jar-plugin.version>3.0.2</maven-jar-plugin.version>
<maven-war-plugin.version>3.0.0</maven-war-plugin.version>
<jnlp-jardiff.version>1.6.0</jnlp-jardiff.version> <jnlp-jardiff.version>1.6.0</jnlp-jardiff.version>
<jnlp-servlet.version>1.6.0</jnlp-servlet.version> <jnlp-servlet.version>1.6.0</jnlp-servlet.version>
</properties> </properties>

View File

@ -94,7 +94,7 @@
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>
<version>${h2database.version}</version> <version>${h2.version}</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/io.arrow-kt/arrow-core --> <!-- https://mvnrepository.com/artifact/io.arrow-kt/arrow-core -->
<dependency> <dependency>
@ -184,7 +184,6 @@
<junit.platform.version>1.1.1</junit.platform.version> <junit.platform.version>1.1.1</junit.platform.version>
<junit.vintage.version>5.2.0</junit.vintage.version> <junit.vintage.version>5.2.0</junit.vintage.version>
<assertj.version>3.10.0</assertj.version> <assertj.version>3.10.0</assertj.version>
<h2database.version>1.4.197</h2database.version>
<exposed.version>0.10.4</exposed.version> <exposed.version>0.10.4</exposed.version>
<mockk.version>1.9.3</mockk.version> <mockk.version>1.9.3</mockk.version>
</properties> </properties>

View File

@ -8,6 +8,12 @@
<name>kotlin-quasar</name> <name>kotlin-quasar</name>
<packaging>jar</packaging> <packaging>jar</packaging>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
@ -45,6 +51,27 @@
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.12</version> <version>4.12</version>
</dependency> </dependency>
<!-- logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -116,5 +143,7 @@
<properties> <properties>
<quasar.version>0.8.0</quasar.version> <quasar.version>0.8.0</quasar.version>
<kotlin.version>1.3.31</kotlin.version> <kotlin.version>1.3.31</kotlin.version>
<org.slf4j.version>1.7.21</org.slf4j.version>
<logback.version>1.1.7</logback.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,157 @@
package com.baeldung.quasar
import co.paralleluniverse.actors.Actor
import co.paralleluniverse.actors.ActorRef
import co.paralleluniverse.actors.behaviors.*
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.strands.SuspendableCallable
import org.junit.Test
import org.slf4j.LoggerFactory
import java.lang.Exception
class ActorsBehaviorTest {
companion object {
private val LOG = LoggerFactory.getLogger(ActorsBehaviorTest::class.java)
}
@Test
fun requestReplyHelper() {
data class TestMessage(val input: Int) : RequestMessage<Int>()
val actor = object : Actor<TestMessage, Void>("requestReplyActor", null) {
@Suspendable
override fun doRun(): Void? {
while (true) {
val msg = receive()
LOG.info("Processing message: {}", msg)
RequestReplyHelper.reply(msg, msg.input * 100)
}
}
}
val actorRef = actor.spawn()
val result = RequestReplyHelper.call(actorRef, TestMessage(50))
LOG.info("Received reply: {}", result)
}
@Test
fun server() {
val actor = ServerActor(object : AbstractServerHandler<Int, String, Float>() {
@Suspendable
override fun handleCall(from: ActorRef<*>?, id: Any?, m: Int?): String {
LOG.info("Called with message: {} from {} with ID {}", m, from, id)
return m.toString() ?: "None"
}
@Suspendable
override fun handleCast(from: ActorRef<*>?, id: Any?, m: Float?) {
LOG.info("Cast message: {} from {} with ID {}", m, from, id)
}
})
val server = actor.spawn()
LOG.info("Call result: {}", server.call(5))
server.cast(2.5f)
server.shutdown()
}
interface Summer {
fun sum(a: Int, b: Int) : Int
}
@Test
fun proxyServer() {
val actor = ProxyServerActor(false, object : Summer {
@Synchronized
override fun sum(a: Int, b: Int): Int {
Exception().printStackTrace()
LOG.info("Adding together {} and {}", a, b)
return a + b
}
})
val summerActor = actor.spawn()
val result = (summerActor as Summer).sum(1, 2)
LOG.info("Result: {}", result)
summerActor.shutdown()
}
@Test
fun eventSource() {
val actor = EventSourceActor<String>()
val eventSource = actor.spawn()
eventSource.addHandler { msg ->
LOG.info("Sent message: {}", msg)
}
val name = "Outside Value"
eventSource.addHandler { msg ->
LOG.info("Also Sent message: {} {}", msg, name)
}
eventSource.send("Hello")
eventSource.shutdown()
}
@Test
fun finiteStateMachine() {
val actor = object : FiniteStateMachineActor() {
@Suspendable
override fun initialState(): SuspendableCallable<SuspendableCallable<*>> {
LOG.info("Starting")
return SuspendableCallable { lockedState() }
}
@Suspendable
fun lockedState() : SuspendableCallable<SuspendableCallable<*>> {
return receive {msg ->
when (msg) {
"PUSH" -> {
LOG.info("Still locked")
lockedState()
}
"COIN" -> {
LOG.info("Unlocking...")
unlockedState()
}
else -> TERMINATE
}
}
}
@Suspendable
fun unlockedState() : SuspendableCallable<SuspendableCallable<*>> {
return receive {msg ->
when (msg) {
"PUSH" -> {
LOG.info("Locking")
lockedState()
}
"COIN" -> {
LOG.info("Unlocked")
unlockedState()
}
else -> TERMINATE
}
}
}
}
val actorRef = actor.spawn()
listOf("PUSH", "COIN", "COIN", "PUSH", "PUSH").forEach {
LOG.info(it)
actorRef.sendSync(it)
}
actorRef.shutdown()
}
}

View File

@ -0,0 +1,298 @@
package com.baeldung.quasar
import co.paralleluniverse.actors.*
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.strands.channels.Channels
import org.junit.Assert
import org.junit.Test
import org.slf4j.LoggerFactory
import java.util.concurrent.TimeUnit
class ActorsTest {
companion object {
private val LOG = LoggerFactory.getLogger(ActorsTest::class.java)
}
@Test
fun createNoopActor() {
val actor = object : Actor<Int, String>("noopActor", MailboxConfig(5, Channels.OverflowPolicy.THROW)) {
@Suspendable
override fun doRun(): String {
return "Hello"
}
}
actor.spawn()
println("Noop Actor: ${actor.get()}")
}
@Test
fun registerActor() {
val actor = object : Actor<Int, String>("registerActor", null) {
@Suspendable
override fun doRun(): String {
return "Hello"
}
}
val actorRef = actor.spawn()
actor.register()
val retrievedRef = ActorRegistry.getActor<ActorRef<Int>>("registerActor")
Assert.assertEquals(actorRef, retrievedRef)
actor.join()
}
@Test
fun registerActorNewName() {
val actor = object : Actor<Int, String>(null, null) {
@Suspendable
override fun doRun(): String {
return "Hello"
}
}
val actorRef = actor.spawn()
actor.register("renamedActor")
val retrievedRef = ActorRegistry.getActor<ActorRef<Int>>("renamedActor")
Assert.assertEquals(actorRef, retrievedRef)
actor.join()
}
@Test
fun retrieveUnknownActor() {
val retrievedRef = ActorRegistry.getActor<ActorRef<Int>>("unknownActor", 1, TimeUnit.SECONDS)
Assert.assertNull(retrievedRef)
}
@Test
fun createSimpleActor() {
val actor = object : Actor<Int, Void?>("simpleActor", null) {
@Suspendable
override fun doRun(): Void? {
val msg = receive()
LOG.info("SimpleActor Received Message: {}", msg)
return null
}
}
val actorRef = actor.spawn()
actorRef.send(1)
actor.join()
}
@Test
fun createLoopingActor() {
val actor = object : Actor<Int, Void?>("loopingActor", null) {
@Suspendable
override fun doRun(): Void? {
while (true) {
val msg = receive()
if (msg > 0) {
LOG.info("LoopingActor Received Message: {}", msg)
} else {
break
}
}
return null
}
}
val actorRef = actor.spawn()
actorRef.send(3)
actorRef.send(2)
actorRef.send(1)
actorRef.send(0)
actor.join()
}
@Test
fun actorBacklog() {
val actor = object : Actor<Int, String>("backlogActor", MailboxConfig(1, Channels.OverflowPolicy.THROW)) {
@Suspendable
override fun doRun(): String {
TimeUnit.MILLISECONDS.sleep(500);
LOG.info("Backlog Actor Received: {}", receive())
try {
receive()
} catch (e: Throwable) {
LOG.info("==== Exception throws by receive() ====")
e.printStackTrace()
}
return "No Exception"
}
}
val actorRef = actor.spawn()
actorRef.send(1)
actorRef.send(2)
try {
LOG.info("Backlog Actor: {}", actor.get())
} catch (e: Exception) {
// Expected
LOG.info("==== Exception throws by get() ====")
e.printStackTrace()
}
}
@Test
fun actorBacklogTrySend() {
val actor = object : Actor<Int, String>("backlogTrySendActor", MailboxConfig(1, Channels.OverflowPolicy.THROW)) {
@Suspendable
override fun doRun(): String {
TimeUnit.MILLISECONDS.sleep(500);
LOG.info("Backlog TrySend Actor Received: {}", receive())
return "No Exception"
}
}
val actorRef = actor.spawn()
LOG.info("Backlog TrySend 1: {}", actorRef.trySend(1))
LOG.info("Backlog TrySend 1: {}", actorRef.trySend(2))
actor.join()
}
@Test
fun actorTimeoutReceive() {
val actor = object : Actor<Int, String>("TimeoutReceiveActor", MailboxConfig(1, Channels.OverflowPolicy.THROW)) {
@Suspendable
override fun doRun(): String {
LOG.info("Timeout Actor Received: {}", receive(500, TimeUnit.MILLISECONDS))
return "Finished"
}
}
val actorRef = actor.spawn()
TimeUnit.MILLISECONDS.sleep(300)
actorRef.trySend(1)
actor.join()
}
@Test
fun actorNonBlockingReceive() {
val actor = object : Actor<Int, String>("NonBlockingReceiveActor", MailboxConfig(1, Channels.OverflowPolicy.THROW)) {
@Suspendable
override fun doRun(): String {
LOG.info("NonBlocking Actor Received #1: {}", tryReceive())
TimeUnit.MILLISECONDS.sleep(500)
LOG.info("NonBlocking Actor Received #2: {}", tryReceive())
return "Finished"
}
}
val actorRef = actor.spawn()
TimeUnit.MILLISECONDS.sleep(300)
actorRef.trySend(1)
actor.join()
}
@Test
fun evenActor() {
val actor = object : Actor<Int, Void?>("EvenActor", null) {
@Suspendable
override fun filterMessage(m: Any?): Int? {
return when (m) {
is Int -> {
if (m % 2 == 0) {
m * 10
} else {
null
}
}
else -> super.filterMessage(m)
}
}
@Suspendable
override fun doRun(): Void? {
while (true) {
val msg = receive()
if (msg > 0) {
LOG.info("EvenActor Received Message: {}", msg)
} else {
break
}
}
return null
}
}
val actorRef = actor.spawn()
actorRef.send(3)
actorRef.send(2)
actorRef.send(1)
actorRef.send(0)
actor.join()
}
@Test
fun watchingActors() {
val watched = object : Actor<Int, Void?>("WatchedActor", null) {
@Suspendable
override fun doRun(): Void? {
LOG.info("WatchedActor Starting")
receive(500, TimeUnit.MILLISECONDS)
LOG.info("WatchedActor Finishing")
return null
}
}
val watcher = object : Actor<Int, Void?>("WatcherActor", null) {
@Suspendable
override fun doRun(): Void? {
LOG.info("WatcherActor Listening")
try {
LOG.info("WatcherActor received Message: {}", receive(2, TimeUnit.SECONDS))
} catch (e: Exception) {
LOG.info("WatcherActor Received Exception", e)
}
return null
}
@Suspendable
override fun handleLifecycleMessage(m: LifecycleMessage?): Int? {
LOG.info("WatcherActor Received Lifecycle Message: {}", m)
return super.handleLifecycleMessage(m)
}
}
val watcherRef = watcher.spawn()
TimeUnit.MILLISECONDS.sleep(200)
val watchedRef = watched.spawn()
watcher.link(watchedRef)
watched.join()
watcher.join()
}
}

View File

@ -0,0 +1,135 @@
package com.baeldung.quasar
import co.paralleluniverse.fibers.Suspendable
import co.paralleluniverse.kotlin.fiber
import co.paralleluniverse.strands.channels.Channels
import co.paralleluniverse.strands.channels.Topic
import co.paralleluniverse.strands.channels.reactivestreams.ReactiveStreams
import org.junit.Test
import org.reactivestreams.Subscriber
import org.reactivestreams.Subscription
import org.slf4j.LoggerFactory
import java.util.concurrent.TimeUnit
class ReactiveStreamsTest {
companion object {
private val LOG = LoggerFactory.getLogger(ReactiveStreamsTest::class.java)
}
@Test
fun publisher() {
val inputChannel = Channels.newChannel<String>(1);
val publisher = ReactiveStreams.toPublisher(inputChannel)
publisher.subscribe(object : Subscriber<String> {
@Suspendable
override fun onComplete() {
LOG.info("onComplete")
}
@Suspendable
override fun onSubscribe(s: Subscription) {
LOG.info("onSubscribe: {}", s)
s.request(2)
}
@Suspendable
override fun onNext(t: String?) {
LOG.info("onNext: {}", t)
}
@Suspendable
override fun onError(t: Throwable?) {
LOG.info("onError: {}", t)
}
})
inputChannel.send("Hello")
inputChannel.send("World")
TimeUnit.SECONDS.sleep(1)
inputChannel.close()
}
@Test
fun publisherTopic() {
val inputTopic = Topic<String>()
val publisher = ReactiveStreams.toPublisher(inputTopic)
publisher.subscribe(object : Subscriber<String> {
@Suspendable
override fun onComplete() {
LOG.info("onComplete 1")
}
@Suspendable
override fun onSubscribe(s: Subscription) {
LOG.info("onSubscribe 1: {}", s)
s.request(2)
}
@Suspendable
override fun onNext(t: String?) {
LOG.info("onNext 1: {}", t)
}
@Suspendable
override fun onError(t: Throwable?) {
LOG.info("onError 1: {}", t)
}
})
publisher.subscribe(object : Subscriber<String> {
@Suspendable
override fun onComplete() {
LOG.info("onComplete 2")
}
@Suspendable
override fun onSubscribe(s: Subscription) {
LOG.info("onSubscribe 2: {}", s)
s.request(2)
}
@Suspendable
override fun onNext(t: String?) {
LOG.info("onNext 2: {}", t)
}
@Suspendable
override fun onError(t: Throwable?) {
LOG.info("onError 2: {}", t)
}
})
inputTopic.send("Hello")
inputTopic.send("World")
TimeUnit.SECONDS.sleep(1)
inputTopic.close()
}
@Test
fun subscribe() {
val inputChannel = Channels.newChannel<String>(10);
val publisher = ReactiveStreams.toPublisher(inputChannel)
val channel = ReactiveStreams.subscribe(10, Channels.OverflowPolicy.THROW, publisher)
fiber @Suspendable {
while (!channel.isClosed) {
val message = channel.receive()
LOG.info("Received: {}", message)
}
LOG.info("Stopped receiving messages")
}
inputChannel.send("Hello")
inputChannel.send("World")
TimeUnit.SECONDS.sleep(1)
inputChannel.close()
}
}

View File

@ -25,7 +25,7 @@
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<version>${commons-lang.version}</version> <version>${commons-lang3.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
@ -35,7 +35,7 @@
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>${commons.io.version}</version> <version>${commons-io.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-chain</groupId> <groupId>commons-chain</groupId>
@ -87,13 +87,12 @@
</dependencies> </dependencies>
<properties> <properties>
<commons-lang.version>3.6</commons-lang.version> <commons-lang3.version>3.6</commons-lang3.version>
<commons-text.version>1.1</commons-text.version> <commons-text.version>1.1</commons-text.version>
<commons-beanutils.version>1.9.3</commons-beanutils.version> <commons-beanutils.version>1.9.3</commons-beanutils.version>
<commons-chain.version>1.2</commons-chain.version> <commons-chain.version>1.2</commons-chain.version>
<commons-csv.version>1.4</commons-csv.version> <commons-csv.version>1.4</commons-csv.version>
<assertj.version>3.6.2</assertj.version> <assertj.version>3.6.2</assertj.version>
<commons.io.version>2.5</commons.io.version>
<commons.dbutils.version>1.6</commons.dbutils.version> <commons.dbutils.version>1.6</commons.dbutils.version>
<commons.collections.version>4.1</commons.collections.version> <commons.collections.version>4.1</commons.collections.version>
<org.hamcrest.java-hamcrest.version>2.0.0.0</org.hamcrest.java-hamcrest.version> <org.hamcrest.java-hamcrest.version>2.0.0.0</org.hamcrest.java-hamcrest.version>

View File

@ -449,7 +449,6 @@
<gson.version>2.8.2</gson.version> <gson.version>2.8.2</gson.version>
<cache.version>1.1.0</cache.version> <cache.version>1.1.0</cache.version>
<flink.version>1.5.0</flink.version> <flink.version>1.5.0</flink.version>
<jackson.version>2.9.7</jackson.version>
<awaitility.version>3.0.0</awaitility.version> <awaitility.version>3.0.0</awaitility.version>
<assertj.version>3.6.2</assertj.version> <assertj.version>3.6.2</assertj.version>
<hazelcast.version>3.8.4</hazelcast.version> <hazelcast.version>3.8.4</hazelcast.version>

View File

@ -52,7 +52,7 @@
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>${commons.io.version}</version> <version>${commons-io.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
@ -114,7 +114,6 @@
<properties> <properties>
<assertj.version>3.6.2</assertj.version> <assertj.version>3.6.2</assertj.version>
<httpclient.version>4.5.3</httpclient.version> <httpclient.version>4.5.3</httpclient.version>
<commons.io.version>2.5</commons.io.version>
<jetty.version>9.4.8.v20171121</jetty.version> <jetty.version>9.4.8.v20171121</jetty.version>
<netty.version>4.1.20.Final</netty.version> <netty.version>4.1.20.Final</netty.version>
<commons.collections.version>4.1</commons.collections.version> <commons.collections.version>4.1</commons.collections.version>

View File

@ -45,7 +45,7 @@
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<version>${commons-lang.version}</version> <version>${commons-lang3.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>commons-net</groupId> <groupId>commons-net</groupId>
@ -818,7 +818,6 @@
<crdt.version>0.1.0</crdt.version> <crdt.version>0.1.0</crdt.version>
<multiverse.version>0.7.0</multiverse.version> <multiverse.version>0.7.0</multiverse.version>
<cglib.version>3.2.7</cglib.version> <cglib.version>3.2.7</cglib.version>
<commons-lang.version>3.6</commons-lang.version>
<jasypt.version>1.9.2</jasypt.version> <jasypt.version>1.9.2</jasypt.version>
<javatuples.version>1.2</javatuples.version> <javatuples.version>1.2</javatuples.version>
<javaassist.version>3.21.0-GA</javaassist.version> <javaassist.version>3.21.0-GA</javaassist.version>
@ -826,12 +825,10 @@
<jsonassert.version>1.5.0</jsonassert.version> <jsonassert.version>1.5.0</jsonassert.version>
<javers.version>3.1.0</javers.version> <javers.version>3.1.0</javers.version>
<httpclient.version>4.5.3</httpclient.version> <httpclient.version>4.5.3</httpclient.version>
<h2.version>1.4.196</h2.version>
<jnats.version>1.0</jnats.version> <jnats.version>1.0</jnats.version>
<httpclient.version>4.5.3</httpclient.version> <httpclient.version>4.5.3</httpclient.version>
<jackson.version>2.9.7</jackson.version>
<neuroph.version>2.92</neuroph.version> <neuroph.version>2.92</neuroph.version>
<serenity.version>1.9.26</serenity.version> <serenity.version>1.9.26</serenity.version>
<serenity.jbehave.version>1.41.0</serenity.jbehave.version> <serenity.jbehave.version>1.41.0</serenity.jbehave.version>

View File

@ -101,7 +101,6 @@
<log4j2.version>2.7</log4j2.version> <log4j2.version>2.7</log4j2.version>
<disruptor.version>3.3.6</disruptor.version> <disruptor.version>3.3.6</disruptor.version>
<jbosslogging.version>3.3.0.Final</jbosslogging.version> <jbosslogging.version>3.3.0.Final</jbosslogging.version>
<maven-war-plugin.version>2.4</maven-war-plugin.version>
</properties> </properties>
</project> </project>

View File

@ -5,10 +5,10 @@
"version": "1.0-SNAPSHOT", "version": "1.0-SNAPSHOT",
"name": "Json Maven Polyglot", "name": "Json Maven Polyglot",
"parent": { "parent": {
"groupId": "org.springframework.boot", "groupId": "com.baeldung",
"artifactId": "spring-boot-starter-parent", "artifactId": "parent-boot-2",
"version": "2.0.5.RELEASE", "version": "0.0.1-SNAPSHOT",
"relativePath": null "relativePath": "../../parent-boot-2"
}, },
"properties": { "properties": {
"project.build.sourceEncoding": "UTF-8", "project.build.sourceEncoding": "UTF-8",

View File

@ -8,17 +8,24 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<name>maven-polyglot-json-extension</name> <name>maven-polyglot-json-extension</name>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.apache.maven</groupId> <groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId> <artifactId>maven-core</artifactId>
<version>3.5.4</version> <version>${maven-core.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.9.6</version> <version>${jackson.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
@ -42,6 +49,7 @@
<properties> <properties>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<maven-core.version>3.5.4</maven-core.version>
</properties> </properties>
</project> </project>

View File

@ -4,4 +4,10 @@ artifactId: maven-polyglot-yml-app
version: 1.0-SNAPSHOT version: 1.0-SNAPSHOT
name: 'YAML Demo' name: 'YAML Demo'
parent:
groupId: "com.baeldung"
artifactId: "parent-modules"
version: "1.0.0-SNAPSHOT"
relativePath: "../.."
properties: {maven.compiler.source: 1.8, maven.compiler.target: 1.8} properties: {maven.compiler.source: 1.8, maven.compiler.target: 1.8}

View File

@ -7,6 +7,12 @@
<name>maven</name> <name>maven</name>
<packaging>pom</packaging> <packaging>pom</packaging>
<parent>
<artifactId>parent-modules</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modules> <modules>
<module>custom-rule</module> <module>custom-rule</module>
<module>maven-enforcer</module> <module>maven-enforcer</module>
@ -293,7 +299,6 @@
</profiles> </profiles>
<properties> <properties>
<java.version>1.8</java.version>
<maven.resources.version>3.0.2</maven.resources.version> <maven.resources.version>3.0.2</maven.resources.version>
<maven.compiler.version>3.8.0</maven.compiler.version> <maven.compiler.version>3.8.0</maven.compiler.version>
<maven.surefire.version>2.22.0</maven.surefire.version> <maven.surefire.version>2.22.0</maven.surefire.version>
@ -304,6 +309,5 @@
<resources.name>Baeldung</resources.name> <resources.name>Baeldung</resources.name>
<jetty.version>9.4.11.v20180605</jetty.version> <jetty.version>9.4.11.v20180605</jetty.version>
<jersey.version>2.27</jersey.version> <jersey.version>2.27</jersey.version>
<junit.version>4.12</junit.version>
</properties> </properties>
</project> </project>

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<artifactId>oauth2-authorization-server</artifactId>
<packaging>war</packaging>
<parent>
<groupId>com.baeldung.oauth2</groupId>
<artifactId>oauth2-framework-impl</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<properties>
<h2.version>1.4.199</h2.version>
<httpPort>9080</httpPort>
<httpsPort>9443</httpsPort>
</properties>
<dependencies>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>nimbus-jose-jwt</artifactId>
<version>7.3</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.62</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.62</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>net.wasdev.wlp.maven.plugins</groupId>
<artifactId>liberty-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-h2-dependency</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<type>jar</type>
<outputDirectory>${project.build.directory}/liberty/wlp/usr/shared/resources/
</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,8 @@
package com.baeldung.oauth2.authorization.server;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/")
public class OAuth2ServerApplication extends Application {
}

View File

@ -0,0 +1,17 @@
package com.baeldung.oauth2.authorization.server;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import static java.lang.Thread.currentThread;
public class PEMKeyUtils {
public static String readKeyAsString(String keyLocation) throws Exception {
URI uri = currentThread().getContextClassLoader().getResource(keyLocation).toURI();
byte[] byteArray = Files.readAllBytes(Paths.get(uri));
return new String(byteArray);
}
}

View File

@ -0,0 +1,185 @@
package com.baeldung.oauth2.authorization.server.api;
import com.baeldung.oauth2.authorization.server.handler.AuthorizationGrantTypeHandler;
import com.baeldung.oauth2.authorization.server.model.AppDataRepository;
import com.baeldung.oauth2.authorization.server.model.AuthorizationCode;
import com.baeldung.oauth2.authorization.server.model.Client;
import com.baeldung.oauth2.authorization.server.model.User;
import javax.annotation.security.RolesAllowed;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.literal.NamedLiteral;
import javax.inject.Inject;
import javax.json.JsonObject;
import javax.security.enterprise.SecurityContext;
import javax.security.enterprise.authentication.mechanism.http.FormAuthenticationMechanismDefinition;
import javax.security.enterprise.authentication.mechanism.http.LoginToContinue;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import java.io.IOException;
import java.net.URI;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.*;
@FormAuthenticationMechanismDefinition(
loginToContinue = @LoginToContinue(loginPage = "/login.jsp", errorPage = "/login.jsp")
)
@RolesAllowed("USER")
@RequestScoped
@Path("authorize")
public class AuthorizationEndpoint {
@Inject
private SecurityContext securityContext;
@Inject
private AppDataRepository appDataRepository;
@Inject
Instance<AuthorizationGrantTypeHandler> authorizationGrantTypeHandlers;
@GET
@Produces(MediaType.TEXT_HTML)
public Response doGet(@Context HttpServletRequest request,
@Context HttpServletResponse response,
@Context UriInfo uriInfo) throws ServletException, IOException {
MultivaluedMap<String, String> params = uriInfo.getQueryParameters();
Principal principal = securityContext.getCallerPrincipal();
//error about redirect_uri && client_id ==> forward user, thus to error.jsp.
//otherwise ==> sendRedirect redirect_uri?error=error&error_description=error_description
//1. client_id
String clientId = params.getFirst("client_id");
if (clientId == null || clientId.isEmpty()) {
return informUserAboutError(request, response, "Invalid client_id :" + clientId);
}
Client client = appDataRepository.getClient(clientId);
if (client == null) {
return informUserAboutError(request, response, "Invalid client_id :" + clientId);
}
//2. Client Authorized Grant Type
String clientError = "";
if (client.getAuthorizedGrantTypes() != null && !client.getAuthorizedGrantTypes().contains("authorization_code")) {
return informUserAboutError(request, response, "Authorization Grant type, authorization_code, is not allowed for this client :" + clientId);
}
//3. redirectUri
String redirectUri = params.getFirst("redirect_uri");
if (client.getRedirectUri() != null && !client.getRedirectUri().isEmpty()) {
if (redirectUri != null && !redirectUri.isEmpty() && !client.getRedirectUri().equals(redirectUri)) {
//sould be in the client.redirectUri
return informUserAboutError(request, response, "redirect_uri is pre-registred and should match");
}
redirectUri = client.getRedirectUri();
params.putSingle("resolved_redirect_uri", redirectUri);
} else {
if (redirectUri == null || redirectUri.isEmpty()) {
return informUserAboutError(request, response, "redirect_uri is not pre-registred and should be provided");
}
params.putSingle("resolved_redirect_uri", redirectUri);
}
request.setAttribute("client", client);
//4. response_type
String responseType = params.getFirst("response_type");
if (!"code".equals(responseType) && !"token".equals(responseType)) {
//error = "invalid_grant :" + responseType + ", response_type params should be code or token:";
//return informUserAboutError(error);
}
//Save params in session
request.getSession().setAttribute("ORIGINAL_PARAMS", params);
//4.scope: Optional
String requestedScope = request.getParameter("scope");
if (requestedScope == null || requestedScope.isEmpty()) {
requestedScope = client.getScope();
}
User user = appDataRepository.getUser(principal.getName());
String allowedScopes = checkUserScopes(user.getScopes(), requestedScope);
request.setAttribute("scopes", allowedScopes);
request.getRequestDispatcher("/authorize.jsp").forward(request, response);
return null;
}
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.TEXT_HTML)
public Response doPost(@Context HttpServletRequest request,
@Context HttpServletResponse response,
MultivaluedMap<String, String> params) throws Exception {
MultivaluedMap<String, String> originalParams = (MultivaluedMap<String, String>) request.getSession().getAttribute("ORIGINAL_PARAMS");
if (originalParams == null) {
return informUserAboutError(request, response, "No pending authorization request.");
}
String redirectUri = originalParams.getFirst("resolved_redirect_uri");
StringBuilder sb = new StringBuilder(redirectUri);
String approbationStatus = params.getFirst("approbation_status");
if ("NO".equals(approbationStatus)) {
URI location = UriBuilder.fromUri(sb.toString())
.queryParam("error", "User doesn't approved the request.")
.queryParam("error_description", "User doesn't approved the request.")
.build();
return Response.seeOther(location).build();
}
//==> YES
List<String> approvedScopes = params.get("scope");
if (approvedScopes == null || approvedScopes.isEmpty()) {
URI location = UriBuilder.fromUri(sb.toString())
.queryParam("error", "User doesn't approved the request.")
.queryParam("error_description", "User doesn't approved the request.")
.build();
return Response.seeOther(location).build();
}
String responseType = originalParams.getFirst("response_type");
String clientId = originalParams.getFirst("client_id");
if ("code".equals(responseType)) {
String userId = securityContext.getCallerPrincipal().getName();
AuthorizationCode authorizationCode = new AuthorizationCode();
authorizationCode.setClientId(clientId);
authorizationCode.setUserId(userId);
authorizationCode.setApprovedScopes(String.join(" ", approvedScopes));
authorizationCode.setExpirationDate(LocalDateTime.now().plusMinutes(10));
authorizationCode.setRedirectUri(redirectUri);
appDataRepository.save(authorizationCode);
String code = authorizationCode.getCode();
sb.append("?code=").append(code);
} else {
//Implicit: responseType=token
AuthorizationGrantTypeHandler authorizationGrantTypeHandler = authorizationGrantTypeHandlers.select(NamedLiteral.of("implicit")).get();
JsonObject tokenResponse = authorizationGrantTypeHandler.createAccessToken(clientId, params);
sb.append("#access_token=").append(tokenResponse.getString("access_token"))
.append("&token_type=").append(tokenResponse.getString("token_type"))
.append("&scope=").append(tokenResponse.getString("scope"));
}
String state = originalParams.getFirst("state");
if (state != null) {
sb.append("&state=").append(state);
}
return Response.seeOther(UriBuilder.fromUri(sb.toString()).build()).build();
}
private String checkUserScopes(String userScopes, String requestedScope) {
Set<String> allowedScopes = new LinkedHashSet<>();
Set<String> rScopes = new HashSet(Arrays.asList(requestedScope.split(" ")));
Set<String> uScopes = new HashSet(Arrays.asList(userScopes.split(" ")));
for (String scope : uScopes) {
if (rScopes.contains(scope)) allowedScopes.add(scope);
}
return String.join(" ", allowedScopes);
}
private Response informUserAboutError(HttpServletRequest request, HttpServletResponse response, String error) throws ServletException, IOException {
request.setAttribute("error", error);
request.getRequestDispatcher("/error.jsp").forward(request, response);
return null;
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.oauth2.authorization.server.api;
import com.baeldung.oauth2.authorization.server.PEMKeyUtils;
import com.nimbusds.jose.jwk.JWK;
import org.eclipse.microprofile.config.Config;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Arrays;
@Path("jwk")
@ApplicationScoped
public class JWKEndpoint {
@Inject
private Config config;
@GET
public Response getKey(@QueryParam("format") String format) throws Exception {
if (format != null && !Arrays.asList("jwk", "pem").contains(format)) {
return Response.status(Response.Status.BAD_REQUEST).entity("Public Key Format should be : jwk or pem").build();
}
String verificationkey = config.getValue("verificationkey", String.class);
String pemEncodedRSAPublicKey = PEMKeyUtils.readKeyAsString(verificationkey);
if (format == null || format.equals("jwk")) {
JWK jwk = JWK.parseFromPEMEncodedObjects(pemEncodedRSAPublicKey);
return Response.ok(jwk.toJSONString()).type(MediaType.APPLICATION_JSON).build();
} else if (format.equals("pem")) {
return Response.ok(pemEncodedRSAPublicKey).build();
}
return null;
}
}

View File

@ -0,0 +1,86 @@
package com.baeldung.oauth2.authorization.server.api;
import com.baeldung.oauth2.authorization.server.handler.AuthorizationGrantTypeHandler;
import com.baeldung.oauth2.authorization.server.model.AppDataRepository;
import com.baeldung.oauth2.authorization.server.model.Client;
import com.nimbusds.jose.JOSEException;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.literal.NamedLiteral;
import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonObject;
import javax.ws.rs.*;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@Path("token")
public class TokenEndpoint {
List<String> supportedGrantTypes = Collections.singletonList("authorization_code");
@Inject
private AppDataRepository appDataRepository;
@Inject
Instance<AuthorizationGrantTypeHandler> authorizationGrantTypeHandlers;
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response token(MultivaluedMap<String, String> params,
@HeaderParam(HttpHeaders.AUTHORIZATION) String authHeader) throws JOSEException {
//Check grant_type params
String grantType = params.getFirst("grant_type");
Objects.requireNonNull(grantType, "grant_type params is required");
if (!supportedGrantTypes.contains(grantType)) {
JsonObject error = Json.createObjectBuilder()
.add("error", "unsupported_grant_type")
.add("error_description", "grant type should be one of :" + supportedGrantTypes)
.build();
return Response.status(Response.Status.BAD_REQUEST)
.entity(error).build();
}
//Client Authentication
String[] clientCredentials = extract(authHeader);
String clientId = clientCredentials[0];
String clientSecret = clientCredentials[1];
Client client = appDataRepository.getClient(clientId);
if (client == null || clientSecret == null || !clientSecret.equals(client.getClientSecret())) {
JsonObject error = Json.createObjectBuilder()
.add("error", "invalid_client")
.build();
return Response.status(Response.Status.UNAUTHORIZED)
.entity(error).build();
}
AuthorizationGrantTypeHandler authorizationGrantTypeHandler = authorizationGrantTypeHandlers.select(NamedLiteral.of(grantType)).get();
JsonObject tokenResponse = null;
try {
tokenResponse = authorizationGrantTypeHandler.createAccessToken(clientId, params);
} catch (Exception e) {
e.printStackTrace();
}
return Response.ok(tokenResponse)
.header("Cache-Control", "no-store")
.header("Pragma", "no-cache")
.build();
}
private String[] extract(String authHeader) {
if (authHeader != null && authHeader.startsWith("Basic ")) {
return new String(Base64.getDecoder().decode(authHeader.substring(6))).split(":");
}
return null;
}
}

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