Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
90c9744746
@ -0,0 +1,59 @@
|
||||
package com.baeldung.algorithms.prime;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class PrimeGenerator {
|
||||
public static List<Integer> sieveOfEratosthenes(int n) {
|
||||
final boolean prime[] = new boolean[n + 1];
|
||||
Arrays.fill(prime, true);
|
||||
|
||||
for (int p = 2; p * p <= n; p++) {
|
||||
if (prime[p]) {
|
||||
for (int i = p * 2; i <= n; i += p)
|
||||
prime[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
final List<Integer> primes = new LinkedList<>();
|
||||
for (int i = 2; i <= n; i++) {
|
||||
if (prime[i])
|
||||
primes.add(i);
|
||||
}
|
||||
return primes;
|
||||
}
|
||||
|
||||
public static List<Integer> primeNumbersBruteForce(int max) {
|
||||
final List<Integer> primeNumbers = new LinkedList<Integer>();
|
||||
for (int i = 2; i <= max; i++) {
|
||||
if (isPrimeBruteForce(i)) {
|
||||
primeNumbers.add(i);
|
||||
}
|
||||
}
|
||||
return primeNumbers;
|
||||
}
|
||||
|
||||
private static boolean isPrimeBruteForce(int x) {
|
||||
for (int i = 2; i < x; i++) {
|
||||
if (x % i == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static List<Integer> primeNumbersTill(int max) {
|
||||
return IntStream.rangeClosed(2, max)
|
||||
.filter(x -> isPrime(x))
|
||||
.boxed()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static boolean isPrime(int x) {
|
||||
return IntStream.rangeClosed(2, (int) (Math.sqrt(x)))
|
||||
.allMatch(n -> x % n != 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.baeldung.algorithms.prime;
|
||||
|
||||
import static com.baeldung.algorithms.prime.PrimeGenerator.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class PrimeGeneratorTest {
|
||||
@Test
|
||||
public void whenBruteForced_returnsSuccessfully() {
|
||||
final List<Integer> primeNumbers = primeNumbersBruteForce(20);
|
||||
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenOptimized_returnsSuccessfully() {
|
||||
final List<Integer> primeNumbers = primeNumbersTill(20);
|
||||
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSieveOfEratosthenes_returnsSuccessfully() {
|
||||
final List<Integer> primeNumbers = sieveOfEratosthenes(20);
|
||||
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.baeldung.prime;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class PrimeGenerator {
|
||||
public static List<Integer> sieveOfEratosthenes(int n) {
|
||||
final boolean prime[] = new boolean[n + 1];
|
||||
Arrays.fill(prime, true);
|
||||
|
||||
for (int p = 2; p * p <= n; p++) {
|
||||
if (prime[p]) {
|
||||
for (int i = p * 2; i <= n; i += p)
|
||||
prime[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
final List<Integer> primes = new LinkedList<>();
|
||||
for (int i = 2; i <= n; i++) {
|
||||
if (prime[i])
|
||||
primes.add(i);
|
||||
}
|
||||
return primes;
|
||||
}
|
||||
|
||||
public static List<Integer> primeNumbersBruteForce(int max) {
|
||||
final List<Integer> primeNumbers = new LinkedList<Integer>();
|
||||
for (int i = 2; i <= max; i++) {
|
||||
if (isPrimeBruteForce(i)) {
|
||||
primeNumbers.add(i);
|
||||
}
|
||||
}
|
||||
return primeNumbers;
|
||||
}
|
||||
|
||||
private static boolean isPrimeBruteForce(int x) {
|
||||
for (int i = 2; i < x; i++) {
|
||||
if (x % i == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static List<Integer> primeNumbersTill(int max) {
|
||||
return IntStream.rangeClosed(2, max)
|
||||
.filter(x -> isPrime(x))
|
||||
.boxed()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static boolean isPrime(int x) {
|
||||
return IntStream.rangeClosed(2, (int) (Math.sqrt(x)))
|
||||
.allMatch(n -> x % n != 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.baeldung.prime;
|
||||
|
||||
import static com.baeldung.prime.PrimeGenerator.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class PrimeGeneratorTest {
|
||||
@Test
|
||||
public void whenBruteForced_returnsSuccessfully() {
|
||||
final List<Integer> primeNumbers = primeNumbersBruteForce(20);
|
||||
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenOptimized_returnsSuccessfully() {
|
||||
final List<Integer> primeNumbers = primeNumbersTill(20);
|
||||
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSieveOfEratosthenes_returnsSuccessfully() {
|
||||
final List<Integer> primeNumbers = sieveOfEratosthenes(20);
|
||||
assertEquals(Arrays.asList(new Integer[] { 2, 3, 5, 7, 11, 13, 17, 19 }), primeNumbers);
|
||||
}
|
||||
}
|
137
core-java/src/test/java/com/baeldung/stack/StackUnitTest.java
Normal file
137
core-java/src/test/java/com/baeldung/stack/StackUnitTest.java
Normal file
@ -0,0 +1,137 @@
|
||||
package com.baeldung.stack;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.junit.Test;
|
||||
public class StackUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenStackIsCreated_thenItHasSize0() {
|
||||
Stack intStack = new Stack();
|
||||
assertEquals(0, intStack.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmptyStack_whenElementIsPushed_thenStackSizeisIncreased() {
|
||||
Stack intStack = new Stack();
|
||||
intStack.push(1);
|
||||
assertEquals(1, intStack.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenEmptyStack_whenMultipleElementsArePushed_thenStackSizeisIncreased() {
|
||||
Stack intStack = new Stack();
|
||||
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
|
||||
boolean result = intStack.addAll(intList);
|
||||
assertTrue(result);
|
||||
assertEquals(7, intList.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenElementIsPoppedFromStack_thenElementIsRemovedAndSizeChanges() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
intStack.push(5);
|
||||
intStack.pop();
|
||||
assertTrue(intStack.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenElementIsPeeked_thenElementIsNotRemovedAndSizeDoesNotChange() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
intStack.push(5);
|
||||
intStack.peek();
|
||||
assertEquals(1, intStack.search(5));
|
||||
assertEquals(1, intStack.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenElementIsOnStack_thenSearchReturnsItsDistanceFromTheTop() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
intStack.push(5);
|
||||
assertEquals(1, intStack.search(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenElementIsOnStack_thenIndexOfReturnsItsIndex() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
intStack.push(5);
|
||||
int indexOf = intStack.indexOf(5);
|
||||
assertEquals(0, indexOf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenMultipleElementsAreOnStack_thenIndexOfReturnsLastElementIndex() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
intStack.push(5);
|
||||
intStack.push(5);
|
||||
intStack.push(5);
|
||||
int lastIndexOf = intStack.lastIndexOf(5);
|
||||
assertEquals(2, lastIndexOf);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenElementOnStack_whenRemoveElementIsInvoked_thenElementIsRemoved() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
intStack.push(5);
|
||||
intStack.push(5);
|
||||
intStack.removeElement(5);
|
||||
assertEquals(1, intStack.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenElementOnStack_whenRemoveElementAtIsInvoked_thenElementIsRemoved() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
intStack.push(5);
|
||||
intStack.push(7);
|
||||
intStack.removeElementAt(1);
|
||||
assertEquals(-1, intStack.search(7));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenElementsOnStack_whenRemoveAllElementsIsInvoked_thenAllElementsAreRemoved() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
intStack.push(5);
|
||||
intStack.push(7);
|
||||
intStack.removeAllElements();
|
||||
assertTrue(intStack.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenElementsOnStack_whenRemoveAllIsInvoked_thenAllElementsFromCollectionAreRemoved() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
|
||||
intStack.addAll(intList);
|
||||
intStack.add(500);
|
||||
intStack.removeAll(intList);
|
||||
assertEquals(1, intStack.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenElementsOnStack_whenRemoveIfIsInvoked_thenAllElementsSatysfyingConditionAreRemoved() {
|
||||
Stack<Integer> intStack = new Stack();
|
||||
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
|
||||
intStack.addAll(intList);
|
||||
intStack.removeIf(element -> element < 6);
|
||||
assertEquals(2, intStack.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenAnotherStackCreatedWhileTraversingStack_thenStacksAreEqual() {
|
||||
Stack<Integer> intStack = new Stack<>();
|
||||
List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
|
||||
intStack.addAll(intList);
|
||||
ListIterator<Integer> it = intStack.listIterator();
|
||||
Stack<Integer> result = new Stack();
|
||||
while(it.hasNext()) {
|
||||
result.push(it.next());
|
||||
}
|
||||
|
||||
assertThat(result, equalTo(intStack));
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.baeldung.stringpool;
|
||||
|
||||
import org.junit.Test;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
public class StringPoolUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenCreatingConstantStrings_thenTheirAddressesAreEqual() {
|
||||
String constantString1 = "Baeldung";
|
||||
String constantString2 = "Baeldung";
|
||||
|
||||
assertThat(constantString1).isSameAs(constantString2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCreatingStringsWithTheNewOperator_thenTheirAddressesAreDifferent() {
|
||||
String newString1 = new String("Baeldung");
|
||||
String newString2 = new String("Baeldung");
|
||||
|
||||
assertThat(newString1).isNotSameAs(newString2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenComparingConstantAndNewStrings_thenTheirAddressesAreDifferent() {
|
||||
String constantString = "Baeldung";
|
||||
String newString = new String("Baeldung");
|
||||
|
||||
assertThat(constantString).isNotSameAs(newString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInterningAStringWithIdenticalValueToAnother_thenTheirAddressesAreEqual() {
|
||||
String constantString = "interned Baeldung";
|
||||
String newString = new String("interned Baeldung");
|
||||
|
||||
assertThat(constantString).isNotSameAs(newString);
|
||||
|
||||
String internedString = newString.intern();
|
||||
|
||||
assertThat(constantString).isSameAs(internedString);
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>drools-backward-chaining</artifactId>
|
||||
@ -17,7 +16,6 @@
|
||||
<properties>
|
||||
<runtime.version>6.4.0.Final</runtime.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.kie</groupId>
|
||||
@ -26,7 +24,6 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.drools</groupId>
|
||||
<artifactId>drools-core</artifactId>
|
||||
<version>${runtime.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -35,4 +32,4 @@
|
||||
<version>${runtime.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
@ -21,13 +21,11 @@ public class BackwardChaining {
|
||||
KieSession ksession = kContainer.newKieSession("ksession-backward-chaining");
|
||||
ksession.setGlobal("result", result);
|
||||
ksession.insert(new Fact("Asia", "Planet Earth"));
|
||||
// ksession.insert(new Fact("China", "Asia"));
|
||||
// ksession.insert(new Fact("China", "Asia"));
|
||||
ksession.insert(new Fact("Great Wall of China", "China"));
|
||||
|
||||
ksession.fireAllRules();
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.baeldung
|
||||
|
||||
import com.baeldung.drools.model.Fact;
|
||||
|
||||
global com.baeldung.drools.model.Result result;
|
||||
|
||||
dialect "mvel"
|
||||
|
||||
query belongsTo(String x, String y)
|
||||
Fact(x, y;)
|
||||
or
|
||||
(Fact(z, y;) and belongsTo(x, z;))
|
||||
end
|
||||
|
||||
rule "Great Wall of China BELONGS TO Planet Earth"
|
||||
when
|
||||
belongsTo("Great Wall of China", "Planet Earth";)
|
||||
then
|
||||
result.setValue("Decision one taken: Great Wall of China BELONGS TO Planet Earth");
|
||||
end
|
||||
|
||||
rule "print all facts"
|
||||
when
|
||||
belongsTo(element, place;)
|
||||
then
|
||||
result.addFact(element + " IS ELEMENT OF " + place);
|
||||
end
|
@ -2,8 +2,6 @@ package com.baeldung.test;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.kie.api.KieServices;
|
||||
import org.kie.api.runtime.KieContainer;
|
||||
import org.kie.api.runtime.KieSession;
|
||||
@ -13,7 +11,6 @@ import com.baeldung.drools.model.Result;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
|
||||
@RunWith(value = JUnit4.class)
|
||||
public class BackwardChainingTest {
|
||||
private Result result;
|
||||
private KieServices ks;
|
||||
|
@ -7,6 +7,8 @@
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>drools</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
|
17
guest/spring-security/README.md
Normal file
17
guest/spring-security/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
## Building
|
||||
|
||||
To build the module, use Maven's `package` goal:
|
||||
|
||||
```
|
||||
mvn clean package
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
To run the application, use Spring Boot's `run` goal:
|
||||
|
||||
```
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
The application will be accessible at [http://localhost:8080/](http://localhost:8080/)
|
77
guest/spring-security/pom.xml
Normal file
77
guest/spring-security/pom.xml
Normal file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.stackify.guest</groupId>
|
||||
<artifactId>spring-security</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.0.M6</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<name>spring-security</name>
|
||||
<description>Spring Security Sample Project</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf-spring5</artifactId>
|
||||
<version>3.0.8.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
@ -0,0 +1,15 @@
|
||||
package com.stackify.guest.springsecurity;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages = {"com.stackify.guest.springsecurity"})
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.stackify.guest.springsecurity.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebMvcConfiguration implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/customLogin").setViewName("customLogin");
|
||||
registry.addViewController("/loginSuccess").setViewName("index");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.stackify.guest.springsecurity.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.provisioning.JdbcUserDetailsManager;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@EnableWebSecurity
|
||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Bean
|
||||
public UserDetailsService jdbcUserDetailsService(DataSource dataSource) {
|
||||
JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
|
||||
manager.setDataSource(dataSource);
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.authorizeRequests()
|
||||
.antMatchers("/css/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and().formLogin()
|
||||
.loginPage("/customLogin")
|
||||
.defaultSuccessUrl("/loginSuccess", true)
|
||||
.permitAll();
|
||||
}
|
||||
|
||||
}
|
2
guest/spring-security/src/main/resources/data.sql
Normal file
2
guest/spring-security/src/main/resources/data.sql
Normal file
@ -0,0 +1,2 @@
|
||||
INSERT INTO users VALUES ('jill', '$2a$04$qUlqAEEYF1YvrpJMosodoewgL6aO.qgHytl2k5L7kdXEWnJsFdxvq', TRUE);
|
||||
INSERT INTO authorities VALUES ('jill', 'USERS');
|
10
guest/spring-security/src/main/resources/schema.sql
Normal file
10
guest/spring-security/src/main/resources/schema.sql
Normal file
@ -0,0 +1,10 @@
|
||||
CREATE TABLE users (
|
||||
username VARCHAR(256) PRIMARY KEY,
|
||||
password VARCHAR(256),
|
||||
enabled BOOLEAN
|
||||
);
|
||||
|
||||
CREATE TABLE authorities (
|
||||
username VARCHAR(256) REFERENCES users (username),
|
||||
authority VARCHAR(256)
|
||||
);
|
@ -0,0 +1,3 @@
|
||||
.bad-login {
|
||||
color: red;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<link rel="stylesheet" href="/css/styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<form th:action="@{/customLogin}" method="post">
|
||||
<fieldset>
|
||||
<label for="username">Login:</label>
|
||||
<input id="username" name="username">
|
||||
<label for="password">Password:</label>
|
||||
<input id="password" name="password" type="password">
|
||||
</fieldset>
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
|
||||
<input type="submit" value="Login">
|
||||
<div th:if="${param.error}" class="bad-login">Bad login or password.</div>
|
||||
<div th:if="${param.logout}">Log out successful.</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:th="http://www.thymeleaf.org">
|
||||
<p>Hello, <span th:text="${
|
||||
T(org.springframework.security.core.context.SecurityContextHolder)
|
||||
.context.authentication.principal.username}"></span>!</p>
|
||||
<form action="/logout" method="post">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
|
||||
<input type="submit" value="Log Out">
|
||||
</form>
|
||||
</html>
|
@ -2,8 +2,17 @@ package com.baeldung.hibernate;
|
||||
|
||||
import com.baeldung.hibernate.pojo.Employee;
|
||||
import com.baeldung.hibernate.pojo.EntityDescription;
|
||||
import com.baeldung.hibernate.pojo.OrderEntry;
|
||||
import com.baeldung.hibernate.pojo.OrderEntryIdClass;
|
||||
import com.baeldung.hibernate.pojo.OrderEntryPK;
|
||||
import com.baeldung.hibernate.pojo.Product;
|
||||
import com.baeldung.hibernate.pojo.Phone;
|
||||
import com.baeldung.hibernate.pojo.TemporalValues;
|
||||
import com.baeldung.hibernate.pojo.Course;
|
||||
import com.baeldung.hibernate.pojo.Student;
|
||||
import com.baeldung.hibernate.pojo.User;
|
||||
import com.baeldung.hibernate.pojo.UserProfile;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.boot.Metadata;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
@ -33,6 +42,14 @@ public class HibernateUtil {
|
||||
metadataSources.addAnnotatedClass(Phone.class);
|
||||
metadataSources.addAnnotatedClass(EntityDescription.class);
|
||||
metadataSources.addAnnotatedClass(TemporalValues.class);
|
||||
metadataSources.addAnnotatedClass(User.class);
|
||||
metadataSources.addAnnotatedClass(Student.class);
|
||||
metadataSources.addAnnotatedClass(Course.class);
|
||||
metadataSources.addAnnotatedClass(Product.class);
|
||||
metadataSources.addAnnotatedClass(OrderEntryPK.class);
|
||||
metadataSources.addAnnotatedClass(OrderEntry.class);
|
||||
metadataSources.addAnnotatedClass(OrderEntryIdClass.class);
|
||||
metadataSources.addAnnotatedClass(UserProfile.class);
|
||||
|
||||
Metadata metadata = metadataSources.buildMetadata();
|
||||
return metadata.getSessionFactoryBuilder()
|
||||
|
@ -0,0 +1,27 @@
|
||||
package com.baeldung.hibernate.pojo;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Course {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private UUID courseId;
|
||||
|
||||
public UUID getCourseId() {
|
||||
return courseId;
|
||||
}
|
||||
|
||||
public void setCourseId(UUID courseId) {
|
||||
this.courseId = courseId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.baeldung.hibernate.pojo;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.TableGenerator;
|
||||
|
||||
@Entity
|
||||
public class Department {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.TABLE, generator="table-generator")
|
||||
@TableGenerator (name="table-generator", table="dep_ids", pkColumnName="seq_id", valueColumnName="seq_value")
|
||||
private long depId;
|
||||
|
||||
public long getDepId() {
|
||||
return depId;
|
||||
}
|
||||
|
||||
public void setDepId(long depId) {
|
||||
this.depId = depId;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.baeldung.hibernate.pojo;
|
||||
|
||||
import javax.persistence.EmbeddedId;
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class OrderEntry {
|
||||
|
||||
@EmbeddedId
|
||||
private OrderEntryPK entryId;
|
||||
|
||||
public OrderEntryPK getEntryId() {
|
||||
return entryId;
|
||||
}
|
||||
|
||||
public void setEntryId(OrderEntryPK entryId) {
|
||||
this.entryId = entryId;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.baeldung.hibernate.pojo;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
|
||||
@Entity
|
||||
@IdClass(OrderEntryPK.class)
|
||||
public class OrderEntryIdClass {
|
||||
@Id
|
||||
private long orderId;
|
||||
@Id
|
||||
private long productId;
|
||||
|
||||
public long getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public void setOrderId(long orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public long getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(long productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.baeldung.hibernate.pojo;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
|
||||
@Embeddable
|
||||
public class OrderEntryPK implements Serializable {
|
||||
|
||||
private long orderId;
|
||||
private long productId;
|
||||
|
||||
public long getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public void setOrderId(long orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public long getProductId() {
|
||||
return productId;
|
||||
}
|
||||
|
||||
public void setProductId(long productId) {
|
||||
this.productId = productId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
OrderEntryPK pk = (OrderEntryPK) o;
|
||||
return Objects.equals(orderId, pk.orderId) && Objects.equals(productId, pk.productId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(orderId, productId);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.baeldung.hibernate.pojo;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
import org.hibernate.annotations.Parameter;
|
||||
|
||||
@Entity
|
||||
public class Product {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(generator = "prod-generator")
|
||||
@GenericGenerator(name = "prod-generator", parameters = @Parameter(name = "prefix", value = "prod"), strategy = "com.baeldung.hibernate.pojo.generator.MyGenerator")
|
||||
private String prodId;
|
||||
|
||||
public String getProdId() {
|
||||
return prodId;
|
||||
}
|
||||
|
||||
public void setProdId(String prodId) {
|
||||
this.prodId = prodId;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.baeldung.hibernate.pojo;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Student {
|
||||
|
||||
@Id
|
||||
@GeneratedValue (strategy = GenerationType.SEQUENCE)
|
||||
private long studentId;
|
||||
|
||||
public long getStudentId() {
|
||||
return studentId;
|
||||
}
|
||||
|
||||
public void setStudent_id(long studentId) {
|
||||
this.studentId = studentId;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.baeldung.hibernate.pojo;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.SequenceGenerator;
|
||||
|
||||
@Entity
|
||||
public class User {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence-generator")
|
||||
@SequenceGenerator(name = "sequence-generator", sequenceName = "user_sequence", initialValue = 4)
|
||||
private long userId;
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.baeldung.hibernate.pojo;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.MapsId;
|
||||
import javax.persistence.OneToOne;
|
||||
|
||||
@Entity
|
||||
public class UserProfile {
|
||||
|
||||
@Id
|
||||
private long profileId;
|
||||
|
||||
@OneToOne
|
||||
@MapsId
|
||||
private User user;
|
||||
|
||||
public long getProfileId() {
|
||||
return profileId;
|
||||
}
|
||||
|
||||
public void setProfileId(long profileId) {
|
||||
this.profileId = profileId;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.baeldung.hibernate.pojo.generator;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.id.Configurable;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.type.Type;
|
||||
|
||||
public class MyGenerator implements IdentifierGenerator, Configurable {
|
||||
|
||||
private String prefix;
|
||||
|
||||
@Override
|
||||
public Serializable generate(SharedSessionContractImplementor session, Object obj) throws HibernateException {
|
||||
|
||||
String query = String.format("select %s from %s",
|
||||
session.getEntityPersister(obj.getClass().getName(), obj).getIdentifierPropertyName(),
|
||||
obj.getClass().getSimpleName());
|
||||
|
||||
Stream<String> ids = session.createQuery(query).stream();
|
||||
|
||||
Long max = ids.map(o -> o.replace(prefix + "-", ""))
|
||||
.mapToLong(Long::parseLong)
|
||||
.max()
|
||||
.orElse(0L);
|
||||
|
||||
return prefix + "-" + (max + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(Type type, Properties properties, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
prefix = properties.getProperty("prefix");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package com.baeldung.hibernate;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.hibernate.Transaction;
|
||||
import java.io.IOException;
|
||||
import org.hibernate.Session;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import com.baeldung.hibernate.pojo.Product;
|
||||
import com.baeldung.hibernate.pojo.Course;
|
||||
import com.baeldung.hibernate.pojo.OrderEntry;
|
||||
import com.baeldung.hibernate.pojo.OrderEntryIdClass;
|
||||
import com.baeldung.hibernate.pojo.OrderEntryPK;
|
||||
import com.baeldung.hibernate.pojo.Student;
|
||||
import com.baeldung.hibernate.pojo.User;
|
||||
import com.baeldung.hibernate.pojo.UserProfile;
|
||||
|
||||
public class IdentifiersIntegrationTest {
|
||||
private Session session;
|
||||
|
||||
private Transaction transaction;
|
||||
|
||||
@Before
|
||||
public void setUp() throws IOException {
|
||||
session = HibernateUtil.getSessionFactory()
|
||||
.openSession();
|
||||
transaction = session.beginTransaction();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
transaction.rollback();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSaveSimpleIdEntities_thenOk() {
|
||||
Student student = new Student();
|
||||
session.save(student);
|
||||
User user = new User();
|
||||
session.save(user);
|
||||
|
||||
assertThat(student.getStudentId()).isEqualTo(1L);
|
||||
assertThat(user.getUserId()).isEqualTo(4L);
|
||||
|
||||
Course course = new Course();
|
||||
session.save(course);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSaveCustomGeneratedId_thenOk() {
|
||||
Product product = new Product();
|
||||
session.save(product);
|
||||
Product product2 = new Product();
|
||||
session.save(product2);
|
||||
|
||||
assertThat(product2.getProdId()).isEqualTo("prod-2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSaveCompositeIdEntity_thenOk() {
|
||||
OrderEntryPK entryPK = new OrderEntryPK();
|
||||
entryPK.setOrderId(1L);
|
||||
entryPK.setProductId(30L);
|
||||
|
||||
OrderEntry entry = new OrderEntry();
|
||||
entry.setEntryId(entryPK);
|
||||
session.save(entry);
|
||||
|
||||
assertThat(entry.getEntryId()
|
||||
.getOrderId()).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSaveIdClassEntity_thenOk() {
|
||||
OrderEntryIdClass entry = new OrderEntryIdClass();
|
||||
entry.setOrderId(1L);
|
||||
entry.setProductId(30L);
|
||||
session.save(entry);
|
||||
|
||||
assertThat(entry.getOrderId()).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSaveDerivedIdEntity_thenOk() {
|
||||
User user = new User();
|
||||
session.save(user);
|
||||
|
||||
UserProfile profile = new UserProfile();
|
||||
profile.setUser(user);
|
||||
session.save(profile);
|
||||
|
||||
assertThat(profile.getProfileId()).isEqualTo(user.getUserId());
|
||||
}
|
||||
|
||||
}
|
12
jsonb/.gitignore
vendored
Normal file
12
jsonb/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
#folders#
|
||||
.idea
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
1
jsonb/README.md
Normal file
1
jsonb/README.md
Normal file
@ -0,0 +1 @@
|
||||
## JSON B
|
106
jsonb/pom.xml
Normal file
106
jsonb/pom.xml
Normal file
@ -0,0 +1,106 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>json-b</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>json-b</name>
|
||||
<description>json-b sample project</description>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>yasson</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<!-- Dependencies for Yasson -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse</groupId>
|
||||
<artifactId>yasson</artifactId>
|
||||
<version>${yasson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>javax.json</artifactId>
|
||||
<version>${javax.json.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>johnzon</id>
|
||||
<dependencies>
|
||||
<!-- Dependencies for Johnzon -->
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-json_1.1_spec</artifactId>
|
||||
<version>${geronimo-json_1.1_spec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.johnzon</groupId>
|
||||
<artifactId>johnzon-jsonb</artifactId>
|
||||
<version>${johnzon.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>javax.json.bind</groupId>
|
||||
<artifactId>javax.json.bind-api</artifactId>
|
||||
<version>${jsonb-api.version}</version>
|
||||
</dependency>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-surefire-provider</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<junit.platform.version>1.0.0</junit.platform.version>
|
||||
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
||||
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
||||
<jsonb-api.version>1.0</jsonb-api.version>
|
||||
<johnzon.version>1.1.3</johnzon.version>
|
||||
<geronimo-json_1.1_spec.version>1.0</geronimo-json_1.1_spec.version>
|
||||
<yasson.version>1.0</yasson.version>
|
||||
<javax.json.version>1.1.2</javax.json.version>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
127
jsonb/src/main/java/com/baeldung/jsonb/Person.java
Normal file
127
jsonb/src/main/java/com/baeldung/jsonb/Person.java
Normal file
@ -0,0 +1,127 @@
|
||||
package com.baeldung.jsonb;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
import javax.json.bind.annotation.JsonbDateFormat;
|
||||
import javax.json.bind.annotation.JsonbNumberFormat;
|
||||
import javax.json.bind.annotation.JsonbProperty;
|
||||
import javax.json.bind.annotation.JsonbTransient;
|
||||
|
||||
public class Person {
|
||||
|
||||
private int id;
|
||||
@JsonbProperty("person-name")
|
||||
private String name;
|
||||
@JsonbProperty(nillable = true)
|
||||
private String email;
|
||||
@JsonbTransient
|
||||
private int age;
|
||||
@JsonbDateFormat("dd-MM-yyyy")
|
||||
private LocalDate registeredDate;
|
||||
private BigDecimal salary;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(int id, String name, String email, int age, LocalDate registeredDate, BigDecimal salary) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.age = age;
|
||||
this.registeredDate = registeredDate;
|
||||
this.salary = salary;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@JsonbNumberFormat(locale = "en_US", value = "#0.0")
|
||||
public BigDecimal getSalary() {
|
||||
return salary;
|
||||
}
|
||||
|
||||
public void setSalary(BigDecimal salary) {
|
||||
this.salary = salary;
|
||||
}
|
||||
|
||||
public LocalDate getRegisteredDate() {
|
||||
return registeredDate;
|
||||
}
|
||||
|
||||
public void setRegisteredDate(LocalDate registeredDate) {
|
||||
this.registeredDate = registeredDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("Person [id=");
|
||||
builder.append(id);
|
||||
builder.append(", name=");
|
||||
builder.append(name);
|
||||
builder.append(", email=");
|
||||
builder.append(email);
|
||||
builder.append(", age=");
|
||||
builder.append(age);
|
||||
builder.append(", registeredDate=");
|
||||
builder.append(registeredDate);
|
||||
builder.append(", salary=");
|
||||
builder.append(salary);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + id;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Person other = (Person) obj;
|
||||
if (id != other.id)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
158
jsonb/src/test/java/com/baeldung/jsonb/JsonbTest.java
Normal file
158
jsonb/src/test/java/com/baeldung/jsonb/JsonbTest.java
Normal file
@ -0,0 +1,158 @@
|
||||
package com.baeldung.jsonb;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.json.bind.Jsonb;
|
||||
import javax.json.bind.JsonbBuilder;
|
||||
import javax.json.bind.JsonbConfig;
|
||||
import javax.json.bind.config.PropertyNamingStrategy;
|
||||
import javax.json.bind.config.PropertyOrderStrategy;
|
||||
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JsonbTest {
|
||||
|
||||
@Test
|
||||
public void givenPersonList_whenSerializeWithJsonb_thenGetPersonJsonArray() {
|
||||
Jsonb jsonb = JsonbBuilder.create();
|
||||
// @formatter:off
|
||||
List<Person> personList = Arrays.asList(
|
||||
new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)),
|
||||
new Person(2, "Jhon", "jhon1@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500)),
|
||||
new Person(3, "Jhon", null, 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)),
|
||||
new Person(4, "Tom", "tom@test.com", 21, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500)));
|
||||
// @formatter:on
|
||||
String jsonArrayPerson = jsonb.toJson(personList);
|
||||
// @formatter:off
|
||||
String jsonExpected = "[" +
|
||||
"{\"email\":\"jhon@test.com\"," +
|
||||
"\"id\":1,\"person-name\":\"Jhon\"," +
|
||||
"\"registeredDate\":\"09-09-2019\"," +
|
||||
"\"salary\":\"1000.0\"}," +
|
||||
"{\"email\":\"jhon1@test.com\"," +
|
||||
"\"id\":2,\"person-name\":\"Jhon\"," +
|
||||
"\"registeredDate\":\"09-09-2019\"," +
|
||||
"\"salary\":\"1500.0\"},{\"email\":null," +
|
||||
"\"id\":3,\"person-name\":\"Jhon\"," +
|
||||
"\"registeredDate\":\"09-09-2019\"," +
|
||||
"\"salary\":\"1000.0\"}," +
|
||||
"{\"email\":\"tom@test.com\"," +
|
||||
"\"id\":4,\"person-name\":\"Tom\"," +
|
||||
"\"registeredDate\":\"09-09-2019\"," +
|
||||
"\"salary\":\"1500.0\"}"
|
||||
+ "]";
|
||||
// @formatter:on
|
||||
assertTrue(jsonArrayPerson.equals(jsonExpected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPersonJsonArray_whenDeserializeWithJsonb_thenGetPersonList() {
|
||||
Jsonb jsonb = JsonbBuilder.create();
|
||||
// @formatter:off
|
||||
String personJsonArray =
|
||||
"[" +
|
||||
"{\"email\":\"jhon@test.com\"," +
|
||||
"\"id\":1,\"person-name\":\"Jhon\"," +
|
||||
"\"registeredDate\":\"09-09-2019\"," +
|
||||
"\"salary\":\"1000.0\"}," +
|
||||
"{\"email\":\"jhon1@test.com\"," +
|
||||
"\"id\":2,\"person-name\":\"Jhon\"," +
|
||||
"\"registeredDate\":\"09-09-2019\"," +
|
||||
"\"salary\":\"1500.0\"},{\"email\":null," +
|
||||
"\"id\":3,\"person-name\":\"Jhon\"," +
|
||||
"\"registeredDate\":\"09-09-2019\"," +
|
||||
"\"salary\":\"1000.0\"}," +
|
||||
"{\"email\":\"tom@test.com\"," +
|
||||
"\"id\":4,\"person-name\":\"Tom\"," +
|
||||
"\"registeredDate\":\"09-09-2019\"," +
|
||||
"\"salary\":\"1500.0\"}"
|
||||
+ "]";
|
||||
// @formatter:on
|
||||
@SuppressWarnings("serial")
|
||||
List<Person> personList = jsonb.fromJson(personJsonArray, new ArrayList<Person>() {
|
||||
}.getClass()
|
||||
.getGenericSuperclass());
|
||||
// @formatter:off
|
||||
List<Person> personListExpected = Arrays.asList(
|
||||
new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)),
|
||||
new Person(2, "Jhon", "jhon1@test.com", 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500)),
|
||||
new Person(3, "Jhon", null, 20, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1000)),
|
||||
new Person(4, "Tom", "tom@test.com", 21, LocalDate.of(2019, 9, 9), BigDecimal.valueOf(1500)));
|
||||
// @formatter:on
|
||||
assertTrue(ListUtils.isEqualList(personList, personListExpected));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPersonObject_whenNamingStrategy_thenGetCustomPersonJson() {
|
||||
JsonbConfig config = new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES);
|
||||
Jsonb jsonb = JsonbBuilder.create(config);
|
||||
Person person = new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000));
|
||||
String jsonPerson = jsonb.toJson(person);
|
||||
// @formatter:off
|
||||
String jsonExpected =
|
||||
"{\"email\":\"jhon@test.com\"," +
|
||||
"\"id\":1," +
|
||||
"\"person-name\":\"Jhon\"," +
|
||||
"\"registered_date\":\"07-09-2019\"," +
|
||||
"\"salary\":\"1000.0\"}";
|
||||
// @formatter:on
|
||||
assertTrue(jsonExpected.equals(jsonPerson));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPersonObject_whenWithPropertyOrderStrategy_thenGetReversePersonJson() {
|
||||
JsonbConfig config = new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.REVERSE);
|
||||
Jsonb jsonb = JsonbBuilder.create(config);
|
||||
Person person = new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000));
|
||||
String jsonPerson = jsonb.toJson(person);
|
||||
// @formatter:off
|
||||
String jsonExpected =
|
||||
"{\"salary\":\"1000.0\","+
|
||||
"\"registeredDate\":\"07-09-2019\"," +
|
||||
"\"person-name\":\"Jhon\"," +
|
||||
"\"id\":1," +
|
||||
"\"email\":\"jhon@test.com\"}";
|
||||
// @formatter:on
|
||||
assertTrue(jsonExpected.equals(jsonPerson));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPersonObject_whenSerializeWithJsonb_thenGetPersonJson() {
|
||||
Jsonb jsonb = JsonbBuilder.create();
|
||||
Person person = new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000));
|
||||
String jsonPerson = jsonb.toJson(person);
|
||||
// @formatter:off
|
||||
String jsonExpected =
|
||||
"{\"email\":\"jhon@test.com\"," +
|
||||
"\"id\":1," +
|
||||
"\"person-name\":\"Jhon\"," +
|
||||
"\"registeredDate\":\"07-09-2019\"," +
|
||||
"\"salary\":\"1000.0\"}";
|
||||
// @formatter:on
|
||||
assertTrue(jsonExpected.equals(jsonPerson));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPersonJson_whenDeserializeWithJsonb_thenGetPersonObject() {
|
||||
Jsonb jsonb = JsonbBuilder.create();
|
||||
Person person = new Person(1, "Jhon", "jhon@test.com", 0, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000.0));
|
||||
// @formatter:off
|
||||
String jsonPerson =
|
||||
"{\"email\":\"jhon@test.com\"," +
|
||||
"\"id\":1," +
|
||||
"\"person-name\":\"Jhon\"," +
|
||||
"\"registeredDate\":\"07-09-2019\"," +
|
||||
"\"salary\":\"1000.0\"}";
|
||||
// @formatter:on
|
||||
assertTrue(jsonb.fromJson(jsonPerson, Person.class)
|
||||
.equals(person));
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +1,32 @@
|
||||
package com.baeldung.templatemethodpattern.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class Computer {
|
||||
|
||||
protected Map<String, String> computerParts = new HashMap<>();
|
||||
protected List<String> moterboardSetupStatus = new ArrayList<>();
|
||||
|
||||
public final void buildComputer() {
|
||||
addMotherboard();
|
||||
addMotherboard();
|
||||
setupMotherboard();
|
||||
addProcessor();
|
||||
addMemory();
|
||||
addHardDrive();
|
||||
addGraphicCard();
|
||||
addSoundCard();
|
||||
}
|
||||
|
||||
public abstract void addProcessor();
|
||||
|
||||
public abstract void addMotherboard();
|
||||
|
||||
public abstract void addMemory();
|
||||
public abstract void setupMotherboard();
|
||||
|
||||
public abstract void addHardDrive();
|
||||
|
||||
public abstract void addGraphicCard();
|
||||
|
||||
public abstract void addSoundCard();
|
||||
public abstract void addProcessor();
|
||||
|
||||
public List<String> getMotherboardSetupStatus() {
|
||||
return moterboardSetupStatus;
|
||||
}
|
||||
|
||||
public Map<String, String> getComputerParts() {
|
||||
return computerParts;
|
||||
}
|
||||
|
@ -3,32 +3,24 @@ package com.baeldung.templatemethodpattern.model;
|
||||
public class HighEndComputer extends Computer {
|
||||
|
||||
@Override
|
||||
public void addProcessor() {
|
||||
computerParts.put("Processor", "High End Processor");
|
||||
public void addMotherboard() {
|
||||
computerParts.put("Motherboard", "High-end Motherboard");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setupMotherboard() {
|
||||
moterboardSetupStatus.add("Screwing the high-end motherboard to the case.");
|
||||
moterboardSetupStatus.add("Pluging in the power supply connectors.");
|
||||
moterboardSetupStatus.forEach(step -> System.out.println(step));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProcessor() {
|
||||
computerParts.put("Processor", "High-end Processor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMotherboard() {
|
||||
computerParts.put("Motherboard", "High End Motherboard");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMemory() {
|
||||
computerParts.put("Memory", "16GB");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHardDrive() {
|
||||
computerParts.put("Hard Drive", "2TB Hard Drive");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGraphicCard() {
|
||||
computerParts.put("Graphic Card", "High End Graphic Card");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSoundCard() {
|
||||
computerParts.put("Sound Card", "High End Sound Card");
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,18 @@
|
||||
package com.baeldung.templatemethodpattern.model;
|
||||
|
||||
public class StandardComputer extends Computer {
|
||||
|
||||
|
||||
public void addMotherboard() {
|
||||
computerParts.put("Motherboard", "Standard Motherboard");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupMotherboard() {
|
||||
moterboardSetupStatus.add("Screwing the standard motherboard to the case.");
|
||||
moterboardSetupStatus.add("Pluging in the power supply connectors.");
|
||||
moterboardSetupStatus.forEach(step -> System.out.println(step));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProcessor() {
|
||||
computerParts.put("Processor", "Standard Processor");
|
||||
@ -11,24 +22,4 @@ public class StandardComputer extends Computer {
|
||||
public void addMotherboard() {
|
||||
computerParts.put("Motherboard", "Standard Motherboard");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMemory() {
|
||||
computerParts.put("Memory", "8GB");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHardDrive() {
|
||||
computerParts.put("Hard Drive", "1TB Hard Drive");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGraphicCard() {
|
||||
computerParts.put("Graphic Card", "Standard Graphic Card");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSoundCard() {
|
||||
computerParts.put("Sound Card", "Standard Sound Card");
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,12 @@ package com.baeldung.templatemethodpatterntest;
|
||||
import com.baeldung.templatemethodpattern.model.HighEndComputer;
|
||||
import com.baeldung.templatemethodpattern.model.StandardComputer;
|
||||
import org.junit.Assert;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TemplateMethodPatternTest {
|
||||
|
||||
|
||||
private static StandardComputer standardComputer;
|
||||
private static HighEndComputer highEndComputer;
|
||||
|
||||
@ -20,101 +21,54 @@ public class TemplateMethodPatternTest {
|
||||
public static void setUpHighEndComputerInstance() {
|
||||
highEndComputer = new HighEndComputer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStandardMotherBoard_whenAddingMotherBoard_thenEqualAssertion() {
|
||||
standardComputer.addMotherboard();
|
||||
assertEquals("Standard Motherboard", standardComputer.getComputerParts().get("Motherboard"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStandardMotheroboard_whenSetup_thenTwoEqualAssertions() {
|
||||
standardComputer.setupMotherboard();
|
||||
assertEquals("Screwing the standard motherboard to the case.", standardComputer.getMotherboardSetupStatus().get(0));
|
||||
assertEquals("Plugin in the power supply connectors.", standardComputer.getMotherboardSetupStatus().get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStandardProcessor_whenAddingProcessor_thenEqualAssertion() {
|
||||
standardComputer.addProcessor();
|
||||
Assert.assertEquals("Standard Processor", standardComputer
|
||||
.getComputerParts().get("Processor"));
|
||||
assertEquals("Standard Processor", standardComputer.getComputerParts().get("Processor"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenStandardMotherBoard_whenAddingMotherBoard_thenEqualAssertion() {
|
||||
standardComputer.addMotherboard();
|
||||
Assert.assertEquals("Standard Motherboard", standardComputer
|
||||
.getComputerParts().get("Motherboard"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStandardMemory_whenAddingMemory_thenEqualAssertion() {
|
||||
standardComputer.addMemory();
|
||||
Assert.assertEquals("8GB", standardComputer
|
||||
.getComputerParts().get("Memory"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStandardHardDrive_whenAddingHardDrive_thenEqualAssertion() {
|
||||
standardComputer.addHardDrive();
|
||||
Assert.assertEquals("1TB Hard Drive", standardComputer
|
||||
.getComputerParts().get("Hard Drive"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStandardGraphicaCard_whenAddingGraphicCard_thenEqualAssertion() {
|
||||
standardComputer.addGraphicCard();
|
||||
Assert.assertEquals("Standard Graphic Card", standardComputer
|
||||
.getComputerParts().get("Graphic Card"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStandardSoundCard_whenAddingSoundCard_thenEqualAssertion() {
|
||||
standardComputer.addSoundCard();
|
||||
Assert.assertEquals("Standard Sound Card", standardComputer
|
||||
.getComputerParts().get("Sound Card"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAllStandardParts_whenBuildingComputer_thenSixParts() {
|
||||
public void givenAllStandardParts_whenBuildingComputer_thenTwoParts() {
|
||||
standardComputer.buildComputer();
|
||||
Assert.assertEquals(6, standardComputer
|
||||
.getComputerParts().size());
|
||||
assertEquals(2, standardComputer.getComputerParts().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHighEnddMotherBoard_whenAddingMotherBoard_thenEqualAssertion() {
|
||||
highEndComputer.addMotherboard();
|
||||
Assert.assertEquals("High-end Motherboard", highEndComputer.getComputerParts().get("Motherboard"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHighEnddMotheroboard_whenSetup_thenTwoEqualAssertions() {
|
||||
highEndComputer.setupMotherboard();
|
||||
assertEquals("Screwing the high-end motherboard to the case.", highEndComputer.getMotherboardSetupStatus().get(0));
|
||||
assertEquals("Plugin in the power supply connectors.", highEndComputer.getMotherboardSetupStatus().get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHightEndProcessor_whenAddingProcessor_thenEqualAssertion() {
|
||||
highEndComputer.addProcessor();
|
||||
Assert.assertEquals("High End Processor", highEndComputer
|
||||
.getComputerParts().get("Processor"));
|
||||
Assert.assertEquals("High-end Processor", highEndComputer.getComputerParts().get("Processor"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHighEnddMotherBoard_whenAddingMotherBoard_thenEqualAssertion() {
|
||||
highEndComputer.addMotherboard();
|
||||
Assert.assertEquals("High End Motherboard", highEndComputer
|
||||
.getComputerParts().get("Motherboard"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHighEndMemory_whenAddingMemory_thenEqualAssertion() {
|
||||
highEndComputer.addMemory();
|
||||
Assert.assertEquals("16GB", highEndComputer
|
||||
.getComputerParts().get("Memory"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHighEndHardDrive_whenAddingHardDrive_thenEqualAssertion() {
|
||||
highEndComputer.addHardDrive();
|
||||
Assert.assertEquals("2TB Hard Drive", highEndComputer
|
||||
.getComputerParts().get("Hard Drive"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHighEndGraphicCard_whenAddingGraphicCard_thenEqualAssertion() {
|
||||
highEndComputer.addGraphicCard();
|
||||
Assert.assertEquals("High End Graphic Card", highEndComputer
|
||||
.getComputerParts().get("Graphic Card"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenHighEndSoundCard_whenAddingSoundCard_thenEqualAssertion() {
|
||||
highEndComputer.addSoundCard();
|
||||
Assert.assertEquals("High End Sound Card", highEndComputer
|
||||
.getComputerParts().get("Sound Card"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAllHighEndParts_whenBuildingComputer_thenSixParts() {
|
||||
public void givenAllHighEnddParts_whenBuildingComputer_thenTwoParts() {
|
||||
highEndComputer.buildComputer();
|
||||
Assert.assertEquals(6, highEndComputer.getComputerParts().size());
|
||||
assertEquals(2, highEndComputer.getComputerParts().size());
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,18 @@
|
||||
<artifactId>javax.json.bind-api</artifactId>
|
||||
<version>${jsonb-api.version}</version>
|
||||
</dependency>
|
||||
<!-- Dependencies for Yasson -->
|
||||
<!-- <dependency> -->
|
||||
<!-- <groupId>org.eclipse</groupId> -->
|
||||
<!-- <artifactId>yasson</artifactId> -->
|
||||
<!-- <version>1.0</version> -->
|
||||
<!-- </dependency> -->
|
||||
<!-- <dependency> -->
|
||||
<!-- <groupId>org.glassfish</groupId> -->
|
||||
<!-- <artifactId>javax.json</artifactId> -->
|
||||
<!-- <version>1.1.2</version> -->
|
||||
<!-- </dependency> -->
|
||||
<!-- Dependencies for Johnzon -->
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-json_1.1_spec</artifactId>
|
||||
@ -88,6 +100,13 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
|
@ -1,38 +0,0 @@
|
||||
package com.baeldung.jsonb;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
import javax.json.bind.Jsonb;
|
||||
import javax.json.bind.JsonbBuilder;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JsonbTest {
|
||||
|
||||
private Jsonb jsonb;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
jsonb = JsonbBuilder.create();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPersonObject_whenSerializeWithJsonb_thenGetPersonJson() {
|
||||
Person person = new Person(1, "Jhon", "jhon@test.com", 20, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000));
|
||||
String jsonPerson = jsonb.toJson(person);
|
||||
assertTrue("{\"email\":\"jhon@test.com\",\"id\":1,\"person-name\":\"Jhon\",\"registeredDate\":\"07-09-2019\",\"salary\":\"1000.0\"}".equals(jsonPerson));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPersonJson_whenDeserializeWithJsonb_thenGetPersonObject() {
|
||||
Person person = new Person(1, "Jhon", "jhon@test.com", 0, LocalDate.of(2019, 9, 7), BigDecimal.valueOf(1000.0));
|
||||
String jsonPerson = "{\"email\":\"jhon@test.com\",\"id\":1,\"person-name\":\"Jhon\",\"registeredDate\":\"07-09-2019\",\"salary\":\"1000.0\"}";
|
||||
assertTrue(jsonb.fromJson(jsonPerson, Person.class)
|
||||
.equals(person));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package org.baeldung.dsrouting;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
/**
|
||||
* Database access code for datasource routing example.
|
||||
*/
|
||||
public class ClientDao {
|
||||
|
||||
private static final String SQL_GET_CLIENT_NAME = "select name from client";
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public ClientDao(DataSource datasource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(datasource);
|
||||
}
|
||||
|
||||
public String getClientName() {
|
||||
return this.jdbcTemplate.query(SQL_GET_CLIENT_NAME, rowMapper)
|
||||
.get(0);
|
||||
}
|
||||
|
||||
private static RowMapper<String> rowMapper = (rs, rowNum) -> {
|
||||
return rs.getString("name");
|
||||
};
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package org.baeldung.dsrouting;
|
||||
|
||||
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
||||
|
||||
/**
|
||||
* Returns thread bound client lookup key for current context.
|
||||
*/
|
||||
public class ClientDataSourceRouter extends AbstractRoutingDataSource {
|
||||
|
||||
@Override
|
||||
protected Object determineCurrentLookupKey() {
|
||||
return ClientDatabaseContextHolder.getClientDatabase();
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package org.baeldung.dsrouting;
|
||||
|
||||
public enum ClientDatabase {
|
||||
|
||||
ACME_WIDGETS, WIDGETS_ARE_US, WIDGET_DEPOT
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package org.baeldung.dsrouting;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Thread shared context to point to the datasource which should be used. This
|
||||
* enables context switches between different clients.
|
||||
*/
|
||||
public class ClientDatabaseContextHolder {
|
||||
|
||||
private static final ThreadLocal<ClientDatabase> CONTEXT = new ThreadLocal<>();
|
||||
|
||||
public static void set(ClientDatabase clientDatabase) {
|
||||
Assert.notNull(clientDatabase, "clientDatabase cannot be null");
|
||||
CONTEXT.set(clientDatabase);
|
||||
}
|
||||
|
||||
public static ClientDatabase getClientDatabase() {
|
||||
return CONTEXT.get();
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
CONTEXT.remove();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package org.baeldung.dsrouting;
|
||||
|
||||
/**
|
||||
* Service layer code for datasource routing example. Here, the service methods are responsible
|
||||
* for setting and clearing the context.
|
||||
*/
|
||||
public class ClientService {
|
||||
|
||||
private final ClientDao clientDao;
|
||||
|
||||
public ClientService(ClientDao clientDao) {
|
||||
this.clientDao = clientDao;
|
||||
}
|
||||
|
||||
public String getClientName(ClientDatabase clientDb) {
|
||||
ClientDatabaseContextHolder.set(clientDb);
|
||||
String clientName = this.clientDao.getClientName();
|
||||
ClientDatabaseContextHolder.clear();
|
||||
return clientName;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package org.baeldung.dsrouting;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
@Configuration
|
||||
public class DataSourceRoutingTestConfiguration {
|
||||
|
||||
@Bean
|
||||
public ClientService clientService() {
|
||||
return new ClientService(new ClientDao(clientDatasource()));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataSource clientDatasource() {
|
||||
Map<Object, Object> targetDataSources = new HashMap<>();
|
||||
DataSource acmeWidgetsDatasource = acmeWidgetsDatasource();
|
||||
DataSource widgetsAreUsDatasource = widgetsAreUsDatasource();
|
||||
DataSource widgetsDepotDatasource = widgetsDepotDatasource();
|
||||
targetDataSources.put(ClientDatabase.ACME_WIDGETS, acmeWidgetsDatasource);
|
||||
targetDataSources.put(ClientDatabase.WIDGETS_ARE_US, widgetsAreUsDatasource);
|
||||
targetDataSources.put(ClientDatabase.WIDGET_DEPOT, widgetsDepotDatasource);
|
||||
|
||||
ClientDataSourceRouter clientRoutingDatasource = new ClientDataSourceRouter();
|
||||
clientRoutingDatasource.setTargetDataSources(targetDataSources);
|
||||
clientRoutingDatasource.setDefaultTargetDataSource(acmeWidgetsDatasource);
|
||||
return clientRoutingDatasource;
|
||||
}
|
||||
|
||||
private DataSource acmeWidgetsDatasource() {
|
||||
EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder();
|
||||
EmbeddedDatabase embeddedDb = dbBuilder.setType(EmbeddedDatabaseType.H2)
|
||||
.setName("ACMEWIDGETS")
|
||||
.addScript("classpath:dsrouting-db.sql")
|
||||
.build();
|
||||
return embeddedDb;
|
||||
}
|
||||
|
||||
private DataSource widgetsAreUsDatasource() {
|
||||
EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder();
|
||||
EmbeddedDatabase embeddedDb = dbBuilder.setType(EmbeddedDatabaseType.H2)
|
||||
.setName("WIDGETSAREUS")
|
||||
.addScript("classpath:dsrouting-db.sql")
|
||||
.build();
|
||||
return embeddedDb;
|
||||
}
|
||||
|
||||
private DataSource widgetsDepotDatasource() {
|
||||
EmbeddedDatabaseBuilder dbBuilder = new EmbeddedDatabaseBuilder();
|
||||
EmbeddedDatabase embeddedDb = dbBuilder.setType(EmbeddedDatabaseType.H2)
|
||||
.setName("WIDGETDEPOT")
|
||||
.addScript("classpath:dsrouting-db.sql")
|
||||
.build();
|
||||
return embeddedDb;
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package org.baeldung.dsrouting;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@ContextConfiguration(classes = DataSourceRoutingTestConfiguration.class)
|
||||
public class DataSourceRoutingTests {
|
||||
|
||||
@Autowired
|
||||
DataSource routingDatasource;
|
||||
|
||||
@Autowired
|
||||
ClientService clientService;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
final String SQL_ACME_WIDGETS = "insert into client (id, name) values (1, 'ACME WIDGETS')";
|
||||
final String SQL_WIDGETS_ARE_US = "insert into client (id, name) values (2, 'WIDGETS ARE US')";
|
||||
final String SQL_WIDGET_DEPOT = "insert into client (id, name) values (3, 'WIDGET DEPOT')";
|
||||
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate();
|
||||
jdbcTemplate.setDataSource(routingDatasource);
|
||||
|
||||
ClientDatabaseContextHolder.set(ClientDatabase.ACME_WIDGETS);
|
||||
jdbcTemplate.execute(SQL_ACME_WIDGETS);
|
||||
ClientDatabaseContextHolder.clear();
|
||||
|
||||
ClientDatabaseContextHolder.set(ClientDatabase.WIDGETS_ARE_US);
|
||||
jdbcTemplate.execute(SQL_WIDGETS_ARE_US);
|
||||
ClientDatabaseContextHolder.clear();
|
||||
|
||||
ClientDatabaseContextHolder.set(ClientDatabase.WIDGET_DEPOT);
|
||||
jdbcTemplate.execute(SQL_WIDGET_DEPOT);
|
||||
ClientDatabaseContextHolder.clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenClientDbs_whenContextsSwitch_thenRouteToCorrectDatabase() throws Exception {
|
||||
|
||||
// test ACME WIDGETS
|
||||
String clientName = clientService.getClientName(ClientDatabase.ACME_WIDGETS);
|
||||
assertEquals(clientName, "ACME WIDGETS");
|
||||
|
||||
// test WIDGETS_ARE_US
|
||||
clientName = clientService.getClientName(ClientDatabase.WIDGETS_ARE_US);
|
||||
assertEquals(clientName, "WIDGETS ARE US");
|
||||
|
||||
// test WIDGET_DEPOT
|
||||
clientName = clientService.getClientName(ClientDatabase.WIDGET_DEPOT);
|
||||
assertEquals(clientName, "WIDGET DEPOT");
|
||||
}
|
||||
}
|
5
spring-boot/src/test/resources/dsrouting-db.sql
Normal file
5
spring-boot/src/test/resources/dsrouting-db.sql
Normal file
@ -0,0 +1,5 @@
|
||||
create table client (
|
||||
id numeric,
|
||||
name varchar(50),
|
||||
constraint pk_client primary key (id)
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user