From e69b630923ad5f25fc2e4cd7e137c1d31dc427c4 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Tue, 17 Apr 2018 17:04:06 -0600 Subject: [PATCH 01/93] Code for eval article --- .../EventStreamServer.java | 12 ++++++++++++ .../client/EventStreamClient.java | 18 ++++++++++++++++++ .../controller/EventStreamController.java | 17 +++++++++++++++++ .../src/main/resources/application.properties | 0 .../EventStreamServerTests.java | 16 ++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100644 spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServer.java create mode 100644 spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/client/EventStreamClient.java create mode 100644 spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/controller/EventStreamController.java create mode 100644 spring-webflux-event-stream/src/main/resources/application.properties create mode 100644 spring-webflux-event-stream/src/test/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServerTests.java diff --git a/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServer.java b/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServer.java new file mode 100644 index 0000000000..48548bd8d5 --- /dev/null +++ b/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServer.java @@ -0,0 +1,12 @@ +package com.baeldung.demo.eventstreamwebfluxdemo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class EventStreamServer { + + public static void main(String[] args) { + SpringApplication.run(EventStreamServer.class, args); + } +} diff --git a/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/client/EventStreamClient.java b/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/client/EventStreamClient.java new file mode 100644 index 0000000000..73ca753136 --- /dev/null +++ b/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/client/EventStreamClient.java @@ -0,0 +1,18 @@ +package com.baeldung.demo.eventstreamwebfluxdemo.client; + +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.client.WebClient; + +public class EventStreamClient { + public static void main(String[] args) + { + WebClient.create("http://127.0.0.1:8080") + .get() + .uri("/events") + .accept(MediaType.APPLICATION_STREAM_JSON) + .retrieve() + .bodyToFlux(Long.class) + .toStream() + .forEach(item -> System.out.println("New event : " + item)); + } +} diff --git a/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/controller/EventStreamController.java b/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/controller/EventStreamController.java new file mode 100644 index 0000000000..d28d402316 --- /dev/null +++ b/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/controller/EventStreamController.java @@ -0,0 +1,17 @@ +package com.baeldung.demo.eventstreamwebfluxdemo.controller; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Flux; + +import java.time.Duration; + +@RestController +public class EventStreamController +{ + @RequestMapping("/events") + public Flux getServerEvents() + { + return Flux.interval(Duration.ofMillis(1000)); + } +} diff --git a/spring-webflux-event-stream/src/main/resources/application.properties b/spring-webflux-event-stream/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-webflux-event-stream/src/test/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServerTests.java b/spring-webflux-event-stream/src/test/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServerTests.java new file mode 100644 index 0000000000..d4dfcce4b3 --- /dev/null +++ b/spring-webflux-event-stream/src/test/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServerTests.java @@ -0,0 +1,16 @@ +package com.baeldung.demo.eventstreamwebfluxdemo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class EventStreamServerTests { + + @Test + public void contextLoads() { + } + +} From 0da695fba58b4da8e3a6fa60b073c713b5fbc746 Mon Sep 17 00:00:00 2001 From: Erdem Date: Wed, 25 Apr 2018 00:59:56 +0300 Subject: [PATCH 02/93] tutorial real time event streaming with spring webflux --- .../com/baeldung/reactive/webflux/Event.java | 13 ++++++ .../webflux/EventStreamController.java | 20 +++++++++ .../webflux/WebfluxDemoApplication.java | 12 +++++ .../static/webflux/client-event-stream.html | 45 +++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/Event.java create mode 100644 spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java create mode 100644 spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/WebfluxDemoApplication.java create mode 100644 spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/Event.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/Event.java new file mode 100644 index 0000000000..03e80e915e --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/Event.java @@ -0,0 +1,13 @@ +package com.baeldung.reactive.webflux; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class Event { + + private Long id; + private String body; + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java new file mode 100644 index 0000000000..5a88f6823e --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java @@ -0,0 +1,20 @@ +package com.baeldung.reactive.webflux; + +import java.time.Duration; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import reactor.core.publisher.Flux; + +@RestController +public class EventStreamController { + + @GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE) + public Flux getMessages() { + return Flux.interval(Duration.ofMillis(1000)) + .map(tick -> new Event(tick, "This is Message #" + tick)); + } + +} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/WebfluxDemoApplication.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/WebfluxDemoApplication.java new file mode 100644 index 0000000000..70cad0ad22 --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/WebfluxDemoApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.reactive.webflux; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class WebfluxDemoApplication { + + public static void main(String[] args) { + SpringApplication.run(WebfluxDemoApplication.class, args); + } +} diff --git a/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html b/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html new file mode 100644 index 0000000000..d7631f9217 --- /dev/null +++ b/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html @@ -0,0 +1,45 @@ + + + + + Baeldung: Spring 5 Reactive Webflux - real time event streaming + + + + + + +

Events streamed...

+ + + + + + + + + +
Event IdEvent Body
+ + + + + \ No newline at end of file From 6cbe92600d3da221a3b1a1324f953898d7ef16b7 Mon Sep 17 00:00:00 2001 From: Erdem Date: Wed, 25 Apr 2018 01:37:08 +0300 Subject: [PATCH 03/93] fix some type and change spring boot version to 2.0.1 from 2.0.0 --- spring-5-reactive/pom.xml | 2 +- .../baeldung/reactive/webflux/EventStreamController.java | 4 ++-- .../resources/static/webflux/client-event-stream.html | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spring-5-reactive/pom.xml b/spring-5-reactive/pom.xml index 96378c60de..324fb13dd2 100644 --- a/spring-5-reactive/pom.xml +++ b/spring-5-reactive/pom.xml @@ -13,7 +13,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.0.RELEASE + 2.0.1.RELEASE diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java index 5a88f6823e..f3d10437e2 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java @@ -12,9 +12,9 @@ import reactor.core.publisher.Flux; public class EventStreamController { @GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public Flux getMessages() { + public Flux getEvents() { return Flux.interval(Duration.ofMillis(1000)) - .map(tick -> new Event(tick, "This is Message #" + tick)); + .map(tick -> new Event(tick, "This is Event #" + tick)); } } diff --git a/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html b/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html index d7631f9217..e44cbf0746 100644 --- a/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html +++ b/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html @@ -32,12 +32,12 @@ var data = JSON.parse(event.data); var table = document.getElementById("events-table"); var row = table.insertRow(1); - var cell1 = row.insertCell(0); - var cell2 = row.insertCell(1); + var cellId = row.insertCell(0); + var cellBody = row.insertCell(1); - cell1.innerHTML = '' + data.id + ''; - cell2.innerHTML = '' + data.body + ''; + cellId.innerHTML = '' + data.id + ''; + cellBody.innerHTML = '' + data.body + ''; } From 79ab39d9f18024cb5696da31ebe5a12f4ce22982 Mon Sep 17 00:00:00 2001 From: DOHA Date: Sat, 28 Apr 2018 15:52:27 +0300 Subject: [PATCH 04/93] spring data rest projections --- .../java/com/baeldung/config/RestConfig.java | 17 ++++ .../main/java/com/baeldung/models/Book.java | 16 +++- .../com/baeldung/projections/CustomBook.java | 22 +++++ .../baeldung/repositories/BookRepository.java | 7 +- .../SpringDataProjectionIntegrationTest.java | 92 +++++++++++++++++++ 5 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 spring-data-rest/src/main/java/com/baeldung/config/RestConfig.java create mode 100644 spring-data-rest/src/main/java/com/baeldung/projections/CustomBook.java create mode 100644 spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java diff --git a/spring-data-rest/src/main/java/com/baeldung/config/RestConfig.java b/spring-data-rest/src/main/java/com/baeldung/config/RestConfig.java new file mode 100644 index 0000000000..7434dde394 --- /dev/null +++ b/spring-data-rest/src/main/java/com/baeldung/config/RestConfig.java @@ -0,0 +1,17 @@ +package com.baeldung.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.rest.core.config.RepositoryRestConfiguration; +import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter; + +import com.baeldung.projections.CustomBook; + + +@Configuration +public class RestConfig extends RepositoryRestConfigurerAdapter{ + + @Override + public void configureRepositoryRestConfiguration(RepositoryRestConfiguration repositoryRestConfiguration){ + repositoryRestConfiguration.getProjectionConfiguration().addProjection(CustomBook.class); + } +} diff --git a/spring-data-rest/src/main/java/com/baeldung/models/Book.java b/spring-data-rest/src/main/java/com/baeldung/models/Book.java index 06abfb8f4d..002a64e738 100644 --- a/spring-data-rest/src/main/java/com/baeldung/models/Book.java +++ b/spring-data-rest/src/main/java/com/baeldung/models/Book.java @@ -4,6 +4,7 @@ import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -20,12 +21,14 @@ public class Book { @Column(nullable = false) private String title; - + + private String isbn; + @ManyToOne @JoinColumn(name = "library_id") private Library library; - @ManyToMany(mappedBy = "books") + @ManyToMany(mappedBy = "books", fetch = FetchType.EAGER) private List authors; public Book() { @@ -52,6 +55,15 @@ public class Book { this.id = id; } + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public Library getLibrary() { return library; } diff --git a/spring-data-rest/src/main/java/com/baeldung/projections/CustomBook.java b/spring-data-rest/src/main/java/com/baeldung/projections/CustomBook.java new file mode 100644 index 0000000000..1cd9c01383 --- /dev/null +++ b/spring-data-rest/src/main/java/com/baeldung/projections/CustomBook.java @@ -0,0 +1,22 @@ +package com.baeldung.projections; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.rest.core.config.Projection; + +import com.baeldung.models.Author; +import com.baeldung.models.Book; + +@Projection(name = "customBook", types = { Book.class }) +public interface CustomBook { + @Value("#{target.id}") + long getId(); + + String getTitle(); + + List getAuthors(); + + @Value("#{target.getAuthors().size()}") + int getAuthorCount(); +} diff --git a/spring-data-rest/src/main/java/com/baeldung/repositories/BookRepository.java b/spring-data-rest/src/main/java/com/baeldung/repositories/BookRepository.java index f9176032ab..34019a9d91 100644 --- a/spring-data-rest/src/main/java/com/baeldung/repositories/BookRepository.java +++ b/spring-data-rest/src/main/java/com/baeldung/repositories/BookRepository.java @@ -1,9 +1,10 @@ package com.baeldung.repositories; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; import com.baeldung.models.Book; +import com.baeldung.projections.CustomBook; -public interface BookRepository extends CrudRepository { - -} +@RepositoryRestResource(excerptProjection = CustomBook.class) +public interface BookRepository extends CrudRepository {} diff --git a/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java b/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java new file mode 100644 index 0000000000..4091fdf154 --- /dev/null +++ b/spring-data-rest/src/test/java/com/baeldung/projection/SpringDataProjectionIntegrationTest.java @@ -0,0 +1,92 @@ +package com.baeldung.projection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import io.restassured.RestAssured; +import io.restassured.response.Response; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.SpringDataRestApplication; +import com.baeldung.models.Author; +import com.baeldung.models.Book; +import com.baeldung.repositories.AuthorRepository; +import com.baeldung.repositories.BookRepository; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = SpringDataRestApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT) + +public class SpringDataProjectionIntegrationTest { + private static final String BOOK_ENDPOINT = "http://localhost:8080/books"; + private static final String AUTHOR_ENDPOINT = "http://localhost:8080/authors"; + + + @Autowired + private BookRepository bookRepo; + + @Autowired + private AuthorRepository authorRepo; + + @Before + public void setup(){ + if(bookRepo.findOne(1L) == null){ + Book book = new Book("Animal Farm"); + book.setIsbn("978-1943138425"); + book = bookRepo.save(book); + Author author = new Author("George Orwell"); + author = authorRepo.save(author); + author.setBooks(Arrays.asList(book)); + author = authorRepo.save(author); + } + } + + @Test + public void whenGetBook_thenOK(){ + final Response response = RestAssured.get(BOOK_ENDPOINT+"/1"); + + assertEquals(200, response.getStatusCode()); + assertTrue(response.asString().contains("isbn")); + assertFalse(response.asString().contains("authorCount")); +// System.out.println(response.asString()); + } + + + @Test + public void whenGetBookProjection_thenOK(){ + final Response response = RestAssured.get(BOOK_ENDPOINT+"/1?projection=customBook"); + + assertEquals(200, response.getStatusCode()); + assertFalse(response.asString().contains("isbn")); + assertTrue(response.asString().contains("authorCount")); +// System.out.println(response.asString()); + } + + @Test + public void whenGetAllBooks_thenOK(){ + final Response response = RestAssured.get(BOOK_ENDPOINT); + + assertEquals(200, response.getStatusCode()); + assertFalse(response.asString().contains("isbn")); + assertTrue(response.asString().contains("authorCount")); + // System.out.println(response.asString()); + } + + @Test + public void whenGetAuthorBooks_thenOK(){ + final Response response = RestAssured.get(AUTHOR_ENDPOINT+"/1/books"); + + assertEquals(200, response.getStatusCode()); + assertFalse(response.asString().contains("isbn")); + assertTrue(response.asString().contains("authorCount")); + System.out.println(response.asString()); + } +} From f9ddc38a39fe6baa835fb7418bd493c975b3aeb7 Mon Sep 17 00:00:00 2001 From: RajatGarg Date: Tue, 1 May 2018 14:24:25 +0530 Subject: [PATCH 05/93] BAEL-1734 move packages from libraries to libraries-data --- libraries-data/README.md | 4 + libraries-data/log4j.properties | 1 + libraries-data/myPersistence.xml | 26 +++ libraries-data/pom.xml | 73 ++++++ .../com/baeldung/hikaricp/DataSource.java | 0 .../java/com/baeldung/hikaricp/Employee.java | 0 .../com/baeldung/hikaricp/HikariCPDemo.java | 0 .../jcache/SimpleCacheEntryListener.java | 0 .../baeldung/jcache/SimpleCacheLoader.java | 0 .../baeldung/jcache/SimpleEntryProcessor.java | 0 .../java/com/baeldung/jdo/GuideToJDO.java | 0 .../main/java/com/baeldung/jdo/Product.java | 0 .../java/com/baeldung/jdo/ProductXML.java | 0 .../java/com/baeldung/jdo/query/MyApp.java | 192 ++++++++-------- .../com/baeldung/jdo/query/ProductItem.java | 140 ++++++------ .../com/baeldung/jdo/xml/AnnotadedPerson.java | 132 +++++------ .../main/java/com/baeldung/jdo/xml/MyApp.java | 210 +++++++++--------- .../java/com/baeldung/jdo/xml/Person.java | 116 +++++----- .../java/com/baeldung/jdo/xml/Product.java | 116 +++++----- .../src/main/resources/META-INF/BenchmarkList | 0 .../resources/META-INF/datanucleus.properties | 4 + .../src/main/resources/META-INF/jdoconfig.xml | 32 +-- .../src/main/resources/META-INF/package.jdo | 56 ++--- .../src/main/resources/db.sql | 0 .../hikaricp/HikariCPIntegrationTest.java | 0 .../com/baeldung/jcache/CacheLoaderTest.java | 0 .../jcache/EntryProcessorIntegrationTest.java | 0 .../jcache/EventListenerIntegrationTest.java | 0 .../jcache/JCacheIntegrationTest.java | 0 .../jdo/GuideToJDOIntegrationTest.java | 0 libraries/README.md | 4 - 31 files changed, 605 insertions(+), 501 deletions(-) create mode 100644 libraries-data/log4j.properties create mode 100644 libraries-data/myPersistence.xml rename {libraries => libraries-data}/src/main/java/com/baeldung/hikaricp/DataSource.java (100%) rename {libraries => libraries-data}/src/main/java/com/baeldung/hikaricp/Employee.java (100%) rename {libraries => libraries-data}/src/main/java/com/baeldung/hikaricp/HikariCPDemo.java (100%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jcache/SimpleCacheEntryListener.java (100%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jcache/SimpleCacheLoader.java (100%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jcache/SimpleEntryProcessor.java (100%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jdo/GuideToJDO.java (100%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jdo/Product.java (100%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jdo/ProductXML.java (100%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jdo/query/MyApp.java (97%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jdo/query/ProductItem.java (95%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java (96%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jdo/xml/MyApp.java (97%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jdo/xml/Person.java (95%) rename {libraries => libraries-data}/src/main/java/com/baeldung/jdo/xml/Product.java (94%) create mode 100644 libraries-data/src/main/resources/META-INF/BenchmarkList create mode 100644 libraries-data/src/main/resources/META-INF/datanucleus.properties rename {libraries => libraries-data}/src/main/resources/META-INF/jdoconfig.xml (96%) rename {libraries => libraries-data}/src/main/resources/META-INF/package.jdo (97%) rename {libraries => libraries-data}/src/main/resources/db.sql (100%) rename {libraries => libraries-data}/src/test/java/com/baeldung/hikaricp/HikariCPIntegrationTest.java (100%) rename {libraries => libraries-data}/src/test/java/com/baeldung/jcache/CacheLoaderTest.java (100%) rename {libraries => libraries-data}/src/test/java/com/baeldung/jcache/EntryProcessorIntegrationTest.java (100%) rename {libraries => libraries-data}/src/test/java/com/baeldung/jcache/EventListenerIntegrationTest.java (100%) rename {libraries => libraries-data}/src/test/java/com/baeldung/jcache/JCacheIntegrationTest.java (100%) rename {libraries => libraries-data}/src/test/java/com/baeldung/jdo/GuideToJDOIntegrationTest.java (100%) diff --git a/libraries-data/README.md b/libraries-data/README.md index 9e8d32fa44..afca20eb2a 100644 --- a/libraries-data/README.md +++ b/libraries-data/README.md @@ -3,3 +3,7 @@ - [Introduction to ORMLite](http://www.baeldung.com/ormlite) - [Introduction To Kryo](http://www.baeldung.com/kryo) - [Introduction to KafkaStreams in Java](http://www.baeldung.com/java-kafka-streams) +- [Guide to Java Data Objects](http://www.baeldung.com/jdo) +- [Intro to JDO Queries 2/2](http://www.baeldung.com/jdo-queries) +- [Introduction to HikariCP](http://www.baeldung.com/hikaricp) +- [Introduction to JCache](http://www.baeldung.com/jcache) diff --git a/libraries-data/log4j.properties b/libraries-data/log4j.properties new file mode 100644 index 0000000000..2173c5d96f --- /dev/null +++ b/libraries-data/log4j.properties @@ -0,0 +1 @@ +log4j.rootLogger=INFO, stdout diff --git a/libraries-data/myPersistence.xml b/libraries-data/myPersistence.xml new file mode 100644 index 0000000000..de2c250957 --- /dev/null +++ b/libraries-data/myPersistence.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index 55bf02ae16..6ea80f1c1f 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -85,6 +85,55 @@ gson ${gson.version} + + + com.zaxxer + HikariCP + 2.7.2 + compile + + + + org.datanucleus + javax.jdo + 3.2.0-m7 + + + org.datanucleus + datanucleus-core + 5.1.1 + + + org.datanucleus + datanucleus-api-jdo + 5.1.1 + + + org.datanucleus + datanucleus-rdbms + 5.1.1 + + + org.datanucleus + datanucleus-maven-plugin + 5.0.2 + + + org.datanucleus + datanucleus-xml + 5.0.0-release + + + org.datanucleus + datanucleus-jdo-query + 5.0.4 + + + + javax.cache + cache-api + ${cache.version} + @@ -184,6 +233,29 @@ + + + org.datanucleus + datanucleus-maven-plugin + 5.0.2 + + JDO + ${basedir}/datanucleus.properties + ${basedir}/log4j.properties + true + false + + + + + process-classes + + enhance + + + + + @@ -203,5 +275,6 @@ 1.0.0 2.3.0 2.8.2 + 1.0.0 \ No newline at end of file diff --git a/libraries/src/main/java/com/baeldung/hikaricp/DataSource.java b/libraries-data/src/main/java/com/baeldung/hikaricp/DataSource.java similarity index 100% rename from libraries/src/main/java/com/baeldung/hikaricp/DataSource.java rename to libraries-data/src/main/java/com/baeldung/hikaricp/DataSource.java diff --git a/libraries/src/main/java/com/baeldung/hikaricp/Employee.java b/libraries-data/src/main/java/com/baeldung/hikaricp/Employee.java similarity index 100% rename from libraries/src/main/java/com/baeldung/hikaricp/Employee.java rename to libraries-data/src/main/java/com/baeldung/hikaricp/Employee.java diff --git a/libraries/src/main/java/com/baeldung/hikaricp/HikariCPDemo.java b/libraries-data/src/main/java/com/baeldung/hikaricp/HikariCPDemo.java similarity index 100% rename from libraries/src/main/java/com/baeldung/hikaricp/HikariCPDemo.java rename to libraries-data/src/main/java/com/baeldung/hikaricp/HikariCPDemo.java diff --git a/libraries/src/main/java/com/baeldung/jcache/SimpleCacheEntryListener.java b/libraries-data/src/main/java/com/baeldung/jcache/SimpleCacheEntryListener.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jcache/SimpleCacheEntryListener.java rename to libraries-data/src/main/java/com/baeldung/jcache/SimpleCacheEntryListener.java diff --git a/libraries/src/main/java/com/baeldung/jcache/SimpleCacheLoader.java b/libraries-data/src/main/java/com/baeldung/jcache/SimpleCacheLoader.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jcache/SimpleCacheLoader.java rename to libraries-data/src/main/java/com/baeldung/jcache/SimpleCacheLoader.java diff --git a/libraries/src/main/java/com/baeldung/jcache/SimpleEntryProcessor.java b/libraries-data/src/main/java/com/baeldung/jcache/SimpleEntryProcessor.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jcache/SimpleEntryProcessor.java rename to libraries-data/src/main/java/com/baeldung/jcache/SimpleEntryProcessor.java diff --git a/libraries/src/main/java/com/baeldung/jdo/GuideToJDO.java b/libraries-data/src/main/java/com/baeldung/jdo/GuideToJDO.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jdo/GuideToJDO.java rename to libraries-data/src/main/java/com/baeldung/jdo/GuideToJDO.java diff --git a/libraries/src/main/java/com/baeldung/jdo/Product.java b/libraries-data/src/main/java/com/baeldung/jdo/Product.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jdo/Product.java rename to libraries-data/src/main/java/com/baeldung/jdo/Product.java diff --git a/libraries/src/main/java/com/baeldung/jdo/ProductXML.java b/libraries-data/src/main/java/com/baeldung/jdo/ProductXML.java similarity index 100% rename from libraries/src/main/java/com/baeldung/jdo/ProductXML.java rename to libraries-data/src/main/java/com/baeldung/jdo/ProductXML.java diff --git a/libraries/src/main/java/com/baeldung/jdo/query/MyApp.java b/libraries-data/src/main/java/com/baeldung/jdo/query/MyApp.java similarity index 97% rename from libraries/src/main/java/com/baeldung/jdo/query/MyApp.java rename to libraries-data/src/main/java/com/baeldung/jdo/query/MyApp.java index 235142d16e..30f019a79d 100644 --- a/libraries/src/main/java/com/baeldung/jdo/query/MyApp.java +++ b/libraries-data/src/main/java/com/baeldung/jdo/query/MyApp.java @@ -1,96 +1,96 @@ -package com.baeldung.jdo.query; - -import java.util.List; - -import javax.jdo.JDOQLTypedQuery; -import javax.jdo.PersistenceManager; -import javax.jdo.PersistenceManagerFactory; -import javax.jdo.Query; - -import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; -import org.datanucleus.metadata.PersistenceUnitMetaData; - -public class MyApp { - - private static PersistenceManagerFactory pmf; - private static PersistenceManager pm; - - public static void main(String[] args) { - - defineDynamicPersistentUnit(); - createTestData(); - queryUsingJDOQL(); - queryUsingTypedJDOQL(); - queryUsingSQL(); - queryUsingJPQL(); - - } - - public static void createTestData() { - ProductItem item1 = new ProductItem("supportedItem", "price less than 10", "SoldOut", 5); - ProductItem item2 = new ProductItem("pro2", "price less than 10", "InStock", 8); - ProductItem item3 = new ProductItem("pro3", "price more than 10", "SoldOut", 15); - - if (pm != null) { - pm.makePersistent(item1); - pm.makePersistent(item2); - pm.makePersistent(item3); - } - } - - public static void defineDynamicPersistentUnit() { - - PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); - pumd.addProperty("javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost:3306/jdo_db"); - pumd.addProperty("javax.jdo.option.ConnectionUserName", "root"); - pumd.addProperty("javax.jdo.option.ConnectionPassword", "admin"); - pumd.addProperty("javax.jdo.option.ConnectionDriverName", "com.mysql.jdbc.Driver"); - pumd.addProperty("datanucleus.schema.autoCreateAll", "true"); - - pmf = new JDOPersistenceManagerFactory(pumd, null); - pm = pmf.getPersistenceManager(); - } - - public static void queryUsingJDOQL() { - - Query query = pm.newQuery("SELECT FROM com.baeldung.jdo.query.ProductItem " + "WHERE price < threshold PARAMETERS double threshold"); - List explicitParamResults = (List) query.execute(10); - - query = pm.newQuery("SELECT FROM " + "com.baeldung.jdo.query.ProductItem WHERE price < :threshold"); - query.setParameters("double threshold"); - List explicitParamResults2 = (List) query.execute(10); - - query = pm.newQuery("SELECT FROM " + "com.baeldung.jdo.query.ProductItem WHERE price < :threshold"); - List implicitParamResults = (List) query.execute(10); - - } - - public static void queryUsingTypedJDOQL() { - JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(ProductItem.class); - QProductItem cand = QProductItem.candidate(); - tq = tq.filter(cand.price.lt(10).and(cand.name.startsWith("pro"))); - List results = tq.executeList(); - - } - - public static void queryUsingSQL() { - - Query query = pm.newQuery("javax.jdo.query.SQL", "select * from " + "product_item where price < ? and status = ?"); - query.setClass(ProductItem.class); - query.setParameters(10, "InStock"); - List results = query.executeList(); - - } - - public static void queryUsingJPQL() { - Query query = pm.newQuery("JPQL", "select i from " + "com.baeldung.jdo.query.ProductItem i where i.price < 10" + " and i.status = 'InStock'"); - List results = (List) query.execute(); - - } - - public static void namedQuery() { - Query query = pm.newNamedQuery(ProductItem.class, "PriceBelow10"); - List results = query.executeList(); - - } -} +package com.baeldung.jdo.query; + +import java.util.List; + +import javax.jdo.JDOQLTypedQuery; +import javax.jdo.PersistenceManager; +import javax.jdo.PersistenceManagerFactory; +import javax.jdo.Query; + +import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; +import org.datanucleus.metadata.PersistenceUnitMetaData; + +public class MyApp { + + private static PersistenceManagerFactory pmf; + private static PersistenceManager pm; + + public static void main(String[] args) { + + defineDynamicPersistentUnit(); + createTestData(); + queryUsingJDOQL(); + queryUsingTypedJDOQL(); + queryUsingSQL(); + queryUsingJPQL(); + + } + + public static void createTestData() { + ProductItem item1 = new ProductItem("supportedItem", "price less than 10", "SoldOut", 5); + ProductItem item2 = new ProductItem("pro2", "price less than 10", "InStock", 8); + ProductItem item3 = new ProductItem("pro3", "price more than 10", "SoldOut", 15); + + if (pm != null) { + pm.makePersistent(item1); + pm.makePersistent(item2); + pm.makePersistent(item3); + } + } + + public static void defineDynamicPersistentUnit() { + + PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); + pumd.addProperty("javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost:3306/jdo_db"); + pumd.addProperty("javax.jdo.option.ConnectionUserName", "root"); + pumd.addProperty("javax.jdo.option.ConnectionPassword", "admin"); + pumd.addProperty("javax.jdo.option.ConnectionDriverName", "com.mysql.jdbc.Driver"); + pumd.addProperty("datanucleus.schema.autoCreateAll", "true"); + + pmf = new JDOPersistenceManagerFactory(pumd, null); + pm = pmf.getPersistenceManager(); + } + + public static void queryUsingJDOQL() { + + Query query = pm.newQuery("SELECT FROM com.baeldung.jdo.query.ProductItem " + "WHERE price < threshold PARAMETERS double threshold"); + List explicitParamResults = (List) query.execute(10); + + query = pm.newQuery("SELECT FROM " + "com.baeldung.jdo.query.ProductItem WHERE price < :threshold"); + query.setParameters("double threshold"); + List explicitParamResults2 = (List) query.execute(10); + + query = pm.newQuery("SELECT FROM " + "com.baeldung.jdo.query.ProductItem WHERE price < :threshold"); + List implicitParamResults = (List) query.execute(10); + + } + + public static void queryUsingTypedJDOQL() { + JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(ProductItem.class); + QProductItem cand = QProductItem.candidate(); + tq = tq.filter(cand.price.lt(10).and(cand.name.startsWith("pro"))); + List results = tq.executeList(); + + } + + public static void queryUsingSQL() { + + Query query = pm.newQuery("javax.jdo.query.SQL", "select * from " + "product_item where price < ? and status = ?"); + query.setClass(ProductItem.class); + query.setParameters(10, "InStock"); + List results = query.executeList(); + + } + + public static void queryUsingJPQL() { + Query query = pm.newQuery("JPQL", "select i from " + "com.baeldung.jdo.query.ProductItem i where i.price < 10" + " and i.status = 'InStock'"); + List results = (List) query.execute(); + + } + + public static void namedQuery() { + Query query = pm.newNamedQuery(ProductItem.class, "PriceBelow10"); + List results = query.executeList(); + + } +} diff --git a/libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java b/libraries-data/src/main/java/com/baeldung/jdo/query/ProductItem.java similarity index 95% rename from libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java rename to libraries-data/src/main/java/com/baeldung/jdo/query/ProductItem.java index fbe999ba2a..25dd8bdb98 100644 --- a/libraries/src/main/java/com/baeldung/jdo/query/ProductItem.java +++ b/libraries-data/src/main/java/com/baeldung/jdo/query/ProductItem.java @@ -1,70 +1,70 @@ -package com.baeldung.jdo.query; - -import javax.jdo.annotations.IdGeneratorStrategy; -import javax.jdo.annotations.PersistenceCapable; -import javax.jdo.annotations.Persistent; -import javax.jdo.annotations.PrimaryKey; - -@PersistenceCapable(table = "product_item") -public class ProductItem { - - @PrimaryKey - @Persistent(valueStrategy = IdGeneratorStrategy.INCREMENT) - int id; - String name; - String description; - String status; - double price; - - public ProductItem() { - - } - - public ProductItem(String name, String description, String status, double price) { - this.name = name; - this.description = description; - this.status = status; - this.price = price; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public double getPrice() { - return price; - } - - public void setPrice(double price) { - this.price = price; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - -} +package com.baeldung.jdo.query; + +import javax.jdo.annotations.IdGeneratorStrategy; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.Persistent; +import javax.jdo.annotations.PrimaryKey; + +@PersistenceCapable(table = "product_item") +public class ProductItem { + + @PrimaryKey + @Persistent(valueStrategy = IdGeneratorStrategy.INCREMENT) + int id; + String name; + String description; + String status; + double price; + + public ProductItem() { + + } + + public ProductItem(String name, String description, String status, double price) { + this.name = name; + this.description = description; + this.status = status; + this.price = price; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + +} diff --git a/libraries/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java b/libraries-data/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java similarity index 96% rename from libraries/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java rename to libraries-data/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java index acfc26627a..0673ff341c 100644 --- a/libraries/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java +++ b/libraries-data/src/main/java/com/baeldung/jdo/xml/AnnotadedPerson.java @@ -1,66 +1,66 @@ -package com.baeldung.jdo.xml; - -import java.util.ArrayList; -import java.util.List; - -import javax.jdo.annotations.Element; -import javax.jdo.annotations.PersistenceCapable; -import javax.jdo.annotations.PrimaryKey; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElementWrapper; - -@PersistenceCapable(schema = "/myproduct/people", table = "person") -public class AnnotadedPerson { - @XmlAttribute - private long personNum; - - @PrimaryKey - private String firstName; - private String lastName; - - @XmlElementWrapper(name = "phone-numbers") - @XmlElement(name = "phone-number") - @Element(types = String.class) - private List phoneNumbers = new ArrayList(); - - public AnnotadedPerson(long personNum, String firstName, String lastName) { - super(); - this.personNum = personNum; - this.firstName = firstName; - this.lastName = lastName; - } - - public long getPersonNum() { - return personNum; - } - - public void setPersonNum(long personNum) { - this.personNum = personNum; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public List getPhoneNumbers() { - return phoneNumbers; - } - - public void setPhoneNumbers(List phoneNumbers) { - this.phoneNumbers = phoneNumbers; - } - -} +package com.baeldung.jdo.xml; + +import java.util.ArrayList; +import java.util.List; + +import javax.jdo.annotations.Element; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.PrimaryKey; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; + +@PersistenceCapable(schema = "/myproduct/people", table = "person") +public class AnnotadedPerson { + @XmlAttribute + private long personNum; + + @PrimaryKey + private String firstName; + private String lastName; + + @XmlElementWrapper(name = "phone-numbers") + @XmlElement(name = "phone-number") + @Element(types = String.class) + private List phoneNumbers = new ArrayList(); + + public AnnotadedPerson(long personNum, String firstName, String lastName) { + super(); + this.personNum = personNum; + this.firstName = firstName; + this.lastName = lastName; + } + + public long getPersonNum() { + return personNum; + } + + public void setPersonNum(long personNum) { + this.personNum = personNum; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List getPhoneNumbers() { + return phoneNumbers; + } + + public void setPhoneNumbers(List phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + +} diff --git a/libraries/src/main/java/com/baeldung/jdo/xml/MyApp.java b/libraries-data/src/main/java/com/baeldung/jdo/xml/MyApp.java similarity index 97% rename from libraries/src/main/java/com/baeldung/jdo/xml/MyApp.java rename to libraries-data/src/main/java/com/baeldung/jdo/xml/MyApp.java index c75d3695f7..b43b45f415 100644 --- a/libraries/src/main/java/com/baeldung/jdo/xml/MyApp.java +++ b/libraries-data/src/main/java/com/baeldung/jdo/xml/MyApp.java @@ -1,105 +1,105 @@ -package com.baeldung.jdo.xml; - -import java.util.List; - -import javax.jdo.JDOHelper; -import javax.jdo.PersistenceManager; -import javax.jdo.PersistenceManagerFactory; -import javax.jdo.Query; -import javax.jdo.Transaction; - -import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; -import org.datanucleus.metadata.PersistenceUnitMetaData; - -public class MyApp { - - private static PersistenceUnitMetaData pumd; - private static PersistenceManagerFactory pmf; - private static PersistenceManager pm; - - public static void main(String[] args) { - - // persist product object using dynamic persistence unit - defineDynamicPersistentUnit(); - Product product = new Product("id1", "Sony Discman", "A standard discman from Sony", 49.99); - persistObject(product); - closePersistenceManager(); - - // persist AnnotatedPerson object using named pmf - defineNamedPersistenceManagerFactory("XmlDatastore"); - AnnotadedPerson annotatedPerson = new AnnotadedPerson(654320, "annotated", "person"); - annotatedPerson.getPhoneNumbers().add("999999999"); - annotatedPerson.getPhoneNumbers().add("000000000"); - persistObject(annotatedPerson); - queryAnnotatedPersonsInXML(); - closePersistenceManager(); - - // persist Person object using PMF created by properties file - definePersistenceManagerFactoryUsingPropertiesFile("META-INF\\datanucleus.properties"); - Person person = new Person(654321, "bealdung", "author"); - person.getPhoneNumbers().add("123456789"); - person.getPhoneNumbers().add("987654321"); - persistObject(person); - queryPersonsInXML(); - closePersistenceManager(); - } - - public static void defineDynamicPersistentUnit() { - - PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); - pumd.addProperty("javax.jdo.option.ConnectionURL", "xml:file:myfile_dynamicPMF.xml"); - pumd.addProperty("datanucleus.schema.autoCreateAll", "true"); - pumd.addProperty("datanucleus.xml.indentSize", "4"); - - pmf = new JDOPersistenceManagerFactory(pumd, null); - pm = pmf.getPersistenceManager(); - } - - public static void defineNamedPersistenceManagerFactory(String pmfName) { - - pmf = JDOHelper.getPersistenceManagerFactory("XmlDatastore"); - pm = pmf.getPersistenceManager(); - } - - public static void definePersistenceManagerFactoryUsingPropertiesFile(String filePath) { - - pmf = JDOHelper.getPersistenceManagerFactory(filePath); - pm = pmf.getPersistenceManager(); - } - - public static void closePersistenceManager() { - - if (pm != null && !pm.isClosed()) { - pm.close(); - } - } - - public static void persistObject(Object obj) { - - Transaction tx = pm.currentTransaction(); - - try { - tx.begin(); - pm.makePersistent(obj); - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - } - } - - public static void queryPersonsInXML() { - - Query query = pm.newQuery(Person.class); - List result = query.executeList(); - System.out.println("name: " + result.get(0).getFirstName()); - } - - public static void queryAnnotatedPersonsInXML() { - - Query query = pm.newQuery(AnnotadedPerson.class); - List result = query.executeList(); - System.out.println("name: " + result.get(0).getFirstName()); - } -} +package com.baeldung.jdo.xml; + +import java.util.List; + +import javax.jdo.JDOHelper; +import javax.jdo.PersistenceManager; +import javax.jdo.PersistenceManagerFactory; +import javax.jdo.Query; +import javax.jdo.Transaction; + +import org.datanucleus.api.jdo.JDOPersistenceManagerFactory; +import org.datanucleus.metadata.PersistenceUnitMetaData; + +public class MyApp { + + private static PersistenceUnitMetaData pumd; + private static PersistenceManagerFactory pmf; + private static PersistenceManager pm; + + public static void main(String[] args) { + + // persist product object using dynamic persistence unit + defineDynamicPersistentUnit(); + Product product = new Product("id1", "Sony Discman", "A standard discman from Sony", 49.99); + persistObject(product); + closePersistenceManager(); + + // persist AnnotatedPerson object using named pmf + defineNamedPersistenceManagerFactory("XmlDatastore"); + AnnotadedPerson annotatedPerson = new AnnotadedPerson(654320, "annotated", "person"); + annotatedPerson.getPhoneNumbers().add("999999999"); + annotatedPerson.getPhoneNumbers().add("000000000"); + persistObject(annotatedPerson); + queryAnnotatedPersonsInXML(); + closePersistenceManager(); + + // persist Person object using PMF created by properties file + definePersistenceManagerFactoryUsingPropertiesFile("META-INF\\datanucleus.properties"); + Person person = new Person(654321, "bealdung", "author"); + person.getPhoneNumbers().add("123456789"); + person.getPhoneNumbers().add("987654321"); + persistObject(person); + queryPersonsInXML(); + closePersistenceManager(); + } + + public static void defineDynamicPersistentUnit() { + + PersistenceUnitMetaData pumd = new PersistenceUnitMetaData("dynamic-unit", "RESOURCE_LOCAL", null); + pumd.addProperty("javax.jdo.option.ConnectionURL", "xml:file:myfile_dynamicPMF.xml"); + pumd.addProperty("datanucleus.schema.autoCreateAll", "true"); + pumd.addProperty("datanucleus.xml.indentSize", "4"); + + pmf = new JDOPersistenceManagerFactory(pumd, null); + pm = pmf.getPersistenceManager(); + } + + public static void defineNamedPersistenceManagerFactory(String pmfName) { + + pmf = JDOHelper.getPersistenceManagerFactory("XmlDatastore"); + pm = pmf.getPersistenceManager(); + } + + public static void definePersistenceManagerFactoryUsingPropertiesFile(String filePath) { + + pmf = JDOHelper.getPersistenceManagerFactory(filePath); + pm = pmf.getPersistenceManager(); + } + + public static void closePersistenceManager() { + + if (pm != null && !pm.isClosed()) { + pm.close(); + } + } + + public static void persistObject(Object obj) { + + Transaction tx = pm.currentTransaction(); + + try { + tx.begin(); + pm.makePersistent(obj); + tx.commit(); + } finally { + if (tx.isActive()) { + tx.rollback(); + } + } + } + + public static void queryPersonsInXML() { + + Query query = pm.newQuery(Person.class); + List result = query.executeList(); + System.out.println("name: " + result.get(0).getFirstName()); + } + + public static void queryAnnotatedPersonsInXML() { + + Query query = pm.newQuery(AnnotadedPerson.class); + List result = query.executeList(); + System.out.println("name: " + result.get(0).getFirstName()); + } +} diff --git a/libraries/src/main/java/com/baeldung/jdo/xml/Person.java b/libraries-data/src/main/java/com/baeldung/jdo/xml/Person.java similarity index 95% rename from libraries/src/main/java/com/baeldung/jdo/xml/Person.java rename to libraries-data/src/main/java/com/baeldung/jdo/xml/Person.java index 0678201afd..4fbc81ee03 100644 --- a/libraries/src/main/java/com/baeldung/jdo/xml/Person.java +++ b/libraries-data/src/main/java/com/baeldung/jdo/xml/Person.java @@ -1,58 +1,58 @@ -package com.baeldung.jdo.xml; - -import java.util.ArrayList; -import java.util.List; - -import javax.jdo.annotations.PersistenceCapable; -import javax.jdo.annotations.PrimaryKey; - -@PersistenceCapable -public class Person { - private long personNum; - - @PrimaryKey - private String firstName; - private String lastName; - - private List phoneNumbers = new ArrayList(); - - public Person(long personNum, String firstName, String lastName) { - super(); - this.personNum = personNum; - this.firstName = firstName; - this.lastName = lastName; - } - - public long getPersonNum() { - return personNum; - } - - public void setPersonNum(long personNum) { - this.personNum = personNum; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public List getPhoneNumbers() { - return phoneNumbers; - } - - public void setPhoneNumbers(List phoneNumbers) { - this.phoneNumbers = phoneNumbers; - } - -} +package com.baeldung.jdo.xml; + +import java.util.ArrayList; +import java.util.List; + +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.PrimaryKey; + +@PersistenceCapable +public class Person { + private long personNum; + + @PrimaryKey + private String firstName; + private String lastName; + + private List phoneNumbers = new ArrayList(); + + public Person(long personNum, String firstName, String lastName) { + super(); + this.personNum = personNum; + this.firstName = firstName; + this.lastName = lastName; + } + + public long getPersonNum() { + return personNum; + } + + public void setPersonNum(long personNum) { + this.personNum = personNum; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List getPhoneNumbers() { + return phoneNumbers; + } + + public void setPhoneNumbers(List phoneNumbers) { + this.phoneNumbers = phoneNumbers; + } + +} diff --git a/libraries/src/main/java/com/baeldung/jdo/xml/Product.java b/libraries-data/src/main/java/com/baeldung/jdo/xml/Product.java similarity index 94% rename from libraries/src/main/java/com/baeldung/jdo/xml/Product.java rename to libraries-data/src/main/java/com/baeldung/jdo/xml/Product.java index 1e46f212cb..5aac05834d 100644 --- a/libraries/src/main/java/com/baeldung/jdo/xml/Product.java +++ b/libraries-data/src/main/java/com/baeldung/jdo/xml/Product.java @@ -1,58 +1,58 @@ -package com.baeldung.jdo.xml; - -import javax.jdo.annotations.PersistenceCapable; -import javax.jdo.annotations.PrimaryKey; - -@PersistenceCapable -public class Product { - - @PrimaryKey - String id; - String name; - String description; - double price; - - public Product() { - - } - - public Product(String id, String name, String description, double price) { - this.id = id; - this.name = name; - this.description = description; - this.price = price; - } - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public double getPrice() { - return price; - } - - public void setPrice(double price) { - this.price = price; - } - -} +package com.baeldung.jdo.xml; + +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.PrimaryKey; + +@PersistenceCapable +public class Product { + + @PrimaryKey + String id; + String name; + String description; + double price; + + public Product() { + + } + + public Product(String id, String name, String description, double price) { + this.id = id; + this.name = name; + this.description = description; + this.price = price; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + +} diff --git a/libraries-data/src/main/resources/META-INF/BenchmarkList b/libraries-data/src/main/resources/META-INF/BenchmarkList new file mode 100644 index 0000000000..e69de29bb2 diff --git a/libraries-data/src/main/resources/META-INF/datanucleus.properties b/libraries-data/src/main/resources/META-INF/datanucleus.properties new file mode 100644 index 0000000000..7470a58d23 --- /dev/null +++ b/libraries-data/src/main/resources/META-INF/datanucleus.properties @@ -0,0 +1,4 @@ +javax.jdo.PersistenceManagerFactoryClass=org.datanucleus.api.jdo.JDOPersistenceManagerFactory +javax.jdo.option.ConnectionURL= xml:file:myfile-ds.xml +datanucleus.xml.indentSize=6 +datanucleus.schema.autoCreateAll=true \ No newline at end of file diff --git a/libraries/src/main/resources/META-INF/jdoconfig.xml b/libraries-data/src/main/resources/META-INF/jdoconfig.xml similarity index 96% rename from libraries/src/main/resources/META-INF/jdoconfig.xml rename to libraries-data/src/main/resources/META-INF/jdoconfig.xml index 77da460686..910f63cb9a 100644 --- a/libraries/src/main/resources/META-INF/jdoconfig.xml +++ b/libraries-data/src/main/resources/META-INF/jdoconfig.xml @@ -1,17 +1,17 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/libraries/src/main/resources/META-INF/package.jdo b/libraries-data/src/main/resources/META-INF/package.jdo similarity index 97% rename from libraries/src/main/resources/META-INF/package.jdo rename to libraries-data/src/main/resources/META-INF/package.jdo index d3cf501bb6..7f85bbbd58 100644 --- a/libraries/src/main/resources/META-INF/package.jdo +++ b/libraries-data/src/main/resources/META-INF/package.jdo @@ -1,29 +1,29 @@ - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/src/main/resources/db.sql b/libraries-data/src/main/resources/db.sql similarity index 100% rename from libraries/src/main/resources/db.sql rename to libraries-data/src/main/resources/db.sql diff --git a/libraries/src/test/java/com/baeldung/hikaricp/HikariCPIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/hikaricp/HikariCPIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/hikaricp/HikariCPIntegrationTest.java rename to libraries-data/src/test/java/com/baeldung/hikaricp/HikariCPIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/jcache/CacheLoaderTest.java b/libraries-data/src/test/java/com/baeldung/jcache/CacheLoaderTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/jcache/CacheLoaderTest.java rename to libraries-data/src/test/java/com/baeldung/jcache/CacheLoaderTest.java diff --git a/libraries/src/test/java/com/baeldung/jcache/EntryProcessorIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/jcache/EntryProcessorIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/jcache/EntryProcessorIntegrationTest.java rename to libraries-data/src/test/java/com/baeldung/jcache/EntryProcessorIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/jcache/EventListenerIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/jcache/EventListenerIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/jcache/EventListenerIntegrationTest.java rename to libraries-data/src/test/java/com/baeldung/jcache/EventListenerIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/jcache/JCacheIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/jcache/JCacheIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/jcache/JCacheIntegrationTest.java rename to libraries-data/src/test/java/com/baeldung/jcache/JCacheIntegrationTest.java diff --git a/libraries/src/test/java/com/baeldung/jdo/GuideToJDOIntegrationTest.java b/libraries-data/src/test/java/com/baeldung/jdo/GuideToJDOIntegrationTest.java similarity index 100% rename from libraries/src/test/java/com/baeldung/jdo/GuideToJDOIntegrationTest.java rename to libraries-data/src/test/java/com/baeldung/jdo/GuideToJDOIntegrationTest.java diff --git a/libraries/README.md b/libraries/README.md index 7c06aa88ca..ace2000d8d 100644 --- a/libraries/README.md +++ b/libraries/README.md @@ -17,9 +17,7 @@ - [Introduction to Quartz](http://www.baeldung.com/quartz) - [How to Warm Up the JVM](http://www.baeldung.com/java-jvm-warmup) - [Apache Commons Collections SetUtils](http://www.baeldung.com/apache-commons-setutils) -- [Guide to Java Data Objects](http://www.baeldung.com/jdo) - [Software Transactional Memory in Java Using Multiverse](http://www.baeldung.com/java-multiverse-stm) -- [Introduction to HikariCP](http://www.baeldung.com/hikaricp) - [Serenity BDD with Spring and JBehave](http://www.baeldung.com/serenity-spring-jbehave) - [Locality-Sensitive Hashing in Java Using Java-LSH](http://www.baeldung.com/locality-sensitive-hashing) - [Apache Commons Collections OrderedMap](http://www.baeldung.com/apache-commons-ordered-map) @@ -47,7 +45,6 @@ - [Guide to JDeferred](http://www.baeldung.com/jdeferred) - [Integrating Retrofit with RxJava](http://www.baeldung.com/retrofit-rxjava) - [Introduction to MBassador](http://www.baeldung.com/mbassador) -- [Introduction to JCache](http://www.baeldung.com/jcache) - [Introduction to Retrofit](http://www.baeldung.com/retrofit) - [Using Pairs in Java](http://www.baeldung.com/java-pairs) - [Apache Commons Collections Bag](http://www.baeldung.com/apache-commons-bag) @@ -56,7 +53,6 @@ - [Introduction To Docx4J](http://www.baeldung.com/docx4j) - [Introduction to StreamEx](http://www.baeldung.com/streamex) - [Introduction to BouncyCastle with Java](http://www.baeldung.com/java-bouncy-castle) -- [Intro to JDO Queries 2/2](http://www.baeldung.com/jdo-queries) - [Guide to google-http-client](http://www.baeldung.com/google-http-client) - [Interact with Google Sheets from Java](http://www.baeldung.com/google-sheets-java-client) - [Programatically Create, Configure, and Run a Tomcat Server] (http://www.baeldung.com/tomcat-programmatic-setup) From 9a496e0d258c8d125ee6b62da8bdc69fbe75eab4 Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Thu, 3 May 2018 12:13:12 +0400 Subject: [PATCH 06/93] Composite design pattern --- .../composite/CompositeDemo.java | 11 ++++++ .../designpatterns/composite/Department.java | 9 +++++ .../composite/FinancialDepartment.java | 35 +++++++++++++++++++ .../composite/GeneralDepartment.java | 33 +++++++++++++++++ .../composite/SalesDepartment.java | 35 +++++++++++++++++++ 5 files changed, 123 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java create mode 100644 core-java/src/main/java/com/baeldung/designpatterns/composite/Department.java create mode 100644 core-java/src/main/java/com/baeldung/designpatterns/composite/FinancialDepartment.java create mode 100644 core-java/src/main/java/com/baeldung/designpatterns/composite/GeneralDepartment.java create mode 100644 core-java/src/main/java/com/baeldung/designpatterns/composite/SalesDepartment.java diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java b/core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java new file mode 100644 index 0000000000..83024b7d21 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java @@ -0,0 +1,11 @@ +package com.baeldung.designpatterns.composite; + +/** + * Created by Gebruiker on 5/3/2018. + */ +public class CompositeDemo { + + public static void main(String args[]) { + Department salesDepartment = new SalesDepartment(); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/Department.java b/core-java/src/main/java/com/baeldung/designpatterns/composite/Department.java new file mode 100644 index 0000000000..82fa3a3efc --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/composite/Department.java @@ -0,0 +1,9 @@ +package com.baeldung.designpatterns.composite; + +/** + * Created by Gebruiker on 5/1/2018. + */ +public interface Department { + + void printDepartmentName(); +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/FinancialDepartment.java b/core-java/src/main/java/com/baeldung/designpatterns/composite/FinancialDepartment.java new file mode 100644 index 0000000000..dc5a2bb9d9 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/composite/FinancialDepartment.java @@ -0,0 +1,35 @@ +package com.baeldung.designpatterns.composite; + +/** + * Created by Gebruiker on 5/1/2018. + */ +public class FinancialDepartment implements Department { + + private Integer id; + private String name; + + public FinancialDepartment(Integer id, String name) { + this.id = id; + this.name = name; + } + + public void printDepartmentName() { + System.out.println(getClass().getSimpleName()); + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/GeneralDepartment.java b/core-java/src/main/java/com/baeldung/designpatterns/composite/GeneralDepartment.java new file mode 100644 index 0000000000..15c5bc9494 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/composite/GeneralDepartment.java @@ -0,0 +1,33 @@ +package com.baeldung.designpatterns.composite; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Gebruiker on 5/1/2018. + */ +public class GeneralDepartment implements Department { + + private Integer id; + private String name; + + private List childDepartments; + + public GeneralDepartment(Integer id, String name) { + this.id = id; + this.name = name; + this.childDepartments = new ArrayList(); + } + + public void printDepartmentName() { + childDepartments.stream().forEach(Department::printDepartmentName); + } + + public void addDepartMent(Department department) { + childDepartments.add(department); + } + + public void removeDepartment(Department department) { + childDepartments.remove(department); + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/SalesDepartment.java b/core-java/src/main/java/com/baeldung/designpatterns/composite/SalesDepartment.java new file mode 100644 index 0000000000..af234b4915 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/designpatterns/composite/SalesDepartment.java @@ -0,0 +1,35 @@ +package com.baeldung.designpatterns.composite; + +/** + * Created by Gebruiker on 5/1/2018. + */ +public class SalesDepartment implements Department { + + private Integer id; + private String name; + + public SalesDepartment(Integer id, String name) { + this.id = id; + this.name = name; + } + + public void printDepartmentName() { + System.out.println(getClass().getSimpleName()); + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} From ef481d19ee865911ed5ec5c9423c79d9242e4631 Mon Sep 17 00:00:00 2001 From: Erdem Date: Thu, 3 May 2018 22:02:16 +0300 Subject: [PATCH 07/93] BAEL-1746 added property editor implementation --- .../baeldung/propertyeditor/CreditCard.java | 41 +++++++++++++++++++ .../propertyeditor/CreditCardEditor.java | 39 ++++++++++++++++++ .../CreditCardRestController.java | 17 ++++++++ .../PropertyEditorApplication.java | 12 ++++++ .../propertyeditor/CreditCardEditorTest.java | 41 +++++++++++++++++++ 5 files changed, 150 insertions(+) create mode 100644 spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCard.java create mode 100644 spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardEditor.java create mode 100644 spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardRestController.java create mode 100644 spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorApplication.java create mode 100644 spring-rest/src/test/java/com/baeldung/propertyeditor/CreditCardEditorTest.java diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCard.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCard.java new file mode 100644 index 0000000000..2b1fbb9b6c --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCard.java @@ -0,0 +1,41 @@ +package com.baeldung.propertyeditor; + +public class CreditCard { + + private String rawCardNumber; + + private Integer bankIdNo; + + private Integer accountNo; + + private Integer checkCode; + + public String getRawCardNumber() { + return rawCardNumber; + } + public void setRawCardNumber(String rawCardNumber) { + this.rawCardNumber = rawCardNumber; + } + + public Integer getBankIdNo() { + return bankIdNo; + } + public void setBankIdNo(Integer bankIdNo) { + this.bankIdNo = bankIdNo; + } + + public Integer getAccountNo() { + return accountNo; + } + public void setAccountNo(Integer accountNo) { + this.accountNo = accountNo; + } + + public Integer getCheckCode() { + return checkCode; + } + public void setCheckCode(Integer checkCode) { + this.checkCode = checkCode; + } + +} diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardEditor.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardEditor.java new file mode 100644 index 0000000000..4b1374a76a --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardEditor.java @@ -0,0 +1,39 @@ +package com.baeldung.propertyeditor; + +import java.beans.PropertyEditorSupport; + +import org.springframework.util.StringUtils; + +public class CreditCardEditor extends PropertyEditorSupport { + + @Override + public String getAsText() { + CreditCard creditCard = (CreditCard) getValue(); + + return creditCard == null ? "" : creditCard.getRawCardNumber(); + } + + @Override + public void setAsText(String text) throws IllegalArgumentException { + if (StringUtils.isEmpty(text)) { + setValue(null); + } else { + CreditCard creditCard = new CreditCard(); + creditCard.setRawCardNumber(text); + + String cardNo = text.replaceAll("-", ""); + if (cardNo.length() != 16) + throw new IllegalArgumentException("Credit card format should be xxxx-xxxx-xxxx-xxxx"); + + try { + creditCard.setBankIdNo( Integer.valueOf(cardNo.substring(0, 6)) ); + creditCard.setAccountNo( Integer.valueOf(cardNo.substring(6, cardNo.length() - 1)) ); + creditCard.setCheckCode( Integer.valueOf(cardNo.substring(cardNo.length() - 1)) ); + } catch (NumberFormatException nfe) { + throw new IllegalArgumentException(nfe); + } + + setValue(creditCard); + } + } +} diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardRestController.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardRestController.java new file mode 100644 index 0000000000..bf8e0586f8 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardRestController.java @@ -0,0 +1,17 @@ +package com.baeldung.propertyeditor; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(value = "/credit-card") +public class CreditCardRestController { + + @GetMapping(value = "/parse/{card-no}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public CreditCard parseCreditCardNumber(@PathVariable("card-no") CreditCard creditCard) { + return creditCard; + } +} diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorApplication.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorApplication.java new file mode 100644 index 0000000000..b0d75cd072 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.propertyeditor; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class PropertyEditorApplication { + + public static void main(String[] args) { + SpringApplication.run(PropertyEditorApplication.class, args); + } +} diff --git a/spring-rest/src/test/java/com/baeldung/propertyeditor/CreditCardEditorTest.java b/spring-rest/src/test/java/com/baeldung/propertyeditor/CreditCardEditorTest.java new file mode 100644 index 0000000000..b7da905f13 --- /dev/null +++ b/spring-rest/src/test/java/com/baeldung/propertyeditor/CreditCardEditorTest.java @@ -0,0 +1,41 @@ +package com.baeldung.propertyeditor; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class CreditCardEditorTest { + + private CreditCardEditor creditCardEditor; + + @Before + public void setup() { + creditCardEditor = new CreditCardEditor(); + } + + @Test(expected=IllegalArgumentException.class) + public void whenInvalidCardNoWithLessDigits_thenThrowsException() { + creditCardEditor.setAsText("123-123-123-123"); + } + + @Test(expected=IllegalArgumentException.class) + public void whenInvalidCardNoWithNonDigits_thenThrowsException() { + creditCardEditor.setAsText("1234-1234-xxxx-yyyy"); + } + + @Test + public void whenCardNoWithNonDigits_parseCreditCard() { + creditCardEditor.setAsText("1234-5678-9123-4560"); + + CreditCard creditCard = (CreditCard) creditCardEditor.getValue(); + Assert.assertNotNull(creditCard); + + Assert.assertEquals(123456, creditCard.getBankIdNo().intValue()); + Assert.assertEquals(789123456, creditCard.getAccountNo().intValue()); + Assert.assertEquals(0, creditCard.getCheckCode().intValue()); + } + +} From 043f6bade7aea7004907e2495b945b23dd7c9381 Mon Sep 17 00:00:00 2001 From: Erdem Date: Thu, 3 May 2018 23:27:12 +0300 Subject: [PATCH 08/93] BAEL-1746 added custom property editor implementation --- .../CreditCardRestController.java | 17 ---------- .../PropertyEditorApplication.java | 6 ++-- .../PropertyEditorRestController.java | 34 +++++++++++++++++++ .../{ => creditcard}/CreditCard.java | 2 +- .../{ => creditcard}/CreditCardEditor.java | 2 +- .../editor/CustomExoticTypeEditor.java | 23 +++++++++++++ .../exotictype/model/ExoticType.java | 14 ++++++++ .../src/main/resources/application.properties | 2 +- .../CreditCardEditorTest.java | 5 ++- 9 files changed, 81 insertions(+), 24 deletions(-) delete mode 100644 spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardRestController.java create mode 100644 spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java rename spring-rest/src/main/java/com/baeldung/propertyeditor/{ => creditcard}/CreditCard.java (94%) rename spring-rest/src/main/java/com/baeldung/propertyeditor/{ => creditcard}/CreditCardEditor.java (96%) create mode 100644 spring-rest/src/main/java/com/baeldung/propertyeditor/exotictype/editor/CustomExoticTypeEditor.java create mode 100644 spring-rest/src/main/java/com/baeldung/propertyeditor/exotictype/model/ExoticType.java rename spring-rest/src/test/java/com/baeldung/propertyeditor/{ => creditcard}/CreditCardEditorTest.java (88%) diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardRestController.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardRestController.java deleted file mode 100644 index bf8e0586f8..0000000000 --- a/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardRestController.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung.propertyeditor; - -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping(value = "/credit-card") -public class CreditCardRestController { - - @GetMapping(value = "/parse/{card-no}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) - public CreditCard parseCreditCardNumber(@PathVariable("card-no") CreditCard creditCard) { - return creditCard; - } -} diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorApplication.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorApplication.java index b0d75cd072..f98648c6b2 100644 --- a/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorApplication.java +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorApplication.java @@ -6,7 +6,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class PropertyEditorApplication { - public static void main(String[] args) { - SpringApplication.run(PropertyEditorApplication.class, args); - } + public static void main(String[] args) { + SpringApplication.run(PropertyEditorApplication.class, args); + } } diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java new file mode 100644 index 0000000000..24f1b33471 --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java @@ -0,0 +1,34 @@ +package com.baeldung.propertyeditor; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.InitBinder; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.propertyeditor.creditcard.CreditCard; +import com.baeldung.propertyeditor.exotictype.editor.CustomExoticTypeEditor; +import com.baeldung.propertyeditor.exotictype.model.ExoticType; + +@RestController +@RequestMapping(value = "/property-editor") +public class PropertyEditorRestController { + + @GetMapping(value = "/credit-card/{card-no}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public CreditCard parseCreditCardNumber(@PathVariable("card-no") CreditCard creditCard) { + return creditCard; + } + + @GetMapping(value = "/exotic-type/{value}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public ExoticType parseCreditCardNumber(@PathVariable("value") ExoticType exoticType) { + return exoticType; + } + + @InitBinder + public void initBinder(WebDataBinder binder) { + binder.registerCustomEditor(ExoticType.class, new CustomExoticTypeEditor()); + } + +} diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCard.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCard.java similarity index 94% rename from spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCard.java rename to spring-rest/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCard.java index 2b1fbb9b6c..f3adfb5d9f 100644 --- a/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCard.java +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCard.java @@ -1,4 +1,4 @@ -package com.baeldung.propertyeditor; +package com.baeldung.propertyeditor.creditcard; public class CreditCard { diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardEditor.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCardEditor.java similarity index 96% rename from spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardEditor.java rename to spring-rest/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCardEditor.java index 4b1374a76a..d413afee85 100644 --- a/spring-rest/src/main/java/com/baeldung/propertyeditor/CreditCardEditor.java +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/creditcard/CreditCardEditor.java @@ -1,4 +1,4 @@ -package com.baeldung.propertyeditor; +package com.baeldung.propertyeditor.creditcard; import java.beans.PropertyEditorSupport; diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/exotictype/editor/CustomExoticTypeEditor.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/exotictype/editor/CustomExoticTypeEditor.java new file mode 100644 index 0000000000..08dbceae3d --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/exotictype/editor/CustomExoticTypeEditor.java @@ -0,0 +1,23 @@ +package com.baeldung.propertyeditor.exotictype.editor; + +import java.beans.PropertyEditorSupport; + +import com.baeldung.propertyeditor.exotictype.model.ExoticType; + +public class CustomExoticTypeEditor extends PropertyEditorSupport { + + @Override + public String getAsText() { + ExoticType exoticType = (ExoticType) getValue(); + + return exoticType == null ? "" : exoticType.getName(); + } + + @Override + public void setAsText(String text) throws IllegalArgumentException { + ExoticType exoticType = new ExoticType(); + exoticType.setName(text.toUpperCase()); + + setValue(exoticType); + } +} diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/exotictype/model/ExoticType.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/exotictype/model/ExoticType.java new file mode 100644 index 0000000000..95ba95643d --- /dev/null +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/exotictype/model/ExoticType.java @@ -0,0 +1,14 @@ +package com.baeldung.propertyeditor.exotictype.model; + +public class ExoticType { + + private String name; + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + +} diff --git a/spring-rest/src/main/resources/application.properties b/spring-rest/src/main/resources/application.properties index 300589f561..c4722f3c36 100644 --- a/spring-rest/src/main/resources/application.properties +++ b/spring-rest/src/main/resources/application.properties @@ -1,2 +1,2 @@ -server.port= 8082 +server.port= 8080 server.context-path=/spring-rest \ No newline at end of file diff --git a/spring-rest/src/test/java/com/baeldung/propertyeditor/CreditCardEditorTest.java b/spring-rest/src/test/java/com/baeldung/propertyeditor/creditcard/CreditCardEditorTest.java similarity index 88% rename from spring-rest/src/test/java/com/baeldung/propertyeditor/CreditCardEditorTest.java rename to spring-rest/src/test/java/com/baeldung/propertyeditor/creditcard/CreditCardEditorTest.java index b7da905f13..e87adbc712 100644 --- a/spring-rest/src/test/java/com/baeldung/propertyeditor/CreditCardEditorTest.java +++ b/spring-rest/src/test/java/com/baeldung/propertyeditor/creditcard/CreditCardEditorTest.java @@ -1,4 +1,4 @@ -package com.baeldung.propertyeditor; +package com.baeldung.propertyeditor.creditcard; import org.junit.Assert; import org.junit.Before; @@ -6,6 +6,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; +import com.baeldung.propertyeditor.creditcard.CreditCard; +import com.baeldung.propertyeditor.creditcard.CreditCardEditor; + @RunWith(MockitoJUnitRunner.class) public class CreditCardEditorTest { From 1fe62a811cd311c2fd1c5153114dd090cba6e473 Mon Sep 17 00:00:00 2001 From: Erdem Date: Fri, 4 May 2018 00:26:37 +0300 Subject: [PATCH 09/93] BAEL-1746 added custom property editor implementation --- .../propertyeditor/PropertyEditorRestController.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java b/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java index 24f1b33471..02edc96cf6 100644 --- a/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java +++ b/spring-rest/src/main/java/com/baeldung/propertyeditor/PropertyEditorRestController.java @@ -16,13 +16,15 @@ import com.baeldung.propertyeditor.exotictype.model.ExoticType; @RequestMapping(value = "/property-editor") public class PropertyEditorRestController { - @GetMapping(value = "/credit-card/{card-no}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @GetMapping(value = "/credit-card/{card-no}", + produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public CreditCard parseCreditCardNumber(@PathVariable("card-no") CreditCard creditCard) { return creditCard; } - @GetMapping(value = "/exotic-type/{value}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) - public ExoticType parseCreditCardNumber(@PathVariable("value") ExoticType exoticType) { + @GetMapping(value = "/exotic-type/{value}", + produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + public ExoticType parseExoticType(@PathVariable("value") ExoticType exoticType) { return exoticType; } From c8b44cc141a0db743e52f19c87995b349e65ef11 Mon Sep 17 00:00:00 2001 From: Erdem Date: Fri, 4 May 2018 00:53:01 +0300 Subject: [PATCH 10/93] remove weblux files --- .../com/baeldung/reactive/webflux/Event.java | 13 ------ .../webflux/EventStreamController.java | 20 --------- .../webflux/WebfluxDemoApplication.java | 12 ----- .../static/webflux/client-event-stream.html | 45 ------------------- 4 files changed, 90 deletions(-) delete mode 100644 spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/Event.java delete mode 100644 spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java delete mode 100644 spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/WebfluxDemoApplication.java delete mode 100644 spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/Event.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/Event.java deleted file mode 100644 index 03e80e915e..0000000000 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/Event.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.baeldung.reactive.webflux; - -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -public class Event { - - private Long id; - private String body; - -} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java deleted file mode 100644 index f3d10437e2..0000000000 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/EventStreamController.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.baeldung.reactive.webflux; - -import java.time.Duration; - -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import reactor.core.publisher.Flux; - -@RestController -public class EventStreamController { - - @GetMapping(value = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE) - public Flux getEvents() { - return Flux.interval(Duration.ofMillis(1000)) - .map(tick -> new Event(tick, "This is Event #" + tick)); - } - -} diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/WebfluxDemoApplication.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/WebfluxDemoApplication.java deleted file mode 100644 index 70cad0ad22..0000000000 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/webflux/WebfluxDemoApplication.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.reactive.webflux; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class WebfluxDemoApplication { - - public static void main(String[] args) { - SpringApplication.run(WebfluxDemoApplication.class, args); - } -} diff --git a/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html b/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html deleted file mode 100644 index e44cbf0746..0000000000 --- a/spring-5-reactive/src/main/resources/static/webflux/client-event-stream.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - Baeldung: Spring 5 Reactive Webflux - real time event streaming - - - - - - -

Events streamed...

- - - - - - - - - -
Event IdEvent Body
- - - - - \ No newline at end of file From 8d8010cd2e36f51115f4705127f6dd33fa43ac31 Mon Sep 17 00:00:00 2001 From: Erdem Date: Fri, 4 May 2018 00:53:57 +0300 Subject: [PATCH 11/93] remove weblux files --- spring-5-reactive/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-5-reactive/pom.xml b/spring-5-reactive/pom.xml index 324fb13dd2..96378c60de 100644 --- a/spring-5-reactive/pom.xml +++ b/spring-5-reactive/pom.xml @@ -13,7 +13,7 @@ org.springframework.boot spring-boot-starter-parent - 2.0.1.RELEASE + 2.0.0.RELEASE From 88e49ebda5d44713bc23bcd872eac147afe163a6 Mon Sep 17 00:00:00 2001 From: Tom Hombergs Date: Fri, 4 May 2018 20:53:53 +0200 Subject: [PATCH 12/93] added article link --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index 8a94c9de8e..b40298abe4 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -146,3 +146,4 @@ - [Introduction to SSL in Java](http://www.baeldung.com/java-ssl) - [Java KeyStore API](http://www.baeldung.com/java-keystore) - [Double-Checked Locking with Singleton](http://www.baeldung.com/java-singleton-double-checked-locking) +- [Guide to Java Clock Class](http://www.baeldung.com/java-clock) From 4ad804252205ef5b0e6a0e60d4302a087917eceb Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Sat, 5 May 2018 10:26:51 +0400 Subject: [PATCH 13/93] test the results --- .../designpatterns/composite/CompositeDemo.java | 10 +++++++++- .../{GeneralDepartment.java => HeadDepartment.java} | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) rename core-java/src/main/java/com/baeldung/designpatterns/composite/{GeneralDepartment.java => HeadDepartment.java} (86%) diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java b/core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java index 83024b7d21..9537dd0d2b 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java @@ -6,6 +6,14 @@ package com.baeldung.designpatterns.composite; public class CompositeDemo { public static void main(String args[]) { - Department salesDepartment = new SalesDepartment(); + Department salesDepartment = new SalesDepartment(1, "Sales department"); + Department financialDepartment = new FinancialDepartment(2, "Financial department"); + + HeadDepartment headDepartment = new HeadDepartment(3, "Head department"); + + headDepartment.addDepartMent(salesDepartment); + headDepartment.addDepartMent(financialDepartment); + + headDepartment.printDepartmentName(); } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/GeneralDepartment.java b/core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java similarity index 86% rename from core-java/src/main/java/com/baeldung/designpatterns/composite/GeneralDepartment.java rename to core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java index 15c5bc9494..8854fce5b3 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/composite/GeneralDepartment.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java @@ -6,14 +6,14 @@ import java.util.List; /** * Created by Gebruiker on 5/1/2018. */ -public class GeneralDepartment implements Department { +public class HeadDepartment implements Department { private Integer id; private String name; private List childDepartments; - public GeneralDepartment(Integer id, String name) { + public HeadDepartment(Integer id, String name) { this.id = id; this.name = name; this.childDepartments = new ArrayList(); From 0128224acc21d3460f72745bde3d15f9cea04b35 Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Sun, 6 May 2018 22:44:11 +0400 Subject: [PATCH 14/93] add instance variable hiding class --- .../scope/method/MethodHidingDemo.java | 10 ++++++++ .../baeldung/scope/variable/HideVariable.java | 23 +++++++++++++++++++ .../scope/variable/VariableHidingDemo.java | 12 ++++++++++ 3 files changed, 45 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/scope/method/MethodHidingDemo.java create mode 100644 core-java/src/main/java/com/baeldung/scope/variable/HideVariable.java create mode 100644 core-java/src/main/java/com/baeldung/scope/variable/VariableHidingDemo.java diff --git a/core-java/src/main/java/com/baeldung/scope/method/MethodHidingDemo.java b/core-java/src/main/java/com/baeldung/scope/method/MethodHidingDemo.java new file mode 100644 index 0000000000..26f27a0bc2 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/scope/method/MethodHidingDemo.java @@ -0,0 +1,10 @@ +package com.baeldung.scope.method; + +/** + * Created by Gebruiker on 5/6/2018. + */ +public class MethodHidingDemo { + public static void main(String[] args) { + + } +} diff --git a/core-java/src/main/java/com/baeldung/scope/variable/HideVariable.java b/core-java/src/main/java/com/baeldung/scope/variable/HideVariable.java new file mode 100644 index 0000000000..32251f2d37 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/scope/variable/HideVariable.java @@ -0,0 +1,23 @@ +package com.baeldung.scope.variable; + +/** + * Created by Gebruiker on 5/6/2018. + */ +public class HideVariable { + + private String instanceVariable = "this is instance variable"; + + HideVariable() { + instanceVariable = "constructor local variable"; + System.out.println(instanceVariable); + } + + public void printLocalVariable() { + instanceVariable = "method local variable"; + System.out.println(instanceVariable); + } + + public void printInstanceVariable() { + System.out.println(this.instanceVariable); + } +} diff --git a/core-java/src/main/java/com/baeldung/scope/variable/VariableHidingDemo.java b/core-java/src/main/java/com/baeldung/scope/variable/VariableHidingDemo.java new file mode 100644 index 0000000000..ac1e24db6d --- /dev/null +++ b/core-java/src/main/java/com/baeldung/scope/variable/VariableHidingDemo.java @@ -0,0 +1,12 @@ +package com.baeldung.scope.variable; + +/** + * Created by Gebruiker on 5/6/2018. + */ +public class VariableHidingDemo { + public static void main(String[] args) { + HideVariable variable = new HideVariable(); + variable.printLocalVariable(); + variable.printInstanceVariable(); + } +} From 88a3f6c0fe20f4a1da6e3329b3e9bf338accf5c9 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sun, 6 May 2018 23:02:49 +0300 Subject: [PATCH 15/93] replace requestmapping, update properties --- .../src/main/resources/application.properties | 2 -- spring-boot/README.MD | 1 - .../controller/UserController.java | 3 +- .../controller/FooController.java | 4 +-- .../controllers/MyErrorController.java | 4 +-- .../baeldung/git/CommitInfoController.java | 4 +-- .../intro/controller/HomeController.java | 6 ++-- .../baeldung/rss/ArticleRssController.java | 4 +-- .../WarInitializerApplication.java | 4 +-- .../com/baeldung/webjar/TestController.java | 4 +-- .../controller/GenericEntityController.java | 9 +++-- .../common/error/MyCustomErrorController.java | 4 +-- .../error/controller/ErrorController.java | 6 ++-- .../baeldung/main/SpringBootApplication.java | 4 +-- .../src/main/resources/application.properties | 36 ++++++++----------- 15 files changed, 43 insertions(+), 52 deletions(-) diff --git a/spring-boot-autoconfiguration/src/main/resources/application.properties b/spring-boot-autoconfiguration/src/main/resources/application.properties index 09df3b8f02..4456c78e5d 100644 --- a/spring-boot-autoconfiguration/src/main/resources/application.properties +++ b/spring-boot-autoconfiguration/src/main/resources/application.properties @@ -1,4 +1,2 @@ -server.port=9090 - spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto = update diff --git a/spring-boot/README.MD b/spring-boot/README.MD index 7e68e30a47..72da255b95 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -20,7 +20,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Dynamic DTO Validation Config Retrieved from DB](http://www.baeldung.com/spring-dynamic-dto-validation) - [Custom Information in Spring Boot Info Endpoint](http://www.baeldung.com/spring-boot-info-actuator-custom) - [Using @JsonComponent in Spring Boot](http://www.baeldung.com/spring-boot-jsoncomponent) -- [Create a Custom Auto-Configuration with Spring Boot](http://www.baeldung.com/spring-boot-custom-auto-configuration) - [Testing in Spring Boot](http://www.baeldung.com/spring-boot-testing) - [Guide to @ConfigurationProperties in Spring Boot](http://www.baeldung.com/configuration-properties-in-spring-boot) - [How to Get All Spring-Managed Beans?](http://www.baeldung.com/spring-show-all-beans) diff --git a/spring-boot/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java b/spring-boot/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java index 9dfab1192d..97165f2cf3 100644 --- a/spring-boot/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java +++ b/spring-boot/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java @@ -6,6 +6,7 @@ import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -22,7 +23,7 @@ public class UserController { private static final Logger LOG = LoggerFactory.getLogger(UserController.class); - @RequestMapping("") + @GetMapping("") public List getAllUsers() { LOG.info("Fetching all the users"); return Arrays.asList( diff --git a/spring-boot/src/main/java/com/baeldung/displayallbeans/controller/FooController.java b/spring-boot/src/main/java/com/baeldung/displayallbeans/controller/FooController.java index 26f0a60bff..c4a83cc2d9 100644 --- a/spring-boot/src/main/java/com/baeldung/displayallbeans/controller/FooController.java +++ b/spring-boot/src/main/java/com/baeldung/displayallbeans/controller/FooController.java @@ -4,7 +4,7 @@ import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import com.baeldung.displayallbeans.service.FooService; @@ -13,7 +13,7 @@ public class FooController { @Autowired private FooService fooService; - @RequestMapping(value = "/displayallbeans") + @GetMapping(value = "/displayallbeans") public String getHeaderAndBody(Map model) { model.put("header", fooService.getHeader()); model.put("message", fooService.getBody()); diff --git a/spring-boot/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java b/spring-boot/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java index 8bdfea74cd..e002ac045d 100644 --- a/spring-boot/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java +++ b/spring-boot/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java @@ -3,7 +3,7 @@ package com.baeldung.errorhandling.controllers; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import javax.servlet.RequestDispatcher; import javax.servlet.http.HttpServletRequest; @@ -13,7 +13,7 @@ public class MyErrorController implements ErrorController { public MyErrorController() {} - @RequestMapping(value = "/error") + @GetMapping(value = "/error") public String handleError(HttpServletRequest request) { Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); diff --git a/spring-boot/src/main/java/com/baeldung/git/CommitInfoController.java b/spring-boot/src/main/java/com/baeldung/git/CommitInfoController.java index 6d44e02ec2..9dca749319 100644 --- a/spring-boot/src/main/java/com/baeldung/git/CommitInfoController.java +++ b/spring-boot/src/main/java/com/baeldung/git/CommitInfoController.java @@ -1,7 +1,7 @@ package com.baeldung.git; import org.springframework.beans.factory.annotation.Value; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; @@ -19,7 +19,7 @@ public class CommitInfoController { @Value("${git.commit.id}") private String commitId; - @RequestMapping("/commitId") + @GetMapping("/commitId") public Map getCommitId() { Map result = new HashMap<>(); result.put("Commit message", commitMessage); diff --git a/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java b/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java index 2a82e58829..32f22f2cae 100644 --- a/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java +++ b/spring-boot/src/main/java/com/baeldung/intro/controller/HomeController.java @@ -1,17 +1,17 @@ package com.baeldung.intro.controller; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HomeController { - @RequestMapping("/") + @GetMapping("/") public String root() { return "Index Page"; } - @RequestMapping("/local") + @GetMapping("/local") public String local() { return "/local"; } diff --git a/spring-boot/src/main/java/com/baeldung/rss/ArticleRssController.java b/spring-boot/src/main/java/com/baeldung/rss/ArticleRssController.java index a3fbc4a37e..daaeb8159b 100644 --- a/spring-boot/src/main/java/com/baeldung/rss/ArticleRssController.java +++ b/spring-boot/src/main/java/com/baeldung/rss/ArticleRssController.java @@ -1,14 +1,14 @@ package com.baeldung.rss; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; @Controller @RequestMapping(value = "/rss", produces = "application/*") public class ArticleRssController { - @RequestMapping(method = RequestMethod.GET) + @GetMapping public String articleFeed() { return "articleFeedView"; } diff --git a/spring-boot/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java b/spring-boot/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java index 1faee5c488..5b9ce1271e 100644 --- a/spring-boot/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java +++ b/spring-boot/src/main/java/com/baeldung/servletinitializer/WarInitializerApplication.java @@ -7,7 +7,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @@ -27,7 +27,7 @@ public class WarInitializerApplication extends SpringBootServletInitializer { @RestController public static class WarInitializerController { - @RequestMapping("/") + @GetMapping("/") public String handler(Model model) { model.addAttribute("date", LocalDateTime.now()); return "WarInitializerApplication is up and running!"; diff --git a/spring-boot/src/main/java/com/baeldung/webjar/TestController.java b/spring-boot/src/main/java/com/baeldung/webjar/TestController.java index e8e7fd5ce9..e5404c7c7c 100644 --- a/spring-boot/src/main/java/com/baeldung/webjar/TestController.java +++ b/spring-boot/src/main/java/com/baeldung/webjar/TestController.java @@ -2,12 +2,12 @@ package com.baeldung.webjar; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; @Controller public class TestController { - @RequestMapping(value = "/") + @GetMapping(value = "/") public String welcome(Model model) { return "index"; } diff --git a/spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java b/spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java index 817bae8d01..17457f4c20 100644 --- a/spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java +++ b/spring-boot/src/main/java/org/baeldung/boot/controller/GenericEntityController.java @@ -7,8 +7,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDateTime; @@ -26,18 +25,18 @@ public class GenericEntityController { entityList.add(new GenericEntity(4l, "entity_4")); } - @RequestMapping("/entity/all") + @GetMapping("/entity/all") public List findAll() { return entityList; } - @RequestMapping(value = "/entity", method = RequestMethod.POST) + @PostMapping("/entity") public GenericEntity addEntity(GenericEntity entity) { entityList.add(entity); return entity; } - @RequestMapping("/entity/findby/{id}") + @GetMapping("/entity/findby/{id}") public GenericEntity findById(@PathVariable Long id) { return entityList.stream().filter(entity -> entity.getId().equals(id)).findFirst().get(); } diff --git a/spring-boot/src/main/java/org/baeldung/common/error/MyCustomErrorController.java b/spring-boot/src/main/java/org/baeldung/common/error/MyCustomErrorController.java index a826a604d3..e4e20de671 100644 --- a/spring-boot/src/main/java/org/baeldung/common/error/MyCustomErrorController.java +++ b/spring-boot/src/main/java/org/baeldung/common/error/MyCustomErrorController.java @@ -1,7 +1,7 @@ package org.baeldung.common.error; import org.springframework.boot.web.servlet.error.ErrorController; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; public class MyCustomErrorController implements ErrorController { @@ -11,7 +11,7 @@ public class MyCustomErrorController implements ErrorController { // TODO Auto-generated constructor stub } - @RequestMapping(value = PATH) + @GetMapping(value = PATH) public String error() { return "Error heaven"; } diff --git a/spring-boot/src/main/java/org/baeldung/common/error/controller/ErrorController.java b/spring-boot/src/main/java/org/baeldung/common/error/controller/ErrorController.java index ecabde7d9d..d503f5da6d 100644 --- a/spring-boot/src/main/java/org/baeldung/common/error/controller/ErrorController.java +++ b/spring-boot/src/main/java/org/baeldung/common/error/controller/ErrorController.java @@ -1,6 +1,6 @@ package org.baeldung.common.error.controller; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @@ -9,12 +9,12 @@ public class ErrorController { public ErrorController() { } - @RequestMapping("/400") + @GetMapping("/400") String error400() { return "Error Code: 400 occured."; } - @RequestMapping("/errorHeaven") + @GetMapping("/errorHeaven") String errorHeaven() { return "You have reached the heaven of errors!!!"; } diff --git a/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java b/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java index 7d13173be0..30ac94221b 100644 --- a/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java +++ b/spring-boot/src/main/java/org/baeldung/main/SpringBootApplication.java @@ -10,7 +10,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.concurrent.ExecutorService; @@ -23,7 +23,7 @@ public class SpringBootApplication { private static ApplicationContext applicationContext; - @RequestMapping("/") + @GetMapping("/") String home() { return "TADA!!! You are in Spring Boot Actuator test application."; } diff --git a/spring-boot/src/main/resources/application.properties b/spring-boot/src/main/resources/application.properties index 203f0ee3c5..04a4fbf9de 100644 --- a/spring-boot/src/main/resources/application.properties +++ b/spring-boot/src/main/resources/application.properties @@ -1,21 +1,22 @@ server.port=9090 -server.contextPath=/springbootapp -management.port=8081 -management.address=127.0.0.1 +server.servlet.contextPath=/springbootapp +management.server.port=8081 +management.server.address=127.0.0.1 #debug=true spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto = update -endpoints.shutdown.enabled=true -endpoints.jmx.domain=Spring Sample Application -endpoints.jmx.uniqueNames=true +management.endpoints.jmx.domain=Spring Sample Application +management.endpoints.jmx.uniqueNames=true + +management.endpoint.shutdown.enabled=true ##jolokia.config.debug=true ##endpoints.jolokia.enabled=true ##endpoints.jolokia.path=jolokia spring.jmx.enabled=true -endpoints.jmx.enabled=true +management.endpoints.jmx.enabled=true ## for pretty printing of json when endpoints accessed over HTTP http.mappers.jsonPrettyPrint=true @@ -26,11 +27,7 @@ info.app.description=This is my first spring boot application G1 info.app.version=1.0.0 info.java-vendor = ${java.specification.vendor} -## Spring Security Configurations -security.user.name=admin1 -security.user.password=secret1 management.security.role=SUPERUSER -management.endpoint.shutdown.enabled=true logging.level.org.springframework=INFO @@ -38,15 +35,12 @@ logging.level.org.springframework=INFO servlet.name=dispatcherExample servlet.mapping=/dispatcherExampleURL -#banner.charset=UTF-8 -#banner.location=classpath:banner.txt -#banner.image.location=classpath:banner.gif -#banner.image.width= //TODO -#banner.image.height= //TODO -#banner.image.margin= //TODO -#banner.image.invert= //TODO +#spring.banner.charset=UTF-8 +#spring.banner.location=classpath:banner.txt +#spring.banner.image.location=classpath:banner.gif +#spring.banner.image.width= //TODO +#spring.banner.image.height= //TODO +#spring.banner.image.margin= //TODO +#spring.banner.image.invert= //TODO contactInfoType=email - -endpoints.beans.id=springbeans -endpoints.beans.sensitive=false From 0ee2e1adfc98a485671139503d0adea5609c959d Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Mon, 7 May 2018 16:17:56 +0400 Subject: [PATCH 16/93] parent/child variable classes --- .../java/com/baeldung/scope/variable/ChildVariable.java | 9 +++++++++ .../java/com/baeldung/scope/variable/ParentVariable.java | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/scope/variable/ChildVariable.java create mode 100644 core-java/src/main/java/com/baeldung/scope/variable/ParentVariable.java diff --git a/core-java/src/main/java/com/baeldung/scope/variable/ChildVariable.java b/core-java/src/main/java/com/baeldung/scope/variable/ChildVariable.java new file mode 100644 index 0000000000..5ec50b8b68 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/scope/variable/ChildVariable.java @@ -0,0 +1,9 @@ +package com.baeldung.scope.variable; + +/** + * Created by Gebruiker on 5/7/2018. + */ +public class ChildVariable extends ParentVariable { + + String instanceVariable = "parent variable"; +} diff --git a/core-java/src/main/java/com/baeldung/scope/variable/ParentVariable.java b/core-java/src/main/java/com/baeldung/scope/variable/ParentVariable.java new file mode 100644 index 0000000000..868a8a1acc --- /dev/null +++ b/core-java/src/main/java/com/baeldung/scope/variable/ParentVariable.java @@ -0,0 +1,9 @@ +package com.baeldung.scope.variable; + +/** + * Created by Gebruiker on 5/7/2018. + */ +public class ParentVariable { + + String instanceVariable = "parent variable"; +} From 1d0a6248e5ef85ea581eff57d696646622bcc8ce Mon Sep 17 00:00:00 2001 From: Felipe Santiago Corro Date: Tue, 8 May 2018 01:19:57 -0300 Subject: [PATCH 17/93] Spring Cache Custom KeyGenerator in module spring-all (#4196) --- .../config/ApplicationCacheConfig.java | 30 ++++++++++++++ .../caching/config/CustomKeyGenerator.java | 14 +++++++ .../baeldung/caching/example/BookService.java | 21 ++++++++++ .../main/java/org/baeldung/model/Book.java | 41 +++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 spring-all/src/main/java/org/baeldung/caching/config/ApplicationCacheConfig.java create mode 100644 spring-all/src/main/java/org/baeldung/caching/config/CustomKeyGenerator.java create mode 100644 spring-all/src/main/java/org/baeldung/caching/example/BookService.java create mode 100644 spring-all/src/main/java/org/baeldung/model/Book.java diff --git a/spring-all/src/main/java/org/baeldung/caching/config/ApplicationCacheConfig.java b/spring-all/src/main/java/org/baeldung/caching/config/ApplicationCacheConfig.java new file mode 100644 index 0000000000..8bf23de2cc --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/caching/config/ApplicationCacheConfig.java @@ -0,0 +1,30 @@ +package org.baeldung.caching.config; + +import org.springframework.cache.Cache; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.concurrent.ConcurrentMapCache; +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.cache.support.SimpleCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.Arrays; + +@EnableCaching +@Configuration +public class ApplicationCacheConfig { + + @Bean + public CacheManager cacheManager() { + SimpleCacheManager cacheManager = new SimpleCacheManager(); + Cache booksCache = new ConcurrentMapCache("books"); + cacheManager.setCaches(Arrays.asList(booksCache)); + return cacheManager; + } + + @Bean("customKeyGenerator") + public KeyGenerator keyGenerator() { + return new CustomKeyGenerator(); + } +} diff --git a/spring-all/src/main/java/org/baeldung/caching/config/CustomKeyGenerator.java b/spring-all/src/main/java/org/baeldung/caching/config/CustomKeyGenerator.java new file mode 100644 index 0000000000..c1da9493e0 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/caching/config/CustomKeyGenerator.java @@ -0,0 +1,14 @@ +package org.baeldung.caching.config; + +import org.springframework.cache.interceptor.KeyGenerator; +import org.springframework.util.StringUtils; + +import java.lang.reflect.Method; + +public class CustomKeyGenerator implements KeyGenerator { + + public Object generate(Object target, Method method, Object... params) { + return target.getClass().getSimpleName() + "_" + method.getName() + "_" + + StringUtils.arrayToDelimitedString(params, "_"); + } +} diff --git a/spring-all/src/main/java/org/baeldung/caching/example/BookService.java b/spring-all/src/main/java/org/baeldung/caching/example/BookService.java new file mode 100644 index 0000000000..26118d61de --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/caching/example/BookService.java @@ -0,0 +1,21 @@ +package org.baeldung.caching.example; + +import org.baeldung.model.Book; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +@Component +public class BookService { + + @Cacheable(value="books", keyGenerator="customKeyGenerator") + public List getBooks() { + List books = new ArrayList(); + books.add(new Book(1, "The Counterfeiters", "André Gide")); + books.add(new Book(2, "Peer Gynt and Hedda Gabler", "Henrik Ibsen")); + return books; + } + +} diff --git a/spring-all/src/main/java/org/baeldung/model/Book.java b/spring-all/src/main/java/org/baeldung/model/Book.java new file mode 100644 index 0000000000..9305ce9653 --- /dev/null +++ b/spring-all/src/main/java/org/baeldung/model/Book.java @@ -0,0 +1,41 @@ +package org.baeldung.model; + +public class Book { + + private int id; + private String author; + private String title; + + public Book() { + } + + public Book(int id, String author, String title) { + this.id = id; + this.author = author; + this.title = title; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} From 2a92926cad3c7502a4391b09713ddfde8e9e51a0 Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Tue, 8 May 2018 09:15:51 +0400 Subject: [PATCH 18/93] remove stream --- .../com/baeldung/designpatterns/composite/HeadDepartment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java b/core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java index 8854fce5b3..119b9c76b5 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java +++ b/core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java @@ -20,7 +20,7 @@ public class HeadDepartment implements Department { } public void printDepartmentName() { - childDepartments.stream().forEach(Department::printDepartmentName); + childDepartments.forEach(Department::printDepartmentName); } public void addDepartMent(Department department) { From 0dfaafac5c7b1209aa06a79f28ebae32f5148d36 Mon Sep 17 00:00:00 2001 From: Wosin Date: Tue, 8 May 2018 10:50:53 +0200 Subject: [PATCH 19/93] BAEL-430: Added performance tests for mapping frameworks (#4092) * BAEL-430: Added performance tests for mapping frameworks * Fixes * Removed @Test annotation. --- performance-tests/pom.xml | 79 +++++++ .../baeldung/performancetests/Converter.java | 11 + .../dozer/DozerConverter.java | 29 +++ .../jmapper/JMapperConverter.java | 30 +++ .../mapstruct/MapStructConverter.java | 22 ++ .../model/destination/AccountStatus.java | 5 + .../model/destination/Address.java | 83 +++++++ .../model/destination/DeliveryData.java | 83 +++++++ .../model/destination/DestinationCode.java | 23 ++ .../model/destination/Discount.java | 70 ++++++ .../model/destination/Order.java | 210 ++++++++++++++++++ .../model/destination/OrderStatus.java | 5 + .../model/destination/PaymentType.java | 5 + .../model/destination/Product.java | 107 +++++++++ .../model/destination/RefundPolicy.java | 72 ++++++ .../model/destination/Review.java | 67 ++++++ .../model/destination/Shop.java | 57 +++++ .../model/destination/User.java | 87 ++++++++ .../model/source/AccountStatus.java | 7 + .../model/source/Address.java | 54 +++++ .../model/source/DeliveryData.java | 54 +++++ .../model/source/Discount.java | 44 ++++ .../model/source/OrderStatus.java | 7 + .../model/source/PaymentType.java | 7 + .../model/source/Product.java | 76 +++++++ .../model/source/RefundPolicy.java | 48 ++++ .../performancetests/model/source/Review.java | 63 ++++++ .../performancetests/model/source/Shop.java | 55 +++++ .../model/source/SourceCode.java | 22 ++ .../model/source/SourceOrder.java | 118 ++++++++++ .../performancetests/model/source/User.java | 42 ++++ .../modelmapper/ModelMapperConverter.java | 26 +++ .../orika/OrikaConverter.java | 31 +++ .../src/main/resources/dozer-mapping.xml | 25 +++ .../MappingFrameworksPerformance.java | 193 ++++++++++++++++ .../src/test/resources/dozer-mapping.xml | 21 ++ pom.xml | 1 + 37 files changed, 1939 insertions(+) create mode 100644 performance-tests/pom.xml create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/Converter.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/dozer/DozerConverter.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/jmapper/JMapperConverter.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/mapstruct/MapStructConverter.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/AccountStatus.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Address.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/DeliveryData.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/DestinationCode.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Discount.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Order.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/OrderStatus.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/PaymentType.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Product.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/RefundPolicy.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Review.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Shop.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/destination/User.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/AccountStatus.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/Address.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/DeliveryData.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/Discount.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/OrderStatus.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/PaymentType.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/Product.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/RefundPolicy.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/Review.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/Shop.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/SourceCode.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/SourceOrder.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/model/source/User.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/modelmapper/ModelMapperConverter.java create mode 100644 performance-tests/src/main/java/com/baeldung/performancetests/orika/OrikaConverter.java create mode 100644 performance-tests/src/main/resources/dozer-mapping.xml create mode 100644 performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java create mode 100644 performance-tests/src/test/resources/dozer-mapping.xml diff --git a/performance-tests/pom.xml b/performance-tests/pom.xml new file mode 100644 index 0000000000..3f25796516 --- /dev/null +++ b/performance-tests/pom.xml @@ -0,0 +1,79 @@ + + + + parent-modules + com.baeldung + 1.0.0-SNAPSHOT + + 4.0.0 + + performancetests + + + + ma.glasnost.orika + orika-core + 1.5.2 + + + net.sf.dozer + dozer + 5.5.1 + + + io.craftsman + dozer-jdk8-support + 1.0.2 + + + org.mapstruct + mapstruct-jdk8 + 1.2.0.Final + + + org.modelmapper + modelmapper + 1.1.0 + + + com.googlecode.jmapper-framework + jmapper-core + 1.6.0.1 + + + org.openjdk.jmh + jmh-core + 1.20 + + + org.openjdk.jmh + jmh-generator-annprocess + 1.20 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + org.mapstruct + mapstruct-processor + 1.2.0.Final + + + + + + + + + \ No newline at end of file diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/Converter.java b/performance-tests/src/main/java/com/baeldung/performancetests/Converter.java new file mode 100644 index 0000000000..097600849b --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/Converter.java @@ -0,0 +1,11 @@ +package com.baeldung.performancetests; + +import com.baeldung.performancetests.model.destination.DestinationCode; +import com.baeldung.performancetests.model.source.SourceCode; +import com.baeldung.performancetests.model.source.SourceOrder; +import com.baeldung.performancetests.model.destination.Order; + +public interface Converter { + Order convert(SourceOrder sourceOrder); + DestinationCode convert(SourceCode sourceCode); +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/dozer/DozerConverter.java b/performance-tests/src/main/java/com/baeldung/performancetests/dozer/DozerConverter.java new file mode 100644 index 0000000000..710145ec58 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/dozer/DozerConverter.java @@ -0,0 +1,29 @@ +package com.baeldung.performancetests.dozer; + +import com.baeldung.performancetests.Converter; +import com.baeldung.performancetests.model.destination.DestinationCode; +import com.baeldung.performancetests.model.source.SourceCode; +import com.baeldung.performancetests.model.source.SourceOrder; +import com.baeldung.performancetests.model.destination.Order; +import org.dozer.DozerBeanMapper; +import org.dozer.Mapper; + + public class DozerConverter implements Converter { + private final Mapper mapper; + + public DozerConverter() { + DozerBeanMapper mapper = new DozerBeanMapper(); + mapper.addMapping(DozerConverter.class.getResourceAsStream("/dozer-mapping.xml")); + this.mapper = mapper; + } + + @Override + public Order convert(SourceOrder sourceOrder) { + return mapper.map(sourceOrder,Order.class); + } + + @Override + public DestinationCode convert(SourceCode sourceCode) { + return mapper.map(sourceCode, DestinationCode.class); + } + } diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/jmapper/JMapperConverter.java b/performance-tests/src/main/java/com/baeldung/performancetests/jmapper/JMapperConverter.java new file mode 100644 index 0000000000..b61cfbb771 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/jmapper/JMapperConverter.java @@ -0,0 +1,30 @@ +package com.baeldung.performancetests.jmapper; + +import com.baeldung.performancetests.Converter; +import com.baeldung.performancetests.model.destination.DestinationCode; +import com.baeldung.performancetests.model.source.SourceCode; +import com.baeldung.performancetests.model.source.SourceOrder; +import com.baeldung.performancetests.model.destination.Order; +import com.googlecode.jmapper.JMapper; +import com.googlecode.jmapper.api.JMapperAPI; + +public class JMapperConverter implements Converter { + JMapper realLifeMapper; + JMapper simpleMapper; + public JMapperConverter() { + JMapperAPI api = new JMapperAPI().add(JMapperAPI.mappedClass(Order.class)); + realLifeMapper = new JMapper(Order.class, SourceOrder.class, api); + JMapperAPI simpleApi = new JMapperAPI().add(JMapperAPI.mappedClass(DestinationCode.class)); + simpleMapper = new JMapper(DestinationCode.class, SourceCode.class, simpleApi); + } + + @Override + public Order convert(SourceOrder sourceOrder) { + return (Order) realLifeMapper.getDestination(sourceOrder); + } + + @Override + public DestinationCode convert(SourceCode sourceCode) { + return (DestinationCode) simpleMapper.getDestination(sourceCode); + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/mapstruct/MapStructConverter.java b/performance-tests/src/main/java/com/baeldung/performancetests/mapstruct/MapStructConverter.java new file mode 100644 index 0000000000..27ec6e6c83 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/mapstruct/MapStructConverter.java @@ -0,0 +1,22 @@ +package com.baeldung.performancetests.mapstruct; + +import com.baeldung.performancetests.Converter; +import com.baeldung.performancetests.model.destination.DestinationCode; +import com.baeldung.performancetests.model.source.SourceCode; +import com.baeldung.performancetests.model.source.SourceOrder; +import com.baeldung.performancetests.model.destination.Order; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface MapStructConverter extends Converter { + MapStructConverter MAPPER = Mappers.getMapper(MapStructConverter.class); + + @Mapping(source = "status", target = "orderStatus") + @Override + Order convert(SourceOrder sourceOrder); + + @Override + DestinationCode convert(SourceCode sourceCode); +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/AccountStatus.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/AccountStatus.java new file mode 100644 index 0000000000..c435a73b56 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/AccountStatus.java @@ -0,0 +1,5 @@ +package com.baeldung.performancetests.model.destination; + +public enum AccountStatus { + ACTIVE, NOT_ACTIVE, BANNED +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Address.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Address.java new file mode 100644 index 0000000000..9107f47455 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Address.java @@ -0,0 +1,83 @@ +package com.baeldung.performancetests.model.destination; + +import com.googlecode.jmapper.annotations.JGlobalMap; + +import java.util.Objects; + +@JGlobalMap +public class Address { + private String street; + private String city; + private String postalCode; + + public Address() { + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if(o.getClass() == com.baeldung.performancetests.model.source.Address.class) { + com.baeldung.performancetests.model.source.Address address = + (com.baeldung.performancetests.model.source.Address) o; + return Objects.equals(street, address.getStreet()) && + Objects.equals(city, address.getCity()) && + Objects.equals(postalCode, address.getPostalCode()) && + Objects.equals(country, address.getCountry()); + } + if(o.getClass() != getClass()) return false; + Address address = (Address) o; + return Objects.equals(street, address.street) && + Objects.equals(city, address.city) && + Objects.equals(postalCode, address.postalCode) && + Objects.equals(country, address.country); + } + + @Override + public int hashCode() { + + return Objects.hash(street, city, postalCode, country); + } + + private String country; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public Address(String street, String city, String postalCode, String country) { + + this.street = street; + this.city = city; + this.postalCode = postalCode; + this.country = country; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/DeliveryData.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/DeliveryData.java new file mode 100644 index 0000000000..1d9bde1088 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/DeliveryData.java @@ -0,0 +1,83 @@ +package com.baeldung.performancetests.model.destination; + +import com.googlecode.jmapper.annotations.JGlobalMap; +import com.googlecode.jmapper.annotations.JMapAccessor; + +import java.util.Objects; + +@JGlobalMap +public class DeliveryData { + private Address deliveryAddress; + @JMapAccessor(get = "isPrePaid", set = "setPrePaid") + private boolean isPrePaid; + private String trackingCode; + private int expectedDeliveryTimeInDays; + + public DeliveryData() { + } + + public Address getDeliveryAddress() { + return deliveryAddress; + } + + public void setDeliveryAddress(Address deliveryAddress) { + this.deliveryAddress = deliveryAddress; + } + + public boolean isPrePaid() { + return isPrePaid; + } + + public void setPrePaid(boolean prePaid) { + isPrePaid = prePaid; + } + + public String getTrackingCode() { + return trackingCode; + } + + public void setTrackingCode(String trackingCode) { + this.trackingCode = trackingCode; + } + + public int getExpectedDeliveryTimeInDays() { + return expectedDeliveryTimeInDays; + } + + public void setExpectedDeliveryTimeInDays(int expectedDeliveryTimeInDays) { + this.expectedDeliveryTimeInDays = expectedDeliveryTimeInDays; + } + + public DeliveryData(Address deliveryAddress, boolean isPrePaid, String trackingCode, int expectedDeliveryTimeInDays) { + this.deliveryAddress = deliveryAddress; + this.isPrePaid = isPrePaid; + this.trackingCode = trackingCode; + this.expectedDeliveryTimeInDays = expectedDeliveryTimeInDays; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if(o.getClass() == com.baeldung.performancetests.model.source.DeliveryData.class) { + com.baeldung.performancetests.model.source.DeliveryData deliveryData = + (com.baeldung.performancetests.model.source.DeliveryData) o; + return isPrePaid == deliveryData.isPrePaid() && + expectedDeliveryTimeInDays == deliveryData.getExpectedDeliveryTimeInDays() && + Objects.equals(deliveryAddress, deliveryData.getDeliveryAddress()) && + Objects.equals(trackingCode, deliveryData.getTrackingCode()); + } + if (o.getClass() != getClass()) return false; + DeliveryData that = (DeliveryData) o; + return isPrePaid == that.isPrePaid && + expectedDeliveryTimeInDays == that.expectedDeliveryTimeInDays && + Objects.equals(deliveryAddress, that.deliveryAddress) && + Objects.equals(trackingCode, that.trackingCode); + } + + @Override + public int hashCode() { + + return Objects.hash(deliveryAddress, isPrePaid, trackingCode, expectedDeliveryTimeInDays); + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/DestinationCode.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/DestinationCode.java new file mode 100644 index 0000000000..d0a7985db8 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/DestinationCode.java @@ -0,0 +1,23 @@ +package com.baeldung.performancetests.model.destination; + +import com.googlecode.jmapper.annotations.JMap; + +public class DestinationCode { + @JMap + String code; + + public DestinationCode(String code) { + this.code = code; + } + + public DestinationCode() { + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Discount.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Discount.java new file mode 100644 index 0000000000..920cc71a7e --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Discount.java @@ -0,0 +1,70 @@ +package com.baeldung.performancetests.model.destination; + +import com.google.common.base.Objects; +import com.googlecode.jmapper.annotations.JGlobalMap; + +import java.math.BigDecimal; + +@JGlobalMap +public class Discount { + private String startTime; + private String endTime; + private BigDecimal discountPrice; + + public Discount() { + } + + public String getStartTime() { + return startTime; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if (o.getClass() == com.baeldung.performancetests.model.source.Discount.class) { + com.baeldung.performancetests.model.source.Discount discount = + (com.baeldung.performancetests.model.source.Discount) o; + return Objects.equal(startTime, discount.getStartTime()) && + Objects.equal(endTime, discount.getEndTime()) && + Objects.equal(discountPrice, discount.getDiscountPrice()); + } + if(o.getClass() != getClass()) return false; + Discount discount = (Discount) o; + return Objects.equal(startTime, discount.startTime) && + Objects.equal(endTime, discount.endTime) && + Objects.equal(discountPrice, discount.discountPrice); + } + + @Override + public int hashCode() { + return Objects.hashCode(startTime, endTime, discountPrice); + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public BigDecimal getDiscountPrice() { + return discountPrice; + } + + public void setDiscountPrice(BigDecimal discountPrice) { + this.discountPrice = discountPrice; + } + + public Discount(String startTime, String endTime, BigDecimal discountPrice) { + + this.startTime = startTime; + this.endTime = endTime; + this.discountPrice = discountPrice; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Order.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Order.java new file mode 100644 index 0000000000..cbce84efc4 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Order.java @@ -0,0 +1,210 @@ +package com.baeldung.performancetests.model.destination; + +import com.baeldung.performancetests.model.source.SourceOrder; +import com.google.common.base.Objects; +import com.googlecode.jmapper.annotations.JMap; +import com.googlecode.jmapper.annotations.JMapConversion; + +import java.util.List; +public class Order { + @JMap + private User orderingUser; + @JMap + private List orderedProducts; + @JMap("status") + private OrderStatus orderStatus; + @JMap + private String orderDate; + @JMap + private String orderFinishDate; + @JMap + private PaymentType paymentType; + @JMap + private Discount discount; + @JMap + private int orderId; + @JMap + private DeliveryData deliveryData; + @JMap + private Shop offeringShop; + + public Order() { + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if (o.getClass() == SourceOrder.class) { + SourceOrder order = + (SourceOrder) o; + return Objects.equal(orderingUser, order.getOrderingUser()) && + Objects.equal(orderedProducts, order.getOrderedProducts()) && + orderStatus.ordinal() == order.getStatus().ordinal() && + Objects.equal(orderDate, order.getOrderDate()) && + Objects.equal(orderFinishDate, order.getOrderFinishDate()) && + paymentType.ordinal() == order.getPaymentType().ordinal() && + Objects.equal(discount, order.getDiscount()) && + Objects.equal(deliveryData, order.getDeliveryData()); + } + if (o.getClass() != getClass()) return false; + Order order = (Order) o; + return Objects.equal(orderingUser, order.orderingUser) && + Objects.equal(orderedProducts, order.orderedProducts) && + orderStatus == order.orderStatus && + Objects.equal(orderDate, order.orderDate) && + Objects.equal(orderFinishDate, order.orderFinishDate) && + paymentType == order.paymentType && + Objects.equal(discount, order.discount) && + Objects.equal(deliveryData, order.deliveryData); + } + + @Override + public int hashCode() { + return Objects.hashCode(orderingUser, orderedProducts, orderStatus, orderDate, orderFinishDate, paymentType, discount, deliveryData); + } + + public User getOrderingUser() { + return orderingUser; + } + + public void setOrderingUser(User orderingUser) { + this.orderingUser = orderingUser; + } + + public List getOrderedProducts() { + return orderedProducts; + } + + public void setOrderedProducts(List orderedProducts) { + this.orderedProducts = orderedProducts; + } + + public OrderStatus getOrderStatus() { + return orderStatus; + } + + public void setOrderStatus(OrderStatus status) { + this.orderStatus = status; + } + + public String getOrderDate() { + return orderDate; + } + + public void setOrderDate(String orderDate) { + this.orderDate = orderDate; + } + + public String getOrderFinishDate() { + return orderFinishDate; + } + + public void setOrderFinishDate(String orderFinishDate) { + this.orderFinishDate = orderFinishDate; + } + + public PaymentType getPaymentType() { + return paymentType; + } + + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + + public Discount getDiscount() { + return discount; + } + + public void setDiscount(Discount discount) { + this.discount = discount; + } + + public DeliveryData getDeliveryData() { + return deliveryData; + } + + public void setDeliveryData(DeliveryData deliveryData) { + this.deliveryData = deliveryData; + } + + + public int getOrderId() { + return orderId; + } + + public void setOrderId(int orderId) { + this.orderId = orderId; + } + + public Order(User orderingUser, List orderedProducts, OrderStatus orderStatus, String orderDate, String orderFinishDate, PaymentType paymentType, Discount discount, int orderId, DeliveryData deliveryData, Shop offeringShop) { + + this.orderingUser = orderingUser; + this.orderedProducts = orderedProducts; + this.orderStatus = orderStatus; + this.orderDate = orderDate; + this.orderFinishDate = orderFinishDate; + this.paymentType = paymentType; + this.discount = discount; + this.orderId = orderId; + this.deliveryData = deliveryData; + this.offeringShop = offeringShop; + } + + public Shop getOfferingShop() { + return offeringShop; + } + + public void setOfferingShop(Shop offeringShop) { + this.offeringShop = offeringShop; + } + + + + @JMapConversion(from = "status", to = "orderStatus") + public OrderStatus conversion(com.baeldung.performancetests.model.source.OrderStatus status) { + OrderStatus orderStatus = null; + switch(status) { + case CREATED: + orderStatus = OrderStatus.CREATED; + break; + case FINISHED: + orderStatus = OrderStatus.FINISHED; + break; + + case CONFIRMED: + orderStatus = OrderStatus.CONFIRMED; + break; + + case COLLECTING: + orderStatus = OrderStatus.COLLECTING; + break; + + case IN_TRANSPORT: + orderStatus = OrderStatus.IN_TRANSPORT; + break; + } + return orderStatus; + } + + @JMapConversion(from = "paymentType", to = "paymentType") + public PaymentType conversion(com.baeldung.performancetests.model.source.PaymentType type) { + PaymentType paymentType = null; + switch(type) { + case CARD: + paymentType = PaymentType.CARD; + break; + + case CASH: + paymentType = PaymentType.CASH; + break; + + case TRANSFER: + paymentType = PaymentType.TRANSFER; + break; + } + return paymentType; + } + + +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/OrderStatus.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/OrderStatus.java new file mode 100644 index 0000000000..48118201e1 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/OrderStatus.java @@ -0,0 +1,5 @@ +package com.baeldung.performancetests.model.destination; + +public enum OrderStatus { + CREATED, CONFIRMED, COLLECTING, IN_TRANSPORT, FINISHED +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/PaymentType.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/PaymentType.java new file mode 100644 index 0000000000..441e275b18 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/PaymentType.java @@ -0,0 +1,5 @@ +package com.baeldung.performancetests.model.destination; + +public enum PaymentType { + CASH, CARD, TRANSFER +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Product.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Product.java new file mode 100644 index 0000000000..bc1e95e2c0 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Product.java @@ -0,0 +1,107 @@ +package com.baeldung.performancetests.model.destination; + +import com.google.common.base.Objects; +import com.googlecode.jmapper.annotations.JGlobalMap; + +import java.math.BigDecimal; + +@JGlobalMap +public class Product { + private BigDecimal price; + private int quantity; + + public Product() { + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isAvailable() { + return available; + } + + public void setAvailable(boolean available) { + this.available = available; + } + + public RefundPolicy getRefundPolicy() { + return refundPolicy; + } + + public void setRefundPolicy(RefundPolicy refundPolicy) { + this.refundPolicy = refundPolicy; + } + + private String name; + + public Product(BigDecimal price, int quantity, String name, String description, boolean available, RefundPolicy refundPolicy) { + this.price = price; + this.quantity = quantity; + this.name = name; + this.description = description; + this.available = available; + this.refundPolicy = refundPolicy; + } + + String description; + boolean available; + private RefundPolicy refundPolicy; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if (o.getClass() == com.baeldung.performancetests.model.source.Product.class) { + com.baeldung.performancetests.model.source.Product product = + (com.baeldung.performancetests.model.source.Product) o; + return quantity == product.getQuantity() && + available == product.isAvailable() && + Objects.equal(price, product.getPrice()) && + Objects.equal(name, product.getName()) && + Objects.equal(description, product.getDescription()) && + Objects.equal(refundPolicy, product.getRefundPolicy()); + } + if(o.getClass() != getClass()) return false; + Product product = (Product) o; + return quantity == product.quantity && + available == product.available && + Objects.equal(price, product.price) && + Objects.equal(name, product.name) && + Objects.equal(description, product.description) && + Objects.equal(refundPolicy, product.refundPolicy); + } + + @Override + public int hashCode() { + return Objects.hashCode(price, quantity, name, description, available, refundPolicy); + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/RefundPolicy.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/RefundPolicy.java new file mode 100644 index 0000000000..523957596c --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/RefundPolicy.java @@ -0,0 +1,72 @@ +package com.baeldung.performancetests.model.destination; + +import com.google.common.base.Objects; +import com.googlecode.jmapper.annotations.JGlobalMap; +import com.googlecode.jmapper.annotations.JMapAccessor; + +import java.util.List; + +@JGlobalMap +public class RefundPolicy { + @JMapAccessor(get = "isRefundable", set = "setRefundable") + private boolean isRefundable; + private int refundTimeInDays; + + public RefundPolicy() { + } + + public boolean isRefundable() { + return isRefundable; + } + + public void setRefundable(boolean refundable) { + isRefundable = refundable; + } + + public int getRefundTimeInDays() { + return refundTimeInDays; + } + + public void setRefundTimeInDays(int refundTimeInDays) { + this.refundTimeInDays = refundTimeInDays; + } + + public List getNotes() { + return notes; + } + + public void setNotes(List notes) { + this.notes = notes; + } + + public RefundPolicy(boolean isRefundable, int refundTimeInDays, List notes) { + + this.isRefundable = isRefundable; + this.refundTimeInDays = refundTimeInDays; + this.notes = notes; + } + + private List notes; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if (o.getClass() == com.baeldung.performancetests.model.source.RefundPolicy.class) { + com.baeldung.performancetests.model.source.RefundPolicy that = (com.baeldung.performancetests.model.source.RefundPolicy) o; + return isRefundable == that.isRefundable() && + refundTimeInDays == that.getRefundTimeInDays() && + Objects.equal(notes, that.getNotes()); + } + if (o.getClass() != getClass()) return false; + RefundPolicy that = (RefundPolicy) o; + return isRefundable == that.isRefundable && + refundTimeInDays == that.refundTimeInDays && + Objects.equal(notes, that.notes); + } + + @Override + public int hashCode() { + return Objects.hashCode(isRefundable, refundTimeInDays, notes); + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Review.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Review.java new file mode 100644 index 0000000000..d1794d4913 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Review.java @@ -0,0 +1,67 @@ +package com.baeldung.performancetests.model.destination; + +import com.baeldung.performancetests.model.source.User; +import com.googlecode.jmapper.annotations.JGlobalMap; + +@JGlobalMap +public class Review { + + int shippingGrade; + int pricingGrade; + int serviceGrade; + User reviewingUser; + String note; + + public int getShippingGrade() { + return shippingGrade; + } + + public void setShippingGrade(int shippingGrade) { + this.shippingGrade = shippingGrade; + } + + public int getPricingGrade() { + return pricingGrade; + } + + public void setPricingGrade(int pricingGrade) { + this.pricingGrade = pricingGrade; + } + + public int getServiceGrade() { + return serviceGrade; + } + + public void setServiceGrade(int serviceGrade) { + this.serviceGrade = serviceGrade; + } + + public User getReviewingUser() { + return reviewingUser; + } + + public void setReviewingUser(User reviewingUser) { + this.reviewingUser = reviewingUser; + } + + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } + + public Review() { + + } + + public Review(int shippingGrade, int pricingGrade, int serviceGrade, User reviewingUser, String note) { + + this.shippingGrade = shippingGrade; + this.pricingGrade = pricingGrade; + this.serviceGrade = serviceGrade; + this.reviewingUser = reviewingUser; + this.note = note; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Shop.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Shop.java new file mode 100644 index 0000000000..75f37b8bba --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/Shop.java @@ -0,0 +1,57 @@ +package com.baeldung.performancetests.model.destination; + +import com.baeldung.performancetests.model.source.Address; +import com.googlecode.jmapper.annotations.JGlobalMap; + +import java.util.List; +@JGlobalMap +public class Shop { + + private String shopName; + private Address shopAddres; + private String shopUrl; + private List reviews; + + public String getShopName() { + return shopName; + } + + public void setShopName(String shopName) { + this.shopName = shopName; + } + + public Address getShopAddres() { + return shopAddres; + } + + public void setShopAddres(Address shopAddres) { + this.shopAddres = shopAddres; + } + + public String getShopUrl() { + return shopUrl; + } + + public void setShopUrl(String shopUrl) { + this.shopUrl = shopUrl; + } + + public Shop() { + } + + public List getReviews() { + return reviews; + } + + public void setReviews(List reviews) { + this.reviews = reviews; + } + + public Shop(String shopName, Address shopAddres, String shopUrl, List reviews) { + + this.shopName = shopName; + this.shopAddres = shopAddres; + this.shopUrl = shopUrl; + this.reviews = reviews; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/User.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/User.java new file mode 100644 index 0000000000..6f604f64b3 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/destination/User.java @@ -0,0 +1,87 @@ +package com.baeldung.performancetests.model.destination; + +import com.google.common.base.Objects; +import com.googlecode.jmapper.annotations.JGlobalMap; +import com.googlecode.jmapper.annotations.JMapConversion; + +@JGlobalMap +public class User { + private String username; + private String email; + private AccountStatus userAccountStatus; + + public User(String username, String email, AccountStatus userAccountStatus) { + this.username = username; + this.email = email; + this.userAccountStatus = userAccountStatus; + } + + public User() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public AccountStatus getUserAccountStatus() { + return userAccountStatus; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if (o.getClass() == com.baeldung.performancetests.model.source.User.class) { + com.baeldung.performancetests.model.source.User user = + (com.baeldung.performancetests.model.source.User) o; + return Objects.equal(username, user.getUsername()) && + Objects.equal(email, user.getEmail()) && + userAccountStatus.ordinal() == user.getUserAccountStatus().ordinal(); + } + if (o.getClass() != getClass()) return false; + User user = (User) o; + return Objects.equal(username, user.username) && + Objects.equal(email, user.email) && + userAccountStatus == user.userAccountStatus; + } + + @Override + public int hashCode() { + return Objects.hashCode(username, email, userAccountStatus); + } + + public void setUserAccountStatus(AccountStatus userAccountStatus) { + this.userAccountStatus = userAccountStatus; + } + + + @JMapConversion(from = "userAccountStatus", to = "userAccountStatus") + public AccountStatus conversion(com.baeldung.performancetests.model.source.AccountStatus status) { + AccountStatus accountStatus = null; + switch(status) { + case ACTIVE: + accountStatus = AccountStatus.ACTIVE; + break; + case NOT_ACTIVE: + accountStatus = AccountStatus.NOT_ACTIVE; + break; + + case BANNED: + accountStatus = AccountStatus.BANNED; + break; + } + return accountStatus; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/AccountStatus.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/AccountStatus.java new file mode 100644 index 0000000000..e3e7d7964c --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/AccountStatus.java @@ -0,0 +1,7 @@ +package com.baeldung.performancetests.model.source; + +import com.googlecode.jmapper.annotations.JGlobalMap; + +public enum AccountStatus { + ACTIVE, NOT_ACTIVE, BANNED +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Address.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Address.java new file mode 100644 index 0000000000..2818fa0065 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Address.java @@ -0,0 +1,54 @@ +package com.baeldung.performancetests.model.source; + +import com.googlecode.jmapper.annotations.JGlobalMap; + +public class Address { + private String street; + private String city; + private String postalCode; + + public Address() { + } + + private String country; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public Address(String street, String city, String postalCode, String country) { + + this.street = street; + this.city = city; + this.postalCode = postalCode; + this.country = country; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/DeliveryData.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/DeliveryData.java new file mode 100644 index 0000000000..9501649a05 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/DeliveryData.java @@ -0,0 +1,54 @@ +package com.baeldung.performancetests.model.source; + +import com.googlecode.jmapper.annotations.JGlobalMap; +import com.googlecode.jmapper.annotations.JMapAccessor; + +public class DeliveryData { + private Address deliveryAddress; + @JMapAccessor(get = "isPrePaid", set = "setPrePaid") + private boolean isPrePaid; + private String trackingCode; + private int expectedDeliveryTimeInDays; + + public DeliveryData() { + } + + public Address getDeliveryAddress() { + return deliveryAddress; + } + + public void setDeliveryAddress(Address deliveryAddress) { + this.deliveryAddress = deliveryAddress; + } + + public boolean isPrePaid() { + return isPrePaid; + } + + public void setPrePaid(boolean prePaid) { + isPrePaid = prePaid; + } + + public String getTrackingCode() { + return trackingCode; + } + + public void setTrackingCode(String trackingCode) { + this.trackingCode = trackingCode; + } + + public int getExpectedDeliveryTimeInDays() { + return expectedDeliveryTimeInDays; + } + + public void setExpectedDeliveryTimeInDays(int expectedDeliveryTimeInDays) { + this.expectedDeliveryTimeInDays = expectedDeliveryTimeInDays; + } + + public DeliveryData(Address deliveryAddress, boolean isPrePaid, String trackingCode, int expectedDeliveryTimeInDays) { + this.deliveryAddress = deliveryAddress; + this.isPrePaid = isPrePaid; + this.trackingCode = trackingCode; + this.expectedDeliveryTimeInDays = expectedDeliveryTimeInDays; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Discount.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Discount.java new file mode 100644 index 0000000000..603432dfed --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Discount.java @@ -0,0 +1,44 @@ +package com.baeldung.performancetests.model.source; + +import com.googlecode.jmapper.annotations.JGlobalMap; + +import java.math.BigDecimal; +public class Discount { + private String startTime; + private String endTime; + private BigDecimal discountPrice; + + public Discount() { + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public BigDecimal getDiscountPrice() { + return discountPrice; + } + + public void setDiscountPrice(BigDecimal discountPrice) { + this.discountPrice = discountPrice; + } + + public Discount(String startTime, String endTime, BigDecimal discountPrice) { + + this.startTime = startTime; + this.endTime = endTime; + this.discountPrice = discountPrice; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/OrderStatus.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/OrderStatus.java new file mode 100644 index 0000000000..962c91a6c4 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/OrderStatus.java @@ -0,0 +1,7 @@ +package com.baeldung.performancetests.model.source; + +import com.googlecode.jmapper.annotations.JGlobalMap; + +public enum OrderStatus { + CREATED, CONFIRMED, COLLECTING, IN_TRANSPORT, FINISHED +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/PaymentType.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/PaymentType.java new file mode 100644 index 0000000000..fbb4c82afc --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/PaymentType.java @@ -0,0 +1,7 @@ +package com.baeldung.performancetests.model.source; + +import com.googlecode.jmapper.annotations.JGlobalMap; + +public enum PaymentType { + CASH, CARD, TRANSFER +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Product.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Product.java new file mode 100644 index 0000000000..5feccb97dc --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Product.java @@ -0,0 +1,76 @@ +package com.baeldung.performancetests.model.source; + +import com.googlecode.jmapper.annotations.JGlobalMap; + +import java.math.BigDecimal; + +public class Product { + private BigDecimal price; + private int quantity; + + public Product() { + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isAvailable() { + return available; + } + + public void setAvailable(boolean available) { + this.available = available; + } + + public RefundPolicy getRefundPolicy() { + return refundPolicy; + } + + public void setRefundPolicy(RefundPolicy refundPolicy) { + this.refundPolicy = refundPolicy; + } + + private String name; + + public Product(BigDecimal price, int quantity, String name, String description, boolean available, RefundPolicy refundPolicy) { + this.price = price; + this.quantity = quantity; + this.name = name; + this.description = description; + this.available = available; + this.refundPolicy = refundPolicy; + } + + String description; + boolean available; + private RefundPolicy refundPolicy; +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/RefundPolicy.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/RefundPolicy.java new file mode 100644 index 0000000000..5111e27b54 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/RefundPolicy.java @@ -0,0 +1,48 @@ +package com.baeldung.performancetests.model.source; + +import com.googlecode.jmapper.annotations.JGlobalMap; +import com.googlecode.jmapper.annotations.JMapAccessor; + +import java.util.List; + +public class RefundPolicy { + @JMapAccessor(get = "isRefundable", set = "setRefundable") + private boolean isRefundable; + private int refundTimeInDays; + + public RefundPolicy() { + } + + public boolean isRefundable() { + return isRefundable; + } + + public void setRefundable(boolean refundable) { + isRefundable = refundable; + } + + public int getRefundTimeInDays() { + return refundTimeInDays; + } + + public void setRefundTimeInDays(int refundTimeInDays) { + this.refundTimeInDays = refundTimeInDays; + } + + public List getNotes() { + return notes; + } + + public void setNotes(List notes) { + this.notes = notes; + } + + public RefundPolicy(boolean isRefundable, int refundTimeInDays, List notes) { + + this.isRefundable = isRefundable; + this.refundTimeInDays = refundTimeInDays; + this.notes = notes; + } + + private List notes; +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Review.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Review.java new file mode 100644 index 0000000000..8e2630b672 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Review.java @@ -0,0 +1,63 @@ +package com.baeldung.performancetests.model.source; + +public class Review { + + int shippingGrade; + int pricingGrade; + int serviceGrade; + User reviewingUser; + String note; + + public int getShippingGrade() { + return shippingGrade; + } + + public void setShippingGrade(int shippingGrade) { + this.shippingGrade = shippingGrade; + } + + public int getPricingGrade() { + return pricingGrade; + } + + public void setPricingGrade(int pricingGrade) { + this.pricingGrade = pricingGrade; + } + + public int getServiceGrade() { + return serviceGrade; + } + + public void setServiceGrade(int serviceGrade) { + this.serviceGrade = serviceGrade; + } + + public User getReviewingUser() { + return reviewingUser; + } + + public void setReviewingUser(User reviewingUser) { + this.reviewingUser = reviewingUser; + } + + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } + + public Review() { + + } + + public Review(int shippingGrade, int pricingGrade, int serviceGrade, User reviewingUser, String note) { + + this.shippingGrade = shippingGrade; + this.pricingGrade = pricingGrade; + this.serviceGrade = serviceGrade; + this.reviewingUser = reviewingUser; + this.note = note; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Shop.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Shop.java new file mode 100644 index 0000000000..d35681933b --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/Shop.java @@ -0,0 +1,55 @@ +package com.baeldung.performancetests.model.source; + +import java.util.List; + +public class Shop { + + private String shopName; + private Address shopAddres; + + public String getShopName() { + return shopName; + } + + public void setShopName(String shopName) { + this.shopName = shopName; + } + + public Address getShopAddres() { + return shopAddres; + } + + public void setShopAddres(Address shopAddres) { + this.shopAddres = shopAddres; + } + + public Shop() { + } + + public String getShopUrl() { + return shopUrl; + } + + public void setShopUrl(String shopUrl) { + this.shopUrl = shopUrl; + } + + public List getReviews() { + return reviews; + } + + public void setReviews(List reviews) { + this.reviews = reviews; + } + + public Shop(String shopName, Address shopAddres, String shopUrl, List reviews) { + + this.shopName = shopName; + this.shopAddres = shopAddres; + this.shopUrl = shopUrl; + this.reviews = reviews; + } + + private String shopUrl; + private List reviews; +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/SourceCode.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/SourceCode.java new file mode 100644 index 0000000000..52934d6e0b --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/SourceCode.java @@ -0,0 +1,22 @@ +package com.baeldung.performancetests.model.source; + +public class SourceCode { + String code; + + public SourceCode() { + } + + public String getCode() { + + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public SourceCode(String code) { + + this.code = code; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/SourceOrder.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/SourceOrder.java new file mode 100644 index 0000000000..e83a145f6f --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/SourceOrder.java @@ -0,0 +1,118 @@ +package com.baeldung.performancetests.model.source; + + +import java.util.List; +public class SourceOrder { + private String orderFinishDate; + private PaymentType paymentType; + private Discount discount; + private DeliveryData deliveryData; + private User orderingUser; + private List orderedProducts; + private Shop offeringShop; + private int orderId; + private OrderStatus status; + private String orderDate; + public SourceOrder() { + } + + public User getOrderingUser() { + return orderingUser; + } + + public void setOrderingUser(User orderingUser) { + this.orderingUser = orderingUser; + } + + public List getOrderedProducts() { + return orderedProducts; + } + + public void setOrderedProducts(List orderedProducts) { + this.orderedProducts = orderedProducts; + } + + public OrderStatus getStatus() { + return status; + } + + public void setStatus(OrderStatus status) { + this.status = status; + } + + public String getOrderDate() { + return orderDate; + } + + public void setOrderDate(String orderDate) { + this.orderDate = orderDate; + } + + public String getOrderFinishDate() { + return orderFinishDate; + } + + public void setOrderFinishDate(String orderFinishDate) { + this.orderFinishDate = orderFinishDate; + } + + public PaymentType getPaymentType() { + return paymentType; + } + + public void setPaymentType(PaymentType paymentType) { + this.paymentType = paymentType; + } + + public Discount getDiscount() { + return discount; + } + + public void setDiscount(Discount discount) { + this.discount = discount; + } + + public DeliveryData getDeliveryData() { + return deliveryData; + } + + public void setDeliveryData(DeliveryData deliveryData) { + this.deliveryData = deliveryData; + } + + public Shop getOfferingShop() { + return offeringShop; + } + + public void setOfferingShop(Shop offeringShop) { + this.offeringShop = offeringShop; + } + + + + + + public int getOrderId() { + return orderId; + } + + public void setOrderId(int orderId) { + this.orderId = orderId; + } + + public SourceOrder(OrderStatus status, String orderDate, String orderFinishDate, PaymentType paymentType, Discount discount, DeliveryData deliveryData, User orderingUser, List orderedProducts, Shop offeringShop, int orderId) { + + this.status = status; + this.orderDate = orderDate; + this.orderFinishDate = orderFinishDate; + this.paymentType = paymentType; + this.discount = discount; + this.deliveryData = deliveryData; + this.orderingUser = orderingUser; + this.orderedProducts = orderedProducts; + this.offeringShop = offeringShop; + this.orderId = orderId; + } + + +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/model/source/User.java b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/User.java new file mode 100644 index 0000000000..8c50acb560 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/model/source/User.java @@ -0,0 +1,42 @@ +package com.baeldung.performancetests.model.source; + +import com.googlecode.jmapper.annotations.JGlobalMap; + +public class User { + private String username; + private String email; + private AccountStatus userAccountStatus; + + public User(String username, String email, AccountStatus userAccountStatus) { + this.username = username; + this.email = email; + this.userAccountStatus = userAccountStatus; + } + + public User() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public AccountStatus getUserAccountStatus() { + return userAccountStatus; + } + + public void setUserAccountStatus(AccountStatus userAccountStatus) { + this.userAccountStatus = userAccountStatus; + } +} diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/modelmapper/ModelMapperConverter.java b/performance-tests/src/main/java/com/baeldung/performancetests/modelmapper/ModelMapperConverter.java new file mode 100644 index 0000000000..e3f0426e39 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/modelmapper/ModelMapperConverter.java @@ -0,0 +1,26 @@ +package com.baeldung.performancetests.modelmapper; + +import com.baeldung.performancetests.Converter; +import com.baeldung.performancetests.model.destination.DestinationCode; +import com.baeldung.performancetests.model.source.SourceCode; +import com.baeldung.performancetests.model.source.SourceOrder; +import com.baeldung.performancetests.model.destination.Order; +import org.modelmapper.ModelMapper; + + public class ModelMapperConverter implements Converter { + private ModelMapper modelMapper; + + public ModelMapperConverter() { + modelMapper = new ModelMapper(); + } + + @Override + public Order convert(SourceOrder sourceOrder) { + return modelMapper.map(sourceOrder, Order.class); + } + + @Override + public DestinationCode convert(SourceCode sourceCode) { + return modelMapper.map(sourceCode, DestinationCode.class); + } + } diff --git a/performance-tests/src/main/java/com/baeldung/performancetests/orika/OrikaConverter.java b/performance-tests/src/main/java/com/baeldung/performancetests/orika/OrikaConverter.java new file mode 100644 index 0000000000..994a1830d5 --- /dev/null +++ b/performance-tests/src/main/java/com/baeldung/performancetests/orika/OrikaConverter.java @@ -0,0 +1,31 @@ +package com.baeldung.performancetests.orika; + +import com.baeldung.performancetests.Converter; +import com.baeldung.performancetests.model.destination.DestinationCode; +import com.baeldung.performancetests.model.source.SourceCode; +import com.baeldung.performancetests.model.source.SourceOrder; +import com.baeldung.performancetests.model.destination.Order; +import ma.glasnost.orika.MapperFacade; +import ma.glasnost.orika.MapperFactory; +import ma.glasnost.orika.impl.DefaultMapperFactory; + +public class OrikaConverter implements Converter{ + private MapperFacade mapperFacade; + + public OrikaConverter() { + MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); + + mapperFactory.classMap(Order.class, SourceOrder.class).field("orderStatus", "status").byDefault().register(); + mapperFacade = mapperFactory.getMapperFacade(); + } + + @Override + public Order convert(SourceOrder sourceOrder) { + return mapperFacade.map(sourceOrder, Order.class); + } + + @Override + public DestinationCode convert(SourceCode sourceCode) { + return mapperFacade.map(sourceCode, DestinationCode.class); + } +} diff --git a/performance-tests/src/main/resources/dozer-mapping.xml b/performance-tests/src/main/resources/dozer-mapping.xml new file mode 100644 index 0000000000..7fd7e78e9f --- /dev/null +++ b/performance-tests/src/main/resources/dozer-mapping.xml @@ -0,0 +1,25 @@ + + + + + true + MM/dd/yyyy HH:mm + true + + + + com.baeldung.performancetests.model.source.SourceOrder + com.baeldung.performancetests.model.destination.Order + + status + orderStatus + + + + com.baeldung.performancetests.model.source.SourceCode + com.baeldung.performancetests.model.destination.DestinationCode + + \ No newline at end of file diff --git a/performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java b/performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java new file mode 100644 index 0000000000..9a45f032a6 --- /dev/null +++ b/performance-tests/src/test/java/com/baeldung/performancetests/benchmark/MappingFrameworksPerformance.java @@ -0,0 +1,193 @@ +package com.baeldung.performancetests.benchmark; + +import com.baeldung.performancetests.dozer.DozerConverter; +import com.baeldung.performancetests.jmapper.JMapperConverter; +import com.baeldung.performancetests.mapstruct.MapStructConverter; +import com.baeldung.performancetests.model.destination.DestinationCode; +import com.baeldung.performancetests.model.source.*; +import com.baeldung.performancetests.model.destination.Order; +import com.baeldung.performancetests.modelmapper.ModelMapperConverter; +import com.baeldung.performancetests.orika.OrikaConverter; +import org.junit.Assert; +import org.junit.Test; +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.runner.RunnerException; + +import java.io.IOException; +import java.math.BigDecimal; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@State(Scope.Group) +public class MappingFrameworksPerformance { + SourceOrder sourceOrder = null; + SourceCode sourceCode = null; + @Setup + public void setUp() { + User user = new User("John", "John@doe.com", AccountStatus.ACTIVE); + RefundPolicy refundPolicy = new RefundPolicy(true, 30, Collections.singletonList("Refundable only if not used!")); + + Product product = new Product(BigDecimal.valueOf(10.99), + 100, + "Sample Product", + "Sample Product to be sold", + true, + refundPolicy + ); + + Discount discount = new Discount(Instant.now().toString(), Instant.now().toString(), BigDecimal.valueOf(5.99)); + Address deliveryAddress = new Address("Washington Street 5", "New York", "55045", "USA"); + DeliveryData deliveryData = new DeliveryData(deliveryAddress, true, "", 10); + Address shopAddress = new Address("Roosvelt Street 9", "Boston", "55042", "USA"); + User reviewingUser = new User("John", "Johhny@John.com", AccountStatus.ACTIVE); + User negativeReviewingUser = new User("Carl", "Carl@Coral.com", AccountStatus.ACTIVE); + Review review = new Review(5, 5, 5, reviewingUser, "The best shop I've ever bought things in"); + + Review negativeReview = new Review(1, 1, 1, negativeReviewingUser, "I will never buy anything again here!"); + + List reviewList = new ArrayList<>(); + reviewList.add(review); + reviewList.add(negativeReview); + Shop shop = new Shop("Super Shop", shopAddress,"www.super-shop.com",reviewList); + + sourceOrder = new SourceOrder(OrderStatus.CONFIRMED, + Instant.now().toString(), + Instant.MAX.toString(), + PaymentType.TRANSFER, + discount, + deliveryData, + user, + Collections.singletonList(product), + shop, + 1 + ); + + sourceCode = new SourceCode("This is source code!"); + } + + + public void main(String[] args) throws IOException, RunnerException { + org.openjdk.jmh.Main.main(args); + } + + + @Benchmark + @Group("realLifeTest") + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + @BenchmarkMode(Mode.All) + public void orikaMapperRealLifeBenchmark() { + OrikaConverter orikaConverter = new OrikaConverter(); + Order mappedOrder = orikaConverter.convert(sourceOrder); + Assert.assertEquals(mappedOrder, sourceOrder); + + } + + @Benchmark + @Group("realLifeTest") + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + @BenchmarkMode(Mode.All) + public void jmapperRealLifeBenchmark() { + JMapperConverter jmapperConverter = new JMapperConverter(); + Order mappedOrder = jmapperConverter.convert(sourceOrder); + Assert.assertEquals(mappedOrder, sourceOrder); + } + + @Benchmark + @Group("realLifeTest") + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + @BenchmarkMode(Mode.All) + public void modelMapperRealLifeBenchmark() { + ModelMapperConverter modelMapperConverter = new ModelMapperConverter(); + Order mappedOrder = modelMapperConverter.convert(sourceOrder); + Assert.assertEquals(mappedOrder, sourceOrder); + } + + + @Benchmark + @Group("realLifeTest") + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + @BenchmarkMode(Mode.All) + public void dozerMapperRealLifeBenchmark() { + DozerConverter dozerConverter = new DozerConverter(); + Order mappedOrder = dozerConverter.convert(sourceOrder); + Assert.assertEquals(mappedOrder, sourceOrder); + + } + + @Benchmark + @Group("realLifeTest") + @Fork(value = 1, warmups = 1) + @BenchmarkMode(Mode.All) + public void mapStructRealLifeMapperBenchmark() { + MapStructConverter converter = MapStructConverter.MAPPER; + Order mappedOrder = converter.convert(sourceOrder); + Assert.assertEquals(mappedOrder, sourceOrder); + } + + @Benchmark + @Group("simpleTest") + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + @BenchmarkMode(Mode.All) + public void orikaMapperSimpleBenchmark() { + OrikaConverter orikaConverter = new OrikaConverter(); + DestinationCode mappedCode = orikaConverter.convert(sourceCode); + Assert.assertEquals(mappedCode.getCode(), sourceCode.getCode()); + + } + + @Benchmark + @Group("simpleTest") + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + @BenchmarkMode(Mode.All) + public void jmapperSimpleBenchmark() { + JMapperConverter jmapperConverter = new JMapperConverter(); + DestinationCode mappedCode = jmapperConverter.convert(sourceCode); + Assert.assertEquals(mappedCode.getCode(), sourceCode.getCode()); + } + + @Benchmark + @Group("simpleTest") + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + @BenchmarkMode(Mode.All) + public void modelMapperBenchmark() { + ModelMapperConverter modelMapperConverter = new ModelMapperConverter(); + DestinationCode mappedCode = modelMapperConverter.convert(sourceCode); + Assert.assertEquals(mappedCode.getCode(), sourceCode.getCode()); + } + + + @Benchmark + @Group("simpleTest") + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + @BenchmarkMode(Mode.All) + public void dozerMapperSimpleBenchmark() { + DozerConverter dozerConverter = new DozerConverter(); + Order mappedOrder = dozerConverter.convert(sourceOrder); + Assert.assertEquals(mappedOrder, sourceOrder); + + } + + @Benchmark + @Group("simpleTest") + @Fork(value = 1, warmups = 1) + @OutputTimeUnit(TimeUnit.MILLISECONDS) + @BenchmarkMode(Mode.All) + public void mapStructMapperSimpleBenchmark() { + MapStructConverter converter = MapStructConverter.MAPPER; + DestinationCode mappedCode = converter.convert(sourceCode); + Assert.assertEquals(mappedCode.getCode(), sourceCode.getCode()); + } + + +} diff --git a/performance-tests/src/test/resources/dozer-mapping.xml b/performance-tests/src/test/resources/dozer-mapping.xml new file mode 100644 index 0000000000..7484812431 --- /dev/null +++ b/performance-tests/src/test/resources/dozer-mapping.xml @@ -0,0 +1,21 @@ + + + + + true + MM/dd/yyyy HH:mm + true + + + + com.baeldung.performancetests.model.source.SourceOrder + com.baeldung.performancetests.model.destination.Order + + status + orderStatus + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3ba6b0c8df..78e0fa925e 100644 --- a/pom.xml +++ b/pom.xml @@ -256,6 +256,7 @@ persistence-modules/java-jdbi jersey java-spi + performance-tests From 635cd110b3e2ac968efb5e023b08a7a870b7946d Mon Sep 17 00:00:00 2001 From: Karan Khanna Date: Tue, 8 May 2018 18:48:04 +0200 Subject: [PATCH 20/93] code samples for spring data key value BAEL-1467 --- spring-data-keyvalue/pom.xml | 39 ++++++++ .../spring/data/keyvalue/Configurations.java | 28 ++++++ .../SpringDataKeyValueApplication.java | 15 ++++ .../repositories/EmployeeRepository.java | 10 +++ .../keyvalue/services/EmployeeService.java | 19 ++++ .../EmployeeServicesWithKeyValueTemplate.java | 57 ++++++++++++ .../impl/EmployeeServicesWithRepository.java | 48 ++++++++++ .../spring/data/keyvalue/vo/Employee.java | 68 ++++++++++++++ ...loyeeServicesWithKeyValueTemplateTest.java | 88 +++++++++++++++++++ .../EmployeeServicesWithRepositoryTest.java | 73 +++++++++++++++ 10 files changed, 445 insertions(+) create mode 100644 spring-data-keyvalue/pom.xml create mode 100644 spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/Configurations.java create mode 100644 spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/SpringDataKeyValueApplication.java create mode 100644 spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/repositories/EmployeeRepository.java create mode 100644 spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/EmployeeService.java create mode 100644 spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/impl/EmployeeServicesWithKeyValueTemplate.java create mode 100644 spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/impl/EmployeeServicesWithRepository.java create mode 100644 spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/vo/Employee.java create mode 100644 spring-data-keyvalue/src/test/java/com/baeldung/spring/data/keyvalue/services/test/EmployeeServicesWithKeyValueTemplateTest.java create mode 100644 spring-data-keyvalue/src/test/java/com/baeldung/spring/data/keyvalue/services/test/EmployeeServicesWithRepositoryTest.java diff --git a/spring-data-keyvalue/pom.xml b/spring-data-keyvalue/pom.xml new file mode 100644 index 0000000000..1b77667e0e --- /dev/null +++ b/spring-data-keyvalue/pom.xml @@ -0,0 +1,39 @@ + + 4.0.0 + com.baeldung + spring-data-keyvalue + 1.0 + + + org.springframework.boot + spring-boot-starter-parent + 2.0.1.RELEASE + + + + + 2.0.3.RELEASE + + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.data + spring-data-keyvalue + ${spring-data-keyvalue.version} + + + + org.springframework.boot + spring-boot-starter-test + 1.5.12.RELEASE + + + + \ No newline at end of file diff --git a/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/Configurations.java b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/Configurations.java new file mode 100644 index 0000000000..c762c00333 --- /dev/null +++ b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/Configurations.java @@ -0,0 +1,28 @@ +package com.baeldung.spring.data.keyvalue; + +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.keyvalue.core.KeyValueAdapter; +import org.springframework.data.keyvalue.core.KeyValueOperations; +import org.springframework.data.keyvalue.core.KeyValueTemplate; +import org.springframework.data.map.MapKeyValueAdapter; + +@Configuration +public class Configurations { + + //To be used only if @EnableMapRepositories is not used. + //Else @EnableMapRepositories gives us a template as well. + @Bean("keyValueTemplate") + public KeyValueOperations keyValueTemplate() { + return new KeyValueTemplate(keyValueAdapter()); + + } + + @Bean + public KeyValueAdapter keyValueAdapter() { + return new MapKeyValueAdapter(ConcurrentHashMap.class); + } + +} diff --git a/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/SpringDataKeyValueApplication.java b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/SpringDataKeyValueApplication.java new file mode 100644 index 0000000000..6a5b5264df --- /dev/null +++ b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/SpringDataKeyValueApplication.java @@ -0,0 +1,15 @@ +package com.baeldung.spring.data.keyvalue; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.map.repository.config.EnableMapRepositories; + +@SpringBootApplication +@EnableMapRepositories +public class SpringDataKeyValueApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringDataKeyValueApplication.class, args); + } + +} diff --git a/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/repositories/EmployeeRepository.java b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/repositories/EmployeeRepository.java new file mode 100644 index 0000000000..5b7545d5b6 --- /dev/null +++ b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/repositories/EmployeeRepository.java @@ -0,0 +1,10 @@ +package com.baeldung.spring.data.keyvalue.repositories; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import com.baeldung.spring.data.keyvalue.vo.Employee; + +@Repository("employeeRepository") +public interface EmployeeRepository extends CrudRepository { +} \ No newline at end of file diff --git a/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/EmployeeService.java b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/EmployeeService.java new file mode 100644 index 0000000000..dd89609be7 --- /dev/null +++ b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/EmployeeService.java @@ -0,0 +1,19 @@ +package com.baeldung.spring.data.keyvalue.services; + +import com.baeldung.spring.data.keyvalue.vo.Employee; + +public interface EmployeeService { + + void save(Employee employee); + + Employee get(Integer id); + + Iterable fetchAll(); + + void update(Employee employee); + + void delete(Integer id); + + Iterable getSortedListOfEmployeesBySalary(); + +} diff --git a/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/impl/EmployeeServicesWithKeyValueTemplate.java b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/impl/EmployeeServicesWithKeyValueTemplate.java new file mode 100644 index 0000000000..26f1756add --- /dev/null +++ b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/impl/EmployeeServicesWithKeyValueTemplate.java @@ -0,0 +1,57 @@ +package com.baeldung.spring.data.keyvalue.services.impl; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.DependsOn; +import org.springframework.data.domain.Sort; +import org.springframework.data.keyvalue.core.KeyValueTemplate; +import org.springframework.data.keyvalue.core.query.KeyValueQuery; +import org.springframework.stereotype.Service; + +import com.baeldung.spring.data.keyvalue.services.EmployeeService; +import com.baeldung.spring.data.keyvalue.vo.Employee; + +@Service("employeeServicesWithKeyValueTemplate") +@DependsOn("keyValueTemplate") +public class EmployeeServicesWithKeyValueTemplate implements EmployeeService { + + @Autowired + @Qualifier("keyValueTemplate") + KeyValueTemplate keyValueTemplate; + + @Override + public void save(Employee employee) { + keyValueTemplate.insert(employee); + } + + @Override + public Employee get(Integer id) { + Optional employee = keyValueTemplate.findById(id, Employee.class); + return employee.isPresent() ? employee.get() : null; + } + + @Override + public Iterable fetchAll() { + return keyValueTemplate.findAll(Employee.class); + } + + @Override + public void update(Employee employee) { + keyValueTemplate.update(employee); + } + + @Override + public void delete(Integer id) { + keyValueTemplate.delete(id, Employee.class); + } + + @Override + public Iterable getSortedListOfEmployeesBySalary() { + KeyValueQuery query = new KeyValueQuery(); + query.setSort(new Sort(Sort.Direction.DESC, "salary")); + return keyValueTemplate.find(query, Employee.class); + } + +} diff --git a/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/impl/EmployeeServicesWithRepository.java b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/impl/EmployeeServicesWithRepository.java new file mode 100644 index 0000000000..73f3493a6b --- /dev/null +++ b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/services/impl/EmployeeServicesWithRepository.java @@ -0,0 +1,48 @@ +package com.baeldung.spring.data.keyvalue.services.impl; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baeldung.spring.data.keyvalue.repositories.EmployeeRepository; +import com.baeldung.spring.data.keyvalue.services.EmployeeService; +import com.baeldung.spring.data.keyvalue.vo.Employee; + +@Service("employeeServicesWithRepository") +public class EmployeeServicesWithRepository implements EmployeeService { + + @Autowired + EmployeeRepository employeeRepository; + + + @Override + public void save(Employee employee) { + employeeRepository.save(employee); + } + + @Override + public Iterable fetchAll() { + return employeeRepository.findAll(); + + } + + @Override + public Employee get(Integer id) { + return employeeRepository.findById(id).get(); + } + + @Override + public void update(Employee employee) { + employeeRepository.save(employee); + + } + + @Override + public void delete(Integer id) { + employeeRepository.deleteById(id); + } + + public Iterable getSortedListOfEmployeesBySalary() { + throw new RuntimeException("Method not supported by CRUDRepository"); + } + +} diff --git a/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/vo/Employee.java b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/vo/Employee.java new file mode 100644 index 0000000000..208e6e1735 --- /dev/null +++ b/spring-data-keyvalue/src/main/java/com/baeldung/spring/data/keyvalue/vo/Employee.java @@ -0,0 +1,68 @@ +package com.baeldung.spring.data.keyvalue.vo; + +import java.io.Serializable; + +import org.springframework.data.annotation.Id; +import org.springframework.data.keyvalue.annotation.KeySpace; + +@KeySpace("employees") +public class Employee implements Serializable { + + @Id + private Integer id; + + private String name; + + private String department; + + private String salary; + + public Employee(Integer id, String name, String department, String salary) { + this.id = id; + this.name = name; + this.department = department; + this.salary = salary; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDepartment() { + return department; + } + + public void setDepartment(String department) { + this.department = department; + } + + public String getSalary() { + return salary; + } + + public void setSalary(String salary) { + this.salary = salary; + } + + @Override + public String toString() { + return "Employee{" + + "id=" + id + + ", name='" + name + '\'' + + ", department='" + department + '\'' + + ", salary='" + salary + '\'' + + '}'; + } +} diff --git a/spring-data-keyvalue/src/test/java/com/baeldung/spring/data/keyvalue/services/test/EmployeeServicesWithKeyValueTemplateTest.java b/spring-data-keyvalue/src/test/java/com/baeldung/spring/data/keyvalue/services/test/EmployeeServicesWithKeyValueTemplateTest.java new file mode 100644 index 0000000000..78e985fe4b --- /dev/null +++ b/spring-data-keyvalue/src/test/java/com/baeldung/spring/data/keyvalue/services/test/EmployeeServicesWithKeyValueTemplateTest.java @@ -0,0 +1,88 @@ +package com.baeldung.spring.data.keyvalue.services.test; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.keyvalue.core.KeyValueTemplate; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.data.keyvalue.SpringDataKeyValueApplication; +import com.baeldung.spring.data.keyvalue.services.EmployeeService; +import com.baeldung.spring.data.keyvalue.vo.Employee; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = SpringDataKeyValueApplication.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class EmployeeServicesWithKeyValueTemplateTest { + + @Autowired + @Qualifier("employeeServicesWithKeyValueTemplate") + EmployeeService employeeService; + + @Autowired + @Qualifier("keyValueTemplate") + KeyValueTemplate keyValueTemplate; + + static Employee employee1; + + static Employee employee2; + + @BeforeClass + public static void setUp() { + employee1 = new Employee(1, "Karan", "IT", "5000"); + employee2 = new Employee(2, "Jack", "HR", "2000"); + } + + @Test + public void test1_whenEmployeeSaved_thenEmployeeIsAddedToMap() { + employeeService.save(employee1); + assertEquals(keyValueTemplate.findById(1, Employee.class).get(), employee1); + } + + @Test + public void test2_whenEmployeeGet_thenEmployeeIsReturnedFromMap() { + Employee employeeFetched = employeeService.get(1); + assertEquals(employeeFetched, employee1); + } + + @Test + public void test3_whenEmployeesFetched_thenEmployeesAreReturnedFromMap() { + List employees = (List)employeeService.fetchAll(); + assertEquals(employees.size(), 1); + assertEquals(employees.get(0), employee1); + } + + @Test + public void test4_whenEmployeeUpdated_thenEmployeeIsUpdatedToMap() { + employee1.setName("Pawan"); + employeeService.update(employee1); + assertEquals(keyValueTemplate.findById(1, Employee.class).get().getName(),"Pawan"); + } + + @Test + public void test5_whenSortedEmployeesFetched_thenEmployeesAreReturnedFromMapInOrder() { + employeeService.save(employee2); + List employees = (List)employeeService.getSortedListOfEmployeesBySalary(); + assertEquals(employees.size(), 2); + assertEquals(employees.get(0), employee1); + assertEquals(employees.get(1), employee2); + } + + @Test + public void test6_whenEmployeeDeleted_thenEmployeeIsRemovedMap() { + employeeService.delete(1); + assertEquals(keyValueTemplate.findById(1, Employee.class).isPresent(), false); + } + + + +} diff --git a/spring-data-keyvalue/src/test/java/com/baeldung/spring/data/keyvalue/services/test/EmployeeServicesWithRepositoryTest.java b/spring-data-keyvalue/src/test/java/com/baeldung/spring/data/keyvalue/services/test/EmployeeServicesWithRepositoryTest.java new file mode 100644 index 0000000000..5b32728893 --- /dev/null +++ b/spring-data-keyvalue/src/test/java/com/baeldung/spring/data/keyvalue/services/test/EmployeeServicesWithRepositoryTest.java @@ -0,0 +1,73 @@ +package com.baeldung.spring.data.keyvalue.services.test; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.baeldung.spring.data.keyvalue.SpringDataKeyValueApplication; +import com.baeldung.spring.data.keyvalue.repositories.EmployeeRepository; +import com.baeldung.spring.data.keyvalue.services.EmployeeService; +import com.baeldung.spring.data.keyvalue.vo.Employee; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = SpringDataKeyValueApplication.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class EmployeeServicesWithRepositoryTest { + + @Autowired + @Qualifier("employeeServicesWithRepository") + EmployeeService employeeService; + + @Autowired + EmployeeRepository employeeRepository; + + static Employee employee1; + + @BeforeClass + public static void setUp() { + employee1 = new Employee(1, "Karan", "IT", "5000"); + } + + @Test + public void test1_whenEmployeeSaved_thenEmployeeIsAddedToMap() { + employeeService.save(employee1); + assertEquals(employeeRepository.findById(1).get(), employee1); + } + + @Test + public void test2_whenEmployeeGet_thenEmployeeIsReturnedFromMap() { + Employee employeeFetched = employeeService.get(1); + assertEquals(employeeFetched, employee1); + } + + @Test + public void test3_whenEmployeesFetched_thenEmployeesAreReturnedFromMap() { + List employees = (List)employeeService.fetchAll(); + assertEquals(employees.size(), 1); + assertEquals(employees.get(0), employee1); + } + + @Test + public void test4_whenEmployeeUpdated_thenEmployeeIsUpdatedToMap() { + employee1.setName("Pawan"); + employeeService.update(employee1); + assertEquals(employeeRepository.findById(1).get().getName(),"Pawan"); + } + + @Test + public void test5_whenEmployeeDeleted_thenEmployeeIsRemovedMap() { + employeeService.delete(1); + assertEquals(employeeRepository.findById(1).isPresent(), false); + } + +} From b2e489ca6460eb2316ff5f56830b2096685fb855 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Tue, 8 May 2018 21:16:49 +0300 Subject: [PATCH 21/93] emptyiterable ex --- .../java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java b/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java index 6b9cee1992..0ddeab90a1 100644 --- a/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java +++ b/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java @@ -12,6 +12,7 @@ import static org.hamcrest.Matchers.hasItems; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertThat; +import static org.hamcrest.Matchers.emptyIterable; import java.util.Collections; import java.util.List; @@ -56,6 +57,7 @@ public class HamcrestExamplesUnitTest { public final void givenCollectionIsEmpty_whenChecking_thenEmpty() { final List collection = Lists.newArrayList(); assertThat(collection, empty()); + assertThat(collection, emptyIterable()); } @Test From 4e7efb139583cc7c1ee8af748286bcda7103134a Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Tue, 8 May 2018 21:20:53 +0300 Subject: [PATCH 22/93] emptyiterable ex --- .../org/baeldung/hamcrest/HamcrestExamplesUnitTest.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java b/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java index 0ddeab90a1..efecc39bcd 100644 --- a/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java +++ b/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java @@ -59,6 +59,12 @@ public class HamcrestExamplesUnitTest { assertThat(collection, empty()); assertThat(collection, emptyIterable()); } + + @Test + public final void givenIterableIsEmpty_whenChecking_thenEmpty() { + final Iterable collection = Lists.newArrayList(); + assertThat(collection, emptyIterable()); + } @Test public final void givenCollectionIsNotEmpty_whenChecking_thenNotEmpty() { From 75afb5da3e4e0cecbbd93aca67997c0a2dfc5c82 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Tue, 8 May 2018 21:21:22 +0300 Subject: [PATCH 23/93] emptyiterable ex --- .../java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java b/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java index efecc39bcd..82b6b8c87c 100644 --- a/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java +++ b/guava/src/test/java/org/baeldung/hamcrest/HamcrestExamplesUnitTest.java @@ -57,7 +57,6 @@ public class HamcrestExamplesUnitTest { public final void givenCollectionIsEmpty_whenChecking_thenEmpty() { final List collection = Lists.newArrayList(); assertThat(collection, empty()); - assertThat(collection, emptyIterable()); } @Test From 08c0b590b04b5e23018fe5846cd282e81201731a Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Tue, 8 May 2018 22:04:21 +0300 Subject: [PATCH 24/93] upgrade bootstrap project --- spring-boot-bootstrap/pom.xml | 4 ++-- .../org/baeldung/config/SecurityConfig.java | 20 +++++++++++++++++++ .../persistence/repo/BookRepository.java | 1 - .../java/org/baeldung/web/BookController.java | 12 ++++++----- .../src/main/resources/application.properties | 6 ++---- .../SpringBootBootstrapIntegrationTest.java | 10 +++------- 6 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 spring-boot-bootstrap/src/main/java/org/baeldung/config/SecurityConfig.java diff --git a/spring-boot-bootstrap/pom.xml b/spring-boot-bootstrap/pom.xml index 1ec9af8189..03ce9b6906 100644 --- a/spring-boot-bootstrap/pom.xml +++ b/spring-boot-bootstrap/pom.xml @@ -9,10 +9,10 @@ Demo project for Spring Boot - parent-boot-5 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-2 - - + + - - contextClass - - org.springframework.web.context.support.AnnotationConfigWebApplicationContext - - - - contextConfigLocation - org.baeldung.spring.web.config - - - - org.springframework.web.context.ContextLoaderListener - - - - - mvc - org.springframework.web.servlet.DispatcherServlet - 1 - - - mvc - / - - - - index.html - - - \ No newline at end of file From 8d05a42c30ddadae90f9877cee77ffd85fc5ff1a Mon Sep 17 00:00:00 2001 From: Nikhil Khatwani Date: Wed, 9 May 2018 18:03:35 +0530 Subject: [PATCH 27/93] Changes for BAEL-1657 --- .../DeferredResultController.java | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) rename {spring-boot/src/main/java/com/baeldung/servlets => spring-rest/src/main/java/com/baeldung/controllers}/DeferredResultController.java (76%) diff --git a/spring-boot/src/main/java/com/baeldung/servlets/DeferredResultController.java b/spring-rest/src/main/java/com/baeldung/controllers/DeferredResultController.java similarity index 76% rename from spring-boot/src/main/java/com/baeldung/servlets/DeferredResultController.java rename to spring-rest/src/main/java/com/baeldung/controllers/DeferredResultController.java index c43b0e6dc0..c61d51e1af 100644 --- a/spring-boot/src/main/java/com/baeldung/servlets/DeferredResultController.java +++ b/spring-rest/src/main/java/com/baeldung/controllers/DeferredResultController.java @@ -1,4 +1,4 @@ -package com.baeldung.servlets; +package com.baeldung.controllers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.async.DeferredResult; +import java.util.concurrent.ForkJoinPool; + @RestController public class DeferredResultController { @@ -16,14 +18,18 @@ public class DeferredResultController { @GetMapping("/async-deferredresult") public DeferredResult> handleReqDefResult(Model model) { - LOG.info("Received async-deferredresult request"); - DeferredResult> output = new DeferredResult<>(); - new Thread(() -> { - LOG.info("Processing in separate thread"); - output.setResult(ResponseEntity.ok("ok")); - }).start(); - LOG.info("servlet thread freed"); - return output; + LOG.info("Received async-deferredresult request"); + DeferredResult> output = new DeferredResult<>(); + ForkJoinPool.commonPool().submit(() -> { + LOG.info("Processing in separate thread"); + try { + Thread.sleep(6000); + } catch (InterruptedException e) { + } + output.setResult(ResponseEntity.ok("ok")); + }); + LOG.info("servlet thread freed"); + return output; } public DeferredResult> handleReqWithTimeouts(Model model) { @@ -36,8 +42,7 @@ public class DeferredResultController { ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT).body("Request timeout occurred.")); } }); - - new Thread(() -> { + ForkJoinPool.commonPool().submit(() -> { LOG.info("Processing in separate thread"); try { Thread.sleep(600l); @@ -48,14 +53,14 @@ public class DeferredResultController { .body("INTERNAL_SERVER_ERROR occurred.")); } - }).start(); + }); LOG.info("servlet thread freed"); return deferredResult; } public DeferredResult> handleAsyncFailedRequest(Model model) { DeferredResult> deferredResult = new DeferredResult<>(); - new Thread(() -> { + ForkJoinPool.commonPool().submit(() -> { try { // Exception occurred in processing throw new Exception(); @@ -64,7 +69,7 @@ public class DeferredResultController { deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("INTERNAL_SERVER_ERROR occurred.")); } - }).start(); + }); return deferredResult; } From 475931974b425314433df55bd8e032114b5021eb Mon Sep 17 00:00:00 2001 From: KevinGilmore Date: Thu, 10 May 2018 07:31:19 -0500 Subject: [PATCH 28/93] README links for BAEL-82 and BAEL-1722 (#4210) * BAEL-1612: Update README * BAEL-1562: Update README * BAEL-1562: Update README * BAEL-1679: Update README * BAEL-1701: Update README * Added article links to README files --- patterns/README.md | 1 + spring-all/README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/patterns/README.md b/patterns/README.md index f00e7c351d..df39b39224 100644 --- a/patterns/README.md +++ b/patterns/README.md @@ -3,4 +3,5 @@ - [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java) - [Implementing the Template Method Pattern in Java](http://www.baeldung.com/java-template-method-pattern) - [Chain of Responsibility Design Pattern in Java](http://www.baeldung.com/chain-of-responsibility-pattern) +- [The Command Pattern in Java](http://www.baeldung.com/java-command-pattern) diff --git a/spring-all/README.md b/spring-all/README.md index a3e1ca5464..173f410620 100644 --- a/spring-all/README.md +++ b/spring-all/README.md @@ -27,3 +27,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [A Guide To Caching in Spring](http://www.baeldung.com/spring-cache-tutorial) - [How To Do @Async in Spring](http://www.baeldung.com/spring-async) - [Quick Guide to the Spring @Order Annotation](http://www.baeldung.com/spring-order) +- [Spring Web Contexts](http://www.baeldung.com/spring-web-contexts) From c0c319b13f5fef8c360b6090293e1c2e96e5bfb6 Mon Sep 17 00:00:00 2001 From: Patryk Kucharz Date: Mon, 30 Apr 2018 16:33:50 +0200 Subject: [PATCH 29/93] BAEL-1713: Pessimistic Locking in JPA Tests for the article. --- .../com/baeldung/hibernate/HibernateUtil.java | 38 ++--- .../hibernate/pessimisticlocking/Address.java | 34 ++++ .../pessimisticlocking/Customer.java | 58 +++++++ .../pessimisticlocking/Individual.java | 49 ++++++ .../PessimisticLockingCourse.java | 47 ++++++ .../PessimisticLockingEmployee.java | 27 ++++ .../PessimisticLockingStudent.java | 46 ++++++ ...asicPessimisticLockingIntegrationTest.java | 151 ++++++++++++++++++ .../PessimisticLockScopesIntegrationTest.java | 100 ++++++++++++ .../hibernate-pessimistic-locking.properties | 8 + .../pessimisticlocking/Address.java | 34 ++++ .../springdata/pessimisticlocking/Course.java | 50 ++++++ .../pessimisticlocking/Customer.java | 61 +++++++ .../pessimisticlocking/Employee.java | 27 ++++ .../pessimisticlocking/Individual.java | 49 ++++++ .../pessimisticlocking/Student.java | 48 ++++++ .../src/main/resources/application.properties | 2 +- .../PessimisticLockScopesIntegrationTest.java | 103 ++++++++++++ 18 files changed, 906 insertions(+), 26 deletions(-) create mode 100644 hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java create mode 100644 hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java create mode 100644 hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java create mode 100644 hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java create mode 100644 hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java create mode 100644 hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java create mode 100644 hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java create mode 100644 hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java create mode 100644 hibernate5/src/test/resources/hibernate-pessimistic-locking.properties create mode 100644 persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Address.java create mode 100644 persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Course.java create mode 100644 persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Customer.java create mode 100644 persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Employee.java create mode 100644 persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Individual.java create mode 100644 persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Student.java create mode 100644 persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java index 130edec8cc..e8fdabebbc 100644 --- a/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java +++ b/hibernate5/src/main/java/com/baeldung/hibernate/HibernateUtil.java @@ -1,30 +1,12 @@ 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.PointEntity; -import com.baeldung.hibernate.pojo.PolygonEntity; -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 com.baeldung.hibernate.pojo.inheritance.Animal; -import com.baeldung.hibernate.pojo.inheritance.Bag; -import com.baeldung.hibernate.pojo.inheritance.Book; -import com.baeldung.hibernate.pojo.inheritance.Car; -import com.baeldung.hibernate.pojo.inheritance.MyEmployee; -import com.baeldung.hibernate.pojo.inheritance.MyProduct; -import com.baeldung.hibernate.pojo.inheritance.Pen; -import com.baeldung.hibernate.pojo.inheritance.Person; -import com.baeldung.hibernate.pojo.inheritance.Pet; -import com.baeldung.hibernate.pojo.inheritance.Vehicle; - +import com.baeldung.hibernate.pessimisticlocking.Individual; +import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingCourse; +import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingEmployee; +import com.baeldung.hibernate.pessimisticlocking.PessimisticLockingStudent; +import com.baeldung.hibernate.pojo.*; +import com.baeldung.hibernate.pojo.Person; +import com.baeldung.hibernate.pojo.inheritance.*; import org.apache.commons.lang3.StringUtils; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; @@ -82,6 +64,12 @@ public class HibernateUtil { metadataSources.addAnnotatedClass(PointEntity.class); metadataSources.addAnnotatedClass(PolygonEntity.class); metadataSources.addAnnotatedClass(com.baeldung.hibernate.pojo.Person.class); + metadataSources.addAnnotatedClass(Individual.class); + metadataSources.addAnnotatedClass(PessimisticLockingEmployee.class); + metadataSources.addAnnotatedClass(PessimisticLockingStudent.class); + metadataSources.addAnnotatedClass(PessimisticLockingCourse.class); + metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Customer.class); + metadataSources.addAnnotatedClass(com.baeldung.hibernate.pessimisticlocking.Address.class); Metadata metadata = metadataSources.buildMetadata(); return metadata.getSessionFactoryBuilder() diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java new file mode 100644 index 0000000000..c889cb6127 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Address.java @@ -0,0 +1,34 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.Embeddable; + +@Embeddable +public class Address { + + private String country; + private String city; + + public Address(String country, String city) { + this.country = country; + this.city = city; + } + + public Address() { + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java new file mode 100644 index 0000000000..cb73cbc958 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Customer.java @@ -0,0 +1,58 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class Customer { + + @Id + private Long customerId; + private String name; + private String lastName; + @ElementCollection + @CollectionTable(name = "customer_address") + private List
addressList; + + public Customer() { + } + + public Customer(Long customerId, String name, String lastName, List
addressList) { + this.customerId = customerId; + this.name = name; + this.lastName = lastName; + this.addressList = addressList; + } + + public Long getCustomerId() { + return customerId; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List
getAddressList() { + return addressList; + } + + public void setAddressList(List
addressList) { + this.addressList = addressList; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java new file mode 100644 index 0000000000..e491c09eb5 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/Individual.java @@ -0,0 +1,49 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +@Entity +@Inheritance(strategy = InheritanceType.JOINED) +public class Individual { + + @Id + private Long id; + private String name; + private String lastName; + + public Individual(Long id, String name, String lastName) { + this.id = id; + this.name = name; + this.lastName = lastName; + } + + public Individual() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java new file mode 100644 index 0000000000..aea7d5fc87 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingCourse.java @@ -0,0 +1,47 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.*; + +@Entity +public class PessimisticLockingCourse { + + @Id + private Long courseId; + private String name; + @ManyToOne + @JoinTable(name = "student_course") + private PessimisticLockingStudent student; + + public PessimisticLockingCourse(Long courseId, String name, PessimisticLockingStudent student) { + this.courseId = courseId; + this.name = name; + this.student = student; + } + + public PessimisticLockingCourse() { + } + + public Long getCourseId() { + return courseId; + } + + public void setCourseId(Long courseId) { + this.courseId = courseId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public PessimisticLockingStudent getStudent() { + return student; + } + + public void setStudent(PessimisticLockingStudent students) { + this.student = students; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java new file mode 100644 index 0000000000..a1328cbdad --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingEmployee.java @@ -0,0 +1,27 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.Entity; +import java.math.BigDecimal; + +@Entity +public class PessimisticLockingEmployee extends Individual { + + private BigDecimal salary; + + public PessimisticLockingEmployee(Long id, String name, String lastName, BigDecimal salary) { + super(id, name, lastName); + this.salary = salary; + } + + public PessimisticLockingEmployee() { + super(); + } + + public BigDecimal getSalary() { + return salary; + } + + public void setSalary(BigDecimal average) { + this.salary = average; + } +} diff --git a/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java new file mode 100644 index 0000000000..e6c5f476b4 --- /dev/null +++ b/hibernate5/src/main/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockingStudent.java @@ -0,0 +1,46 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class PessimisticLockingStudent { + + @Id + private Long id; + private String name; + @OneToMany(mappedBy = "student") + private List courses; + + public PessimisticLockingStudent(Long id, String name) { + this.id = id; + this.name = name; + } + + public PessimisticLockingStudent() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getCourses() { + return courses; + } + + public void setCourses(List courses) { + this.courses = courses; + } +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java new file mode 100644 index 0000000000..f416c11d1f --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/BasicPessimisticLockingIntegrationTest.java @@ -0,0 +1,151 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import com.baeldung.hibernate.HibernateUtil; +import com.vividsolutions.jts.util.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.persistence.*; +import java.io.IOException; +import java.util.Arrays; + +public class BasicPessimisticLockingIntegrationTest { + + @BeforeClass + public static void setUp() throws IOException { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent student = new PessimisticLockingStudent(1L, "JOHN"); + PessimisticLockingCourse course = new PessimisticLockingCourse(1L, "MATH", student); + student.setCourses(Arrays.asList(course)); + entityManager.persist(course); + entityManager.persist(student); + entityManager.getTransaction() + .commit(); + entityManager.close(); + } + + @Test + public void givenFoundRecordWithPessimisticRead_whenFindingNewOne_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + entityManager.find(PessimisticLockingStudent.class, 1L, LockModeType.PESSIMISTIC_READ); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + entityManager2.find(PessimisticLockingStudent.class, 1L, LockModeType.PESSIMISTIC_READ); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordWithPessimisticReadQuery_whenQueryingNewOne_PessimisticLockExceptionThrown() throws IOException { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + Query query = entityManager.createQuery("from Student where studentId = :studentId"); + query.setParameter("studentId", 1L); + query.setLockMode(LockModeType.PESSIMISTIC_WRITE); + query.getResultList(); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + Query query2 = entityManager2.createQuery("from Student where studentId = :studentId"); + query2.setParameter("studentId", 1L); + query2.setLockMode(LockModeType.PESSIMISTIC_READ); + query2.getResultList(); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordWithPessimisticReadLock_whenFindingNewOne_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent = entityManager.find(PessimisticLockingStudent.class, 1L); + entityManager.lock(resultStudent, LockModeType.PESSIMISTIC_READ); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + entityManager2.find(PessimisticLockingStudent.class, 1L, LockModeType.PESSIMISTIC_FORCE_INCREMENT); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordAndRefreshWithPessimisticRead_whenFindingWithPessimisticWrite_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent = entityManager.find(PessimisticLockingStudent.class, 1L); + entityManager.refresh(resultStudent, LockModeType.PESSIMISTIC_FORCE_INCREMENT); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + entityManager2.find(PessimisticLockingStudent.class, 1L, LockModeType.PESSIMISTIC_WRITE); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordWithPessimisticRead_whenUpdatingRecord_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent = entityManager.find(PessimisticLockingStudent.class, 1L); + entityManager.refresh(resultStudent, LockModeType.PESSIMISTIC_READ); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent2 = entityManager2.find(PessimisticLockingStudent.class, 1L); + resultStudent2.setName("Change"); + entityManager2.persist(resultStudent2); + entityManager2.getTransaction() + .commit(); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + @Test + public void givenRecordWithPessimisticWrite_whenUpdatingRecord_PessimisticLockExceptionThrown() { + try { + EntityManager entityManager = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent = entityManager.find(PessimisticLockingStudent.class, 1L); + entityManager.refresh(resultStudent, LockModeType.PESSIMISTIC_WRITE); + + EntityManager entityManager2 = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent resultStudent2 = entityManager2.find(PessimisticLockingStudent.class, 1L); + resultStudent2.setName("Change"); + entityManager2.persist(resultStudent2); + entityManager2.getTransaction() + .commit(); + + entityManager.close(); + entityManager2.close(); + } catch (Exception e) { + Assert.isTrue(e instanceof PessimisticLockException); + } + } + + protected static EntityManager getEntityManagerWithOpenTransaction() throws IOException { + String propertyFileName = "hibernate-pessimistic-locking.properties"; + EntityManager entityManager = HibernateUtil.getSessionFactory(propertyFileName) + .openSession(); + entityManager.getTransaction() + .begin(); + + return entityManager; + } + +} diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java new file mode 100644 index 0000000000..c774c6eaa4 --- /dev/null +++ b/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java @@ -0,0 +1,100 @@ +package com.baeldung.hibernate.pessimisticlocking; + +import com.baeldung.hibernate.HibernateUtil; +import org.junit.Test; + +import javax.persistence.EntityManager; +import javax.persistence.LockModeType; +import javax.persistence.PessimisticLockScope; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class PessimisticLockScopesIntegrationTest { + + @Test + public void givenEclipseEntityWithJoinInheritance_whenNormalLock_thenShouldChildAndParentEntity() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + PessimisticLockingEmployee employee = new PessimisticLockingEmployee(1L, "A", "B", new BigDecimal(4.5)); + em.persist(employee); + em.getTransaction() + .commit(); + em.close(); + + // NORMAL SCOPE + em = getEntityManagerWithOpenTransaction(); + PessimisticLockingEmployee foundEmployee = em.find(PessimisticLockingEmployee.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em.getTransaction() + .rollback(); + + // EXTENDED SCOPE + Map map = new HashMap<>(); + map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + + em = getEntityManagerWithOpenTransaction(); + foundEmployee = em.find(PessimisticLockingEmployee.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + } + + @Test + public void givenEclipseEntityWithElementCollection_whenNormalLock_thenShouldLockOnlyOwningEntity() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + Address address = new Address("Poland", "Warsaw"); + Customer customer = new Customer(1L, "A", "B", Arrays.asList(address)); + em.persist(customer); + em.getTransaction() + .commit(); + em.close(); + + // NORMAL SCOPE + em = getEntityManagerWithOpenTransaction(); + Customer foundCustomer = em.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em.getTransaction() + .rollback(); + + // EXTENDED SCOPE + Map map = new HashMap<>(); + map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + + em = getEntityManagerWithOpenTransaction(); + foundCustomer = em.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + } + + @Test + public void givenEclipseEntityWithOneToMany_whenNormalLock_thenShouldLockOnlyOwningEntity() throws IOException { + EntityManager em = getEntityManagerWithOpenTransaction(); + PessimisticLockingStudent student = new PessimisticLockingStudent(1L, "JOE"); + PessimisticLockingCourse course = new PessimisticLockingCourse(1L, "COURSE", student); + student.setCourses(Arrays.asList(course)); + em.persist(course); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + + // NORMAL SCOPE + em = getEntityManagerWithOpenTransaction(); + PessimisticLockingCourse foundCourse = em.find(PessimisticLockingCourse.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em.getTransaction() + .rollback(); + + // EXTENDED SCOPE + Map map = new HashMap<>(); + map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + + em = getEntityManagerWithOpenTransaction(); + foundCourse = em.find(PessimisticLockingCourse.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + } + + protected EntityManager getEntityManagerWithOpenTransaction() throws IOException { + String propertyFileName = "hibernate-pessimistic-locking.properties"; + EntityManager entityManager = HibernateUtil.getSessionFactory(propertyFileName) + .openSession(); + entityManager.getTransaction() + .begin(); + + return entityManager; + } + +} diff --git a/hibernate5/src/test/resources/hibernate-pessimistic-locking.properties b/hibernate5/src/test/resources/hibernate-pessimistic-locking.properties new file mode 100644 index 0000000000..c76bd3358b --- /dev/null +++ b/hibernate5/src/test/resources/hibernate-pessimistic-locking.properties @@ -0,0 +1,8 @@ +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:mem:mydb1;DB_CLOSE_DELAY=-1;LOCK_TIMEOUT=100;MVCC=FALSE +hibernate.connection.username=sa +hibernate.connection.autocommit=true +hibernate.dialect=org.hibernate.dialect.H2Dialect + +hibernate.show_sql=true +hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Address.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Address.java new file mode 100644 index 0000000000..b62889208c --- /dev/null +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Address.java @@ -0,0 +1,34 @@ +package com.baeldung.eclipselink.springdata.pessimisticlocking; + +import javax.persistence.Embeddable; + +@Embeddable +public class Address { + + private String country; + private String city; + + public Address(String country, String city) { + this.country = country; + this.city = city; + } + + public Address() { + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } +} diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Course.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Course.java new file mode 100644 index 0000000000..8d90659f3e --- /dev/null +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Course.java @@ -0,0 +1,50 @@ +package com.baeldung.eclipselink.springdata.pessimisticlocking; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinTable; +import javax.persistence.ManyToOne; + +@Entity +public class Course { + + @Id + private Long courseId; + private String name; + @ManyToOne + @JoinTable(name = "student_course") + private Student student; + + public Course(Long courseId, String name, Student student) { + this.courseId = courseId; + this.name = name; + this.student = student; + } + + public Course() { + } + + public Long getCourseId() { + return courseId; + } + + public void setCourseId(Long courseId) { + this.courseId = courseId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Student getStudent() { + return student; + } + + public void setStudent(Student students) { + this.student = students; + } +} diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Customer.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Customer.java new file mode 100644 index 0000000000..f06a676de8 --- /dev/null +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Customer.java @@ -0,0 +1,61 @@ +package com.baeldung.eclipselink.springdata.pessimisticlocking; + +import javax.persistence.CollectionTable; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.Id; +import java.util.List; + +@Entity +public class Customer { + + @Id + private Long customerId; + private String name; + private String lastName; + @ElementCollection + @CollectionTable(name = "customer_address") + private List
addressList; + + public Customer() { + } + + public Customer(Long customerId, String name, String lastName, List
addressList) { + this.customerId = customerId; + this.name = name; + this.lastName = lastName; + this.addressList = addressList; + } + + public Long getCustomerId() { + return customerId; + } + + public void setCustomerId(Long customerId) { + this.customerId = customerId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public List
getAddressList() { + return addressList; + } + + public void setAddressList(List
addressList) { + this.addressList = addressList; + } +} diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Employee.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Employee.java new file mode 100644 index 0000000000..d09b123225 --- /dev/null +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Employee.java @@ -0,0 +1,27 @@ +package com.baeldung.eclipselink.springdata.pessimisticlocking; + +import javax.persistence.Entity; +import java.math.BigDecimal; + +@Entity +public class Employee extends Individual { + + private BigDecimal salary; + + public Employee(Long id, String name, String lastName, BigDecimal salary) { + super(id, name, lastName); + this.salary = salary; + } + + public Employee() { + super(); + } + + public BigDecimal getSalary() { + return salary; + } + + public void setSalary(BigDecimal average) { + this.salary = average; + } +} diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Individual.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Individual.java new file mode 100644 index 0000000000..7edaaace54 --- /dev/null +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Individual.java @@ -0,0 +1,49 @@ +package com.baeldung.eclipselink.springdata.pessimisticlocking; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +@Entity +@Inheritance(strategy = InheritanceType.JOINED) +public class Individual { + + @Id + private Long id; + private String name; + private String lastName; + + public Individual(Long id, String name, String lastName) { + this.id = id; + this.name = name; + this.lastName = lastName; + } + + public Individual() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Student.java b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Student.java new file mode 100644 index 0000000000..f613aab0f6 --- /dev/null +++ b/persistence-modules/spring-data-eclipselink/src/main/java/com/baeldung/eclipselink/springdata/pessimisticlocking/Student.java @@ -0,0 +1,48 @@ +package com.baeldung.eclipselink.springdata.pessimisticlocking; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import java.util.List; + +@Entity +public class Student { + + @Id + private Long id; + private String name; + @OneToMany(mappedBy = "student") + private List courses; + + public Student(Long id, String name) { + this.id = id; + this.name = name; + } + + public Student() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getCourses() { + return courses; + } + + public void setCourses(List courses) { + this.courses = courses; + } +} diff --git a/persistence-modules/spring-data-eclipselink/src/main/resources/application.properties b/persistence-modules/spring-data-eclipselink/src/main/resources/application.properties index 549c0b4ada..5874482e7a 100644 --- a/persistence-modules/spring-data-eclipselink/src/main/resources/application.properties +++ b/persistence-modules/spring-data-eclipselink/src/main/resources/application.properties @@ -1,2 +1,2 @@ -spring.datasource.url=jdbc:h2:mem:test +spring.datasource.url=jdbc:h2:mem:test;MVCC=FALSE;LOCK_TIMEOUT=100; spring.jpa.show-sql=true \ No newline at end of file diff --git a/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java b/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java new file mode 100644 index 0000000000..e84e991d5d --- /dev/null +++ b/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java @@ -0,0 +1,103 @@ +package com.baeldung.eclipselink.springdata.pessimisticlocking; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.persistence.*; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class PessimisticLockScopesIntegrationTest { + + @Autowired + EntityManagerFactory entityManagerFactory; + + @Test + public void givenEclipseEntityWithJoinInheritance_whenNormalLock_thenShouldChildAndParentEntity() { + EntityManager em = getEntityManagerWithOpenTransaction(); + Employee employee = new Employee(1L, "A", "B", new BigDecimal(4.5)); + em.persist(employee); + em.getTransaction() + .commit(); + em.close(); + + // NORMAL SCOPE + em = getEntityManagerWithOpenTransaction(); + Employee foundEmployee = em.find(Employee.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em.getTransaction() + .rollback(); + + // EXTENDED SCOPE + Map map = new HashMap<>(); + map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + + em = getEntityManagerWithOpenTransaction(); + foundEmployee = em.find(Employee.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + } + + @Test + public void givenEclipseEntityWithElementCollection_whenNormalLock_thenShouldLockOnlyOwningEntity() { + EntityManager em = getEntityManagerWithOpenTransaction(); + Address address = new Address("Poland", "Warsaw"); + Customer customer = new Customer(1L, "A", "B", Arrays.asList(address)); + em.persist(customer); + em.getTransaction() + .commit(); + em.close(); + + // NORMAL SCOPE + em = getEntityManagerWithOpenTransaction(); + Customer foundCustomer = em.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em.getTransaction() + .rollback(); + + // EXTENDED SCOPE + Map map = new HashMap<>(); + map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + + em = getEntityManagerWithOpenTransaction(); + foundCustomer = em.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + } + + @Test + public void givenEclipseEntityWithOneToMany_whenNormalLock_thenShouldLockOnlyOwningEntity() { + EntityManager em = getEntityManagerWithOpenTransaction(); + Student student = new Student(1L, "JOE"); + Course course = new Course(1L, "COURSE", student); + student.setCourses(Arrays.asList(course)); + em.persist(course); + em.persist(student); + em.getTransaction() + .commit(); + em.close(); + + // NORMAL SCOPE + em = getEntityManagerWithOpenTransaction(); + Course foundCourse = em.find(Course.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em.getTransaction() + .rollback(); + + // EXTENDED SCOPE + Map map = new HashMap<>(); + map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); + + em = getEntityManagerWithOpenTransaction(); + foundCourse = em.find(Course.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + } + + protected EntityManager getEntityManagerWithOpenTransaction() { + EntityManager entityManager = entityManagerFactory.createEntityManager(); + entityManager.getTransaction() + .begin(); + return entityManager; + } +} From d9ddaa8e0835462a9cb8b9d56fb86976b1862669 Mon Sep 17 00:00:00 2001 From: xenteros Date: Thu, 10 May 2018 17:32:20 +0300 Subject: [PATCH 30/93] Add sources for BAEL-468 (#4171) * Added POJO, * Added DTO, * Added Mapper --- .../java/com/baeldung/dto/TransactionDTO.java | 23 +++++++++++++++++++ .../java/com/baeldung/entity/Transaction.java | 23 +++++++++++++++++++ .../baeldung/mapper/TransactionMapper.java | 23 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 mapstruct/src/main/java/com/baeldung/dto/TransactionDTO.java create mode 100644 mapstruct/src/main/java/com/baeldung/entity/Transaction.java create mode 100644 mapstruct/src/main/java/com/baeldung/mapper/TransactionMapper.java diff --git a/mapstruct/src/main/java/com/baeldung/dto/TransactionDTO.java b/mapstruct/src/main/java/com/baeldung/dto/TransactionDTO.java new file mode 100644 index 0000000000..132607ddd6 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/dto/TransactionDTO.java @@ -0,0 +1,23 @@ +package com.baeldung.dto; + +public class TransactionDTO { + + private String uuid; + private Long totalInCents; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Long getTotalInCents() { + return totalInCents; + } + + public void setTotalInCents(Long totalInCents) { + this.totalInCents = totalInCents; + } +} diff --git a/mapstruct/src/main/java/com/baeldung/entity/Transaction.java b/mapstruct/src/main/java/com/baeldung/entity/Transaction.java new file mode 100644 index 0000000000..fd2a09e7ce --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/entity/Transaction.java @@ -0,0 +1,23 @@ +package com.baeldung.entity; + +import java.math.BigDecimal; +import java.util.UUID; + +public class Transaction { + + private Long id; + private String uuid = UUID.randomUUID().toString(); + private BigDecimal total; + + public Long getId() { + return id; + } + + public String getUuid() { + return uuid; + } + + public BigDecimal getTotal() { + return total; + } +} diff --git a/mapstruct/src/main/java/com/baeldung/mapper/TransactionMapper.java b/mapstruct/src/main/java/com/baeldung/mapper/TransactionMapper.java new file mode 100644 index 0000000000..42957bff46 --- /dev/null +++ b/mapstruct/src/main/java/com/baeldung/mapper/TransactionMapper.java @@ -0,0 +1,23 @@ +package com.baeldung.mapper; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.List; + +import org.mapstruct.Mapper; + +import com.baeldung.dto.TransactionDTO; +import com.baeldung.entity.Transaction; + +@Mapper +abstract class TransactionMapper { + + public TransactionDTO toTransactionDTO(Transaction transaction) { + TransactionDTO transactionDTO = new TransactionDTO(); + transactionDTO.setUuid(transaction.getUuid()); + transactionDTO.setTotalInCents(transaction.getTotal().multiply(new BigDecimal("100")).longValue()); + return transactionDTO; + } + + public abstract List toTransactionDTO(Collection transactions); +} From db77297fa1db5879dcedad77b12c2a2ba3015b9e Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Thu, 10 May 2018 20:19:35 +0300 Subject: [PATCH 31/93] update charset class --- .../org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java b/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java index 7a75729ea5..c9956e5852 100644 --- a/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java +++ b/httpclient/src/test/java/org/baeldung/httpclient/sec/HttpClientAuthLiveTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import java.io.IOException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; @@ -89,7 +90,7 @@ public class HttpClientAuthLiveTest { public final void givenAuthorizationHeaderIsSetManually_whenExecutingGetRequest_thenSuccess2() throws IOException { final HttpGet request = new HttpGet(URL_SECURED_BY_BASIC_AUTHENTICATION); final String auth = DEFAULT_USER + ":" + DEFAULT_PASS; - final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("ISO-8859-1"))); + final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1)); final String authHeader = "Basic " + new String(encodedAuth); request.setHeader(HttpHeaders.AUTHORIZATION, authHeader); @@ -129,7 +130,7 @@ public class HttpClientAuthLiveTest { private String authorizationHeader(final String username, final String password) { final String auth = username + ":" + password; - final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("ISO-8859-1"))); + final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1)); return "Basic " + new String(encodedAuth); } From 6fdd23bd3d8fbfcaa263d4279ef6c8c597b657b1 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Thu, 10 May 2018 21:08:56 +0300 Subject: [PATCH 32/93] fix boot project --- .../boot/monitor/jmx/MonitoringConfig.java | 21 ------------------- spring-boot/src/test/resources/data.sql | 5 ----- spring-boot/src/test/resources/schema.sql | 5 ----- 3 files changed, 31 deletions(-) delete mode 100644 spring-boot/src/main/java/org/baeldung/boot/monitor/jmx/MonitoringConfig.java delete mode 100644 spring-boot/src/test/resources/data.sql delete mode 100644 spring-boot/src/test/resources/schema.sql diff --git a/spring-boot/src/main/java/org/baeldung/boot/monitor/jmx/MonitoringConfig.java b/spring-boot/src/main/java/org/baeldung/boot/monitor/jmx/MonitoringConfig.java deleted file mode 100644 index 28c6ac5953..0000000000 --- a/spring-boot/src/main/java/org/baeldung/boot/monitor/jmx/MonitoringConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.baeldung.boot.monitor.jmx; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import com.codahale.metrics.JmxReporter; -import com.codahale.metrics.MetricRegistry; - -@Configuration -public class MonitoringConfig { - @Autowired - private MetricRegistry registry; - - @Bean - public JmxReporter jmxReporter() { - JmxReporter reporter = JmxReporter.forRegistry(registry).build(); - reporter.start(); - return reporter; - } -} diff --git a/spring-boot/src/test/resources/data.sql b/spring-boot/src/test/resources/data.sql deleted file mode 100644 index f36e034ce1..0000000000 --- a/spring-boot/src/test/resources/data.sql +++ /dev/null @@ -1,5 +0,0 @@ -INSERT INTO country (name) VALUES ('India'); -INSERT INTO country (name) VALUES ('Brazil'); -INSERT INTO country (name) VALUES ('USA'); -INSERT INTO country (name) VALUES ('Italy'); -COMMIT; diff --git a/spring-boot/src/test/resources/schema.sql b/spring-boot/src/test/resources/schema.sql deleted file mode 100644 index 15d7788cd7..0000000000 --- a/spring-boot/src/test/resources/schema.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE country ( - id INTEGER NOT NULL AUTO_INCREMENT, - name VARCHAR(128) NOT NULL, - PRIMARY KEY (id) -); From ea4b7a9bb54fcd4c6c17052f8cb0d74015c20244 Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 10 May 2018 21:46:58 +0300 Subject: [PATCH 33/93] dom parsing --- .../com/baeldung/xml/XercesDomUnitTest.java | 139 ++++++++++++++++++ xml/src/test/resources/Xerces_dom.xml | 1 + 2 files changed, 140 insertions(+) create mode 100644 xml/src/test/java/com/baeldung/xml/XercesDomUnitTest.java create mode 100644 xml/src/test/resources/Xerces_dom.xml diff --git a/xml/src/test/java/com/baeldung/xml/XercesDomUnitTest.java b/xml/src/test/java/com/baeldung/xml/XercesDomUnitTest.java new file mode 100644 index 0000000000..a5091c62fc --- /dev/null +++ b/xml/src/test/java/com/baeldung/xml/XercesDomUnitTest.java @@ -0,0 +1,139 @@ +package com.baeldung.xml; + +import static org.junit.Assert.assertEquals; + +import java.io.File; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.junit.Before; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class XercesDomUnitTest { + + final private String FILE_NAME = "src/test/resources/example_jdom.xml"; + final private String OUTPUT_DOM = "src/test/resources/Xerces_dom.xml"; + + private Document doc; + private DocumentBuilder builder; + + @Before + public void loadXmlFile() throws Exception { + if (doc == null) { + builder = DocumentBuilderFactory.newInstance() + .newDocumentBuilder(); + doc = builder.parse(new File(FILE_NAME)); + doc.getDocumentElement() + .normalize(); + } + } + + @Test + public void whenGetElementByTag_thenSuccess() { + NodeList nodeList = doc.getElementsByTagName("tutorial"); + Node first = nodeList.item(0); + + assertEquals(4, nodeList.getLength()); + assertEquals(Node.ELEMENT_NODE, first.getNodeType()); + assertEquals("tutorial", first.getNodeName()); + } + + @Test + public void whenGetFirstElementAttributes_thenSuccess() { + Node first = doc.getElementsByTagName("tutorial") + .item(0); + NamedNodeMap attrList = first.getAttributes(); + + assertEquals(2, attrList.getLength()); + + assertEquals("tutId", attrList.item(0) + .getNodeName()); + assertEquals("01", attrList.item(0) + .getNodeValue()); + + assertEquals("type", attrList.item(1) + .getNodeName()); + assertEquals("java", attrList.item(1) + .getNodeValue()); + } + + + @Test + public void whenTraverseChildNodes_thenSuccess() { + Node first = doc.getElementsByTagName("tutorial") + .item(0); + NodeList nodeList = first.getChildNodes(); + int n = nodeList.getLength(); + + Node current; + for (int i = 0; i < n; i++) { + current = nodeList.item(i); + if (current.getNodeType() == Node.ELEMENT_NODE) { + System.out.println(current.getNodeName() + ": " + current.getTextContent()); + } + } + } + + @Test + public void whenModifyElementAttribute_thenModified() { + NodeList nodeList = doc.getElementsByTagName("tutorial"); + Element first = (Element) nodeList.item(0); + assertEquals("java", first.getAttribute("type")); + + first.setAttribute("type", "other"); + assertEquals("other", first.getAttribute("type")); + } + + + @Test + public void whenCreateNewDocument_thenCreated() throws Exception { + Document newDoc = builder.newDocument(); + Element root = newDoc.createElement("users"); + newDoc.appendChild(root); + + Element first = newDoc.createElement("user"); + root.appendChild(first); + first.setAttribute("id", "1"); + + Element email = newDoc.createElement("email"); + email.appendChild(newDoc.createTextNode("john@example.com")); + first.appendChild(email); + + assertEquals(1, newDoc.getChildNodes() + .getLength()); + assertEquals("users", newDoc.getChildNodes() + .item(0) + .getNodeName()); + + printDom(newDoc); + saveDomToFile(newDoc, OUTPUT_DOM); + } + + private void printDom(Document document) throws Exception { + DOMSource dom = new DOMSource(document); + Transformer transformer = TransformerFactory.newInstance() + .newTransformer(); + + transformer.transform(dom, new StreamResult(System.out)); + } + + private void saveDomToFile(Document document, String fileName) throws Exception { + DOMSource dom = new DOMSource(document); + Transformer transformer = TransformerFactory.newInstance() + .newTransformer(); + + StreamResult result = new StreamResult(new File(fileName)); + transformer.transform(dom, result); + } + +} diff --git a/xml/src/test/resources/Xerces_dom.xml b/xml/src/test/resources/Xerces_dom.xml new file mode 100644 index 0000000000..5b148606af --- /dev/null +++ b/xml/src/test/resources/Xerces_dom.xml @@ -0,0 +1 @@ +john@example.com \ No newline at end of file From fd11e089fe49e5d52c18ef3c5575943fa5f9f9e4 Mon Sep 17 00:00:00 2001 From: Patryk Kucharz Date: Thu, 10 May 2018 20:53:58 +0200 Subject: [PATCH 34/93] BAEL-1713: Pessimistic Locking in JPA Improvments for tests. --- .../PessimisticLockScopesIntegrationTest.java | 53 +++++++++++------- .../PessimisticLockScopesIntegrationTest.java | 55 ++++++++++++------- 2 files changed, 69 insertions(+), 39 deletions(-) diff --git a/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java b/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java index c774c6eaa4..ac56ab7133 100644 --- a/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java +++ b/hibernate5/src/test/java/com/baeldung/hibernate/pessimisticlocking/PessimisticLockScopesIntegrationTest.java @@ -17,52 +17,62 @@ public class PessimisticLockScopesIntegrationTest { @Test public void givenEclipseEntityWithJoinInheritance_whenNormalLock_thenShouldChildAndParentEntity() throws IOException { EntityManager em = getEntityManagerWithOpenTransaction(); - PessimisticLockingEmployee employee = new PessimisticLockingEmployee(1L, "A", "B", new BigDecimal(4.5)); + PessimisticLockingEmployee employee = new PessimisticLockingEmployee(1L, "JOHN", "SMITH", new BigDecimal(4.5)); em.persist(employee); em.getTransaction() .commit(); em.close(); // NORMAL SCOPE - em = getEntityManagerWithOpenTransaction(); - PessimisticLockingEmployee foundEmployee = em.find(PessimisticLockingEmployee.class, 1L, LockModeType.PESSIMISTIC_WRITE); - em.getTransaction() + EntityManager em2 = getEntityManagerWithOpenTransaction(); + PessimisticLockingEmployee foundEmployee = em2.find(PessimisticLockingEmployee.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em2.getTransaction() .rollback(); // EXTENDED SCOPE Map map = new HashMap<>(); map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); - em = getEntityManagerWithOpenTransaction(); - foundEmployee = em.find(PessimisticLockingEmployee.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + EntityManager em3 = getEntityManagerWithOpenTransaction(); + foundEmployee = em3.find(PessimisticLockingEmployee.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + em3.getTransaction() + .rollback(); + + em2.close(); + em3.close(); } @Test - public void givenEclipseEntityWithElementCollection_whenNormalLock_thenShouldLockOnlyOwningEntity() throws IOException { + public void givenEntityWithElementCollection_whenLock_thenHibernateExtendedScopeLockOnlyOwningEntity() throws IOException { EntityManager em = getEntityManagerWithOpenTransaction(); Address address = new Address("Poland", "Warsaw"); - Customer customer = new Customer(1L, "A", "B", Arrays.asList(address)); + Customer customer = new Customer(1L, "JOE", "DOE", Arrays.asList(address)); em.persist(customer); em.getTransaction() .commit(); em.close(); // NORMAL SCOPE - em = getEntityManagerWithOpenTransaction(); - Customer foundCustomer = em.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE); - em.getTransaction() + EntityManager em2 = getEntityManagerWithOpenTransaction(); + Customer foundCustomer = em2.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em2.getTransaction() .rollback(); // EXTENDED SCOPE Map map = new HashMap<>(); map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); - em = getEntityManagerWithOpenTransaction(); - foundCustomer = em.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + EntityManager em3 = getEntityManagerWithOpenTransaction(); + foundCustomer = em3.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + em2.getTransaction() + .rollback(); + + em2.close(); + em3.close(); } @Test - public void givenEclipseEntityWithOneToMany_whenNormalLock_thenShouldLockOnlyOwningEntity() throws IOException { + public void givenEntityWithOneToMany_whenLock_thenHibernateExtendedScopeLockOnlyOwningEntity() throws IOException { EntityManager em = getEntityManagerWithOpenTransaction(); PessimisticLockingStudent student = new PessimisticLockingStudent(1L, "JOE"); PessimisticLockingCourse course = new PessimisticLockingCourse(1L, "COURSE", student); @@ -74,17 +84,22 @@ public class PessimisticLockScopesIntegrationTest { em.close(); // NORMAL SCOPE - em = getEntityManagerWithOpenTransaction(); - PessimisticLockingCourse foundCourse = em.find(PessimisticLockingCourse.class, 1L, LockModeType.PESSIMISTIC_WRITE); - em.getTransaction() + EntityManager em2 = getEntityManagerWithOpenTransaction(); + PessimisticLockingCourse foundCourse = em2.find(PessimisticLockingCourse.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em2.getTransaction() .rollback(); // EXTENDED SCOPE Map map = new HashMap<>(); map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); - em = getEntityManagerWithOpenTransaction(); - foundCourse = em.find(PessimisticLockingCourse.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + EntityManager em3 = getEntityManagerWithOpenTransaction(); + foundCourse = em3.find(PessimisticLockingCourse.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + em3.getTransaction() + .rollback(); + + em2.close(); + em3.close(); } protected EntityManager getEntityManagerWithOpenTransaction() throws IOException { diff --git a/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java b/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java index e84e991d5d..6ee40fac9a 100644 --- a/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java +++ b/persistence-modules/spring-data-eclipselink/src/test/java/com/baeldung/eclipselink/springdata/pessimisticlocking/PessimisticLockScopesIntegrationTest.java @@ -22,54 +22,64 @@ public class PessimisticLockScopesIntegrationTest { EntityManagerFactory entityManagerFactory; @Test - public void givenEclipseEntityWithJoinInheritance_whenNormalLock_thenShouldChildAndParentEntity() { + public void givenEntityWithJoinInheritance_whenLock_thenNormalAndExtendScopesLockParentAndChildEntity() { EntityManager em = getEntityManagerWithOpenTransaction(); - Employee employee = new Employee(1L, "A", "B", new BigDecimal(4.5)); + Employee employee = new Employee(1L, "JOE", "DOE", new BigDecimal(4.5)); em.persist(employee); em.getTransaction() .commit(); em.close(); // NORMAL SCOPE - em = getEntityManagerWithOpenTransaction(); - Employee foundEmployee = em.find(Employee.class, 1L, LockModeType.PESSIMISTIC_WRITE); - em.getTransaction() + EntityManager em2 = getEntityManagerWithOpenTransaction(); + Employee foundEmployee = em2.find(Employee.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em2.getTransaction() .rollback(); // EXTENDED SCOPE Map map = new HashMap<>(); map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); - em = getEntityManagerWithOpenTransaction(); - foundEmployee = em.find(Employee.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + EntityManager em3 = getEntityManagerWithOpenTransaction(); + foundEmployee = em3.find(Employee.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + em3.getTransaction() + .rollback(); + + em2.close(); + em3.close(); } @Test - public void givenEclipseEntityWithElementCollection_whenNormalLock_thenShouldLockOnlyOwningEntity() { + public void givenEntityWithElementCollection_whenLock_thenExtendScopeLocksAlsoCollectionTable() { EntityManager em = getEntityManagerWithOpenTransaction(); Address address = new Address("Poland", "Warsaw"); - Customer customer = new Customer(1L, "A", "B", Arrays.asList(address)); + Customer customer = new Customer(1L, "JOHN", "SMITH", Arrays.asList(address)); em.persist(customer); em.getTransaction() .commit(); em.close(); // NORMAL SCOPE - em = getEntityManagerWithOpenTransaction(); - Customer foundCustomer = em.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE); - em.getTransaction() + EntityManager em2 = getEntityManagerWithOpenTransaction(); + Customer foundCustomer = em2.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em2.getTransaction() .rollback(); // EXTENDED SCOPE Map map = new HashMap<>(); map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); - em = getEntityManagerWithOpenTransaction(); - foundCustomer = em.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + EntityManager em3 = getEntityManagerWithOpenTransaction(); + foundCustomer = em3.find(Customer.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + em3.getTransaction() + .rollback(); + + em2.close(); + em3.close(); } @Test - public void givenEclipseEntityWithOneToMany_whenNormalLock_thenShouldLockOnlyOwningEntity() { + public void givenEclipseEntityWithOneToMany_whenLock_thenExtendedLockAlsoJoinTable() { EntityManager em = getEntityManagerWithOpenTransaction(); Student student = new Student(1L, "JOE"); Course course = new Course(1L, "COURSE", student); @@ -81,17 +91,22 @@ public class PessimisticLockScopesIntegrationTest { em.close(); // NORMAL SCOPE - em = getEntityManagerWithOpenTransaction(); - Course foundCourse = em.find(Course.class, 1L, LockModeType.PESSIMISTIC_WRITE); - em.getTransaction() + EntityManager em2 = getEntityManagerWithOpenTransaction(); + Course foundCourse = em2.find(Course.class, 1L, LockModeType.PESSIMISTIC_WRITE); + em2.getTransaction() .rollback(); // EXTENDED SCOPE Map map = new HashMap<>(); map.put("javax.persistence.lock.scope", PessimisticLockScope.EXTENDED); - em = getEntityManagerWithOpenTransaction(); - foundCourse = em.find(Course.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + EntityManager em3 = getEntityManagerWithOpenTransaction(); + foundCourse = em3.find(Course.class, 1L, LockModeType.PESSIMISTIC_WRITE, map); + em3.getTransaction() + .rollback(); + + em2.close(); + em3.close(); } protected EntityManager getEntityManagerWithOpenTransaction() { From 07838a2d254bbfd934660ed90601b58b6d7eafe8 Mon Sep 17 00:00:00 2001 From: ramansahasi Date: Fri, 11 May 2018 02:11:33 +0530 Subject: [PATCH 35/93] BAEL-1739 - Check If a String is Numeric in Java (#4209) * BAEL-1725 Java Pass-by-reference vs Pass-by-value - First commit * updated test cases * First commit consisting only of test cases * First commit with test cases * Introduced JMH Michrobenchmarking * Minor corrections --- .../stringisnumeric/Benchmarking.java | 75 ++++++++++++++++++ .../baeldung/stringisnumeric/IsNumeric.java | 35 ++++++++ .../stringisnumeric/IsNumericDriver.java | 33 ++++++++ .../java/com/baeldung/stringisnumeric.zip | Bin 0 -> 3227 bytes .../CoreJavaIsNumericUnitTest.java | 31 ++++++++ .../NumberUtilsIsCreatableUnitTest.java | 28 +++++++ .../NumberUtilsIsParsableUnitTest.java | 26 ++++++ .../RegularExpressionsUnitTest.java | 22 +++++ .../StringUtilsIsNumericSpaceUnitTest.java | 23 ++++++ .../StringUtilsIsNumericUnitTest.java | 24 ++++++ 10 files changed, 297 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/stringisnumeric/Benchmarking.java create mode 100644 core-java/src/main/java/com/baeldung/stringisnumeric/IsNumeric.java create mode 100644 core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java create mode 100644 core-java/src/test/java/com/baeldung/stringisnumeric.zip create mode 100644 core-java/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java create mode 100644 core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsCreatableUnitTest.java create mode 100644 core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsParsableUnitTest.java create mode 100644 core-java/src/test/java/com/baeldung/stringisnumeric/RegularExpressionsUnitTest.java create mode 100644 core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericSpaceUnitTest.java create mode 100644 core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericUnitTest.java diff --git a/core-java/src/main/java/com/baeldung/stringisnumeric/Benchmarking.java b/core-java/src/main/java/com/baeldung/stringisnumeric/Benchmarking.java new file mode 100644 index 0000000000..4ae1f5aa83 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/stringisnumeric/Benchmarking.java @@ -0,0 +1,75 @@ +package com.baeldung.stringisnumeric; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.RunnerException; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; + + +public class Benchmarking { + public static void main(String[] args) throws RunnerException { + Options opt = new OptionsBuilder() + .include(Benchmarking.class.getSimpleName()) + .forks(1) + .build(); + + new Runner(opt).run(); + } + + @State(Scope.Thread) + public static class ExecutionPlan { + public String number = Integer.toString(Integer.MAX_VALUE); + public boolean isNumber = false; + public IsNumeric isNumeric= new IsNumeric(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void usingCoreJava(ExecutionPlan plan) { + plan.isNumber = plan.isNumeric.usingCoreJava(plan.number); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void usingRegularExpressions(ExecutionPlan plan) { + plan.isNumber = plan.isNumeric.usingRegularExpressions(plan.number); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void usingNumberUtils_isCreatable(ExecutionPlan plan) { + plan.isNumber = plan.isNumeric.usingNumberUtils_isCreatable(plan.number); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void usingNumberUtils_isParsable(ExecutionPlan plan) { + plan.isNumber = plan.isNumeric.usingNumberUtils_isParsable(plan.number); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void usingStringUtils_isNumeric(ExecutionPlan plan) { + plan.isNumber = plan.isNumeric.usingStringUtils_isNumeric(plan.number); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.NANOSECONDS) + public void usingStringUtils_isNumericSpace(ExecutionPlan plan) { + plan.isNumber = plan.isNumeric.usingStringUtils_isNumericSpace(plan.number); + } +} \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumeric.java b/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumeric.java new file mode 100644 index 0000000000..c438071e42 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumeric.java @@ -0,0 +1,35 @@ +package com.baeldung.stringisnumeric; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; + +public class IsNumeric { + public boolean usingCoreJava(String strNum) { + try { + double d = Double.parseDouble(strNum); + } catch (NumberFormatException | NullPointerException nfe) { + return false; + } + return true; + } + + public boolean usingRegularExpressions(String strNum) { + return strNum.matches("-?\\d+(\\.\\d+)?"); + } + + public boolean usingNumberUtils_isCreatable(String strNum) { + return NumberUtils.isCreatable(strNum); + } + + public boolean usingNumberUtils_isParsable(String strNum) { + return NumberUtils.isParsable(strNum); + } + + public boolean usingStringUtils_isNumeric(String strNum) { + return StringUtils.isNumeric(strNum); + } + + public boolean usingStringUtils_isNumericSpace(String strNum) { + return StringUtils.isNumericSpace(strNum); + } +} diff --git a/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java b/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java new file mode 100644 index 0000000000..3dc2b6632a --- /dev/null +++ b/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java @@ -0,0 +1,33 @@ +package com.baeldung.stringisnumeric; + +import static com.baeldung.designpatterns.util.LogerUtil.LOG; + +public class IsNumericDriver { + private static IsNumeric isNumeric; + + static { + isNumeric =new IsNumeric(); + } + + public static void main(String[] args) { + LOG.info("Testing all methods..."); + + boolean res = isNumeric.usingCoreJava("1001"); + LOG.info("Using Core Java : " + res); + + res = isNumeric.usingRegularExpressions("1001"); + LOG.info("Using Regular Expressions : " + res); + + res =isNumeric.usingNumberUtils_isCreatable("1001"); + LOG.info("Using NumberUtils.isCreatable : " + res); + + res =isNumeric.usingNumberUtils_isParsable("1001"); + LOG.info("Using NumberUtils.isParsable : " + res); + + res =isNumeric.usingStringUtils_isNumeric("1001"); + LOG.info("Using StringUtils.isNumeric : " + res); + + res =isNumeric.usingStringUtils_isNumericSpace("1001"); + LOG.info("Using StringUtils.isNumericSpace : " + res); + } +} diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric.zip b/core-java/src/test/java/com/baeldung/stringisnumeric.zip new file mode 100644 index 0000000000000000000000000000000000000000..b8a7b9b35a09fea091423fe1c08e771d6be48112 GIT binary patch literal 3227 zcmb7`3p|r;AIFE8Q#sT~iO3?$jHZaC7KOJ* zaw>Ajnb{*sN(|9UdG7V*(~9?fdar#x`|rL#*S-Ju{{61&fBg|wTwo}OHSRgxvi|nt z`qk&N1KdqG_QbNzKv>uDt^NjGc^=ySm$o9%`v@T?&+2AZwIeizN0te6c_{1Z@4cN(MNL$2~mO{t>34e+Fg4dh^c zmAlykHVhA)D&DR-aQ1%rdb1 z<{xhfi8NNB3GdHJIVtX#AGVl`q#ZK!QPev?do6Jr6G^^#O6aSg?zN%`hkef%3SS&7 z7?4P>TgsU0Kbuu&-hIaXWi5A4 zjgpB=-F}P#TTl|QIA5qzuzUHY(e(hz!W;Q#){r#r6>k5D%ohthKb(mGoOyC(gQ_Ut z%z3~WwRM~U{BXwN?FcweKMTLZcr1p1arVUiWKV9AzDJ#^aQz$cWl3X&;9Jh<1LttO z(8nY}{~lkIpd&?2BKN%@nO@D@amgw}K{`3GivDOpOZYlMc5}(NXr9(W;rQ!2u={eI z9u+pO7-5J_KnXE^yXNlW9v*_m?nBXW-8*C8%sRQo?w3q^*a&Lc`g6j@AoIzyhzQE{ zN=VN%&B@-~YL_TBEZNGZV3fPVvwJ?BDH6rB>g8{qa2MH*=Z)0cEiMt5;W`MJ7oj!fA9@zrVMI{@0Uo_J)kaugbM-YyRXB57_xXi~DcAn#h%KHJ8 z7df~GAb`pj0hJH@lgbDT-fykQ?YbaG6+R-q%O}1F{(|d zcrHnhyi!e-+?Kf)CpK{PW932=*_AhP&+myRJFmLCVFDjWF40(O zhurj+K)P9n;+Ik-;r<>f@{fgfyHw6?_FM7g5Ll3IPHSPIw+_V6ko#tIgQe2WfBBO7 zWzAoSpX=dxrd{Pb5XoQrJaz=bCgrsjaYheLKd_*x zOSC>-to1q^)0lQJc;+mKCJPtu2@!biwcn_}0WKymQ@l4vlL{^nlbDi|)Y^6Knrk+! z>rqdbfIYsl%0{a#vn2(I4$`gaB)&jWmSlvQJ60lgw$+;ld($&%K0ns+B%t^u(i2W~ zK=E`g5J+Pk#cjWx0^h5}_fl@_i*fm-U?f+2N2)@j-$>60+Mh_>pnf6##5TKP64}bA zr%_XEuuI%kLJJw1_26jzz#LOnUU9Rzd0u4gM=5%0oX|B(VUyNP%CE>ByYIE;!Q0;{ zWkTv(7ea()sj7nfX$Rm4g{?B@^7q-IiyZymXZ7Y&AGJ?-klV}CDyA|V8zf_$+)7|m zmKw56@t$;U^Kk}!_h{*D1nTlmOT}h}_wbXNd6Oih^)py$F62}VEzrC6t!^GMVvBis zMi707L9YGtvs#+g1E6fTCNk3~uY)@K#0)_n(J7H|`Ho(VN9kxf(OL6ANhYS^q_+li zp=JnN@fmkMr&eU6p(-IF|=lUufN7J)HG?D_OX3d=!X$?=v&r13NmgP07m2jM(qDhBYs-^xk=STgH6LH!jiW9xj{CpGvfqfoh4^csJqsRxgkf(K^*l@Gv3^T?!Pk$`gIF|JGDLo)@ z0jU#0#i56qur0&70t?DYa2)HNH`>m%OapiwbP)q-*n(gxeUR zudi?7WNCXjxne4dXqsZLs^53gVW+BB~erU z0-=iwUkIhhPC`q1b;xKL57)~We%Y)~jKJ-e_0ZzwPNDXgxy;}h-Jlwv5^-?qgZ^7T zBnMc+8m!KUHGb`m_(9U&?sI^|LE+8i;_2g^9IMd|cZrY;T>r?hUJtdJf%QNCe@Dfh zzr8}th&}%*2YddtodSFQMqnZS`i8&JH?Tuce83|l;H3);hHtP(c8IkHDLaHRuoM0# z#Ja~SJ3~b7o=dFUSS;gV8e3#%SbOZSGem*cGW^3K#15cWaR|(E;@uyzg)@Cg7M7vy7I{SAPt7WDuC literal 0 HcmV?d00001 diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java b/core-java/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java new file mode 100644 index 0000000000..808d3c45b0 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/stringisnumeric/CoreJavaIsNumericUnitTest.java @@ -0,0 +1,31 @@ +package com.baeldung.stringisnumeric; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class CoreJavaIsNumericUnitTest { + public static boolean isNumeric(String strNum) { + try { + double d = Double.parseDouble(strNum); + } catch (NumberFormatException | NullPointerException nfe) { + return false; + } + return true; + } + + @Test + public void whenUsingCoreJava_thenTrue() { + // Valid Numbers + assertThat(isNumeric("22")).isTrue(); + assertThat(isNumeric("5.05")).isTrue(); + assertThat(isNumeric("-200")).isTrue(); + assertThat(isNumeric("10.0d")).isTrue(); + assertThat(isNumeric(" 22 ")).isTrue(); + + // Invalid Numbers + assertThat(isNumeric(null)).isFalse(); + assertThat(isNumeric("")).isFalse(); + assertThat(isNumeric("abc")).isFalse(); + } +} diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsCreatableUnitTest.java b/core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsCreatableUnitTest.java new file mode 100644 index 0000000000..467d58837a --- /dev/null +++ b/core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsCreatableUnitTest.java @@ -0,0 +1,28 @@ +package com.baeldung.stringisnumeric; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.commons.lang3.math.NumberUtils; +import org.junit.Test; + +public class NumberUtilsIsCreatableUnitTest { + @Test + public void givenApacheCommons_whenUsingIsParsable_thenTrue() { + // Valid Numbers + assertThat(NumberUtils.isCreatable("22")).isTrue(); + assertThat(NumberUtils.isCreatable("5.05")).isTrue(); + assertThat(NumberUtils.isCreatable("-200")).isTrue(); + assertThat(NumberUtils.isCreatable("10.0d")).isTrue(); + assertThat(NumberUtils.isCreatable("1000L")).isTrue(); + assertThat(NumberUtils.isCreatable("0xFF")).isTrue(); + assertThat(NumberUtils.isCreatable("07")).isTrue(); + assertThat(NumberUtils.isCreatable("2.99e+8")).isTrue(); + + // Invalid Numbers + assertThat(NumberUtils.isCreatable(null)).isFalse(); + assertThat(NumberUtils.isCreatable("")).isFalse(); + assertThat(NumberUtils.isCreatable("abc")).isFalse(); + assertThat(NumberUtils.isCreatable(" 22 ")).isFalse(); + assertThat(NumberUtils.isCreatable("09")).isFalse(); + } +} diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsParsableUnitTest.java b/core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsParsableUnitTest.java new file mode 100644 index 0000000000..141a761158 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/stringisnumeric/NumberUtilsIsParsableUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.stringisnumeric; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.commons.lang3.math.NumberUtils; +import org.junit.Test; + +public class NumberUtilsIsParsableUnitTest { + @Test + public void givenApacheCommons_whenUsingIsParsable_thenTrue() { + // Valid Numbers + assertThat(NumberUtils.isParsable("22")).isTrue(); + assertThat(NumberUtils.isParsable("-23")).isTrue(); + assertThat(NumberUtils.isParsable("2.2")).isTrue(); + assertThat(NumberUtils.isParsable("09")).isTrue(); + + // Invalid Numbers + assertThat(NumberUtils.isParsable(null)).isFalse(); + assertThat(NumberUtils.isParsable("")).isFalse(); + assertThat(NumberUtils.isParsable("6.2f")).isFalse(); + assertThat(NumberUtils.isParsable("9.8d")).isFalse(); + assertThat(NumberUtils.isParsable("22L")).isFalse(); + assertThat(NumberUtils.isParsable("0xFF")).isFalse(); + assertThat(NumberUtils.isParsable("2.99e+8")).isFalse(); + } +} diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/RegularExpressionsUnitTest.java b/core-java/src/test/java/com/baeldung/stringisnumeric/RegularExpressionsUnitTest.java new file mode 100644 index 0000000000..c3aa43ac94 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/stringisnumeric/RegularExpressionsUnitTest.java @@ -0,0 +1,22 @@ +package com.baeldung.stringisnumeric; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class RegularExpressionsUnitTest { + public static boolean isNumeric(String strNum) { + return strNum.matches("-?\\d+(\\.\\d+)?"); + } + + @Test + public void whenUsingRegularExpressions_thenTrue() { + // Valid Numbers + assertThat(isNumeric("22")).isTrue(); + assertThat(isNumeric("5.05")).isTrue(); + assertThat(isNumeric("-200")).isTrue(); + + // Invalid Numbers + assertThat(isNumeric("abc")).isFalse(); + } +} diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericSpaceUnitTest.java b/core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericSpaceUnitTest.java new file mode 100644 index 0000000000..135780d9ad --- /dev/null +++ b/core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericSpaceUnitTest.java @@ -0,0 +1,23 @@ +package com.baeldung.stringisnumeric; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; + +public class StringUtilsIsNumericSpaceUnitTest { + @Test + public void givenApacheCommons_whenUsingIsNumericSpace_thenTrue() { + // Valid Numbers + assertThat(StringUtils.isNumericSpace("123")).isTrue(); + assertThat(StringUtils.isNumericSpace("١٢٣")).isTrue(); + assertThat(StringUtils.isNumericSpace("")).isTrue(); + assertThat(StringUtils.isNumericSpace(" ")).isTrue(); + assertThat(StringUtils.isNumericSpace("12 3")).isTrue(); + + // Invalid Numbers + assertThat(StringUtils.isNumericSpace(null)).isFalse(); + assertThat(StringUtils.isNumericSpace("ab2c")).isFalse(); + assertThat(StringUtils.isNumericSpace("12.3")).isFalse(); + assertThat(StringUtils.isNumericSpace("-123")).isFalse(); + } +} diff --git a/core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericUnitTest.java b/core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericUnitTest.java new file mode 100644 index 0000000000..b667dda906 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/stringisnumeric/StringUtilsIsNumericUnitTest.java @@ -0,0 +1,24 @@ +package com.baeldung.stringisnumeric; + +import org.apache.commons.lang3.StringUtils; +import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; + +public class StringUtilsIsNumericUnitTest { + @Test + public void givenApacheCommons_whenUsingIsNumeric_thenTrue() { + // Valid Numbers + assertThat(StringUtils.isNumeric("123")).isTrue(); + assertThat(StringUtils.isNumeric("١٢٣")).isTrue(); + assertThat(StringUtils.isNumeric("१२३")).isTrue(); + + // Invalid Numbers + assertThat(StringUtils.isNumeric(null)).isFalse(); + assertThat(StringUtils.isNumeric("")).isFalse(); + assertThat(StringUtils.isNumeric(" ")).isFalse(); + assertThat(StringUtils.isNumeric("12 3")).isFalse(); + assertThat(StringUtils.isNumeric("ab2c")).isFalse(); + assertThat(StringUtils.isNumeric("12.3")).isFalse(); + assertThat(StringUtils.isNumeric("-123")).isFalse(); + } +} From 114b44da7e52d4f6a91c214114b7bd98248b0f21 Mon Sep 17 00:00:00 2001 From: Karan Khanna Date: Thu, 10 May 2018 22:56:09 +0200 Subject: [PATCH 36/93] changes to add spring-data-keyvalue to parent pom. --- pom.xml | 1 + spring-data-keyvalue/pom.xml | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3ba6b0c8df..ea1f5e1f94 100644 --- a/pom.xml +++ b/pom.xml @@ -152,6 +152,7 @@ spring-data-couchbase-2 persistence-modules/spring-data-dynamodb spring-data-elasticsearch + spring-data-keyvalue spring-data-mongodb persistence-modules/spring-data-neo4j persistence-modules/spring-data-redis diff --git a/spring-data-keyvalue/pom.xml b/spring-data-keyvalue/pom.xml index 1b77667e0e..e90f18948f 100644 --- a/spring-data-keyvalue/pom.xml +++ b/spring-data-keyvalue/pom.xml @@ -26,13 +26,11 @@ org.springframework.data spring-data-keyvalue - ${spring-data-keyvalue.version} org.springframework.boot spring-boot-starter-test - 1.5.12.RELEASE From e166f5d9c9777e07dbc9279cf6bb6914629b66ef Mon Sep 17 00:00:00 2001 From: Harsh Jain Date: Fri, 11 May 2018 08:40:46 +0530 Subject: [PATCH 37/93] BAEL - 1577 hamcrest core matchers 2.0 version examples as test cases (#4214) * BAEL-1577 : hamcrest core matchers examples added as test cases * BAEL-1577 : Hamcrest java library 2.0.0.0 examples updated as test cases * BAEL-1577 : changed test class name to HamcrestCoreMatchersTest to resolve conflicts --- guava/pom.xml | 9 + .../hamcrest/HamcrestCoreMatchersTest.java | 259 ++++++++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 guava/src/test/java/org/baeldung/hamcrest/HamcrestCoreMatchersTest.java diff --git a/guava/pom.xml b/guava/pom.xml index da880cc995..b36506f87a 100644 --- a/guava/pom.xml +++ b/guava/pom.xml @@ -32,6 +32,14 @@ ${assertj.version} test + + + + org.hamcrest + java-hamcrest + ${java-hamcrest.version} + test + @@ -52,6 +60,7 @@ 3.6.1 + 2.0.0.0 \ No newline at end of file diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestCoreMatchersTest.java b/guava/src/test/java/org/baeldung/hamcrest/HamcrestCoreMatchersTest.java new file mode 100644 index 0000000000..8f3e96c956 --- /dev/null +++ b/guava/src/test/java/org/baeldung/hamcrest/HamcrestCoreMatchersTest.java @@ -0,0 +1,259 @@ +package org.baeldung.hamcrest; + + +import com.google.common.collect.Lists; +import org.junit.Test; + +import java.util.List; + +import static org.hamcrest.CoreMatchers.*; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.StringEndsWith.endsWith; +import static org.hamcrest.core.StringStartsWith.startsWith; + +public class HamcrestCoreMatchersTest { + + @Test + public void givenTestInput_WhenUsingIsForMatch() { + + // GIVEN + String testString = "hamcrest core"; + + // ASSERT + assertThat(testString, is("hamcrest core")); + assertThat(testString, is(equalTo("hamcrest core"))); + } + + @Test + public void givenDifferentStaticTypeTestInput_WhenUsingEqualToObject_ThenCorrect() { + + // GIVEN + Object original = 100; + + // ASSERT + assertThat(original, equalToObject(100)); + } + + @Test + public void givenTestInput_WhenUsingInstanceOfForClassTypeCheck() { + + assertThat("hamcrest", is(instanceOf(String.class))); + } + + @Test + public void givenTestInput_WhenUsingIsA_ThenAssertType() { + + assertThat("hamcrest core", isA(String.class)); + } + + @Test + public void givenTestInput_WhenUsingEqualToMatcherForEquality() { + + // GIVEN + String actualString = "Hamcrest Core"; + List actualList = Lists.newArrayList("hamcrest", "core"); + + // ASSERT + assertThat(actualString, is(equalTo("Hamcrest Core"))); + assertThat(actualList, is(equalTo(Lists.newArrayList("hamcrest", "core")))); + } + + @Test + public void givenTestInput_WhenUsingNotForMatch() { + + // GIVEN + String testString = "hamcrest"; + + // ASSERT + assertThat(testString, not("hamcrest core")); + assertThat(testString, is(not(equalTo("hamcrest core")))); + assertThat(testString, is(not(instanceOf(Integer.class)))); + } + + @Test + public void givenTestInput_WhenUsingNullValueForNullCheck() { + + // GIVEN + Integer nullObject = null; + + // ASSERT + assertThat(nullObject, is(nullValue())); + assertThat(nullObject, is(nullValue(Integer.class))); + } + + @Test + public void givenTestInput_WhenUsingNotNullValueForNotNullCheck() { + + // GIVEN + Integer testNumber = 123; + + // ASSERT + assertThat(testNumber, is(notNullValue())); + assertThat(testNumber, is(notNullValue(Integer.class))); + } + + @Test + public void givenString_WhenStartsWith_ThenCorrect() { + + // GIVEN + String testString = "hamcrest core"; + + // ASSERT + assertThat(testString, startsWith("hamcrest")); + } + + @Test + public void giveString_WhenStartsWithIgnoringCase_ThenCorrect() { + + // GIVEN + String testString = "hamcrest core"; + + // ASSERT + assertThat(testString, startsWithIgnoringCase("HAMCREST")); + } + + @Test + public void givenString_WhenEndsWith_ThenCorrect() { + + // GIVEN + String testString = "hamcrest core"; + + // ASSERT + assertThat(testString, endsWith("core")); + } + + @Test + public void givenString_WhenEndsWithIgnoringCase_ThenCorrect() { + + // GIVEN + String testString = "hamcrest core"; + + // ASSERT + assertThat(testString, endsWithIgnoringCase("CORE")); + } + + @Test + public void givenString_WhenContainsString_ThenCorrect() { + + // GIVEN + String testString = "hamcrest core"; + + // ASSERT + assertThat(testString, containsString("co")); + } + + @Test + public void givenString_WhenContainsStringIgnoringCase_ThenCorrect() { + + + // GIVEN + String testString = "hamcrest core"; + + // ASSERT + assertThat(testString, containsStringIgnoringCase("CO")); + } + + @Test + public void givenTestInput_WhenUsingHasItemInCollection() { + + // GIVEN + List list = Lists.newArrayList("java", "spring", "baeldung"); + + // ASSERT + assertThat(list, hasItem("java")); + assertThat(list, hasItem(isA(String.class))); + } + + + @Test + public void givenTestInput_WhenUsingHasItemsInCollection() { + + // GIVEN + List list = Lists.newArrayList("java", "spring", "baeldung"); + + // ASSERT + assertThat(list, hasItems("java", "baeldung")); + assertThat(list, hasItems(isA(String.class), endsWith("ing"))); + } + + @Test + public void givenTestInput_WhenUsingAnyForClassType() { + + assertThat("hamcrest", is(any(String.class))); + assertThat("hamcrest", is(any(Object.class))); + } + + @Test + public void givenTestInput_WhenUsingAllOfForAllMatchers() { + + // GIVEN + String testString = "Hamcrest Core"; + + // ASSERT + assertThat(testString, allOf(startsWith("Ham"), endsWith("ore"), containsString("Core"))); + } + + @Test + public void givenTestInput_WhenUsingAnyOfForAnyMatcher() { + + // GIVEN + String testString = "Hamcrest Core"; + + // ASSERT + assertThat(testString, anyOf(startsWith("Ham"), containsString("baeldung"))); + } + + @Test + public void givenTestInput_WhenUsingBothForMatcher() { + + // GIVEN + String testString = "Hamcrest Core Matchers"; + + // ASSERT + assertThat(testString, both(startsWith("Ham")).and(containsString("Core"))); + } + + @Test + public void givenTestInput_WhenUsingEitherForMatcher() { + + // GIVEN + String testString = "Hamcrest Core Matchers"; + + // ASSERT + assertThat(testString, either(startsWith("Bael")).or(containsString("Core"))); + } + + + @Test + public void givenTestInput_WhenUsingEveryItemForMatchInCollection() { + + // GIVEN + List testItems = Lists.newArrayList("Common", "Core", "Combinable"); + + // ASSERT + assertThat(testItems, everyItem(startsWith("Co"))); + } + + @Test + public void givenTwoTestInputs_WhenUsingSameInstanceForMatch() { + + // GIVEN + String string1 = "hamcrest"; + String string2 = string1; + + // ASSERT + assertThat(string1, is(sameInstance(string2))); + } + + @Test + public void givenTwoTestInputs_WhenUsingTheInstanceForMatch() { + // GIVEN + String string1 = "hamcrest"; + String string2 = string1; + + // ASSERT + assertThat(string1, is(theInstance(string2))); + } + +} + From 4a08fd1352dc2fafb2a51a6fecb5822af7f0811f Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Fri, 11 May 2018 10:07:57 +0300 Subject: [PATCH 38/93] update, move deferredresult controller (#4164) --- .../servlets/DeferredResultController.java | 71 ---------------- .../controller/DeferredResultController.java | 85 +++++++++++++++++++ 2 files changed, 85 insertions(+), 71 deletions(-) delete mode 100644 spring-boot/src/main/java/com/baeldung/servlets/DeferredResultController.java create mode 100644 spring-rest/src/main/java/org/baeldung/web/controller/DeferredResultController.java diff --git a/spring-boot/src/main/java/com/baeldung/servlets/DeferredResultController.java b/spring-boot/src/main/java/com/baeldung/servlets/DeferredResultController.java deleted file mode 100644 index c43b0e6dc0..0000000000 --- a/spring-boot/src/main/java/com/baeldung/servlets/DeferredResultController.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.baeldung.servlets; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.context.request.async.DeferredResult; - -@RestController -public class DeferredResultController { - - private final static Logger LOG = LoggerFactory.getLogger(DeferredResultController.class); - - @GetMapping("/async-deferredresult") - public DeferredResult> handleReqDefResult(Model model) { - LOG.info("Received async-deferredresult request"); - DeferredResult> output = new DeferredResult<>(); - new Thread(() -> { - LOG.info("Processing in separate thread"); - output.setResult(ResponseEntity.ok("ok")); - }).start(); - LOG.info("servlet thread freed"); - return output; - } - - public DeferredResult> handleReqWithTimeouts(Model model) { - LOG.info("Received async request with a configured timeout"); - DeferredResult> deferredResult = new DeferredResult<>(500l); - deferredResult.onTimeout(new Runnable() { - @Override - public void run() { - deferredResult.setErrorResult( - ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT).body("Request timeout occurred.")); - } - }); - - new Thread(() -> { - LOG.info("Processing in separate thread"); - try { - Thread.sleep(600l); - deferredResult.setResult(ResponseEntity.ok("ok")); - } catch (InterruptedException e) { - LOG.info("Request processing interrupted"); - deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("INTERNAL_SERVER_ERROR occurred.")); - } - - }).start(); - LOG.info("servlet thread freed"); - return deferredResult; - } - - public DeferredResult> handleAsyncFailedRequest(Model model) { - DeferredResult> deferredResult = new DeferredResult<>(); - new Thread(() -> { - try { - // Exception occurred in processing - throw new Exception(); - } catch (Exception e) { - LOG.info("Request processing failed"); - deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("INTERNAL_SERVER_ERROR occurred.")); - } - }).start(); - return deferredResult; - } - -} diff --git a/spring-rest/src/main/java/org/baeldung/web/controller/DeferredResultController.java b/spring-rest/src/main/java/org/baeldung/web/controller/DeferredResultController.java new file mode 100644 index 0000000000..5d039d2d02 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/web/controller/DeferredResultController.java @@ -0,0 +1,85 @@ +package org.baeldung.web.controller; + +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.async.DeferredResult; + +@RestController +public class DeferredResultController { + + private final static Logger LOG = LoggerFactory.getLogger(DeferredResultController.class); + + @GetMapping("/async-deferredresult") + public DeferredResult> handleReqDefResult(Model model) { + LOG.info("Received request"); + DeferredResult> deferredResult = new DeferredResult<>(); + + deferredResult.onCompletion(() -> LOG.info("Processing complete")); + + CompletableFuture.supplyAsync(() -> { + LOG.info("Processing in separate thread"); + try { + Thread.sleep(6000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "OK"; + }) + .whenCompleteAsync((result, exc) -> deferredResult.setResult(ResponseEntity.ok(result))); + + LOG.info("Servlet thread freed"); + return deferredResult; + } + + @GetMapping("/process-blocking") + public ResponseEntity handleReqSync(Model model) { + // ... + return ResponseEntity.ok("ok"); + } + + @GetMapping("/async-deferredresult-timeout") + public DeferredResult> handleReqWithTimeouts(Model model) { + LOG.info("Received async request with a configured timeout"); + DeferredResult> deferredResult = new DeferredResult<>(500l); + deferredResult.onTimeout(() -> deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT) + .body("Request timeout occurred."))); + + CompletableFuture.supplyAsync(() -> { + LOG.info("Processing in separate thread"); + try { + Thread.sleep(6000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "error"; + }) + .whenCompleteAsync((result, exc) -> deferredResult.setResult(ResponseEntity.ok(result))); + LOG.info("servlet thread freed"); + return deferredResult; + } + + @GetMapping("/async-deferredresult-error") + public DeferredResult> handleAsyncFailedRequest(Model model) { + LOG.info("Received async request with a configured error handler"); + DeferredResult> deferredResult = new DeferredResult<>(); + deferredResult.onError(new Consumer() { + @Override + public void accept(Throwable t) { + deferredResult.setErrorResult(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("An error occurred.")); + } + + }); + LOG.info("servlet thread freed"); + return deferredResult; + } + +} From 537c1d1150263154436c508e1cc17ea44f6cd70a Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Fri, 11 May 2018 10:11:13 +0300 Subject: [PATCH 39/93] move design patterns to new module (#4206) * move design patterns to new module * fix logger import --- .../creational/abstractfactory/Color.java | 5 ---- .../creational/factory/Polygon.java | 5 ---- .../numberofdigits/NumberOfDigitsDriver.java | 4 ++- .../{facade => design-patterns}/README.md | 0 .../pom.xml | 22 +++++++++++---- .../adapter/AdapterPatternDriver.java | 4 +-- .../com/baeldung}/adapter/AstonMartin.java | 16 +++++------ .../com/baeldung}/adapter/BugattiVeyron.java | 16 +++++------ .../java/com/baeldung}/adapter/McLaren.java | 16 +++++------ .../java/com/baeldung}/adapter/Movable.java | 10 +++---- .../com/baeldung}/adapter/MovableAdapter.java | 2 +- .../baeldung}/adapter/MovableAdapterImpl.java | 2 +- .../main/java/com/baeldung}/bridge/Blue.java | 2 +- .../baeldung}/bridge/BridgePatternDriver.java | 2 +- .../main/java/com/baeldung}/bridge/Color.java | 2 +- .../main/java/com/baeldung}/bridge/Red.java | 2 +- .../main/java/com/baeldung}/bridge/Shape.java | 2 +- .../java/com/baeldung}/bridge/Square.java | 2 +- .../java/com/baeldung}/bridge/Triangle.java | 2 +- .../AuthenticationProcessor.java | 0 .../AuthenticationProvider.java | 0 .../OAuthAuthenticationProcessor.java | 0 .../OAuthTokenProvider.java | 0 .../SamlAuthenticationProvider.java | 0 ...ernamePasswordAuthenticationProcessor.java | 0 .../UsernamePasswordProvider.java | 0 .../command/client/TextFileApplication.java | 0 .../command/OpenTextFileOperation.java | 0 .../command/SaveTextFileOperation.java | 0 .../command/command/TextFileOperation.java | 0 .../invoker/TextFileOperationExecutor.java | 0 .../baeldung}/command/receiver/TextFile.java | 0 .../baeldung}/composite/CompositeDemo.java | 2 +- .../com/baeldung}/composite/Department.java | 2 +- .../composite/FinancialDepartment.java | 2 +- .../baeldung}/composite/HeadDepartment.java | 2 +- .../baeldung}/composite/SalesDepartment.java | 2 +- .../abstractfactory/AbstractFactory.java | 2 +- .../AbstractPatternDriver.java | 2 +- .../creational/abstractfactory/Animal.java | 2 +- .../abstractfactory/AnimalFactory.java | 2 +- .../creational/abstractfactory/Brown.java | 2 +- .../creational/abstractfactory/Color.java | 5 ++++ .../abstractfactory/ColorFactory.java | 2 +- .../creational/abstractfactory/Dog.java | 2 +- .../creational/abstractfactory/Duck.java | 2 +- .../abstractfactory/FactoryProvider.java | 2 +- .../creational/abstractfactory/White.java | 2 +- .../creational/builder/BankAccount.java | 2 +- .../builder/BuilderPatternDriver.java | 2 +- .../creational/factory/FactoryDriver.java | 2 +- .../creational/factory/Heptagon.java | 2 +- .../baeldung}/creational/factory/Octagon.java | 2 +- .../creational/factory/Pentagon.java | 2 +- .../baeldung/creational/factory/Polygon.java | 5 ++++ .../creational/factory/PolygonFactory.java | 2 +- .../baeldung}/creational/factory/Square.java | 2 +- .../creational/factory/Triangle.java | 2 +- .../creational/singleton/Singleton.java | 2 +- .../creational/singleton/SingletonDriver.java | 2 +- .../com/baeldung}/decorator/BubbleLights.java | 2 +- .../baeldung}/decorator/ChristmasTree.java | 2 +- .../decorator/ChristmasTreeImpl.java | 2 +- .../decorator/DecoratorPatternDriver.java | 4 +-- .../java/com/baeldung}/decorator/Garland.java | 2 +- .../baeldung}/decorator/TreeDecorator.java | 2 +- .../com/baeldung}/facade/CarEngineFacade.java | 4 +-- .../facade/carsystem/AirFlowController.java | 2 +- .../facade/carsystem/AirFlowMeter.java | 4 +-- .../facade/carsystem/CatalyticConverter.java | 2 +- .../facade/carsystem/CoolingController.java | 4 +-- .../facade/carsystem/FuelInjector.java | 4 +-- .../baeldung}/facade/carsystem/FuelPump.java | 4 +-- .../baeldung}/facade/carsystem/Radiator.java | 2 +- .../baeldung}/facade/carsystem/Starter.java | 4 +-- .../facade/carsystem/TemperatureSensor.java | 4 +-- .../java/com/baeldung}/flyweight/Car.java | 8 +++--- .../java/com/baeldung}/flyweight/Engine.java | 2 +- .../java/com/baeldung}/flyweight/Vehicle.java | 2 +- .../baeldung}/flyweight/VehicleFactory.java | 2 +- .../java/com/baeldung}/observer/Channel.java | 2 +- .../com/baeldung}/observer/NewsAgency.java | 2 +- .../com/baeldung}/observer/NewsChannel.java | 2 +- .../com/baeldung}/observer/ONewsAgency.java | 2 +- .../com/baeldung}/observer/ONewsChannel.java | 2 +- .../com/baeldung}/observer/PCLNewsAgency.java | 2 +- .../baeldung}/observer/PCLNewsChannel.java | 2 +- .../com/baeldung}/proxy/ExpensiveObject.java | 2 +- .../baeldung}/proxy/ExpensiveObjectImpl.java | 6 ++-- .../baeldung}/proxy/ExpensiveObjectProxy.java | 2 +- .../baeldung}/proxy/ProxyPatternDriver.java | 2 +- .../com/baeldung}/service/locator/Cache.java | 2 +- .../service/locator/EmailService.java | 2 +- .../service/locator/InitialContext.java | 2 +- .../com/baeldung}/service/locator/Main.java | 2 +- .../service/locator/MessagingService.java | 2 +- .../baeldung}/service/locator/SMSService.java | 2 +- .../service/locator/ServiceLocator.java | 2 +- .../baeldung}/singleton/ClassSingleton.java | 2 +- .../baeldung}/singleton/EnumSingleton.java | 2 +- .../java/com/baeldung}/singleton/Sandbox.java | 2 +- .../synchronization/DclSingleton.java | 2 +- .../synchronization/DraconianSingleton.java | 2 +- .../synchronization/EarlyInitSingleton.java | 2 +- .../synchronization/EnumSingleton.java | 2 +- .../InitOnDemandSingleton.java | 2 +- .../application/Application.java | 0 .../templatemethod/model/Computer.java | 0 .../templatemethod/model/ComputerBuilder.java | 0 .../templatemethod/model/HighEndComputer.java | 0 .../model/HighEndComputerBuilder.java | 0 .../model/StandardComputer.java | 0 .../model/StandardComputerBuilder.java | 0 .../java/com/baeldung}/util/LogerUtil.java | 2 +- .../AdapterPatternIntegrationTest.java | 14 +++++----- .../BridgePatternIntegrationTest.java | 12 ++++---- .../DecoratorPatternIntegrationTest.java | 10 +++---- .../ProxyPatternIntegrationTest.java | 10 +++---- .../java/com/baeldung}/TestAppenderDP.java | 2 +- .../ChainOfResponsibilityTest.java | 0 .../test/OpenTextFileOperationUnitTest.java | 0 .../test/SaveTextFileOperationUnitTest.java | 0 .../TextFileOperationExecutorUnitTest.java | 0 .../command/test/TextFileUnitTest.java | 0 .../AbstractPatternIntegrationTest.java | 2 +- .../BuilderPatternIntegrationTest.java | 2 +- .../factory/FactoryIntegrationTest.java | 2 +- .../singleton/SingletonIntegrationTest.java | 2 +- .../baeldung}/facade/CarEngineFacadeTest.java | 14 +++++----- .../flyweight/FlyweightUnitTest.java | 2 +- .../observer/ObserverIntegrationTest.java | 6 ++-- .../SingletonSynchronizationUnitTest.java | 2 +- .../test/TemplateMethodPatternTest.java | 0 patterns/facade/pom.xml | 28 ------------------- patterns/front-controller/pom.xml | 2 +- patterns/intercepting-filter/pom.xml | 2 +- patterns/pom.xml | 4 +-- 137 files changed, 200 insertions(+), 214 deletions(-) delete mode 100644 core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java delete mode 100644 core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java rename patterns/{facade => design-patterns}/README.md (100%) rename patterns/{behavioral-patterns => design-patterns}/pom.xml (68%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/adapter/AdapterPatternDriver.java (87%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/adapter/AstonMartin.java (69%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/adapter/BugattiVeyron.java (69%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/adapter/McLaren.java (68%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/adapter/Movable.java (61%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/adapter/MovableAdapter.java (66%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/adapter/MovableAdapterImpl.java (90%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/bridge/Blue.java (73%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/bridge/BridgePatternDriver.java (88%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/bridge/Color.java (51%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/bridge/Red.java (73%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/bridge/Shape.java (79%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/bridge/Square.java (81%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/bridge/Triangle.java (82%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/chainofresponsibility/AuthenticationProcessor.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/chainofresponsibility/AuthenticationProvider.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/chainofresponsibility/OAuthAuthenticationProcessor.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/chainofresponsibility/OAuthTokenProvider.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/chainofresponsibility/SamlAuthenticationProvider.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/chainofresponsibility/UsernamePasswordAuthenticationProcessor.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/chainofresponsibility/UsernamePasswordProvider.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/command/client/TextFileApplication.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/command/command/OpenTextFileOperation.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/command/command/SaveTextFileOperation.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/command/command/TextFileOperation.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/command/invoker/TextFileOperationExecutor.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/command/receiver/TextFile.java (100%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/composite/CompositeDemo.java (92%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/composite/Department.java (70%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/composite/FinancialDepartment.java (92%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/composite/HeadDepartment.java (94%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/composite/SalesDepartment.java (92%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/AbstractFactory.java (63%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/AbstractPatternDriver.java (90%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/Animal.java (52%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/AnimalFactory.java (87%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/Brown.java (64%) create mode 100644 patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Color.java rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/ColorFactory.java (87%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/Dog.java (74%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/Duck.java (75%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/FactoryProvider.java (83%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/abstractfactory/White.java (64%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/builder/BankAccount.java (96%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/builder/BuilderPatternDriver.java (90%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/factory/FactoryDriver.java (89%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/factory/Heptagon.java (69%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/factory/Octagon.java (68%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/factory/Pentagon.java (69%) create mode 100644 patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Polygon.java rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/factory/PolygonFactory.java (89%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/factory/Square.java (68%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/factory/Triangle.java (69%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/singleton/Singleton.java (83%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/creational/singleton/SingletonDriver.java (76%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/decorator/BubbleLights.java (87%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/decorator/ChristmasTree.java (54%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/decorator/ChristmasTreeImpl.java (75%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/decorator/DecoratorPatternDriver.java (80%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/decorator/Garland.java (86%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/decorator/TreeDecorator.java (85%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/CarEngineFacade.java (92%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/carsystem/AirFlowController.java (90%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/carsystem/AirFlowMeter.java (68%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/carsystem/CatalyticConverter.java (88%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/carsystem/CoolingController.java (91%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/carsystem/FuelInjector.java (82%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/carsystem/FuelPump.java (66%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/carsystem/Radiator.java (90%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/carsystem/Starter.java (70%) rename patterns/{facade/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/facade/carsystem/TemperatureSensor.java (67%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/flyweight/Car.java (83%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/flyweight/Engine.java (90%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/flyweight/Vehicle.java (87%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/flyweight/VehicleFactory.java (96%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/observer/Channel.java (58%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/observer/NewsAgency.java (91%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/observer/NewsChannel.java (86%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/observer/ONewsAgency.java (83%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/observer/ONewsChannel.java (89%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/observer/PCLNewsAgency.java (93%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/observer/PCLNewsChannel.java (90%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/proxy/ExpensiveObject.java (57%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/proxy/ExpensiveObjectImpl.java (64%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/proxy/ExpensiveObjectProxy.java (86%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/proxy/ProxyPatternDriver.java (82%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/service/locator/Cache.java (94%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/service/locator/EmailService.java (82%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/service/locator/InitialContext.java (87%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/service/locator/Main.java (91%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/service/locator/MessagingService.java (65%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/service/locator/SMSService.java (82%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/service/locator/ServiceLocator.java (91%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/singleton/ClassSingleton.java (91%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/singleton/EnumSingleton.java (90%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/singleton/Sandbox.java (96%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/singleton/synchronization/DclSingleton.java (91%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/singleton/synchronization/DraconianSingleton.java (90%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/singleton/synchronization/EarlyInitSingleton.java (90%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/singleton/synchronization/EnumSingleton.java (77%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/singleton/synchronization/InitOnDemandSingleton.java (92%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/templatemethod/application/Application.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/templatemethod/model/Computer.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/templatemethod/model/ComputerBuilder.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/templatemethod/model/HighEndComputer.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/templatemethod/model/HighEndComputerBuilder.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/templatemethod/model/StandardComputer.java (100%) rename patterns/{behavioral-patterns/src/main/java/com/baeldung/pattern => design-patterns/src/main/java/com/baeldung}/templatemethod/model/StandardComputerBuilder.java (100%) rename {core-java/src/main/java/com/baeldung/designpatterns => patterns/design-patterns/src/main/java/com/baeldung}/util/LogerUtil.java (94%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/AdapterPatternIntegrationTest.java (68%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/BridgePatternIntegrationTest.java (64%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/DecoratorPatternIntegrationTest.java (69%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/ProxyPatternIntegrationTest.java (80%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/TestAppenderDP.java (94%) rename patterns/{behavioral-patterns/src/test/java/com/baeldung/pattern => design-patterns/src/test/java/com/baeldung}/chainofresponsibility/ChainOfResponsibilityTest.java (100%) rename patterns/{behavioral-patterns/src/test/java/com/baeldung/pattern => design-patterns/src/test/java/com/baeldung}/command/test/OpenTextFileOperationUnitTest.java (100%) rename patterns/{behavioral-patterns/src/test/java/com/baeldung/pattern => design-patterns/src/test/java/com/baeldung}/command/test/SaveTextFileOperationUnitTest.java (100%) rename patterns/{behavioral-patterns/src/test/java/com/baeldung/pattern => design-patterns/src/test/java/com/baeldung}/command/test/TextFileOperationExecutorUnitTest.java (100%) rename patterns/{behavioral-patterns/src/test/java/com/baeldung/pattern => design-patterns/src/test/java/com/baeldung}/command/test/TextFileUnitTest.java (100%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/creational/abstractfactory/AbstractPatternIntegrationTest.java (91%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/creational/builder/BuilderPatternIntegrationTest.java (95%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/creational/factory/FactoryIntegrationTest.java (94%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/creational/singleton/SingletonIntegrationTest.java (92%) rename patterns/{facade/src/test/java/com/baeldung/pattern => design-patterns/src/test/java/com/baeldung}/facade/CarEngineFacadeTest.java (94%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/flyweight/FlyweightUnitTest.java (96%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/observer/ObserverIntegrationTest.java (87%) rename {core-java/src/test/java/com/baeldung/designpatterns => patterns/design-patterns/src/test/java/com/baeldung}/singleton/synchronization/SingletonSynchronizationUnitTest.java (98%) rename patterns/{behavioral-patterns/src/test/java/com/baeldung/pattern => design-patterns/src/test/java/com/baeldung}/templatemethod/test/TemplateMethodPatternTest.java (100%) delete mode 100644 patterns/facade/pom.xml diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java deleted file mode 100644 index 897bb71f38..0000000000 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Color.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.baeldung.designpatterns.creational.abstractfactory; - -public interface Color { - String getColor(); -} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java b/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java deleted file mode 100644 index 8364e546b0..0000000000 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Polygon.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.baeldung.designpatterns.creational.factory; - -public interface Polygon { - String getType(); -} diff --git a/core-java/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java b/core-java/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java index 32d3051327..c3cc567eaa 100755 --- a/core-java/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java +++ b/core-java/src/main/java/com/baeldung/numberofdigits/NumberOfDigitsDriver.java @@ -1,10 +1,12 @@ package com.baeldung.numberofdigits; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; +import org.apache.log4j.Logger; public class NumberOfDigitsDriver { private static NumberOfDigits numberOfDigits; + private static Logger LOG = Logger.getLogger(NumberOfDigitsDriver.class); + static { numberOfDigits = new NumberOfDigits(); } diff --git a/patterns/facade/README.md b/patterns/design-patterns/README.md similarity index 100% rename from patterns/facade/README.md rename to patterns/design-patterns/README.md diff --git a/patterns/behavioral-patterns/pom.xml b/patterns/design-patterns/pom.xml similarity index 68% rename from patterns/behavioral-patterns/pom.xml rename to patterns/design-patterns/pom.xml index 435f07aa98..87db08ab32 100644 --- a/patterns/behavioral-patterns/pom.xml +++ b/patterns/design-patterns/pom.xml @@ -1,12 +1,12 @@ 4.0.0 - com.baeldung.pattern.templatemethod - pattern.templatemethod + com.baeldung + design-patterns 1.0 jar - com.baeldung.patterns + com.baeldung patterns-parent 1.0.0-SNAPSHOT .. @@ -19,7 +19,7 @@ 4.12 test - + org.hamcrest hamcrest-core 1.3 @@ -31,10 +31,22 @@ 3.8.0 test + + log4j + log4j + ${log4j.version} + + + com.googlecode.grep4j + grep4j + ${grep4j.version} + UTF-8 1.8 1.8 - + 1.2.17 + 1.8.7 + \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java b/patterns/design-patterns/src/main/java/com/baeldung/adapter/AdapterPatternDriver.java similarity index 87% rename from core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java rename to patterns/design-patterns/src/main/java/com/baeldung/adapter/AdapterPatternDriver.java index 79f618d038..a4e10a0868 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AdapterPatternDriver.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/adapter/AdapterPatternDriver.java @@ -1,6 +1,6 @@ -package com.baeldung.designpatterns.adapter; +package com.baeldung.adapter; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; +import static com.baeldung.util.LogerUtil.LOG; public class AdapterPatternDriver { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AstonMartin.java b/patterns/design-patterns/src/main/java/com/baeldung/adapter/AstonMartin.java similarity index 69% rename from core-java/src/main/java/com/baeldung/designpatterns/adapter/AstonMartin.java rename to patterns/design-patterns/src/main/java/com/baeldung/adapter/AstonMartin.java index 7dd83079a2..c6aa0c525a 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/AstonMartin.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/adapter/AstonMartin.java @@ -1,8 +1,8 @@ -package com.baeldung.designpatterns.adapter; - -public class AstonMartin implements Movable { - @Override - public double getSpeed() { - return 220; - } -} +package com.baeldung.adapter; + +public class AstonMartin implements Movable { + @Override + public double getSpeed() { + return 220; + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/BugattiVeyron.java b/patterns/design-patterns/src/main/java/com/baeldung/adapter/BugattiVeyron.java similarity index 69% rename from core-java/src/main/java/com/baeldung/designpatterns/adapter/BugattiVeyron.java rename to patterns/design-patterns/src/main/java/com/baeldung/adapter/BugattiVeyron.java index a249d64b6f..e7d47d138a 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/BugattiVeyron.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/adapter/BugattiVeyron.java @@ -1,8 +1,8 @@ -package com.baeldung.designpatterns.adapter; - -public class BugattiVeyron implements Movable { - @Override - public double getSpeed() { - return 268; - } -} +package com.baeldung.adapter; + +public class BugattiVeyron implements Movable { + @Override + public double getSpeed() { + return 268; + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/McLaren.java b/patterns/design-patterns/src/main/java/com/baeldung/adapter/McLaren.java similarity index 68% rename from core-java/src/main/java/com/baeldung/designpatterns/adapter/McLaren.java rename to patterns/design-patterns/src/main/java/com/baeldung/adapter/McLaren.java index c807df67db..4ca1cde856 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/McLaren.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/adapter/McLaren.java @@ -1,8 +1,8 @@ -package com.baeldung.designpatterns.adapter; - -public class McLaren implements Movable { - @Override - public double getSpeed() { - return 241; - } -} +package com.baeldung.adapter; + +public class McLaren implements Movable { + @Override + public double getSpeed() { + return 241; + } +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/Movable.java b/patterns/design-patterns/src/main/java/com/baeldung/adapter/Movable.java similarity index 61% rename from core-java/src/main/java/com/baeldung/designpatterns/adapter/Movable.java rename to patterns/design-patterns/src/main/java/com/baeldung/adapter/Movable.java index ec94e90af0..bec0bee568 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/Movable.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/adapter/Movable.java @@ -1,6 +1,6 @@ -package com.baeldung.designpatterns.adapter; - -public interface Movable { - // returns speed in MPH - double getSpeed(); +package com.baeldung.adapter; + +public interface Movable { + // returns speed in MPH + double getSpeed(); } \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapter.java b/patterns/design-patterns/src/main/java/com/baeldung/adapter/MovableAdapter.java similarity index 66% rename from core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapter.java rename to patterns/design-patterns/src/main/java/com/baeldung/adapter/MovableAdapter.java index b9c7484446..8d529e7b13 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapter.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/adapter/MovableAdapter.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.adapter; +package com.baeldung.adapter; public interface MovableAdapter { // returns speed in KMPH diff --git a/core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapterImpl.java b/patterns/design-patterns/src/main/java/com/baeldung/adapter/MovableAdapterImpl.java similarity index 90% rename from core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapterImpl.java rename to patterns/design-patterns/src/main/java/com/baeldung/adapter/MovableAdapterImpl.java index eb74641389..8f18cc9942 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/adapter/MovableAdapterImpl.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/adapter/MovableAdapterImpl.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.adapter; +package com.baeldung.adapter; public class MovableAdapterImpl implements MovableAdapter { private Movable luxuryCars; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Blue.java similarity index 73% rename from core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java rename to patterns/design-patterns/src/main/java/com/baeldung/bridge/Blue.java index da5d29617f..022905f30d 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Blue.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Blue.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.bridge; +package com.baeldung.bridge; public class Blue implements Color { @Override diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java b/patterns/design-patterns/src/main/java/com/baeldung/bridge/BridgePatternDriver.java similarity index 88% rename from core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java rename to patterns/design-patterns/src/main/java/com/baeldung/bridge/BridgePatternDriver.java index e6a7fb41c1..31d18a2347 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/BridgePatternDriver.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/bridge/BridgePatternDriver.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.bridge; +package com.baeldung.bridge; public class BridgePatternDriver { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Color.java similarity index 51% rename from core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java rename to patterns/design-patterns/src/main/java/com/baeldung/bridge/Color.java index 05618e6d6e..9d38f407ba 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Color.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Color.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.bridge; +package com.baeldung.bridge; public interface Color { String fill(); diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Red.java similarity index 73% rename from core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java rename to patterns/design-patterns/src/main/java/com/baeldung/bridge/Red.java index bc83199591..e7011096ce 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Red.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Red.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.bridge; +package com.baeldung.bridge; public class Red implements Color { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Shape.java similarity index 79% rename from core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java rename to patterns/design-patterns/src/main/java/com/baeldung/bridge/Shape.java index 75cd43dbc8..20085cf112 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Shape.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Shape.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.bridge; +package com.baeldung.bridge; public abstract class Shape { protected Color color; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Square.java similarity index 81% rename from core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java rename to patterns/design-patterns/src/main/java/com/baeldung/bridge/Square.java index 7397f4bd47..21a59247d5 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Square.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Square.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.bridge; +package com.baeldung.bridge; public class Square extends Shape { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Triangle.java similarity index 82% rename from core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java rename to patterns/design-patterns/src/main/java/com/baeldung/bridge/Triangle.java index 46db66ee42..1647e7106d 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/bridge/Triangle.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/bridge/Triangle.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.bridge; +package com.baeldung.bridge; public class Triangle extends Shape { diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/AuthenticationProcessor.java b/patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/AuthenticationProcessor.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/AuthenticationProcessor.java rename to patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/AuthenticationProcessor.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/AuthenticationProvider.java b/patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/AuthenticationProvider.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/AuthenticationProvider.java rename to patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/AuthenticationProvider.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/OAuthAuthenticationProcessor.java b/patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/OAuthAuthenticationProcessor.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/OAuthAuthenticationProcessor.java rename to patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/OAuthAuthenticationProcessor.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/OAuthTokenProvider.java b/patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/OAuthTokenProvider.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/OAuthTokenProvider.java rename to patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/OAuthTokenProvider.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/SamlAuthenticationProvider.java b/patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/SamlAuthenticationProvider.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/SamlAuthenticationProvider.java rename to patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/SamlAuthenticationProvider.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/UsernamePasswordAuthenticationProcessor.java b/patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/UsernamePasswordAuthenticationProcessor.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/UsernamePasswordAuthenticationProcessor.java rename to patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/UsernamePasswordAuthenticationProcessor.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/UsernamePasswordProvider.java b/patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/UsernamePasswordProvider.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/chainofresponsibility/UsernamePasswordProvider.java rename to patterns/design-patterns/src/main/java/com/baeldung/chainofresponsibility/UsernamePasswordProvider.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/client/TextFileApplication.java b/patterns/design-patterns/src/main/java/com/baeldung/command/client/TextFileApplication.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/client/TextFileApplication.java rename to patterns/design-patterns/src/main/java/com/baeldung/command/client/TextFileApplication.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/command/OpenTextFileOperation.java b/patterns/design-patterns/src/main/java/com/baeldung/command/command/OpenTextFileOperation.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/command/OpenTextFileOperation.java rename to patterns/design-patterns/src/main/java/com/baeldung/command/command/OpenTextFileOperation.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/command/SaveTextFileOperation.java b/patterns/design-patterns/src/main/java/com/baeldung/command/command/SaveTextFileOperation.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/command/SaveTextFileOperation.java rename to patterns/design-patterns/src/main/java/com/baeldung/command/command/SaveTextFileOperation.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/command/TextFileOperation.java b/patterns/design-patterns/src/main/java/com/baeldung/command/command/TextFileOperation.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/command/TextFileOperation.java rename to patterns/design-patterns/src/main/java/com/baeldung/command/command/TextFileOperation.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/invoker/TextFileOperationExecutor.java b/patterns/design-patterns/src/main/java/com/baeldung/command/invoker/TextFileOperationExecutor.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/invoker/TextFileOperationExecutor.java rename to patterns/design-patterns/src/main/java/com/baeldung/command/invoker/TextFileOperationExecutor.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/receiver/TextFile.java b/patterns/design-patterns/src/main/java/com/baeldung/command/receiver/TextFile.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/command/receiver/TextFile.java rename to patterns/design-patterns/src/main/java/com/baeldung/command/receiver/TextFile.java diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java b/patterns/design-patterns/src/main/java/com/baeldung/composite/CompositeDemo.java similarity index 92% rename from core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java rename to patterns/design-patterns/src/main/java/com/baeldung/composite/CompositeDemo.java index 9537dd0d2b..2296912c76 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/composite/CompositeDemo.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/composite/CompositeDemo.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.composite; +package com.baeldung.composite; /** * Created by Gebruiker on 5/3/2018. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/Department.java b/patterns/design-patterns/src/main/java/com/baeldung/composite/Department.java similarity index 70% rename from core-java/src/main/java/com/baeldung/designpatterns/composite/Department.java rename to patterns/design-patterns/src/main/java/com/baeldung/composite/Department.java index 82fa3a3efc..7e623a9337 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/composite/Department.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/composite/Department.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.composite; +package com.baeldung.composite; /** * Created by Gebruiker on 5/1/2018. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/FinancialDepartment.java b/patterns/design-patterns/src/main/java/com/baeldung/composite/FinancialDepartment.java similarity index 92% rename from core-java/src/main/java/com/baeldung/designpatterns/composite/FinancialDepartment.java rename to patterns/design-patterns/src/main/java/com/baeldung/composite/FinancialDepartment.java index dc5a2bb9d9..173281f833 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/composite/FinancialDepartment.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/composite/FinancialDepartment.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.composite; +package com.baeldung.composite; /** * Created by Gebruiker on 5/1/2018. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java b/patterns/design-patterns/src/main/java/com/baeldung/composite/HeadDepartment.java similarity index 94% rename from core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java rename to patterns/design-patterns/src/main/java/com/baeldung/composite/HeadDepartment.java index 119b9c76b5..f54bcf303b 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/composite/HeadDepartment.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/composite/HeadDepartment.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.composite; +package com.baeldung.composite; import java.util.ArrayList; import java.util.List; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/composite/SalesDepartment.java b/patterns/design-patterns/src/main/java/com/baeldung/composite/SalesDepartment.java similarity index 92% rename from core-java/src/main/java/com/baeldung/designpatterns/composite/SalesDepartment.java rename to patterns/design-patterns/src/main/java/com/baeldung/composite/SalesDepartment.java index af234b4915..7f5e903100 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/composite/SalesDepartment.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/composite/SalesDepartment.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.composite; +package com.baeldung.composite; /** * Created by Gebruiker on 5/1/2018. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractFactory.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/AbstractFactory.java similarity index 63% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractFactory.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/AbstractFactory.java index 46d97d1a15..5b4bf08006 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractFactory.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/AbstractFactory.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public interface AbstractFactory { Animal getAnimal(String toyType) ; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternDriver.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/AbstractPatternDriver.java similarity index 90% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternDriver.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/AbstractPatternDriver.java index 7ab166e16a..68759d5aff 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternDriver.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/AbstractPatternDriver.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public class AbstractPatternDriver { public static void main(String[] args) { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Animal.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Animal.java similarity index 52% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Animal.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Animal.java index 59c1336053..52a8c83752 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Animal.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Animal.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public interface Animal { String getType(); diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AnimalFactory.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/AnimalFactory.java similarity index 87% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AnimalFactory.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/AnimalFactory.java index 49583c3a98..bbc3eb7a82 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/AnimalFactory.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/AnimalFactory.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public class AnimalFactory implements AbstractFactory { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Brown.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Brown.java similarity index 64% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Brown.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Brown.java index f251285ebf..d395d9de33 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Brown.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Brown.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public class Brown implements Color { diff --git a/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Color.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Color.java new file mode 100644 index 0000000000..337760fa4d --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Color.java @@ -0,0 +1,5 @@ +package com.baeldung.creational.abstractfactory; + +public interface Color { + String getColor(); +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/ColorFactory.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/ColorFactory.java similarity index 87% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/ColorFactory.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/ColorFactory.java index 8f7559ff27..8b7e4f8086 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/ColorFactory.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/ColorFactory.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public class ColorFactory implements AbstractFactory { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Dog.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Dog.java similarity index 74% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Dog.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Dog.java index 002b5665d3..38e90f34dc 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Dog.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Dog.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public class Dog implements Animal { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Duck.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Duck.java similarity index 75% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Duck.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Duck.java index 5603ad6eee..678ae5ca0c 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/Duck.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/Duck.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public class Duck implements Animal { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/FactoryProvider.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/FactoryProvider.java similarity index 83% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/FactoryProvider.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/FactoryProvider.java index fcbee1e6de..34ddbea545 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/FactoryProvider.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/FactoryProvider.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public class FactoryProvider { public static AbstractFactory getFactory(String choice){ diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/White.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/White.java similarity index 64% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/White.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/White.java index 62ef8048ea..6cb1e4cdd4 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/abstractfactory/White.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/abstractfactory/White.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; public class White implements Color { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BankAccount.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/builder/BankAccount.java similarity index 96% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BankAccount.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/builder/BankAccount.java index 355fa74895..1c6b0cc78e 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BankAccount.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/builder/BankAccount.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.builder; +package com.baeldung.creational.builder; public class BankAccount { private String name; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BuilderPatternDriver.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/builder/BuilderPatternDriver.java similarity index 90% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BuilderPatternDriver.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/builder/BuilderPatternDriver.java index d92a70e664..2d3a88a86b 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/builder/BuilderPatternDriver.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/builder/BuilderPatternDriver.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.builder; +package com.baeldung.creational.builder; public class BuilderPatternDriver { public static void main(String[] args) { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/FactoryDriver.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/FactoryDriver.java similarity index 89% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/factory/FactoryDriver.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/factory/FactoryDriver.java index 64ee307bb8..9261a5c0cb 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/FactoryDriver.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/FactoryDriver.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.factory; +package com.baeldung.creational.factory; public class FactoryDriver { public static void main(String[] args) { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Heptagon.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Heptagon.java similarity index 69% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Heptagon.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Heptagon.java index 935fc2f04c..9e6f04b951 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Heptagon.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Heptagon.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.factory; +package com.baeldung.creational.factory; public class Heptagon implements Polygon { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Octagon.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Octagon.java similarity index 68% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Octagon.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Octagon.java index fc62302dc8..b5c3be8a87 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Octagon.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Octagon.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.factory; +package com.baeldung.creational.factory; public class Octagon implements Polygon { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Pentagon.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Pentagon.java similarity index 69% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Pentagon.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Pentagon.java index 65d109b10b..0866de4f25 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Pentagon.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Pentagon.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.factory; +package com.baeldung.creational.factory; public class Pentagon implements Polygon { diff --git a/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Polygon.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Polygon.java new file mode 100644 index 0000000000..ed3f13eed6 --- /dev/null +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Polygon.java @@ -0,0 +1,5 @@ +package com.baeldung.creational.factory; + +public interface Polygon { + String getType(); +} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/PolygonFactory.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/PolygonFactory.java similarity index 89% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/factory/PolygonFactory.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/factory/PolygonFactory.java index 9f34fe77b9..c9af0952da 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/PolygonFactory.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/PolygonFactory.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.factory; +package com.baeldung.creational.factory; public class PolygonFactory { public Polygon getPolygon(int numberOfSides) { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Square.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Square.java similarity index 68% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Square.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Square.java index 805c1c9ae3..5c19873f00 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Square.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Square.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.factory; +package com.baeldung.creational.factory; public class Square implements Polygon { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Triangle.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Triangle.java similarity index 69% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Triangle.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Triangle.java index 8a8832d8a1..2f84674ae5 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/factory/Triangle.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/factory/Triangle.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.factory; +package com.baeldung.creational.factory; public class Triangle implements Polygon { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/Singleton.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/singleton/Singleton.java similarity index 83% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/Singleton.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/singleton/Singleton.java index 1a5ac82c89..e914fbd4af 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/Singleton.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/singleton/Singleton.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.singleton; +package com.baeldung.creational.singleton; public class Singleton { private Singleton() {} diff --git a/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/SingletonDriver.java b/patterns/design-patterns/src/main/java/com/baeldung/creational/singleton/SingletonDriver.java similarity index 76% rename from core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/SingletonDriver.java rename to patterns/design-patterns/src/main/java/com/baeldung/creational/singleton/SingletonDriver.java index 1955008d3e..555e751acb 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/creational/singleton/SingletonDriver.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/creational/singleton/SingletonDriver.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.singleton; +package com.baeldung.creational.singleton; public class SingletonDriver { public static void main(String[] args) { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/BubbleLights.java b/patterns/design-patterns/src/main/java/com/baeldung/decorator/BubbleLights.java similarity index 87% rename from core-java/src/main/java/com/baeldung/designpatterns/decorator/BubbleLights.java rename to patterns/design-patterns/src/main/java/com/baeldung/decorator/BubbleLights.java index 881add8b21..fff5a95b4b 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/decorator/BubbleLights.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/decorator/BubbleLights.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.decorator; +package com.baeldung.decorator; public class BubbleLights extends TreeDecorator { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java b/patterns/design-patterns/src/main/java/com/baeldung/decorator/ChristmasTree.java similarity index 54% rename from core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java rename to patterns/design-patterns/src/main/java/com/baeldung/decorator/ChristmasTree.java index e5dca41dd8..be07f4faf2 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTree.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/decorator/ChristmasTree.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.decorator; +package com.baeldung.decorator; public interface ChristmasTree { String decorate(); diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTreeImpl.java b/patterns/design-patterns/src/main/java/com/baeldung/decorator/ChristmasTreeImpl.java similarity index 75% rename from core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTreeImpl.java rename to patterns/design-patterns/src/main/java/com/baeldung/decorator/ChristmasTreeImpl.java index 9241fd59db..2b9e210eab 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/decorator/ChristmasTreeImpl.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/decorator/ChristmasTreeImpl.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.decorator; +package com.baeldung.decorator; public class ChristmasTreeImpl implements ChristmasTree { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/DecoratorPatternDriver.java b/patterns/design-patterns/src/main/java/com/baeldung/decorator/DecoratorPatternDriver.java similarity index 80% rename from core-java/src/main/java/com/baeldung/designpatterns/decorator/DecoratorPatternDriver.java rename to patterns/design-patterns/src/main/java/com/baeldung/decorator/DecoratorPatternDriver.java index 70b4f801cd..c20c23ff6e 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/decorator/DecoratorPatternDriver.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/decorator/DecoratorPatternDriver.java @@ -1,6 +1,6 @@ -package com.baeldung.designpatterns.decorator; +package com.baeldung.decorator; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; +import static com.baeldung.util.LogerUtil.LOG; public class DecoratorPatternDriver { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/Garland.java b/patterns/design-patterns/src/main/java/com/baeldung/decorator/Garland.java similarity index 86% rename from core-java/src/main/java/com/baeldung/designpatterns/decorator/Garland.java rename to patterns/design-patterns/src/main/java/com/baeldung/decorator/Garland.java index d2efd6e451..d3cb28a9e9 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/decorator/Garland.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/decorator/Garland.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.decorator; +package com.baeldung.decorator; public class Garland extends TreeDecorator { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/decorator/TreeDecorator.java b/patterns/design-patterns/src/main/java/com/baeldung/decorator/TreeDecorator.java similarity index 85% rename from core-java/src/main/java/com/baeldung/designpatterns/decorator/TreeDecorator.java rename to patterns/design-patterns/src/main/java/com/baeldung/decorator/TreeDecorator.java index 5427d2ac7e..47385a1967 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/decorator/TreeDecorator.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/decorator/TreeDecorator.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.decorator; +package com.baeldung.decorator; public abstract class TreeDecorator implements ChristmasTree { private ChristmasTree tree; diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/CarEngineFacade.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/CarEngineFacade.java similarity index 92% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/CarEngineFacade.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/CarEngineFacade.java index 91f9b79738..27a1eb2729 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/CarEngineFacade.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/CarEngineFacade.java @@ -1,6 +1,6 @@ -package com.baeldung.pattern.facade; +package com.baeldung.facade; -import com.baeldung.pattern.facade.carsystem.*; +import com.baeldung.facade.carsystem.*; public class CarEngineFacade { private static final Integer DEFAULT_COOLING_TEMP = 90; diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/AirFlowController.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/AirFlowController.java similarity index 90% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/AirFlowController.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/AirFlowController.java index 5ee846ea31..c9cf130e20 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/AirFlowController.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/AirFlowController.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade.carsystem; +package com.baeldung.facade.carsystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/AirFlowMeter.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/AirFlowMeter.java similarity index 68% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/AirFlowMeter.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/AirFlowMeter.java index b47f9cfc4a..4eb7ac3c44 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/AirFlowMeter.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/AirFlowMeter.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade.carsystem; +package com.baeldung.facade.carsystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -8,6 +8,6 @@ public class AirFlowMeter { private static final Logger LOGGER = LoggerFactory.getLogger(AirFlowMeter.class); public void getMeasurements() { - LOGGER.info("Getting air measurements..."); + LOGGER.info("Getting air measurements.."); } } diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/CatalyticConverter.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/CatalyticConverter.java similarity index 88% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/CatalyticConverter.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/CatalyticConverter.java index 7d637cd444..0abc8c58ce 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/CatalyticConverter.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/CatalyticConverter.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade.carsystem; +package com.baeldung.facade.carsystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/CoolingController.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/CoolingController.java similarity index 91% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/CoolingController.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/CoolingController.java index ae556e685c..c13850d166 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/CoolingController.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/CoolingController.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade.carsystem; +package com.baeldung.facade.carsystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +28,7 @@ public class CoolingController { } public void stop() { - LOGGER.info("Stopping Cooling Controller..."); + LOGGER.info("Stopping Cooling Controller.."); radiator.off(); } } diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/FuelInjector.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/FuelInjector.java similarity index 82% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/FuelInjector.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/FuelInjector.java index c7905745e4..a619508e7a 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/FuelInjector.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/FuelInjector.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade.carsystem; +package com.baeldung.facade.carsystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,6 +18,6 @@ public class FuelInjector { } public void off() { - LOGGER.info("Stopping Fuel injector..."); + LOGGER.info("Stopping Fuel injector.."); } } diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/FuelPump.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/FuelPump.java similarity index 66% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/FuelPump.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/FuelPump.java index 900358f8ff..0cd193558d 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/FuelPump.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/FuelPump.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade.carsystem; +package com.baeldung.facade.carsystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -8,6 +8,6 @@ public class FuelPump { private static final Logger LOGGER = LoggerFactory.getLogger(FuelPump.class); public void pump() { - LOGGER.info("Fuel Pump is pumping fuel..."); + LOGGER.info("Fuel Pump is pumping fuel.."); } } diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/Radiator.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/Radiator.java similarity index 90% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/Radiator.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/Radiator.java index 6ca6cef9d9..c1004f561f 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/Radiator.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/Radiator.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade.carsystem; +package com.baeldung.facade.carsystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/Starter.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/Starter.java similarity index 70% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/Starter.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/Starter.java index b1f45a0be8..5f13d5726a 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/Starter.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/Starter.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade.carsystem; +package com.baeldung.facade.carsystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -8,6 +8,6 @@ public class Starter { private static final Logger LOGGER = LoggerFactory.getLogger(Starter.class); public void start() { - LOGGER.info("Starting..."); + LOGGER.info("Starting.."); } } diff --git a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/TemperatureSensor.java b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/TemperatureSensor.java similarity index 67% rename from patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/TemperatureSensor.java rename to patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/TemperatureSensor.java index d6a94858b4..5850a8a3be 100644 --- a/patterns/facade/src/main/java/com/baeldung/pattern/facade/carsystem/TemperatureSensor.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/facade/carsystem/TemperatureSensor.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade.carsystem; +package com.baeldung.facade.carsystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -7,7 +7,7 @@ public class TemperatureSensor { private static final Logger LOGGER = LoggerFactory.getLogger(TemperatureSensor.class); public void getTemperature(){ - LOGGER.info("Getting temperature from the sensor..."); + LOGGER.info("Getting temperature from the sensor.."); } } diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Car.java b/patterns/design-patterns/src/main/java/com/baeldung/flyweight/Car.java similarity index 83% rename from core-java/src/main/java/com/baeldung/designpatterns/flyweight/Car.java rename to patterns/design-patterns/src/main/java/com/baeldung/flyweight/Car.java index 50f62cafaa..a0b1a7cdf5 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Car.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/flyweight/Car.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.flyweight; +package com.baeldung.flyweight; import java.awt.Color; @@ -53,7 +53,7 @@ public class Car implements Vehicle { /* * (non-Javadoc) * - * @see com.baeldung.designpatterns.flyweight.Vehicle#start() + * @see com.baeldung.flyweight.Vehicle#start() */ @Override public void start() { @@ -64,7 +64,7 @@ public class Car implements Vehicle { /* * (non-Javadoc) * - * @see com.baeldung.designpatterns.flyweight.Vehicle#stop() + * @see com.baeldung.flyweight.Vehicle#stop() */ @Override public void stop() { @@ -75,7 +75,7 @@ public class Car implements Vehicle { /* * (non-Javadoc) * - * @see com.baeldung.designpatterns.flyweight.Vehicle#getColor() + * @see com.baeldung.flyweight.Vehicle#getColor() */ @Override public Color getColor() { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Engine.java b/patterns/design-patterns/src/main/java/com/baeldung/flyweight/Engine.java similarity index 90% rename from core-java/src/main/java/com/baeldung/designpatterns/flyweight/Engine.java rename to patterns/design-patterns/src/main/java/com/baeldung/flyweight/Engine.java index 05d9ca98b8..2319f61a74 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Engine.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/flyweight/Engine.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.flyweight; +package com.baeldung.flyweight; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Vehicle.java b/patterns/design-patterns/src/main/java/com/baeldung/flyweight/Vehicle.java similarity index 87% rename from core-java/src/main/java/com/baeldung/designpatterns/flyweight/Vehicle.java rename to patterns/design-patterns/src/main/java/com/baeldung/flyweight/Vehicle.java index c285f9fcff..8cbb8e2896 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/Vehicle.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/flyweight/Vehicle.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.flyweight; +package com.baeldung.flyweight; import java.awt.Color; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/VehicleFactory.java b/patterns/design-patterns/src/main/java/com/baeldung/flyweight/VehicleFactory.java similarity index 96% rename from core-java/src/main/java/com/baeldung/designpatterns/flyweight/VehicleFactory.java rename to patterns/design-patterns/src/main/java/com/baeldung/flyweight/VehicleFactory.java index 2854b7dab1..ff0dbbdada 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/flyweight/VehicleFactory.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/flyweight/VehicleFactory.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.flyweight; +package com.baeldung.flyweight; import java.awt.Color; import java.util.HashMap; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/observer/Channel.java b/patterns/design-patterns/src/main/java/com/baeldung/observer/Channel.java similarity index 58% rename from core-java/src/main/java/com/baeldung/designpatterns/observer/Channel.java rename to patterns/design-patterns/src/main/java/com/baeldung/observer/Channel.java index 9ca2edac38..dcffe1a37d 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/observer/Channel.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/observer/Channel.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.observer; +package com.baeldung.observer; public interface Channel { public void update(Object o); diff --git a/core-java/src/main/java/com/baeldung/designpatterns/observer/NewsAgency.java b/patterns/design-patterns/src/main/java/com/baeldung/observer/NewsAgency.java similarity index 91% rename from core-java/src/main/java/com/baeldung/designpatterns/observer/NewsAgency.java rename to patterns/design-patterns/src/main/java/com/baeldung/observer/NewsAgency.java index 0330fbdcdc..02e2872417 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/observer/NewsAgency.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/observer/NewsAgency.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.observer; +package com.baeldung.observer; import java.util.ArrayList; import java.util.List; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/observer/NewsChannel.java b/patterns/design-patterns/src/main/java/com/baeldung/observer/NewsChannel.java similarity index 86% rename from core-java/src/main/java/com/baeldung/designpatterns/observer/NewsChannel.java rename to patterns/design-patterns/src/main/java/com/baeldung/observer/NewsChannel.java index 09c22e0ad8..fd0178ca45 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/observer/NewsChannel.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/observer/NewsChannel.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.observer; +package com.baeldung.observer; public class NewsChannel implements Channel { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/observer/ONewsAgency.java b/patterns/design-patterns/src/main/java/com/baeldung/observer/ONewsAgency.java similarity index 83% rename from core-java/src/main/java/com/baeldung/designpatterns/observer/ONewsAgency.java rename to patterns/design-patterns/src/main/java/com/baeldung/observer/ONewsAgency.java index 2849820663..b567ad295a 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/observer/ONewsAgency.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/observer/ONewsAgency.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.observer; +package com.baeldung.observer; import java.util.Observable; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/observer/ONewsChannel.java b/patterns/design-patterns/src/main/java/com/baeldung/observer/ONewsChannel.java similarity index 89% rename from core-java/src/main/java/com/baeldung/designpatterns/observer/ONewsChannel.java rename to patterns/design-patterns/src/main/java/com/baeldung/observer/ONewsChannel.java index 3989fe0286..20cc1811bf 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/observer/ONewsChannel.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/observer/ONewsChannel.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.observer; +package com.baeldung.observer; import java.util.Observable; import java.util.Observer; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/observer/PCLNewsAgency.java b/patterns/design-patterns/src/main/java/com/baeldung/observer/PCLNewsAgency.java similarity index 93% rename from core-java/src/main/java/com/baeldung/designpatterns/observer/PCLNewsAgency.java rename to patterns/design-patterns/src/main/java/com/baeldung/observer/PCLNewsAgency.java index b05b97ab0b..df46731a85 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/observer/PCLNewsAgency.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/observer/PCLNewsAgency.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.observer; +package com.baeldung.observer; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/observer/PCLNewsChannel.java b/patterns/design-patterns/src/main/java/com/baeldung/observer/PCLNewsChannel.java similarity index 90% rename from core-java/src/main/java/com/baeldung/designpatterns/observer/PCLNewsChannel.java rename to patterns/design-patterns/src/main/java/com/baeldung/observer/PCLNewsChannel.java index ff8d35463c..d3e096f7e8 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/observer/PCLNewsChannel.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/observer/PCLNewsChannel.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.observer; +package com.baeldung.observer; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java b/patterns/design-patterns/src/main/java/com/baeldung/proxy/ExpensiveObject.java similarity index 57% rename from core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java rename to patterns/design-patterns/src/main/java/com/baeldung/proxy/ExpensiveObject.java index 256b31bc84..ae7820024c 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObject.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/proxy/ExpensiveObject.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.proxy; +package com.baeldung.proxy; public interface ExpensiveObject { void process(); diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectImpl.java b/patterns/design-patterns/src/main/java/com/baeldung/proxy/ExpensiveObjectImpl.java similarity index 64% rename from core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectImpl.java rename to patterns/design-patterns/src/main/java/com/baeldung/proxy/ExpensiveObjectImpl.java index de31e22b30..7ade31da88 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectImpl.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/proxy/ExpensiveObjectImpl.java @@ -1,6 +1,6 @@ -package com.baeldung.designpatterns.proxy; +package com.baeldung.proxy; -import static com.baeldung.designpatterns.util.LogerUtil.LOG;; +import static com.baeldung.util.LogerUtil.LOG;; public class ExpensiveObjectImpl implements ExpensiveObject { @@ -14,7 +14,7 @@ public class ExpensiveObjectImpl implements ExpensiveObject { } private void heavyInitialConfiguration() { - LOG.info("Loading initial configuration..."); + LOG.info("Loading initial configuration.."); } } \ No newline at end of file diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectProxy.java b/patterns/design-patterns/src/main/java/com/baeldung/proxy/ExpensiveObjectProxy.java similarity index 86% rename from core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectProxy.java rename to patterns/design-patterns/src/main/java/com/baeldung/proxy/ExpensiveObjectProxy.java index f36e688c90..f7985f331e 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ExpensiveObjectProxy.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/proxy/ExpensiveObjectProxy.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.proxy; +package com.baeldung.proxy; public class ExpensiveObjectProxy implements ExpensiveObject{ private static ExpensiveObject object; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ProxyPatternDriver.java b/patterns/design-patterns/src/main/java/com/baeldung/proxy/ProxyPatternDriver.java similarity index 82% rename from core-java/src/main/java/com/baeldung/designpatterns/proxy/ProxyPatternDriver.java rename to patterns/design-patterns/src/main/java/com/baeldung/proxy/ProxyPatternDriver.java index 088b069e28..02e4de96ea 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/proxy/ProxyPatternDriver.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/proxy/ProxyPatternDriver.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.proxy; +package com.baeldung.proxy; public class ProxyPatternDriver { public static void main(String[] args) { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/Cache.java b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/Cache.java similarity index 94% rename from core-java/src/main/java/com/baeldung/designpatterns/service/locator/Cache.java rename to patterns/design-patterns/src/main/java/com/baeldung/service/locator/Cache.java index 847d8a71e0..c215dda91f 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/Cache.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/Cache.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.service.locator; +package com.baeldung.service.locator; import java.util.ArrayList; import java.util.List; diff --git a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/EmailService.java b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/EmailService.java similarity index 82% rename from core-java/src/main/java/com/baeldung/designpatterns/service/locator/EmailService.java rename to patterns/design-patterns/src/main/java/com/baeldung/service/locator/EmailService.java index 7ac7e05790..930312aecd 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/EmailService.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/EmailService.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.service.locator; +package com.baeldung.service.locator; /** * Created by Gebruiker on 4/20/2018. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/InitialContext.java b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/InitialContext.java similarity index 87% rename from core-java/src/main/java/com/baeldung/designpatterns/service/locator/InitialContext.java rename to patterns/design-patterns/src/main/java/com/baeldung/service/locator/InitialContext.java index d5234b39cd..3614b212f5 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/InitialContext.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/InitialContext.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.service.locator; +package com.baeldung.service.locator; /** * Created by Gebruiker on 4/20/2018. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/Main.java b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/Main.java similarity index 91% rename from core-java/src/main/java/com/baeldung/designpatterns/service/locator/Main.java rename to patterns/design-patterns/src/main/java/com/baeldung/service/locator/Main.java index 787f7e708c..984410a991 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/Main.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/Main.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.service.locator; +package com.baeldung.service.locator; /** * Created by Gebruiker on 4/20/2018. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/MessagingService.java b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/MessagingService.java similarity index 65% rename from core-java/src/main/java/com/baeldung/designpatterns/service/locator/MessagingService.java rename to patterns/design-patterns/src/main/java/com/baeldung/service/locator/MessagingService.java index 5853dfd7f7..0b48d9ea5e 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/MessagingService.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/MessagingService.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.service.locator; +package com.baeldung.service.locator; public interface MessagingService { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/SMSService.java b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/SMSService.java similarity index 82% rename from core-java/src/main/java/com/baeldung/designpatterns/service/locator/SMSService.java rename to patterns/design-patterns/src/main/java/com/baeldung/service/locator/SMSService.java index 87255ef658..d0bc13b847 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/SMSService.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/SMSService.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.service.locator; +package com.baeldung.service.locator; /** * Created by Gebruiker on 4/20/2018. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/ServiceLocator.java b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/ServiceLocator.java similarity index 91% rename from core-java/src/main/java/com/baeldung/designpatterns/service/locator/ServiceLocator.java rename to patterns/design-patterns/src/main/java/com/baeldung/service/locator/ServiceLocator.java index 7e1a2349a1..6da441d0aa 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/service/locator/ServiceLocator.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/service/locator/ServiceLocator.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.service.locator; +package com.baeldung.service.locator; /** * Created by Gebruiker on 4/20/2018. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/ClassSingleton.java b/patterns/design-patterns/src/main/java/com/baeldung/singleton/ClassSingleton.java similarity index 91% rename from core-java/src/main/java/com/baeldung/designpatterns/singleton/ClassSingleton.java rename to patterns/design-patterns/src/main/java/com/baeldung/singleton/ClassSingleton.java index 0fc86e30a7..d538e6dda3 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/singleton/ClassSingleton.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/singleton/ClassSingleton.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.singleton; +package com.baeldung.singleton; public class ClassSingleton { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/EnumSingleton.java b/patterns/design-patterns/src/main/java/com/baeldung/singleton/EnumSingleton.java similarity index 90% rename from core-java/src/main/java/com/baeldung/designpatterns/singleton/EnumSingleton.java rename to patterns/design-patterns/src/main/java/com/baeldung/singleton/EnumSingleton.java index f75484477b..89321a6b3f 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/singleton/EnumSingleton.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/singleton/EnumSingleton.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.singleton; +package com.baeldung.singleton; public enum EnumSingleton { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/Sandbox.java b/patterns/design-patterns/src/main/java/com/baeldung/singleton/Sandbox.java similarity index 96% rename from core-java/src/main/java/com/baeldung/designpatterns/singleton/Sandbox.java rename to patterns/design-patterns/src/main/java/com/baeldung/singleton/Sandbox.java index f8ca2ffa78..c7fb363336 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/singleton/Sandbox.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/singleton/Sandbox.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.singleton; +package com.baeldung.singleton; public class Sandbox { diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/DclSingleton.java b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/DclSingleton.java similarity index 91% rename from core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/DclSingleton.java rename to patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/DclSingleton.java index e10f111a56..26cd9927b4 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/DclSingleton.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/DclSingleton.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.singleton.synchronization; +package com.baeldung.singleton.synchronization; /** * Double-checked locking design pattern applied to a singleton. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/DraconianSingleton.java b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/DraconianSingleton.java similarity index 90% rename from core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/DraconianSingleton.java rename to patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/DraconianSingleton.java index 1d01c49b13..9c51b4044b 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/DraconianSingleton.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/DraconianSingleton.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.singleton.synchronization; +package com.baeldung.singleton.synchronization; /** * Draconian singleton. The method to get the instance is synchronized. diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/EarlyInitSingleton.java b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/EarlyInitSingleton.java similarity index 90% rename from core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/EarlyInitSingleton.java rename to patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/EarlyInitSingleton.java index 18c4b7cdce..22e1d3edab 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/EarlyInitSingleton.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/EarlyInitSingleton.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.singleton.synchronization; +package com.baeldung.singleton.synchronization; /** * Singleton with early initialization. Inlines the singleton instance diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/EnumSingleton.java b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/EnumSingleton.java similarity index 77% rename from core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/EnumSingleton.java rename to patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/EnumSingleton.java index b7ff7f50b1..afa6911910 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/EnumSingleton.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/EnumSingleton.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.singleton.synchronization; +package com.baeldung.singleton.synchronization; /** * Enum singleton pattern. Uses an enum to hold a reference to the singleton diff --git a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/InitOnDemandSingleton.java b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/InitOnDemandSingleton.java similarity index 92% rename from core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/InitOnDemandSingleton.java rename to patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/InitOnDemandSingleton.java index d76bada786..46feab6208 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/singleton/synchronization/InitOnDemandSingleton.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/singleton/synchronization/InitOnDemandSingleton.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.singleton.synchronization; +package com.baeldung.singleton.synchronization; /** * Initialization on demand singleton pattern. Uses a nested static class to diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/application/Application.java b/patterns/design-patterns/src/main/java/com/baeldung/templatemethod/application/Application.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/application/Application.java rename to patterns/design-patterns/src/main/java/com/baeldung/templatemethod/application/Application.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/Computer.java b/patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/Computer.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/Computer.java rename to patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/Computer.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/ComputerBuilder.java b/patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/ComputerBuilder.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/ComputerBuilder.java rename to patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/ComputerBuilder.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputer.java b/patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/HighEndComputer.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputer.java rename to patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/HighEndComputer.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputerBuilder.java b/patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/HighEndComputerBuilder.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/HighEndComputerBuilder.java rename to patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/HighEndComputerBuilder.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputer.java b/patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/StandardComputer.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputer.java rename to patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/StandardComputer.java diff --git a/patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputerBuilder.java b/patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/StandardComputerBuilder.java similarity index 100% rename from patterns/behavioral-patterns/src/main/java/com/baeldung/pattern/templatemethod/model/StandardComputerBuilder.java rename to patterns/design-patterns/src/main/java/com/baeldung/templatemethod/model/StandardComputerBuilder.java diff --git a/core-java/src/main/java/com/baeldung/designpatterns/util/LogerUtil.java b/patterns/design-patterns/src/main/java/com/baeldung/util/LogerUtil.java similarity index 94% rename from core-java/src/main/java/com/baeldung/designpatterns/util/LogerUtil.java rename to patterns/design-patterns/src/main/java/com/baeldung/util/LogerUtil.java index f7b6e4f3e9..7217a4bc40 100644 --- a/core-java/src/main/java/com/baeldung/designpatterns/util/LogerUtil.java +++ b/patterns/design-patterns/src/main/java/com/baeldung/util/LogerUtil.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.util; +package com.baeldung.util; import java.io.BufferedReader; import java.io.IOException; diff --git a/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java b/patterns/design-patterns/src/test/java/com/baeldung/AdapterPatternIntegrationTest.java similarity index 68% rename from core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/AdapterPatternIntegrationTest.java index 8cad1290d9..78a1492d83 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/AdapterPatternIntegrationTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/AdapterPatternIntegrationTest.java @@ -1,15 +1,15 @@ -package com.baeldung.designpatterns; +package com.baeldung; import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.baeldung.designpatterns.adapter.AstonMartin; -import com.baeldung.designpatterns.adapter.BugattiVeyron; -import com.baeldung.designpatterns.adapter.McLaren; -import com.baeldung.designpatterns.adapter.Movable; -import com.baeldung.designpatterns.adapter.MovableAdapter; -import com.baeldung.designpatterns.adapter.MovableAdapterImpl; +import com.baeldung.adapter.AstonMartin; +import com.baeldung.adapter.BugattiVeyron; +import com.baeldung.adapter.McLaren; +import com.baeldung.adapter.Movable; +import com.baeldung.adapter.MovableAdapter; +import com.baeldung.adapter.MovableAdapterImpl; public class AdapterPatternIntegrationTest { @Test diff --git a/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java b/patterns/design-patterns/src/test/java/com/baeldung/BridgePatternIntegrationTest.java similarity index 64% rename from core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/BridgePatternIntegrationTest.java index ed7eb0c453..adcb5cdd2c 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/BridgePatternIntegrationTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/BridgePatternIntegrationTest.java @@ -1,14 +1,14 @@ -package com.baeldung.designpatterns; +package com.baeldung; import static org.junit.Assert.*; import org.junit.Test; -import com.baeldung.designpatterns.bridge.Blue; -import com.baeldung.designpatterns.bridge.Red; -import com.baeldung.designpatterns.bridge.Shape; -import com.baeldung.designpatterns.bridge.Square; -import com.baeldung.designpatterns.bridge.Triangle; +import com.baeldung.bridge.Blue; +import com.baeldung.bridge.Red; +import com.baeldung.bridge.Shape; +import com.baeldung.bridge.Square; +import com.baeldung.bridge.Triangle; public class BridgePatternIntegrationTest { diff --git a/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java b/patterns/design-patterns/src/test/java/com/baeldung/DecoratorPatternIntegrationTest.java similarity index 69% rename from core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/DecoratorPatternIntegrationTest.java index de0ca8a135..23a717ae2e 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/DecoratorPatternIntegrationTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/DecoratorPatternIntegrationTest.java @@ -1,13 +1,13 @@ -package com.baeldung.designpatterns; +package com.baeldung; import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.baeldung.designpatterns.decorator.BubbleLights; -import com.baeldung.designpatterns.decorator.ChristmasTree; -import com.baeldung.designpatterns.decorator.ChristmasTreeImpl; -import com.baeldung.designpatterns.decorator.Garland; +import com.baeldung.decorator.BubbleLights; +import com.baeldung.decorator.ChristmasTree; +import com.baeldung.decorator.ChristmasTreeImpl; +import com.baeldung.decorator.Garland; public class DecoratorPatternIntegrationTest { @Test diff --git a/core-java/src/test/java/com/baeldung/designpatterns/ProxyPatternIntegrationTest.java b/patterns/design-patterns/src/test/java/com/baeldung/ProxyPatternIntegrationTest.java similarity index 80% rename from core-java/src/test/java/com/baeldung/designpatterns/ProxyPatternIntegrationTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/ProxyPatternIntegrationTest.java index 7fa95b31d7..c035793b64 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/ProxyPatternIntegrationTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/ProxyPatternIntegrationTest.java @@ -1,6 +1,6 @@ -package com.baeldung.designpatterns; +package com.baeldung; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; +import static com.baeldung.util.LogerUtil.LOG; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -11,8 +11,8 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import com.baeldung.designpatterns.proxy.ExpensiveObject; -import com.baeldung.designpatterns.proxy.ExpensiveObjectProxy; +import com.baeldung.proxy.ExpensiveObject; +import com.baeldung.proxy.ExpensiveObjectProxy; public class ProxyPatternIntegrationTest { public static TestAppenderDP appender; @@ -31,7 +31,7 @@ public class ProxyPatternIntegrationTest { final List log = appender.getLog(); - assertThat((String) log.get(0).getMessage(), is("Loading initial configuration...")); + assertThat((String) log.get(0).getMessage(), is("Loading initial configuration..")); assertThat((String) log.get(1).getMessage(), is("processing complete.")); assertThat((String) log.get(2).getMessage(), is("processing complete.")); } diff --git a/core-java/src/test/java/com/baeldung/designpatterns/TestAppenderDP.java b/patterns/design-patterns/src/test/java/com/baeldung/TestAppenderDP.java similarity index 94% rename from core-java/src/test/java/com/baeldung/designpatterns/TestAppenderDP.java rename to patterns/design-patterns/src/test/java/com/baeldung/TestAppenderDP.java index 613c26fa13..2b3bc47292 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/TestAppenderDP.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/TestAppenderDP.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns; +package com.baeldung; import java.util.ArrayList; import java.util.List; diff --git a/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/chainofresponsibility/ChainOfResponsibilityTest.java b/patterns/design-patterns/src/test/java/com/baeldung/chainofresponsibility/ChainOfResponsibilityTest.java similarity index 100% rename from patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/chainofresponsibility/ChainOfResponsibilityTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/chainofresponsibility/ChainOfResponsibilityTest.java diff --git a/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/command/test/OpenTextFileOperationUnitTest.java b/patterns/design-patterns/src/test/java/com/baeldung/command/test/OpenTextFileOperationUnitTest.java similarity index 100% rename from patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/command/test/OpenTextFileOperationUnitTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/command/test/OpenTextFileOperationUnitTest.java diff --git a/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/command/test/SaveTextFileOperationUnitTest.java b/patterns/design-patterns/src/test/java/com/baeldung/command/test/SaveTextFileOperationUnitTest.java similarity index 100% rename from patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/command/test/SaveTextFileOperationUnitTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/command/test/SaveTextFileOperationUnitTest.java diff --git a/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/command/test/TextFileOperationExecutorUnitTest.java b/patterns/design-patterns/src/test/java/com/baeldung/command/test/TextFileOperationExecutorUnitTest.java similarity index 100% rename from patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/command/test/TextFileOperationExecutorUnitTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/command/test/TextFileOperationExecutorUnitTest.java diff --git a/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/command/test/TextFileUnitTest.java b/patterns/design-patterns/src/test/java/com/baeldung/command/test/TextFileUnitTest.java similarity index 100% rename from patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/command/test/TextFileUnitTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/command/test/TextFileUnitTest.java diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternIntegrationTest.java b/patterns/design-patterns/src/test/java/com/baeldung/creational/abstractfactory/AbstractPatternIntegrationTest.java similarity index 91% rename from core-java/src/test/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternIntegrationTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/creational/abstractfactory/AbstractPatternIntegrationTest.java index dc02b976a0..6d1a4ad8fd 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/creational/abstractfactory/AbstractPatternIntegrationTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/creational/abstractfactory/AbstractPatternIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.abstractfactory; +package com.baeldung.creational.abstractfactory; import static org.junit.Assert.*; diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/builder/BuilderPatternIntegrationTest.java b/patterns/design-patterns/src/test/java/com/baeldung/creational/builder/BuilderPatternIntegrationTest.java similarity index 95% rename from core-java/src/test/java/com/baeldung/designpatterns/creational/builder/BuilderPatternIntegrationTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/creational/builder/BuilderPatternIntegrationTest.java index 898330b26e..03b0b3db90 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/creational/builder/BuilderPatternIntegrationTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/creational/builder/BuilderPatternIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.builder; +package com.baeldung.creational.builder; import static org.junit.Assert.assertEquals; diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/factory/FactoryIntegrationTest.java b/patterns/design-patterns/src/test/java/com/baeldung/creational/factory/FactoryIntegrationTest.java similarity index 94% rename from core-java/src/test/java/com/baeldung/designpatterns/creational/factory/FactoryIntegrationTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/creational/factory/FactoryIntegrationTest.java index ed0419c16d..61cf83c1e7 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/creational/factory/FactoryIntegrationTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/creational/factory/FactoryIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.factory; +package com.baeldung.creational.factory; import static org.junit.Assert.*; diff --git a/core-java/src/test/java/com/baeldung/designpatterns/creational/singleton/SingletonIntegrationTest.java b/patterns/design-patterns/src/test/java/com/baeldung/creational/singleton/SingletonIntegrationTest.java similarity index 92% rename from core-java/src/test/java/com/baeldung/designpatterns/creational/singleton/SingletonIntegrationTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/creational/singleton/SingletonIntegrationTest.java index a3d5b7a14d..7c3d134ae6 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/creational/singleton/SingletonIntegrationTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/creational/singleton/SingletonIntegrationTest.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.creational.singleton; +package com.baeldung.creational.singleton; import org.junit.Test; import static org.junit.Assert.*; diff --git a/patterns/facade/src/test/java/com/baeldung/pattern/facade/CarEngineFacadeTest.java b/patterns/design-patterns/src/test/java/com/baeldung/facade/CarEngineFacadeTest.java similarity index 94% rename from patterns/facade/src/test/java/com/baeldung/pattern/facade/CarEngineFacadeTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/facade/CarEngineFacadeTest.java index 79c159319d..88c5d3c9bc 100644 --- a/patterns/facade/src/test/java/com/baeldung/pattern/facade/CarEngineFacadeTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/facade/CarEngineFacadeTest.java @@ -1,4 +1,4 @@ -package com.baeldung.pattern.facade; +package com.baeldung.facade; import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.spi.ILoggingEvent; @@ -35,12 +35,12 @@ public class CarEngineFacadeTest { CarEngineFacade carEngineFacade = new CarEngineFacade(); carEngineFacade.startEngine(); assertTrue(appender.logContains("Fuel injector ready to inject fuel.")); - assertTrue(appender.logContains("Getting air measurements...")); + assertTrue(appender.logContains("Getting air measurements..")); assertTrue(appender.logContains("Air provided!")); assertTrue(appender.logContains("Fuel injector ready to inject fuel.")); - assertTrue(appender.logContains("Fuel Pump is pumping fuel...")); + assertTrue(appender.logContains("Fuel Pump is pumping fuel..")); assertTrue(appender.logContains("Fuel injected.")); - assertTrue(appender.logContains("Starting...")); + assertTrue(appender.logContains("Starting..")); assertTrue(appender.logContains("Setting temperature upper limit to 90")); assertTrue(appender.logContains("Cooling Controller ready!")); assertTrue(appender.logContains("Setting radiator speed to 10")); @@ -52,12 +52,12 @@ public class CarEngineFacadeTest { public void whenStopEngine_thenAllNecessaryActionsPerformed() { CarEngineFacade carEngineFacade = new CarEngineFacade(); carEngineFacade.stopEngine(); - assertTrue(appender.logContains("Stopping Fuel injector...")); + assertTrue(appender.logContains("Stopping Fuel injector..")); assertTrue(appender.logContains("Catalytic Converter switched off!")); assertTrue(appender.logContains("Scheduled cooling with maximum allowed temperature 50")); - assertTrue(appender.logContains("Getting temperature from the sensor...")); + assertTrue(appender.logContains("Getting temperature from the sensor..")); assertTrue(appender.logContains("Radiator switched on!")); - assertTrue(appender.logContains("Stopping Cooling Controller...")); + assertTrue(appender.logContains("Stopping Cooling Controller..")); assertTrue(appender.logContains("Radiator switched off!")); assertTrue(appender.logContains("Air controller switched off.")); } diff --git a/core-java/src/test/java/com/baeldung/designpatterns/flyweight/FlyweightUnitTest.java b/patterns/design-patterns/src/test/java/com/baeldung/flyweight/FlyweightUnitTest.java similarity index 96% rename from core-java/src/test/java/com/baeldung/designpatterns/flyweight/FlyweightUnitTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/flyweight/FlyweightUnitTest.java index 645e2fd459..ab8ed32b4e 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/flyweight/FlyweightUnitTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/flyweight/FlyweightUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.flyweight; +package com.baeldung.flyweight; import java.awt.Color; diff --git a/core-java/src/test/java/com/baeldung/designpatterns/observer/ObserverIntegrationTest.java b/patterns/design-patterns/src/test/java/com/baeldung/observer/ObserverIntegrationTest.java similarity index 87% rename from core-java/src/test/java/com/baeldung/designpatterns/observer/ObserverIntegrationTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/observer/ObserverIntegrationTest.java index a8a0e29990..5590ecd717 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/observer/ObserverIntegrationTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/observer/ObserverIntegrationTest.java @@ -1,11 +1,11 @@ -package com.baeldung.designpatterns.observer; +package com.baeldung.observer; import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.baeldung.designpatterns.observer.NewsAgency; -import com.baeldung.designpatterns.observer.NewsChannel; +import com.baeldung.observer.NewsAgency; +import com.baeldung.observer.NewsChannel; public class ObserverIntegrationTest { diff --git a/core-java/src/test/java/com/baeldung/designpatterns/singleton/synchronization/SingletonSynchronizationUnitTest.java b/patterns/design-patterns/src/test/java/com/baeldung/singleton/synchronization/SingletonSynchronizationUnitTest.java similarity index 98% rename from core-java/src/test/java/com/baeldung/designpatterns/singleton/synchronization/SingletonSynchronizationUnitTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/singleton/synchronization/SingletonSynchronizationUnitTest.java index 2c1a3fe093..08a70f6056 100644 --- a/core-java/src/test/java/com/baeldung/designpatterns/singleton/synchronization/SingletonSynchronizationUnitTest.java +++ b/patterns/design-patterns/src/test/java/com/baeldung/singleton/synchronization/SingletonSynchronizationUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.designpatterns.singleton.synchronization; +package com.baeldung.singleton.synchronization; import java.util.Collections; import java.util.HashSet; diff --git a/patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/templatemethod/test/TemplateMethodPatternTest.java b/patterns/design-patterns/src/test/java/com/baeldung/templatemethod/test/TemplateMethodPatternTest.java similarity index 100% rename from patterns/behavioral-patterns/src/test/java/com/baeldung/pattern/templatemethod/test/TemplateMethodPatternTest.java rename to patterns/design-patterns/src/test/java/com/baeldung/templatemethod/test/TemplateMethodPatternTest.java diff --git a/patterns/facade/pom.xml b/patterns/facade/pom.xml deleted file mode 100644 index 573e557eb6..0000000000 --- a/patterns/facade/pom.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - 4.0.0 - com.baeldung.pattern.facade - pattern.facade - 1.0 - jar - - com.baeldung.patterns - patterns-parent - 1.0.0-SNAPSHOT - .. - - - - - junit - junit - 4.12 - test - - - - UTF-8 - 1.8 - 1.8 - - \ No newline at end of file diff --git a/patterns/front-controller/pom.xml b/patterns/front-controller/pom.xml index 877277a062..a12d606165 100644 --- a/patterns/front-controller/pom.xml +++ b/patterns/front-controller/pom.xml @@ -7,7 +7,7 @@ patterns-parent - com.baeldung.patterns + com.baeldung 1.0.0-SNAPSHOT .. diff --git a/patterns/intercepting-filter/pom.xml b/patterns/intercepting-filter/pom.xml index b9916d9157..8c68302315 100644 --- a/patterns/intercepting-filter/pom.xml +++ b/patterns/intercepting-filter/pom.xml @@ -7,7 +7,7 @@ war - com.baeldung.patterns + com.baeldung patterns-parent 1.0.0-SNAPSHOT .. diff --git a/patterns/pom.xml b/patterns/pom.xml index 7ee2c749be..a811664b86 100644 --- a/patterns/pom.xml +++ b/patterns/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - com.baeldung.patterns + com.baeldung patterns-parent pom @@ -16,7 +16,7 @@ front-controller intercepting-filter - behavioral-patterns + design-patterns From b677208899684e9326b23a8eab940dbb4ebb04b8 Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Fri, 11 May 2018 13:35:04 +0100 Subject: [PATCH 40/93] Examples for Spek article (#4106) * Examples for BAEL-1169 * Examples for Spek --- core-kotlin/pom.xml | 18 ++++++ .../kotlin/spek/CalculatorSubjectTest5.kt | 19 ++++++ .../baeldung/kotlin/spek/CalculatorTest5.kt | 32 ++++++++++ .../baeldung/kotlin/spek/DataDrivenTest5.kt | 21 +++++++ .../com/baeldung/kotlin/spek/GroupTest5.kt | 62 +++++++++++++++++++ 5 files changed, 152 insertions(+) create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorSubjectTest5.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorTest5.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/DataDrivenTest5.kt create mode 100644 core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/GroupTest5.kt diff --git a/core-kotlin/pom.xml b/core-kotlin/pom.xml index 00c3ac188d..24bfb302cf 100644 --- a/core-kotlin/pom.xml +++ b/core-kotlin/pom.xml @@ -63,6 +63,24 @@ kotlinx-coroutines-core ${kotlinx.version} + + org.jetbrains.spek + spek-api + 1.1.5 + test + + + org.jetbrains.spek + spek-subject-extension + 1.1.5 + test + + + org.jetbrains.spek + spek-junit-platform-engine + 1.1.5 + test + com.nhaarman mockito-kotlin diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorSubjectTest5.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorSubjectTest5.kt new file mode 100644 index 0000000000..f595d65bf2 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorSubjectTest5.kt @@ -0,0 +1,19 @@ +package com.baeldung.kotlin.spek + +import com.baeldung.kotlin.junit5.Calculator +import org.jetbrains.spek.api.dsl.describe +import org.jetbrains.spek.api.dsl.it +import org.jetbrains.spek.subject.SubjectSpek +import org.junit.jupiter.api.Assertions.assertEquals + +class CalculatorSubjectTest5 : SubjectSpek({ + subject { Calculator() } + describe("A calculator") { + describe("Addition") { + val result = subject.add(3, 5) + it("Produces the correct answer") { + assertEquals(8, result) + } + } + } +}) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorTest5.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorTest5.kt new file mode 100644 index 0000000000..3c49d916e4 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/CalculatorTest5.kt @@ -0,0 +1,32 @@ +package com.baeldung.kotlin.spek + +import com.baeldung.kotlin.junit5.Calculator +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.describe +import org.jetbrains.spek.api.dsl.given +import org.jetbrains.spek.api.dsl.it +import org.jetbrains.spek.api.dsl.on +import org.junit.jupiter.api.Assertions.assertEquals + +class CalculatorTest5 : Spek({ + given("A calculator") { + val calculator = Calculator() + on("Adding 3 and 5") { + val result = calculator.add(3, 5) + it("Produces 8") { + assertEquals(8, result) + } + } + } + + describe("A calculator") { + val calculator = Calculator() + describe("Addition") { + val result = calculator.add(3, 5) + it("Produces the correct answer") { + assertEquals(8, result) + } + } + } + +}) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/DataDrivenTest5.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/DataDrivenTest5.kt new file mode 100644 index 0000000000..bbcb36e8bb --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/DataDrivenTest5.kt @@ -0,0 +1,21 @@ +package com.baeldung.kotlin.spek + +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.describe +import org.jetbrains.spek.api.dsl.it +import org.junit.jupiter.api.Assertions + +class DataDrivenTest5 : Spek({ + describe("A data driven test") { + mapOf( + "hello" to "HELLO", + "world" to "WORLD" + ).forEach { input, expected -> + describe("Capitalising $input") { + it("Correctly returns $expected") { + Assertions.assertEquals(expected, input.toUpperCase()) + } + } + } + } +}) diff --git a/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/GroupTest5.kt b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/GroupTest5.kt new file mode 100644 index 0000000000..5aeee622e4 --- /dev/null +++ b/core-kotlin/src/test/kotlin/com/baeldung/kotlin/spek/GroupTest5.kt @@ -0,0 +1,62 @@ +package com.baeldung.kotlin.spek + +import org.jetbrains.spek.api.Spek +import org.jetbrains.spek.api.dsl.describe +import org.jetbrains.spek.api.dsl.it + +class GroupTest5 : Spek({ + describe("Outer group") { + beforeEachTest { + System.out.println("BeforeEachTest 0") + } + beforeGroup { + System.out.println("BeforeGroup 0") + } + afterEachTest { + System.out.println("AfterEachTest 0") + } + afterGroup { + System.out.println("AfterGroup 0") + } + describe("Inner group 1") { + beforeEachTest { + System.out.println("BeforeEachTest 1") + } + beforeGroup { + System.out.println("BeforeGroup 1") + } + afterEachTest { + System.out.println("AfterEachTest 1") + } + afterGroup { + System.out.println("AfterGroup 1") + } + it("Test 1") { + System.out.println("Test 1") + } + it("Test 2") { + System.out.println("Test 2") + } + } + describe("Inner group 2") { + beforeEachTest { + System.out.println("BeforeEachTest 2") + } + beforeGroup { + System.out.println("BeforeGroup 2") + } + afterEachTest { + System.out.println("AfterEachTest 2") + } + afterGroup { + System.out.println("AfterGroup 2") + } + it("Test 3") { + System.out.println("Test 3") + } + it("Test 4") { + System.out.println("Test 4") + } + } + } +}) From cfdf48ac9320f9589ad4d78914023073baeda615 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 12 May 2018 00:34:53 +0300 Subject: [PATCH 41/93] Update README.md --- core-java/README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core-java/README.md b/core-java/README.md index 8a94c9de8e..9f9ff61a48 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -74,17 +74,14 @@ - [CharSequence vs. String in Java](http://www.baeldung.com/java-char-sequence-string) - [Period and Duration in Java](http://www.baeldung.com/java-period-duration) - [Guide to the Diamond Operator in Java](http://www.baeldung.com/java-diamond-operator) -- [Singletons in Java](http://www.baeldung.com/java-singleton) - [“Sneaky Throws” in Java](http://www.baeldung.com/java-sneaky-throws) - [OutOfMemoryError: GC Overhead Limit Exceeded](http://www.baeldung.com/java-gc-overhead-limit-exceeded) - [StringBuilder and StringBuffer in Java](http://www.baeldung.com/java-string-builder-string-buffer) - [Number of Digits in an Integer in Java](http://www.baeldung.com/java-number-of-digits-in-int) -- [Proxy, Decorator, Adapter and Bridge Patterns](http://www.baeldung.com/java-structural-design-patterns) - [Creating a Java Compiler Plugin](http://www.baeldung.com/java-build-compiler-plugin) - [A Guide to the Static Keyword in Java](http://www.baeldung.com/java-static) - [Initializing Arrays in Java](http://www.baeldung.com/java-initialize-array) - [Guide to Java String Pool](http://www.baeldung.com/java-string-pool) -- [Introduction to Creational Design Patterns](http://www.baeldung.com/creational-design-patterns) - [Quick Example - Comparator vs Comparable in Java](http://www.baeldung.com/java-comparator-comparable) - [Quick Guide to Java Stack](http://www.baeldung.com/java-stack) - [The Java continue and break Keywords](http://www.baeldung.com/java-continue-and-break) @@ -116,8 +113,6 @@ - [Comparing Strings in Java](http://www.baeldung.com/java-compare-strings) - [Guide to Inheritance in Java](http://www.baeldung.com/java-inheritance) - [Guide to Externalizable Interface in Java](http://www.baeldung.com/java-externalizable) -- [The Observer Pattern in Java](http://www.baeldung.com/java-observer-pattern) -- [Flyweight Pattern in Java](http://www.baeldung.com/java-flyweight) - [Object Type Casting in Java](http://www.baeldung.com/java-type-casting) - [A Practical Guide to DecimalFormat](http://www.baeldung.com/java-decimalformat) - [How to Detect the OS Using Java](http://www.baeldung.com/java-detect-os) @@ -136,7 +131,6 @@ - [Class Loaders in Java](http://www.baeldung.com/java-classloaders) - [Find Sum and Average in a Java Array](http://www.baeldung.com/java-array-sum-average) - [Java List UnsupportedOperationException](http://www.baeldung.com/java-list-unsupported-operation-exception) -- [Service Locator Pattern](http://www.baeldung.com/java-service-locator-pattern) - [Type Erasure in Java Explained](http://www.baeldung.com/java-type-erasure) - [BigDecimal and BigInteger in Java](http://www.baeldung.com/java-bigdecimal-biginteger) - [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones) @@ -145,4 +139,3 @@ - [Sending Emails with Java](http://www.baeldung.com/java-email) - [Introduction to SSL in Java](http://www.baeldung.com/java-ssl) - [Java KeyStore API](http://www.baeldung.com/java-keystore) -- [Double-Checked Locking with Singleton](http://www.baeldung.com/java-singleton-double-checked-locking) From a61bdbcc59be3ab7686c910ebac8c95d333570a8 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 12 May 2018 00:39:53 +0300 Subject: [PATCH 42/93] Update README.md --- core-java/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java/README.md b/core-java/README.md index 9f9ff61a48..3cefb5820d 100644 --- a/core-java/README.md +++ b/core-java/README.md @@ -139,3 +139,4 @@ - [Sending Emails with Java](http://www.baeldung.com/java-email) - [Introduction to SSL in Java](http://www.baeldung.com/java-ssl) - [Java KeyStore API](http://www.baeldung.com/java-keystore) +- [Using Java Assertions](http://www.baeldung.com/java-assert) From 85f8404b402c2e463f3ed06ea801ea7a113eadff Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 12 May 2018 01:27:49 +0300 Subject: [PATCH 43/93] fix logger import --- .../java/com/baeldung/stringisnumeric/IsNumericDriver.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java b/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java index 3dc2b6632a..c0a6edae50 100644 --- a/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java +++ b/core-java/src/main/java/com/baeldung/stringisnumeric/IsNumericDriver.java @@ -1,12 +1,13 @@ package com.baeldung.stringisnumeric; -import static com.baeldung.designpatterns.util.LogerUtil.LOG; +import org.apache.log4j.Logger; public class IsNumericDriver { private static IsNumeric isNumeric; - + private static Logger LOG = Logger.getLogger(IsNumericDriver.class); static { isNumeric =new IsNumeric(); + } public static void main(String[] args) { From ca5a7d2e40b2af728256927de309d039a3937c99 Mon Sep 17 00:00:00 2001 From: christopherfranklin Date: Sat, 12 May 2018 00:23:24 -0400 Subject: [PATCH 44/93] [BAEL-1659] Create REST microservices with javalin (#4145) * [BAEL-1615] Code to support article. * Adding example of provides...with * Adding uses to main module * [BAEL-1659] Creat REST microservices with javalin * [BAEL-1659] Update article code based on feedback * Revert parent pom change * Using Optional instead of null --- libraries/pom.xml | 6 ++++ .../java/com/baeldung/javalin/JavalinApp.java | 16 +++++++++ .../java/com/baeldung/javalin/User/User.java | 11 +++++++ .../baeldung/javalin/User/UserController.java | 24 ++++++++++++++ .../com/baeldung/javalin/User/UserDao.java | 33 +++++++++++++++++++ 5 files changed, 90 insertions(+) create mode 100644 libraries/src/main/java/com/baeldung/javalin/JavalinApp.java create mode 100644 libraries/src/main/java/com/baeldung/javalin/User/User.java create mode 100644 libraries/src/main/java/com/baeldung/javalin/User/UserController.java create mode 100644 libraries/src/main/java/com/baeldung/javalin/User/UserDao.java diff --git a/libraries/pom.xml b/libraries/pom.xml index f4bf994a58..678ba3279c 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -680,6 +680,12 @@ ${unirest.version} + + + io.javalin + javalin + 1.6.0 + io.atlassian.fugue diff --git a/libraries/src/main/java/com/baeldung/javalin/JavalinApp.java b/libraries/src/main/java/com/baeldung/javalin/JavalinApp.java new file mode 100644 index 0000000000..33d2c7083f --- /dev/null +++ b/libraries/src/main/java/com/baeldung/javalin/JavalinApp.java @@ -0,0 +1,16 @@ +package com.baeldung.javalin; + +import com.baeldung.javalin.User.UserController; +import io.javalin.Javalin; + +public class JavalinApp { + public static void main(String[] args) { + Javalin app = Javalin.create() + .port(7000) + .start(); + + app.get("/hello", ctx -> ctx.html("Hello, Javalin!")); + app.get("/users", UserController.fetchAllUsernames); + app.get("/users/:id", UserController.fetchById); + } +} diff --git a/libraries/src/main/java/com/baeldung/javalin/User/User.java b/libraries/src/main/java/com/baeldung/javalin/User/User.java new file mode 100644 index 0000000000..09f710453b --- /dev/null +++ b/libraries/src/main/java/com/baeldung/javalin/User/User.java @@ -0,0 +1,11 @@ +package com.baeldung.javalin.User; + +public class User { + public final int id; + public final String name; + + public User(int id, String name) { + this.id = id; + this.name = name; + } +} diff --git a/libraries/src/main/java/com/baeldung/javalin/User/UserController.java b/libraries/src/main/java/com/baeldung/javalin/User/UserController.java new file mode 100644 index 0000000000..fd713606cf --- /dev/null +++ b/libraries/src/main/java/com/baeldung/javalin/User/UserController.java @@ -0,0 +1,24 @@ +package com.baeldung.javalin.User; + +import io.javalin.Handler; + +import java.util.Objects; + +public class UserController { + public static Handler fetchAllUsernames = ctx -> { + UserDao dao = UserDao.instance(); + Iterable allUsers = dao.getAllUsernames(); + ctx.json(allUsers); + }; + + public static Handler fetchById = ctx -> { + int id = Integer.parseInt(Objects.requireNonNull(ctx.param("id"))); + UserDao dao = UserDao.instance(); + User user = dao.getUserById(id); + if (user == null) { + ctx.html("Not Found"); + } else { + ctx.json(user); + } + }; +} diff --git a/libraries/src/main/java/com/baeldung/javalin/User/UserDao.java b/libraries/src/main/java/com/baeldung/javalin/User/UserDao.java new file mode 100644 index 0000000000..1cbf3012a8 --- /dev/null +++ b/libraries/src/main/java/com/baeldung/javalin/User/UserDao.java @@ -0,0 +1,33 @@ +package com.baeldung.javalin.User; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +class UserDao { + + private final List users = Arrays.asList( + new User(0, "Steve Rogers"), + new User(1, "Tony Stark"), + new User(2, "Carol Danvers") + ); + + private static UserDao userDao = null; + + private UserDao() { + } + + static UserDao instance() { + if (userDao == null) { + userDao = new UserDao(); + } + return userDao; + } + + Optional getUserById(int id) { return users.stream().filter(u -> u.id == id).findFirst(); } + + Iterable getAllUsernames() { + return users.stream().map(user -> user.name).collect(Collectors.toList()); + } +} From 35c5016dacd78653a5f1da1bb7feaa531c34d108 Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Sat, 12 May 2018 10:56:27 +0400 Subject: [PATCH 45/93] method hiding --- .../java/com/baeldung/scope/method/BaseMethodClass.java | 9 +++++++++ .../java/com/baeldung/scope/method/ChildMethodClass.java | 9 +++++++++ .../java/com/baeldung/scope/method/MethodHidingDemo.java | 6 ++---- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 core-java/src/main/java/com/baeldung/scope/method/BaseMethodClass.java create mode 100644 core-java/src/main/java/com/baeldung/scope/method/ChildMethodClass.java diff --git a/core-java/src/main/java/com/baeldung/scope/method/BaseMethodClass.java b/core-java/src/main/java/com/baeldung/scope/method/BaseMethodClass.java new file mode 100644 index 0000000000..46ed5fd99f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/scope/method/BaseMethodClass.java @@ -0,0 +1,9 @@ +package com.baeldung.scope.method; + + +public class BaseMethodClass { + + public static void printMessage() { + System.out.println("base static method"); + } +} diff --git a/core-java/src/main/java/com/baeldung/scope/method/ChildMethodClass.java b/core-java/src/main/java/com/baeldung/scope/method/ChildMethodClass.java new file mode 100644 index 0000000000..1d0cff2d6b --- /dev/null +++ b/core-java/src/main/java/com/baeldung/scope/method/ChildMethodClass.java @@ -0,0 +1,9 @@ +package com.baeldung.scope.method; + + +public class ChildMethodClass extends BaseMethodClass { + + public static void printMessage() { + System.out.println("child static method"); + } +} diff --git a/core-java/src/main/java/com/baeldung/scope/method/MethodHidingDemo.java b/core-java/src/main/java/com/baeldung/scope/method/MethodHidingDemo.java index 26f27a0bc2..7e0b3ed146 100644 --- a/core-java/src/main/java/com/baeldung/scope/method/MethodHidingDemo.java +++ b/core-java/src/main/java/com/baeldung/scope/method/MethodHidingDemo.java @@ -1,10 +1,8 @@ package com.baeldung.scope.method; -/** - * Created by Gebruiker on 5/6/2018. - */ public class MethodHidingDemo { - public static void main(String[] args) { + public static void main(String[] args) { + ChildMethodClass.printMessage(); } } From 4a81b13958e4d4b8048ef423f2793b6775076d91 Mon Sep 17 00:00:00 2001 From: Ekaterina Galkina Date: Sat, 12 May 2018 18:10:42 +0500 Subject: [PATCH 46/93] BAEL-1736 --- .../java/com/baeldung/hashtable/Word.java | 28 ++ .../baeldung/hashtable/HashtableUnitTest.java | 274 ++++++++++++++++++ 2 files changed, 302 insertions(+) create mode 100644 core-java-8/src/main/java/com/baeldung/hashtable/Word.java create mode 100644 core-java-8/src/test/java/com/baeldung/hashtable/HashtableUnitTest.java diff --git a/core-java-8/src/main/java/com/baeldung/hashtable/Word.java b/core-java-8/src/main/java/com/baeldung/hashtable/Word.java new file mode 100644 index 0000000000..eb7c5b7dca --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/hashtable/Word.java @@ -0,0 +1,28 @@ +package com.baeldung.hashtable; + +public class Word { + private String name; + + public Word(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof Word)) + return false; + + Word word = (Word) o; + return word.getName().equals(this.name) ? true : false; + + } + + public int hashCode() { + return name.hashCode(); + } +} diff --git a/core-java-8/src/test/java/com/baeldung/hashtable/HashtableUnitTest.java b/core-java-8/src/test/java/com/baeldung/hashtable/HashtableUnitTest.java new file mode 100644 index 0000000000..e8c42c94e1 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/hashtable/HashtableUnitTest.java @@ -0,0 +1,274 @@ +package com.baeldung.hashtable; + +import java.util.ConcurrentModificationException; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; + +import static org.junit.Assert.*; +import static org.hamcrest.Matchers.*; +import org.junit.Test; + +public class HashtableUnitTest { + + @Test + public void whenPutAndGet_thenReturnsValue() { + Hashtable table = new Hashtable(); + + Word word = new Word("cat"); + table.put(word, "an animal"); + + String definition = table.get(word); + + assertEquals("an animal", definition); + + definition = table.remove(word); + + assertEquals("an animal", definition); + } + + @Test + public void whenThesameInstanceOfKey_thenReturnsValue() { + Hashtable table = new Hashtable(); + Word word = new Word("cat"); + table.put(word, "an animal"); + String extracted = table.get(word); + assertEquals("an animal", extracted); + } + + @Test + public void whenEqualsOverridden_thenReturnsValue() { + Hashtable table = new Hashtable(); + Word word = new Word("cat"); + table.put(word, "an animal"); + String extracted = table.get(new Word("cat")); + assertEquals("an animal", extracted); + } + + @Test(expected = NullPointerException.class) + public void whenNullKey_thenException() { + Hashtable table = new Hashtable(); + table.put(null, "an animal"); + } + + @Test(expected = ConcurrentModificationException.class) + public void whenIterate_thenFailFast() { + + Hashtable table = new Hashtable(); + table.put(new Word("cat"), "an animal"); + table.put(new Word("dog"), "another animal"); + + Iterator it = table.keySet().iterator(); + System.out.println("iterator created"); + + table.remove(new Word("dog")); + System.out.println("element removed"); + + while (it.hasNext()) { + Word key = it.next(); + System.out.println(table.get(key)); + } + } + + @Test + public void whenEnumerate_thenNotFailFast() { + + Hashtable table = new Hashtable(); + table.put(new Word("1"), "one"); + table.put(new Word("2"), "two"); + table.put(new Word("3"), "three"); + table.put(new Word("4"), "four"); + table.put(new Word("5"), "five"); + table.put(new Word("6"), "six"); + table.put(new Word("7"), "seven"); + table.put(new Word("8"), "eight"); + + Enumeration enumKey = table.keys(); + System.out.println("Enumeration created"); + table.remove(new Word("1")); + System.out.println("element removed"); + while (enumKey.hasMoreElements()) { + Word key = enumKey.nextElement(); + System.out.println(table.get(key)); + } + } + + @Test + public void whenAddElements_thenIterationOrderUnpredicable() { + + Hashtable table = new Hashtable(); + table.put(new Word("1"), "one"); + table.put(new Word("2"), "two"); + table.put(new Word("3"), "three"); + table.put(new Word("4"), "four"); + table.put(new Word("5"), "five"); + table.put(new Word("6"), "six"); + table.put(new Word("7"), "seven"); + table.put(new Word("8"), "eight"); + + Iterator> it = table.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + System.out.println(entry.getValue()); + } + } + + @Test + public void whenGetOrDefault_thenDefaultGot() { + + Hashtable table = new Hashtable(); + table.put(new Word("cat"), "a small domesticated carnivorous mammal"); + Word key = new Word("dog"); + String definition; + + // old way + /* if (table.containsKey(key)) { + definition = table.get(key); + } else { + definition = "not found"; + }*/ + + // new way + definition = table.getOrDefault(key, "not found"); + + assertThat(definition, is("not found")); + } + + @Test + public void whenPutifAbsent_thenNotRewritten() { + + Hashtable table = new Hashtable(); + table.put(new Word("cat"), "a small domesticated carnivorous mammal"); + + String definition = "an animal"; + // old way + /* if (!table.containsKey(new Word("cat"))) { + table.put(new Word("cat"), definition); + }*/ + // new way + table.putIfAbsent(new Word("cat"), definition); + + assertThat(table.get(new Word("cat")), is("a small domesticated carnivorous mammal")); + } + + @Test + public void whenRemovePair_thenCheckKeyAndValue() { + + Hashtable table = new Hashtable(); + table.put(new Word("cat"), "a small domesticated carnivorous mammal"); + + // old way + /* if (table.get(new Word("cat")).equals("an animal")) { + table.remove(new Word("cat")); + }*/ + + // new way + boolean result = table.remove(new Word("cat"), "an animal"); + + assertThat(result, is(false)); + } + + @Test + public void whenReplacePair_thenValueChecked() { + + Hashtable table = new Hashtable(); + table.put(new Word("cat"), "a small domesticated carnivorous mammal"); + + String definition = "an animal"; + + // old way + /* if (table.containsKey(new Word("cat")) && table.get(new Word("cat")).equals("a small domesticated carnivorous mammal")) { + table.put(new Word("cat"), definition); + }*/ + // new way + table.replace(new Word("cat"), "a small domesticated carnivorous mammal", definition); + + assertThat(table.get(new Word("cat")), is("an animal")); + + } + + @Test + public void whenKeyIsAbsent_thenNotRewritten() { + + Hashtable table = new Hashtable(); + table.put(new Word("cat"), "a small domesticated carnivorous mammal"); + + // old way + /* if (!table.containsKey(cat)) { + String definition = "an animal";// calculate + table.put(new Word("cat"), definition); + } + */ + // new way + + table.computeIfAbsent(new Word("cat"), key -> "an animal"); + assertThat(table.get(new Word("cat")), is("a small domesticated carnivorous mammal")); + + } + + @Test + public void whenKeyIsPresent_thenComputeIfPresent() { + + Hashtable table = new Hashtable(); + table.put(new Word("cat"), "a small domesticated carnivorous mammal"); + + Word cat = new Word("cat"); + // old way + /* if (table.containsKey(cat)) { + String concatination = cat.getName() + " - " + table.get(cat); + table.put(cat, concatination); + }*/ + + // new way + table.computeIfPresent(cat, (key, value) -> key.getName() + " - " + value); + + assertThat(table.get(cat), is("cat - a small domesticated carnivorous mammal")); + + } + + @Test + public void whenCompute_thenForAllKeys() { + + Hashtable table = new Hashtable(); + String[] animals = { "cat", "dog", "dog", "cat", "bird", "mouse", "mouse" }; + for (String animal : animals) { + table.compute(animal, (key, value) -> (value == null ? Integer.valueOf(1) : Integer.valueOf(value) + 1)); + } + assertThat(table.values(), hasItems(2, 2, 2, 1)); + + } + + @Test + public void whenInsteadOfCompute_thenMerge() { + + Hashtable table = new Hashtable(); + String[] animals = { "cat", "dog", "dog", "cat", "bird", "mouse", "mouse" }; + for (String animal : animals) { + table.merge(animal, 1, (oldValue, value) -> (oldValue + value)); + } + assertThat(table.values(), hasItems(2, 2, 2, 1)); + } + + @Test + public void whenForeach_thenIterate() { + + Hashtable table = new Hashtable(); + table.put(new Word("cat"), "a small domesticated carnivorous mammal"); + table.put(new Word("dog"), "another animal"); + table.forEach((k, v) -> System.out.println(k.getName() + " - " + v) + + ); + } + + @Test + public void whenReplaceall_thenNoIterationNeeded() { + + Hashtable table = new Hashtable(); + table.put(new Word("cat"), "a small domesticated carnivorous mammal"); + table.put(new Word("dog"), "another animal"); + table.replaceAll((k, v) -> k.getName() + " - " + v); + + assertThat(table.values(), hasItems("cat - a small domesticated carnivorous mammal", "dog - another animal")); + } +} From 257bc7cc0f49bd96d22021097c44faa853c0a777 Mon Sep 17 00:00:00 2001 From: Shreyash Date: Sat, 12 May 2018 21:24:27 +0530 Subject: [PATCH 47/93] BAEL-998:- Java Vavr interoperability --- .../CollectionsInteroperabilityUnitTest.java | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java diff --git a/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java b/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java new file mode 100644 index 0000000000..776ef5c56d --- /dev/null +++ b/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.vavr.interoperability; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Test; + +import io.vavr.collection.HashMap; +import io.vavr.collection.LinkedHashSet; +import io.vavr.collection.List; +import io.vavr.collection.Map; +import io.vavr.collection.Stream; + +public class CollectionsInteroperabilityUnitTest { + + @Test + public void givenParams_whenVavrList_thenReturnJavaList() { + List vavrStringList = List.of("JAVA", "Javascript", "Scala"); + + java.util.List javaStringList = vavrStringList.toJavaList(); + assertTrue(javaStringList instanceof java.util.List); + } + + @Test + public void givenParams_whenVavrStream_thenReturnJavaStream() { + Stream vavrStream = Stream.of("JAVA", "Javascript", "Scala"); + + java.util.stream.Stream javaParallelStream = vavrStream.toJavaParallelStream(); + assertTrue(javaParallelStream instanceof java.util.stream.Stream); + + java.util.List javaStringList = vavrStream.toJavaList(); + assertTrue(javaStringList instanceof java.util.List); + } + + @Test + public void givenParams_whenVavrMap_thenReturnJavaMap() { + Map vavrMap = HashMap.of("1", "a", "2", "b", "3", "c"); + + java.util.Map javaMap = vavrMap.toJavaMap(); + assertTrue(javaMap instanceof java.util.Map); + } + + @Test + public void givenParams_whenJavaList_thenReturnVavrListUsingOfAll() { + java.util.List javaList = Arrays.asList("Java", "Haskell", "Scala"); + List vavrList = List.ofAll(javaList); + assertTrue(vavrList instanceof io.vavr.collection.List); + } + + @Test + public void givenParams_whenJavaStream_thenReturnVavrListUsingOfAll() { + java.util.stream.Stream javaStream = Arrays.asList("Java", "Haskell", "Scala") + .stream(); + Stream vavrStream = Stream.ofAll(javaStream); + assertTrue(vavrStream instanceof io.vavr.collection.Stream); + } + + @Test(expected = UnsupportedOperationException.class) + public void givenParams_whenVavrListConverted_thenException() { + java.util.List javaList = List.of("Java", "Haskell", "Scala") + .asJava(); + javaList.add("Python"); + assertEquals(4, javaList.size()); + } + + @Test + public void givenParams_whenVavrListConvertedToMutable_thenRetunMutableList() { + java.util.List javaList = List.of("Java", "Haskell", "Scala") + .asJavaMutable(); + javaList.add("Python"); + assertEquals(4, javaList.size()); + } + + @Test + public void givenParams_WhenVavarListConvertedToLinkedSet_thenReturnLinkedSet() { + List vavrList = List.of("Java", "Haskell", "Scala", "Java"); + LinkedHashSet linkedSet = (LinkedHashSet) vavrList.toLinkedSet(); + assertEquals(3, linkedSet.size()); + } + +} From 9aad5c0daf90b172e5b80496364eaf9aad73dfb7 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 12 May 2018 19:06:51 +0300 Subject: [PATCH 48/93] Update README.md From 7cb7928ebf710e45490699832b2e63ae897385fe Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 12 May 2018 19:36:06 +0300 Subject: [PATCH 49/93] remove security auto-config --- .../activitiwithspring/ActivitiWithSpringApplication.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java b/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java index 2cfacdcf0d..a9cd1301eb 100644 --- a/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java +++ b/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java @@ -2,8 +2,9 @@ package com.example.activitiwithspring; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration; -@SpringBootApplication +@SpringBootApplication(exclude = {SecurityAutoConfiguration.class}) public class ActivitiWithSpringApplication { public static void main(String[] args) { SpringApplication.run(ActivitiWithSpringApplication.class, args); From 80c3a36e1313c0ec52d22c261df7120f94196af9 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 12 May 2018 22:29:32 +0300 Subject: [PATCH 50/93] Update ActivitiWithSpringApplication.java --- .../activitiwithspring/ActivitiWithSpringApplication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java b/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java index a9cd1301eb..cf18e42cb6 100644 --- a/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java +++ b/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java @@ -10,3 +10,4 @@ public class ActivitiWithSpringApplication { SpringApplication.run(ActivitiWithSpringApplication.class, args); } } + From a29edce5f6f6de55f85b5ece65d62fa828c9025d Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 12 May 2018 22:49:49 +0300 Subject: [PATCH 51/93] Update README.md --- patterns/design-patterns/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/patterns/design-patterns/README.md b/patterns/design-patterns/README.md index cb44bf4bc4..dcfbbfd6cd 100644 --- a/patterns/design-patterns/README.md +++ b/patterns/design-patterns/README.md @@ -1,2 +1,10 @@ ### Relevant Articles: - [Facade Design Pattern in Java](http://www.baeldung.com/java-facade-pattern) +- [Singletons in Java](http://www.baeldung.com/java-singleton) +- [Proxy, Decorator, Adapter and Bridge Patterns](http://www.baeldung.com/java-structural-design-patterns) +- [Introduction to Creational Design Patterns](http://www.baeldung.com/creational-design-patterns) +- [The Observer Pattern in Java](http://www.baeldung.com/java-observer-pattern) +- [Flyweight Pattern in Java](http://www.baeldung.com/java-flyweight) +- [Service Locator Pattern](http://www.baeldung.com/java-service-locator-pattern) +- [Double-Checked Locking with Singleton](http://www.baeldung.com/java-singleton-double-checked-locking) +- [Composite Design Pattern in Java](http://www.baeldung.com/java-composite-pattern) From 3788f23a798fafcca96d960f0aea0200c1a117d0 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 12 May 2018 22:51:15 +0300 Subject: [PATCH 52/93] Update README.MD --- spring-boot/README.MD | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-boot/README.MD b/spring-boot/README.MD index 72da255b95..a1fadf787b 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -34,4 +34,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Spring Boot Customize Whitelabel Error Page](http://www.baeldung.com/spring-boot-custom-error-page) - [Spring Boot: Configuring a Main Class](http://www.baeldung.com/spring-boot-main-class) - [Shutdown a Spring Boot Application](http://www.baeldung.com/spring-boot-shutdown) -- [A Quick Intro to the SpringBootServletInitializer](http://www.baeldung.com/spring-boot-servlet-initializer) \ No newline at end of file +- [A Quick Intro to the SpringBootServletInitializer](http://www.baeldung.com/spring-boot-servlet-initializer) +- [How to Change the Default Port in Spring Boot](http://www.baeldung.com/spring-boot-change-port) From 506962bc96309ad49a6ad1f38dd5bb91f73e91e7 Mon Sep 17 00:00:00 2001 From: fanatixan Date: Sat, 12 May 2018 22:43:12 +0200 Subject: [PATCH 53/93] Spring annotations article (#4232) * Spring annotations * commented VehicleFactoryApplication to fix CI build --- .../java/com/baeldung/annotations/Bike.java | 20 ++++++ .../java/com/baeldung/annotations/Biker.java | 24 +++++++ .../java/com/baeldung/annotations/Car.java | 30 +++++++++ .../com/baeldung/annotations/CarMechanic.java | 10 +++ .../com/baeldung/annotations/CarUtility.java | 7 ++ .../java/com/baeldung/annotations/Driver.java | 32 +++++++++ .../java/com/baeldung/annotations/Engine.java | 26 ++++++++ .../com/baeldung/annotations/Vehicle.java | 4 ++ .../annotations/VehicleController.java | 66 +++++++++++++++++++ .../VehicleFactoryApplication.java | 13 ++++ .../annotations/VehicleFactoryConfig.java | 30 +++++++++ .../annotations/VehicleRepository.java | 8 +++ .../annotations/VehicleRestController.java | 8 +++ .../baeldung/annotations/VehicleService.java | 13 ++++ .../src/main/resources/annotations.properties | 1 + .../src/main/resources/annotations.xml | 9 +++ 16 files changed, 301 insertions(+) create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/Bike.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/Biker.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/Car.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/CarMechanic.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/CarUtility.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/Driver.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/Engine.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/Vehicle.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleController.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryApplication.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryConfig.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRepository.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRestController.java create mode 100644 spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleService.java create mode 100644 spring-mvc-java/src/main/resources/annotations.properties create mode 100644 spring-mvc-java/src/main/resources/annotations.xml diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Bike.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/Bike.java new file mode 100644 index 0000000000..2a893e7903 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/Bike.java @@ -0,0 +1,20 @@ +package com.baeldung.annotations; + +import org.springframework.beans.factory.annotation.Required; +import org.springframework.context.annotation.DependsOn; + +@DependsOn +public class Bike implements Vehicle { + + private String color; + + @Required + public void setColor(String color) { + this.color = color; + } + + public String getColor() { + return color; + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Biker.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/Biker.java new file mode 100644 index 0000000000..dcbe534a90 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/Biker.java @@ -0,0 +1,24 @@ +package com.baeldung.annotations; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +@Component +public class Biker { + + @Autowired + @Qualifier("bike") + private Vehicle vehicle; + + @Autowired + public Biker(@Qualifier("bike") Vehicle vehicle) { + this.vehicle = vehicle; + } + + @Autowired + public void setVehicle(@Qualifier("bike") Vehicle vehicle) { + this.vehicle = vehicle; + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Car.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/Car.java new file mode 100644 index 0000000000..cb252b60c9 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/Car.java @@ -0,0 +1,30 @@ +package com.baeldung.annotations; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +@Component +@Primary +@DependsOn("engine") +public class Car implements Vehicle { + + @Autowired + private Engine engine; + + @Autowired + public Car(Engine engine) { + this.engine = engine; + } + + @Autowired + public void setEngine(Engine engine) { + this.engine = engine; + } + + public Engine getEngine() { + return engine; + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/CarMechanic.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/CarMechanic.java new file mode 100644 index 0000000000..fc933dcd61 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/CarMechanic.java @@ -0,0 +1,10 @@ +package com.baeldung.annotations; + +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +@Component +@Lazy +public class CarMechanic { + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/CarUtility.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/CarUtility.java new file mode 100644 index 0000000000..e66ab02b01 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/CarUtility.java @@ -0,0 +1,7 @@ +package com.baeldung.annotations; + +import org.springframework.stereotype.Component; + +@Component +public class CarUtility { +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Driver.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/Driver.java new file mode 100644 index 0000000000..5a2d86e99e --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/Driver.java @@ -0,0 +1,32 @@ +package com.baeldung.annotations; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Component +public class Driver { + + @Autowired + private Vehicle vehicle; + + @Autowired + public Driver(Vehicle vehicle) { + this.vehicle = vehicle; + } + + @Autowired + public void setVehicle(Vehicle vehicle) { + this.vehicle = vehicle; + } + + public Vehicle getVehicle() { + return vehicle; + } + + @Scheduled(fixedRate = 10000) + @Scheduled(cron = "0 * * * * MON-FRI") + public void checkVehicle() { + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Engine.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/Engine.java new file mode 100644 index 0000000000..f8c0154639 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/Engine.java @@ -0,0 +1,26 @@ +package com.baeldung.annotations; + +import org.springframework.beans.factory.annotation.Value; + +public class Engine { + + @Value("8") + private int cylinderCount; + + @Value("${engine.fuelType}") + private String fuelType; + + public Engine() { + this(8); + } + + public Engine(@Value("8") int cylinderCount) { + this.cylinderCount = cylinderCount; + } + + @Value("8") + public void setCylinderCount(int cylinderCount) { + this.cylinderCount = cylinderCount; + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/Vehicle.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/Vehicle.java new file mode 100644 index 0000000000..7176c3cc8a --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/Vehicle.java @@ -0,0 +1,4 @@ +package com.baeldung.annotations; + +public interface Vehicle { +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleController.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleController.java new file mode 100644 index 0000000000..a979dff708 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleController.java @@ -0,0 +1,66 @@ +package com.baeldung.annotations; + +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +@Controller +@RequestMapping(value = "/vehicles", method = RequestMethod.GET) +public class VehicleController { + + @CrossOrigin + @ResponseBody + @RequestMapping("/hello") + public String hello() { + return "Hello World!"; + } + + @RequestMapping("/home") + public String home() { + return "home"; + } + + @PostMapping("/save") + public void saveVehicle(@RequestBody Vehicle vehicle) { + } + + @RequestMapping("/{id}") + public Vehicle getVehicle(@PathVariable("id") long id) { + return null; + } + + @RequestMapping + public Vehicle getVehicleByParam(@RequestParam("id") long id) { + return null; + } + + @RequestMapping("/buy") + public Car buyCar(@RequestParam(defaultValue = "5") int seatCount) { + return null; + } + + @ExceptionHandler(IllegalArgumentException.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public void onIllegalArgumentException(IllegalArgumentException exception) { + } + + @PostMapping("/assemble") + public void assembleVehicle(@ModelAttribute("vehicle") Vehicle vehicle) { + } + + @ModelAttribute("vehicle") + public Vehicle getVehicle() { + return null; + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryApplication.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryApplication.java new file mode 100644 index 0000000000..ab90d8cef2 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.annotations; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +// @SpringBootApplication +public class VehicleFactoryApplication { + +// public static void main(String[] args) { +// SpringApplication.run(VehicleFactoryApplication.class, args); +// } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryConfig.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryConfig.java new file mode 100644 index 0000000000..ad43a19b66 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleFactoryConfig.java @@ -0,0 +1,30 @@ +package com.baeldung.annotations; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.context.annotation.Lazy; +import org.springframework.context.annotation.PropertySource; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@Configuration +@ComponentScan(basePackages = "com.baeldung.annotations") +@ComponentScan(basePackageClasses = VehicleFactoryConfig.class) +@ImportResource("classpath:/annotations.xml") +@PropertySource("classpath:/annotations.properties") +@Lazy +@EnableAutoConfiguration +@EnableAsync +@EnableScheduling +public class VehicleFactoryConfig { + + @Bean + @Lazy(false) + public Engine engine() { + return new Engine(); + } + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRepository.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRepository.java new file mode 100644 index 0000000000..4dfd2dd771 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRepository.java @@ -0,0 +1,8 @@ +package com.baeldung.annotations; + +import org.springframework.stereotype.Repository; + +@Repository +public class VehicleRepository { + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRestController.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRestController.java new file mode 100644 index 0000000000..9dd98e688f --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleRestController.java @@ -0,0 +1,8 @@ +package com.baeldung.annotations; + +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class VehicleRestController { + +} diff --git a/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleService.java b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleService.java new file mode 100644 index 0000000000..19e5a3b4a4 --- /dev/null +++ b/spring-mvc-java/src/main/java/com/baeldung/annotations/VehicleService.java @@ -0,0 +1,13 @@ +package com.baeldung.annotations; + +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +@Service +public class VehicleService { + + @Async + public void repairCar() { + } + +} diff --git a/spring-mvc-java/src/main/resources/annotations.properties b/spring-mvc-java/src/main/resources/annotations.properties new file mode 100644 index 0000000000..ac2f50b39b --- /dev/null +++ b/spring-mvc-java/src/main/resources/annotations.properties @@ -0,0 +1 @@ +engine.fuelType=petrol \ No newline at end of file diff --git a/spring-mvc-java/src/main/resources/annotations.xml b/spring-mvc-java/src/main/resources/annotations.xml new file mode 100644 index 0000000000..b477b68ef6 --- /dev/null +++ b/spring-mvc-java/src/main/resources/annotations.xml @@ -0,0 +1,9 @@ + + + + + + + + From eceb73823bbd7bf3b3b326c5308cf308fd3ce3c0 Mon Sep 17 00:00:00 2001 From: Thoughtscript Date: Sun, 13 May 2018 03:48:53 +0100 Subject: [PATCH 54/93] BAEL-1740 --- javax-servlets/pom.xml | 109 +++++++++++------- .../java/com/baeldung/servlets/Constants.java | 12 ++ .../com/baeldung/servlets/FormServlet.java | 4 +- .../com/baeldung/servlets/UploadServlet.java | 61 ++++++++++ .../src/main/webapp/WEB-INF/web.xml | 14 ++- javax-servlets/src/main/webapp/result.jsp | 13 +++ javax-servlets/src/main/webapp/upload.jsp | 15 +++ 7 files changed, 183 insertions(+), 45 deletions(-) create mode 100644 javax-servlets/src/main/java/com/baeldung/servlets/Constants.java create mode 100644 javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java create mode 100644 javax-servlets/src/main/webapp/result.jsp create mode 100644 javax-servlets/src/main/webapp/upload.jsp diff --git a/javax-servlets/pom.xml b/javax-servlets/pom.xml index 69d952da9c..41a3bb69be 100644 --- a/javax-servlets/pom.xml +++ b/javax-servlets/pom.xml @@ -1,46 +1,75 @@ - - 4.0.0 - javax-servlets - 1.0-SNAPSHOT + + 4.0.0 + javax-servlets + 1.0-SNAPSHOT - - com.baeldung - parent-modules - 1.0.0-SNAPSHOT - + + com.baeldung + parent-modules + 1.0.0-SNAPSHOT + - - - javax.servlet - javax.servlet-api - ${javax.servlet.version} - - - org.apache.httpcomponents - httpclient - ${org.apache.httpcomponents.version} - test - - - commons-logging - commons-logging - - - - - org.springframework - spring-test - ${spring-test.version} - test - - + + + + commons-fileupload + commons-fileupload + 1.3.3 + + + commons-io + commons-io + 2.6 + - - 3.1.0 - 4.5.3 - 5.0.5.RELEASE - + + + javax.servlet + javax.servlet-api + 4.0.1 + + + javax.servlet.jsp.jstl + jstl-api + 1.2 + + + javax.servlet.jsp + javax.servlet.jsp-api + 2.3.1 + + + javax.servlet + jstl + 1.2 + + + + org.apache.httpcomponents + httpclient + ${org.apache.httpcomponents.version} + test + + + commons-logging + commons-logging + + + + + org.springframework + spring-test + ${spring-test.version} + test + + + + + 4.5.3 + 5.0.5.RELEASE + \ No newline at end of file diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/Constants.java b/javax-servlets/src/main/java/com/baeldung/servlets/Constants.java new file mode 100644 index 0000000000..3195e95088 --- /dev/null +++ b/javax-servlets/src/main/java/com/baeldung/servlets/Constants.java @@ -0,0 +1,12 @@ +package com.baeldung.servlets; + +public class Constants { + + public static final String UPLOAD_DIRECTORY = "upload"; + public static final String ENDPOINT = "/jspupload/uploadFile"; + + public static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; + public static final int MAX_FILE_SIZE = 1024 * 1024 * 40; + public static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; + +} diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java index c78129a9cf..79004f9d94 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java @@ -24,10 +24,10 @@ public class FormServlet extends HttpServlet { response.setHeader("Test", "Success"); response.setHeader("BMI", String.valueOf(bmi)); - RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/index.jsp"); + RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/upload.jsp"); dispatcher.forward(request, response); } catch (Exception e) { - response.sendRedirect("index.jsp"); + response.sendRedirect("upload.jsp"); } } diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java new file mode 100644 index 0000000000..c809a9e818 --- /dev/null +++ b/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java @@ -0,0 +1,61 @@ +package com.baeldung.servlets; + +import static com.baeldung.servlets.Constants.MAX_FILE_SIZE; +import static com.baeldung.servlets.Constants.MAX_REQUEST_SIZE; +import static com.baeldung.servlets.Constants.MEMORY_THRESHOLD; +import static com.baeldung.servlets.Constants.UPLOAD_DIRECTORY; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; + +public class UploadServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + if (ServletFileUpload.isMultipartContent(request)) { + + DiskFileItemFactory factory = new DiskFileItemFactory(); + factory.setSizeThreshold(MEMORY_THRESHOLD); + factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); + + ServletFileUpload upload = new ServletFileUpload(factory); + upload.setFileSizeMax(MAX_FILE_SIZE); + upload.setSizeMax(MAX_REQUEST_SIZE); + String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; + File uploadDir = new File(uploadPath); + if (!uploadDir.exists()) { + uploadDir.mkdir(); + } + + try { + List formItems = upload.parseRequest(request); + + if (formItems != null && formItems.size() > 0) { + for (FileItem item : formItems) { + if (!item.isFormField()) { + String fileName = new File(item.getName()).getName(); + String filePath = uploadPath + File.separator + fileName; + File storeFile = new File(filePath); + item.write(storeFile); + request.setAttribute("message", "File " + fileName + " has uploaded successfully!"); + } + } + } + } catch (Exception ex) { + request.setAttribute("message","There was an error: " + ex.getMessage()); + } + getServletContext().getRequestDispatcher("/result.jsp").forward(request, response); + } + } +} \ No newline at end of file diff --git a/javax-servlets/src/main/webapp/WEB-INF/web.xml b/javax-servlets/src/main/webapp/WEB-INF/web.xml index 66934d8fd3..6f1220fa12 100644 --- a/javax-servlets/src/main/webapp/WEB-INF/web.xml +++ b/javax-servlets/src/main/webapp/WEB-INF/web.xml @@ -1,7 +1,15 @@ + 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/web-app_3_1.xsd" + version="3.1"> + + UploadServlet + com.baeldung.servlets.UploadServlet + + + UploadServlet + /uploadFile + \ No newline at end of file diff --git a/javax-servlets/src/main/webapp/result.jsp b/javax-servlets/src/main/webapp/result.jsp new file mode 100644 index 0000000000..2e985cb322 --- /dev/null +++ b/javax-servlets/src/main/webapp/result.jsp @@ -0,0 +1,13 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + + + + + + Upload Result + + + +

${message}

+ + \ No newline at end of file diff --git a/javax-servlets/src/main/webapp/upload.jsp b/javax-servlets/src/main/webapp/upload.jsp new file mode 100644 index 0000000000..8a0fcfc220 --- /dev/null +++ b/javax-servlets/src/main/webapp/upload.jsp @@ -0,0 +1,15 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + + + + + + File Upload Demo + + + +
+ Choose a file: +
+ + \ No newline at end of file From 3f50caa710dad3513cc710ed3a7d6334953812ab Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sun, 13 May 2018 08:58:05 +0300 Subject: [PATCH 55/93] Update README.md --- patterns/design-patterns/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/patterns/design-patterns/README.md b/patterns/design-patterns/README.md index dcfbbfd6cd..fb80f4bd6a 100644 --- a/patterns/design-patterns/README.md +++ b/patterns/design-patterns/README.md @@ -8,3 +8,4 @@ - [Service Locator Pattern](http://www.baeldung.com/java-service-locator-pattern) - [Double-Checked Locking with Singleton](http://www.baeldung.com/java-singleton-double-checked-locking) - [Composite Design Pattern in Java](http://www.baeldung.com/java-composite-pattern) + From 3c28681b6db356eebe3b2661c719fb7921c87606 Mon Sep 17 00:00:00 2001 From: Tino Mulanchira Thomas <38363530+tinomthomas@users.noreply.github.com> Date: Sun, 13 May 2018 11:31:30 +0300 Subject: [PATCH 56/93] BAEL-1756 (#4230) * code samples for spring data key value BAEL-1467 * changes to add spring-data-keyvalue to parent pom. * Update README.md * Update README.md * Update README.md * How to Use Spring RestTemplate Interceptor * Spring annotations article (#4232) * Spring annotations * commented VehicleFactoryApplication to fix CI build * BAEL-1756 Test typo fixed --- .../java/com/baeldung/transfer/LoginForm.java | 6 +++ .../org/baeldung/config/RestClientConfig.java | 30 +++++++++++++ .../RestTemplateLoggingInterceptor.java | 41 ++++++++++++++++++ .../RestTemplateIntegrationTest.java | 43 +++++++++++++++++++ 4 files changed, 120 insertions(+) create mode 100644 spring-rest/src/main/java/org/baeldung/config/RestClientConfig.java create mode 100644 spring-rest/src/main/java/org/baeldung/interceptors/RestTemplateLoggingInterceptor.java create mode 100644 spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java diff --git a/spring-rest/src/main/java/com/baeldung/transfer/LoginForm.java b/spring-rest/src/main/java/com/baeldung/transfer/LoginForm.java index 19c9b0a349..caafcdb500 100644 --- a/spring-rest/src/main/java/com/baeldung/transfer/LoginForm.java +++ b/spring-rest/src/main/java/com/baeldung/transfer/LoginForm.java @@ -7,6 +7,12 @@ public class LoginForm { public LoginForm() { } + public LoginForm(String username, String password) { + super(); + this.username = username; + this.password = password; + } + public String getUsername() { return username; } diff --git a/spring-rest/src/main/java/org/baeldung/config/RestClientConfig.java b/spring-rest/src/main/java/org/baeldung/config/RestClientConfig.java new file mode 100644 index 0000000000..3619f43f8a --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/config/RestClientConfig.java @@ -0,0 +1,30 @@ +package org.baeldung.config; + +import java.util.ArrayList; +import java.util.List; + +import org.baeldung.interceptors.RestTemplateLoggingInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.util.CollectionUtils; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestClientConfig { + + @Bean + public RestTemplate restTemplate() { + RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory())); + + List interceptors = restTemplate.getInterceptors(); + if (CollectionUtils.isEmpty(interceptors)) { + interceptors = new ArrayList(); + } + interceptors.add(new RestTemplateLoggingInterceptor()); + restTemplate.setInterceptors(interceptors); + return restTemplate; + } +} diff --git a/spring-rest/src/main/java/org/baeldung/interceptors/RestTemplateLoggingInterceptor.java b/spring-rest/src/main/java/org/baeldung/interceptors/RestTemplateLoggingInterceptor.java new file mode 100644 index 0000000000..56de3d04b8 --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/interceptors/RestTemplateLoggingInterceptor.java @@ -0,0 +1,41 @@ +package org.baeldung.interceptors; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.util.StreamUtils; + +public class RestTemplateLoggingInterceptor implements ClientHttpRequestInterceptor { + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { + logRequest(body); + ClientHttpResponse response = execution.execute(request, body); + logResponse(response); + response.getHeaders().add("Foo", "bar"); + return response; + } + + private void logRequest(byte[] body) { + String payLoad = StringUtils.EMPTY; + if (body.length > 0) { + payLoad = new String(body, StandardCharsets.UTF_8); + } + System.out.println("Request Body > " + payLoad); + } + + private void logResponse(ClientHttpResponse response) throws IOException { + String payLoad = StringUtils.EMPTY; + long contentLength = response.getHeaders() + .getContentLength(); + if (contentLength != 0) { + payLoad = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8); + } + System.out.println("Response Body > " + payLoad); + } +} diff --git a/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java b/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java new file mode 100644 index 0000000000..e0c24c32b1 --- /dev/null +++ b/spring-rest/src/test/java/org/baeldung/resttemplate/RestTemplateIntegrationTest.java @@ -0,0 +1,43 @@ +package org.baeldung.resttemplate; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.baeldung.config.RestClientConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.client.RestTemplate; + +import com.baeldung.transfer.LoginForm; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = RestClientConfig.class) +public class RestTemplateIntegrationTest { + + @Autowired + RestTemplate restTemplate; + + @Test + public void givenRestTemplate_whenRequested_thenLogAndModifyResponse() { + LoginForm loginForm = new LoginForm("userName", "password"); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity requestEntity = new HttpEntity(loginForm, headers); + + ResponseEntity responseEntity = restTemplate.postForEntity("http://httpbin.org/post", requestEntity, String.class); + + assertThat(responseEntity.getStatusCode(), is(equalTo(HttpStatus.OK))); + assertThat(responseEntity.getHeaders() + .get("Foo") + .get(0), is(equalTo("bar"))); + } +} From 73db2e159fc4063c6378bce57c11cd5b2b1c0685 Mon Sep 17 00:00:00 2001 From: Shreyash Date: Sun, 13 May 2018 16:47:08 +0530 Subject: [PATCH 57/93] BAEL-998 --- .../CollectionsInteroperabilityUnitTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java b/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java index 776ef5c56d..8256c2369a 100644 --- a/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java +++ b/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.Arrays; +import java.util.Optional; import org.junit.Test; @@ -80,4 +81,11 @@ public class CollectionsInteroperabilityUnitTest { assertEquals(3, linkedSet.size()); } + @Test + public void givenParams_WhenVavrList_thenReturnJavaOptional() { + List vavrList = List.of("Java"); + Optional optional = vavrList.toJavaOptional(); + assertEquals("Java", optional.get()); + } + } From 2e119f774fecc70f809bd752987c20a50513779c Mon Sep 17 00:00:00 2001 From: Rajat Garg Date: Sun, 13 May 2018 21:35:58 +0530 Subject: [PATCH 58/93] Add hazelcast dependency --- libraries-data/pom.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries-data/pom.xml b/libraries-data/pom.xml index c9d240beb4..f1531a8eae 100644 --- a/libraries-data/pom.xml +++ b/libraries-data/pom.xml @@ -136,6 +136,11 @@ cache-api ${cache.version}
+ + com.hazelcast + hazelcast + ${hazelcast.version} + @@ -268,9 +273,10 @@ 1.0.0 2.4.0 2.8.2 - 1.0.0 + 1.1.0 + 3.8.4 1.8 3.0.0 -
\ No newline at end of file + From c319fbafca70cbe595144b99ded9d69927ca1f66 Mon Sep 17 00:00:00 2001 From: Rajat Garg Date: Sun, 13 May 2018 21:38:16 +0530 Subject: [PATCH 59/93] add fully qualified class name Add fully qualified class name because of multiple cache providers like iginte and hazelcast --- .../src/test/java/com/baeldung/jcache/CacheLoaderTest.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries-data/src/test/java/com/baeldung/jcache/CacheLoaderTest.java b/libraries-data/src/test/java/com/baeldung/jcache/CacheLoaderTest.java index a4747785cd..93ff3f09a3 100644 --- a/libraries-data/src/test/java/com/baeldung/jcache/CacheLoaderTest.java +++ b/libraries-data/src/test/java/com/baeldung/jcache/CacheLoaderTest.java @@ -21,7 +21,8 @@ public class CacheLoaderTest { @Before public void setup() { - CachingProvider cachingProvider = Caching.getCachingProvider(); + // Adding fully qualified class name because of multiple Cache Provider (Ignite and Hazelcast) + CachingProvider cachingProvider = Caching.getCachingProvider("com.hazelcast.cache.HazelcastCachingProvider"); CacheManager cacheManager = cachingProvider.getCacheManager(); MutableConfiguration config = new MutableConfiguration().setReadThrough(true).setCacheLoaderFactory(new FactoryBuilder.SingletonFactory<>(new SimpleCacheLoader())); this.cache = cacheManager.createCache("SimpleCache", config); @@ -29,7 +30,7 @@ public class CacheLoaderTest { @After public void tearDown() { - Caching.getCachingProvider().getCacheManager().destroyCache(CACHE_NAME); + Caching.getCachingProvider("com.hazelcast.cache.HazelcastCachingProvider").getCacheManager().destroyCache(CACHE_NAME); } @Test @@ -39,4 +40,4 @@ public class CacheLoaderTest { assertEquals("fromCache" + i, value); } } -} \ No newline at end of file +} From e6390c8d8d9913facc9096e71768488dd1250b43 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sun, 13 May 2018 19:24:29 +0300 Subject: [PATCH 60/93] Update ActivitiWithSpringApplication.java --- .../activitiwithspring/ActivitiWithSpringApplication.java | 1 - 1 file changed, 1 deletion(-) diff --git a/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java b/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java index cf18e42cb6..a9cd1301eb 100644 --- a/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java +++ b/spring-activiti/src/main/java/com/example/activitiwithspring/ActivitiWithSpringApplication.java @@ -10,4 +10,3 @@ public class ActivitiWithSpringApplication { SpringApplication.run(ActivitiWithSpringApplication.class, args); } } - From 8be0f4e1af47a3ca5968444dc8ba693dec9bfe07 Mon Sep 17 00:00:00 2001 From: Dhrubajyoti Bhattacharjee Date: Sun, 13 May 2018 23:19:47 +0530 Subject: [PATCH 61/93] BAEL-1627 Define a favicon in spring boot (#3957) * BAEL-1627 Define a favicon in spring boot * Restrict favicon requests to GET only * Update FaviconConfiguration.java --- .../baeldung/config/FaviconConfiguration.java | 44 ++++++++++++++++++ .../src/main/resources/application.properties | 3 +- .../baeldung/produceimage/images/favicon.ico | Bin 0 -> 15086 bytes .../src/main/resources/static/favicon.ico | Bin 0 -> 15086 bytes 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 spring-rest/src/main/java/org/baeldung/config/FaviconConfiguration.java create mode 100644 spring-rest/src/main/resources/com/baeldung/produceimage/images/favicon.ico create mode 100644 spring-rest/src/main/resources/static/favicon.ico diff --git a/spring-rest/src/main/java/org/baeldung/config/FaviconConfiguration.java b/spring-rest/src/main/java/org/baeldung/config/FaviconConfiguration.java new file mode 100644 index 0000000000..78a2a3eb2c --- /dev/null +++ b/spring-rest/src/main/java/org/baeldung/config/FaviconConfiguration.java @@ -0,0 +1,44 @@ +package org.baeldung.config; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; +import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; + +@Configuration +public class FaviconConfiguration { + @Bean + public SimpleUrlHandlerMapping myFaviconHandlerMapping() { + SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); + mapping.setOrder(Integer.MIN_VALUE); + mapping.setUrlMap(Collections.singletonMap("/favicon.ico", faviconRequestHandler())); + return mapping; + } + + @Bean + protected ResourceHttpRequestHandler faviconRequestHandler() { + ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler(); + ClassPathResource classPathResource = new ClassPathResource("com/baeldung/produceimage/images"); + List locations = Arrays.asList(classPathResource); + requestHandler.setLocations(locations); + return requestHandler; + } + + //@Controller + static class FaviconController { + + @RequestMapping(value="favicon.ico", method=RequestMethod.GET) + @ResponseBody + void favicon() {} + } +} diff --git a/spring-rest/src/main/resources/application.properties b/spring-rest/src/main/resources/application.properties index dd7e4e2f2d..5ea345c395 100644 --- a/spring-rest/src/main/resources/application.properties +++ b/spring-rest/src/main/resources/application.properties @@ -1,2 +1,3 @@ server.port= 8082 -server.servlet.context-path=/spring-rest \ No newline at end of file +server.servlet.context-path=/spring-rest +spring.mvc.favicon.enabled=false \ No newline at end of file diff --git a/spring-rest/src/main/resources/com/baeldung/produceimage/images/favicon.ico b/spring-rest/src/main/resources/com/baeldung/produceimage/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..64105ac11c6186e380a724416ceb77ab5c263fef GIT binary patch literal 15086 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 literal 0 HcmV?d00001 diff --git a/spring-rest/src/main/resources/static/favicon.ico b/spring-rest/src/main/resources/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..64105ac11c6186e380a724416ceb77ab5c263fef GIT binary patch literal 15086 zcmeI33yf6N8OP5s)D;AFL7}u+*#$K|S}oXWX{A6BF!-qLwvyDOsBLZ4#$rp2QmZaB zDMc+H+EzuWwblBlHY$b~O&EM6N;Jr;Vo@0)La}NWK^bJ(>Fs!o&?#+$PV&lcoe<}Q{V*nJA~=Gv^RNwrqwUlyiXv{0{QS2SOqSBm|V^K zQLxvS?=`|#!l^JBRzeqq>8p;)yEgECA92~92j{^Ocmu-PBuDxspmqtCp>qEVFM;g6 z3&A`)Nb3(OYfs4gVE$lypKZf~(VYR$L6|Q=Js00EefOZN@uR+-2@ByKP=BkBcZ1V& za;MV`ljQFM^6k?gyLZAaaQZKV=~YTY?;z0l>;SdzoJx5srK6LD`LGc*O%p%p9R+QP z6|Dlgn&*8KEf$U0H~|`r8OzLXW>yUXO|EuJ9@z;+0>uLCE$K;D6=;Qtp!LanwD8pF zL%lx*!{PIA@PT%dGLMJnL2J+?m5&?%=R+Heh0&mOOj7IG$)NNv!-;S-s1E&-`j3w4 ze*;$_%n#DP4jaI&`|AJo@DvQQK3qds^Eye{{=D+zeqa~w{*b0M zR(W3qW}MgW;|R}%kv6VAT?u}hX~JrYFZewm{*2G=D}>$H)B1k}oNImf8sV*wrd+?y z)7Ti{d?5T*z~&a>=YZD3X`uXPTOYnp*uPHu?IsD|j2-XPgVeqn)YVx26$}E6htuI$ z=m)c54+M3R#I@(TzV57GOMWc_&GAFvV)zbdzFY;nAxW9RytksSIj1=teCLnv;Qe)= zb~qBILNjQ;t7bg>3;iR&KmPpX2E$qd7QkdsUwjrOfz}JnuVDV3;_5@4Pt~85`XJ1P z#>Nw%K9~Y(mmfe5lJ?1BbkwHnA*`&ZG_6NkC)dDVKz($ljemfQ(sl1v*mvbDZk2$~y7?4-@x zRW95YplprFUxW6=G;=GiKOg#v?G~im3}}vj6Lbc79A1XE;C)CkXDj*hPPalMB9y1k z3)+Wu9+?PQi?t@tf!jfA!mAK>?#ZVO5kX$cp1^G4tk~}hZLk@FK5QjzOk$%c6ewpJYzz2sH}Qi~m`kNXS(kuY zm$grwk;+g?CCbwo<{?l&`~&)@G?iM7GS39v#f(dBqzXmK)%tNZB)&_lqS&%3^N>f>U?kt99_50 zhB$`5I&0nnn?UCU-Dj5f0>T4eGH4GS47y*`p6bnANsH35pnXpFH$q{h_3Avw{!hT| zCpweq>j&>4EIgEVC&504U$@;BuG_UxHy!leH5& z{a^{WbHN||wh5mKJALn6zBE#29i4;Lf!bgOe8#m`T#3#QIMn4QJOZ8t`Sc$c?|Y~7 zpxQT$zdh;f!|qy`1;bsLJxTKZ4AkZWTwcPbz!p%MkH8?`yNSemx}WID*QodUytxYW z8N<8pbY%x6?;BwS=uABq{PXp@#MQs*=UGmdu;$`oi1MKp?=((-0~K%BdG}S&7*Top z{G`5fcVJpCE`{e|K9uiD36Fv`Pzyh!Y^d$DE_ipYt___eUF(4Ve&9XgKLu9@tvLfh zYp2dx{yMY~?|`WCYw=EFLv{FAKal3mzW#DlhhG5SvXmaer-RyC>)&9dBGo?{b7~{M zes6@;#u`gryIQy8gFbtQm8bn{9(eN>sde>g*abI%H`kHc^X`Q(8?{c;eDLm!ef~%F zzt*$ALW^y0?Y9?!>ii?0jTYi7q1OI}+0(jSo(qKKV^}_an&z+etv;YJqy0f=h;iV3 z4};Wwy5C+>czgc^UvL=@^ogn2KcptH};1TUIh2RaW-u_TjMp&81nn?!d=+XJYNo1z!Vq>{a`FCfo-6C zPA9GW5E~bO*2G0Muovcs_VIP_H<$&Q_c{|UhL=F|sG7Pguyf#e>}-ZGA8MJlmonaj z7eVXTde{wV%Xm!w>%qpQAp2=;rPZsZ{nwVf_x#tor+HS5y|i^mtGCVhZ~H*&#oeEv zI_&oQZ|iU<{{J4_9Yor;IS_i?zUOmw!FR29I%jT%1K~&7GD5#6wEd95cdbje!@G4_ zk8ZywbnWk#_^mVlIJgDWAJy*FY1=wX?*qTDQDOYnxqlSQfTge+-iA1zAHvG6McTik ze6I8kpS5QX0iAW);BvSb9s-?%Ho#WU`A+LVZ>`DeEBTlv9Y6bm&eFQiJOWOHsqj7c zCFuOK0=7Uc_R3{x{7kEZ&sr1u!${CsNavu9kakYZPwPu9^zd8tIUIC`UjzFg?!3@v zqv^HqqZT&sr5Wae&fjtBpfmr+ez#Z)U((vZAFT`e%%HyLsSY}mN8atG^`lxn{5k^ef&EKUa3$A^-tpOIeN?2N_O$_+t3kGhpQ{;)KfZsYtO$v;QuD# zbv19J+6-S?V4bal_VL+K`Rnl=KI<++>ygeTvA-9qm%8Ay?vVZo-ko8+_!ZX={BDA2 z(Cxd6xcc>w58r$Bd;5B*<0sLF(hr98+af(5$qpMYbeOEt3s)M`g6u>#AYbQ~W*Ou{ z{o?Fec zlG%Jonz7_IIsM_udw)NY9X5_N?{OdO<&K_W&J*7Mb9r%_KsEEFc+pc)wR4m&nYXfF dWheeBz01lX^-;Vm7uxu0D>qw-6JEX$`9Ha#9tHpa literal 0 HcmV?d00001 From d205ffbc46fb531968df7e933906ab7dc7787323 Mon Sep 17 00:00:00 2001 From: Eugen Paraschiv Date: Mon, 14 May 2018 00:20:56 +0300 Subject: [PATCH 62/93] minor scala and gatling upgrades --- testing-modules/gatling/pom.xml | 11 ++++++----- .../scala/org/baeldung/RecordedSimulation.scala | 13 ++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/testing-modules/gatling/pom.xml b/testing-modules/gatling/pom.xml index 10df52835a..c4aec4d61a 100644 --- a/testing-modules/gatling/pom.xml +++ b/testing-modules/gatling/pom.xml @@ -13,10 +13,11 @@ 1.8 1.8 - 2.11.7 UTF-8 - 2.2.0 - 3.2.2 + 2.11.12 + 2.2.5 + 3.2.2 + 2.2.1 @@ -85,7 +86,7 @@ - -Ybackend:GenBCode + -Ydelambdafy:method -target:jvm-1.8 -deprecation @@ -101,7 +102,7 @@ io.gatling gatling-maven-plugin - ${gatling.version} + ${gatling-maven-plugin.version} test diff --git a/testing-modules/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala b/testing-modules/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala index cdbef1bf3c..dece393478 100644 --- a/testing-modules/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala +++ b/testing-modules/gatling/src/test/scala/org/baeldung/RecordedSimulation.scala @@ -9,17 +9,16 @@ import io.gatling.jdbc.Predef._ class RecordedSimulation extends Simulation { val httpProtocol = http - .baseURL("http://computer-database.gatling.io") - .inferHtmlResources(BlackList(""".*\.css""", """.*\.js""", """.*\.ico"""), WhiteList()) - .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") - .acceptEncodingHeader("gzip, deflate") - .acceptLanguageHeader("it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3") + .baseURL("http://computer-database.gatling.io") + .inferHtmlResources(BlackList(""".*\.css""", """.*\.js""", """.*\.ico"""), WhiteList()) + .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") + .acceptEncodingHeader("gzip, deflate") + .acceptLanguageHeader("it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3") .userAgentHeader("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0") - val scn = scenario("RecordedSimulation") .exec(http("request_0") .get("/")) @@ -43,4 +42,4 @@ class RecordedSimulation extends Simulation { .get("/computers?p=3")) setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol) -} +} From 368fb608f7741553ae294d021979ee41d91b425e Mon Sep 17 00:00:00 2001 From: Thoughtscript Date: Sun, 13 May 2018 23:56:37 +0100 Subject: [PATCH 63/93] BAEL-1740: Cleanup and Annotation Approach --- .../baeldung/{servlets => }/Constants.java | 7 +- .../com/baeldung/servlets/FormServlet.java | 4 +- .../baeldung/servlets/MultipartServlet.java | 49 ++++++++++ .../com/baeldung/servlets/UploadServlet.java | 91 +++++++++---------- .../src/main/webapp/WEB-INF/web.xml | 9 ++ javax-servlets/src/main/webapp/upload.jsp | 12 ++- 6 files changed, 117 insertions(+), 55 deletions(-) rename javax-servlets/src/main/java/com/baeldung/{servlets => }/Constants.java (73%) create mode 100644 javax-servlets/src/main/java/com/baeldung/servlets/MultipartServlet.java diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/Constants.java b/javax-servlets/src/main/java/com/baeldung/Constants.java similarity index 73% rename from javax-servlets/src/main/java/com/baeldung/servlets/Constants.java rename to javax-servlets/src/main/java/com/baeldung/Constants.java index 3195e95088..90c64870ad 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/Constants.java +++ b/javax-servlets/src/main/java/com/baeldung/Constants.java @@ -1,12 +1,11 @@ -package com.baeldung.servlets; +package com.baeldung; public class Constants { public static final String UPLOAD_DIRECTORY = "upload"; - public static final String ENDPOINT = "/jspupload/uploadFile"; + public static final String DEFAULT_FILENAME = "default.file"; public static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; public static final int MAX_FILE_SIZE = 1024 * 1024 * 40; public static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; - -} +} \ No newline at end of file diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java index 79004f9d94..c78129a9cf 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/FormServlet.java @@ -24,10 +24,10 @@ public class FormServlet extends HttpServlet { response.setHeader("Test", "Success"); response.setHeader("BMI", String.valueOf(bmi)); - RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/upload.jsp"); + RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/jsp/index.jsp"); dispatcher.forward(request, response); } catch (Exception e) { - response.sendRedirect("upload.jsp"); + response.sendRedirect("index.jsp"); } } diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/MultipartServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/MultipartServlet.java new file mode 100644 index 0000000000..18296ca1d8 --- /dev/null +++ b/javax-servlets/src/main/java/com/baeldung/servlets/MultipartServlet.java @@ -0,0 +1,49 @@ +package com.baeldung.servlets; + +import com.baeldung.Constants; + +import javax.servlet.ServletException; +import javax.servlet.annotation.MultipartConfig; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.Part; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +import static com.baeldung.Constants.UPLOAD_DIRECTORY; + +@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 5 * 5) +public class MultipartServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private String getFileName(Part part) { + for (String content : part.getHeader("content-disposition").split(";")) { + if (content.trim().startsWith("filename")) + return content.substring(content.indexOf("=") + 2, content.length() - 1); + } + return Constants.DEFAULT_FILENAME; + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; + File uploadDir = new File(uploadPath); + if (!uploadDir.exists()) + uploadDir.mkdir(); + + try { + String fileName = ""; + for (Part part : request.getParts()) { + fileName = getFileName(part); + part.write(uploadPath + File.separator + fileName); + } + request.setAttribute("message", "File " + fileName + " has uploaded successfully!"); + } catch (FileNotFoundException fne) { + request.setAttribute("message", "There was an error: " + fne.getMessage()); + } + getServletContext().getRequestDispatcher("/result.jsp").forward(request, response); + } +} \ No newline at end of file diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java index c809a9e818..e67bc349a1 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java @@ -1,61 +1,58 @@ package com.baeldung.servlets; -import static com.baeldung.servlets.Constants.MAX_FILE_SIZE; -import static com.baeldung.servlets.Constants.MAX_REQUEST_SIZE; -import static com.baeldung.servlets.Constants.MEMORY_THRESHOLD; -import static com.baeldung.servlets.Constants.UPLOAD_DIRECTORY; - -import java.io.File; -import java.io.IOException; -import java.util.List; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.util.List; + +import static com.baeldung.Constants.*; + public class UploadServlet extends HttpServlet { - - private static final long serialVersionUID = 1L; - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { + private static final long serialVersionUID = 1L; - if (ServletFileUpload.isMultipartContent(request)) { + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - DiskFileItemFactory factory = new DiskFileItemFactory(); - factory.setSizeThreshold(MEMORY_THRESHOLD); - factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); + if (ServletFileUpload.isMultipartContent(request)) { - ServletFileUpload upload = new ServletFileUpload(factory); - upload.setFileSizeMax(MAX_FILE_SIZE); - upload.setSizeMax(MAX_REQUEST_SIZE); - String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; - File uploadDir = new File(uploadPath); - if (!uploadDir.exists()) { - uploadDir.mkdir(); - } + DiskFileItemFactory factory = new DiskFileItemFactory(); + factory.setSizeThreshold(MEMORY_THRESHOLD); + factory.setRepository(new File(System.getProperty("java.io.tmpdir"))); - try { - List formItems = upload.parseRequest(request); + ServletFileUpload upload = new ServletFileUpload(factory); + upload.setFileSizeMax(MAX_FILE_SIZE); + upload.setSizeMax(MAX_REQUEST_SIZE); + String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY; + File uploadDir = new File(uploadPath); + if (!uploadDir.exists()) { + uploadDir.mkdir(); + } - if (formItems != null && formItems.size() > 0) { - for (FileItem item : formItems) { - if (!item.isFormField()) { - String fileName = new File(item.getName()).getName(); - String filePath = uploadPath + File.separator + fileName; - File storeFile = new File(filePath); - item.write(storeFile); - request.setAttribute("message", "File " + fileName + " has uploaded successfully!"); - } - } - } - } catch (Exception ex) { - request.setAttribute("message","There was an error: " + ex.getMessage()); - } - getServletContext().getRequestDispatcher("/result.jsp").forward(request, response); - } - } + try { + List formItems = upload.parseRequest(request); + + if (formItems != null && formItems.size() > 0) { + for (FileItem item : formItems) { + if (!item.isFormField()) { + String fileName = new File(item.getName()).getName(); + String filePath = uploadPath + File.separator + fileName; + File storeFile = new File(filePath); + item.write(storeFile); + request.setAttribute("message", "File " + fileName + " has uploaded successfully!"); + } + } + } + } catch (Exception ex) { + request.setAttribute("message", "There was an error: " + ex.getMessage()); + } + getServletContext().getRequestDispatcher("/result.jsp").forward(request, response); + } + } } \ No newline at end of file diff --git a/javax-servlets/src/main/webapp/WEB-INF/web.xml b/javax-servlets/src/main/webapp/WEB-INF/web.xml index 6f1220fa12..e5a854f5d0 100644 --- a/javax-servlets/src/main/webapp/WEB-INF/web.xml +++ b/javax-servlets/src/main/webapp/WEB-INF/web.xml @@ -12,4 +12,13 @@ UploadServlet /uploadFile + + + MultiPartServlet + com.baeldung.servlets.MultipartServlet + + + MultiPartServlet + /multiPartServlet + \ No newline at end of file diff --git a/javax-servlets/src/main/webapp/upload.jsp b/javax-servlets/src/main/webapp/upload.jsp index 8a0fcfc220..f365484892 100644 --- a/javax-servlets/src/main/webapp/upload.jsp +++ b/javax-servlets/src/main/webapp/upload.jsp @@ -1,4 +1,4 @@ -<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> @@ -8,8 +8,16 @@ +
Apache FileUpload
- Choose a file: + Choose a file: +
+ +
+ +
Servlet Multipart
+
+ Choose a file:
\ No newline at end of file From 388a2891b33b1f6198f5163532010fd918b2e9ac Mon Sep 17 00:00:00 2001 From: Harsh Jain Date: Mon, 14 May 2018 04:43:47 +0530 Subject: [PATCH 64/93] BAEL-1577 : moved hamcrest Core Matchers code samples to testing sub-modules from guava (#4245) --- .../HamcrestCommonCoreMatchersTest.java | 206 ------------------ .../hamcrest/HamcrestCoreMatchersTest.java | 0 2 files changed, 206 deletions(-) delete mode 100644 guava/src/test/java/org/baeldung/hamcrest/HamcrestCommonCoreMatchersTest.java rename {guava => testing-modules/mockito}/src/test/java/org/baeldung/hamcrest/HamcrestCoreMatchersTest.java (100%) diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestCommonCoreMatchersTest.java b/guava/src/test/java/org/baeldung/hamcrest/HamcrestCommonCoreMatchersTest.java deleted file mode 100644 index 2c85067c9b..0000000000 --- a/guava/src/test/java/org/baeldung/hamcrest/HamcrestCommonCoreMatchersTest.java +++ /dev/null @@ -1,206 +0,0 @@ -package org.baeldung.hamcrest; - -import org.assertj.core.util.Lists; -import org.junit.Test; - -import java.util.List; - -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.StringEndsWith.endsWith; -import static org.hamcrest.core.StringStartsWith.startsWith; - -public class HamcrestCommonCoreMatchersTest { - - @Test - public void givenTestInput_WhenUsingIsForMatch() { - - // GIVEN - String testString = "hamcrest core"; - - // ASSERT - assertThat(testString, is("hamcrest core")); - assertThat(testString, is(equalTo("hamcrest core"))); - } - - @Test - public void givenTestInput_WhenUsingInstanceOfForClassTypeCheck(){ - - assertThat("hamcrest", is(instanceOf(String.class))); - } - - @Test - public void givenTestInput_WhenUsingIsA_ThenAssertType(){ - - assertThat("hamcrest core", isA(String.class)); - } - - @Test - public void givenTestInput_WhenUsingEqualToMatcherForEquality(){ - - // GIVEN - String actualString = "Hamcrest Core"; - List actualList = Lists.newArrayList("hamcrest", "core"); - - // ASSERT - assertThat(actualString, is(equalTo("Hamcrest Core"))); - assertThat(actualList, is(equalTo(Lists.newArrayList("hamcrest", "core")))); - } - - @Test - public void givenTestInput_WhenUsingNotForMatch(){ - - // GIVEN - String testString = "hamcrest"; - - // ASSERT - assertThat(testString, not("hamcrest core")); - assertThat(testString, is(not(equalTo("hamcrest core")))); - assertThat(testString, is(not(instanceOf(Integer.class)))); - } - - @Test - public void givenTestInput_WhenUsingNullValueForNullCheck(){ - - // GIVEN - Integer nullObject = null; - - // ASSERT - assertThat(nullObject, is(nullValue())); - assertThat(nullObject, is(nullValue(Integer.class))); - } - - @Test - public void givenTestInput_WhenUsingNotNullValueForNotNullCheck(){ - - // GIVEN - Integer testNumber = 123; - - // ASSERT - assertThat(testNumber, is(notNullValue())); - assertThat(testNumber, is(notNullValue(Integer.class))); - } - - @Test - public void givenString_WhenStartsWith_ThenCorrect(){ - - // GIVEN - String testString = "hamcrest core"; - - // ASSERT - assertThat(testString, startsWith("hamcrest")); - } - - @Test - public void givenString_WhenEndsWith_ThenCorrect(){ - - // GIVEN - String testString = "hamcrest core"; - - // ASSERT - assertThat(testString, endsWith("core")); - } - - @Test - public void givenString_WhenContainsString_ThenCorrect(){ - - // GIVEN - String testString = "hamcrest core"; - - // ASSERT - assertThat(testString, containsString("co")); - } - - @Test - public void givenTestInput_WhenUsingHasItemInCollection(){ - - // GIVEN - List list = Lists.newArrayList("java", "spring", "baeldung"); - - // ASSERT - assertThat(list, hasItem("java")); - assertThat(list, hasItem(isA(String.class))); - } - - - @Test - public void givenTestInput_WhenUsingHasItemsInCollection(){ - - // GIVEN - List list = Lists.newArrayList("java", "spring", "baeldung"); - - // ASSERT - assertThat(list, hasItems("java", "baeldung")); - assertThat(list, hasItems(isA(String.class), endsWith("ing"))); - } - - @Test - public void givenTestInput_WhenUsingAnyForClassType(){ - - assertThat("hamcrest", is(any(String.class))); - assertThat("hamcrest", is(any(Object.class))); - } - - @Test - public void givenTestInput_WhenUsingAllOfForAllMatchers(){ - - // GIVEN - String testString = "Hamcrest Core"; - - // ASSERT - assertThat(testString, allOf(startsWith("Ham"), endsWith("ore"), containsString("Core"))); - } - - @Test - public void givenTestInput_WhenUsingAnyOfForAnyMatcher(){ - - // GIVEN - String testString = "Hamcrest Core"; - - // ASSERT - assertThat(testString, anyOf(startsWith("Ham"), containsString("baeldung"))); - } - - @Test - public void givenTestInput_WhenUsingBothForMatcher(){ - - // GIVEN - String testString = "Hamcrest Core Matchers"; - - // ASSERT - assertThat(testString, both(startsWith("Ham")).and(containsString("Core"))); - } - - @Test - public void givenTestInput_WhenUsingEitherForMatcher(){ - - // GIVEN - String testString = "Hamcrest Core Matchers"; - - // ASSERT - assertThat(testString, either(startsWith("Bael")).or(containsString("Core"))); - } - - - @Test - public void givenTestInput_WhenUsingEveryItemForMatchInCollection(){ - - // GIVEN - List testItems = Lists.newArrayList("Common", "Core", "Combinable"); - - // ASSERT - assertThat(testItems, everyItem(startsWith("Co"))); - } - - @Test - public void givenTwoTestInputs_WhenUsingSameInstanceForMatch(){ - - // GIVEN - String string1 = "hamcrest"; - String string2 = string1; - - // ASSERT - assertThat(string1, is(sameInstance(string2))); - } - -} \ No newline at end of file diff --git a/guava/src/test/java/org/baeldung/hamcrest/HamcrestCoreMatchersTest.java b/testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestCoreMatchersTest.java similarity index 100% rename from guava/src/test/java/org/baeldung/hamcrest/HamcrestCoreMatchersTest.java rename to testing-modules/mockito/src/test/java/org/baeldung/hamcrest/HamcrestCoreMatchersTest.java From 050cec1aef266aa88ac36adb562e4180607bd4f4 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Sun, 13 May 2018 21:09:29 -0600 Subject: [PATCH 65/93] BAEL-1745: Twilio SMS article --- twilio/sms/pom.xml | 24 +++++++++++++ .../sms/src/main/java/TwilioSmsExample.java | 22 ++++++++++++ .../src/main/java/TwilioSmsMediaExample.java | 27 +++++++++++++++ .../java/TwilioSmsStatusAsyncExample.java | 34 +++++++++++++++++++ .../src/main/java/TwilioSmsStatusExample.java | 22 ++++++++++++ 5 files changed, 129 insertions(+) create mode 100644 twilio/sms/pom.xml create mode 100644 twilio/sms/src/main/java/TwilioSmsExample.java create mode 100644 twilio/sms/src/main/java/TwilioSmsMediaExample.java create mode 100644 twilio/sms/src/main/java/TwilioSmsStatusAsyncExample.java create mode 100644 twilio/sms/src/main/java/TwilioSmsStatusExample.java diff --git a/twilio/sms/pom.xml b/twilio/sms/pom.xml new file mode 100644 index 0000000000..58ac33a7f3 --- /dev/null +++ b/twilio/sms/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + com.baeldung.twilio + sms + 1.0-SNAPSHOT + + + 1.8 + 1.8 + + + + + com.twilio.sdk + twilio + 7.20.0 + + + + diff --git a/twilio/sms/src/main/java/TwilioSmsExample.java b/twilio/sms/src/main/java/TwilioSmsExample.java new file mode 100644 index 0000000000..442546027b --- /dev/null +++ b/twilio/sms/src/main/java/TwilioSmsExample.java @@ -0,0 +1,22 @@ +import com.twilio.Twilio; +import com.twilio.rest.api.v2010.account.Message; +import com.twilio.type.PhoneNumber; + +public class TwilioSmsExample { + // Find your Account Sid and Token at twilio.com/console + public static final String ACCOUNT_SID = "YOUR_ACCOUNT_SID"; + public static final String AUTH_TOKEN = "YOUR_ACCOUNT_TOKEN"; + + // Create a phone number in the Twilio console + public static final String TWILIO_NUMBER = "+13334445555"; + + public static void main(String[] args) { + Twilio.init(ACCOUNT_SID, AUTH_TOKEN); + Message message = Message.creator( + new PhoneNumber("+12227779999"), + new PhoneNumber(TWILIO_NUMBER), + "Sample Twilio SMS using Java") + .create(); + + } +} diff --git a/twilio/sms/src/main/java/TwilioSmsMediaExample.java b/twilio/sms/src/main/java/TwilioSmsMediaExample.java new file mode 100644 index 0000000000..09a2f9fd63 --- /dev/null +++ b/twilio/sms/src/main/java/TwilioSmsMediaExample.java @@ -0,0 +1,27 @@ +import com.twilio.Twilio; +import com.twilio.converter.Promoter; +import com.twilio.rest.api.v2010.account.Message; +import com.twilio.type.PhoneNumber; + +import java.net.URI; + +public class TwilioSmsMediaExample { + // Find your Account Sid and Token at twilio.com/console + public static final String ACCOUNT_SID = "YOUR_ACCOUNT_SID"; + public static final String AUTH_TOKEN = "YOUR_ACCOUNT_TOKEN"; + + // Create a phone number in the Twilio console + public static final String TWILIO_NUMBER = "+13334445555"; + + public static void main(String[] args) { + Twilio.init(ACCOUNT_SID, AUTH_TOKEN); + Message message = Message.creator( + new PhoneNumber("+12227779999"), + new PhoneNumber(TWILIO_NUMBER), + "Sample Twilio MMS using Java") + .setMediaUrl( + Promoter.listOfOne( + URI.create("http://www.baeldung.com/wp-content/uploads/2017/10/icon-javaseries-home.png"))) + .create(); + } +} diff --git a/twilio/sms/src/main/java/TwilioSmsStatusAsyncExample.java b/twilio/sms/src/main/java/TwilioSmsStatusAsyncExample.java new file mode 100644 index 0000000000..d75788a6a6 --- /dev/null +++ b/twilio/sms/src/main/java/TwilioSmsStatusAsyncExample.java @@ -0,0 +1,34 @@ +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.twilio.Twilio; +import com.twilio.base.ResourceSet; +import com.twilio.rest.api.v2010.account.Message; + +public class TwilioSmsStatusAsyncExample { + // Find your Account Sid and Token at twilio.com/console + public static final String ACCOUNT_SID = "YOUR_ACCOUNT_SID"; + public static final String AUTH_TOKEN = "YOUR_AUTH_TOKEN"; + + // Create a phone number in the Twilio console + public static final String TWILIO_NUMBER = "+13334445555"; + + public static void main(String[] args) { + + Twilio.init(ACCOUNT_SID, AUTH_TOKEN); + ListenableFuture> future = Message.reader().readAsync(); + Futures.addCallback( + future, + new FutureCallback>() { + public void onSuccess(ResourceSet messages) { + for (Message message : messages) { + System.out.println(message.getSid() + " : " + message.getStatus()); + } + } + + public void onFailure(Throwable t) { + System.out.println("Failed to get message status: " + t.getMessage()); + } + }); + } +} diff --git a/twilio/sms/src/main/java/TwilioSmsStatusExample.java b/twilio/sms/src/main/java/TwilioSmsStatusExample.java new file mode 100644 index 0000000000..9ed2ac5bcc --- /dev/null +++ b/twilio/sms/src/main/java/TwilioSmsStatusExample.java @@ -0,0 +1,22 @@ +import com.twilio.Twilio; +import com.twilio.base.ResourceSet; +import com.twilio.rest.api.v2010.account.Message; +import com.twilio.type.PhoneNumber; + +public class TwilioSmsStatusExample { + // Find your Account Sid and Token at twilio.com/console + public static final String ACCOUNT_SID = "YOUR_ACCOUNT_SID"; + public static final String AUTH_TOKEN = "YOUR_ACCOUNT_TOKEN"; + + // Create a phone number in the Twilio console + public static final String TWILIO_NUMBER = "+13334445555"; + + public static void main(String[] args) { + + Twilio.init(ACCOUNT_SID, AUTH_TOKEN); + ResourceSet messages = Message.reader().read(); + for (Message message : messages) { + System.out.println(message.getSid() + " : " + message.getStatus()); + } + } +} From ee930d56c4358fb00a9b42146e64ce131abb68a1 Mon Sep 17 00:00:00 2001 From: Timoteo Ponce <248934+timoteoponce@users.noreply.github.com> Date: Mon, 14 May 2018 03:10:20 -0400 Subject: [PATCH 66/93] BAEL-1696 Initial setup in a workable state (#4173) * BAEL-1696 Initial setup in a workable state * Fixed method name on tomcatController --- pom.xml | 3 +- spring-boot-tomcat/pom.xml | 57 +++++++++++++++++++ .../SpringBootTomcatApplication.java | 13 +++++ .../springbootsimple/TomcatController.java | 18 ++++++ .../src/main/resources/application.properties | 0 .../SpringBootTomcatApplicationTests.java | 16 ++++++ 6 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 spring-boot-tomcat/pom.xml create mode 100644 spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/SpringBootTomcatApplication.java create mode 100644 spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/TomcatController.java create mode 100644 spring-boot-tomcat/src/main/resources/application.properties create mode 100644 spring-boot-tomcat/src/test/java/com/baeldung/springbootsimple/SpringBootTomcatApplicationTests.java diff --git a/pom.xml b/pom.xml index fb098a1eb3..a73d7ed357 100644 --- a/pom.xml +++ b/pom.xml @@ -141,6 +141,7 @@ spring-boot-keycloak spring-boot-bootstrap spring-boot-admin + spring-boot-tomcat spring-boot-security spring-cloud-data-flow spring-cloud @@ -530,4 +531,4 @@ 5.0.2 - \ No newline at end of file + diff --git a/spring-boot-tomcat/pom.xml b/spring-boot-tomcat/pom.xml new file mode 100644 index 0000000000..29c8ce95d6 --- /dev/null +++ b/spring-boot-tomcat/pom.xml @@ -0,0 +1,57 @@ + + + 4.0.0 + + com.baeldung + spring-boot-tomcat + 0.0.1-SNAPSHOT + war + + spring-boot-tomcat + Demo project for Spring Boot and Tomcat setup + + + org.springframework.boot + spring-boot-starter-parent + 2.0.1.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + ${artifactId} + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/SpringBootTomcatApplication.java b/spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/SpringBootTomcatApplication.java new file mode 100644 index 0000000000..c9f90683ec --- /dev/null +++ b/spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/SpringBootTomcatApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.springbootsimple; + +import org.springframework.boot.*; +import org.springframework.boot.autoconfigure.*; +import org.springframework.boot.web.servlet.support.*; + +@SpringBootApplication +public class SpringBootTomcatApplication extends SpringBootServletInitializer { + + public static void main(String[] args) { + SpringApplication.run(SpringBootTomcatApplication.class, args); + } +} diff --git a/spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/TomcatController.java b/spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/TomcatController.java new file mode 100644 index 0000000000..fcf7ecd6c0 --- /dev/null +++ b/spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/TomcatController.java @@ -0,0 +1,18 @@ +package com.baeldung.springbootsimple; + +import org.springframework.web.bind.annotation.*; + +import java.util.*; +import java.util.stream.*; + +@RestController +public class TomcatController { + + @GetMapping(value = "/hello") + public Collection sayHello() { + return IntStream.range(0, 10) + .mapToObj(i -> "Hello number " + i) + .collect(Collectors.toList()); + } + +} diff --git a/spring-boot-tomcat/src/main/resources/application.properties b/spring-boot-tomcat/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spring-boot-tomcat/src/test/java/com/baeldung/springbootsimple/SpringBootTomcatApplicationTests.java b/spring-boot-tomcat/src/test/java/com/baeldung/springbootsimple/SpringBootTomcatApplicationTests.java new file mode 100644 index 0000000000..4c0d4d577a --- /dev/null +++ b/spring-boot-tomcat/src/test/java/com/baeldung/springbootsimple/SpringBootTomcatApplicationTests.java @@ -0,0 +1,16 @@ +package com.baeldung.springbootsimple; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class SpringBootTomcatApplicationTests { + + @Test + public void contextLoads() { + } + +} From dec95f5c25fed16386972f19966ce200272dc3c0 Mon Sep 17 00:00:00 2001 From: Eugen Paraschiv Date: Mon, 14 May 2018 10:12:38 +0300 Subject: [PATCH 67/93] renaming the boot ops module --- pom.xml | 2 +- {spring-boot-tomcat => spring-boot-ops}/pom.xml | 6 +++--- .../springbootsimple/SpringBootTomcatApplication.java | 0 .../com/baeldung/springbootsimple/TomcatController.java | 0 .../src/main/resources/application.properties | 0 .../springbootsimple/SpringBootTomcatApplicationTests.java | 0 6 files changed, 4 insertions(+), 4 deletions(-) rename {spring-boot-tomcat => spring-boot-ops}/pom.xml (90%) rename {spring-boot-tomcat => spring-boot-ops}/src/main/java/com/baeldung/springbootsimple/SpringBootTomcatApplication.java (100%) rename {spring-boot-tomcat => spring-boot-ops}/src/main/java/com/baeldung/springbootsimple/TomcatController.java (100%) rename {spring-boot-tomcat => spring-boot-ops}/src/main/resources/application.properties (100%) rename {spring-boot-tomcat => spring-boot-ops}/src/test/java/com/baeldung/springbootsimple/SpringBootTomcatApplicationTests.java (100%) diff --git a/pom.xml b/pom.xml index a73d7ed357..9dea3dc79d 100644 --- a/pom.xml +++ b/pom.xml @@ -141,7 +141,7 @@ spring-boot-keycloak spring-boot-bootstrap spring-boot-admin - spring-boot-tomcat + spring-boot-ops spring-boot-security spring-cloud-data-flow spring-cloud diff --git a/spring-boot-tomcat/pom.xml b/spring-boot-ops/pom.xml similarity index 90% rename from spring-boot-tomcat/pom.xml rename to spring-boot-ops/pom.xml index 29c8ce95d6..0d0ccc0ef2 100644 --- a/spring-boot-tomcat/pom.xml +++ b/spring-boot-ops/pom.xml @@ -4,12 +4,12 @@ 4.0.0 com.baeldung - spring-boot-tomcat + spring-boot-ops 0.0.1-SNAPSHOT war - spring-boot-tomcat - Demo project for Spring Boot and Tomcat setup + spring-boot-ops + Demo project for Spring Boot org.springframework.boot diff --git a/spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/SpringBootTomcatApplication.java b/spring-boot-ops/src/main/java/com/baeldung/springbootsimple/SpringBootTomcatApplication.java similarity index 100% rename from spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/SpringBootTomcatApplication.java rename to spring-boot-ops/src/main/java/com/baeldung/springbootsimple/SpringBootTomcatApplication.java diff --git a/spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/TomcatController.java b/spring-boot-ops/src/main/java/com/baeldung/springbootsimple/TomcatController.java similarity index 100% rename from spring-boot-tomcat/src/main/java/com/baeldung/springbootsimple/TomcatController.java rename to spring-boot-ops/src/main/java/com/baeldung/springbootsimple/TomcatController.java diff --git a/spring-boot-tomcat/src/main/resources/application.properties b/spring-boot-ops/src/main/resources/application.properties similarity index 100% rename from spring-boot-tomcat/src/main/resources/application.properties rename to spring-boot-ops/src/main/resources/application.properties diff --git a/spring-boot-tomcat/src/test/java/com/baeldung/springbootsimple/SpringBootTomcatApplicationTests.java b/spring-boot-ops/src/test/java/com/baeldung/springbootsimple/SpringBootTomcatApplicationTests.java similarity index 100% rename from spring-boot-tomcat/src/test/java/com/baeldung/springbootsimple/SpringBootTomcatApplicationTests.java rename to spring-boot-ops/src/test/java/com/baeldung/springbootsimple/SpringBootTomcatApplicationTests.java From 5b7c29e7bf0bf094a0c7ff1582013e3b2d0b3e4b Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Mon, 14 May 2018 11:21:52 +0400 Subject: [PATCH 68/93] renaming the variable --- .../com/baeldung/scope/variable/HideVariable.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core-java/src/main/java/com/baeldung/scope/variable/HideVariable.java b/core-java/src/main/java/com/baeldung/scope/variable/HideVariable.java index 32251f2d37..8243fdb249 100644 --- a/core-java/src/main/java/com/baeldung/scope/variable/HideVariable.java +++ b/core-java/src/main/java/com/baeldung/scope/variable/HideVariable.java @@ -5,19 +5,19 @@ package com.baeldung.scope.variable; */ public class HideVariable { - private String instanceVariable = "this is instance variable"; + private String message = "this is instance variable"; HideVariable() { - instanceVariable = "constructor local variable"; - System.out.println(instanceVariable); + String message = "constructor local variable"; + System.out.println(message); } public void printLocalVariable() { - instanceVariable = "method local variable"; - System.out.println(instanceVariable); + String message = "method local variable"; + System.out.println(message); } public void printInstanceVariable() { - System.out.println(this.instanceVariable); + System.out.println(this.message); } } From 1fce593392e3166952dc1ba272eddea610ab25b9 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Mon, 14 May 2018 10:23:03 +0300 Subject: [PATCH 69/93] Update README.MD --- spring-boot/README.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-boot/README.MD b/spring-boot/README.MD index a1fadf787b..79f66b4a38 100644 --- a/spring-boot/README.MD +++ b/spring-boot/README.MD @@ -36,3 +36,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring - [Shutdown a Spring Boot Application](http://www.baeldung.com/spring-boot-shutdown) - [A Quick Intro to the SpringBootServletInitializer](http://www.baeldung.com/spring-boot-servlet-initializer) - [How to Change the Default Port in Spring Boot](http://www.baeldung.com/spring-boot-change-port) + From 6adc92c451b8985e33e1994fd773ea00bba5635f Mon Sep 17 00:00:00 2001 From: mherbaghinyan Date: Mon, 14 May 2018 11:49:03 +0400 Subject: [PATCH 70/93] hiding test --- .../java/com/baeldung/scope/variable/ChildVariable.java | 6 +++++- .../java/com/baeldung/scope/variable/ParentVariable.java | 4 ++++ .../com/baeldung/scope/variable/VariableHidingDemo.java | 6 ++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/core-java/src/main/java/com/baeldung/scope/variable/ChildVariable.java b/core-java/src/main/java/com/baeldung/scope/variable/ChildVariable.java index 5ec50b8b68..5730e5e282 100644 --- a/core-java/src/main/java/com/baeldung/scope/variable/ChildVariable.java +++ b/core-java/src/main/java/com/baeldung/scope/variable/ChildVariable.java @@ -5,5 +5,9 @@ package com.baeldung.scope.variable; */ public class ChildVariable extends ParentVariable { - String instanceVariable = "parent variable"; + String instanceVariable = "child variable"; + + public void printInstanceVariable() { + System.out.println(instanceVariable); + } } diff --git a/core-java/src/main/java/com/baeldung/scope/variable/ParentVariable.java b/core-java/src/main/java/com/baeldung/scope/variable/ParentVariable.java index 868a8a1acc..7f116b955e 100644 --- a/core-java/src/main/java/com/baeldung/scope/variable/ParentVariable.java +++ b/core-java/src/main/java/com/baeldung/scope/variable/ParentVariable.java @@ -6,4 +6,8 @@ package com.baeldung.scope.variable; public class ParentVariable { String instanceVariable = "parent variable"; + + public void printInstanceVariable() { + System.out.println(instanceVariable); + } } diff --git a/core-java/src/main/java/com/baeldung/scope/variable/VariableHidingDemo.java b/core-java/src/main/java/com/baeldung/scope/variable/VariableHidingDemo.java index ac1e24db6d..1ad71bd966 100644 --- a/core-java/src/main/java/com/baeldung/scope/variable/VariableHidingDemo.java +++ b/core-java/src/main/java/com/baeldung/scope/variable/VariableHidingDemo.java @@ -8,5 +8,11 @@ public class VariableHidingDemo { HideVariable variable = new HideVariable(); variable.printLocalVariable(); variable.printInstanceVariable(); + + ParentVariable parentVariable = new ParentVariable(); + ParentVariable childVariable = new ChildVariable(); + + parentVariable.printInstanceVariable(); + childVariable.printInstanceVariable(); } } From 19dd1a83ae39fb986e73144604ff69fdda2ab188 Mon Sep 17 00:00:00 2001 From: Thoughtscript Date: Mon, 14 May 2018 10:51:17 +0100 Subject: [PATCH 71/93] Servlet for upload.jsp --- .../baeldung/servlets/MultipartServlet.java | 5 ++++ .../com/baeldung/servlets/UploadServlet.java | 5 ++++ .../servlets/UploadWelcomeServlet.java | 18 ++++++++++++++ .../src/main/webapp/WEB-INF/web.xml | 24 ------------------- 4 files changed, 28 insertions(+), 24 deletions(-) create mode 100644 javax-servlets/src/main/java/com/baeldung/servlets/UploadWelcomeServlet.java delete mode 100644 javax-servlets/src/main/webapp/WEB-INF/web.xml diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/MultipartServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/MultipartServlet.java index 18296ca1d8..185edcf916 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/MultipartServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/MultipartServlet.java @@ -4,6 +4,7 @@ import com.baeldung.Constants; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; +import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -14,6 +15,10 @@ import java.io.IOException; import static com.baeldung.Constants.UPLOAD_DIRECTORY; +@WebServlet( + name = "MultiPartServlet", + urlPatterns = {"/multiPartServlet"} +) @MultipartConfig(fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 5 * 5) public class MultipartServlet extends HttpServlet { diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java index e67bc349a1..4de7b20913 100644 --- a/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java +++ b/javax-servlets/src/main/java/com/baeldung/servlets/UploadServlet.java @@ -1,5 +1,6 @@ package com.baeldung.servlets; +import javax.servlet.annotation.WebServlet; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; @@ -14,6 +15,10 @@ import java.util.List; import static com.baeldung.Constants.*; +@WebServlet( + name = "UploadServlet", + urlPatterns = {"/uploadFile"} +) public class UploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; diff --git a/javax-servlets/src/main/java/com/baeldung/servlets/UploadWelcomeServlet.java b/javax-servlets/src/main/java/com/baeldung/servlets/UploadWelcomeServlet.java new file mode 100644 index 0000000000..56cec546be --- /dev/null +++ b/javax-servlets/src/main/java/com/baeldung/servlets/UploadWelcomeServlet.java @@ -0,0 +1,18 @@ +package com.baeldung.servlets; + +import java.io.IOException; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name = "UploadWelcomeServlet", urlPatterns = "/uploadwelcome") +public class UploadWelcomeServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + request.getRequestDispatcher("/upload.jsp").forward(request, response); + } +} diff --git a/javax-servlets/src/main/webapp/WEB-INF/web.xml b/javax-servlets/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index e5a854f5d0..0000000000 --- a/javax-servlets/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - UploadServlet - com.baeldung.servlets.UploadServlet - - - UploadServlet - /uploadFile - - - - MultiPartServlet - com.baeldung.servlets.MultipartServlet - - - MultiPartServlet - /multiPartServlet - - \ No newline at end of file From 30552c8d0a5b22695c6dbff8c437cd32caa7b90f Mon Sep 17 00:00:00 2001 From: Eugen Paraschiv Date: Mon, 14 May 2018 14:30:26 +0300 Subject: [PATCH 72/93] formatting cleanup --- .../components/AttrListener.java | 4 +- .../components/EchoServlet.java | 4 +- .../components/HelloFilter.java | 4 +- .../components/HelloServlet.java | 8 +-- .../src/main/java/com/baeldung/intro/App.java | 6 +- .../intro/controller/HomeController.java | 6 +- .../configuration/WebMvcConfigure.java | 1 - .../servlets/props/PropertySourcesLoader.java | 3 +- .../servlets/javaee/AnnotationServlet.java | 4 +- .../java/com/baeldung/utils/Application.java | 10 +-- .../utils/controller/UtilsController.java | 67 +++++++++---------- .../webjar/WebjarsdemoApplication.java | 1 - .../baeldung/boot/components/FooService.java | 4 +- .../boot/exceptions/CommonException.java | 4 +- .../boot/exceptions/FooNotFoundException.java | 4 +- .../java/org/baeldung/boot/model/Foo.java | 1 - .../baeldung/boot/service/FooController.java | 2 +- ...otWithServletComponentIntegrationTest.java | 14 ++-- ...ithoutServletComponentIntegrationTest.java | 8 +-- .../java/com/baeldung/intro/AppLiveTest.java | 8 +-- .../utils/UtilsControllerIntegrationTest.java | 22 +++--- .../SpringBootMailIntegrationTest.java | 2 - .../boot/FooComponentIntegrationTest.java | 4 +- .../org/baeldung/boot/FooIntegrationTest.java | 20 +++--- .../baeldung/boot/FooJPAIntegrationTest.java | 6 +- .../baeldung/boot/FooJsonIntegrationTest.java | 3 +- 26 files changed, 93 insertions(+), 127 deletions(-) diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java index bad39c52c4..b1bdc7d781 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java @@ -9,9 +9,7 @@ public class AttrListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent servletContextEvent) { - servletContextEvent - .getServletContext() - .setAttribute("servlet-context-attr", "test"); + servletContextEvent.getServletContext().setAttribute("servlet-context-attr", "test"); System.out.println("context init"); } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java index 3419cd0eaf..d8192c2cb1 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java @@ -16,9 +16,7 @@ public class EchoServlet extends HttpServlet { @Override public void doPost(HttpServletRequest request, HttpServletResponse response) { try { - Path path = File - .createTempFile("echo", "tmp") - .toPath(); + Path path = File.createTempFile("echo", "tmp").toPath(); Files.copy(request.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING); Files.copy(path, response.getOutputStream()); Files.delete(path); diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java index dc2368c5b2..146e5ae386 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java @@ -18,9 +18,7 @@ public class HelloFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { - servletResponse - .getOutputStream() - .print(filterConfig.getInitParameter("msg")); + servletResponse.getOutputStream().print(filterConfig.getInitParameter("msg")); filterChain.doFilter(servletRequest, servletResponse); } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java index aeae7aecc9..5269c1bf29 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java @@ -8,22 +8,20 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -@WebServlet(urlPatterns = "/hello", initParams = { @WebInitParam(name = "msg", value = "hello")}) +@WebServlet(urlPatterns = "/hello", initParams = { @WebInitParam(name = "msg", value = "hello") }) public class HelloServlet extends HttpServlet { private ServletConfig servletConfig; @Override - public void init(ServletConfig servletConfig){ + public void init(ServletConfig servletConfig) { this.servletConfig = servletConfig; } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) { try { - response - .getOutputStream() - .write(servletConfig.getInitParameter("msg").getBytes()); + response.getOutputStream().write(servletConfig.getInitParameter("msg").getBytes()); } catch (IOException e) { e.printStackTrace(); } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/App.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/App.java index 3db5d3256e..77cdf4ddb9 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/App.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/App.java @@ -4,10 +4,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class App -{ - public static void main( String[] args ) - { +public class App { + public static void main(String[] args) { SpringApplication.run(App.class, args); } } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java index 2a7111135c..5c0cb2d2de 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java @@ -7,12 +7,12 @@ import org.springframework.web.bind.annotation.RestController; public class HomeController { @RequestMapping("/") - public String root(){ + public String root() { return "Index Page"; } - + @RequestMapping("/local") - public String local(){ + public String local() { return "/local"; } } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java index 3d6a10c2ac..8dea814bc7 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java @@ -26,7 +26,6 @@ public class WebMvcConfigure extends WebMvcConfigurerAdapter { configurer.enable(); } - @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/resources/").setCachePeriod(3600).resourceChain(true).addResolver(new PathResourceResolver()); diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java index 56a6751326..21e8949653 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java @@ -10,7 +10,8 @@ import org.springframework.core.env.ConfigurableEnvironment; @Configuration @ComponentScan(basePackages = { "com.baeldung.*" }) -@PropertySource("classpath:custom.properties") public class PropertySourcesLoader { +@PropertySource("classpath:custom.properties") +public class PropertySourcesLoader { private static final Logger log = LoggerFactory.getLogger(PropertySourcesLoader.class); diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java index b50a7d5454..992976ca0e 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java @@ -7,9 +7,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -@WebServlet(name = "AnnotationServlet", - description = "Example Servlet Using Annotations", - urlPatterns = { "/annotationservlet" }) +@WebServlet(name = "AnnotationServlet", description = "Example Servlet Using Annotations", urlPatterns = { "/annotationservlet" }) public class AnnotationServlet extends HttpServlet { private static final long serialVersionUID = 1L; diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java index a3d9f9130c..46cf3fb4aa 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java @@ -7,12 +7,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication -@ComponentScan(basePackages="com.baeldung.utils") +@ComponentScan(basePackages = "com.baeldung.utils") public class Application { - @RolesAllowed("*") - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } + @RolesAllowed("*") + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java index 7b4827cdf2..8c7f2f932a 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java @@ -4,7 +4,6 @@ import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.web.bind.ServletRequestBindingException; import org.springframework.web.bind.ServletRequestUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -13,37 +12,37 @@ import org.springframework.web.util.WebUtils; @Controller public class UtilsController { - @GetMapping("/utils") - public String webUtils(Model model) { - return "utils"; - } - - @PostMapping("/setParam") - public String post(HttpServletRequest request, Model model) { - String param = ServletRequestUtils.getStringParameter(request, "param", "DEFAULT"); - -// Long param = ServletRequestUtils.getLongParameter(request, "param",1L); -// boolean param = ServletRequestUtils.getBooleanParameter(request, "param", true); -// double param = ServletRequestUtils.getDoubleParameter(request, "param", 1000); -// float param = ServletRequestUtils.getFloatParameter(request, "param", (float) 1.00); -// int param = ServletRequestUtils.getIntParameter(request, "param", 100); - -// try { -// ServletRequestUtils.getRequiredStringParameter(request, "param"); -// } catch (ServletRequestBindingException e) { -// e.printStackTrace(); -// } - - WebUtils.setSessionAttribute(request, "parameter", param); - model.addAttribute("parameter", "You set: "+(String) WebUtils.getSessionAttribute(request, "parameter")); - return "utils"; - } - - @GetMapping("/other") - public String other(HttpServletRequest request, Model model) { - String param = (String) WebUtils.getSessionAttribute(request, "parameter"); - model.addAttribute("parameter", param); - return "other"; - } - + @GetMapping("/utils") + public String webUtils(Model model) { + return "utils"; + } + + @PostMapping("/setParam") + public String post(HttpServletRequest request, Model model) { + String param = ServletRequestUtils.getStringParameter(request, "param", "DEFAULT"); + + // Long param = ServletRequestUtils.getLongParameter(request, "param",1L); + // boolean param = ServletRequestUtils.getBooleanParameter(request, "param", true); + // double param = ServletRequestUtils.getDoubleParameter(request, "param", 1000); + // float param = ServletRequestUtils.getFloatParameter(request, "param", (float) 1.00); + // int param = ServletRequestUtils.getIntParameter(request, "param", 100); + + // try { + // ServletRequestUtils.getRequiredStringParameter(request, "param"); + // } catch (ServletRequestBindingException e) { + // e.printStackTrace(); + // } + + WebUtils.setSessionAttribute(request, "parameter", param); + model.addAttribute("parameter", "You set: " + (String) WebUtils.getSessionAttribute(request, "parameter")); + return "utils"; + } + + @GetMapping("/other") + public String other(HttpServletRequest request, Model model) { + String param = (String) WebUtils.getSessionAttribute(request, "parameter"); + model.addAttribute("parameter", param); + return "other"; + } + } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java index d2135754c9..2397861f1d 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java @@ -2,7 +2,6 @@ package com.baeldung.webjar; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.ComponentScan; @SpringBootApplication public class WebjarsdemoApplication { diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java index 235fd43299..4ff8e9fdd4 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java @@ -10,11 +10,11 @@ public class FooService { @Autowired private FooRepository fooRepository; - + public Foo getFooWithId(Integer id) throws Exception { return fooRepository.findOne(id); } - + public Foo getFooWithName(String name) { return fooRepository.findByName(name); } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java index 1f008440e6..e03b859eab 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java @@ -1,13 +1,13 @@ package org.baeldung.boot.exceptions; -public class CommonException extends RuntimeException{ +public class CommonException extends RuntimeException { /** * */ private static final long serialVersionUID = 3080004140659213332L; - public CommonException(String message){ + public CommonException(String message) { super(message); } } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java index 68ef3fa389..0b04bd2759 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java @@ -1,13 +1,13 @@ package org.baeldung.boot.exceptions; -public class FooNotFoundException extends RuntimeException{ +public class FooNotFoundException extends RuntimeException { /** * */ private static final long serialVersionUID = 9042200028456133589L; - public FooNotFoundException(String message){ + public FooNotFoundException(String message) { super(message); } } diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java index ac8a8fe429..d373e25b85 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java @@ -21,7 +21,6 @@ public class Foo implements Serializable { this.name = name; } - public Foo(Integer id, String name) { super(); this.id = id; diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java index 834fa342e2..d400c3bf9e 100644 --- a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java +++ b/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java @@ -18,7 +18,7 @@ public class FooController { public Foo getFooWithId(@PathVariable Integer id) throws Exception { return fooService.getFooWithId(id); } - + @GetMapping("/") public Foo getFooWithName(@RequestParam String name) throws Exception { return fooService.getFooWithName(name); diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java index 8d5eb56bf4..81774b6b8a 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java @@ -22,7 +22,8 @@ import static org.junit.Assert.*; @TestPropertySource(properties = { "security.basic.enabled=false" }) public class SpringBootWithServletComponentIntegrationTest { - @Autowired private ServletContext servletContext; + @Autowired + private ServletContext servletContext; @Test public void givenServletContext_whenAccessAttrs_thenFoundAttrsPutInServletListner() { @@ -37,12 +38,11 @@ public class SpringBootWithServletComponentIntegrationTest { FilterRegistration filterRegistration = servletContext.getFilterRegistration("hello filter"); assertNotNull(filterRegistration); - assertTrue(filterRegistration - .getServletNameMappings() - .contains("echo servlet")); + assertTrue(filterRegistration.getServletNameMappings().contains("echo servlet")); } - @Autowired private TestRestTemplate restTemplate; + @Autowired + private TestRestTemplate restTemplate; @Test public void givenServletFilter_whenGetHello_thenRequestFiltered() { @@ -58,8 +58,4 @@ public class SpringBootWithServletComponentIntegrationTest { assertEquals("filtering echo", responseEntity.getBody()); } - - } - - diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java index 64507ad02c..346f99a88a 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java @@ -22,9 +22,11 @@ import static org.junit.Assert.*; @TestPropertySource(properties = { "security.basic.enabled=false" }) public class SpringBootWithoutServletComponentIntegrationTest { - @Autowired private ServletContext servletContext; + @Autowired + private ServletContext servletContext; - @Autowired private TestRestTemplate restTemplate; + @Autowired + private TestRestTemplate restTemplate; @Test public void givenServletContext_whenAccessAttrs_thenNotFound() { @@ -46,5 +48,3 @@ public class SpringBootWithoutServletComponentIntegrationTest { } } - - diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java index af46fe0423..2c0152b97f 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java @@ -26,16 +26,12 @@ public class AppLiveTest { @Test public void getIndex() throws Exception { - mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().string(equalTo("Index Page"))); + mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(content().string(equalTo("Index Page"))); } @Test public void getLocal() throws Exception { - mvc.perform(MockMvcRequestBuilders.get("/local").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(content().string(equalTo("/local"))); + mvc.perform(MockMvcRequestBuilders.get("/local").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(content().string(equalTo("/local"))); } } \ No newline at end of file diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java index 829c0a6ac4..99e719d7e9 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java @@ -10,32 +10,26 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - import com.baeldung.utils.controller.UtilsController; public class UtilsControllerIntegrationTest { - @InjectMocks + @InjectMocks private UtilsController utilsController; - + private MockMvc mockMvc; - + @Before public void setup() { MockitoAnnotations.initMocks(this); - this.mockMvc = MockMvcBuilders.standaloneSetup(utilsController) - .build(); + this.mockMvc = MockMvcBuilders.standaloneSetup(utilsController).build(); } - + @Test public void givenParameter_setRequestParam_andSetSessionAttribute() throws Exception { - String param = "testparam"; - this.mockMvc.perform( - post("/setParam") - .param("param", param) - .sessionAttr("parameter", param)) - .andExpect(status().isOk()); + String param = "testparam"; + this.mockMvc.perform(post("/setParam").param("param", param).sessionAttr("parameter", param)).andExpect(status().isOk()); } - + } diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java index 10e3d6d60b..14386d73c1 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java @@ -9,8 +9,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.web.context.WebApplicationContext; import org.subethamail.wiser.Wiser; import org.subethamail.wiser.WiserMessage; diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentIntegrationTest.java index df975df0c1..07a5495e8a 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentIntegrationTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentIntegrationTest.java @@ -23,9 +23,7 @@ import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; @RunWith(SpringRunner.class) -@SpringBootTest( - classes = DemoApplication.class, - webEnvironment = WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = DemoApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class FooComponentIntegrationTest { @Autowired diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java index 932cce26d5..52728fbb5b 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java @@ -1,4 +1,5 @@ package org.baeldung.boot; + import java.util.HashMap; import java.util.Map; @@ -16,28 +17,27 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) -@SpringBootTest(classes=DemoApplication.class,webEnvironment = WebEnvironment.RANDOM_PORT) +@SpringBootTest(classes = DemoApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class FooIntegrationTest { @Autowired private TestRestTemplate testRestTemplate; - - + @Test - public void givenInquiryingFooWithId_whenIdIsValid_thenHttpStatusOK(){ - Map pathVariables = new HashMap(); + public void givenInquiryingFooWithId_whenIdIsValid_thenHttpStatusOK() { + Map pathVariables = new HashMap(); pathVariables.put("id", "1"); ResponseEntity fooResponse = testRestTemplate.getForEntity("/{id}", Foo.class, pathVariables); Assert.assertNotNull(fooResponse); - Assert.assertEquals(HttpStatus.OK,fooResponse.getStatusCode()); + Assert.assertEquals(HttpStatus.OK, fooResponse.getStatusCode()); } - + @Test - public void givenInquiryingFooWithName_whenNameIsValid_thenHttpStatusOK(){ - Map pathVariables = new HashMap(); + public void givenInquiryingFooWithName_whenNameIsValid_thenHttpStatusOK() { + Map pathVariables = new HashMap(); pathVariables.put("name", "Foo_Name"); ResponseEntity fooResponse = testRestTemplate.getForEntity("/?name={name}", Foo.class, pathVariables); Assert.assertNotNull(fooResponse); - Assert.assertEquals(HttpStatus.OK,fooResponse.getStatusCode()); + Assert.assertEquals(HttpStatus.OK, fooResponse.getStatusCode()); } } \ No newline at end of file diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java index 87afe565ee..40f1892be8 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java @@ -27,8 +27,8 @@ public class FooJPAIntegrationTest { this.entityManager.persist(new Foo("Foo_Name_2")); Foo foo = this.repository.findByName("Foo_Name_2"); assertNotNull(foo); - assertEquals("Foo_Name_2",foo.getName()); - // Due to having Insert query for Foo with Id 1, so TestEntityManager generates new Id of 2 - assertEquals(2l,foo.getId().longValue()); + assertEquals("Foo_Name_2", foo.getName()); + // Due to having Insert query for Foo with Id 1, so TestEntityManager generates new Id of 2 + assertEquals(2l, foo.getId().longValue()); } } \ No newline at end of file diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java index c74fd83e89..939e66f356 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java @@ -16,7 +16,6 @@ public class FooJsonIntegrationTest { @Autowired private JacksonTester json; - @Test public void testSerialize() throws Exception { @@ -30,6 +29,6 @@ public class FooJsonIntegrationTest { public void testDeserialize() throws Exception { String content = "{\"id\":4,\"name\":\"Foo_Name_4\"}"; assertThat(this.json.parseObject(content).getName()).isEqualTo("Foo_Name_4"); - assertThat(this.json.parseObject(content).getId()==4); + assertThat(this.json.parseObject(content).getId() == 4); } } \ No newline at end of file From cf76e126352a5044ddf64f5b87030cea3b5c54b3 Mon Sep 17 00:00:00 2001 From: Eugen Paraschiv Date: Mon, 14 May 2018 15:56:52 +0300 Subject: [PATCH 73/93] using the Spring MVC testing support properly --- .../baeldung/repository/UserRepository.java | 2 - .../shutdown/ShutdownApplicationTest.java | 11 ++--- .../toggle/ToggleIntegrationTest.java | 16 +++--- ...yeeConverterControllerIntegrationTest.java | 2 +- ...EmployeeRestControllerIntegrationTest.java | 49 ++++++++++--------- ...ithoutServletComponentIntegrationTest.java | 14 +++--- 6 files changed, 46 insertions(+), 48 deletions(-) diff --git a/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java b/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java index a5cf6a0c24..cba504b6c6 100644 --- a/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java +++ b/spring-boot/src/main/java/org/baeldung/repository/UserRepository.java @@ -10,8 +10,6 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; import java.util.Collection; import java.util.List; diff --git a/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java b/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java index 7896b9dc09..ae70276b9f 100644 --- a/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java +++ b/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java @@ -1,5 +1,8 @@ package com.baeldung.shutdown; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -12,10 +15,6 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - - @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class) @AutoConfigureMockMvc @@ -36,8 +35,6 @@ public class ShutdownApplicationTest { @Ignore public void givenBootApp_whenShutdownEndpoint_thenExit() throws Exception { - mockMvc.perform( - post("/shutdown")) - .andExpect(status().isOk()); + mockMvc.perform(post("/shutdown")).andExpect(status().isOk()); } } diff --git a/spring-boot/src/test/java/com/baeldung/toggle/ToggleIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/toggle/ToggleIntegrationTest.java index 471565b1c6..3213a10df9 100644 --- a/spring-boot/src/test/java/com/baeldung/toggle/ToggleIntegrationTest.java +++ b/spring-boot/src/test/java/com/baeldung/toggle/ToggleIntegrationTest.java @@ -1,31 +1,27 @@ package com.baeldung.toggle; +import static org.junit.Assert.assertEquals; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import static org.junit.Assert.assertEquals; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = ToggleApplication.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = ToggleApplication.class) @AutoConfigureMockMvc public class ToggleIntegrationTest { @Autowired - SalaryService salaryService; - - @Autowired - EmployeeRepository employeeRepository; + private EmployeeRepository employeeRepository; @Autowired private MockMvc mockMvc; diff --git a/spring-boot/src/test/java/org/baeldung/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java index 466d81e658..2afda7565a 100644 --- a/spring-boot/src/test/java/org/baeldung/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/converter/controller/StringToEmployeeConverterControllerIntegrationTest.java @@ -17,7 +17,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import org.baeldung.boot.Application; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = Application.class) @AutoConfigureMockMvc public class StringToEmployeeConverterControllerIntegrationTest { diff --git a/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRestControllerIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRestControllerIntegrationTest.java index da9df4db7d..d76dbfc803 100644 --- a/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRestControllerIntegrationTest.java +++ b/spring-boot/src/test/java/org/baeldung/demo/boottest/EmployeeRestControllerIntegrationTest.java @@ -1,23 +1,5 @@ package org.baeldung.demo.boottest; -import org.baeldung.demo.DemoApplication; -import org.baeldung.demo.boottest.Employee; -import org.baeldung.demo.boottest.EmployeeRepository; -import org.junit.After; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.http.MediaType; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; - -import java.io.IOException; -import java.util.List; - import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.greaterThanOrEqualTo; @@ -29,8 +11,23 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.io.IOException; +import java.util.List; + +import org.baeldung.demo.DemoApplication; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = DemoApplication.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = DemoApplication.class) @AutoConfigureMockMvc // @TestPropertySource(locations = "classpath:application-integrationtest.properties") @AutoConfigureTestDatabase @@ -58,14 +55,22 @@ public class EmployeeRestControllerIntegrationTest { @Test public void givenEmployees_whenGetEmployees_thenStatus200() throws Exception { - createTestEmployee("bob"); createTestEmployee("alex"); - mvc.perform(get("/api/employees").contentType(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk()).andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)).andExpect(jsonPath("$", hasSize(greaterThanOrEqualTo(2)))) - .andExpect(jsonPath("$[0].name", is("bob"))).andExpect(jsonPath("$[1].name", is("alex"))); + // @formatter:off + mvc.perform(get("/api/employees").contentType(MediaType.APPLICATION_JSON)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$", hasSize(greaterThanOrEqualTo(2)))) + .andExpect(jsonPath("$[0].name", is("bob"))) + .andExpect(jsonPath("$[1].name", is("alex"))); + // @formatter:on } + // + private void createTestEmployee(String name) { Employee emp = new Employee(name); repository.saveAndFlush(emp); diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java index 346f99a88a..e7e1d5486c 100644 --- a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java +++ b/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java @@ -1,5 +1,12 @@ package com.baeldung.annotation.servletcomponentscan; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import javax.servlet.FilterRegistration; +import javax.servlet.ServletContext; + import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -11,13 +18,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; -import javax.servlet.FilterRegistration; -import javax.servlet.ServletContext; - -import static org.junit.Assert.*; - @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootPlainApp.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = SpringBootPlainApp.class) @AutoConfigureMockMvc @TestPropertySource(properties = { "security.basic.enabled=false" }) public class SpringBootWithoutServletComponentIntegrationTest { From 8b324a315be6527be5f65023b39171a9f7b21e11 Mon Sep 17 00:00:00 2001 From: Shreyash Date: Tue, 15 May 2018 22:45:00 +0530 Subject: [PATCH 74/93] Changes for suggestions on BAEL-998 (#4250) --- .../interoperability/CollectionsInteroperabilityUnitTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java b/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java index 8256c2369a..ed394f9023 100644 --- a/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java +++ b/vavr/src/test/java/com/baeldung/vavr/interoperability/CollectionsInteroperabilityUnitTest.java @@ -12,6 +12,7 @@ import io.vavr.collection.HashMap; import io.vavr.collection.LinkedHashSet; import io.vavr.collection.List; import io.vavr.collection.Map; +import io.vavr.collection.Set; import io.vavr.collection.Stream; public class CollectionsInteroperabilityUnitTest { @@ -77,8 +78,9 @@ public class CollectionsInteroperabilityUnitTest { @Test public void givenParams_WhenVavarListConvertedToLinkedSet_thenReturnLinkedSet() { List vavrList = List.of("Java", "Haskell", "Scala", "Java"); - LinkedHashSet linkedSet = (LinkedHashSet) vavrList.toLinkedSet(); + Set linkedSet = vavrList.toLinkedSet(); assertEquals(3, linkedSet.size()); + assertTrue(linkedSet instanceof LinkedHashSet); } @Test From bdb937e68b2cf4a18776caea2be2e2ff2ee1f69f Mon Sep 17 00:00:00 2001 From: Shubhra Srivastava Date: Tue, 15 May 2018 23:50:55 +0530 Subject: [PATCH 75/93] BAEL 1748 - Optional - orElse() vs orElseGet() (#4240) * Types of Bean Injection in Spring * Changing config file name * BAEL-1584 : Find an element in list * Revert "Changing config file name" This reverts commit d857db9f65b1cf89773348e3901385ce59d9e1f8. * Revert "Types of Bean Injection in Spring" This reverts commit e9efcb8e70f37e7488aa2371bb3ee62c676996f4. * BAEL-1584 : Find an Element in Given List * BAEL-1584 : Hashcode impl changed * BAEL:1584 : ListIterator to Iterator change * Method name refactoring * BAEL 1748 - Optional OrElse vs OrElseGet * BAEL-1748 Benchmark Runner --- .../baeldung/optional/OrElseAndOrElseGet.java | 34 ++++++++++++++ .../OrElseAndOrElseGetBenchmarkRunner.java | 37 ++++++++++++++++ .../optional/OrElseAndOrElseGetTest.java | 44 +++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 core-java-8/src/main/java/com/baeldung/optional/OrElseAndOrElseGet.java create mode 100644 core-java-8/src/main/java/com/baeldung/optional/OrElseAndOrElseGetBenchmarkRunner.java create mode 100644 core-java-8/src/test/java/com/baeldung/java8/optional/OrElseAndOrElseGetTest.java diff --git a/core-java-8/src/main/java/com/baeldung/optional/OrElseAndOrElseGet.java b/core-java-8/src/main/java/com/baeldung/optional/OrElseAndOrElseGet.java new file mode 100644 index 0000000000..d4d07291d5 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/optional/OrElseAndOrElseGet.java @@ -0,0 +1,34 @@ +package com.baeldung.optional; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.Random; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class OrElseAndOrElseGet { + + public static List names = Arrays.asList("John", "Jones", "Kelly", "Cristina", "Raven"); + + private static final Logger LOG = LoggerFactory.getLogger(OrElseAndOrElseGet.class); + + public String getRandomName() { + LOG.info("getRandomName() method - start"); + Random random = new Random(); + int index = random.nextInt(5); + LOG.info("getRandomName() method - end"); + return names.get(index); + } + + public String getNameUsingOrElse(String name) { + return Optional.ofNullable(name) + .orElse(getRandomName()); + } + + public String getNameUsingOrElseGet(String name) { + return Optional.ofNullable(name) + .orElseGet(() -> getRandomName()); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/optional/OrElseAndOrElseGetBenchmarkRunner.java b/core-java-8/src/main/java/com/baeldung/optional/OrElseAndOrElseGetBenchmarkRunner.java new file mode 100644 index 0000000000..8bf0b0b25d --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/optional/OrElseAndOrElseGetBenchmarkRunner.java @@ -0,0 +1,37 @@ +package com.baeldung.optional; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.runner.RunnerException; + +@Fork(1) +@State(Scope.Benchmark) +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +public class OrElseAndOrElseGetBenchmarkRunner { + + private OrElseAndOrElseGet orElsevsOrElseGet = new OrElseAndOrElseGet(); + + public static void main(String[] args) throws RunnerException, IOException { + org.openjdk.jmh.Main.main(args); + } + + @Benchmark + public String orElseBenchmark() { + return orElsevsOrElseGet.getNameUsingOrElse("baeldung"); + } + + @Benchmark + public String orElseGetBenchmark() { + return orElsevsOrElseGet.getNameUsingOrElseGet("baeldung"); + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/java8/optional/OrElseAndOrElseGetTest.java b/core-java-8/src/test/java/com/baeldung/java8/optional/OrElseAndOrElseGetTest.java new file mode 100644 index 0000000000..2519a77f1f --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/java8/optional/OrElseAndOrElseGetTest.java @@ -0,0 +1,44 @@ +package com.baeldung.java8.optional; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.*; + +import com.baeldung.optional.OrElseAndOrElseGet; + +public class OrElseAndOrElseGetTest { + + private OrElseAndOrElseGet orElsevsOrElseGet = new OrElseAndOrElseGet(); + + private static final Logger LOG = LoggerFactory.getLogger(OrElseAndOrElseGetTest.class); + + @Test + public void givenNonEmptyOptional_whenOrElseUsed_thenGivenStringReturned() { + LOG.info("In givenNonEmptyOptional_whenOrElseUsed_thenGivenStringReturned()"); + String name = orElsevsOrElseGet.getNameUsingOrElse("baeldung"); + assertEquals(name, "baeldung"); + } + + @Test + public void givenEmptyOptional_whenOrElseUsed_thenRandomStringReturned() { + LOG.info("In givenEmptyOptional_whenOrElseUsed_thenRandomStringReturned()"); + String name = orElsevsOrElseGet.getNameUsingOrElse(null); + assertTrue(orElsevsOrElseGet.names.contains(name)); + } + + @Test + public void givenNonEmptyOptional_whenOrElseGetUsed_thenGivenStringReturned() { + LOG.info("In givenNonEmptyOptional_whenOrElseGetUsed_thenGivenStringReturned()"); + String name = orElsevsOrElseGet.getNameUsingOrElseGet("baeldung"); + assertEquals(name, "baeldung"); + } + + @Test + public void givenEmptyOptional_whenOrElseGetUsed_thenRandomStringReturned() { + LOG.info("In givenEmptyOptional_whenOrElseGetUsed_thenRandomStringReturned()"); + String name = orElsevsOrElseGet.getNameUsingOrElseGet(null); + assertTrue(orElsevsOrElseGet.names.contains(name)); + } +} From 62b5a591af53ca807d8b5fac91653dcede2f821e Mon Sep 17 00:00:00 2001 From: Miguel Rivero Date: Tue, 15 May 2018 23:18:41 +0200 Subject: [PATCH 76/93] BAEL-1637: Guide to JNI(Java Native Interface) (#4066) * BAEL-1546: Java 8 Math additions * Applied feedback to Unit Tests * BAEL-1546 Added missing test annotations * Added code for BAEL-1637 * Added script for Windows C++ code compile * Added compilation script for MacOS * Added some Unit tests --- jni/native/linux_x86_64/libnative.so | Bin 0 -> 19856 bytes jni/native/macos/libnative.dylib | Bin 0 -> 23056 bytes jni/native/win32/native.dll | Bin 0 -> 1593130 bytes jni/pom.xml | 15 +++++ .../com_baeldung_jni_ExampleObjectsJNI.cpp | 48 +++++++++++++++ .../cpp/com_baeldung_jni_ExampleObjectsJNI.h | 29 +++++++++ .../com_baeldung_jni_ExampleParametersJNI.cpp | 34 ++++++++++ .../com_baeldung_jni_ExampleParametersJNI.h | 29 +++++++++ .../cpp/com_baeldung_jni_HelloWorldJNI.cpp | 13 ++++ .../main/cpp/com_baeldung_jni_HelloWorldJNI.h | 21 +++++++ jni/src/main/cpp/generateNativeLib.bat | 6 ++ jni/src/main/cpp/generateNativeLib.sh | 7 +++ jni/src/main/cpp/generateNativeLibMac.sh | 6 ++ .../com/baeldung/jni/ExampleObjectsJNI.java | 19 ++++++ .../baeldung/jni/ExampleParametersJNI.java | 20 ++++++ .../java/com/baeldung/jni/HelloWorldJNI.java | 15 +++++ .../main/java/com/baeldung/jni/UserData.java | 11 ++++ .../java/com/baeldung/jni/JNINativeTests.java | 58 ++++++++++++++++++ 18 files changed, 331 insertions(+) create mode 100755 jni/native/linux_x86_64/libnative.so create mode 100755 jni/native/macos/libnative.dylib create mode 100644 jni/native/win32/native.dll create mode 100644 jni/pom.xml create mode 100644 jni/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp create mode 100644 jni/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h create mode 100644 jni/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp create mode 100644 jni/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h create mode 100644 jni/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp create mode 100644 jni/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h create mode 100644 jni/src/main/cpp/generateNativeLib.bat create mode 100755 jni/src/main/cpp/generateNativeLib.sh create mode 100755 jni/src/main/cpp/generateNativeLibMac.sh create mode 100644 jni/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java create mode 100644 jni/src/main/java/com/baeldung/jni/ExampleParametersJNI.java create mode 100644 jni/src/main/java/com/baeldung/jni/HelloWorldJNI.java create mode 100644 jni/src/main/java/com/baeldung/jni/UserData.java create mode 100644 jni/src/test/java/com/baeldung/jni/JNINativeTests.java diff --git a/jni/native/linux_x86_64/libnative.so b/jni/native/linux_x86_64/libnative.so new file mode 100755 index 0000000000000000000000000000000000000000..213491e2688a87bdecd1fea411e578149f8e3f32 GIT binary patch literal 19856 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 z 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

&5>we{)F73-C+}Ge#>LbUOaH8v^%Ofl& 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%0DPN$M?Mk-NiR8pxNRFW_#CDBQtC{0(DE~8F2 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

r7*R9XFjGQUjnQi%FSRG7pG{)HhIKi%8|7QqI}S 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 literal 0 HcmV?d00001 diff --git a/jni/pom.xml b/jni/pom.xml new file mode 100644 index 0000000000..752277f526 --- /dev/null +++ b/jni/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + com.baeldung + jni + 0.0.1-SNAPSHOT + + + + junit + junit + 4.8.1 + test + + + \ No newline at end of file diff --git a/jni/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp b/jni/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp new file mode 100644 index 0000000000..65c11cb9e1 --- /dev/null +++ b/jni/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.cpp @@ -0,0 +1,48 @@ +#include "com_baeldung_jni_ExampleObjectsJNI.h" +#include + +/* + * Class: com_baeldung_jni_ExampleObjectsJNI + * Method: createUser + * Signature: (Ljava/lang/String;D)Lcom/baeldung/jni/UserData; + */ +JNIEXPORT jobject JNICALL Java_com_baeldung_jni_ExampleObjectsJNI_createUser + (JNIEnv *env, jobject thisObject, jstring name, jdouble balance){ + + // Create the object of the class UserData + jclass userDataClass = env->FindClass("com/baeldung/jni/UserData"); + jobject newUserData = env->AllocObject(userDataClass); + + // Get UserData fields to set + jfieldID nameField = env->GetFieldID(userDataClass , "name", "Ljava/lang/String;"); + jfieldID balanceField = env->GetFieldID(userDataClass , "balance", "D"); + + // Set the values of the new object + env->SetObjectField(newUserData, nameField, name); + env->SetDoubleField(newUserData, balanceField, balance); + + // Return the created object + return newUserData; + } + +/* + * Class: com_baeldung_jni_ExampleObjectsJNI + * Method: printUserData + * Signature: (Lcom/baeldung/jni/UserData;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_baeldung_jni_ExampleObjectsJNI_printUserData + (JNIEnv *env, jobject thisObject, jobject userData){ + + // Find the class method id + jclass userDataClass = env->GetObjectClass(userData); + jmethodID methodId = env->GetMethodID(userDataClass, "getUserInfo", "()Ljava/lang/String;"); + + // Call the object method and get the result + jstring result = (jstring)env->CallObjectMethod(userData, methodId); + + // Print the result + std::cout << "C++: User data is: " << env->GetStringUTFChars(result, NULL) << std::endl; + + return result; + } + diff --git a/jni/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h b/jni/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h new file mode 100644 index 0000000000..28cb782eed --- /dev/null +++ b/jni/src/main/cpp/com_baeldung_jni_ExampleObjectsJNI.h @@ -0,0 +1,29 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_baeldung_jni_ExampleObjectsJNI */ + +#ifndef _Included_com_baeldung_jni_ExampleObjectsJNI +#define _Included_com_baeldung_jni_ExampleObjectsJNI +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_baeldung_jni_ExampleObjectsJNI + * Method: createUser + * Signature: (Ljava/lang/String;D)Lcom/baeldung/jni/UserData; + */ +JNIEXPORT jobject JNICALL Java_com_baeldung_jni_ExampleObjectsJNI_createUser + (JNIEnv *, jobject, jstring, jdouble); + +/* + * Class: com_baeldung_jni_ExampleObjectsJNI + * Method: printUserData + * Signature: (Lcom/baeldung/jni/UserData;)V + */ +JNIEXPORT jstring JNICALL Java_com_baeldung_jni_ExampleObjectsJNI_printUserData + (JNIEnv *, jobject, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/jni/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp b/jni/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp new file mode 100644 index 0000000000..319b85f592 --- /dev/null +++ b/jni/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.cpp @@ -0,0 +1,34 @@ +#include "com_baeldung_jni_ExampleParametersJNI.h" +#include +#include + +/* + * Class: com_baeldung_jni_ExampleParametersJNI + * Method: sumIntegers + * Signature: (II)J + */ +JNIEXPORT jlong JNICALL Java_com_baeldung_jni_ExampleParametersJNI_sumIntegers (JNIEnv* env, jobject thisObject, jint first, jint second){ + std::cout << "C++: The numbers received are : " << first << " and " << second << std::endl; + return (long)first + (long)second; +} + + +/* + * Class: com_baeldung_jni_ExampleParametersJNI + * Method: sayHelloToMe + * Signature: (Ljava/lang/String;Z)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_baeldung_jni_ExampleParametersJNI_sayHelloToMe (JNIEnv* env, jobject thisObject, jstring name, jboolean isFemale){ + const char* nameCharPointer = env->GetStringUTFChars(name, NULL); + std::cout << "C++: The string received is: " << nameCharPointer << std::endl; + std::string title; + if(isFemale){ + title = "Ms. "; + } + else{ + title = "Mr. "; + } + + std::string fullName = title + nameCharPointer; + return env->NewStringUTF(fullName.c_str()); +} diff --git a/jni/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h b/jni/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h new file mode 100644 index 0000000000..58b9a2ca2f --- /dev/null +++ b/jni/src/main/cpp/com_baeldung_jni_ExampleParametersJNI.h @@ -0,0 +1,29 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_baeldung_jni_ExampleParametersJNI */ + +#ifndef _Included_com_baeldung_jni_ExampleParametersJNI +#define _Included_com_baeldung_jni_ExampleParametersJNI +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_baeldung_jni_ExampleParametersJNI + * Method: sumIntegers + * Signature: (II)J + */ +JNIEXPORT jlong JNICALL Java_com_baeldung_jni_ExampleParametersJNI_sumIntegers + (JNIEnv*, jobject, jint, jint); + +/* + * Class: com_baeldung_jni_ExampleParametersJNI + * Method: sayHelloToMe + * Signature: (Ljava/lang/String;Z)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_baeldung_jni_ExampleParametersJNI_sayHelloToMe + (JNIEnv*, jobject, jstring, jboolean); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/jni/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp b/jni/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp new file mode 100644 index 0000000000..d2001ebdac --- /dev/null +++ b/jni/src/main/cpp/com_baeldung_jni_HelloWorldJNI.cpp @@ -0,0 +1,13 @@ +#include "com_baeldung_jni_HelloWorldJNI.h" +#include + +/* + * Class: com_baeldung_jni_HelloWorldJNI + * Method: sayHello + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_com_baeldung_jni_HelloWorldJNI_sayHello (JNIEnv* env, jobject thisObject) { + std::string hello = "Hello from C++ !!"; + std::cout << hello << std::endl; + return env->NewStringUTF(hello.c_str()); +} \ No newline at end of file diff --git a/jni/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h b/jni/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h new file mode 100644 index 0000000000..fbdd4cc8f7 --- /dev/null +++ b/jni/src/main/cpp/com_baeldung_jni_HelloWorldJNI.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_baeldung_jni_HelloWorldJNI */ + +#ifndef _Included_com_baeldung_jni_HelloWorldJNI +#define _Included_com_baeldung_jni_HelloWorldJNI +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_baeldung_jni_HelloWorldJNI + * Method: sayHello + * Signature: ()V + */ +JNIEXPORT jstring JNICALL Java_com_baeldung_jni_HelloWorldJNI_sayHello + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/jni/src/main/cpp/generateNativeLib.bat b/jni/src/main/cpp/generateNativeLib.bat new file mode 100644 index 0000000000..73fb29fa66 --- /dev/null +++ b/jni/src/main/cpp/generateNativeLib.bat @@ -0,0 +1,6 @@ +REM Create the header with javac -h . ClassName.java +REM Remember to set your JAVA_HOME env var +g++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 com_baeldung_jni_HelloWorldJNI.cpp -o com_baeldung_jni_HelloWorldJNI.o +g++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 com_baeldung_jni_ExampleParametersJNI.cpp -o com_baeldung_jni_ExampleParametersJNI.o +g++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 com_baeldung_jni_ExampleObjectsJNI.cpp -o com_baeldung_jni_ExampleObjectsJNI.o +g++ -shared -o ..\..\..\native\win32\native.dll com_baeldung_jni_HelloWorldJNI.o com_baeldung_jni_ExampleParametersJNI.o com_baeldung_jni_ExampleObjectsJNI.o -Wl,--add-stdcall-alias \ No newline at end of file diff --git a/jni/src/main/cpp/generateNativeLib.sh b/jni/src/main/cpp/generateNativeLib.sh new file mode 100755 index 0000000000..4a90d1ee04 --- /dev/null +++ b/jni/src/main/cpp/generateNativeLib.sh @@ -0,0 +1,7 @@ +# Create the header with javac -h . ClassName.java +# Remember to set your JAVA_HOME env var +g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux com_baeldung_jni_HelloWorldJNI.cpp -o com_baeldung_jni_HelloWorldJNI.o +g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux com_baeldung_jni_ExampleParametersJNI.cpp -o com_baeldung_jni_ExampleParametersJNI.o +g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux com_baeldung_jni_ExampleObjectsJNI.cpp -o com_baeldung_jni_ExampleObjectsJNI.o +g++ -shared -fPIC -o ../../../native/linux_x86_64/libnative.so com_baeldung_jni_HelloWorldJNI.o com_baeldung_jni_ExampleParametersJNI.o com_baeldung_jni_ExampleObjectsJNI.o -lc +# Don't forget to set java.library.path to point to the folder where you have the libnative you're loading. \ No newline at end of file diff --git a/jni/src/main/cpp/generateNativeLibMac.sh b/jni/src/main/cpp/generateNativeLibMac.sh new file mode 100755 index 0000000000..d11dcc7c01 --- /dev/null +++ b/jni/src/main/cpp/generateNativeLibMac.sh @@ -0,0 +1,6 @@ +# Create the header with javac -h . ClassName.java +# Remember to set your JAVA_HOME env var +g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin com_baeldung_jni_HelloWorldJNI.cpp -o com_baeldung_jni_HelloWorldJNI.o +g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin com_baeldung_jni_ExampleParametersJNI.cpp -o com_baeldung_jni_ExampleParametersJNI.o +g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin com_baeldung_jni_ExampleObjectsJNI.cpp -o com_baeldung_jni_ExampleObjectsJNI.o +g++ -dynamiclib -o ../../../native/macos/libnative.dylib com_baeldung_jni_HelloWorldJNI.o com_baeldung_jni_ExampleParametersJNI.o com_baeldung_jni_ExampleObjectsJNI.o -lc \ No newline at end of file diff --git a/jni/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java b/jni/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java new file mode 100644 index 0000000000..b8ebfb3cd5 --- /dev/null +++ b/jni/src/main/java/com/baeldung/jni/ExampleObjectsJNI.java @@ -0,0 +1,19 @@ +package com.baeldung.jni; + +public class ExampleObjectsJNI { + + static { + System.loadLibrary("native"); + } + + public static void main(String[] args) { + ExampleObjectsJNI instance = new ExampleObjectsJNI(); + UserData newUser = instance.createUser("John Doe", 450.67); + instance.printUserData(newUser); + } + + public native UserData createUser(String name, double balance); + + public native String printUserData(UserData user); + +} diff --git a/jni/src/main/java/com/baeldung/jni/ExampleParametersJNI.java b/jni/src/main/java/com/baeldung/jni/ExampleParametersJNI.java new file mode 100644 index 0000000000..f4553b7773 --- /dev/null +++ b/jni/src/main/java/com/baeldung/jni/ExampleParametersJNI.java @@ -0,0 +1,20 @@ +package com.baeldung.jni; + +public class ExampleParametersJNI { + + static { + System.loadLibrary("native"); + } + + public static void main(String[] args) { + System.out.println("Java: My full name: " + new ExampleParametersJNI().sayHelloToMe("Martin", false)); + long sumFromNative = new ExampleParametersJNI().sumIntegers(456, 44); + System.out.println("Java: The sum coming from native code is: " + sumFromNative); + } + + // Declare another method sumIntegers that receives two integers and return a long with the sum + public native long sumIntegers(int first, int second); + + // Declare another method sayHelloToMe that receives the name and gender and returns the proper salutation + public native String sayHelloToMe(String name, boolean isFemale); +} diff --git a/jni/src/main/java/com/baeldung/jni/HelloWorldJNI.java b/jni/src/main/java/com/baeldung/jni/HelloWorldJNI.java new file mode 100644 index 0000000000..a351238900 --- /dev/null +++ b/jni/src/main/java/com/baeldung/jni/HelloWorldJNI.java @@ -0,0 +1,15 @@ +package com.baeldung.jni; + +public class HelloWorldJNI { + + static { + System.loadLibrary("native"); + } + + public static void main(String[] args) { + new HelloWorldJNI().sayHello(); + } + + // Declare a native method sayHello() that receives no arguments and returns void + public native String sayHello(); +} diff --git a/jni/src/main/java/com/baeldung/jni/UserData.java b/jni/src/main/java/com/baeldung/jni/UserData.java new file mode 100644 index 0000000000..5b93f9dfb0 --- /dev/null +++ b/jni/src/main/java/com/baeldung/jni/UserData.java @@ -0,0 +1,11 @@ +package com.baeldung.jni; + +public class UserData { + + public String name; + public double balance; + + public String getUserInfo() { + return "[name]=" + name + ", [balance]=" + balance; + } +} diff --git a/jni/src/test/java/com/baeldung/jni/JNINativeTests.java b/jni/src/test/java/com/baeldung/jni/JNINativeTests.java new file mode 100644 index 0000000000..42e572d41b --- /dev/null +++ b/jni/src/test/java/com/baeldung/jni/JNINativeTests.java @@ -0,0 +1,58 @@ +package com.baeldung.jni; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; + +public class JNINativeTests { + + @Before + public void setup() { + System.loadLibrary("native"); + } + + @Test + public void whenNativeHelloWorld_thenOutputIsAsExpected() { + HelloWorldJNI helloWorld = new HelloWorldJNI(); + String helloFromNative = helloWorld.sayHello(); + assertTrue(!helloFromNative.isEmpty() && helloFromNative.equals("Hello from C++ !!")); + } + + @Test + public void whenSumNative_thenResultIsArithmeticallyCorrect() { + ExampleParametersJNI parametersNativeMethods = new ExampleParametersJNI(); + assertTrue(parametersNativeMethods.sumIntegers(200, 400) == 600L); + } + + @Test + public void whenSayingNativeHelloToMe_thenResultIsAsExpected() { + ExampleParametersJNI parametersNativeMethods = new ExampleParametersJNI(); + assertEquals(parametersNativeMethods.sayHelloToMe("Orange", true), "Ms. Orange"); + } + + @Test + public void whenCreatingNativeObject_thenObjectIsNotNullAndHasCorrectData() { + String name = "Iker Casillas"; + double balance = 2378.78; + ExampleObjectsJNI objectsNativeMethods = new ExampleObjectsJNI(); + UserData userFromNative = objectsNativeMethods.createUser(name, balance); + assertNotNull(userFromNative); + assertEquals(userFromNative.name, name); + assertTrue(userFromNative.balance == balance); + } + + @Test + public void whenNativeCallingObjectMethod_thenResultIsAsExpected() { + String name = "Sergio Ramos"; + double balance = 666.77; + ExampleObjectsJNI objectsNativeMethods = new ExampleObjectsJNI(); + UserData userData = new UserData(); + userData.name = name; + userData.balance = balance; + assertEquals(objectsNativeMethods.printUserData(userData), "[name]=" + name + ", [balance]=" + balance); + } + +} From 8087dad2b2453c6f0b3a44ddc74be4f3ff255d61 Mon Sep 17 00:00:00 2001 From: Eric Goebelbecker Date: Tue, 15 May 2018 22:43:01 -0400 Subject: [PATCH 77/93] BAEL-1787 - using Lombok @Builder on methods (#4256) * BAEL-1787 - using Lombok @Builder on methods * BAEL-1787 - rename class. Add AssertJ to Lombok project. * BAEL-1787 - rename class again. Change AssertJ tests. --- lombok/pom.xml | 7 +++++++ .../baeldung/lombok/intro/ClientBuilder.java | 11 +++++++++++ .../baeldung/lombok/intro/ImmutableClient.java | 11 +++++++++++ .../lombok/intro/BuilderMethodUnitTest.java | 18 ++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 lombok/src/main/java/com/baeldung/lombok/intro/ClientBuilder.java create mode 100644 lombok/src/main/java/com/baeldung/lombok/intro/ImmutableClient.java create mode 100644 lombok/src/test/java/com/baeldung/lombok/intro/BuilderMethodUnitTest.java diff --git a/lombok/pom.xml b/lombok/pom.xml index d11cffb34b..e0b0426c58 100644 --- a/lombok/pom.xml +++ b/lombok/pom.xml @@ -27,6 +27,12 @@ hibernate-jpa-2.1-api ${hibernate-jpa-2.1-api.version} + + org.assertj + assertj-core + ${assertj-core.version} + test + @@ -76,6 +82,7 @@ 1.0.0.Final 1.16.10.0 + 3.8.0 diff --git a/lombok/src/main/java/com/baeldung/lombok/intro/ClientBuilder.java b/lombok/src/main/java/com/baeldung/lombok/intro/ClientBuilder.java new file mode 100644 index 0000000000..e7851760c5 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/intro/ClientBuilder.java @@ -0,0 +1,11 @@ +package com.baeldung.lombok.intro; + +import lombok.Builder; + +class ClientBuilder { + + @Builder(builderMethodName = "builder") + public static ImmutableClient newClient(int id, String name) { + return new ImmutableClient(id, name); + } +} diff --git a/lombok/src/main/java/com/baeldung/lombok/intro/ImmutableClient.java b/lombok/src/main/java/com/baeldung/lombok/intro/ImmutableClient.java new file mode 100644 index 0000000000..86be75ecd0 --- /dev/null +++ b/lombok/src/main/java/com/baeldung/lombok/intro/ImmutableClient.java @@ -0,0 +1,11 @@ +package com.baeldung.lombok.intro; + +import lombok.Value; + +@Value +final class ImmutableClient { + + private int id; + private String name; + +} diff --git a/lombok/src/test/java/com/baeldung/lombok/intro/BuilderMethodUnitTest.java b/lombok/src/test/java/com/baeldung/lombok/intro/BuilderMethodUnitTest.java new file mode 100644 index 0000000000..52ecc49c45 --- /dev/null +++ b/lombok/src/test/java/com/baeldung/lombok/intro/BuilderMethodUnitTest.java @@ -0,0 +1,18 @@ +package com.baeldung.lombok.intro; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.*; + +public class BuilderMethodUnitTest +{ + + @Test + public void givenBuilderMethod_ClientIsBuilt() { + ImmutableClient testImmutableClient = ClientBuilder.builder().name("foo").id(1).build(); + assertThat(testImmutableClient.getName()) + .isEqualTo("foo"); + assertThat(testImmutableClient.getId()) + .isEqualTo(1); + } +} From 344c94d60ae5e5cca643b4bdf7486931dc0a48c4 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Wed, 16 May 2018 09:56:19 +0530 Subject: [PATCH 78/93] Bael 6513 (#4257) * Added parent module on poms that have no parent defined * Removed dependency reduced pom from undertow module * [BAEL-6513] - Remove nested module --- spring-custom-aop/{spring-custom-aop => }/.gitignore | 0 spring-custom-aop/{spring-custom-aop => }/README.MD | 0 spring-custom-aop/{spring-custom-aop => }/pom.xml | 2 +- .../annotation/servletcomponentscan/SpringBootAnnotatedApp.java | 0 .../annotation/servletcomponentscan/SpringBootPlainApp.java | 0 .../servletcomponentscan/components/AttrListener.java | 0 .../annotation/servletcomponentscan/components/EchoServlet.java | 0 .../annotation/servletcomponentscan/components/HelloFilter.java | 0 .../servletcomponentscan/components/HelloServlet.java | 0 .../src/main/java/com/baeldung/git/CommitIdApplication.java | 0 .../src/main/java/com/baeldung/git/CommitInfoController.java | 0 .../src/main/java/com/baeldung/git/README.md | 0 .../baeldung/internationalization/InternationalizationApp.java | 0 .../com/baeldung/internationalization/config/MvcConfig.java | 0 .../baeldung/internationalization/config/PageController.java | 0 .../src/main/java/com/baeldung/intro/App.java | 0 .../main/java/com/baeldung/intro/controller/HomeController.java | 0 .../src/main/java/com/baeldung/servlets/ApplicationMain.java | 0 .../com/baeldung/servlets/configuration/WebAppInitializer.java | 0 .../com/baeldung/servlets/configuration/WebMvcConfigure.java | 0 .../src/main/java/com/baeldung/servlets/props/Constants.java | 0 .../main/java/com/baeldung/servlets/props/PropertyLoader.java | 0 .../java/com/baeldung/servlets/props/PropertySourcesLoader.java | 0 .../com/baeldung/servlets/servlets/GenericCustomServlet.java | 0 .../baeldung/servlets/servlets/javaee/AnnotationServlet.java | 0 .../com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java | 0 .../servlets/springboot/SpringRegistrationBeanServlet.java | 0 .../servlets/springboot/embedded/EmbeddedTomcatExample.java | 0 .../src/main/java/com/baeldung/utils/Application.java | 0 .../java/com/baeldung/utils/controller/UtilsController.java | 0 .../src/main/java/com/baeldung/webjar/TestController.java | 0 .../main/java/com/baeldung/webjar/WebjarsdemoApplication.java | 0 .../src/main/java/org/baeldung/Application.java | 0 .../src/main/java/org/baeldung/boot/DemoApplication.java | 0 .../src/main/java/org/baeldung/boot/components/FooService.java | 0 .../main/java/org/baeldung/boot/exceptions/CommonException.java | 0 .../java/org/baeldung/boot/exceptions/FooNotFoundException.java | 0 .../src/main/java/org/baeldung/boot/model/Foo.java | 0 .../main/java/org/baeldung/boot/repository/FooRepository.java | 0 .../src/main/java/org/baeldung/boot/service/FooController.java | 0 .../src/main/java/org/baeldung/client/Details.java | 0 .../src/main/java/org/baeldung/client/DetailsServiceClient.java | 0 .../java/org/baeldung/common/error/MyCustomErrorController.java | 0 .../common/error/SpringHelloServletRegistrationBean.java | 0 .../org/baeldung/common/error/controller/ErrorController.java | 0 .../common/properties/MyServletContainerCustomizationBean.java | 0 .../common/resources/ExecutorServiceExitCodeGenerator.java | 0 .../src/main/java/org/baeldung/config/WebConfig.java | 0 .../java/org/baeldung/controller/GenericEntityController.java | 0 .../java/org/baeldung/controller/servlet/HelloWorldServlet.java | 0 .../baeldung/controller/servlet/SpringHelloWorldServlet.java | 0 .../org/baeldung/converter/StringToEnumConverterFactory.java | 0 .../org/baeldung/converter/StringToLocalDateTimeConverter.java | 0 .../src/main/java/org/baeldung/domain/GenericEntity.java | 0 .../src/main/java/org/baeldung/domain/Modes.java | 0 .../src/main/java/org/baeldung/endpoints/CustomEndpoint.java | 0 .../src/main/java/org/baeldung/endpoints/EndpointDTO.java | 0 .../src/main/java/org/baeldung/endpoints/ListEndpoints.java | 0 .../src/main/java/org/baeldung/endpoints/MyHealthCheck.java | 0 .../src/main/java/org/baeldung/main/SpringBootApplication.java | 0 .../main/java/org/baeldung/monitor/jmx/MonitoringConfig.java | 0 .../java/org/baeldung/repository/GenericEntityRepository.java | 0 .../src/main/java/org/baeldung/service/LoginService.java | 0 .../src/main/java/org/baeldung/service/LoginServiceImpl.java | 0 .../main/java/org/baeldung/session/exception/Application.java | 0 .../baeldung/session/exception/repository/FooRepository.java | 0 .../session/exception/repository/FooRepositoryImpl.java | 0 .../baeldung/web/resolver/HeaderVersionArgumentResolver.java | 0 .../src/main/java/org/baeldung/web/resolver/Version.java | 0 .../src/main/resources/application.properties | 0 .../{spring-custom-aop => }/src/main/resources/banner.txt | 0 .../src/main/resources/custom.properties | 0 .../{spring-custom-aop => }/src/main/resources/demo.properties | 0 .../{spring-custom-aop => }/src/main/resources/logback.xml | 0 .../src/main/resources/messages.properties | 0 .../src/main/resources/messages_fr.properties | 0 .../src/main/resources/public/error/404.html | 0 .../src/main/resources/templates/index.html | 0 .../src/main/resources/templates/international.html | 0 .../src/main/resources/templates/other.html | 0 .../src/main/resources/templates/utils.html | 0 .../{spring-custom-aop => }/src/main/webapp/WEB-INF/context.xml | 0 .../src/main/webapp/WEB-INF/dispatcher.xml | 0 .../{spring-custom-aop => }/src/main/webapp/WEB-INF/web.xml | 0 .../src/main/webapp/annotationservlet.jsp | 0 .../{spring-custom-aop => }/src/main/webapp/index.jsp | 0 .../SpringBootWithServletComponentIntegrationTest.java | 0 .../SpringBootWithoutServletComponentIntegrationTest.java | 0 .../src/test/java/com/baeldung/git/CommitIdIntegrationTest.java | 0 .../src/test/java/com/baeldung/intro/AppLiveTest.java | 0 .../java/com/baeldung/utils/UtilsControllerIntegrationTest.java | 0 .../baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java | 0 .../java/org/baeldung/SpringBootApplicationIntegrationTest.java | 0 .../test/java/org/baeldung/SpringBootJPAIntegrationTest.java | 0 .../test/java/org/baeldung/SpringBootMailIntegrationTest.java | 0 .../test/java/org/baeldung/boot/ApplicationIntegrationTest.java | 0 .../java/org/baeldung/boot/DemoApplicationIntegrationTest.java | 0 .../java/org/baeldung/boot/FooComponentIntegrationTest.java | 0 .../src/test/java/org/baeldung/boot/FooIntegrationTest.java | 0 .../src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java | 0 .../src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java | 0 .../baeldung/boot/repository/FooRepositoryIntegrationTest.java | 0 .../boot/repository/HibernateSessionIntegrationTest.java | 0 .../boot/repository/NoHibernateSessionIntegrationTest.java | 0 .../baeldung/client/DetailsServiceClientIntegrationTest.java | 0 .../src/test/resources/application.properties | 0 .../src/test/resources/exception-hibernate.properties | 0 .../src/test/resources/exception.properties | 0 .../{spring-custom-aop => }/src/test/resources/import.sql | 0 .../src/test/resources/org/baeldung/boot/expected.json | 0 110 files changed, 1 insertion(+), 1 deletion(-) rename spring-custom-aop/{spring-custom-aop => }/.gitignore (100%) rename spring-custom-aop/{spring-custom-aop => }/README.MD (100%) rename spring-custom-aop/{spring-custom-aop => }/pom.xml (98%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/git/CommitIdApplication.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/git/CommitInfoController.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/git/README.md (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/internationalization/InternationalizationApp.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/internationalization/config/MvcConfig.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/internationalization/config/PageController.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/intro/App.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/intro/controller/HomeController.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/ApplicationMain.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/props/Constants.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/props/PropertyLoader.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/utils/Application.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/utils/controller/UtilsController.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/webjar/TestController.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/Application.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/boot/DemoApplication.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/boot/components/FooService.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/boot/exceptions/CommonException.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/boot/model/Foo.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/boot/repository/FooRepository.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/boot/service/FooController.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/client/Details.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/client/DetailsServiceClient.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/common/error/MyCustomErrorController.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/common/error/controller/ErrorController.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/config/WebConfig.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/controller/GenericEntityController.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/domain/GenericEntity.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/domain/Modes.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/endpoints/CustomEndpoint.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/endpoints/EndpointDTO.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/endpoints/ListEndpoints.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/endpoints/MyHealthCheck.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/main/SpringBootApplication.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/repository/GenericEntityRepository.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/service/LoginService.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/service/LoginServiceImpl.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/session/exception/Application.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/session/exception/repository/FooRepository.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/java/org/baeldung/web/resolver/Version.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/application.properties (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/banner.txt (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/custom.properties (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/demo.properties (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/logback.xml (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/messages.properties (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/messages_fr.properties (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/public/error/404.html (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/templates/index.html (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/templates/international.html (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/templates/other.html (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/resources/templates/utils.html (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/webapp/WEB-INF/context.xml (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/webapp/WEB-INF/dispatcher.xml (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/webapp/WEB-INF/web.xml (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/webapp/annotationservlet.jsp (100%) rename spring-custom-aop/{spring-custom-aop => }/src/main/webapp/index.jsp (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/com/baeldung/intro/AppLiveTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/boot/FooComponentIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/boot/FooIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/resources/application.properties (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/resources/exception-hibernate.properties (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/resources/exception.properties (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/resources/import.sql (100%) rename spring-custom-aop/{spring-custom-aop => }/src/test/resources/org/baeldung/boot/expected.json (100%) diff --git a/spring-custom-aop/spring-custom-aop/.gitignore b/spring-custom-aop/.gitignore similarity index 100% rename from spring-custom-aop/spring-custom-aop/.gitignore rename to spring-custom-aop/.gitignore diff --git a/spring-custom-aop/spring-custom-aop/README.MD b/spring-custom-aop/README.MD similarity index 100% rename from spring-custom-aop/spring-custom-aop/README.MD rename to spring-custom-aop/README.MD diff --git a/spring-custom-aop/spring-custom-aop/pom.xml b/spring-custom-aop/pom.xml similarity index 98% rename from spring-custom-aop/spring-custom-aop/pom.xml rename to spring-custom-aop/pom.xml index a1e498f65d..76d8e7c344 100644 --- a/spring-custom-aop/spring-custom-aop/pom.xml +++ b/spring-custom-aop/pom.xml @@ -12,7 +12,7 @@ parent-boot-5 com.baeldung 0.0.1-SNAPSHOT - ../../parent-boot-5 + ../parent-boot-5 diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java b/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java rename to spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootAnnotatedApp.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java b/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java rename to spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/SpringBootPlainApp.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java b/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java rename to spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/AttrListener.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java b/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java rename to spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/EchoServlet.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java b/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java rename to spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloFilter.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java b/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java rename to spring-custom-aop/src/main/java/com/baeldung/annotation/servletcomponentscan/components/HelloServlet.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitIdApplication.java b/spring-custom-aop/src/main/java/com/baeldung/git/CommitIdApplication.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitIdApplication.java rename to spring-custom-aop/src/main/java/com/baeldung/git/CommitIdApplication.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitInfoController.java b/spring-custom-aop/src/main/java/com/baeldung/git/CommitInfoController.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/CommitInfoController.java rename to spring-custom-aop/src/main/java/com/baeldung/git/CommitInfoController.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/README.md b/spring-custom-aop/src/main/java/com/baeldung/git/README.md similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/git/README.md rename to spring-custom-aop/src/main/java/com/baeldung/git/README.md diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/InternationalizationApp.java b/spring-custom-aop/src/main/java/com/baeldung/internationalization/InternationalizationApp.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/InternationalizationApp.java rename to spring-custom-aop/src/main/java/com/baeldung/internationalization/InternationalizationApp.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/MvcConfig.java b/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/MvcConfig.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/MvcConfig.java rename to spring-custom-aop/src/main/java/com/baeldung/internationalization/config/MvcConfig.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/PageController.java b/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/PageController.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/internationalization/config/PageController.java rename to spring-custom-aop/src/main/java/com/baeldung/internationalization/config/PageController.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/App.java b/spring-custom-aop/src/main/java/com/baeldung/intro/App.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/App.java rename to spring-custom-aop/src/main/java/com/baeldung/intro/App.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java b/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java rename to spring-custom-aop/src/main/java/com/baeldung/intro/controller/HomeController.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/ApplicationMain.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/ApplicationMain.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/ApplicationMain.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/ApplicationMain.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebAppInitializer.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/configuration/WebMvcConfigure.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/Constants.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/props/Constants.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/Constants.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/props/Constants.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertyLoader.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertyLoader.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertyLoader.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertyLoader.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/props/PropertySourcesLoader.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/GenericCustomServlet.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/AnnotationServlet.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/javaee/EEWebXmlServlet.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/SpringRegistrationBeanServlet.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java b/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java rename to spring-custom-aop/src/main/java/com/baeldung/servlets/servlets/springboot/embedded/EmbeddedTomcatExample.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java b/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/Application.java rename to spring-custom-aop/src/main/java/com/baeldung/utils/Application.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java b/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java rename to spring-custom-aop/src/main/java/com/baeldung/utils/controller/UtilsController.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/TestController.java b/spring-custom-aop/src/main/java/com/baeldung/webjar/TestController.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/TestController.java rename to spring-custom-aop/src/main/java/com/baeldung/webjar/TestController.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java b/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java rename to spring-custom-aop/src/main/java/com/baeldung/webjar/WebjarsdemoApplication.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/Application.java b/spring-custom-aop/src/main/java/org/baeldung/Application.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/Application.java rename to spring-custom-aop/src/main/java/org/baeldung/Application.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/DemoApplication.java b/spring-custom-aop/src/main/java/org/baeldung/boot/DemoApplication.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/DemoApplication.java rename to spring-custom-aop/src/main/java/org/baeldung/boot/DemoApplication.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java b/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java rename to spring-custom-aop/src/main/java/org/baeldung/boot/components/FooService.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java b/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java rename to spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/CommonException.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java b/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java rename to spring-custom-aop/src/main/java/org/baeldung/boot/exceptions/FooNotFoundException.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java b/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java rename to spring-custom-aop/src/main/java/org/baeldung/boot/model/Foo.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/repository/FooRepository.java b/spring-custom-aop/src/main/java/org/baeldung/boot/repository/FooRepository.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/repository/FooRepository.java rename to spring-custom-aop/src/main/java/org/baeldung/boot/repository/FooRepository.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java b/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java rename to spring-custom-aop/src/main/java/org/baeldung/boot/service/FooController.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/Details.java b/spring-custom-aop/src/main/java/org/baeldung/client/Details.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/Details.java rename to spring-custom-aop/src/main/java/org/baeldung/client/Details.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/DetailsServiceClient.java b/spring-custom-aop/src/main/java/org/baeldung/client/DetailsServiceClient.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/client/DetailsServiceClient.java rename to spring-custom-aop/src/main/java/org/baeldung/client/DetailsServiceClient.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/MyCustomErrorController.java b/spring-custom-aop/src/main/java/org/baeldung/common/error/MyCustomErrorController.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/MyCustomErrorController.java rename to spring-custom-aop/src/main/java/org/baeldung/common/error/MyCustomErrorController.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java b/spring-custom-aop/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java rename to spring-custom-aop/src/main/java/org/baeldung/common/error/SpringHelloServletRegistrationBean.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/controller/ErrorController.java b/spring-custom-aop/src/main/java/org/baeldung/common/error/controller/ErrorController.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/error/controller/ErrorController.java rename to spring-custom-aop/src/main/java/org/baeldung/common/error/controller/ErrorController.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java b/spring-custom-aop/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java rename to spring-custom-aop/src/main/java/org/baeldung/common/properties/MyServletContainerCustomizationBean.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java b/spring-custom-aop/src/main/java/org/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java rename to spring-custom-aop/src/main/java/org/baeldung/common/resources/ExecutorServiceExitCodeGenerator.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/config/WebConfig.java b/spring-custom-aop/src/main/java/org/baeldung/config/WebConfig.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/config/WebConfig.java rename to spring-custom-aop/src/main/java/org/baeldung/config/WebConfig.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/GenericEntityController.java b/spring-custom-aop/src/main/java/org/baeldung/controller/GenericEntityController.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/GenericEntityController.java rename to spring-custom-aop/src/main/java/org/baeldung/controller/GenericEntityController.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java b/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java rename to spring-custom-aop/src/main/java/org/baeldung/controller/servlet/HelloWorldServlet.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java b/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java rename to spring-custom-aop/src/main/java/org/baeldung/controller/servlet/SpringHelloWorldServlet.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java b/spring-custom-aop/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java rename to spring-custom-aop/src/main/java/org/baeldung/converter/StringToEnumConverterFactory.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java b/spring-custom-aop/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java rename to spring-custom-aop/src/main/java/org/baeldung/converter/StringToLocalDateTimeConverter.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/GenericEntity.java b/spring-custom-aop/src/main/java/org/baeldung/domain/GenericEntity.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/GenericEntity.java rename to spring-custom-aop/src/main/java/org/baeldung/domain/GenericEntity.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/Modes.java b/spring-custom-aop/src/main/java/org/baeldung/domain/Modes.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/domain/Modes.java rename to spring-custom-aop/src/main/java/org/baeldung/domain/Modes.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/CustomEndpoint.java b/spring-custom-aop/src/main/java/org/baeldung/endpoints/CustomEndpoint.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/CustomEndpoint.java rename to spring-custom-aop/src/main/java/org/baeldung/endpoints/CustomEndpoint.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/EndpointDTO.java b/spring-custom-aop/src/main/java/org/baeldung/endpoints/EndpointDTO.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/EndpointDTO.java rename to spring-custom-aop/src/main/java/org/baeldung/endpoints/EndpointDTO.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java b/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java rename to spring-custom-aop/src/main/java/org/baeldung/endpoints/ListEndpoints.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/MyHealthCheck.java b/spring-custom-aop/src/main/java/org/baeldung/endpoints/MyHealthCheck.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/endpoints/MyHealthCheck.java rename to spring-custom-aop/src/main/java/org/baeldung/endpoints/MyHealthCheck.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/main/SpringBootApplication.java b/spring-custom-aop/src/main/java/org/baeldung/main/SpringBootApplication.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/main/SpringBootApplication.java rename to spring-custom-aop/src/main/java/org/baeldung/main/SpringBootApplication.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java b/spring-custom-aop/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java rename to spring-custom-aop/src/main/java/org/baeldung/monitor/jmx/MonitoringConfig.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/repository/GenericEntityRepository.java b/spring-custom-aop/src/main/java/org/baeldung/repository/GenericEntityRepository.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/repository/GenericEntityRepository.java rename to spring-custom-aop/src/main/java/org/baeldung/repository/GenericEntityRepository.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginService.java b/spring-custom-aop/src/main/java/org/baeldung/service/LoginService.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginService.java rename to spring-custom-aop/src/main/java/org/baeldung/service/LoginService.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginServiceImpl.java b/spring-custom-aop/src/main/java/org/baeldung/service/LoginServiceImpl.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/service/LoginServiceImpl.java rename to spring-custom-aop/src/main/java/org/baeldung/service/LoginServiceImpl.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/Application.java b/spring-custom-aop/src/main/java/org/baeldung/session/exception/Application.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/Application.java rename to spring-custom-aop/src/main/java/org/baeldung/session/exception/Application.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepository.java b/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepository.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepository.java rename to spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepository.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java b/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java rename to spring-custom-aop/src/main/java/org/baeldung/session/exception/repository/FooRepositoryImpl.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java b/spring-custom-aop/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java rename to spring-custom-aop/src/main/java/org/baeldung/web/resolver/HeaderVersionArgumentResolver.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/Version.java b/spring-custom-aop/src/main/java/org/baeldung/web/resolver/Version.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/java/org/baeldung/web/resolver/Version.java rename to spring-custom-aop/src/main/java/org/baeldung/web/resolver/Version.java diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/application.properties b/spring-custom-aop/src/main/resources/application.properties similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/application.properties rename to spring-custom-aop/src/main/resources/application.properties diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/banner.txt b/spring-custom-aop/src/main/resources/banner.txt similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/banner.txt rename to spring-custom-aop/src/main/resources/banner.txt diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/custom.properties b/spring-custom-aop/src/main/resources/custom.properties similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/custom.properties rename to spring-custom-aop/src/main/resources/custom.properties diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/demo.properties b/spring-custom-aop/src/main/resources/demo.properties similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/demo.properties rename to spring-custom-aop/src/main/resources/demo.properties diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/logback.xml b/spring-custom-aop/src/main/resources/logback.xml similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/logback.xml rename to spring-custom-aop/src/main/resources/logback.xml diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/messages.properties b/spring-custom-aop/src/main/resources/messages.properties similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/messages.properties rename to spring-custom-aop/src/main/resources/messages.properties diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/messages_fr.properties b/spring-custom-aop/src/main/resources/messages_fr.properties similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/messages_fr.properties rename to spring-custom-aop/src/main/resources/messages_fr.properties diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/public/error/404.html b/spring-custom-aop/src/main/resources/public/error/404.html similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/public/error/404.html rename to spring-custom-aop/src/main/resources/public/error/404.html diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/templates/index.html b/spring-custom-aop/src/main/resources/templates/index.html similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/templates/index.html rename to spring-custom-aop/src/main/resources/templates/index.html diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/templates/international.html b/spring-custom-aop/src/main/resources/templates/international.html similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/templates/international.html rename to spring-custom-aop/src/main/resources/templates/international.html diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/templates/other.html b/spring-custom-aop/src/main/resources/templates/other.html similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/templates/other.html rename to spring-custom-aop/src/main/resources/templates/other.html diff --git a/spring-custom-aop/spring-custom-aop/src/main/resources/templates/utils.html b/spring-custom-aop/src/main/resources/templates/utils.html similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/resources/templates/utils.html rename to spring-custom-aop/src/main/resources/templates/utils.html diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/context.xml b/spring-custom-aop/src/main/webapp/WEB-INF/context.xml similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/context.xml rename to spring-custom-aop/src/main/webapp/WEB-INF/context.xml diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/dispatcher.xml b/spring-custom-aop/src/main/webapp/WEB-INF/dispatcher.xml similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/dispatcher.xml rename to spring-custom-aop/src/main/webapp/WEB-INF/dispatcher.xml diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/web.xml b/spring-custom-aop/src/main/webapp/WEB-INF/web.xml similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/webapp/WEB-INF/web.xml rename to spring-custom-aop/src/main/webapp/WEB-INF/web.xml diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/annotationservlet.jsp b/spring-custom-aop/src/main/webapp/annotationservlet.jsp similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/webapp/annotationservlet.jsp rename to spring-custom-aop/src/main/webapp/annotationservlet.jsp diff --git a/spring-custom-aop/spring-custom-aop/src/main/webapp/index.jsp b/spring-custom-aop/src/main/webapp/index.jsp similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/main/webapp/index.jsp rename to spring-custom-aop/src/main/webapp/index.jsp diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java b/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java rename to spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java b/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java rename to spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java b/spring-custom-aop/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java rename to spring-custom-aop/src/test/java/com/baeldung/git/CommitIdIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java b/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java rename to spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java b/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java rename to spring-custom-aop/src/test/java/com/baeldung/utils/UtilsControllerIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java b/spring-custom-aop/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java rename to spring-custom-aop/src/test/java/com/baeldung/webjar/WebjarsdemoApplicationIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/SpringBootApplicationIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/SpringBootJPAIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/SpringBootMailIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/boot/ApplicationIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/boot/DemoApplicationIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/boot/FooComponentIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/boot/FooIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/boot/FooJPAIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/boot/FooJsonIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/boot/repository/FooRepositoryIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/boot/repository/HibernateSessionIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/boot/repository/NoHibernateSessionIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java b/spring-custom-aop/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java rename to spring-custom-aop/src/test/java/org/baeldung/client/DetailsServiceClientIntegrationTest.java diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/application.properties b/spring-custom-aop/src/test/resources/application.properties similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/resources/application.properties rename to spring-custom-aop/src/test/resources/application.properties diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/exception-hibernate.properties b/spring-custom-aop/src/test/resources/exception-hibernate.properties similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/resources/exception-hibernate.properties rename to spring-custom-aop/src/test/resources/exception-hibernate.properties diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/exception.properties b/spring-custom-aop/src/test/resources/exception.properties similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/resources/exception.properties rename to spring-custom-aop/src/test/resources/exception.properties diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/import.sql b/spring-custom-aop/src/test/resources/import.sql similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/resources/import.sql rename to spring-custom-aop/src/test/resources/import.sql diff --git a/spring-custom-aop/spring-custom-aop/src/test/resources/org/baeldung/boot/expected.json b/spring-custom-aop/src/test/resources/org/baeldung/boot/expected.json similarity index 100% rename from spring-custom-aop/spring-custom-aop/src/test/resources/org/baeldung/boot/expected.json rename to spring-custom-aop/src/test/resources/org/baeldung/boot/expected.json From bd9f672239c4e68be8a67fc7183bdad1dc6dee71 Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 17 May 2018 13:12:44 +0200 Subject: [PATCH 79/93] fix spring hateoas --- .../web/controller/CustomerController.java | 39 ++++++++++++------- .../web/service/OrderServiceImpl.java | 12 ++---- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java b/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java index 532e6b4d3a..1ca82b8483 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java +++ b/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java @@ -1,23 +1,27 @@ package org.baeldung.web.controller; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; + +import java.util.List; + import org.baeldung.persistence.model.Customer; import org.baeldung.persistence.model.Order; import org.baeldung.web.service.CustomerService; import org.baeldung.web.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.hateoas.Link; +import org.springframework.hateoas.Resources; +import org.springframework.hateoas.config.EnableHypermediaSupport; +import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - -import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; -import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; - @RestController @RequestMapping(value = "/customers") +@EnableHypermediaSupport(type = HypermediaType.HAL) public class CustomerController { @Autowired private CustomerService customerService; @@ -30,36 +34,41 @@ public class CustomerController { return customerService.getCustomerDetail(customerId); } - @RequestMapping(value = "/{customerId}/{orderId}", method = RequestMethod.GET) + @RequestMapping(value = "/{customerId}/{orderId}") public Order getOrderById(@PathVariable final String customerId, @PathVariable final String orderId) { return orderService.getOrderByIdForCustomer(customerId, orderId); } - @RequestMapping(value = "/{customerId}/orders", method = RequestMethod.GET) - public List getOrdersForCustomer(@PathVariable final String customerId) { + @RequestMapping(value = "/{customerId}/orders", method = RequestMethod.GET , produces = {"application/hal+json"}) + public Resources getOrdersForCustomer(@PathVariable final String customerId) { final List orders = orderService.getAllOrdersForCustomer(customerId); for (final Order order : orders) { final Link selfLink = linkTo(methodOn(CustomerController.class).getOrderById(customerId, order.getOrderId())).withSelfRel(); order.add(selfLink); } - return orders; + + Link link =linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customerId)).withSelfRel(); + Resources result = new Resources(orders,link); + return result; } - @RequestMapping(method = RequestMethod.GET) - public List getAllCustomers() { + @RequestMapping(method = RequestMethod.GET, produces = {"application/hal+json"}) + public Resources getAllCustomers() { final List allCustomers = customerService.allCustomers(); + for (final Customer customer : allCustomers) { String customerId = customer.getCustomerId(); Link selfLink = linkTo(CustomerController.class).slash(customerId).withSelfRel(); customer.add(selfLink); if (orderService.getAllOrdersForCustomer(customerId).size() > 0) { - List methodLinkBuilder = methodOn(CustomerController.class).getOrdersForCustomer(customerId); - final Link ordersLink = linkTo(methodLinkBuilder).withRel("allOrders"); + final Link ordersLink = linkTo(methodOn(CustomerController.class).getOrdersForCustomer(customerId)).withRel("allOrders"); customer.add(ordersLink); } - } - return allCustomers; + + Link link =linkTo(CustomerController.class).withSelfRel(); + Resources result = new Resources(allCustomers,link); + return result; } } diff --git a/spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java b/spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java index 1b8e7b0dde..0a6d4708a1 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java +++ b/spring-security-rest/src/main/java/org/baeldung/web/service/OrderServiceImpl.java @@ -3,6 +3,7 @@ package org.baeldung.web.service; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; import org.baeldung.persistence.model.Customer; import org.baeldung.persistence.model.Order; @@ -49,16 +50,9 @@ public class OrderServiceImpl implements OrderService { @Override public Order getOrderByIdForCustomer(final String customerId, final String orderId) { - - final List orders = (List) customerMap.get(customerId).getOrders().values(); - Order selectedOrder = null; - for (final Order order : orders) { - if (order.getId().equals(orderId)) { - selectedOrder = order; - } - } + final Map orders = customerMap.get(customerId).getOrders(); + Order selectedOrder = orders.get(orderId); return selectedOrder; - } } From 70cc4ba459e0b825abb7bb7b52af413840a171ca Mon Sep 17 00:00:00 2001 From: DOHA Date: Thu, 17 May 2018 13:20:43 +0200 Subject: [PATCH 80/93] minor fix --- .../java/org/baeldung/web/controller/CustomerController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java b/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java index 1ca82b8483..b8f67960f5 100644 --- a/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java +++ b/spring-security-rest/src/main/java/org/baeldung/web/controller/CustomerController.java @@ -34,7 +34,7 @@ public class CustomerController { return customerService.getCustomerDetail(customerId); } - @RequestMapping(value = "/{customerId}/{orderId}") + @RequestMapping(value = "/{customerId}/{orderId}", method = RequestMethod.GET) public Order getOrderById(@PathVariable final String customerId, @PathVariable final String orderId) { return orderService.getOrderByIdForCustomer(customerId, orderId); } From 1e3b3f27a41b763f2d37a4566a360090d014125a Mon Sep 17 00:00:00 2001 From: Gangadharan Khoteeswarun Date: Fri, 18 May 2018 05:34:04 +0800 Subject: [PATCH 81/93] Spring Boot and Jasypt Code (#4142) * Spring Boot and Jasypt Code * Tabs to Spaces in POM * Removed unnecessary files * Formatted Pom --- spring-boot-jasypt/.gitignore | 25 ++++++++ spring-boot-jasypt/pom.xml | 60 +++++++++++++++++++ .../main/java/com/baeldung/jasypt/Main.java | 35 +++++++++++ .../simple/AppConfigForJasyptSimple.java | 10 ++++ .../PropertyServiceForJasyptSimple.java | 15 +++++ .../starter/AppConfigForJasyptStarter.java | 9 +++ .../PropertyServiceForJasyptStarter.java | 20 +++++++ .../src/main/resources/application.properties | 3 + .../src/main/resources/encrypted.properties | 1 + .../src/main/resources/encryptedv2.properties | 1 + .../com/baeldung/jasypt/CustomJasyptTest.java | 27 +++++++++ .../com/baeldung/jasypt/JasyptSimpleTest.java | 28 +++++++++ .../jasypt/JasyptWithStarterTest.java | 30 ++++++++++ 13 files changed, 264 insertions(+) create mode 100644 spring-boot-jasypt/.gitignore create mode 100644 spring-boot-jasypt/pom.xml create mode 100644 spring-boot-jasypt/src/main/java/com/baeldung/jasypt/Main.java create mode 100644 spring-boot-jasypt/src/main/java/com/baeldung/jasypt/simple/AppConfigForJasyptSimple.java create mode 100644 spring-boot-jasypt/src/main/java/com/baeldung/jasypt/simple/PropertyServiceForJasyptSimple.java create mode 100644 spring-boot-jasypt/src/main/java/com/baeldung/jasypt/starter/AppConfigForJasyptStarter.java create mode 100644 spring-boot-jasypt/src/main/java/com/baeldung/jasypt/starter/PropertyServiceForJasyptStarter.java create mode 100644 spring-boot-jasypt/src/main/resources/application.properties create mode 100644 spring-boot-jasypt/src/main/resources/encrypted.properties create mode 100644 spring-boot-jasypt/src/main/resources/encryptedv2.properties create mode 100644 spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java create mode 100644 spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java create mode 100644 spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java diff --git a/spring-boot-jasypt/.gitignore b/spring-boot-jasypt/.gitignore new file mode 100644 index 0000000000..82eca336e3 --- /dev/null +++ b/spring-boot-jasypt/.gitignore @@ -0,0 +1,25 @@ +/target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/build/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ \ No newline at end of file diff --git a/spring-boot-jasypt/pom.xml b/spring-boot-jasypt/pom.xml new file mode 100644 index 0000000000..e094f0b061 --- /dev/null +++ b/spring-boot-jasypt/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + com.example.jasypt + JasyptDemo + 0.0.1-SNAPSHOT + jar + + JasyptDemo + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 2.0.1.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + com.github.ulisesbocchio + jasypt-spring-boot-starter + 2.0.0 + + + + com.github.ulisesbocchio + jasypt-spring-boot + 2.0.0 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/Main.java b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/Main.java new file mode 100644 index 0000000000..0cdb5d4f1b --- /dev/null +++ b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/Main.java @@ -0,0 +1,35 @@ +package com.baeldung.jasypt; + +import org.jasypt.encryption.StringEncryptor; +import org.jasypt.encryption.pbe.PooledPBEStringEncryptor; +import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; + +@SpringBootApplication +@ComponentScan(basePackages = { "com.baeldung.jasypt" }) +@EnableEncryptableProperties +public class Main { + public static void main(String[] args) { + new SpringApplicationBuilder().sources(Main.class).run(args); + } + + @Bean(name = "encryptorBean") + public StringEncryptor stringEncryptor() { + PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); + SimpleStringPBEConfig config = new SimpleStringPBEConfig(); + config.setPassword("password"); + config.setAlgorithm("PBEWithMD5AndDES"); + config.setKeyObtentionIterations("1000"); + config.setPoolSize("1"); + config.setProviderName("SunJCE"); + config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); + config.setStringOutputType("base64"); + encryptor.setConfig(config); + return encryptor; + } +} diff --git a/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/simple/AppConfigForJasyptSimple.java b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/simple/AppConfigForJasyptSimple.java new file mode 100644 index 0000000000..41681cb8ca --- /dev/null +++ b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/simple/AppConfigForJasyptSimple.java @@ -0,0 +1,10 @@ +package com.baeldung.jasypt.simple; + +import org.springframework.context.annotation.Configuration; + +import com.ulisesbocchio.jasyptspringboot.annotation.EncryptablePropertySource; + +@Configuration +@EncryptablePropertySource(value = "encryptedv2.properties") +public class AppConfigForJasyptSimple { +} diff --git a/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/simple/PropertyServiceForJasyptSimple.java b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/simple/PropertyServiceForJasyptSimple.java new file mode 100644 index 0000000000..def4808b8e --- /dev/null +++ b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/simple/PropertyServiceForJasyptSimple.java @@ -0,0 +1,15 @@ +package com.baeldung.jasypt.simple; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +public class PropertyServiceForJasyptSimple { + + @Value("${encryptedv2.property}") + private String property; + + public String getProperty() { + return property; + } +} diff --git a/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/starter/AppConfigForJasyptStarter.java b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/starter/AppConfigForJasyptStarter.java new file mode 100644 index 0000000000..4db90ed5dc --- /dev/null +++ b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/starter/AppConfigForJasyptStarter.java @@ -0,0 +1,9 @@ +package com.baeldung.jasypt.starter; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@PropertySource(value = "encrypted.properties") +public class AppConfigForJasyptStarter { +} diff --git a/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/starter/PropertyServiceForJasyptStarter.java b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/starter/PropertyServiceForJasyptStarter.java new file mode 100644 index 0000000000..725720ebff --- /dev/null +++ b/spring-boot-jasypt/src/main/java/com/baeldung/jasypt/starter/PropertyServiceForJasyptStarter.java @@ -0,0 +1,20 @@ +package com.baeldung.jasypt.starter; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; + +@Service +public class PropertyServiceForJasyptStarter { + + @Value("${encrypted.property}") + private String property; + + public String getProperty() { + return property; + } + + public String getPasswordUsingEnvironment(Environment environment) { + return environment.getProperty("encrypted.property"); + } +} diff --git a/spring-boot-jasypt/src/main/resources/application.properties b/spring-boot-jasypt/src/main/resources/application.properties new file mode 100644 index 0000000000..ea61c4d846 --- /dev/null +++ b/spring-boot-jasypt/src/main/resources/application.properties @@ -0,0 +1,3 @@ +jasypt.encryptor.bean=encryptorBean +encryptedv3.property=ENC(askygdq8PHapYFnlX6WsTwZZOxWInq+i) + diff --git a/spring-boot-jasypt/src/main/resources/encrypted.properties b/spring-boot-jasypt/src/main/resources/encrypted.properties new file mode 100644 index 0000000000..0188fc392c --- /dev/null +++ b/spring-boot-jasypt/src/main/resources/encrypted.properties @@ -0,0 +1 @@ +encrypted.property=ENC(uTSqb9grs1+vUv3iN8lItC0kl65lMG+8) \ No newline at end of file diff --git a/spring-boot-jasypt/src/main/resources/encryptedv2.properties b/spring-boot-jasypt/src/main/resources/encryptedv2.properties new file mode 100644 index 0000000000..6785149718 --- /dev/null +++ b/spring-boot-jasypt/src/main/resources/encryptedv2.properties @@ -0,0 +1 @@ +encryptedv2.property=ENC(dQWokHUXXFe+OqXRZYWu22BpXoRZ0Drt) diff --git a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java new file mode 100644 index 0000000000..58c2dc7bb2 --- /dev/null +++ b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/CustomJasyptTest.java @@ -0,0 +1,27 @@ +package com.baeldung.jasypt; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.core.env.Environment; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.jasypt.Main; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {Main.class}) +public class CustomJasyptTest { + + @Autowired + ApplicationContext appCtx; + + @Test + public void whenConfiguredExcryptorUsed_ReturnCustomEncryptor() { + Environment environment = appCtx.getBean(Environment.class); + assertEquals("Password@3", environment.getProperty("encryptedv3.property")); + } +} diff --git a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java new file mode 100644 index 0000000000..f9b66b5044 --- /dev/null +++ b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptSimpleTest.java @@ -0,0 +1,28 @@ +package com.baeldung.jasypt; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.jasypt.simple.PropertyServiceForJasyptSimple; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class JasyptSimpleTest { + + @Autowired + ApplicationContext appCtx; + + @Test + public void whenDecryptedPasswordNeeded_GetFromService() { + System.setProperty("jasypt.encryptor.password", "password"); + PropertyServiceForJasyptSimple service = appCtx.getBean(PropertyServiceForJasyptSimple.class); + assertEquals("Password@2", service.getProperty()); + } + +} diff --git a/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java new file mode 100644 index 0000000000..d246c21036 --- /dev/null +++ b/spring-boot-jasypt/src/test/java/com/baeldung/jasypt/JasyptWithStarterTest.java @@ -0,0 +1,30 @@ +package com.baeldung.jasypt; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.core.env.Environment; +import org.springframework.test.context.junit4.SpringRunner; + +import com.baeldung.jasypt.starter.PropertyServiceForJasyptStarter; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class JasyptWithStarterTest { + + @Autowired + ApplicationContext appCtx; + + @Test + public void whenDecryptedPasswordNeeded_GetFromService() { + System.setProperty("jasypt.encryptor.password", "password"); + PropertyServiceForJasyptStarter service = appCtx.getBean(PropertyServiceForJasyptStarter.class); + assertEquals("Password@1", service.getProperty()); + Environment environment = appCtx.getBean(Environment.class); + assertEquals("Password@1", service.getPasswordUsingEnvironment(environment)); + } +} From 488b4492533ab1957f5a20301f8bfc4a84eb81b8 Mon Sep 17 00:00:00 2001 From: Tino Mulanchira Thomas <38363530+tinomthomas@users.noreply.github.com> Date: Fri, 18 May 2018 10:34:22 +0300 Subject: [PATCH 82/93] BAEL 1756 (#4263) - Review comments incorporated --- .../interceptors/RestTemplateLoggingInterceptor.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/spring-rest/src/main/java/org/baeldung/interceptors/RestTemplateLoggingInterceptor.java b/spring-rest/src/main/java/org/baeldung/interceptors/RestTemplateLoggingInterceptor.java index 56de3d04b8..03a9cdc806 100644 --- a/spring-rest/src/main/java/org/baeldung/interceptors/RestTemplateLoggingInterceptor.java +++ b/spring-rest/src/main/java/org/baeldung/interceptors/RestTemplateLoggingInterceptor.java @@ -22,20 +22,18 @@ public class RestTemplateLoggingInterceptor implements ClientHttpRequestIntercep } private void logRequest(byte[] body) { - String payLoad = StringUtils.EMPTY; if (body.length > 0) { - payLoad = new String(body, StandardCharsets.UTF_8); + String payLoad = new String(body, StandardCharsets.UTF_8); + System.out.println(payLoad); } - System.out.println("Request Body > " + payLoad); } private void logResponse(ClientHttpResponse response) throws IOException { - String payLoad = StringUtils.EMPTY; long contentLength = response.getHeaders() .getContentLength(); if (contentLength != 0) { - payLoad = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8); + String payLoad = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8); + System.out.println(payLoad); } - System.out.println("Response Body > " + payLoad); } } From 70cac0f309f2641ca23acdeb069ae076ece0f65d Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Fri, 18 May 2018 05:36:00 -0600 Subject: [PATCH 83/93] New PR for BAEL-1745 (just Twilio code) --- twilio/pom.xml | 24 +++++++++++++ twilio/src/main/java/TwilioSmsExample.java | 22 ++++++++++++ .../src/main/java/TwilioSmsMediaExample.java | 27 +++++++++++++++ .../java/TwilioSmsStatusAsyncExample.java | 34 +++++++++++++++++++ .../src/main/java/TwilioSmsStatusExample.java | 22 ++++++++++++ 5 files changed, 129 insertions(+) create mode 100644 twilio/pom.xml create mode 100644 twilio/src/main/java/TwilioSmsExample.java create mode 100644 twilio/src/main/java/TwilioSmsMediaExample.java create mode 100644 twilio/src/main/java/TwilioSmsStatusAsyncExample.java create mode 100644 twilio/src/main/java/TwilioSmsStatusExample.java diff --git a/twilio/pom.xml b/twilio/pom.xml new file mode 100644 index 0000000000..13187cfb07 --- /dev/null +++ b/twilio/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + com.baeldung.sms + twilio + 1.0-SNAPSHOT + + + 1.8 + 1.8 + + + + + com.twilio.sdk + twilio + 7.20.0 + + + + diff --git a/twilio/src/main/java/TwilioSmsExample.java b/twilio/src/main/java/TwilioSmsExample.java new file mode 100644 index 0000000000..cf8c162223 --- /dev/null +++ b/twilio/src/main/java/TwilioSmsExample.java @@ -0,0 +1,22 @@ +import com.twilio.Twilio; +import com.twilio.rest.api.v2010.account.Message; +import com.twilio.type.PhoneNumber; + +public class TwilioSmsExample { + // Find your Account Sid and Token at twilio.com/console + public static final String ACCOUNT_SID = "SID"; + public static final String AUTH_TOKEN = "AUTH"; + + // Create a phone number in the Twilio console + public static final String TWILIO_NUMBER = "+12223334444"; + + public static void main(String[] args) { + Twilio.init(ACCOUNT_SID, AUTH_TOKEN); + Message message = Message.creator( + new PhoneNumber("+17778889999"), + new PhoneNumber(TWILIO_NUMBER), + "Sample Twilio SMS using Java") + .create(); + + } +} diff --git a/twilio/src/main/java/TwilioSmsMediaExample.java b/twilio/src/main/java/TwilioSmsMediaExample.java new file mode 100644 index 0000000000..f0b0677198 --- /dev/null +++ b/twilio/src/main/java/TwilioSmsMediaExample.java @@ -0,0 +1,27 @@ +import com.twilio.Twilio; +import com.twilio.converter.Promoter; +import com.twilio.rest.api.v2010.account.Message; +import com.twilio.type.PhoneNumber; + +import java.net.URI; + +public class TwilioSmsMediaExample { + // Find your Account Sid and Token at twilio.com/console + public static final String ACCOUNT_SID = "SID"; + public static final String AUTH_TOKEN = "AUTH"; + + // Create a phone number in the Twilio console + public static final String TWILIO_NUMBER = "+12223334444"; + + public static void main(String[] args) { + Twilio.init(ACCOUNT_SID, AUTH_TOKEN); + Message message = Message.creator( + new PhoneNumber("+17778889999"), + new PhoneNumber(TWILIO_NUMBER), + "Sample Twilio MMS using Java") + .setMediaUrl( + Promoter.listOfOne( + URI.create("http://www.baeldung.com/wp-content/uploads/2017/10/icon-javaseries-home.png"))) + .create(); + } +} diff --git a/twilio/src/main/java/TwilioSmsStatusAsyncExample.java b/twilio/src/main/java/TwilioSmsStatusAsyncExample.java new file mode 100644 index 0000000000..ca55bb1978 --- /dev/null +++ b/twilio/src/main/java/TwilioSmsStatusAsyncExample.java @@ -0,0 +1,34 @@ +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.twilio.Twilio; +import com.twilio.base.ResourceSet; +import com.twilio.rest.api.v2010.account.Message; + +public class TwilioSmsStatusAsyncExample { + // Find your Account Sid and Token at twilio.com/console + public static final String ACCOUNT_SID = "SID"; + public static final String AUTH_TOKEN = "AUTH"; + + // Create a phone number in the Twilio console + public static final String TWILIO_NUMBER = "+12223334444"; + + public static void main(String[] args) { + + Twilio.init(ACCOUNT_SID, AUTH_TOKEN); + ListenableFuture> future = Message.reader().readAsync(); + Futures.addCallback( + future, + new FutureCallback>() { + public void onSuccess(ResourceSet messages) { + for (Message message : messages) { + System.out.println(message.getSid() + " : " + message.getStatus()); + } + } + + public void onFailure(Throwable t) { + System.out.println("Failed to get message status: " + t.getMessage()); + } + }); + } +} diff --git a/twilio/src/main/java/TwilioSmsStatusExample.java b/twilio/src/main/java/TwilioSmsStatusExample.java new file mode 100644 index 0000000000..625af0d848 --- /dev/null +++ b/twilio/src/main/java/TwilioSmsStatusExample.java @@ -0,0 +1,22 @@ +import com.twilio.Twilio; +import com.twilio.base.ResourceSet; +import com.twilio.rest.api.v2010.account.Message; +import com.twilio.type.PhoneNumber; + +public class TwilioSmsStatusExample { + // Find your Account Sid and Token at twilio.com/console + public static final String ACCOUNT_SID = "SID"; + public static final String AUTH_TOKEN = "AUTH"; + + // Create a phone number in the Twilio console + public static final String TWILIO_NUMBER = "+12223334444"; + + public static void main(String[] args) { + + Twilio.init(ACCOUNT_SID, AUTH_TOKEN); + ResourceSet messages = Message.reader().read(); + for (Message message : messages) { + System.out.println(message.getSid() + " : " + message.getStatus()); + } + } +} From dc03c79a7d75f134cef8417462176a8b1e0d4801 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Fri, 18 May 2018 16:30:05 +0300 Subject: [PATCH 84/93] remove eval code, move sms code to package --- pom.xml | 1 + .../EventStreamServer.java | 12 ------- .../client/EventStreamClient.java | 18 ---------- .../controller/EventStreamController.java | 17 ---------- .../src/main/resources/application.properties | 0 .../EventStreamServerTests.java | 16 --------- twilio/pom.xml | 2 +- twilio/sms/pom.xml | 24 ------------- .../sms/src/main/java/TwilioSmsExample.java | 22 ------------ .../src/main/java/TwilioSmsMediaExample.java | 27 --------------- .../java/TwilioSmsStatusAsyncExample.java | 34 ------------------- .../src/main/java/TwilioSmsStatusExample.java | 22 ------------ .../twilio/sms}/TwilioSmsExample.java | 1 + .../twilio/sms}/TwilioSmsMediaExample.java | 1 + .../sms}/TwilioSmsStatusAsyncExample.java | 1 + .../twilio/sms}/TwilioSmsStatusExample.java | 1 + 16 files changed, 6 insertions(+), 193 deletions(-) delete mode 100644 spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServer.java delete mode 100644 spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/client/EventStreamClient.java delete mode 100644 spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/controller/EventStreamController.java delete mode 100644 spring-webflux-event-stream/src/main/resources/application.properties delete mode 100644 spring-webflux-event-stream/src/test/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServerTests.java delete mode 100644 twilio/sms/pom.xml delete mode 100644 twilio/sms/src/main/java/TwilioSmsExample.java delete mode 100644 twilio/sms/src/main/java/TwilioSmsMediaExample.java delete mode 100644 twilio/sms/src/main/java/TwilioSmsStatusAsyncExample.java delete mode 100644 twilio/sms/src/main/java/TwilioSmsStatusExample.java rename twilio/src/main/java/{ => com/baeldung/twilio/sms}/TwilioSmsExample.java (95%) rename twilio/src/main/java/{ => com/baeldung/twilio/sms}/TwilioSmsMediaExample.java (96%) rename twilio/src/main/java/{ => com/baeldung/twilio/sms}/TwilioSmsStatusAsyncExample.java (97%) rename twilio/src/main/java/{ => com/baeldung/twilio/sms}/TwilioSmsStatusExample.java (95%) diff --git a/pom.xml b/pom.xml index 9dea3dc79d..16e826e4e9 100644 --- a/pom.xml +++ b/pom.xml @@ -259,6 +259,7 @@ jersey java-spi performance-tests + twilio diff --git a/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServer.java b/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServer.java deleted file mode 100644 index 48548bd8d5..0000000000 --- a/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServer.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.demo.eventstreamwebfluxdemo; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class EventStreamServer { - - public static void main(String[] args) { - SpringApplication.run(EventStreamServer.class, args); - } -} diff --git a/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/client/EventStreamClient.java b/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/client/EventStreamClient.java deleted file mode 100644 index 73ca753136..0000000000 --- a/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/client/EventStreamClient.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.baeldung.demo.eventstreamwebfluxdemo.client; - -import org.springframework.http.MediaType; -import org.springframework.web.reactive.function.client.WebClient; - -public class EventStreamClient { - public static void main(String[] args) - { - WebClient.create("http://127.0.0.1:8080") - .get() - .uri("/events") - .accept(MediaType.APPLICATION_STREAM_JSON) - .retrieve() - .bodyToFlux(Long.class) - .toStream() - .forEach(item -> System.out.println("New event : " + item)); - } -} diff --git a/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/controller/EventStreamController.java b/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/controller/EventStreamController.java deleted file mode 100644 index d28d402316..0000000000 --- a/spring-webflux-event-stream/src/main/java/com/baeldung/demo/eventstreamwebfluxdemo/controller/EventStreamController.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.baeldung.demo.eventstreamwebfluxdemo.controller; - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; -import reactor.core.publisher.Flux; - -import java.time.Duration; - -@RestController -public class EventStreamController -{ - @RequestMapping("/events") - public Flux getServerEvents() - { - return Flux.interval(Duration.ofMillis(1000)); - } -} diff --git a/spring-webflux-event-stream/src/main/resources/application.properties b/spring-webflux-event-stream/src/main/resources/application.properties deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/spring-webflux-event-stream/src/test/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServerTests.java b/spring-webflux-event-stream/src/test/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServerTests.java deleted file mode 100644 index d4dfcce4b3..0000000000 --- a/spring-webflux-event-stream/src/test/java/com/baeldung/demo/eventstreamwebfluxdemo/EventStreamServerTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.baeldung.demo.eventstreamwebfluxdemo; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class EventStreamServerTests { - - @Test - public void contextLoads() { - } - -} diff --git a/twilio/pom.xml b/twilio/pom.xml index 13187cfb07..89b40ccdac 100644 --- a/twilio/pom.xml +++ b/twilio/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.baeldung.sms + com.baeldung twilio 1.0-SNAPSHOT diff --git a/twilio/sms/pom.xml b/twilio/sms/pom.xml deleted file mode 100644 index 58ac33a7f3..0000000000 --- a/twilio/sms/pom.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - 4.0.0 - - com.baeldung.twilio - sms - 1.0-SNAPSHOT - - - 1.8 - 1.8 - - - - - com.twilio.sdk - twilio - 7.20.0 - - - - diff --git a/twilio/sms/src/main/java/TwilioSmsExample.java b/twilio/sms/src/main/java/TwilioSmsExample.java deleted file mode 100644 index 442546027b..0000000000 --- a/twilio/sms/src/main/java/TwilioSmsExample.java +++ /dev/null @@ -1,22 +0,0 @@ -import com.twilio.Twilio; -import com.twilio.rest.api.v2010.account.Message; -import com.twilio.type.PhoneNumber; - -public class TwilioSmsExample { - // Find your Account Sid and Token at twilio.com/console - public static final String ACCOUNT_SID = "YOUR_ACCOUNT_SID"; - public static final String AUTH_TOKEN = "YOUR_ACCOUNT_TOKEN"; - - // Create a phone number in the Twilio console - public static final String TWILIO_NUMBER = "+13334445555"; - - public static void main(String[] args) { - Twilio.init(ACCOUNT_SID, AUTH_TOKEN); - Message message = Message.creator( - new PhoneNumber("+12227779999"), - new PhoneNumber(TWILIO_NUMBER), - "Sample Twilio SMS using Java") - .create(); - - } -} diff --git a/twilio/sms/src/main/java/TwilioSmsMediaExample.java b/twilio/sms/src/main/java/TwilioSmsMediaExample.java deleted file mode 100644 index 09a2f9fd63..0000000000 --- a/twilio/sms/src/main/java/TwilioSmsMediaExample.java +++ /dev/null @@ -1,27 +0,0 @@ -import com.twilio.Twilio; -import com.twilio.converter.Promoter; -import com.twilio.rest.api.v2010.account.Message; -import com.twilio.type.PhoneNumber; - -import java.net.URI; - -public class TwilioSmsMediaExample { - // Find your Account Sid and Token at twilio.com/console - public static final String ACCOUNT_SID = "YOUR_ACCOUNT_SID"; - public static final String AUTH_TOKEN = "YOUR_ACCOUNT_TOKEN"; - - // Create a phone number in the Twilio console - public static final String TWILIO_NUMBER = "+13334445555"; - - public static void main(String[] args) { - Twilio.init(ACCOUNT_SID, AUTH_TOKEN); - Message message = Message.creator( - new PhoneNumber("+12227779999"), - new PhoneNumber(TWILIO_NUMBER), - "Sample Twilio MMS using Java") - .setMediaUrl( - Promoter.listOfOne( - URI.create("http://www.baeldung.com/wp-content/uploads/2017/10/icon-javaseries-home.png"))) - .create(); - } -} diff --git a/twilio/sms/src/main/java/TwilioSmsStatusAsyncExample.java b/twilio/sms/src/main/java/TwilioSmsStatusAsyncExample.java deleted file mode 100644 index d75788a6a6..0000000000 --- a/twilio/sms/src/main/java/TwilioSmsStatusAsyncExample.java +++ /dev/null @@ -1,34 +0,0 @@ -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.twilio.Twilio; -import com.twilio.base.ResourceSet; -import com.twilio.rest.api.v2010.account.Message; - -public class TwilioSmsStatusAsyncExample { - // Find your Account Sid and Token at twilio.com/console - public static final String ACCOUNT_SID = "YOUR_ACCOUNT_SID"; - public static final String AUTH_TOKEN = "YOUR_AUTH_TOKEN"; - - // Create a phone number in the Twilio console - public static final String TWILIO_NUMBER = "+13334445555"; - - public static void main(String[] args) { - - Twilio.init(ACCOUNT_SID, AUTH_TOKEN); - ListenableFuture> future = Message.reader().readAsync(); - Futures.addCallback( - future, - new FutureCallback>() { - public void onSuccess(ResourceSet messages) { - for (Message message : messages) { - System.out.println(message.getSid() + " : " + message.getStatus()); - } - } - - public void onFailure(Throwable t) { - System.out.println("Failed to get message status: " + t.getMessage()); - } - }); - } -} diff --git a/twilio/sms/src/main/java/TwilioSmsStatusExample.java b/twilio/sms/src/main/java/TwilioSmsStatusExample.java deleted file mode 100644 index 9ed2ac5bcc..0000000000 --- a/twilio/sms/src/main/java/TwilioSmsStatusExample.java +++ /dev/null @@ -1,22 +0,0 @@ -import com.twilio.Twilio; -import com.twilio.base.ResourceSet; -import com.twilio.rest.api.v2010.account.Message; -import com.twilio.type.PhoneNumber; - -public class TwilioSmsStatusExample { - // Find your Account Sid and Token at twilio.com/console - public static final String ACCOUNT_SID = "YOUR_ACCOUNT_SID"; - public static final String AUTH_TOKEN = "YOUR_ACCOUNT_TOKEN"; - - // Create a phone number in the Twilio console - public static final String TWILIO_NUMBER = "+13334445555"; - - public static void main(String[] args) { - - Twilio.init(ACCOUNT_SID, AUTH_TOKEN); - ResourceSet messages = Message.reader().read(); - for (Message message : messages) { - System.out.println(message.getSid() + " : " + message.getStatus()); - } - } -} diff --git a/twilio/src/main/java/TwilioSmsExample.java b/twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsExample.java similarity index 95% rename from twilio/src/main/java/TwilioSmsExample.java rename to twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsExample.java index cf8c162223..8304b953ed 100644 --- a/twilio/src/main/java/TwilioSmsExample.java +++ b/twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsExample.java @@ -1,3 +1,4 @@ +package com.baeldung.twilio.sms; import com.twilio.Twilio; import com.twilio.rest.api.v2010.account.Message; import com.twilio.type.PhoneNumber; diff --git a/twilio/src/main/java/TwilioSmsMediaExample.java b/twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsMediaExample.java similarity index 96% rename from twilio/src/main/java/TwilioSmsMediaExample.java rename to twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsMediaExample.java index f0b0677198..953067659a 100644 --- a/twilio/src/main/java/TwilioSmsMediaExample.java +++ b/twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsMediaExample.java @@ -1,3 +1,4 @@ +package com.baeldung.twilio.sms; import com.twilio.Twilio; import com.twilio.converter.Promoter; import com.twilio.rest.api.v2010.account.Message; diff --git a/twilio/src/main/java/TwilioSmsStatusAsyncExample.java b/twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsStatusAsyncExample.java similarity index 97% rename from twilio/src/main/java/TwilioSmsStatusAsyncExample.java rename to twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsStatusAsyncExample.java index ca55bb1978..d3b1c9b7dc 100644 --- a/twilio/src/main/java/TwilioSmsStatusAsyncExample.java +++ b/twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsStatusAsyncExample.java @@ -1,3 +1,4 @@ +package com.baeldung.twilio.sms; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; diff --git a/twilio/src/main/java/TwilioSmsStatusExample.java b/twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsStatusExample.java similarity index 95% rename from twilio/src/main/java/TwilioSmsStatusExample.java rename to twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsStatusExample.java index 625af0d848..e865c91679 100644 --- a/twilio/src/main/java/TwilioSmsStatusExample.java +++ b/twilio/src/main/java/com/baeldung/twilio/sms/TwilioSmsStatusExample.java @@ -1,3 +1,4 @@ +package com.baeldung.twilio.sms; import com.twilio.Twilio; import com.twilio.base.ResourceSet; import com.twilio.rest.api.v2010.account.Message; From ee8fc48a57a4dab821e40d3ffae110e20e69f423 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Fri, 18 May 2018 17:49:00 +0300 Subject: [PATCH 85/93] update to boot 2 --- vavr/pom.xml | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/vavr/pom.xml b/vavr/pom.xml index 411748afdf..3bf91adcd3 100644 --- a/vavr/pom.xml +++ b/vavr/pom.xml @@ -6,10 +6,10 @@ vavr - parent-boot-5 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-2 @@ -43,29 +43,6 @@ - - - spring-snapshot - Spring Snapshot Repository - https://repo.spring.io/snapshot - - true - - - - snapshots - libs-snapshot - https://repo.spring.io/libs-snapshot - - - - - - spring-snapshots - http://repo.spring.io/snapshot - - - 1.8 0.9.1 From aa83b3324cdf16101e32cd568e805f9b090e4996 Mon Sep 17 00:00:00 2001 From: chandra Date: Fri, 18 May 2018 16:57:28 -0400 Subject: [PATCH 86/93] Nan in Java Example usage of NaN in Java --- .../java/com/baeldung/nan/NaNExample.java | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 core-java/src/main/java/com/baeldung/nan/NaNExample.java diff --git a/core-java/src/main/java/com/baeldung/nan/NaNExample.java b/core-java/src/main/java/com/baeldung/nan/NaNExample.java new file mode 100644 index 0000000000..d54a749d3f --- /dev/null +++ b/core-java/src/main/java/com/baeldung/nan/NaNExample.java @@ -0,0 +1,81 @@ +package com.baeldung.nan; + +/** + * Sample usage of NaN. + * + */ +public class NaNExample { + + public static void main(String[] args) { + NaNExample naNExample = new NaNExample(); + naNExample.demo(); + } + + void demo() { + undefined_operations_produce_NaN(); + operations_with_no_real_results_produce_NaN(); + operations_with_NaN_produce_NaN(); + comparison_with_NaN(); + check_if_a_value_is_NaN(); + assign_NaN_to_missing_values(); + } + + void undefined_operations_produce_NaN() { + System.out.println("Undefined Operations Produce NaN"); + final double ZERO = 0; + System.out.println("ZERO / ZERO = " + (ZERO / ZERO)); + System.out.println("INFINITY - INFINITY = " + (Double.POSITIVE_INFINITY - Double.POSITIVE_INFINITY)); + System.out.println("INFINITY * ZERO = " + (Double.POSITIVE_INFINITY * ZERO)); + System.out.println(); + } + + void operations_with_no_real_results_produce_NaN() { + System.out.println("Operations with no real results produce NaN"); + System.out.println("SQUARE ROOT OF -1 = " + Math.sqrt(-1)); + System.out.println("LOG OF -1 = " + Math.log(-1)); + System.out.println(); + } + + void operations_with_NaN_produce_NaN() { + System.out.println("Operations with NaN produce NaN"); + System.out.println("2 + NaN = " + (2 + Double.NaN)); + System.out.println("2 - NaN = " + (2 - Double.NaN)); + System.out.println("2 * NaN = " + (2 * Double.NaN)); + System.out.println("2 / NaN = " + (2 / Double.NaN)); + System.out.println(); + } + + void assign_NaN_to_missing_values() { + System.out.println("Assign NaN to Missing values"); + double salaryRequired = Double.NaN; + System.out.println(salaryRequired); + System.out.println(); + } + + void comparison_with_NaN() { + System.out.println("Comparison with NaN"); + final double NAN = Double.NaN; + System.out.println("NaN == 1 = " + (NAN == 1)); + System.out.println("NaN > 1 = " + (NAN > 1)); + System.out.println("NaN < 1 = " + (NAN < 1)); + System.out.println("NaN != 1 = " + (NAN != 1)); + System.out.println("NaN == NaN = " + (NAN == NAN)); + System.out.println("NaN > NaN = " + (NAN > NAN)); + System.out.println("NaN < NaN = " + (NAN < NAN)); + System.out.println("NaN != NaN = " + (NAN != NAN)); + System.out.println(); + } + + void check_if_a_value_is_NaN() { + System.out.println("Check if a value is NaN"); + double x = 1; + System.out.println(x + " is NaN = " + (x != x)); + System.out.println(x + " is NaN = " + (Double.isNaN(x))); + + x = Double.NaN; + System.out.println(x + " is NaN = " + (x != x)); + System.out.println(x + " is NaN = " + (Double.isNaN(x))); + System.out.println(); + } + +} From 110d3891c47a764babf645b22846bde639fedce0 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 19 May 2018 14:16:18 +0530 Subject: [PATCH 87/93] Bael 6514 (#4281) * Added parent module on poms that have no parent defined * Removed dependency reduced pom from undertow module * [BAEL-6514] - Fix usage of @AutoConfigureMockMvc without mocking --- flips/src/main/java/com/baeldung/flips/model/Foo.java | 5 +++-- .../com/baeldung/flips/controller/FlipControllerTest.java | 2 +- spring-4/src/main/java/com/baeldung/flips/model/Foo.java | 5 +++-- .../com/baeldung/flips/controller/FlipControllerTest.java | 2 +- .../src/test/java/com/baeldung/intro/AppLiveTest.java | 2 +- spring-mvc-forms-thymeleaf/pom.xml | 1 + .../TodoControllerWithScopedProxyIntegrationTest.java | 5 +++-- .../TodoControllerWithSessionAttributesIntegrationTest.java | 2 +- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/flips/src/main/java/com/baeldung/flips/model/Foo.java b/flips/src/main/java/com/baeldung/flips/model/Foo.java index d98abb79a9..be15bee15c 100644 --- a/flips/src/main/java/com/baeldung/flips/model/Foo.java +++ b/flips/src/main/java/com/baeldung/flips/model/Foo.java @@ -1,11 +1,12 @@ package com.baeldung.flips.model; import lombok.Data; +import lombok.NonNull; import lombok.RequiredArgsConstructor; @Data @RequiredArgsConstructor public class Foo { - private final String name; - private final int id; + @NonNull private final String name; + @NonNull private final int id; } diff --git a/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java b/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java index 1b8c78e2a4..8fd9c4e340 100644 --- a/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java +++ b/flips/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java @@ -20,7 +20,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers; "first.active.after=2999-03-15T00:00:00Z", "logging.level.org.flips=info" -}) +}, webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @ActiveProfiles("dev") public class FlipControllerTest { diff --git a/spring-4/src/main/java/com/baeldung/flips/model/Foo.java b/spring-4/src/main/java/com/baeldung/flips/model/Foo.java index d98abb79a9..be15bee15c 100644 --- a/spring-4/src/main/java/com/baeldung/flips/model/Foo.java +++ b/spring-4/src/main/java/com/baeldung/flips/model/Foo.java @@ -1,11 +1,12 @@ package com.baeldung.flips.model; import lombok.Data; +import lombok.NonNull; import lombok.RequiredArgsConstructor; @Data @RequiredArgsConstructor public class Foo { - private final String name; - private final int id; + @NonNull private final String name; + @NonNull private final int id; } diff --git a/spring-4/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java b/spring-4/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java index 1b8c78e2a4..8fd9c4e340 100644 --- a/spring-4/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java +++ b/spring-4/src/test/java/com/baeldung/flips/controller/FlipControllerTest.java @@ -20,7 +20,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers; "first.active.after=2999-03-15T00:00:00Z", "logging.level.org.flips=info" -}) +}, webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @ActiveProfiles("dev") public class FlipControllerTest { diff --git a/spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java b/spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java index 2c0152b97f..83b893ae5c 100644 --- a/spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java +++ b/spring-boot/src/test/java/com/baeldung/intro/AppLiveTest.java @@ -16,7 +16,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @TestPropertySource(properties = { "security.basic.enabled=false" }) public class AppLiveTest { diff --git a/spring-mvc-forms-thymeleaf/pom.xml b/spring-mvc-forms-thymeleaf/pom.xml index b6e931edda..408e7643d2 100644 --- a/spring-mvc-forms-thymeleaf/pom.xml +++ b/spring-mvc-forms-thymeleaf/pom.xml @@ -68,6 +68,7 @@ UTF-8 UTF-8 + 3.0.9.RELEASE diff --git a/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyIntegrationTest.java b/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyIntegrationTest.java index a8a6ce469d..037d4f9d71 100644 --- a/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyIntegrationTest.java +++ b/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithScopedProxyIntegrationTest.java @@ -1,6 +1,7 @@ package com.baeldung.sessionattrs; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -22,7 +23,7 @@ import org.springframework.util.StringUtils; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @Import(TestConfig.class) public class TodoControllerWithScopedProxyIntegrationTest { @@ -47,7 +48,7 @@ public class TodoControllerWithScopedProxyIntegrationTest { .andReturn(); TodoItem item = (TodoItem) result.getModelAndView().getModel().get("todo"); - assertTrue(StringUtils.isEmpty(item.getDescription())); + assertFalse(StringUtils.isEmpty(item.getDescription())); } @Test diff --git a/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesIntegrationTest.java b/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesIntegrationTest.java index b1caac5756..101f4f71d9 100644 --- a/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesIntegrationTest.java +++ b/spring-mvc-forms-thymeleaf/src/test/java/com/baeldung/sessionattrs/TodoControllerWithSessionAttributesIntegrationTest.java @@ -22,7 +22,7 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.FlashMap; @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc public class TodoControllerWithSessionAttributesIntegrationTest { From a6c5f89093d470fc910b8a1d6e99c09a60535bb1 Mon Sep 17 00:00:00 2001 From: amit2103 Date: Sat, 19 May 2018 16:40:29 +0530 Subject: [PATCH 88/93] [Bael 6514] - Fixed missing usage (#4284) * Added parent module on poms that have no parent defined * Removed dependency reduced pom from undertow module * [BAEL-6514] - Fix usage of @AutoConfigureMockMvc without mocking * [BAEL-6514] - Fix usage of @AutoConfigureMockMvc without mocking * [BAEL-6514] - Fix usage of @AutoConfigureMockMvc without mocking --- ...gBootWithServletComponentIntegrationTest.java | 1 - ...otWithoutServletComponentIntegrationTest.java | 16 +++++++--------- .../shutdown/ShutdownApplicationTest.java | 2 +- ...gBootWithServletComponentIntegrationTest.java | 2 +- .../java/com/baeldung/intro/AppLiveTest.java | 2 +- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java index 6d958ea637..2c3ac2e159 100644 --- a/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java +++ b/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java @@ -20,7 +20,6 @@ import static org.junit.Assert.assertTrue; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootAnnotatedApp.class) -@AutoConfigureMockMvc @TestPropertySource(properties = { "security.basic.enabled=false" }) public class SpringBootWithServletComponentIntegrationTest { diff --git a/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java b/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java index a13cd250a2..a30d3ed3f2 100644 --- a/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java +++ b/spring-boot/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithoutServletComponentIntegrationTest.java @@ -1,9 +1,15 @@ package com.baeldung.annotation.servletcomponentscan; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import javax.servlet.FilterRegistration; +import javax.servlet.ServletContext; + import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; @@ -11,16 +17,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; -import javax.servlet.FilterRegistration; -import javax.servlet.ServletContext; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootPlainApp.class) -@AutoConfigureMockMvc @TestPropertySource(properties = { "security.basic.enabled=false" }) public class SpringBootWithoutServletComponentIntegrationTest { diff --git a/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java b/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java index ae70276b9f..e4db0bd1e7 100644 --- a/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java +++ b/spring-boot/src/test/java/com/baeldung/shutdown/ShutdownApplicationTest.java @@ -16,7 +16,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = Application.class) @AutoConfigureMockMvc public class ShutdownApplicationTest { diff --git a/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java b/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java index 81774b6b8a..f6d2a8c465 100644 --- a/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java +++ b/spring-custom-aop/src/test/java/com/baeldung/annotation/servletcomponentscan/SpringBootWithServletComponentIntegrationTest.java @@ -17,7 +17,7 @@ import javax.servlet.ServletContext; import static org.junit.Assert.*; @RunWith(SpringRunner.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringBootAnnotatedApp.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = SpringBootAnnotatedApp.class) @AutoConfigureMockMvc @TestPropertySource(properties = { "security.basic.enabled=false" }) public class SpringBootWithServletComponentIntegrationTest { diff --git a/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java b/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java index 2c0152b97f..83b893ae5c 100644 --- a/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java +++ b/spring-custom-aop/src/test/java/com/baeldung/intro/AppLiveTest.java @@ -16,7 +16,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringRunner.class) -@SpringBootTest +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) @AutoConfigureMockMvc @TestPropertySource(properties = { "security.basic.enabled=false" }) public class AppLiveTest { From ebf0a3b21b0b62fdf4ce3f6824b86fca535bcfaa Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sat, 19 May 2018 21:29:40 +0300 Subject: [PATCH 89/93] add custom shutdown endpoint --- .../com/baeldung/shutdown/Application.java | 3 ++- .../shutdown/shutdown/ShutdownController.java | 20 ++++++++++++++++++- .../src/main/resources/application.properties | 3 +-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/spring-boot/src/main/java/com/baeldung/shutdown/Application.java b/spring-boot/src/main/java/com/baeldung/shutdown/Application.java index 2225df8b34..03f16789dc 100644 --- a/spring-boot/src/main/java/com/baeldung/shutdown/Application.java +++ b/spring-boot/src/main/java/com/baeldung/shutdown/Application.java @@ -9,7 +9,7 @@ import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication public class Application { - + public static void main(String[] args) { SpringApplication.run(Application.class, args); @@ -46,4 +46,5 @@ public class Application { app.build().addListeners(new ApplicationPidFileWriter("./bin/shutdown.pid")); app.run(); } + } diff --git a/spring-boot/src/main/java/com/baeldung/shutdown/shutdown/ShutdownController.java b/spring-boot/src/main/java/com/baeldung/shutdown/shutdown/ShutdownController.java index b0acc1f422..6ebe053654 100644 --- a/spring-boot/src/main/java/com/baeldung/shutdown/shutdown/ShutdownController.java +++ b/spring-boot/src/main/java/com/baeldung/shutdown/shutdown/ShutdownController.java @@ -1,7 +1,25 @@ package com.baeldung.shutdown.shutdown; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; @RestController -public class ShutdownController { +public class ShutdownController implements ApplicationContextAware { + + private ApplicationContext context; + + @PostMapping("/shutdownContext") + public void shutdownContext() { + ((ConfigurableApplicationContext) context).close(); + } + + @Override + public void setApplicationContext(ApplicationContext ctx) throws BeansException { + this.context = ctx; + + } } diff --git a/spring-boot/src/main/resources/application.properties b/spring-boot/src/main/resources/application.properties index 04a4fbf9de..8c02e528ab 100644 --- a/spring-boot/src/main/resources/application.properties +++ b/spring-boot/src/main/resources/application.properties @@ -9,6 +9,7 @@ spring.jpa.hibernate.ddl-auto = update management.endpoints.jmx.domain=Spring Sample Application management.endpoints.jmx.uniqueNames=true +management.endpoints.web.exposure.include=* management.endpoint.shutdown.enabled=true ##jolokia.config.debug=true @@ -27,8 +28,6 @@ info.app.description=This is my first spring boot application G1 info.app.version=1.0.0 info.java-vendor = ${java.specification.vendor} -management.security.role=SUPERUSER - logging.level.org.springframework=INFO #Servlet Configuration From ba55cfb67db49947c633dfaaa14af9ac4ab97932 Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Sat, 19 May 2018 22:07:54 -0600 Subject: [PATCH 90/93] BAEL-1338 - Programmatic Log4j2 This commit features a number of tests for programmatically configuring log4j. Note that in order to have these tests live together, there is a slight deviation in how these are configured vs how they are in the real world, specifically around static initialization. Generally speaking, whenever static initialization is needed for a given configuration, it is embedded in a @BeforeClass-annotated JUnit method. Also, to isolate the tests from each other's plugins, annotation processing was turned off in the build. This is not required when doing programmatic configuration of log4j. It is simply needed for the specific use case of demonstrating these various log4j plugins all in the same module. --- .../modify-xml-configuration/pom.xml | 19 ---- .../config/CustomXMLConfigurationFactory.java | 29 ------ .../log4j2/config/MyXMLConfiguration.java | 35 -------- .../src/main/resources/log4j2.xml | 17 ---- .../com/baeldung/log4j2/logtest/LogTest.java | 23 ----- .../log4j2-programmatic-configuration/pom.xml | 34 ------- .../set-configuration-factory/pom.xml | 10 --- .../config/CustomConfigurationFactory.java | 88 ------------------- .../simple-configuration-xml/pom.xml | 17 ---- .../src/main/resources/log4j2.xml | 32 ------- .../com/baeldung/log4j2/logtest/LogTest.java | 30 ------- .../simple-configuration/pom.xml | 10 --- .../simple-configurator/pom.xml | 10 --- logging-modules/log4j2/pom.xml | 18 +++- .../baeldung/logging/log4j2/Log4j2Test.java | 18 ++++ .../SetConfigurationFactoryTest.java} | 18 ++-- .../CustomConfigurationFactory.java | 6 +- .../SimpleConfigurationTest.java} | 18 ++-- .../simpleconfigurator}/LogPrinter.java | 5 +- .../SimpleConfiguratorTest.java} | 26 +++--- .../logging/log4j2/tests/JSONLayoutTest.java | 3 +- .../CustomXMLConfigurationFactory.java | 24 +++++ .../xmlconfiguration/MyXMLConfiguration.java | 36 ++++++++ .../xmlconfiguration/XMLConfigLogTest.java | 44 ++++++++++ pom.xml | 1 - 25 files changed, 181 insertions(+), 390 deletions(-) delete mode 100644 logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/pom.xml delete mode 100644 logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/java/com/baeldung/log4j2/config/CustomXMLConfigurationFactory.java delete mode 100644 logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/java/com/baeldung/log4j2/config/MyXMLConfiguration.java delete mode 100644 logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/resources/log4j2.xml delete mode 100644 logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/test/java/com/baeldung/log4j2/logtest/LogTest.java delete mode 100644 logging-modules/log4j2-programmatic-configuration/pom.xml delete mode 100644 logging-modules/log4j2-programmatic-configuration/set-configuration-factory/pom.xml delete mode 100644 logging-modules/log4j2-programmatic-configuration/set-configuration-factory/src/main/java/com/baeldung/log4j2/config/CustomConfigurationFactory.java delete mode 100644 logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/pom.xml delete mode 100644 logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/src/main/resources/log4j2.xml delete mode 100644 logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/src/test/java/com/baeldung/log4j2/logtest/LogTest.java delete mode 100644 logging-modules/log4j2-programmatic-configuration/simple-configuration/pom.xml delete mode 100644 logging-modules/log4j2-programmatic-configuration/simple-configurator/pom.xml create mode 100644 logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/Log4j2Test.java rename logging-modules/{log4j2-programmatic-configuration/set-configuration-factory/src/test/java/com/baeldung/log4j2/logtest/LogTest.java => log4j2/src/test/java/com/baeldung/logging/log4j2/setconfigurationfactory/SetConfigurationFactoryTest.java} (66%) rename logging-modules/{log4j2-programmatic-configuration/simple-configuration/src/main/java/com/baeldung/log4j2/config => log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfiguration}/CustomConfigurationFactory.java (97%) rename logging-modules/{log4j2-programmatic-configuration/simple-configuration/src/test/java/com/baeldung/log4j2/logtest/LogTest.java => log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfiguration/SimpleConfigurationTest.java} (51%) rename logging-modules/{log4j2-programmatic-configuration/simple-configurator/src/test/java/com/baeldung/log4j2/logtest => log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfigurator}/LogPrinter.java (84%) rename logging-modules/{log4j2-programmatic-configuration/simple-configurator/src/test/java/com/baeldung/log4j2/configure/LogTest.java => log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfigurator/SimpleConfiguratorTest.java} (60%) create mode 100644 logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/CustomXMLConfigurationFactory.java create mode 100644 logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/MyXMLConfiguration.java create mode 100644 logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/XMLConfigLogTest.java diff --git a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/pom.xml b/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/pom.xml deleted file mode 100644 index 74464a9631..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/pom.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - 4.0.0 - - com.baeldung.log4j2 - log4j2-programmatic-configuration - 0.0.1-SNAPSHOT - - com.baeldung.log4j2 - modify-xml-configuration - 0.0.1-SNAPSHOT - modify-xml-configuration - http://maven.apache.org - - UTF-8 - - diff --git a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/java/com/baeldung/log4j2/config/CustomXMLConfigurationFactory.java b/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/java/com/baeldung/log4j2/config/CustomXMLConfigurationFactory.java deleted file mode 100644 index e92c66f168..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/java/com/baeldung/log4j2/config/CustomXMLConfigurationFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - This class demonstrates on modifying the loaded xml configuration by - extending XMLConfigurationFactory as defined in section 4.4 of - "Programmatic Configuration with Log4j 2" -**/ -package com.baeldung.log4j2.config; - -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.ConfigurationFactory; -import org.apache.logging.log4j.core.config.ConfigurationSource; -import org.apache.logging.log4j.core.config.Order; -import org.apache.logging.log4j.core.config.plugins.Plugin; -import org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory; - -@Plugin(name = "CustomConfigurationFactory", category = ConfigurationFactory.CATEGORY) -@Order(50) -public class CustomXMLConfigurationFactory extends XmlConfigurationFactory { - - @Override - public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) { - return new MyXMLConfiguration(loggerContext, source); - } - - @Override - public String[] getSupportedTypes() { - return new String[] { ".xml", "*" }; - } -} diff --git a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/java/com/baeldung/log4j2/config/MyXMLConfiguration.java b/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/java/com/baeldung/log4j2/config/MyXMLConfiguration.java deleted file mode 100644 index 45ee421316..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/java/com/baeldung/log4j2/config/MyXMLConfiguration.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - This class demonstrates on overriding the configuration loaded through xml - as defined in section 4.4 of "Programmatic Configuration with Log4j 2" -**/ -package com.baeldung.log4j2.config; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.core.Appender; -import org.apache.logging.log4j.core.Layout; -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.appender.FileAppender; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.ConfigurationSource; -import org.apache.logging.log4j.core.config.LoggerConfig; -import org.apache.logging.log4j.core.config.xml.XmlConfiguration; -import org.apache.logging.log4j.core.layout.PatternLayout; - -public class MyXMLConfiguration extends XmlConfiguration { - public MyXMLConfiguration(LoggerContext loggerContext, ConfigurationSource source) { - super(loggerContext, source); - } - - @Override - protected void doConfigure() { - super.doConfigure(); - final LoggerContext ctx = (LoggerContext) LogManager.getContext(false); - Configuration config = ctx.getConfiguration(); - LoggerConfig loggerConfig = config.getLoggerConfig("com"); - final Layout layout = PatternLayout.createLayout("[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n", null, config, null, null, false, false, null, null); - Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true", "false", "false", "4000", layout, null, "false", null, config); - loggerConfig.addAppender(appender, Level.DEBUG, null); - addAppender(appender); - } -} diff --git a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/resources/log4j2.xml b/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/resources/log4j2.xml deleted file mode 100644 index 36823c8122..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/main/resources/log4j2.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/test/java/com/baeldung/log4j2/logtest/LogTest.java b/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/test/java/com/baeldung/log4j2/logtest/LogTest.java deleted file mode 100644 index 993c0d0648..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/modify-xml-configuration/src/test/java/com/baeldung/log4j2/logtest/LogTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.baeldung.log4j2.logtest; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.config.plugins.util.PluginManager; -import org.junit.Test; - - -public class LogTest { - static{ - PluginManager.addPackage("com.baeldung.log4j2.config"); - } - - @Test - public void simpleProgrammaticConfiguration() { - Logger logger = LogManager.getLogger(); - LoggerContext ctx = (LoggerContext) LogManager.getContext(); - logger.debug("Debug log message"); - logger.info("Info log message"); - logger.error("Error log message"); - } -} diff --git a/logging-modules/log4j2-programmatic-configuration/pom.xml b/logging-modules/log4j2-programmatic-configuration/pom.xml deleted file mode 100644 index cd3aced397..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/pom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - 4.0.0 - com.baeldung.log4j2 - log4j2-programmatic-configuration - 0.0.1-SNAPSHOT - pom - - simple-configuration - set-configuration-factory - simple-configurator - simple-configuration-xml - modify-xml-configuration - - - - junit - junit - 4.12 - test - - - org.apache.logging.log4j - log4j-core - 2.11.0 - - - org.apache.logging.log4j - log4j-slf4j-impl - 2.11.0 - - - diff --git a/logging-modules/log4j2-programmatic-configuration/set-configuration-factory/pom.xml b/logging-modules/log4j2-programmatic-configuration/set-configuration-factory/pom.xml deleted file mode 100644 index f2a72563e9..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/set-configuration-factory/pom.xml +++ /dev/null @@ -1,10 +0,0 @@ - - 4.0.0 - - com.baeldung.log4j2 - log4j2-programmatic-configuration - 0.0.1-SNAPSHOT - - set-configuration-factory - \ No newline at end of file diff --git a/logging-modules/log4j2-programmatic-configuration/set-configuration-factory/src/main/java/com/baeldung/log4j2/config/CustomConfigurationFactory.java b/logging-modules/log4j2-programmatic-configuration/set-configuration-factory/src/main/java/com/baeldung/log4j2/config/CustomConfigurationFactory.java deleted file mode 100644 index 9c48702ba0..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/set-configuration-factory/src/main/java/com/baeldung/log4j2/config/CustomConfigurationFactory.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - This class demonstrates how to build the components of - the configuration factory, as described in Section 3 of - "Programmatic Configuration with Log4j 2" -**/ -package com.baeldung.log4j2.config; - -import java.io.IOException; -import java.net.URI; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.core.Filter; -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.ConfigurationFactory; -import org.apache.logging.log4j.core.config.ConfigurationSource; -import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; -import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder; -import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; - -public class CustomConfigurationFactory extends ConfigurationFactory { - - static Configuration createConfiguration(final String name, ConfigurationBuilder builder) { - AppenderComponentBuilder console = builder.newAppender("Stdout", "Console"); - LayoutComponentBuilder layout = builder.newLayout("PatternLayout") - .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"); - console.add(layout); - FilterComponentBuilder filter = builder.newFilter("MarkerFilter", Filter.Result.ACCEPT, Filter.Result.DENY); - filter.addAttribute("marker", "FLOW"); - console.add(filter); - builder.add(console); - ComponentBuilder triggeringPolicies = builder.newComponent("Policies") - .addComponent(builder.newComponent("CronTriggeringPolicy") - .addAttribute("schedule", "0 0 0 * * ?")) - .addComponent(builder.newComponent("SizeBasedTriggeringPolicy") - .addAttribute("size", "100M")); - AppenderComponentBuilder rollingFile = builder.newAppender("rolling", "RollingFile"); - rollingFile.addAttribute("fileName", "target/rolling.log"); - rollingFile.addAttribute("filePattern", "target/archive/rolling-%d{MM-dd-yy}.log.gz"); - rollingFile.add(layout); - rollingFile.addComponent(triggeringPolicies); - builder.add(rollingFile); - AppenderComponentBuilder file = builder.newAppender("FileSystem", "File"); - file.addAttribute("fileName", "target/logging.log"); - file.add(layout); - builder.add(file); - LoggerComponentBuilder logger = builder.newLogger("com", Level.DEBUG); - logger.add(builder.newAppenderRef("Stdout")); - logger.add(builder.newAppenderRef("rolling")); - logger.add(builder.newAppenderRef("FileSystem")); - logger.addAttribute("additivity", false); - builder.add(logger); - RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.ERROR); - rootLogger.add(builder.newAppenderRef("Stdout")); - rootLogger.add(builder.newAppenderRef("rolling")); - rootLogger.add(builder.newAppenderRef("FileSystem")); - rootLogger.addAttribute("additivity", false); - builder.add(rootLogger); - try { - builder.writeXmlConfiguration(System.out); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return builder.build(); - } - - public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI configLocation) { - ConfigurationBuilder builder = newConfigurationBuilder(); - return createConfiguration(name, builder); - } - - @Override - protected String[] getSupportedTypes() { - return new String[] { "*" }; - } - - @Override - public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) { - return getConfiguration(loggerContext, source.toString(), null); - } - -} diff --git a/logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/pom.xml b/logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/pom.xml deleted file mode 100644 index de8c1ff70b..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/pom.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - 4.0.0 - - com.baeldung.log4j2 - log4j2-programmatic-configuration - 0.0.1-SNAPSHOT - - simple-configuration-xml - simple-configuration-xml - http://maven.apache.org - - UTF-8 - - diff --git a/logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/src/main/resources/log4j2.xml b/logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/src/main/resources/log4j2.xml deleted file mode 100644 index 4c49d85471..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/src/main/resources/log4j2.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/src/test/java/com/baeldung/log4j2/logtest/LogTest.java b/logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/src/test/java/com/baeldung/log4j2/logtest/LogTest.java deleted file mode 100644 index f32e0796b6..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/simple-configuration-xml/src/test/java/com/baeldung/log4j2/logtest/LogTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - This class loads the logging configuration from the xml defined in - src/main/resources and uses the same configuration generated through - programmatic configuration as defined in simple-configuration example. -**/ - -package com.baeldung.log4j2.logtest; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.MarkerManager; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - - -@RunWith(JUnit4.class) -public class LogTest { - - @Test - public void simpleProgrammaticConfiguration(){ - Logger logger = LogManager.getLogger(); - Marker markerContent = MarkerManager.getMarker("FLOW"); - logger.debug(markerContent, "Debug log message"); - logger.info(markerContent, "Info log message"); - logger.error(markerContent, "Error log message"); - } - -} diff --git a/logging-modules/log4j2-programmatic-configuration/simple-configuration/pom.xml b/logging-modules/log4j2-programmatic-configuration/simple-configuration/pom.xml deleted file mode 100644 index 0f9e5be3ff..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/simple-configuration/pom.xml +++ /dev/null @@ -1,10 +0,0 @@ - - 4.0.0 - - com.baeldung.log4j2 - log4j2-programmatic-configuration - 0.0.1-SNAPSHOT - - simple-configuration - \ No newline at end of file diff --git a/logging-modules/log4j2-programmatic-configuration/simple-configurator/pom.xml b/logging-modules/log4j2-programmatic-configuration/simple-configurator/pom.xml deleted file mode 100644 index 4e7350f785..0000000000 --- a/logging-modules/log4j2-programmatic-configuration/simple-configurator/pom.xml +++ /dev/null @@ -1,10 +0,0 @@ - - 4.0.0 - - com.baeldung.log4j2 - log4j2-programmatic-configuration - 0.0.1-SNAPSHOT - - simple-configurator - \ No newline at end of file diff --git a/logging-modules/log4j2/pom.xml b/logging-modules/log4j2/pom.xml index 651e1e7d1f..e2ec67a5b5 100644 --- a/logging-modules/log4j2/pom.xml +++ b/logging-modules/log4j2/pom.xml @@ -53,13 +53,25 @@ test-jar test - + - 2.9.3 + 2.9.5 1.4.193 2.1.1 - 2.10.0 + 2.11.0 + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + none + + + + diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/Log4j2Test.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/Log4j2Test.java new file mode 100644 index 0000000000..abd92a2202 --- /dev/null +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/Log4j2Test.java @@ -0,0 +1,18 @@ +package com.baeldung.logging.log4j2; + +import org.apache.logging.log4j.core.config.ConfigurationFactory; +import org.apache.logging.log4j.spi.LoggerContextFactory; +import org.junit.AfterClass; + +import java.lang.reflect.Field; + +public class Log4j2Test { + @AfterClass + public static void tearDown() throws Exception { + Field factories = ConfigurationFactory.class.getDeclaredField("factories"); + factories.setAccessible(true); + factories.set(null, null); + ConfigurationFactory.resetConfigurationFactory(); + + } +} diff --git a/logging-modules/log4j2-programmatic-configuration/set-configuration-factory/src/test/java/com/baeldung/log4j2/logtest/LogTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/setconfigurationfactory/SetConfigurationFactoryTest.java similarity index 66% rename from logging-modules/log4j2-programmatic-configuration/set-configuration-factory/src/test/java/com/baeldung/log4j2/logtest/LogTest.java rename to logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/setconfigurationfactory/SetConfigurationFactoryTest.java index bf78a04dc4..2f9a837424 100644 --- a/logging-modules/log4j2-programmatic-configuration/set-configuration-factory/src/test/java/com/baeldung/log4j2/logtest/LogTest.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/setconfigurationfactory/SetConfigurationFactoryTest.java @@ -2,32 +2,34 @@ This class invokes the configuration factory with static initialization, as defined in section 4.1 of the "Programmatic Configuration with Log4j 2" **/ -package com.baeldung.log4j2.logtest; +package com.baeldung.logging.log4j2.setconfigurationfactory; +import com.baeldung.logging.log4j2.Log4j2Test; +import com.baeldung.logging.log4j2.simpleconfiguration.CustomConfigurationFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; import org.apache.logging.log4j.core.config.ConfigurationFactory; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import com.baeldung.log4j2.config.CustomConfigurationFactory; - @RunWith(JUnit4.class) -public class LogTest { - static { +public class SetConfigurationFactoryTest extends Log4j2Test { + @BeforeClass + public static void setUp() { CustomConfigurationFactory customConfigurationFactory = new CustomConfigurationFactory(); ConfigurationFactory.setConfigurationFactory(customConfigurationFactory); } @Test - public void simpleProgrammaticConfiguration() { - Logger logger = LogManager.getLogger(); + public void givenDirectConfiguration_whenUsingFlowMarkers_ThenLogsCorrectly() { + Logger logger = LogManager.getLogger(this.getClass()); Marker markerContent = MarkerManager.getMarker("FLOW"); logger.debug(markerContent, "Debug log message"); logger.info(markerContent, "Info log message"); logger.error(markerContent, "Error log message"); } -} +} \ No newline at end of file diff --git a/logging-modules/log4j2-programmatic-configuration/simple-configuration/src/main/java/com/baeldung/log4j2/config/CustomConfigurationFactory.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfiguration/CustomConfigurationFactory.java similarity index 97% rename from logging-modules/log4j2-programmatic-configuration/simple-configuration/src/main/java/com/baeldung/log4j2/config/CustomConfigurationFactory.java rename to logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfiguration/CustomConfigurationFactory.java index ca3cfa142d..6beb540115 100644 --- a/logging-modules/log4j2-programmatic-configuration/simple-configuration/src/main/java/com/baeldung/log4j2/config/CustomConfigurationFactory.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfiguration/CustomConfigurationFactory.java @@ -3,8 +3,7 @@ the configuration factory, as described in Section 3 of "Programmatic Configuration with Log4j 2" **/ - -package com.baeldung.log4j2.config; +package com.baeldung.logging.log4j2.simpleconfiguration; import java.io.IOException; import java.net.URI; @@ -26,7 +25,7 @@ import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuild import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; import org.apache.logging.log4j.core.config.plugins.Plugin; -@Plugin(name = "CustomConfigurationFactory", category = ConfigurationFactory.CATEGORY) +@Plugin(name = "simple", category = ConfigurationFactory.CATEGORY) @Order(50) public class CustomConfigurationFactory extends ConfigurationFactory { @@ -92,3 +91,4 @@ public class CustomConfigurationFactory extends ConfigurationFactory { return new String[] { "*" }; } } + diff --git a/logging-modules/log4j2-programmatic-configuration/simple-configuration/src/test/java/com/baeldung/log4j2/logtest/LogTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfiguration/SimpleConfigurationTest.java similarity index 51% rename from logging-modules/log4j2-programmatic-configuration/simple-configuration/src/test/java/com/baeldung/log4j2/logtest/LogTest.java rename to logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfiguration/SimpleConfigurationTest.java index 5637a16508..02330a808b 100644 --- a/logging-modules/log4j2-programmatic-configuration/simple-configuration/src/test/java/com/baeldung/log4j2/logtest/LogTest.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfiguration/SimpleConfigurationTest.java @@ -2,21 +2,29 @@ This class invokes the configuration factory through the run time property, as defined in section 4.2 of the "Programmatic Configuration with Log4j 2" **/ -package com.baeldung.log4j2.logtest; +package com.baeldung.logging.log4j2.simpleconfiguration; +import com.baeldung.logging.log4j2.Log4j2Test; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; +import org.apache.logging.log4j.core.config.plugins.util.PluginManager; +import org.junit.BeforeClass; import org.junit.Test; -public class LogTest { +public class SimpleConfigurationTest extends Log4j2Test { + @BeforeClass + public static void setUp() { + PluginManager.addPackage("com.baeldung.logging.log4j2.simpleconfiguration"); + } + @Test - public void simpleProgrammaticConfiguration() { - Logger logger = LogManager.getLogger(); + public void givenSimpleConfigurationPlugin_whenUsingFlowMarkers_thenLogsCorrectly() throws Exception { + Logger logger = LogManager.getLogger(this.getClass()); Marker markerContent = MarkerManager.getMarker("FLOW"); logger.debug(markerContent, "Debug log message"); logger.info(markerContent, "Info log message"); logger.error(markerContent, "Error log message"); } -} +} \ No newline at end of file diff --git a/logging-modules/log4j2-programmatic-configuration/simple-configurator/src/test/java/com/baeldung/log4j2/logtest/LogPrinter.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfigurator/LogPrinter.java similarity index 84% rename from logging-modules/log4j2-programmatic-configuration/simple-configurator/src/test/java/com/baeldung/log4j2/logtest/LogPrinter.java rename to logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfigurator/LogPrinter.java index d96808c105..d13de25ab9 100644 --- a/logging-modules/log4j2-programmatic-configuration/simple-configurator/src/test/java/com/baeldung/log4j2/logtest/LogPrinter.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfigurator/LogPrinter.java @@ -1,4 +1,5 @@ -package com.baeldung.log4j2.logtest; +package com.baeldung.logging.log4j2.simpleconfigurator; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -12,4 +13,4 @@ public class LogPrinter { logger.info("Info log message"); logger.error("Error log message"); } -} +} \ No newline at end of file diff --git a/logging-modules/log4j2-programmatic-configuration/simple-configurator/src/test/java/com/baeldung/log4j2/configure/LogTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfigurator/SimpleConfiguratorTest.java similarity index 60% rename from logging-modules/log4j2-programmatic-configuration/simple-configurator/src/test/java/com/baeldung/log4j2/configure/LogTest.java rename to logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfigurator/SimpleConfiguratorTest.java index a5a10426ac..03bf996120 100644 --- a/logging-modules/log4j2-programmatic-configuration/simple-configurator/src/test/java/com/baeldung/log4j2/configure/LogTest.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/simpleconfigurator/SimpleConfiguratorTest.java @@ -1,10 +1,11 @@ /** - This class demonstrates how to use ConfigurationBuilderFactory directly, - as described in Section 3 of "Programmatic Configuration with Log4j 2" -**/ + * This class demonstrates how to use ConfigurationBuilderFactory directly, + * as described in Section 3 of "Programmatic Configuration with Log4j 2" + **/ -package com.baeldung.log4j2.configure; +package com.baeldung.logging.log4j2.simpleconfigurator; +import com.baeldung.logging.log4j2.Log4j2Test; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.appender.ConsoleAppender; import org.apache.logging.log4j.core.config.Configurator; @@ -16,23 +17,22 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import com.baeldung.log4j2.logtest.LogPrinter; - @RunWith(JUnit4.class) -public class LogTest { +public class SimpleConfiguratorTest extends Log4j2Test { + @Test - public void simpleProgrammaticConfiguration() { + public void givenDefaultLog4j2Environment_whenProgrammaticallyConfigured_thenLogsCorrectly() { ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder(); AppenderComponentBuilder console = builder.newAppender("Stdout", "CONSOLE") - .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT); + .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT); console.add(builder.newLayout("PatternLayout") - .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable")); + .addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable")); builder.add(console); builder.add(builder.newLogger("com", Level.DEBUG) - .add(builder.newAppenderRef("Stdout")) - .addAttribute("additivity", false)); + .add(builder.newAppenderRef("Stdout")) + .addAttribute("additivity", false)); builder.add(builder.newRootLogger(Level.ERROR) - .add(builder.newAppenderRef("Stdout"))); + .add(builder.newAppenderRef("Stdout"))); Configurator.initialize(builder.build()); LogPrinter logPrinter = new LogPrinter(); logPrinter.printlog(); diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutTest.java index 9493c32094..7a6fbf999c 100644 --- a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutTest.java +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/tests/JSONLayoutTest.java @@ -6,6 +6,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; +import com.baeldung.logging.log4j2.Log4j2Test; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.Before; @@ -13,7 +14,7 @@ import org.junit.Test; import com.fasterxml.jackson.databind.ObjectMapper; -public class JSONLayoutTest { +public class JSONLayoutTest extends Log4j2Test { private static Logger logger; private ByteArrayOutputStream consoleOutput = new ByteArrayOutputStream(); diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/CustomXMLConfigurationFactory.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/CustomXMLConfigurationFactory.java new file mode 100644 index 0000000000..f2392d9f45 --- /dev/null +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/CustomXMLConfigurationFactory.java @@ -0,0 +1,24 @@ +package com.baeldung.logging.log4j2.xmlconfiguration; + +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.ConfigurationFactory; +import org.apache.logging.log4j.core.config.ConfigurationSource; +import org.apache.logging.log4j.core.config.Order; +import org.apache.logging.log4j.core.config.plugins.Plugin; +import org.apache.logging.log4j.core.config.xml.XmlConfigurationFactory; + +@Plugin(name = "xml", category = ConfigurationFactory.CATEGORY) +@Order(50) +public class CustomXMLConfigurationFactory extends XmlConfigurationFactory { + + @Override + public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) { + return new MyXMLConfiguration(loggerContext, source); + } + + @Override + public String[] getSupportedTypes() { + return new String[] { ".xml", "*" }; + } +} diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/MyXMLConfiguration.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/MyXMLConfiguration.java new file mode 100644 index 0000000000..25d2536694 --- /dev/null +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/MyXMLConfiguration.java @@ -0,0 +1,36 @@ +/** +This class demonstrates on overriding the configuration loaded through xml +as defined in section 4.4 of "Programmatic Configuration with Log4j 2" +**/ + +package com.baeldung.logging.log4j2.xmlconfiguration; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Layout; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.FileAppender; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.ConfigurationSource; +import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.logging.log4j.core.config.xml.XmlConfiguration; +import org.apache.logging.log4j.core.layout.PatternLayout; + +public class MyXMLConfiguration extends XmlConfiguration { + public MyXMLConfiguration(LoggerContext loggerContext, ConfigurationSource source) { + super(loggerContext, source); + } + + @Override + protected void doConfigure() { + super.doConfigure(); + final LoggerContext ctx = (LoggerContext) LogManager.getContext(false); + Configuration config = ctx.getConfiguration(); + LoggerConfig loggerConfig = config.getLoggerConfig("com"); + final Layout layout = PatternLayout.createLayout("[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n", null, config, null, null, false, false, null, null); + Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true", "false", "false", "4000", layout, null, "false", null, config); + loggerConfig.addAppender(appender, Level.DEBUG, null); + addAppender(appender); + } +} \ No newline at end of file diff --git a/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/XMLConfigLogTest.java b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/XMLConfigLogTest.java new file mode 100644 index 0000000000..41f733804a --- /dev/null +++ b/logging-modules/log4j2/src/test/java/com/baeldung/logging/log4j2/xmlconfiguration/XMLConfigLogTest.java @@ -0,0 +1,44 @@ + +/** + This class loads the logging configuration from the xml defined in + src/main/resources and uses the same configuration generated through + programmatic configuration as defined in simple-configuration example. +**/ + +package com.baeldung.logging.log4j2.xmlconfiguration; + +import com.baeldung.logging.log4j2.Log4j2Test; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.plugins.util.PluginManager; +import org.junit.BeforeClass; +import org.junit.Test; + +public class XMLConfigLogTest extends Log4j2Test { + + @BeforeClass + public static void setUp() { + PluginManager.addPackage("com.baeldung.logging.log4j2.xmlconfiguration"); + } + + @Test + public void givenXMLConfigurationPlugin_whenUsingFlowMarkers_ThenLogsCorrectly() throws Exception { + Logger logger = LogManager.getLogger(this.getClass()); + Marker markerContent = MarkerManager.getMarker("FLOW"); + logger.debug(markerContent, "Debug log message"); + logger.info(markerContent, "Info log message"); + logger.error(markerContent, "Error log message"); + } + + @Test + public void givenXMLConfigurationPlugin_whenSimpleLog_ThenLogsCorrectly() throws Exception { + Logger logger = LogManager.getLogger(this.getClass()); + LoggerContext ctx = (LoggerContext) LogManager.getContext(); + logger.debug("Debug log message"); + logger.info("Info log message"); + logger.error("Error log message"); + } +} diff --git a/pom.xml b/pom.xml index 16e826e4e9..452c7838f7 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,6 @@ logging-modules/log-mdc logging-modules/log4j logging-modules/log4j2 - logging-modules/log4j2-programmatic-configuration logging-modules/logback lombok mapstruct From 0f960f423df0e77841af668ecbe553cff9ceadcf Mon Sep 17 00:00:00 2001 From: Amit Pandey Date: Sun, 20 May 2018 10:05:03 +0530 Subject: [PATCH 91/93] Bael 5374 (#4266) * Added parent module on poms that have no parent defined * Removed dependency reduced pom from undertow module * [BAEL-5374] - Fix test names --- ...> TestSpringIntegrationSecurityExecutorIntegrationTest.java} | 2 +- ...y.java => TestSpringIntegrationSecurityIntegrationTest.java} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename spring-integration/src/test/java/com/baeldung/si/{TestSpringIntegrationSecurityExecutor.java => TestSpringIntegrationSecurityExecutorIntegrationTest.java} (95%) rename spring-integration/src/test/java/com/baeldung/si/{TestSpringIntegrationSecurity.java => TestSpringIntegrationSecurityIntegrationTest.java} (95%) diff --git a/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutor.java b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutorIntegrationTest.java similarity index 95% rename from spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutor.java rename to spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutorIntegrationTest.java index b06136a7ca..0246bda0e1 100644 --- a/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutor.java +++ b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityExecutorIntegrationTest.java @@ -23,7 +23,7 @@ import com.baeldung.si.security.SecurityPubSubChannel; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { SecurityPubSubChannel.class, MessageConsumer.class, SecurityConfig.class }) -public class TestSpringIntegrationSecurityExecutor { +public class TestSpringIntegrationSecurityExecutorIntegrationTest { @Autowired SubscribableChannel startPSChannel; diff --git a/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityIntegrationTest.java similarity index 95% rename from spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java rename to spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityIntegrationTest.java index 9ae82af2dc..eccab0bee6 100644 --- a/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurity.java +++ b/spring-integration/src/test/java/com/baeldung/si/TestSpringIntegrationSecurityIntegrationTest.java @@ -22,7 +22,7 @@ import com.baeldung.si.security.SecurityConfig; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { SecurityConfig.class, SecuredDirectChannel.class, MessageConsumer.class }) -public class TestSpringIntegrationSecurity { +public class TestSpringIntegrationSecurityIntegrationTest { @Rule public ExpectedException expectedException = ExpectedException.none(); From f1129ea16bb120281be8d0df9ed67cbf3c04b923 Mon Sep 17 00:00:00 2001 From: gautamshetty Date: Sun, 20 May 2018 03:16:46 -0500 Subject: [PATCH 92/93] BAEL 717 - Singleton Session Bean (#4104) * BAEL-717: Singleton EJB Bean Files for BAEL-717:Singleton EJB Bean. * BAEL-717: Singleton EJB Bean Corrected Indentation. * BAEL-717: Singleton EJB Bean Corrected Indentation. * BAEL-717: Singleton EJB Bean Corrected Indentation. * BAEL-717: Singleton EJB Bean Corrected Indentation. * BAEL-717: Singleton EJB Bean Changed artifactId value. * BAEL-717: Singleton EJB Bean. Added module for Singleton EJB Bean. * BAEL-717: Singleton EJB Bean. Removed Singleton EJB Bean Module. * BAEL-717: Singleton EJB Bean Changed the JNDI Lookup name. * BAEL-717: Singleton EJB Bean. Added the "singleton-ejb-bean" module. * BAEL-717: Singleton EJB Bean. Corrected Indentation. * BAEL-717: Singleton EJB Bean Corrected Indentation. * BAEL-717: Singleton EJB Bean. Corrected Indentation. * BAEL-717: Singleton EJB Bean. Corrected Indentation. * BAEL-717:Singleton EJB Bean. Corrected Indentation. * BAEL-717:Singleton EJB Bean. Corrected Indentation. * BAEL-717: Singleton Session Bean. Added class for Bean-Managed concurrrency. Changed class name from CountryStateCacheBean to CountryStateContainerManagedBean. * BAEL-717: Singleton Session Bean. Changing the name of the class to CountryStateContainerManagedBean. * BAEL-717: Singleton Session Bean. Added method to test Bean-Managed concurrency. * Get Latest. * deleting CountryStateBeanManagedBean for new file. * deleting CountryStateCacheBean for new file. * deleting CountryStateContainerManagedBean for new file. * BAEL-717: Singleton Session Bean. Adding file for Bean with Bean-Managed concurrency. Changing file name for original file to CountryStateContainerManagedBean with Container-Managed concurrency. * Deleting file for new checkin. * BAEL-717: Singleton Session Bean. Added test case for Bean-Manged concurrency. Change in JNDI names. * BAEL-717: Singleton Session Bean. Changed the assert method parameter order and null check in test cases. * BAEL-717:Singleton Session Bean Removed volatile keyword for the variable countryStatesMap. Marking it as final. * BAEL 717 - Singleton EJB Bean Added new method setStates(). * BAEL-717: Singleton Session Bean. Renaming directory singleton-ejb-bean to ejb-beans. * BAEL-717: Singleton EJB Beans. Renaming directory name from singleton-ejb-bean to ejb-beans. * BAEL-717: Singleton Session Bean Renaming directory singleton-ejb-bean to ejb-beans. --- .../{singleton-ejb-bean => ejb-beans}/pom.xml | 0 .../baeldung/singletonbean/CountryState.java | 2 + .../CountryStateBeanManagedBean.java | 6 ++- .../CountryStateContainerManagedBean.java | 5 +++ .../CountryStateCacheBeanTest.java | 38 ++++++++++++++++--- spring-ejb/pom.xml | 2 +- 6 files changed, 46 insertions(+), 7 deletions(-) rename spring-ejb/{singleton-ejb-bean => ejb-beans}/pom.xml (100%) rename spring-ejb/{singleton-ejb-bean => ejb-beans}/src/main/java/com/baeldung/singletonbean/CountryState.java (72%) rename spring-ejb/{singleton-ejb-bean => ejb-beans}/src/main/java/com/baeldung/singletonbean/CountryStateBeanManagedBean.java (85%) rename spring-ejb/{singleton-ejb-bean => ejb-beans}/src/main/java/com/baeldung/singletonbean/CountryStateContainerManagedBean.java (88%) rename spring-ejb/{singleton-ejb-bean => ejb-beans}/src/test/java/com/baeldung/singletonbean/CountryStateCacheBeanTest.java (52%) diff --git a/spring-ejb/singleton-ejb-bean/pom.xml b/spring-ejb/ejb-beans/pom.xml similarity index 100% rename from spring-ejb/singleton-ejb-bean/pom.xml rename to spring-ejb/ejb-beans/pom.xml diff --git a/spring-ejb/singleton-ejb-bean/src/main/java/com/baeldung/singletonbean/CountryState.java b/spring-ejb/ejb-beans/src/main/java/com/baeldung/singletonbean/CountryState.java similarity index 72% rename from spring-ejb/singleton-ejb-bean/src/main/java/com/baeldung/singletonbean/CountryState.java rename to spring-ejb/ejb-beans/src/main/java/com/baeldung/singletonbean/CountryState.java index a9a426ae32..1f96fdba7c 100644 --- a/spring-ejb/singleton-ejb-bean/src/main/java/com/baeldung/singletonbean/CountryState.java +++ b/spring-ejb/ejb-beans/src/main/java/com/baeldung/singletonbean/CountryState.java @@ -8,5 +8,7 @@ import javax.ejb.Local; public interface CountryState { public List getStates(String country); + + public void setStates(String country, List states); } diff --git a/spring-ejb/singleton-ejb-bean/src/main/java/com/baeldung/singletonbean/CountryStateBeanManagedBean.java b/spring-ejb/ejb-beans/src/main/java/com/baeldung/singletonbean/CountryStateBeanManagedBean.java similarity index 85% rename from spring-ejb/singleton-ejb-bean/src/main/java/com/baeldung/singletonbean/CountryStateBeanManagedBean.java rename to spring-ejb/ejb-beans/src/main/java/com/baeldung/singletonbean/CountryStateBeanManagedBean.java index ee2c1f005a..3ef7a62753 100644 --- a/spring-ejb/singleton-ejb-bean/src/main/java/com/baeldung/singletonbean/CountryStateBeanManagedBean.java +++ b/spring-ejb/ejb-beans/src/main/java/com/baeldung/singletonbean/CountryStateBeanManagedBean.java @@ -19,7 +19,7 @@ public class CountryStateBeanManagedBean implements CountryState { private final Map> countryStatesMap = new HashMap>(); @PostConstruct - public synchronized void initialize() { + public void initialize() { List states = new ArrayList(); states.add("Texas"); @@ -34,4 +34,8 @@ public class CountryStateBeanManagedBean implements CountryState { public List getStates(String country) { return countryStatesMap.get(country); } + + public synchronized void setStates(String country, List states) { + countryStatesMap.put(country, states); + } } diff --git a/spring-ejb/singleton-ejb-bean/src/main/java/com/baeldung/singletonbean/CountryStateContainerManagedBean.java b/spring-ejb/ejb-beans/src/main/java/com/baeldung/singletonbean/CountryStateContainerManagedBean.java similarity index 88% rename from spring-ejb/singleton-ejb-bean/src/main/java/com/baeldung/singletonbean/CountryStateContainerManagedBean.java rename to spring-ejb/ejb-beans/src/main/java/com/baeldung/singletonbean/CountryStateContainerManagedBean.java index ee16285824..0a970f4c5c 100644 --- a/spring-ejb/singleton-ejb-bean/src/main/java/com/baeldung/singletonbean/CountryStateContainerManagedBean.java +++ b/spring-ejb/ejb-beans/src/main/java/com/baeldung/singletonbean/CountryStateContainerManagedBean.java @@ -38,4 +38,9 @@ public class CountryStateContainerManagedBean implements CountryState { public List getStates(String country) { return countryStatesMap.get(country); } + + @Lock(LockType.WRITE) + public void setStates(String country, List states) { + countryStatesMap.put(country, states); + } } diff --git a/spring-ejb/singleton-ejb-bean/src/test/java/com/baeldung/singletonbean/CountryStateCacheBeanTest.java b/spring-ejb/ejb-beans/src/test/java/com/baeldung/singletonbean/CountryStateCacheBeanTest.java similarity index 52% rename from spring-ejb/singleton-ejb-bean/src/test/java/com/baeldung/singletonbean/CountryStateCacheBeanTest.java rename to spring-ejb/ejb-beans/src/test/java/com/baeldung/singletonbean/CountryStateCacheBeanTest.java index 62412084bd..2207431702 100644 --- a/spring-ejb/singleton-ejb-bean/src/test/java/com/baeldung/singletonbean/CountryStateCacheBeanTest.java +++ b/spring-ejb/ejb-beans/src/test/java/com/baeldung/singletonbean/CountryStateCacheBeanTest.java @@ -3,6 +3,8 @@ package com.baeldung.singletonbean; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertNotNull; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import javax.ejb.embeddable.EJBContainer; @@ -24,29 +26,55 @@ public class CountryStateCacheBeanTest { ejbContainer = EJBContainer.createEJBContainer(); context = ejbContainer.getContext(); } - + @Test public void whenCallGetStatesFromContainerManagedBean_ReturnsStatesForCountry() throws Exception { String[] expectedStates = { "Texas", "Alabama", "Alaska", "Arizona", "Arkansas" }; - CountryState countryStateBean = (CountryState) context.lookup("java:global/singleton-ejb-bean/CountryStateContainerManagedBean"); + CountryState countryStateBean = (CountryState) context.lookup("java:global/ejb-beans/CountryStateContainerManagedBean"); List actualStates = countryStateBean.getStates("UnitedStates"); assertNotNull(actualStates); assertArrayEquals(expectedStates, actualStates.toArray()); } - + @Test public void whenCallGetStatesFromBeanManagedBean_ReturnsStatesForCountry() throws Exception { String[] expectedStates = { "Texas", "Alabama", "Alaska", "Arizona", "Arkansas" }; - CountryState countryStateBean = (CountryState) context.lookup("java:global/singleton-ejb-bean/CountryStateBeanManagedBean"); + CountryState countryStateBean = (CountryState) context.lookup("java:global/ejb-beans/CountryStateBeanManagedBean"); List actualStates = countryStateBean.getStates("UnitedStates"); assertNotNull(actualStates); assertArrayEquals(expectedStates, actualStates.toArray()); } - + + @Test + public void whenCallSetStatesFromContainerManagedBean_SetsStatesForCountry() throws Exception { + + String[] expectedStates = { "California", "Florida", "Hawaii", "Pennsylvania", "Michigan" }; + + CountryState countryStateBean = (CountryState) context.lookup("java:global/ejb-beans/CountryStateContainerManagedBean"); + countryStateBean.setStates("UnitedStates", Arrays.asList(expectedStates)); + + List actualStates = countryStateBean.getStates("UnitedStates"); + assertNotNull(actualStates); + assertArrayEquals(expectedStates, actualStates.toArray()); + } + + @Test + public void whenCallSetStatesFromBeanManagedBean_SetsStatesForCountry() throws Exception { + + String[] expectedStates = { "California", "Florida", "Hawaii", "Pennsylvania", "Michigan" }; + + CountryState countryStateBean = (CountryState) context.lookup("java:global/ejb-beans/CountryStateBeanManagedBean"); + countryStateBean.setStates("UnitedStates", Arrays.asList(expectedStates)); + + List actualStates = countryStateBean.getStates("UnitedStates"); + assertNotNull(actualStates); + assertArrayEquals(expectedStates, actualStates.toArray()); + } + @After public void close() { if (ejbContainer != null) diff --git a/spring-ejb/pom.xml b/spring-ejb/pom.xml index bd0183d71d..188ba0b8fe 100755 --- a/spring-ejb/pom.xml +++ b/spring-ejb/pom.xml @@ -73,6 +73,6 @@ ejb-remote-for-spring spring-ejb-client - singleton-ejb-bean + ejb-beans From 444f059c8eed17852aca4751fcc13dd90e388558 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Sun, 20 May 2018 12:07:44 +0300 Subject: [PATCH 93/93] boot2 upgrade --- spring-security-mvc-boot/pom.xml | 35 +----- .../main/java/org/baeldung/Application.java | 19 --- .../org/baeldung/acl/config/ACLContext.java | 80 ------------ .../AclMethodSecurityConfiguration.java | 21 ---- .../acl/config/JPAPersistenceConfig.java | 16 --- .../dao/NoticeMessageRepository.java | 24 ---- .../acl/persistence/entity/NoticeMessage.java | 29 ----- .../baeldung/config/PersistenceConfig.java | 82 ------------ .../java/org/baeldung/custom/Application.java | 16 +++ .../config/MethodSecurityConfig.java | 6 +- .../{ => custom}/config/MvcConfig.java | 7 +- .../{ => custom}/config/SecurityConfig.java | 4 +- .../{ => custom}/persistence/SetupData.java | 14 +-- .../dao/OrganizationRepository.java | 4 +- .../persistence/dao/PrivilegeRepository.java | 4 +- .../persistence/dao/UserRepository.java | 4 +- .../{ => custom}/persistence/model/Foo.java | 2 +- .../persistence/model/Organization.java | 2 +- .../persistence/model/Privilege.java | 2 +- .../{ => custom}/persistence/model/User.java | 2 +- ...CustomMethodSecurityExpressionHandler.java | 2 +- .../CustomMethodSecurityExpressionRoot.java | 4 +- .../security/CustomPermissionEvaluator.java | 2 +- .../security/MySecurityExpressionRoot.java | 4 +- .../security/MyUserDetailsService.java | 6 +- .../security/MyUserPrincipal.java | 6 +- .../{ => custom}/web/MainController.java | 10 +- .../MultipleAuthController.java | 4 +- .../MultipleAuthProvidersSecurityConfig.java | 10 +- .../MultipleEntryPointsSecurityConfig.java | 11 +- .../multiplelogin/MultipleLoginMvcConfig.java | 5 +- .../MultipleLoginSecurityConfig.java | 18 +-- .../multiplelogin/UsersController.java | 14 +-- .../RolesAuthoritiesApplication.java | 2 +- .../rolesauthorities/config/MvcConfig.java | 5 +- .../persistence/PersistenceJPAConfig.java | 77 ------------ .../org/baeldung/voter/VoterMvcConfig.java | 3 +- .../org/baeldung/voter/WebSecurityConfig.java | 9 +- .../src/main/resources/acl-data.sql | 28 ----- .../src/main/resources/acl-schema.sql | 58 --------- .../application-rolesauthorities.properties | 10 -- .../src/main/resources/application.properties | 1 - .../org.baeldung.acl.datasource.properties | 12 -- .../resources/persistence-derby.properties | 12 -- .../src/main/resources/persistence.properties | 11 -- .../SpringContextIntegrationTest.java | 1 + .../acl/SpringAclIntegrationTest.java | 119 ------------------ .../org/baeldung/web/ApplicationLiveTest.java | 18 +-- ...stomUserDetailsServiceIntegrationTest.java | 12 +- 49 files changed, 130 insertions(+), 717 deletions(-) delete mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/Application.java delete mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/ACLContext.java delete mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java delete mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java delete mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java delete mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java delete mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/config/PersistenceConfig.java create mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/config/MethodSecurityConfig.java (84%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/config/MvcConfig.java (90%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/config/SecurityConfig.java (95%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/persistence/SetupData.java (84%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/persistence/dao/OrganizationRepository.java (65%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/persistence/dao/PrivilegeRepository.java (65%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/persistence/dao/UserRepository.java (76%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/persistence/model/Foo.java (97%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/persistence/model/Organization.java (97%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/persistence/model/Privilege.java (97%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/persistence/model/User.java (98%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/security/CustomMethodSecurityExpressionHandler.java (97%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/security/CustomMethodSecurityExpressionRoot.java (93%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/security/CustomPermissionEvaluator.java (97%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/security/MySecurityExpressionRoot.java (98%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/security/MyUserDetailsService.java (84%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/security/MyUserPrincipal.java (90%) rename spring-security-mvc-boot/src/main/java/org/baeldung/{ => custom}/web/MainController.java (86%) delete mode 100644 spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PersistenceJPAConfig.java delete mode 100644 spring-security-mvc-boot/src/main/resources/acl-data.sql delete mode 100644 spring-security-mvc-boot/src/main/resources/acl-schema.sql delete mode 100644 spring-security-mvc-boot/src/main/resources/application-rolesauthorities.properties delete mode 100644 spring-security-mvc-boot/src/main/resources/org.baeldung.acl.datasource.properties delete mode 100644 spring-security-mvc-boot/src/main/resources/persistence-derby.properties delete mode 100644 spring-security-mvc-boot/src/main/resources/persistence.properties delete mode 100644 spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java diff --git a/spring-security-mvc-boot/pom.xml b/spring-security-mvc-boot/pom.xml index bbc701313a..fe95461eab 100644 --- a/spring-security-mvc-boot/pom.xml +++ b/spring-security-mvc-boot/pom.xml @@ -12,10 +12,10 @@ Spring Security MVC Boot - parent-boot-5 + parent-boot-2 com.baeldung 0.0.1-SNAPSHOT - ../parent-boot-5 + ../parent-boot-2 @@ -79,26 +79,6 @@ test - - org.apache.derby - derby - ${derby.version} - - - org.apache.derby - derbyclient - ${derby.version} - - - org.apache.derby - derbynet - ${derby.version} - - - org.apache.derby - derbytools - ${derby.version} - taglibs standard @@ -107,13 +87,11 @@ org.springframework.security spring-security-taglibs - ${spring-security-taglibs.version} org.springframework.security spring-security-core - ${spring-security-core.version} @@ -122,10 +100,6 @@ ${jstl.version} - - org.springframework.security - spring-security-acl - org.springframework.security spring-security-config @@ -268,12 +242,7 @@ comment the tag above and uncomment the one below --> - 10.13.1.1 1.1.2 - 4.2.2.RELEASE - 4.2.2.RELEASE - 4.2.2.RELEASE - 1.2 1.6.1 diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java b/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java deleted file mode 100644 index 8a40744bdc..0000000000 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/Application.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.baeldung; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.web.support.SpringBootServletInitializer; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -@Configuration -@EnableAutoConfiguration -@ComponentScan({ "org.baeldung.config", "org.baeldung.persistence", "org.baeldung.security", "org.baeldung.web" }) -// @ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.voter.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multipleauthproviders.*"), -// @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multiplelogin.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.multipleentrypoints.*"), -// @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.rolesauthorities.*"), @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.baeldung.acl.*") }) -public class Application extends SpringBootServletInitializer { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/ACLContext.java b/spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/ACLContext.java deleted file mode 100644 index 63a4ea58ef..0000000000 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/ACLContext.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.baeldung.acl.config; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cache.ehcache.EhCacheFactoryBean; -import org.springframework.cache.ehcache.EhCacheManagerFactoryBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; -import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; -import org.springframework.security.acls.AclPermissionCacheOptimizer; -import org.springframework.security.acls.AclPermissionEvaluator; -import org.springframework.security.acls.domain.AclAuthorizationStrategy; -import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl; -import org.springframework.security.acls.domain.ConsoleAuditLogger; -import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy; -import org.springframework.security.acls.domain.EhCacheBasedAclCache; -import org.springframework.security.acls.jdbc.BasicLookupStrategy; -import org.springframework.security.acls.jdbc.JdbcMutableAclService; -import org.springframework.security.acls.jdbc.LookupStrategy; -import org.springframework.security.acls.model.PermissionGrantingStrategy; -import org.springframework.security.core.authority.SimpleGrantedAuthority; - -@Configuration -@EnableAutoConfiguration -public class ACLContext { - - @Autowired - DataSource dataSource; - - @Bean - public EhCacheBasedAclCache aclCache() { - return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(), permissionGrantingStrategy(), aclAuthorizationStrategy()); - } - - @Bean - public EhCacheFactoryBean aclEhCacheFactoryBean() { - EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean(); - ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject()); - ehCacheFactoryBean.setCacheName("aclCache"); - return ehCacheFactoryBean; - } - - @Bean - public EhCacheManagerFactoryBean aclCacheManager() { - return new EhCacheManagerFactoryBean(); - } - - @Bean - public PermissionGrantingStrategy permissionGrantingStrategy() { - return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger()); - } - - @Bean - public AclAuthorizationStrategy aclAuthorizationStrategy() { - return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN")); - } - - @Bean - public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() { - DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); - AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService()); - expressionHandler.setPermissionEvaluator(permissionEvaluator); - expressionHandler.setPermissionCacheOptimizer(new AclPermissionCacheOptimizer(aclService())); - return expressionHandler; - } - - @Bean - public LookupStrategy lookupStrategy() { - return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger()); - } - - @Bean - public JdbcMutableAclService aclService() { - return new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache()); - } - -} \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java b/spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java deleted file mode 100644 index 110c4a6d24..0000000000 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/AclMethodSecurityConfiguration.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.baeldung.acl.config; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; -import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; - -@Configuration -@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) -public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration { - - @Autowired - MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler; - - @Override - protected MethodSecurityExpressionHandler createExpressionHandler() { - return defaultMethodSecurityExpressionHandler; - } - -} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java deleted file mode 100644 index 9b87efa92c..0000000000 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/config/JPAPersistenceConfig.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.baeldung.acl.config; - -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -@Configuration -@EnableTransactionManagement -@EnableJpaRepositories(basePackages = "org.baeldung.acl.persistence.dao") -@PropertySource("classpath:org.baeldung.acl.datasource.properties") -@EntityScan(basePackages={ "org.baeldung.acl.persistence.entity" }) -public class JPAPersistenceConfig { - -} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java b/spring-security-mvc-boot/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java deleted file mode 100644 index 8662c88d6c..0000000000 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/persistence/dao/NoticeMessageRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.baeldung.acl.persistence.dao; - -import java.util.List; - -import org.baeldung.acl.persistence.entity.NoticeMessage; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.repository.query.Param; -import org.springframework.security.access.prepost.PostAuthorize; -import org.springframework.security.access.prepost.PostFilter; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface NoticeMessageRepository extends JpaRepository{ - - @PostFilter("hasPermission(filterObject, 'READ')") - List findAll(); - - @PostAuthorize("hasPermission(returnObject, 'READ')") - NoticeMessage findById(Integer id); - - @SuppressWarnings("unchecked") - @PreAuthorize("hasPermission(#noticeMessage, 'WRITE')") - NoticeMessage save(@Param("noticeMessage")NoticeMessage noticeMessage); - -} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java b/spring-security-mvc-boot/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java deleted file mode 100644 index 23f01a8edb..0000000000 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/acl/persistence/entity/NoticeMessage.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.baeldung.acl.persistence.entity; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; - -@Entity -@Table(name="system_message") -public class NoticeMessage { - - @Id - @Column - private Integer id; - @Column - private String content; - public Integer getId() { - return id; - } - public void setId(Integer id) { - this.id = id; - } - public String getContent() { - return content; - } - public void setContent(String content) { - this.content = content; - } -} \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/config/PersistenceConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/config/PersistenceConfig.java deleted file mode 100644 index 1c4cb0124a..0000000000 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/config/PersistenceConfig.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.baeldung.config; - -import java.util.Properties; - -import javax.persistence.EntityManagerFactory; -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -@Configuration -@EnableTransactionManagement -@PropertySource({ "classpath:persistence-derby.properties" }) -@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao") -public class PersistenceConfig { - - @Autowired - private Environment env; - - public PersistenceConfig() { - super(); - } - - // beans - - @Bean - public LocalContainerEntityManagerFactoryBean entityManagerFactory() { - final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); - em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.persistence.model" }); - - final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); - em.setJpaVendorAdapter(vendorAdapter); - em.setJpaProperties(additionalProperties()); - - return em; - } - - @Bean - public DataSource dataSource() { - final DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); - dataSource.setUrl(env.getProperty("jdbc.url")); - dataSource.setUsername(env.getProperty("jdbc.user")); - dataSource.setPassword(env.getProperty("jdbc.pass")); - - return dataSource; - } - - @Bean - public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) { - final JpaTransactionManager transactionManager = new JpaTransactionManager(); - transactionManager.setEntityManagerFactory(emf); - return transactionManager; - } - - @Bean - public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { - return new PersistenceExceptionTranslationPostProcessor(); - } - - final Properties additionalProperties() { - final Properties hibernateProperties = new Properties(); - hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); - hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); - hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", env.getProperty("hibernate.cache.use_second_level_cache")); - hibernateProperties.setProperty("hibernate.cache.use_query_cache", env.getProperty("hibernate.cache.use_query_cache")); - // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true"); - return hibernateProperties; - } -} \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java new file mode 100644 index 0000000000..f932ac3066 --- /dev/null +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/Application.java @@ -0,0 +1,16 @@ +package org.baeldung.custom; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@SpringBootApplication +public class Application extends SpringBootServletInitializer { + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/config/MethodSecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java similarity index 84% rename from spring-security-mvc-boot/src/main/java/org/baeldung/config/MethodSecurityConfig.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java index c4624e85e0..6a005153dc 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/config/MethodSecurityConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MethodSecurityConfig.java @@ -1,7 +1,7 @@ -package org.baeldung.config; +package org.baeldung.custom.config; -import org.baeldung.security.CustomMethodSecurityExpressionHandler; -import org.baeldung.security.CustomPermissionEvaluator; +import org.baeldung.custom.security.CustomMethodSecurityExpressionHandler; +import org.baeldung.custom.security.CustomPermissionEvaluator; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/config/MvcConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MvcConfig.java similarity index 90% rename from spring-security-mvc-boot/src/main/java/org/baeldung/config/MvcConfig.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MvcConfig.java index 9ade60e54c..58d11ea9ae 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/config/MvcConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/MvcConfig.java @@ -1,4 +1,4 @@ -package org.baeldung.config; +package org.baeldung.custom.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -7,11 +7,11 @@ import org.springframework.web.servlet.config.annotation.DefaultServletHandlerCo import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @EnableWebMvc -public class MvcConfig extends WebMvcConfigurerAdapter { +public class MvcConfig implements WebMvcConfigurer { public MvcConfig() { super(); @@ -30,7 +30,6 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); registry.addViewController("/").setViewName("forward:/index"); registry.addViewController("/index"); } diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/config/SecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/SecurityConfig.java similarity index 95% rename from spring-security-mvc-boot/src/main/java/org/baeldung/config/SecurityConfig.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/SecurityConfig.java index acb7e6820a..f2da5af92c 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/config/SecurityConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/config/SecurityConfig.java @@ -1,6 +1,6 @@ -package org.baeldung.config; +package org.baeldung.custom.config; -import org.baeldung.security.MyUserDetailsService; +import org.baeldung.custom.security.MyUserDetailsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/SetupData.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/SetupData.java similarity index 84% rename from spring-security-mvc-boot/src/main/java/org/baeldung/persistence/SetupData.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/SetupData.java index 2cc86167e2..f0fcce3908 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/SetupData.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/SetupData.java @@ -1,16 +1,16 @@ -package org.baeldung.persistence; +package org.baeldung.custom.persistence; import java.util.Arrays; import java.util.HashSet; import javax.annotation.PostConstruct; -import org.baeldung.persistence.dao.OrganizationRepository; -import org.baeldung.persistence.dao.PrivilegeRepository; -import org.baeldung.persistence.dao.UserRepository; -import org.baeldung.persistence.model.Organization; -import org.baeldung.persistence.model.Privilege; -import org.baeldung.persistence.model.User; +import org.baeldung.custom.persistence.dao.OrganizationRepository; +import org.baeldung.custom.persistence.dao.PrivilegeRepository; +import org.baeldung.custom.persistence.dao.UserRepository; +import org.baeldung.custom.persistence.model.Organization; +import org.baeldung.custom.persistence.model.Privilege; +import org.baeldung.custom.persistence.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/dao/OrganizationRepository.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java similarity index 65% rename from spring-security-mvc-boot/src/main/java/org/baeldung/persistence/dao/OrganizationRepository.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java index a20d24057b..1319a7b9f8 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/dao/OrganizationRepository.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/OrganizationRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.dao; +package org.baeldung.custom.persistence.dao; -import org.baeldung.persistence.model.Organization; +import org.baeldung.custom.persistence.model.Organization; import org.springframework.data.jpa.repository.JpaRepository; public interface OrganizationRepository extends JpaRepository { diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/dao/PrivilegeRepository.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java similarity index 65% rename from spring-security-mvc-boot/src/main/java/org/baeldung/persistence/dao/PrivilegeRepository.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java index edf9002c3d..c232bb986c 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/dao/PrivilegeRepository.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/PrivilegeRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.dao; +package org.baeldung.custom.persistence.dao; -import org.baeldung.persistence.model.Privilege; +import org.baeldung.custom.persistence.model.Privilege; import org.springframework.data.jpa.repository.JpaRepository; public interface PrivilegeRepository extends JpaRepository { diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/dao/UserRepository.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java similarity index 76% rename from spring-security-mvc-boot/src/main/java/org/baeldung/persistence/dao/UserRepository.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java index 337106a187..68dd1d756c 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/dao/UserRepository.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/dao/UserRepository.java @@ -1,6 +1,6 @@ -package org.baeldung.persistence.dao; +package org.baeldung.custom.persistence.dao; -import org.baeldung.persistence.model.User; +import org.baeldung.custom.persistence.model.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.transaction.annotation.Transactional; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/Foo.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Foo.java similarity index 97% rename from spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/Foo.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Foo.java index 29c19cf22e..f139382eea 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/Foo.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Foo.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package org.baeldung.custom.persistence.model; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/Organization.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Organization.java similarity index 97% rename from spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/Organization.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Organization.java index 645285b5e9..1fdb88e320 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/Organization.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Organization.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package org.baeldung.custom.persistence.model; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/Privilege.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Privilege.java similarity index 97% rename from spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/Privilege.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Privilege.java index ff3ae62c25..ed3edd5085 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/Privilege.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/Privilege.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package org.baeldung.custom.persistence.model; import javax.persistence.Column; import javax.persistence.Entity; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/User.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/User.java similarity index 98% rename from spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/User.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/User.java index 2ff8beebf0..c14ef034b4 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/persistence/model/User.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/persistence/model/User.java @@ -1,4 +1,4 @@ -package org.baeldung.persistence.model; +package org.baeldung.custom.persistence.model; import java.util.Set; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionHandler.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java similarity index 97% rename from spring-security-mvc-boot/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionHandler.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java index e040a0b109..646f5a387f 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionHandler.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionHandler.java @@ -1,4 +1,4 @@ -package org.baeldung.security; +package org.baeldung.custom.security; import org.aopalliance.intercept.MethodInvocation; import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java similarity index 93% rename from spring-security-mvc-boot/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java index 2d84536a14..b2f2be8cf5 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/security/CustomMethodSecurityExpressionRoot.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomMethodSecurityExpressionRoot.java @@ -1,6 +1,6 @@ -package org.baeldung.security; +package org.baeldung.custom.security; -import org.baeldung.persistence.model.User; +import org.baeldung.custom.persistence.model.User; import org.springframework.security.access.expression.SecurityExpressionRoot; import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; import org.springframework.security.core.Authentication; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java similarity index 97% rename from spring-security-mvc-boot/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java index 5d96673a8f..f436b4488b 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/security/CustomPermissionEvaluator.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/CustomPermissionEvaluator.java @@ -1,4 +1,4 @@ -package org.baeldung.security; +package org.baeldung.custom.security; import java.io.Serializable; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java similarity index 98% rename from spring-security-mvc-boot/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java index 4d3561b325..03d18cb755 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/security/MySecurityExpressionRoot.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MySecurityExpressionRoot.java @@ -1,11 +1,11 @@ -package org.baeldung.security; +package org.baeldung.custom.security; import java.io.Serializable; import java.util.Collection; import java.util.HashSet; import java.util.Set; -import org.baeldung.persistence.model.User; +import org.baeldung.custom.persistence.model.User; import org.springframework.security.access.PermissionEvaluator; import org.springframework.security.access.expression.method.MethodSecurityExpressionOperations; import org.springframework.security.access.hierarchicalroles.RoleHierarchy; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/security/MyUserDetailsService.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java similarity index 84% rename from spring-security-mvc-boot/src/main/java/org/baeldung/security/MyUserDetailsService.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java index 685219728f..b9b40fbcb9 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/security/MyUserDetailsService.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserDetailsService.java @@ -1,7 +1,7 @@ -package org.baeldung.security; +package org.baeldung.custom.security; -import org.baeldung.persistence.dao.UserRepository; -import org.baeldung.persistence.model.User; +import org.baeldung.custom.persistence.dao.UserRepository; +import org.baeldung.custom.persistence.model.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/security/MyUserPrincipal.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java similarity index 90% rename from spring-security-mvc-boot/src/main/java/org/baeldung/security/MyUserPrincipal.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java index 437bb02cdb..7d57227316 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/security/MyUserPrincipal.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/security/MyUserPrincipal.java @@ -1,11 +1,11 @@ -package org.baeldung.security; +package org.baeldung.custom.security; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.baeldung.persistence.model.Privilege; -import org.baeldung.persistence.model.User; +import org.baeldung.custom.persistence.model.Privilege; +import org.baeldung.custom.persistence.model.User; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/web/MainController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/web/MainController.java similarity index 86% rename from spring-security-mvc-boot/src/main/java/org/baeldung/web/MainController.java rename to spring-security-mvc-boot/src/main/java/org/baeldung/custom/web/MainController.java index 4752f7bdd9..6572954427 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/web/MainController.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/custom/web/MainController.java @@ -1,8 +1,8 @@ -package org.baeldung.web; +package org.baeldung.custom.web; -import org.baeldung.persistence.dao.OrganizationRepository; -import org.baeldung.persistence.model.Foo; -import org.baeldung.persistence.model.Organization; +import org.baeldung.custom.persistence.dao.OrganizationRepository; +import org.baeldung.custom.persistence.model.Foo; +import org.baeldung.custom.persistence.model.Organization; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -52,7 +52,7 @@ public class MainController { @RequestMapping(method = RequestMethod.GET, value = "/organizations/{id}") @ResponseBody public Organization findOrgById(@PathVariable final long id) { - return organizationRepository.findOne(id); + return organizationRepository.findById(id).orElse(null); } } diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java index 80573c1c7d..b63169bb00 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthController.java @@ -1,12 +1,12 @@ package org.baeldung.multipleauthproviders; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class MultipleAuthController { - @RequestMapping("/api/ping") + @GetMapping("/api/ping") public String getPing() { return "OK"; } diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java index 432cc61e87..3819e981a2 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleauthproviders/MultipleAuthProvidersSecurityConfig.java @@ -1,10 +1,13 @@ package org.baeldung.multipleauthproviders; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; @EnableWebSecurity public class MultipleAuthProvidersSecurityConfig extends WebSecurityConfigurerAdapter { @@ -19,7 +22,7 @@ public class MultipleAuthProvidersSecurityConfig extends WebSecurityConfigurerAd auth.inMemoryAuthentication() .withUser("memuser") - .password("pass") + .password(passwordEncoder().encode("pass")) .roles("USER"); } @@ -31,4 +34,9 @@ public class MultipleAuthProvidersSecurityConfig extends WebSecurityConfigurerAd .antMatchers("/api/**") .authenticated(); } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } } diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java index 9f2eba0a2e..dc89c83cde 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multipleentrypoints/MultipleEntryPointsSecurityConfig.java @@ -8,6 +8,8 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; 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.InMemoryUserDetailsManager; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; @@ -21,10 +23,15 @@ public class MultipleEntryPointsSecurityConfig { @Bean public UserDetailsService userDetailsService() throws Exception { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser(User.withUsername("user").password("userPass").roles("USER").build()); - manager.createUser(User.withUsername("admin").password("adminPass").roles("ADMIN").build()); + manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); + manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); return manager; } + + @Bean + public PasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } @Configuration @Order(1) diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java index ec76be1909..204b186411 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginMvcConfig.java @@ -5,6 +5,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; import org.springframework.web.servlet.view.JstlView; @@ -13,7 +14,7 @@ import org.springframework.context.annotation.ComponentScan; @EnableWebMvc @Configuration @ComponentScan("org.baeldung.controller") -public class MultipleLoginMvcConfig extends WebMvcConfigurerAdapter { +public class MultipleLoginMvcConfig implements WebMvcConfigurer { public MultipleLoginMvcConfig() { super(); @@ -23,8 +24,6 @@ public class MultipleLoginMvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); - registry.addViewController("/anonymous.html"); registry.addViewController("/login.html"); diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java index 8327e7e5d3..9962bf41a9 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/MultipleLoginSecurityConfig.java @@ -1,17 +1,16 @@ package org.baeldung.multiplelogin; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; -import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.authentication.TestingAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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.User; 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.InMemoryUserDetailsManager; @Configuration @@ -21,10 +20,15 @@ public class MultipleLoginSecurityConfig { @Bean public UserDetailsService userDetailsService() throws Exception { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); - manager.createUser(User.withUsername("user").password("userPass").roles("USER").build()); - manager.createUser(User.withUsername("admin").password("adminPass").roles("ADMIN").build()); + manager.createUser(User.withUsername("user").password(encoder().encode("userPass")).roles("USER").build()); + manager.createUser(User.withUsername("admin").password(encoder().encode("adminPass")).roles("ADMIN").build()); return manager; } + + @Bean + public static PasswordEncoder encoder() { + return new BCryptPasswordEncoder(); + } @Configuration @Order(1) @@ -36,7 +40,7 @@ public class MultipleLoginSecurityConfig { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN"); + auth.inMemoryAuthentication().withUser("admin").password(encoder().encode("admin")).roles("ADMIN"); } @Override @@ -59,7 +63,7 @@ public class MultipleLoginSecurityConfig { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { - auth.inMemoryAuthentication().withUser("user").password("user").roles("USER"); + auth.inMemoryAuthentication().withUser("user").password(encoder().encode("user")).roles("USER"); } protected void configure(HttpSecurity http) throws Exception { diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java b/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java index 0672a760af..61d7da127c 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/multiplelogin/UsersController.java @@ -1,37 +1,37 @@ package org.baeldung.multiplelogin; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.GetMapping; @Controller public class UsersController { - @RequestMapping("/protectedLinks") + @GetMapping("/protectedLinks") public String getAnonymousPage() { return "protectedLinks"; } - @RequestMapping("/userPage") + @GetMapping("/userPage") public String getUserPage() { return "userPage"; } - @RequestMapping("/adminPage") + @GetMapping("/adminPage") public String getAdminPage() { return "adminPage"; } - @RequestMapping("/loginAdmin") + @GetMapping("/loginAdmin") public String getAdminLoginPage() { return "loginAdmin"; } - @RequestMapping("/loginUser") + @GetMapping("/loginUser") public String getUserLoginPage() { return "loginUser"; } - @RequestMapping("/403") + @GetMapping("/403") public String getAccessDeniedPage() { return "403"; } diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java b/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java index 1c55c145b3..3c4e6f7b5a 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/RolesAuthoritiesApplication.java @@ -2,7 +2,7 @@ package org.baeldung.rolesauthorities; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.web.support.SpringBootServletInitializer; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java index d2edfed749..c42958457e 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/config/MvcConfig.java @@ -7,11 +7,11 @@ import org.springframework.web.servlet.config.annotation.DefaultServletHandlerCo import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration @EnableWebMvc -public class MvcConfig extends WebMvcConfigurerAdapter { +public class MvcConfig implements WebMvcConfigurer { public MvcConfig() { super(); @@ -30,7 +30,6 @@ public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); registry.addViewController("/").setViewName("forward:/home"); registry.addViewController("/protectedbynothing").setViewName("rolesauthorities/protectedbynothing"); registry.addViewController("/protectedbyrole").setViewName("rolesauthorities/protectedbyrole"); diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PersistenceJPAConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PersistenceJPAConfig.java deleted file mode 100644 index a993e41a83..0000000000 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/rolesauthorities/persistence/PersistenceJPAConfig.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.baeldung.rolesauthorities.persistence; - -import java.util.Properties; - -import javax.sql.DataSource; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.core.env.Environment; -import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.jdbc.datasource.DriverManagerDataSource; -import org.springframework.orm.jpa.JpaTransactionManager; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; -import org.springframework.transaction.annotation.EnableTransactionManagement; - -@Configuration -@EnableTransactionManagement -@PropertySource({ "classpath:persistence.properties" }) -@ComponentScan({ "org.baeldung.rolesauthorities.persistence" }) -@EnableJpaRepositories(basePackages = "org.baeldung.rolesauthorities.persistence") -public class PersistenceJPAConfig { - - @Autowired - private Environment env; - - public PersistenceJPAConfig() { - super(); - } - - // - - @Bean - public LocalContainerEntityManagerFactoryBean entityManagerFactory() { - LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); - em.setDataSource(dataSource()); - em.setPackagesToScan(new String[] { "org.baeldung.rolesauthorities" }); - HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); - em.setJpaVendorAdapter(vendorAdapter); - em.setJpaProperties(additionalProperties()); - return em; - } - - @Bean - public DataSource dataSource() { - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); - dataSource.setUrl(env.getProperty("jdbc.url")); - dataSource.setUsername(env.getProperty("jdbc.user")); - dataSource.setPassword(env.getProperty("jdbc.pass")); - return dataSource; - } - - @Bean - public JpaTransactionManager transactionManager() { - JpaTransactionManager transactionManager = new JpaTransactionManager(); - transactionManager.setEntityManagerFactory(entityManagerFactory().getObject()); - return transactionManager; - } - - @Bean - public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { - return new PersistenceExceptionTranslationPostProcessor(); - } - - protected Properties additionalProperties() { - Properties hibernateProperties = new Properties(); - hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); - hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect")); - return hibernateProperties; - } - -} diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java index e282c794d0..8f41153f06 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/voter/VoterMvcConfig.java @@ -3,6 +3,7 @@ package org.baeldung.voter; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; /** @@ -10,7 +11,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter */ @Configuration -public class VoterMvcConfig extends WebMvcConfigurerAdapter { +public class VoterMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("private"); diff --git a/spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java b/spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java index 06fb4d2316..84ed070e8e 100644 --- a/spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java +++ b/spring-security-mvc-boot/src/main/java/org/baeldung/voter/WebSecurityConfig.java @@ -12,6 +12,8 @@ import org.springframework.security.config.annotation.authentication.builders.Au 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.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.access.expression.WebExpressionVoter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @@ -24,7 +26,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { // @formatter: off - auth.inMemoryAuthentication().withUser("user").password("pass").roles("USER").and().withUser("admin").password("pass").roles("ADMIN"); + auth.inMemoryAuthentication().withUser("user").password(passwordEncoder().encode("pass")).roles("USER").and().withUser("admin").password(passwordEncoder().encode("pass")).roles("ADMIN"); // @formatter: on } @@ -45,4 +47,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { // @formatter: on return new UnanimousBased(decisionVoters); } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } } diff --git a/spring-security-mvc-boot/src/main/resources/acl-data.sql b/spring-security-mvc-boot/src/main/resources/acl-data.sql deleted file mode 100644 index 6c01eaacc2..0000000000 --- a/spring-security-mvc-boot/src/main/resources/acl-data.sql +++ /dev/null @@ -1,28 +0,0 @@ -INSERT INTO system_message(id,content) VALUES (1,'First Level Message'); -INSERT INTO system_message(id,content) VALUES (2,'Second Level Message'); -INSERT INTO system_message(id,content) VALUES (3,'Third Level Message'); - -INSERT INTO acl_class (id, class) VALUES -(1, 'org.baeldung.acl.persistence.entity.NoticeMessage'); - -INSERT INTO acl_sid (id, principal, sid) VALUES -(1, 1, 'manager'), -(2, 1, 'hr'), -(3, 1, 'admin'), -(4, 0, 'ROLE_EDITOR'); - -INSERT INTO acl_object_identity (id, object_id_class, object_id_identity, parent_object, owner_sid, entries_inheriting) VALUES -(1, 1, 1, NULL, 3, 0), -(2, 1, 2, NULL, 3, 0), -(3, 1, 3, NULL, 3, 0) -; - -INSERT INTO acl_entry (id, acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure) VALUES -(1, 1, 1, 1, 1, 1, 1, 1), -(2, 1, 2, 1, 2, 1, 1, 1), -(3, 1, 3, 4, 1, 1, 1, 1), -(4, 2, 1, 2, 1, 1, 1, 1), -(5, 2, 2, 4, 1, 1, 1, 1), -(6, 3, 1, 4, 1, 1, 1, 1), -(7, 3, 2, 4, 2, 1, 1, 1) -; \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/acl-schema.sql b/spring-security-mvc-boot/src/main/resources/acl-schema.sql deleted file mode 100644 index 58e9394b2b..0000000000 --- a/spring-security-mvc-boot/src/main/resources/acl-schema.sql +++ /dev/null @@ -1,58 +0,0 @@ -create table system_message (id integer not null, content varchar(255), primary key (id)); - -CREATE TABLE IF NOT EXISTS acl_sid ( - id bigint(20) NOT NULL AUTO_INCREMENT, - principal tinyint(1) NOT NULL, - sid varchar(100) NOT NULL, - PRIMARY KEY (id), - UNIQUE KEY unique_uk_1 (sid,principal) -); - -CREATE TABLE IF NOT EXISTS acl_class ( - id bigint(20) NOT NULL AUTO_INCREMENT, - class varchar(255) NOT NULL, - PRIMARY KEY (id), - UNIQUE KEY unique_uk_2 (class) -); - -CREATE TABLE IF NOT EXISTS acl_entry ( - id bigint(20) NOT NULL AUTO_INCREMENT, - acl_object_identity bigint(20) NOT NULL, - ace_order int(11) NOT NULL, - sid bigint(20) NOT NULL, - mask int(11) NOT NULL, - granting tinyint(1) NOT NULL, - audit_success tinyint(1) NOT NULL, - audit_failure tinyint(1) NOT NULL, - PRIMARY KEY (id), - UNIQUE KEY unique_uk_4 (acl_object_identity,ace_order) -); - -CREATE TABLE IF NOT EXISTS acl_object_identity ( - id bigint(20) NOT NULL AUTO_INCREMENT, - object_id_class bigint(20) NOT NULL, - object_id_identity bigint(20) NOT NULL, - parent_object bigint(20) DEFAULT NULL, - owner_sid bigint(20) DEFAULT NULL, - entries_inheriting tinyint(1) NOT NULL, - PRIMARY KEY (id), - UNIQUE KEY unique_uk_3 (object_id_class,object_id_identity) -); - -ALTER TABLE acl_entry -ADD FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity(id); - -ALTER TABLE acl_entry -ADD FOREIGN KEY (sid) REFERENCES acl_sid(id); - --- --- Constraints for table acl_object_identity --- -ALTER TABLE acl_object_identity -ADD FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id); - -ALTER TABLE acl_object_identity -ADD FOREIGN KEY (object_id_class) REFERENCES acl_class (id); - -ALTER TABLE acl_object_identity -ADD FOREIGN KEY (owner_sid) REFERENCES acl_sid (id); \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/application-rolesauthorities.properties b/spring-security-mvc-boot/src/main/resources/application-rolesauthorities.properties deleted file mode 100644 index 030c79c542..0000000000 --- a/spring-security-mvc-boot/src/main/resources/application-rolesauthorities.properties +++ /dev/null @@ -1,10 +0,0 @@ -server.port=8082 -server.context-path=/ -spring.datasource.driver-class-name=org.h2.Driver -spring.datasource.url=jdbc:h2:mem:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.username=sa -spring.datasource.password= -spring.jpa.hibernate.ddl-auto=create-drop -spring.jpa.database=H2 -spring.jpa.show-sql=false -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/application.properties b/spring-security-mvc-boot/src/main/resources/application.properties index d29b5f6bf1..f015086a4f 100644 --- a/spring-security-mvc-boot/src/main/resources/application.properties +++ b/spring-security-mvc-boot/src/main/resources/application.properties @@ -1,5 +1,4 @@ server.port=8082 -server.context-path=/spring-security-mvc-boot spring.datasource.driver-class-name=org.h2.Driver spring.datasource.url=jdbc:h2:mem:security_permission;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE spring.datasource.username=sa diff --git a/spring-security-mvc-boot/src/main/resources/org.baeldung.acl.datasource.properties b/spring-security-mvc-boot/src/main/resources/org.baeldung.acl.datasource.properties deleted file mode 100644 index 739dd3f07c..0000000000 --- a/spring-security-mvc-boot/src/main/resources/org.baeldung.acl.datasource.properties +++ /dev/null @@ -1,12 +0,0 @@ -spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE -spring.datasource.username=sa -spring.datasource.password= -spring.datasource.driverClassName=org.h2.Driver -spring.jpa.hibernate.ddl-auto=update -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect - -spring.h2.console.path=/myconsole -spring.h2.console.enabled=true -spring.datasource.initialize=true -spring.datasource.schema=classpath:acl-schema.sql -spring.datasource.data=classpath:acl-data.sql \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/persistence-derby.properties b/spring-security-mvc-boot/src/main/resources/persistence-derby.properties deleted file mode 100644 index e808fdc288..0000000000 --- a/spring-security-mvc-boot/src/main/resources/persistence-derby.properties +++ /dev/null @@ -1,12 +0,0 @@ -# jdbc.X -jdbc.driverClassName=org.apache.derby.jdbc.EmbeddedDriver -jdbc.url=jdbc:derby:memory:spring_custom_user_service;create=true -jdbc.user=tutorialuser -jdbc.pass=tutorialpass - -# hibernate.X -hibernate.dialect=org.hibernate.dialect.DerbyDialect -hibernate.show_sql=false -hibernate.hbm2ddl.auto=create -hibernate.cache.use_second_level_cache=false -hibernate.cache.use_query_cache=false \ No newline at end of file diff --git a/spring-security-mvc-boot/src/main/resources/persistence.properties b/spring-security-mvc-boot/src/main/resources/persistence.properties deleted file mode 100644 index b2255cd479..0000000000 --- a/spring-security-mvc-boot/src/main/resources/persistence.properties +++ /dev/null @@ -1,11 +0,0 @@ -####### H2 -#################### DataSource Configuration ########################## -jdbc.driverClassName=org.h2.Driver -jdbc.url=jdbc:h2:mem:registration_02;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE -jdbc.user=sa -jdbc.pass= -init-db=false -#################### Hibernate Configuration ########################## -hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.show_sql=false -hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java index cf1ac7de89..f01cac1c87 100644 --- a/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/SpringContextIntegrationTest.java @@ -1,5 +1,6 @@ package org.baeldung; +import org.baeldung.custom.Application; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java deleted file mode 100644 index 38e1a2a9e7..0000000000 --- a/spring-security-mvc-boot/src/test/java/org/baeldung/acl/SpringAclIntegrationTest.java +++ /dev/null @@ -1,119 +0,0 @@ -package org.baeldung.acl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.List; - -import org.baeldung.acl.persistence.dao.NoticeMessageRepository; -import org.baeldung.acl.persistence.entity.NoticeMessage; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.access.AccessDeniedException; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestExecutionListeners; -import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; -import org.springframework.test.context.support.DirtiesContextTestExecutionListener; -import org.springframework.test.context.transaction.TransactionalTestExecutionListener; -import org.springframework.test.context.web.ServletTestExecutionListener; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -@TestExecutionListeners(listeners={ServletTestExecutionListener.class, - DependencyInjectionTestExecutionListener.class, - DirtiesContextTestExecutionListener.class, - TransactionalTestExecutionListener.class, - WithSecurityContextTestExecutionListener.class}) -public class SpringAclIntegrationTest extends AbstractJUnit4SpringContextTests{ - - private static Integer FIRST_MESSAGE_ID = 1; - private static Integer SECOND_MESSAGE_ID = 2; - private static Integer THIRD_MESSAGE_ID = 3; - private static String EDITTED_CONTENT = "EDITED"; - - @Configuration - @ComponentScan("org.baeldung.acl.*") - public static class SpringConfig { - - } - - @Autowired - NoticeMessageRepository repo; - - @Test - @WithMockUser(username="manager") - public void givenUsernameManager_whenFindAllMessage_thenReturnFirstMessage(){ - List details = repo.findAll(); - assertNotNull(details); - assertEquals(1,details.size()); - assertEquals(FIRST_MESSAGE_ID,details.get(0).getId()); - } - - @Test - @WithMockUser(username="manager") - public void givenUsernameManager_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenOK(){ - NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); - assertNotNull(firstMessage); - assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); - - firstMessage.setContent(EDITTED_CONTENT); - repo.save(firstMessage); - - NoticeMessage editedFirstMessage = repo.findById(FIRST_MESSAGE_ID); - assertNotNull(editedFirstMessage); - assertEquals(FIRST_MESSAGE_ID,editedFirstMessage.getId()); - assertEquals(EDITTED_CONTENT,editedFirstMessage.getContent()); - } - - @Test - @WithMockUser(username="hr") - public void givenUsernameHr_whenFindMessageById2_thenOK(){ - NoticeMessage secondMessage = repo.findById(SECOND_MESSAGE_ID); - assertNotNull(secondMessage); - assertEquals(SECOND_MESSAGE_ID,secondMessage.getId()); - } - - @Test(expected=AccessDeniedException.class) - @WithMockUser(username="hr") - public void givenUsernameHr_whenUpdateMessageWithId2_thenFail(){ - NoticeMessage secondMessage = new NoticeMessage(); - secondMessage.setId(SECOND_MESSAGE_ID); - secondMessage.setContent(EDITTED_CONTENT); - repo.save(secondMessage); - } - - @Test - @WithMockUser(roles={"EDITOR"}) - public void givenRoleEditor_whenFindAllMessage_thenReturnThreeMessage(){ - List details = repo.findAll(); - assertNotNull(details); - assertEquals(3,details.size()); - } - - @Test - @WithMockUser(roles={"EDITOR"}) - public void givenRoleEditor_whenUpdateThirdMessage_thenOK(){ - NoticeMessage thirdMessage = new NoticeMessage(); - thirdMessage.setId(THIRD_MESSAGE_ID); - thirdMessage.setContent(EDITTED_CONTENT); - repo.save(thirdMessage); - } - - @Test(expected=AccessDeniedException.class) - @WithMockUser(roles={"EDITOR"}) - public void givenRoleEditor_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenFail(){ - NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID); - assertNotNull(firstMessage); - assertEquals(FIRST_MESSAGE_ID,firstMessage.getId()); - firstMessage.setContent(EDITTED_CONTENT); - repo.save(firstMessage); - } -} - \ No newline at end of file diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java index 371e53070d..dfcfcad609 100644 --- a/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/ApplicationLiveTest.java @@ -2,12 +2,14 @@ package org.baeldung.web; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; + +import org.baeldung.custom.persistence.model.Foo; + import io.restassured.RestAssured; import io.restassured.authentication.FormAuthConfig; import io.restassured.response.Response; import io.restassured.specification.RequestSpecification; -import org.baeldung.persistence.model.Foo; import org.junit.Test; import org.springframework.http.MediaType; @@ -16,20 +18,20 @@ public class ApplicationLiveTest { @Test public void givenUserWithReadPrivilegeAndHasPermission_whenGetFooById_thenOK() { - final Response response = givenAuth("john", "123").get("http://localhost:8082/spring-security-mvc-boot/foos/1"); + final Response response = givenAuth("john", "123").get("http://localhost:8082/foos/1"); assertEquals(200, response.getStatusCode()); assertTrue(response.asString().contains("id")); } @Test public void givenUserWithNoWritePrivilegeAndHasPermission_whenPostFoo_thenForbidden() { - final Response response = givenAuth("john", "123").contentType(MediaType.APPLICATION_JSON_VALUE).body(new Foo("sample")).post("http://localhost:8082/spring-security-mvc-boot/foos"); + final Response response = givenAuth("john", "123").contentType(MediaType.APPLICATION_JSON_VALUE).body(new Foo("sample")).post("http://localhost:8082/foos"); assertEquals(403, response.getStatusCode()); } @Test public void givenUserWithWritePrivilegeAndHasPermission_whenPostFoo_thenOk() { - final Response response = givenAuth("tom", "111").and().body(new Foo("sample")).and().contentType(MediaType.APPLICATION_JSON_VALUE).post("http://localhost:8082/spring-security-mvc-boot/foos"); + final Response response = givenAuth("tom", "111").and().body(new Foo("sample")).and().contentType(MediaType.APPLICATION_JSON_VALUE).post("http://localhost:8082/foos"); assertEquals(201, response.getStatusCode()); assertTrue(response.asString().contains("id")); } @@ -38,14 +40,14 @@ public class ApplicationLiveTest { @Test public void givenUserMemberInOrganization_whenGetOrganization_thenOK() { - final Response response = givenAuth("john", "123").get("http://localhost:8082/spring-security-mvc-boot/organizations/1"); + final Response response = givenAuth("john", "123").get("http://localhost:8082/organizations/1"); assertEquals(200, response.getStatusCode()); assertTrue(response.asString().contains("id")); } @Test public void givenUserMemberNotInOrganization_whenGetOrganization_thenForbidden() { - final Response response = givenAuth("john", "123").get("http://localhost:8082/spring-security-mvc-boot/organizations/2"); + final Response response = givenAuth("john", "123").get("http://localhost:8082/organizations/2"); assertEquals(403, response.getStatusCode()); } @@ -53,13 +55,13 @@ public class ApplicationLiveTest { @Test public void givenDisabledSecurityExpression_whenGetFooByName_thenError() { - final Response response = givenAuth("john", "123").get("http://localhost:8082/spring-security-mvc-boot/foos?name=sample"); + final Response response = givenAuth("john", "123").get("http://localhost:8082/foos?name=sample"); assertEquals(500, response.getStatusCode()); assertTrue(response.asString().contains("method hasAuthority() not allowed")); } // private RequestSpecification givenAuth(String username, String password) { - return RestAssured.given().log().uri().auth().form(username, password, new FormAuthConfig("/spring-security-mvc-boot/login","username","password")); + return RestAssured.given().log().uri().auth().form(username, password, new FormAuthConfig("/login","username","password")); } } \ No newline at end of file diff --git a/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java b/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java index 503354256f..fb25175902 100644 --- a/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java +++ b/spring-security-mvc-boot/src/test/java/org/baeldung/web/CustomUserDetailsServiceIntegrationTest.java @@ -2,11 +2,11 @@ package org.baeldung.web; import static org.junit.Assert.assertEquals; -import org.baeldung.config.MvcConfig; -import org.baeldung.config.PersistenceConfig; -import org.baeldung.config.SecurityConfig; -import org.baeldung.persistence.dao.UserRepository; -import org.baeldung.persistence.model.User; +import org.baeldung.custom.Application; +import org.baeldung.custom.config.MvcConfig; +import org.baeldung.custom.config.SecurityConfig; +import org.baeldung.custom.persistence.dao.UserRepository; +import org.baeldung.custom.persistence.model.User; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; @@ -21,7 +21,7 @@ import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.boot.test.context.SpringBootTest; @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = {MvcConfig.class, SecurityConfig.class, PersistenceConfig.class}) +@SpringBootTest(classes = {Application.class}) @WebAppConfiguration public class CustomUserDetailsServiceIntegrationTest {