From 29918b148bf10545b2fffe20fe7dbc135135686b Mon Sep 17 00:00:00 2001 From: Marcus Hellberg Date: Tue, 5 Mar 2024 13:46:51 -0800 Subject: [PATCH 01/57] New examples for Vaadin 23.3 --- vaadin/.gitignore | 1 + vaadin/frontend/index.html | 23 ++ vaadin/pom.xml | 183 ++++-------- .../main/java/com/baeldung/Application.java | 8 +- .../src/main/java/com/baeldung/IndexView.java | 25 ++ .../main/java/com/baeldung/data/Contact.java | 73 +++++ .../com/baeldung/data/ContactRepository.java | 6 + .../com/baeldung/data/DataInitializer.java | 46 +++ .../com/baeldung/{ => data}/Employee.java | 9 +- .../{ => data}/EmployeeRepository.java | 2 +- .../com/baeldung/introduction/BindData.java | 20 -- .../com/baeldung/introduction/FormView.java | 88 ++++++ .../com/baeldung/introduction/GridView.java | 40 +++ .../com/baeldung/introduction/PushView.java | 27 ++ .../java/com/baeldung/introduction/Row.java | 45 --- .../com/baeldung/introduction/VaadinUI.java | 282 ------------------ .../introduction/basics/HelloWorldView.java | 13 + .../introduction/basics/VaadinFlowBasics.java | 61 ++++ .../{MainView.java => spring/CrudView.java} | 10 +- .../baeldung/{ => spring}/EmployeeEditor.java | 4 +- .../webapp/VAADIN/themes/mytheme/addons.scss | 7 - .../webapp/VAADIN/themes/mytheme/favicon.ico | Bin 31005 -> 0 bytes .../webapp/VAADIN/themes/mytheme/mytheme.scss | 38 --- .../webapp/VAADIN/themes/mytheme/styles.scss | 11 - 24 files changed, 482 insertions(+), 540 deletions(-) create mode 100644 vaadin/.gitignore create mode 100644 vaadin/frontend/index.html create mode 100644 vaadin/src/main/java/com/baeldung/IndexView.java create mode 100644 vaadin/src/main/java/com/baeldung/data/Contact.java create mode 100644 vaadin/src/main/java/com/baeldung/data/ContactRepository.java create mode 100644 vaadin/src/main/java/com/baeldung/data/DataInitializer.java rename vaadin/src/main/java/com/baeldung/{ => data}/Employee.java (85%) rename vaadin/src/main/java/com/baeldung/{ => data}/EmployeeRepository.java (89%) delete mode 100644 vaadin/src/main/java/com/baeldung/introduction/BindData.java create mode 100644 vaadin/src/main/java/com/baeldung/introduction/FormView.java create mode 100644 vaadin/src/main/java/com/baeldung/introduction/GridView.java create mode 100644 vaadin/src/main/java/com/baeldung/introduction/PushView.java delete mode 100644 vaadin/src/main/java/com/baeldung/introduction/Row.java delete mode 100644 vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java create mode 100644 vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java create mode 100644 vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java rename vaadin/src/main/java/com/baeldung/{MainView.java => spring/CrudView.java} (89%) rename vaadin/src/main/java/com/baeldung/{ => spring}/EmployeeEditor.java (96%) delete mode 100644 vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss delete mode 100644 vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico delete mode 100644 vaadin/src/main/webapp/VAADIN/themes/mytheme/mytheme.scss delete mode 100644 vaadin/src/main/webapp/VAADIN/themes/mytheme/styles.scss diff --git a/vaadin/.gitignore b/vaadin/.gitignore new file mode 100644 index 0000000000..1ef3efefbd --- /dev/null +++ b/vaadin/.gitignore @@ -0,0 +1 @@ +frontend/generated \ No newline at end of file diff --git a/vaadin/frontend/index.html b/vaadin/frontend/index.html new file mode 100644 index 0000000000..d36e593475 --- /dev/null +++ b/vaadin/frontend/index.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + +
+ + diff --git a/vaadin/pom.xml b/vaadin/pom.xml index aa37a2392a..ea9a3ed75a 100644 --- a/vaadin/pom.xml +++ b/vaadin/pom.xml @@ -1,21 +1,25 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.test vaadin 1.0-SNAPSHOT vaadin - war com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 + + 17 + 24.3.3 + + @@ -30,38 +34,24 @@ - javax.servlet - javax.servlet-api - provided + com.vaadin + vaadin-core com.vaadin - vaadin-server - ${vaadin-server.version} - - - com.vaadin - vaadin-push - ${vaadin-push.version} - - - com.vaadin - vaadin-client-compiled - ${vaadin-client-compiled.version} - - - com.vaadin - vaadin-themes - ${vaadin-themes.version} + vaadin-spring-boot-starter org.springframework.boot spring-boot-starter-data-jpa - com.vaadin - vaadin-spring-boot-starter - ${vaadin-spring-boot-starter.version} + org.springframework.boot + spring-boot-starter-validation + + + io.projectreactor + reactor-core com.h2database @@ -76,47 +66,17 @@ - - org.apache.maven.plugins - maven-war-plugin - ${maven-war-plugin.version} - - false - - WEB-INF/classes/VAADIN/widgetsets/WEB-INF/** - - com.vaadin vaadin-maven-plugin - ${vaadin.plugin.version} - - - org.apache.maven.plugins - maven-clean-plugin - ${maven-clean-plugin.version} - - - - - src/main/webapp/VAADIN/themes - - **/styles.css - **/styles.scss.cache - - - - - - - - - org.eclipse.jetty - jetty-maven-plugin - ${jetty.plugin.version} - - 2 - + ${vaadin.version} + + + + prepare-frontend + + + org.springframework.boot @@ -125,68 +85,41 @@ - - - vaadin-addons - https://maven.vaadin.com/vaadin-addons - - - - vaadin-prerelease - - false - - - - - vaadin-prereleases - https://maven.vaadin.com/vaadin-prereleases - - - vaadin-snapshots - https://oss.sonatype.org/content/repositories/vaadin-snapshots/ - - false - - - true - - - - - - vaadin-prereleases - https://maven.vaadin.com/vaadin-prereleases - - - vaadin-snapshots - https://oss.sonatype.org/content/repositories/vaadin-snapshots/ - - false - - - true - - - + + production + + + + com.vaadin + vaadin-core + + + com.vaadin + vaadin-dev + + + + + + + + com.vaadin + vaadin-maven-plugin + ${vaadin.version} + + + + build-frontend + + compile + + + + + - - - 13.0.9 - 13.0.9 - 13.0.9 - 8.8.5 - 8.8.5 - 8.8.5 - 8.8.5 - 9.3.9.v20160517 - local - mytheme - 3.0.0 - - \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/Application.java b/vaadin/src/main/java/com/baeldung/Application.java index 1d3084723a..b62dd79158 100644 --- a/vaadin/src/main/java/com/baeldung/Application.java +++ b/vaadin/src/main/java/com/baeldung/Application.java @@ -1,15 +1,19 @@ package com.baeldung; +import com.baeldung.data.Employee; +import com.baeldung.data.EmployeeRepository; +import com.vaadin.flow.component.page.AppShellConfigurator; +import com.vaadin.flow.component.page.Push; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; +@Push @SpringBootApplication -public class Application { +public class Application implements AppShellConfigurator { private static final Logger log = LoggerFactory.getLogger(Application.class); diff --git a/vaadin/src/main/java/com/baeldung/IndexView.java b/vaadin/src/main/java/com/baeldung/IndexView.java new file mode 100644 index 0000000000..c69b160895 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/IndexView.java @@ -0,0 +1,25 @@ +package com.baeldung; + +import com.baeldung.introduction.PushView; +import com.baeldung.introduction.basics.VaadinFlowBasics; +import com.baeldung.introduction.FormView; +import com.baeldung.introduction.GridView; +import com.baeldung.spring.CrudView; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.router.RouterLink; + +@Route("") +public class IndexView extends VerticalLayout { + + public IndexView() { + add(new H1("Vaadin Flow examples")); + + add(new RouterLink("Basics", VaadinFlowBasics.class)); + add(new RouterLink("Grid", GridView.class)); + add(new RouterLink("Form", FormView.class)); + add(new RouterLink("Push", PushView.class)); + add(new RouterLink("CRUD", CrudView.class)); + } +} diff --git a/vaadin/src/main/java/com/baeldung/data/Contact.java b/vaadin/src/main/java/com/baeldung/data/Contact.java new file mode 100644 index 0000000000..8e534d5bb0 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/data/Contact.java @@ -0,0 +1,73 @@ +package com.baeldung.data; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; + +@Entity +public class Contact { + + @Id + @GeneratedValue + private Long id; + @NotBlank + private String name; + @Email + private String email; + @Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}") + private String phone; + + public Contact() { + } + + public Contact(String name, String email, String phone) { + this.name = name; + this.email = email; + this.phone = phone; + } + + 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 getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + @Override + public String toString() { + return "Contact {" + + "id=" + id + + ", name='" + name + "'" + + ", email='" + email + "'" + + ", phone='" + phone + "'" + + " }"; + } +} diff --git a/vaadin/src/main/java/com/baeldung/data/ContactRepository.java b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java new file mode 100644 index 0000000000..15c4adaaa9 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/data/ContactRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.data; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ContactRepository extends JpaRepository { +} diff --git a/vaadin/src/main/java/com/baeldung/data/DataInitializer.java b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java new file mode 100644 index 0000000000..dba162d4e4 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/data/DataInitializer.java @@ -0,0 +1,46 @@ +package com.baeldung.data; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +@Component +public class DataInitializer implements CommandLineRunner { + + private final ContactRepository contactRepository; + + public DataInitializer(ContactRepository contactRepository) { + this.contactRepository = contactRepository; + } + + private final List firstNames = List.of( + "John", "Jane", "Emily", "Michael", "Sarah", "James", "Mary", "Robert", + "Patricia", "William", "Linda", "David", "Barbara", "Richard", "Susan", + "Joseph", "Jessica", "Thomas", "Karen", "Charles" + ); + private final List lastNames = List.of( + "Doe", "Smith", "Johnson", "Brown", "Davis", "Miller", "Wilson", "Moore", + "Taylor", "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin", + "Thompson", "Garcia", "Martinez", "Robinson", "Clark" + ); + + @Override + public void run(String... args) throws Exception { + var contacts = new ArrayList(); + Random random = new Random(); + + for (int i = 0; i < 100; i++) { + String firstName = firstNames.get(random.nextInt(firstNames.size())); + String lastName = lastNames.get(random.nextInt(lastNames.size())); + String email = String.format("%s.%s@example.com", firstName.toLowerCase(), lastName.toLowerCase()); + String phone = String.format("555-%03d-%04d", random.nextInt(1000), random.nextInt(10000)); + + contacts.add(new Contact(firstName + " " + lastName, email, phone)); + } + + contactRepository.saveAll(contacts); + } +} diff --git a/vaadin/src/main/java/com/baeldung/Employee.java b/vaadin/src/main/java/com/baeldung/data/Employee.java similarity index 85% rename from vaadin/src/main/java/com/baeldung/Employee.java rename to vaadin/src/main/java/com/baeldung/data/Employee.java index 726f0838b6..2685e38286 100644 --- a/vaadin/src/main/java/com/baeldung/Employee.java +++ b/vaadin/src/main/java/com/baeldung/data/Employee.java @@ -1,8 +1,9 @@ -package com.baeldung; +package com.baeldung.data; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Id; @Entity public class Employee { diff --git a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java similarity index 89% rename from vaadin/src/main/java/com/baeldung/EmployeeRepository.java rename to vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java index 044160da78..0d54148c85 100644 --- a/vaadin/src/main/java/com/baeldung/EmployeeRepository.java +++ b/vaadin/src/main/java/com/baeldung/data/EmployeeRepository.java @@ -1,4 +1,4 @@ -package com.baeldung; +package com.baeldung.data; import java.util.List; diff --git a/vaadin/src/main/java/com/baeldung/introduction/BindData.java b/vaadin/src/main/java/com/baeldung/introduction/BindData.java deleted file mode 100644 index 299554c039..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/BindData.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.baeldung.introduction; - -public class BindData { - - private String bindName; - - public BindData(String bindName){ - this.bindName = bindName; - } - - public String getBindName() { - return bindName; - } - - public void setBindName(String bindName) { - this.bindName = bindName; - } - - -} diff --git a/vaadin/src/main/java/com/baeldung/introduction/FormView.java b/vaadin/src/main/java/com/baeldung/introduction/FormView.java new file mode 100644 index 0000000000..34bc334b27 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/FormView.java @@ -0,0 +1,88 @@ +package com.baeldung.introduction; + +import com.baeldung.data.Contact; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.html.H2; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; +import com.vaadin.flow.data.binder.Binder; +import com.vaadin.flow.router.Route; + +@Route("form") +public class FormView extends HorizontalLayout { + + public FormView() { + addBeanValidationExample(); + addCustomValidationExample(); + } + + private void addBeanValidationExample() { + var nameField = new TextField("Name"); + var emailField = new TextField("Email"); + var phoneField = new TextField("Phone"); + var saveButton = new Button("Save"); + + var binder = new BeanValidationBinder<>(Contact.class); + + binder.forField(nameField).bind(Contact::getName, Contact::setName); + binder.forField(emailField).bind(Contact::getEmail, Contact::setEmail); + binder.forField(phoneField).bind(Contact::getPhone, Contact::setPhone); + + var contact = new Contact("John Doe", "john@doe.com", "123-456-7890"); + binder.setBean(contact); + + saveButton.addClickListener(e -> { + if (binder.validate().isOk()) { + Notification.show("Saved " + contact); + } + }); + + add(new VerticalLayout( + new H2("Bean Validation Example"), + nameField, + emailField, + phoneField, + saveButton + )); + } + + private void addCustomValidationExample() { + + var nameField = new TextField("Name"); + var emailField = new TextField("Email"); + var phoneField = new TextField("Phone"); + var saveButton = new Button("Save"); + + var binder = new Binder<>(Contact.class); + + binder.forField(nameField) + .asRequired() + .bind(Contact::getName, Contact::setName); + binder.forField(emailField) + .withValidator(email -> email.contains("@"), "Not a valid email address") + .bind(Contact::getEmail, Contact::setEmail); + binder.forField(phoneField) + .withValidator(phone -> phone.matches("\\d{3}-\\d{3}-\\d{4}"), "Not a valid phone number") + .bind(Contact::getPhone, Contact::setPhone); + + var contact = new Contact("John Doe", "john@doe.com", "123-456-7890"); + binder.setBean(contact); + + saveButton.addClickListener(e -> { + if (binder.validate().isOk()) { + Notification.show("Saved " + contact); + } + }); + + add(new VerticalLayout( + new H2("Custom Validation Example"), + nameField, + emailField, + phoneField, + saveButton + )); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/GridView.java b/vaadin/src/main/java/com/baeldung/introduction/GridView.java new file mode 100644 index 0000000000..3d9500d7d8 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/GridView.java @@ -0,0 +1,40 @@ +package com.baeldung.introduction; + +import com.baeldung.data.Contact; +import com.baeldung.data.ContactRepository; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.spring.data.VaadinSpringDataHelpers; + +@Route("grid") +public class GridView extends VerticalLayout { + + public GridView(ContactRepository contactRepository) { + + add(new H1("Using data grids")); + + // Define a grid for a Contact entity + var grid = new Grid(); + grid.addColumn(Contact::getName).setHeader("Name"); + grid.addColumn(Contact::getEmail).setHeader("Email"); + grid.addColumn(Contact::getPhone).setHeader("Phone"); + + // There are two ways to populate the grid with data: + + // 1) In-memory with a list of items + var contacts = contactRepository.findAll(); + grid.setItems(contacts); + + // 2) with a callback to lazily load items from a data source. + grid.setItems(query -> { + // Turn the page, offset, filter, sort and other info in query into a Spring Data PageRequest + var pageRequest = VaadinSpringDataHelpers.toSpringPageRequest(query); + return contactRepository.findAll(pageRequest).stream(); + }); + + add(grid); + + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/PushView.java b/vaadin/src/main/java/com/baeldung/introduction/PushView.java new file mode 100644 index 0000000000..28d8162003 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/PushView.java @@ -0,0 +1,27 @@ +package com.baeldung.introduction; + +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.html.Span; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; +import reactor.core.publisher.Flux; + +import java.time.Duration; +import java.time.Instant; + +// Ensure you have @Push annotation in your Application class +@Route("push") +public class PushView extends VerticalLayout { + + public PushView() { + var output = new Span(); + + add(new H1("Server Push"), output); + + Flux.interval(Duration.ofSeconds(1)) + .map(o -> "Server time: " + Instant.now()) + .subscribe(time -> getUI().ifPresent(ui -> ui.access(() -> { + output.setText(time); + }))); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/Row.java b/vaadin/src/main/java/com/baeldung/introduction/Row.java deleted file mode 100644 index 412a286376..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/Row.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.baeldung.introduction; - -public class Row { - - private String column1; - - private String column2; - - private String column3; - - public Row() { - - } - - public Row(String column1, String column2, String column3) { - super(); - this.column1 = column1; - this.column2 = column2; - this.column3 = column3; - } - - public String getColumn1() { - return column1; - } - - public void setColumn1(String column1) { - this.column1 = column1; - } - - public String getColumn2() { - return column2; - } - - public void setColumn2(String column2) { - this.column2 = column2; - } - - public String getColumn3() { - return column3; - } - - public void setColumn3(String column3) { - this.column3 = column3; - } -} \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java b/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java deleted file mode 100644 index 22ce19f5e0..0000000000 --- a/vaadin/src/main/java/com/baeldung/introduction/VaadinUI.java +++ /dev/null @@ -1,282 +0,0 @@ -package com.baeldung.introduction; - -import java.time.Instant; -import java.time.LocalDate; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.servlet.annotation.WebServlet; - -import com.vaadin.annotations.Push; -import com.vaadin.annotations.Theme; -import com.vaadin.annotations.VaadinServletConfiguration; -import com.vaadin.data.Binder; -import com.vaadin.data.validator.StringLengthValidator; -import com.vaadin.icons.VaadinIcons; -import com.vaadin.server.ExternalResource; -import com.vaadin.server.VaadinRequest; -import com.vaadin.server.VaadinServlet; -import com.vaadin.ui.Button; -import com.vaadin.ui.CheckBox; -import com.vaadin.ui.ComboBox; -import com.vaadin.ui.DateField; -import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Grid; -import com.vaadin.ui.GridLayout; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.InlineDateField; -import com.vaadin.ui.Label; -import com.vaadin.ui.Link; -import com.vaadin.ui.ListSelect; -import com.vaadin.ui.NativeButton; -import com.vaadin.ui.NativeSelect; -import com.vaadin.ui.Panel; -import com.vaadin.ui.PasswordField; -import com.vaadin.ui.RichTextArea; -import com.vaadin.ui.TextArea; -import com.vaadin.ui.TextField; -import com.vaadin.ui.TwinColSelect; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; - -@SuppressWarnings("serial") -@Push -@Theme("mytheme") -public class VaadinUI extends UI { - - private Label currentTime; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - protected void init(VaadinRequest vaadinRequest) { - final VerticalLayout verticalLayout = new VerticalLayout(); - verticalLayout.setSpacing(true); - verticalLayout.setMargin(true); - final GridLayout gridLayout = new GridLayout(3, 2); - gridLayout.setSpacing(true); - gridLayout.setMargin(true); - final HorizontalLayout horizontalLayout = new HorizontalLayout(); - horizontalLayout.setSpacing(true); - horizontalLayout.setMargin(true); - final FormLayout formLayout = new FormLayout(); - formLayout.setSpacing(true); - formLayout.setMargin(true); - final GridLayout buttonLayout = new GridLayout(3, 5); - buttonLayout.setMargin(true); - buttonLayout.setSpacing(true); - - final Label label = new Label(); - label.setId("Label"); - label.setValue("Label Value"); - label.setCaption("Label"); - gridLayout.addComponent(label); - - final Link link = new Link("Baeldung", new ExternalResource("http://www.baeldung.com/")); - link.setId("Link"); - link.setTargetName("_blank"); - gridLayout.addComponent(link); - - final TextField textField = new TextField(); - textField.setId("TextField"); - textField.setCaption("TextField:"); - textField.setValue("TextField Value"); - textField.setIcon(VaadinIcons.USER); - gridLayout.addComponent(textField); - - final TextArea textArea = new TextArea(); - textArea.setCaption("TextArea"); - textArea.setId("TextArea"); - textArea.setValue("TextArea Value"); - gridLayout.addComponent(textArea); - - final DateField dateField = new DateField("DateField", LocalDate.ofEpochDay(0)); - dateField.setId("DateField"); - gridLayout.addComponent(dateField); - - final PasswordField passwordField = new PasswordField(); - passwordField.setId("PasswordField"); - passwordField.setCaption("PasswordField:"); - passwordField.setValue("password"); - gridLayout.addComponent(passwordField); - - final RichTextArea richTextArea = new RichTextArea(); - richTextArea.setCaption("Rich Text Area"); - richTextArea.setValue("

RichTextArea

"); - richTextArea.setSizeFull(); - - Panel richTextPanel = new Panel(); - richTextPanel.setContent(richTextArea); - - final InlineDateField inlineDateField = new InlineDateField(); - inlineDateField.setValue(LocalDate.ofEpochDay(0)); - inlineDateField.setCaption("Inline Date Field"); - horizontalLayout.addComponent(inlineDateField); - - Button normalButton = new Button("Normal Button"); - normalButton.setId("NormalButton"); - normalButton.addClickListener(e -> { - label.setValue("CLICK"); - }); - buttonLayout.addComponent(normalButton); - - Button tinyButton = new Button("Tiny Button"); - tinyButton.addStyleName("tiny"); - buttonLayout.addComponent(tinyButton); - - Button smallButton = new Button("Small Button"); - smallButton.addStyleName("small"); - buttonLayout.addComponent(smallButton); - - Button largeButton = new Button("Large Button"); - largeButton.addStyleName("large"); - buttonLayout.addComponent(largeButton); - - Button hugeButton = new Button("Huge Button"); - hugeButton.addStyleName("huge"); - buttonLayout.addComponent(hugeButton); - - Button disabledButton = new Button("Disabled Button"); - disabledButton.setDescription("This button cannot be clicked"); - disabledButton.setEnabled(false); - buttonLayout.addComponent(disabledButton); - - Button dangerButton = new Button("Danger Button"); - dangerButton.addStyleName("danger"); - buttonLayout.addComponent(dangerButton); - - Button friendlyButton = new Button("Friendly Button"); - friendlyButton.addStyleName("friendly"); - buttonLayout.addComponent(friendlyButton); - - Button primaryButton = new Button("Primary Button"); - primaryButton.addStyleName("primary"); - buttonLayout.addComponent(primaryButton); - - NativeButton nativeButton = new NativeButton("Native Button"); - buttonLayout.addComponent(nativeButton); - - Button iconButton = new Button("Icon Button"); - iconButton.setIcon(VaadinIcons.ALIGN_LEFT); - buttonLayout.addComponent(iconButton); - - Button borderlessButton = new Button("BorderLess Button"); - borderlessButton.addStyleName("borderless"); - buttonLayout.addComponent(borderlessButton); - - Button linkButton = new Button("Link Button"); - linkButton.addStyleName("link"); - buttonLayout.addComponent(linkButton); - - Button quietButton = new Button("Quiet Button"); - quietButton.addStyleName("quiet"); - buttonLayout.addComponent(quietButton); - - horizontalLayout.addComponent(buttonLayout); - - final CheckBox checkbox = new CheckBox("CheckBox"); - checkbox.setValue(true); - checkbox.addValueChangeListener(e -> checkbox.setValue(!checkbox.getValue())); - formLayout.addComponent(checkbox); - - List numbers = new ArrayList(); - numbers.add("One"); - numbers.add("Ten"); - numbers.add("Eleven"); - ComboBox comboBox = new ComboBox("ComboBox"); - comboBox.setItems(numbers); - formLayout.addComponent(comboBox); - - ListSelect listSelect = new ListSelect("ListSelect"); - listSelect.setItems(numbers); - listSelect.setRows(2); - formLayout.addComponent(listSelect); - - NativeSelect nativeSelect = new NativeSelect("NativeSelect"); - nativeSelect.setItems(numbers); - formLayout.addComponent(nativeSelect); - - TwinColSelect twinColSelect = new TwinColSelect("TwinColSelect"); - twinColSelect.setItems(numbers); - - Grid grid = new Grid(Row.class); - grid.setColumns("column1", "column2", "column3"); - Row row1 = new Row("Item1", "Item2", "Item3"); - Row row2 = new Row("Item4", "Item5", "Item6"); - List rows = new ArrayList(); - rows.add(row1); - rows.add(row2); - grid.setItems(rows); - - Panel panel = new Panel("Panel"); - panel.setContent(grid); - panel.setSizeUndefined(); - - Panel serverPushPanel = new Panel("Server Push"); - FormLayout timeLayout = new FormLayout(); - timeLayout.setSpacing(true); - timeLayout.setMargin(true); - currentTime = new Label("No TIME..."); - timeLayout.addComponent(currentTime); - serverPushPanel.setContent(timeLayout); - serverPushPanel.setSizeUndefined(); - ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(1); - Runnable task = () -> { - currentTime.setValue("Current Time : " + Instant.now()); - }; - scheduleExecutor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS); - - FormLayout dataBindingLayout = new FormLayout(); - dataBindingLayout.setSpacing(true); - dataBindingLayout.setMargin(true); - - Binder binder = new Binder<>(); - BindData bindData = new BindData("BindData"); - binder.readBean(bindData); - TextField bindedTextField = new TextField(); - bindedTextField.setWidth("250px"); - binder.forField(bindedTextField).bind(BindData::getBindName, BindData::setBindName); - dataBindingLayout.addComponent(bindedTextField); - - FormLayout validatorLayout = new FormLayout(); - validatorLayout.setSpacing(true); - validatorLayout.setMargin(true); - - HorizontalLayout textValidatorLayout = new HorizontalLayout(); - textValidatorLayout.setSpacing(true); - textValidatorLayout.setMargin(true); - - - BindData stringValidatorBindData = new BindData(""); - TextField stringValidator = new TextField(); - Binder stringValidatorBinder = new Binder<>(); - stringValidatorBinder.setBean(stringValidatorBindData); - stringValidatorBinder.forField(stringValidator) - .withValidator(new StringLengthValidator("String must have 2-5 characters lenght", 2, 5)) - .bind(BindData::getBindName, BindData::setBindName); - - textValidatorLayout.addComponent(stringValidator); - Button buttonStringValidator = new Button("Validate String"); - buttonStringValidator.addClickListener(e -> stringValidatorBinder.validate()); - textValidatorLayout.addComponent(buttonStringValidator); - - validatorLayout.addComponent(textValidatorLayout); - verticalLayout.addComponent(gridLayout); - verticalLayout.addComponent(richTextPanel); - verticalLayout.addComponent(horizontalLayout); - verticalLayout.addComponent(formLayout); - verticalLayout.addComponent(twinColSelect); - verticalLayout.addComponent(panel); - verticalLayout.addComponent(serverPushPanel); - verticalLayout.addComponent(dataBindingLayout); - verticalLayout.addComponent(validatorLayout); - setContent(verticalLayout); - } - - @WebServlet(urlPatterns = "/VAADIN/*", name = "MyUIServlet", asyncSupported = true) - @VaadinServletConfiguration(ui = VaadinUI.class, productionMode = false) - public static class MyUIServlet extends VaadinServlet { - } -} \ No newline at end of file diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java new file mode 100644 index 0000000000..477cf378c6 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/basics/HelloWorldView.java @@ -0,0 +1,13 @@ +package com.baeldung.introduction.basics; + +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.router.Route; + +@Route("hello-world") +public class HelloWorldView extends VerticalLayout { + + public HelloWorldView() { + add(new H1("Hello, World!")); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java new file mode 100644 index 0000000000..cd028dcd1d --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java @@ -0,0 +1,61 @@ +package com.baeldung.introduction.basics; + +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.checkbox.Checkbox; +import com.vaadin.flow.component.html.H1; +import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.router.Route; +import com.vaadin.flow.router.RouterLink; + +// The @Route annotation defines the URL path for the view +// Any component, most commonly a layout, can be used as a view +@Route("basics") +public class VaadinFlowBasics extends VerticalLayout { + public VaadinFlowBasics() { + + // Add components to the layout with the add method + add(new H1("Vaadin Flow Basics")); + + // Components are Java objects + var textField = new TextField("Name"); + var button = new Button("Click me"); + + // Layouts define the structure of the UI + var verticalLayout = new VerticalLayout( + new Button("Top"), + new Button("Middle"), + new Button("Bottom") + ); + add(verticalLayout); + + var horizontalLayout = new HorizontalLayout( + new Button("Left"), + new Button("Center"), + new Button("Right") + ); + add(horizontalLayout); + + // Layouts can be nested for more complex structures + var nestedLayout = new VerticalLayout( + new HorizontalLayout(new Button("Top Left"), new Button("Top Right")), + new HorizontalLayout(new Button("Bottom Left"), new Button("Bottom Right")) + ); + add(nestedLayout); + + // Use RouterLink to navigate to other views + var link = new RouterLink("Hello world view", HelloWorldView.class); + add(link); + + // Use events to react to user input + var nameField = new TextField("Your name"); + var helloButton = new Button("Say hello"); + helloButton.addClickListener(e -> { + Notification.show("Hello, " + nameField.getValue()); + }); + add(nameField, helloButton); + + } +} diff --git a/vaadin/src/main/java/com/baeldung/MainView.java b/vaadin/src/main/java/com/baeldung/spring/CrudView.java similarity index 89% rename from vaadin/src/main/java/com/baeldung/MainView.java rename to vaadin/src/main/java/com/baeldung/spring/CrudView.java index 6d4c0aaa88..a77e32e965 100644 --- a/vaadin/src/main/java/com/baeldung/MainView.java +++ b/vaadin/src/main/java/com/baeldung/spring/CrudView.java @@ -1,5 +1,7 @@ -package com.baeldung; +package com.baeldung.spring; +import com.baeldung.data.Employee; +import com.baeldung.data.EmployeeRepository; import org.springframework.util.StringUtils; import com.vaadin.flow.component.button.Button; @@ -11,8 +13,8 @@ import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.data.value.ValueChangeMode; import com.vaadin.flow.router.Route; -@Route -public class MainView extends VerticalLayout { +@Route("crud") +public class CrudView extends VerticalLayout { private final EmployeeRepository employeeRepository; @@ -24,7 +26,7 @@ public class MainView extends VerticalLayout { private final Button addNewBtn; - public MainView(EmployeeRepository repo, EmployeeEditor editor) { + public CrudView(EmployeeRepository repo, EmployeeEditor editor) { this.employeeRepository = repo; this.editor = editor; this.grid = new Grid<>(Employee.class); diff --git a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java similarity index 96% rename from vaadin/src/main/java/com/baeldung/EmployeeEditor.java rename to vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java index ee312786d1..25e447102c 100644 --- a/vaadin/src/main/java/com/baeldung/EmployeeEditor.java +++ b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java @@ -1,5 +1,7 @@ -package com.baeldung; +package com.baeldung.spring; +import com.baeldung.data.Employee; +import com.baeldung.data.EmployeeRepository; import com.vaadin.flow.component.Key; import com.vaadin.flow.component.KeyNotifier; import com.vaadin.flow.component.button.Button; diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss b/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss deleted file mode 100644 index a5670b70c7..0000000000 --- a/vaadin/src/main/webapp/VAADIN/themes/mytheme/addons.scss +++ /dev/null @@ -1,7 +0,0 @@ -/* This file is automatically managed and will be overwritten from time to time. */ -/* Do not manually edit this file. */ - -/* Import and include this mixin into your project theme to include the addon themes */ -@mixin addons { -} - diff --git a/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico b/vaadin/src/main/webapp/VAADIN/themes/mytheme/favicon.ico deleted file mode 100644 index ffb34a65c73eb1b3d59dcbb8f18ec78a8b0fc767..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31005 zcmeHu2UL{1_U{a!(mMiDMY@6o1XQYkh@c=AiU^1bD4-}RAjLsZnt+0I1!+Td!Kp9Hw%BW`h2+b(v-dAMJ3Bkc2MUEok)UX4Q6T3= z32s86j-XH|Ztk^bMilBAsN1t=?O6nc3Sb2UCv6?I zxbZY7k9leAEoyaTW*ECNH-?4f@ieBT@igKUNJHR3XgiXIl7PJNZJAcbQ-JJ}o7k0w zNhD2`*u+&O8XmYxYan>hgFGc6q!TyFAu~ z#bQ@+Fu^iX2i`#%NDJE#>c`d$4fq=G!xo1j|Src!$scT7v$d z4o4Ee_~lFDfQ*%iY?;-uHz<5xV1Eb+)JOq}|wd-F}l%i2cIxg<}Nu3==HFI>def4QxwjgOq-e~bKpkNu}VIIg%t z6v;;a_A4*=4xw4|nZLgOC(nr71QhYcwu7%w%s(O{Al$fZa|_XX5Q1+CD79I^-RofwY8n8+j1w{-+$#<657gor8Iq zIF*UQVGD_H3pqqMSRPNKz)oarUx5jhVI6!2XC*@rN5KEaeM&}bI`BV zm3$J|KP*UKtpPqcjbau0U&L<$zY5Dp9ez$j8tht|Rmg)NZzFF)-Nt<5`>{0QKpf}` z^fPO65&u4sPL7wCwHLeCTL#vl57>$91Nb`dZjBzn3d@iO(<`LkVExA}_EjL|xt6y$WDEe! z#x~;!ZoCaa-cSbYH$f)BN5DCYpI3;T=;|RK+tqs7Zr24H-C zGX{_ce*Pfyl;9r-J{97Dz6H)*K=+5f6Lbjq!dPvpKo_rjsB=)B%vHmI-~qvai~+z0 zZG_N{pbJEwfHxuo$U=0m!Jk9l1^ow*58?!9>-aSumM79l0Y63_ZCsH@xm4na#I|1~Ri0=L{j(|6m0c9cb*L)K6-9YZty8aQFYh#{H0{X*($XOby zMdZLg3tjn$EIg*n_4=hBjR-BoI|16_@vn^|7=tw#QybR{xPGkpaQrwS{m0K?$YUaX zP5x*LA_u#=1Y&q=eE(rQ|Nbft&IR~e9`F2ve0=}$zJp)`P!^O4bpU^G4f`3V<8@EK zjUPv#OQ7qCEFs)RsX-*AL8f0Jen*v#?IA8 z;N}`ZKM4u=p1Fny+|uArTZCm;2mR7I9i#_sArI&?5T3uWKf-#nKL64=R>qRR9;L>Q z&_B4&{PqVnalq~te*12%5@`#0L7wA)_pkGhuokTQAF#)SI$N3QgDn11Hhj6zQwUNK zEdJdO3wc4FaR2%z|FgCZ;QjArXjfowLW}H^Ak(FhR_t6`8rUyo0pF8}PaRo6-;qG4 z&@Yi9<#|xI{vOc6Hn1(^0ry#uC*(bqxf!?7|H3&ySPRBdw}ABr;v`>MU6_PTag%w+ zuw(Iv{UK{SvIm3vFko9?T}2XNo3M_M;9e87naoo~LZv zPJp=%u&=JpjR4!;4dxOn7MW9-JV^Wj*Fj`nuJs=&BXv6f9iTzxA7}&GLLQJ8 z%xsI0C*-|R7A$Z4t&c+*RUobi;7x_`7d40-;Fv&}gaqXh%7px9-5M?EFExx)LHq?| z1D;S8LB>Y8gfd|+!e>a2E208&fZxQ&y+~a1XSoFVgdCxVwuY?ZkOx6F z&ROWAfd2pE`!6Vu@cX~H|0H05IU!cuXdfHjBQ*bk{r9gj{`>r24g6OF|L*s{v?&UxAL)I1$d%*RjDj2m1_e( z`+)2>@q5mV?eP0dFm_NcfZv*|Xo7zuVEI>YLmFuB1X_q4p1T7bK|8_UJO2UmS|5O3 z!G0F6_q>zX)#W+3$H%ADCG2F8A<{2|X2Tf#+K;udSVm-~qoN5oHew>w{Vqr5&e~js zVcE33EWlis^AcqMD&U{+_I1e^p z|CJYFo2h8n2Q0)un9~Go1gyX21Utj~Nb~?HNOLFXKA=;9q(*Y4ETN{bp3g0 ztR1;e#AB!W!#p7HBIN7+0Jgh^Wtp%}6R;BWzj1EB_563b|CKL%M(PmT0do@CPT_fA zJ2Pu|SHU+lmPj2A_#eCt&11ox1Qwq8PGoFfx1rzhCg4YG7uXTR1kMWaV*t++)_e>y zCTli@#9|;Of$KWpx%{i$sF)EYvr_XRgc)0-FN<6x<;%Pxh|Y&$Yfq z{1Afw7yJLU9|RkMSk~f{AB32XFjqI?2lPg3aTRiQ^-~9bVK)eN5GSOAx%-RlEPgLV z^bGD{!1qx3>-d+U4I#Eq3&wzXt&G=8d)k<62~#z#TC` z_XIwK9Iq36f8hLs>(OWeu$_FZKdf0ZHGX*fz*c6e+}82qRu+LDGRBU^LmLA9UYo-N zU2Wt~kO{HCm=9tb1sD`q;E~*Z2q9A@Cva#y_w5dte{4HNN0`srGe@ z@H@82yc2kT55GZpCk?)f8(n|DJkf=ntqa;Pmm#m8y8m+-@k7f9Hn4vn?13P5f*s-a zP3UPDql0lk&S5w5A@l*s5xd!re5(cS?bdNY-6Ct%a3eCG!M9mJ#~jEwEDly9@4)w9 z>-5u~9wIyl-xvHr#xMPWnAWgO13x4{upzjwhGn?FgMMml@3DT44Eyk>ejxb4oCUT$ z{prCv9>Uz6ZHmVG`3!LH01~(d0e&?2PjoY%pW^3oCNJI({32_kTwoik5F36UN2~}j z6V3@>8SYWn*4y$!hYg;{p0C?GEF)`fmgrA9*yeY<;I}ku z^WYCT9{->0=kMk((jMsx)Ez!%gzFTH75*+k-@f?0d>ub5!@9p~gS>;hfjmSO7%#%u ztl{|m{9TJ3{>p#i*B5%cT?5{e`DelUV~WJWFdqJ6GQ&<5U%<}RJ_CEliFN$24C~;# z$@hTfPwgNdz!UI>n2~vci~~MCMezTH|NO)H1=fZ?u3xY{7*C+@nMzmSJ36tei_=If z599gYB^;~jDq<8A40@Ds*wO$L;S%w_m3 zLps&p$IlyVh_HW|NTXf?>kDo?V-twqzpv{M?!#xQJV4y=@GsL;>2) zye}lIuYbzn+6w(3n16)td!Q}+iH@*71OEVdPL-Gg`@zqDC=<$t7^Wc>Fn|AQ|A_Cw z&%H4`OIwG|(S{+VvA zE&M+Zz!UBZ2>78)C>vscSSC`@!HAwWoUIXX6LLZ@H)4d4ZM!gC4y+0iQat|$dB8(;w6=KM?NCrJO+ z?n03Bs~j?XJORdVs^ARx{tc|b(4N=gMZ9i*VkJC7tbdgVG#hhRMtCCQ%7KNl!2eI+ z&#wT6fA#zd!M|Z{Or)T|`5`%Cd%%9-xjy*b=4Z@>my5?wz(dgUulRp`|7%+~Um$NN z1ImK-4rPOWAZO7V_qhan`Kz3;Cd2nYPBgBF9DXYW_LQ`LeSW)U7X;kD;@w#PC+zEO z;r#)S0c1g$P&NVMMofgdzsm`80rnezehzgH>|*`={HNYG;@PNwLjCXR2=5S{kS~6X zMZOWjf^V`w{XafGC-kfE-?_g)#{Z9f`b(X!(IS`uZeS~axW6ErIYS&9F%WS5J2_z- zU>i7({-^t+je7lEc>`wXzu=w1f9(E<&`)T4g!4MQZ~dG5I}qmr8^iBGp`OJxE8|o9N_o?&&A;S4&&QD+@Iq6 zf%N6C?oZ*FCShHLcwihr(AB?#?_Z^b_OwwqNX!S~Rv3GOw0?gL_o9URYgpcRe+|#j zfbIMry}$mof4|ccJQoAH6!@#}2jDxx*%^V~uj5Ln|38rIO$@ZV9|bcB&k=5V? z$p1ZJn{G90o_N^fT+Pl9zMiPZBoX>SeBGu|4qGngpH>Y)_00>`*DpL*N9|z@Hmn-p zkFapxr_9JY<~~J)B7IhRAnzu%=i&jgFqG{p)9)T6?yAPG=)MMB=^OlDvNV}?YSDP_ z&SxdZd)#c*Yi80Zz4tINfS8Ef%(PaXOt^mHBXY`OGB$ zNKKf+<1pPWi;*|G^S7erc=bX#(hB^~pwcZj%lGxX(HQ4OO>IJ@cRruyd}LwZTl$Ss zfWmWR#KIaKZZ5iWP;xo^{`F6Vj}FWSSB@>8J@krM&UuF_lh|eDzE`oY)Rd~KD5(Q$ zF0Ibf;(Ch?T>1R5WY_cXBIe15gJ(_-J|lB+H_Lq}?X2@e^b)zty~dtIul;RFz-fMDqi5!Q|(e5SxP>^Sq_%zAdXWw1yz!DdQzQ?s5 zbp@VN{d1H)mu~V!?qZGVa!#081 z_0aIWAF2EYQsTNJI;3oqN{655@S^Fqn?L1=CW==Mc|sk{_Rj0*(;MH3H@ik$2x8e< z&f4p$`?$yW?1d)dV|yBdE(V=dXYQ9Up%rspydPuSnDR@6!}pPZ&FF zFCf3ievh-uhpW6$;0c)?iTQn+?E&1p7QClvw~-EzuDZ~@7eDD7r*Vtt5v^URzOhh> zce6sCDm(uPKStF@yv$m>Lc!_Ir&X`=oadL}&)@F%@!%zun=HEW1{!a9!?_LlXnf@~ zp9%6aY8+!%KHPHRz_EAocJg+LFXVT4i(Ah<$AxNvKg+y z{28*#e3#Gl3HGt~ZR<<>q_z3|9-{>@E!LRFevfk>`%H`XzpLr3X_H90Vt~sN@?R9b zChXwP<8R`R_V-CpKXbj2vGGNMWr9Y-o~!&u&U9v)_CwdP(%Lp{-R!!jb_EYVoEZ=$K@vGypvIk|| zWxZq>3horVcHF&iVU=k0&Qizp*NK6puge-FQY3H42FasIj*y()B1^H4jDFK?l9FO{ zaqfMt-CqoO^&7Sl9bQqq^H7>>KjnF*C2JPZUE*)}N9?lC*gDzTkcb#7D=C)d9`*U~ z<%5c+*H*QyHb*|Hlqol=99Oni4pdeP)Y+w*_Wj6Xy~o_IWVUj#G1>FpxfwtIr9;iN zcjOy+@0h5Ven8qt>&=Y5_{y5MPYjE7ZwPa;adC9f;@lbD$M>nfoiTi8(?{~vFV}V1 zcc6UdfY;>th07~XNdjF`UFwtqOV7JsRDG+;q}ofQp^(viJJoQ?`Fs4cC(ojU#NzAX zKVNZ4Ur4V%%y+>fdFOdC8G-!WCE`(g6mvdZX&gJl5Gh~xR9(>Eh^f7NJ z-veEWw5zF|rYe`iKb@?i>!0}^^8H#R$H(c9%TD`E_S@VxEx3byv{Jl(%$z#$Vbfdv zws$9N&KKwO%oYs$SaMq)ZJDS%Qt5S>t?QacXT!;tCzA_|%+kjD%MZUhe6lBBr1~7S zMVSSY#b}2~TH@8VKpum-S>wuY9^W+h+I@$+bRD%9JF4bfM)PClVwP>X?~vNGcMRoB z>jWF?8no2D?LME_S2Yzmm6fYKQgHUdxf@0_S9~t{r0-;TFdT8ZGL$iHnLlKewi?iz=v}bMabW5E^6t*L9LGLy z+zU2h&&^9?q6PLigLauA$IjKdE%7u4a#eSwR?Su~j`T(fkZTBsCCDYNHZFWMiO-)I zdHL0-Ce6*%=TWxeZk+#Ol19m`npcg?#@FYi03>x4oHw5Td6oVG=eI+6vQY4jgEn8lwU z9~Vi^cms8%&Do8YdT;Ue?WAUy!=p(&BD?KYQ4L7dr7n5GS_+N6y#}XNl4KDiL8PydwFr+H@T;g%0)X{p9=`}dgZ>V%}!-i>Qs;P zWe`-p9er9PRmZhZZ%P^~LpQ(k!>PU&4IYOtnu|Lf#&>AtN9Pr5)U^5R5y|fKDBN0F zcZ}6RYw5gnme<{-tWzcF`Pl;W7fBvba+m80(l@fPsm0yIezdAR@Ju+EctD!?K=>x+ zFti*e7ZrJeAETv8>vd;tgBbO@Vx%Twx3Am!ZQJ&xZjd*ANkN{ph(_;%Z0_4$-cNCM z&!+l|TWXviyzu^B@i6|rf}TvR9mOptYP)6^X^Tj{#_MdQ0t&>3+OtiG&iH>;@yF7i z4rPwoCbvWQOr)x|rAjB4awk{BTP#(>o>?RDyNosohfx;-aE^%#SG2AkXdR{6gY}&J z$Z>;*oa0HDo)6aLNNb?3;!g8<3c((3ZW3DY>XlbXyUstl>PXx3)H*J zi~Oz0k}r?n+y7iHa<3g5tGgn5%eyV}ku-hOdS~-RsJG?5iK4}*4vA+yS2Gy;T5ETE z)APboUSYCf2DI`OqXLhHqEQwthbB`qyA?$e7t}5Fi1^jR>RI`l8dp4T-B)9&Bo&Nagf5$TZdu5kC})i(QR8B|4DzFod-cLTNk3x zeckyMT+U1A+wq}s7p7#l?7wxGZ#%}JthW78PhNvu$)r#9yqmrcn#e z{2Y`&ADGRX`<=4K_f3scmGFva#(c+NL+Mvyy1Mn1UbLv*rUs`2k7mb;&f#ojSoluA zq1C*)^hvGA7z1j|&{ae{by&vQ#4C>^O z)V5C^K;138HMQx&*}WcOZK_AL>%ROjEI(>)p782T8DpTE?e+ZIqg^gJKAzJRF||Yu z)>h93Cf^)Swqy)u)TZk0$*+&gn~D8WVtDDSf!Q6q=$F^KeTF=Qa>=Ra=LbAoQ6YM} z%f&mFCz`^y%^zl1C03HJ<5U+gP@T;fCRQ&Cj`Qmx>Arg2dO6X`X+%z-di-(Uy9ClU z(l+uobvkh}-}A&~t@gY8pUGnOFEQs_y&f4@Ng5X`D3g5uN9@QgT{VUdUp16@YjqJ( zSVi|ry*kP_xy&2W`tYH$r`h6nZ9g}qeW9q~R?(OAH0C8`i+*P5J^f@7rJ1D?{_?7v z=r@*06+E1jlXi_{yLNxnVkEs}NhaZ+ktoPWD*E{noxF9$eybH%^w;ceZoeQ;M&}#4 zZN_YBPk3EXO_?2T23W41q(Odb-VdA|)#Pnk+gRH44)c<|z;K$}aHJVsP2!JM=VeQg zm+w$jyNV@Bn5z4c;&00!-)r7?`oOAO(I@TlOcJHZ1)i6K3O}51Y7KjGcfSpG+l@}1 z);@lnXu_dAz>S-hiO5Im>+xqNhAXnL(qj9;Yc1OM6vNEu1<-6ZOKDWQ^QI$sbv~sY_qC`f?0Z?0M|Q z-7QSy@wTj=XFfZj(<=X)BI@&K<=%#QG1dVt1DB~bA(91YBCUH$YUWK+G1{D$zbT+v z?3#l-gv3^+7^C#>P&#uyS5AHspx!wcWS|n)D~lG-_#E+UKDugDE^_4ieK0Q@6|UTl z7=BIK!H+4PU8$)|kPQ?$f2-056+j=mrTUJY9NI<&Z7Ug2{8{>v%snRxze6W>6sftV zZ1*ZTMDb1yb%vtQU9xcGdvCh4=go^dP;Aw$Q_UJjCS5|0V~VMy?P%m|$b>z<_=@+s zW8NQ73Z5}$mfUvR2bFrxCNQ6JAh5%}_sUr0>`~H*YbB1W*5})9wkJyN%JNTLp7Wgc zxukegq?~ku!ppKP1&hieeL3~*UXfLosj+@lWDfTeE_CK-g6H*Wocw}K`xPR}u*Qmt z+wYW*^#r;{2VEk`mcy7u>@=mzQ9wP2ow=EdGdp+LP`kfQh(YVLXN{hLnmYFOccBFULhfFv}cQ{&~m-5eU(0irMvrRg(&12fo zNnOaXH=6ulYz_$nDa}AuQvv1vu^+K*og*>x_99#3R6F_JFp#PzO$?U%?Tovi$J!Xc zWkB{>P`T!I^ibRN`7a3_#QjTCp5B&WgVX&_gUhV4U4zPEm~-M+Z;s?vA6nc-MjGnm zV8VCa&SEiWa)db4aPqLgYAVyPgpvoRb4_DFZHcK@tZJNyHy_Q|NR*siOsHmrcwlFN@< zdch{y9e#!3)7#@vzeSVQ%aoX(y`k`}}V-%AWcHSW=)zbrmT z5hcUWoNq?@GTt&KkxZ_>*53Y^f@;;b6warSO5MBDQTlFW69!f)4}Ms+4kE<@SM-z6>PB_fZZzhIjPDvx%ag-OcJ5y?!jO zCt`;X8PNrvqJm;s`bZZQl=-=u2h)bzj5~RS6u6y8lYNqtTzGrvExlhu!o z#E|S`N%i(_ix$_xojtVjr?SBgDJ7xc(o-un~Lwwd6fMhaJy z)-AQ}19j@%r}oG2?r;w2E|X#jT#QZN2qW3*TSKCO`YbYF{G~?uZ7aDp@vzUGW?KDC zqWyP86oWNx1uwRkHro&dbdweBT)kUlx5pcMF4kDV?eTGzUY0;oTcU2ch^iNXvJ9(omjdxs#zTeD^ zveDFfE&ap+Z z3UAi*i)X0b#avh(m6Slxy)wAod>F;Y6oX%nRlww04hsyW>XRP77;={TWBp>(tI4`gXg-bB^rgjT(|$D~Wp= zUUzr5@1n`zCU2^Gu?5GRFmAqg=FCxMmg{e4rmYhO^<3ya`k>nMv(F!%h<|gv@2l#7 zwdFe8pzI@v+cj4lGJ!+oRcjVhwlw zD`~C{w99%vV5{FpuW41>wI^*QxlCha4maigWk_2P1AX38Hx(+0`V1A+1DR(O7Q)(Q z`YdDBC)z}27LD(DYZNBREomASovE+rq3Ih=V|G^xp@aBA$3t_fuY6x zd-bT}(`PFB4EeWyM0jKR4qT%By5bUV6P;NuTV7zIIzoq;5>1KrJ1Z{N)}b+;Bd%+> zleuS;o{O%N{zAqeLy)Ub0nfwjMH1ziTjOE6F+oAN1{?{Z7|;d4Y!G)z4UOh9mW?nK#0A?xA{)$mfGF}mu|`JU<; z@}1WeqQ%%qCdl55FbGkiGet5}2FpU7N8fi__Zz#S;&^9La8FaKr=8#0rg+{h(TzRe zOP-P=!A8+vlbUx#_AF{aGr-crvhu|N(>o5;^yu16vdNS)bF)Z$*zO0o>0 zy?e>r9($qM7~29Ajmri`XfXqytw~vOOjYC@=Pie5SYE4RQ6yH+bM1S5Vw}w8TLPM2 zJ*QWbH7(#O%JKF?Rh>KGJRPwQN8H;cSDJb@xJTmVkX1(JVH2DeCH31o=3W|8gM)RdH=~mtAW-$#VS{5pFCS9h#*ab0*Lnk~p zbsZAtP?wB7_Tm8(CMQCX%vDBgsH=0h1}hS`v&=YXYNS7a!FHbFX{1Uw_vSe}u`^*k z^Ga$u_71w37mhWWRnjk0Qd|W?N<2I{9bcQsoGaSv*CfCD1%?-+VZIaQ*qNyFHzVuj9!%OgiOvCH~$yKx3x2+*` zD2*c%#|(W0r=9sKV=GQa-6^`H2^^6w--j#ow?f_I_}^$4vE$fjn}>oL{K(_^1B$O^ zi^OrtZP{{{PVwT1W}f1h?8@zukNUo%*_#hJZn-slJMT!+!_aL~USQ)K!L-%6Dg^Z@ z^uZ>1cLs@PG)4_8%*+QkOYHJOYr>6p%kjVEcHtPhR^^gwZohkU(49s?!Kg?5`N#vM zRuZEovLNA}Qe}2|49C><&Ors&0cUysHxs-p-l6rh12!*fVLEJnRLO=7d@S=$U z=Lb)ec9Udgu+J51cCE=8iZo(LD_gTB=GoJA0+>&!!FN@U#U;}&jGvgkv77CNi+@+- zaZ~*k%8tBY2Fz4CL*tpV?-vz|%7-!>RC2$+8q+-6d&B-z3Y}{_ zHNDd=k{QR7;V7-sk^y=*<@8AI%!e>wyrd$PBS^I*CzKtDG!rsOUwYl%y0~)CFRK24 zg}7;V*|xa}f8-^1Jle(Z3s%d4Yd>ayDl_Fe8K+0#UUkO? zjYXQCJJ>TFkaKWsG?XfM>&W$r$Xv{4w@BZG*Q677x(6Dc)$V0_P*$VpsL@;6)^$!_ z!R*WhcMD3A1}8nOs53hxn`xE8ZT4x>Q5|E{B4Wn&b^D%&C znbb_OVwSXfY@ib3?lfKOD6g!jz zR2EkfP~Z+D6=bJ-HM{RC`ONksSku5#2K_ocS}P8;rJ*=CDn_oN;kJ~roC5b*(!u3O zS+pQfmhr*6!?L)zkNYrdUb|w?eqy@E zn#_kIFf!!iiRmFlo8izGSMG9D+^{T@y(c>U<@P=kRwwc_%Gm813xV1>RxZt=Rq_s0 z_FMDPyBx;f=aDg$cqte*e2NEx8^0~Z7wNgV(3)*OA&BkgI$JByvl3P_y>jQ4=^!qz zQEh%~(E7)l-07Z~tgwCFvZsc-qHUL_#(T0;#(QrWP~-+Z)V%M_S6mP$6lFCNv^Udx z(M8&dg-8ngo4Mr)KAE|XlR=(_KiU=#r1tJSb?a+|@K6SYK<%zP%c!l@^@ZWOs%&yH z3YCkxIEJS_aflRIm6Q-fo7@0l5a3iFy)X>}jn zUNy7&*oyjKsc+K4J;K-@X$gaB6)hj@pSwSgB@<_g<@8)QEZ@dFn^-ZOu3MqqL_ak# zD-cl6b-b6gVeY%x^NR&PMkb>&Ge%?XTvEr)H{3}7ZkB8Jt+mMKWEAbBGcpSDk3dtE zCi+RiuMO`$bGbZs`B1obXHd3E{rre3-;6)&oz9h#`ggakvVKkyVRh1V8c-}MVxA?# zd>QYrS9#0jUF2U8aMJP}y1`Y&rZg!j{ItS_uOYZ?(SB1c&UP-}qVyL&J)TgtWW3E@ z7&Gp<`D}dV0dEhnA0i>&3QgO6rc@#X#(2CsZRDTeyJc% z10}QCMsX&oIXu+y^u(*YOIMSrgU>x;J|P<69#wVjgX7uxW!}WWRwWNk zNtF`PxHoyOM6_aFJnUI@a3e9w?cE)2=i+>>AidX`LpEquS;h-=q5f3*`Q0tw$S?Ok zsZOEoy-<9rB9v)B=L%&9ji<$2<=gLyPX=(}GYY3X?RFNL+%zS1&N|#`Vg0eLSd#bz z`r~uTR5HE0d(SN7a|ZM1qpFWU*BLf{6-~Z%bw{BE*}$1hk`hw|H62H)!eY^~Z@5j* zUPaJ^(8=@Xze6#3VxKPC%rO+!-4Cz}@-gJF;_IH?{)Do()SN?!T)wDw%V*M}Q-@KT zp3#lx-urr}nC;e;Pf^OJ?!VroPV`P6Lx*|!P@7aX{k7cSC11Kigzx+#NoQk?eNQMQ zm?f``MrhB)J~&R2vPDDw45uWGrcM0CmB_WgVzCqwrLt!Pl3emBT9Tvj=n*){*grgKc$KL44lmm~Vs z1uE%r(wV(gEZ-ZgUcJBm<9Gmvdky`YwB#`7*9*9$+nD5Hy3xZKW)yc0TwQt@o*k}K zDnK-1|H$|RN~lJMtVFtWpOnO0#C|TyOSnh-l5gH+1@UM?M0jg>`zc)3xzTH_7O$5I zw^lpxo#5Jk@ z_9~HYo_}2W93^FU*??*9C*{LL(+yu$=30ZrFIgAJ`jL${T@>C@JAPs3y;nJ}zJ6O%q#j%#JKUF6;-(9w*QZbp=6%*enYwC{r;-g!6_Nht(r9hAOzEg|4 zn(EIDYE&g$F!ypkjXSQkUowvavQZoEls{x-|Mu?Gc^c;jgB-X;&S{gPYfbAEXB(cgyv;9hY`jpWBz4eyj`Zd0 zd&Cl?WKLzCGAu8=+_PxRIxouVOK`Bw-*br6rEBAUdgnCmt7|%MYs=w`7?x$0MaXK(eeQ0bu8-C>4bLHiZRG$_;jAQVAL6%%=P0#dbyS(QWpO5#k zvv)_>Hw1XSBN35mwI%Mydg>^=4BYHkb?g$m`*|WA-CV9TqRS^RG2c@5UaO9!F-%DD z@KNn$e{NtQOcS+qJ%R`5;qd#{D(;R|k0?x*V(#Wd!Awy#^A8C>4(>Cn>Ze&MlU*2iTzF4=;&X}eQ2HgOlz%AY;Smw{5- zWYT+lX^YfnSB+UArIjbj1q)7(eiYi}^BInm-I0+p6t3dAHNiPCrgBc6nx?V%nhr~+ zqEAKr@fg|)6JMj$JxpxTmlG8Cy)SW1Enrl?c7F$^^6J54iSACL2GO@VcI+<>HK@lt zc_{PnNvY1=k)lVgg&BE5LpoRZ=VX^@m$l^S+0n`GKjjkha#JZ#JT&d~x+{BUuCLzl zh~MF(#_1Cdq<&x8DEm9q26R~%a)N}_2j>L$8k(Y%)c&S!Bd2NHG{)EIGk!> zX2&T?V+I4N733ZF}Rq{#c3!>C)?qwvB)ZFK`P;my=xXbLMFz3F0pI-qPi4`rr|WB zyzOBMQnDF3qLHQcViVyV`9r~s3;GHSi!#;AcW)H3Dg;M|zf9JseOW^i#+ODvA7#Mr z=oenm*YcDu`D7XAm2lkCqZckwO&MlHoWnMI4xVr;pyx#IdhNLFqGF+7q%kG$Yw3dO z-Vy%yu`85v2dm0|$gw#x@-H4!(wU>1^MArCP1H?E6~}hj0HgbHY9Yr<((;-J<|C$t zLHuc=RISl8TFiK#svO+~yY_HLUL~?Xl;~?aRyJ2Gcj*e>J|Q-?NBv_=W*4V?@>WHH zwk>a7KI%pUOto3%;rKVMDNGEd*rS$*A!P34~IY*%e&Gjp>5&l59Jj95suz7Ov6mW&;! z&kuR+@?KPQ9CtZH6sRX9SDP+j?CVP6QdV$9*U*i3XB}P9RI5ny!I9jj-w$qg4>{O* z!(T}6KzCp9iZW|tX(N=>P~akqVVLBa+a6rXiI9qpuA&9|XU2LI?ppI7>P^~Ax!g1(`B2ri zj-Q2tx5r&aOZ1ZrzQPhc+R?R--MiuVp}8L0a;`R~QhFKm9#n^;c4a$CMlCtz)DweG zK~K#t@E(>N)p70JdoR;&ODPqRSx^p}j{YY4C!M_EM^ZNRju)0lIWY1x-lJ;RV!0yB zK2Z41?C+XSd^WgFg$aRi<#?u>)HcA618GGz&E1PF99k zKC|?9ofb-+XGh0var6vZRnoO}w^(sI5O&LWwlKL_0!lmwN zmJ94T2?}}flIhf%YWMc+_pC*e^C~o7YLXy!mrgzkF48E=d_xN5?-eOJN6=5ZEwbDg zOHLD_8GAO$HvKJru=vgKe#fE?wn<*pX>{E3>TaSYm5zrJ2S3|B$98hevCmnm?^}we zl`kN2WXxRPYfrDtUero+kapentw@tP8x_#7^6oJ;JJF@VbJJnyoCOe)7FOVfb0rf8$2$ijlH8_g zitPsd?3Y{mjmK7=Z(r3e*)G+-*wlW5>e=GI2ps)!^Od(+2FzIlvmiz89WqNbL?(1|K&|0iMoE{&Qb;%oM_NV&g^RFgU;QQ40r2SP&_r{M6Nq9 zeS)xCxv4o)YFdM;3>LXBcT~xUGvZ&Z$C!g@A}n3cCUy-du|Lav{z2a zM34$*5c^}<;tEX89Jbc6%Jj(E{Dgvz?Xdm$mFRt4<(KU#hOFzKjEi#DhKpPjHNSzi zuscd+l&$;rip+~+S~d|96Kh{6baP^F_21Pq$mJ`4m;5$|R$lgKXzN)maH(~RzMoi- z|LZ%y-F}M)O{P1T8N3wFoC-lLcAGpHs(yaICt^G*sunAeyZFU__zrFNzTVW{eT)M& zp79N+sl$HO7jG}?zX{E!%5YY*e)~yVo36Wa6?}Vf{_J$>YvG*8Kw3<=uTI-t&Q}aw z9^4cwBz~rfirr-Dz4`6|jj|ki9(y&8lFG-TLR)v2CijR83g#UZ$aYD2jM36C))_aM z8Iikupubc_fW%0v6x>PqYA@ZMq0{&7ceYS8xgXP&++IF!#uV?|cI8S(n$v^I=?A2w z=;maX3=XlBi&a#6KD^$Wbv4gRkk8wJH0}iLSbp>55c0K3*QuNNd%#C1bf@KRPB^EhUTS z(jEn|fN#{V8Wf~tBy2yo?`T{xQdc15X3?i9YlWWx1&9*UIiQu2NhO7;JDy$N!CmV) zxm?k`Kyz}wNbhP8IXx{IIeI(hA2F`Dh(t7&nZ-Th`Oy+al8@zCn3?O06I|f8o05*O@!UeR#%wG_`S??dnxd zksn6Ybvs>3_$(4j?{CG>LnO}B-!mPwgUe&qzay^o`eAAb`WP<7P^_2E0RQ$+6zFWd zC&LF%L_Q92wa)7=zEO=9dQN?&_hu_ycx2k9gL1CY7Kb?{>U@7>oqw1UG)qt9rZyxg z5un+(;&;+A?7`3n>uw`c`B~jTl_2MSMI~#R)QeMX5f$gG=Ct=x*@z{~gvQ&Kgf`T2 zQ^cVj5A%?8-z8&;H0*sVbXr$};rkxq&u$ERj=!TOIqCWG_QLCj)>Gr|+#cjof(JP# zRa>Y(L`)5wlCPtSttB3(a=P2;Zl2%!?}|Z-N$fqll~{NY_B5Rmf% Date: Thu, 7 Mar 2024 14:07:25 -0800 Subject: [PATCH 02/57] Complete push example --- .../com/baeldung/introduction/PushView.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/vaadin/src/main/java/com/baeldung/introduction/PushView.java b/vaadin/src/main/java/com/baeldung/introduction/PushView.java index 28d8162003..b49aa06e4d 100644 --- a/vaadin/src/main/java/com/baeldung/introduction/PushView.java +++ b/vaadin/src/main/java/com/baeldung/introduction/PushView.java @@ -1,6 +1,5 @@ package com.baeldung.introduction; -import com.vaadin.flow.component.html.H1; import com.vaadin.flow.component.html.Span; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.router.Route; @@ -16,12 +15,18 @@ public class PushView extends VerticalLayout { public PushView() { var output = new Span(); - add(new H1("Server Push"), output); + // Publish server time once a second + var serverTime = Flux.interval(Duration.ofSeconds(1)) + .map(o -> "Server time: " + Instant.now()); - Flux.interval(Duration.ofSeconds(1)) - .map(o -> "Server time: " + Instant.now()) - .subscribe(time -> getUI().ifPresent(ui -> ui.access(() -> { - output.setText(time); - }))); + + serverTime.subscribe(time -> + // ui.access is required to update the UI from a background thread + getUI().ifPresent(ui -> + ui.access(() -> output.setText(time)) + ) + ); + + add(output); } } From 19b08a71a245a035e3e44f1af193d80d5eee11a4 Mon Sep 17 00:00:00 2001 From: anujgaud <146576725+anujgaud@users.noreply.github.com> Date: Sat, 9 Mar 2024 00:08:20 +0530 Subject: [PATCH 03/57] Add InvalidCharactersUnitTest.java --- .../InvalidCharactersUnitTest.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java diff --git a/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java new file mode 100644 index 0000000000..0cfd4a864a --- /dev/null +++ b/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java @@ -0,0 +1,57 @@ +package com.baeldung.xml.invalidcharacters; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXParseException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.StringReader; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class InvalidCharactersUnitTest { + + @Test + void givenXml_whenReservedCharacters_thenThrowException() { + String invalidXmlString = "John & Doe"; + assertThrowsExactly(SAXParseException.class, () -> parseXmlString(invalidXmlString)); + } + + @Test + void givenXml_whenReservedCharactersEscaped_thenSuccess() { + String validXmlString = "John & Doe"; + + assertDoesNotThrow(() -> { + Document document = parseXmlString(validXmlString); + + assertNotNull(document); + assertEquals("John & Doe", document.getElementsByTagName("name").item(0).getTextContent()); + }); + } + + @Test + void givenXml_whenUnicodeCharacters_thenThrowException() { + String invalidXmlString = "John \u001E Doe"; + assertThrowsExactly(SAXParseException.class, () -> parseXmlString(invalidXmlString)); + } + + @Test + void givenXml_whenUnicodeCharactersEscaped_thenSuccess() { + String validXmlString = "John  Doe"; + assertDoesNotThrow(() -> { + Document document = parseXmlString(validXmlString); + + assertNotNull(document); + assertEquals("John \u001E Doe", document.getElementsByTagName("name").item(0).getTextContent()); + }); + } + + private Document parseXmlString(String xmlString) throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + InputSource inputSource = new InputSource(new StringReader(xmlString)); + return builder.parse(inputSource); + } +} From 6c8d1d2bf2972a9b89767b0b0388cf7add8bf605 Mon Sep 17 00:00:00 2001 From: anujgaud <146576725+anujgaud@users.noreply.github.com> Date: Sat, 9 Mar 2024 20:36:27 +0530 Subject: [PATCH 04/57] Add test for CDATA Sections --- .../invalidcharacters/InvalidCharactersUnitTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java index 0cfd4a864a..7878e72f97 100644 --- a/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java +++ b/xml-2/src/test/java/com/baeldung/xml/invalidcharacters/InvalidCharactersUnitTest.java @@ -30,6 +30,18 @@ public class InvalidCharactersUnitTest { assertEquals("John & Doe", document.getElementsByTagName("name").item(0).getTextContent()); }); } + + @Test + void givenXml_whenUsingCdataForReservedCharacters_thenSuccess() { + String validXmlString = ""; + + assertDoesNotThrow(() -> { + Document document = parseXmlString(validXmlString); + + assertNotNull(document); + assertEquals("John & Doe", document.getElementsByTagName("name").item(0).getTextContent()); + }); + } @Test void givenXml_whenUnicodeCharacters_thenThrowException() { From 58335b163a4d354946f6f2c3fb793b893f0e152c Mon Sep 17 00:00:00 2001 From: Marcus Hellberg Date: Wed, 20 Mar 2024 16:17:06 -0700 Subject: [PATCH 05/57] Add example complex layout --- .../introduction/basics/ExampleLayout.java | 45 +++++++++++++++++++ .../introduction/basics/VaadinFlowBasics.java | 2 + 2 files changed, 47 insertions(+) create mode 100644 vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java b/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java new file mode 100644 index 0000000000..6d6e2b2b7d --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/introduction/basics/ExampleLayout.java @@ -0,0 +1,45 @@ +package com.baeldung.introduction.basics; + +import com.baeldung.data.Contact; +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.splitlayout.SplitLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.router.Route; + +import java.util.List; + +@Route("example-layout") +public class ExampleLayout extends SplitLayout { + + public ExampleLayout() { + var grid = new Grid<>(Contact.class); + grid.setColumns("name", "email", "phone"); + grid.setItems(List.of( + new Contact("John Doe", "john@doe.com", "123 456 789"), + new Contact("Jane Doe", "jane@doe.com", "987 654 321") + )); + + var form = new VerticalLayout(); + + var nameField = new TextField("Name"); + var emailField = new TextField("Email"); + var phoneField = new TextField("Phone"); + var saveButton = new Button("Save"); + var cancelButton = new Button("Cancel"); + + form.add( + nameField, + emailField, + phoneField, + new HorizontalLayout(saveButton, cancelButton) + ); + + setSizeFull(); + setSplitterPosition(70); + addToPrimary(grid); + addToSecondary(form); + } +} diff --git a/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java index cd028dcd1d..7a22eea0ab 100644 --- a/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java +++ b/vaadin/src/main/java/com/baeldung/introduction/basics/VaadinFlowBasics.java @@ -45,6 +45,8 @@ public class VaadinFlowBasics extends VerticalLayout { ); add(nestedLayout); + add(new RouterLink("Example layout", ExampleLayout.class)); + // Use RouterLink to navigate to other views var link = new RouterLink("Hello world view", HelloWorldView.class); add(link); From a3af6f70fc3c8e168133e1d27cc9e9c65b32644f Mon Sep 17 00:00:00 2001 From: reza ganji Date: Sat, 30 Mar 2024 13:02:36 +0330 Subject: [PATCH 06/57] BAEL-7540 --- spring-5-webflux-2/README.md | 1 + spring-5-webflux-2/pom.xml | 6 +-- .../com/baeldung/webflux/caching/Item.java | 6 +-- .../baeldung/webflux/caching/ItemService.java | 10 ++-- .../controller/UserController.java | 35 ++++++++++++++ .../ex/NotFoundException.java | 12 +++++ .../exceptionhandeling/model/User.java | 29 +++++++++++ .../repository/UserRepository.java | 24 ++++++++++ .../webflux/filerecord/FileRecord.java | 4 +- .../filerecord/FileRecordApplication.java | 3 +- .../filerecord/FileRecordController.java | 7 +-- .../webflux/filerecord/FileRecordService.java | 1 + .../com/baeldung/webflux/model/Payment.java | 1 - .../webflux/zipwhen/service/EmailService.java | 10 ++-- .../webflux/zipwhen/web/UserController.java | 16 +++---- .../src/main/resources/logback.xml | 2 +- .../MonoFluxResultCachingLiveTest.java | 41 ++++++++-------- .../UserControllerUnitTest.java | 48 +++++++++++++++++++ .../FileRecordControllerIntegrationTest.java | 11 +++-- .../FirstElementOfFluxUnitTest.java | 1 + .../zipwhen/UserControllerUnitTest.java | 12 ++--- 21 files changed, 217 insertions(+), 63 deletions(-) create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java create mode 100644 spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java diff --git a/spring-5-webflux-2/README.md b/spring-5-webflux-2/README.md index 5232d86643..5579e1cec5 100644 --- a/spring-5-webflux-2/README.md +++ b/spring-5-webflux-2/README.md @@ -3,6 +3,7 @@ This module contains articles about Spring 5 WebFlux ## Relevant articles: + - [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable) - [Comparison Between Mono’s doOnNext() and doOnSuccess()](https://www.baeldung.com/mono-doonnext-doonsuccess) - [How to Access the First Element of a Flux](https://www.baeldung.com/java-flux-first-element) diff --git a/spring-5-webflux-2/pom.xml b/spring-5-webflux-2/pom.xml index 38cbbc8bf0..85e451c075 100644 --- a/spring-5-webflux-2/pom.xml +++ b/spring-5-webflux-2/pom.xml @@ -1,7 +1,7 @@ - + 4.0.0 spring-5-webflux-2 1.0-SNAPSHOT diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java index 54b7d63f33..6ad03baafc 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java @@ -41,10 +41,6 @@ public class Item { @Override public String toString() { - return "Item{" + - "id='" + _id + '\'' + - ", name='" + name + '\'' + - ", price=" + price + - '}'; + return "Item{" + "id='" + _id + '\'' + ", name='" + name + '\'' + ", price=" + price + '}'; } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java index 9bf934b504..9286cecef8 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java @@ -16,7 +16,8 @@ public class ItemService { public ItemService(ItemRepository repository) { this.repository = repository; - this.cache = Caffeine.newBuilder().build(this::getItem_withCaffeine); + this.cache = Caffeine.newBuilder() + .build(this::getItem_withCaffeine); } @Cacheable("items") @@ -30,11 +31,14 @@ public class ItemService { @Cacheable("items") public Mono getItem_withCache(String id) { - return repository.findById(id).cache(); + return repository.findById(id) + .cache(); } @Cacheable("items") public Mono getItem_withCaffeine(String id) { - return cache.asMap().computeIfAbsent(id, k -> repository.findById(id).cast(Item.class)); + return cache.asMap() + .computeIfAbsent(id, k -> repository.findById(id) + .cast(Item.class)); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java new file mode 100644 index 0000000000..6490b997af --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java @@ -0,0 +1,35 @@ +package com.baeldung.webflux.exceptionhandeling.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; +import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; +import com.baeldung.webflux.zipwhen.model.User; + +import reactor.core.publisher.Mono; + +@RestController +public class UserController { + + private final UserRepository userRepository; + + @Autowired + public UserController(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @GetMapping("/user/{id}") + public Mono getUserByIdThrowingException(@PathVariable String id) { + return userRepository.findById(id) + .switchIfEmpty(Mono.error(new NotFoundException("User not found"))); + } + + @GetMapping("/user/{id}") + public Mono getUserByIdUsingMonoError(@PathVariable String id) { + return userRepository.findById(id) + .switchIfEmpty(Mono.error(() -> new NotFoundException("User not found"))); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java new file mode 100644 index 0000000000..5401a4d133 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java @@ -0,0 +1,12 @@ +package com.baeldung.webflux.exceptionhandeling.ex; + +public class NotFoundException extends RuntimeException { + + public NotFoundException(String message) { + super(message); + } + + public NotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java new file mode 100644 index 0000000000..42e1293ee8 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java @@ -0,0 +1,29 @@ +package com.baeldung.webflux.exceptionhandeling.model; + +public class User { + private String id; + private String username; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public User(String userId, String userName) { + this.id=userId; + this.username=userName; + + } +} + diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java new file mode 100644 index 0000000000..7d4ac0af86 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java @@ -0,0 +1,24 @@ +package com.baeldung.webflux.exceptionhandeling.repository; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.stereotype.Repository; + +import com.baeldung.webflux.zipwhen.model.User; + +import reactor.core.publisher.Mono; + +@Repository +public class UserRepository { + private final Map userDatabase = new ConcurrentHashMap<>(); + + public UserRepository() { + userDatabase.put("1", new User("1", "John Doe")); + userDatabase.put("2", new User("2", "Jane Smith")); + } + + public Mono findById(String id) { + return Mono.justOrEmpty(userDatabase.get(id)); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java index 5c0e265e13..bd339bf849 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java @@ -1,9 +1,9 @@ package com.baeldung.webflux.filerecord; -import org.springframework.data.annotation.Id; - import java.util.List; +import org.springframework.data.annotation.Id; + public class FileRecord { @Id private int id; diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java index 9c20e10040..0388bdb0b8 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java @@ -1,6 +1,5 @@ package com.baeldung.webflux.filerecord; -import io.r2dbc.spi.ConnectionFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @@ -8,6 +7,8 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer; import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator; +import io.r2dbc.spi.ConnectionFactory; + @SpringBootApplication public class FileRecordApplication { diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java index 943cec9a2d..b3cd0b89e4 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java @@ -1,12 +1,13 @@ package com.baeldung.webflux.filerecord; +import java.nio.file.Paths; + import org.springframework.http.codec.multipart.FilePart; import org.springframework.web.bind.annotation.*; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.nio.file.Paths; - @RestController public class FileRecordController { @@ -28,7 +29,7 @@ public class FileRecordController { FileRecord fileRecord = new FileRecord(); return filePartFlux.flatMap(filePart -> filePart.transferTo(Paths.get(filePart.filename())) - .then(Mono.just(filePart.filename()))) + .then(Mono.just(filePart.filename()))) .collectList() .flatMap(filenames -> { fileRecord.setFilenames(filenames); diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java index 6e74f3577b..bce8c82c39 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java @@ -1,6 +1,7 @@ package com.baeldung.webflux.filerecord; import org.springframework.stereotype.Service; + import reactor.core.publisher.Mono; @Service diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java index f9be73ee44..1fc090446a 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java @@ -1,6 +1,5 @@ package com.baeldung.webflux.model; - public class Payment { private final int amount; diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java index 9c0340b7ee..c4c5520d24 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java @@ -11,10 +11,10 @@ public class EmailService { public Mono sendEmail(String userId) { return userService.getUser(userId) - .flatMap(user -> { - System.out.println("Sending email to: " + user.getEmail()); - return Mono.just(true); - }) - .defaultIfEmpty(false); + .flatMap(user -> { + System.out.println("Sending email to: " + user.getEmail()); + return Mono.just(true); + }) + .defaultIfEmpty(false); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java index dbd89c45d3..fa0d083beb 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java @@ -28,16 +28,16 @@ public class UserController { public Mono> combineAllDataFor(@PathVariable String userId) { Mono userMono = userService.getUser(userId); Mono emailSentMono = emailService.sendEmail(userId) - .subscribeOn(Schedulers.parallel()); + .subscribeOn(Schedulers.parallel()); Mono databaseResultMono = userMono.flatMap(user -> databaseService.saveUserData(user) - .map(Object::toString)); + .map(Object::toString)); return userMono.zipWhen(user -> emailSentMono, Tuples::of) - .zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> { - User user = tuple.getT1(); - Boolean emailSent = tuple.getT2(); - return ResponseEntity.ok() - .body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult); - }); + .zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> { + User user = tuple.getT1(); + Boolean emailSent = tuple.getT2(); + return ResponseEntity.ok() + .body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult); + }); } } diff --git a/spring-5-webflux-2/src/main/resources/logback.xml b/spring-5-webflux-2/src/main/resources/logback.xml index 48b68c6bf1..122a79945b 100644 --- a/spring-5-webflux-2/src/main/resources/logback.xml +++ b/spring-5-webflux-2/src/main/resources/logback.xml @@ -1,7 +1,7 @@ + class="ch.qos.logback.core.ConsoleAppender"> %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java index 2075c1e77e..2ff2c15662 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java @@ -1,5 +1,6 @@ package com.baeldung.webflux.caching; +import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -12,13 +13,10 @@ import org.testcontainers.utility.DockerImageName; import reactor.core.publisher.Mono; -import static org.assertj.core.api.Assertions.assertThat; - @SpringBootTest @ActiveProfiles("cache") public class MonoFluxResultCachingLiveTest { - @Autowired ItemService itemService; @@ -30,32 +28,34 @@ public class MonoFluxResultCachingLiveTest { registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); } -@Test -public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { - Mono glass = itemService.save(new Item("glass", 1.00)); + @Test + public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { + Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block().get_id(); + String id = glass.block() + .get_id(); - Mono mono = itemService.getItem(id); - Item item = mono.block(); + Mono mono = itemService.getItem(id); + Item item = mono.block(); - assertThat(item).isNotNull(); - assertThat(item.getName()).isEqualTo("glass"); - assertThat(item.getPrice()).isEqualTo(1.00); + assertThat(item).isNotNull(); + assertThat(item.getName()).isEqualTo("glass"); + assertThat(item.getPrice()).isEqualTo(1.00); - Mono mono2 = itemService.getItem(id); - Item item2 = mono2.block(); + Mono mono2 = itemService.getItem(id); + Item item2 = mono2.block(); - assertThat(item2).isNotNull(); - assertThat(item2.getName()).isEqualTo("glass"); - assertThat(item2.getPrice()).isEqualTo(1.00); -} + assertThat(item2).isNotNull(); + assertThat(item2.getName()).isEqualTo("glass"); + assertThat(item2.getPrice()).isEqualTo(1.00); + } @Test public void givenItem_whenGetItemWithCacheIsCalled_thenMonoResultIsCached() { Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block().get_id(); + String id = glass.block() + .get_id(); Mono mono = itemService.getItem_withCache(id); Item item = mono.block(); @@ -76,7 +76,8 @@ public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { public void givenItem_whenGetItemWithCaffeineIsCalled_thenMonoResultIsCached() { Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block().get_id(); + String id = glass.block() + .get_id(); Mono mono = itemService.getItem_withCaffeine(id); Item item = mono.block(); diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java new file mode 100644 index 0000000000..d59ec52f3c --- /dev/null +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.webflux.exceptionhandeling; + +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import static org.mockito.Mockito.when; + +import com.baeldung.webflux.exceptionhandeling.controller.UserController; +import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; +import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; + +public class UserControllerUnitTest { + @Mock + private UserRepository userRepository; + + @InjectMocks + private UserController userController; + + public UserControllerUnitTest() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testGetUserByIdUsingMonoError_UserNotFound() { + String userId = "3"; + when(userRepository.findById(userId)).thenReturn(Mono.empty()); + StepVerifier.create(userController.getUserByIdUsingMonoError(userId)) + .expectError(NotFoundException.class) + .verify(); + } + + @Test + public void testGetUserByIdThrowingException_UserNotFound() { + String userId = "3"; + when(userRepository.findById(userId)).thenReturn(Mono.empty()); + assertThrows(NotFoundException.class, () -> userController.getUserByIdThrowingException(userId) + .block()); + } + +} + diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java index c47d53632b..f8585852c1 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java @@ -1,5 +1,10 @@ package com.baeldung.webflux.filerecord; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.util.List; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -13,13 +18,9 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.LinkedMultiValueMap; + import reactor.core.publisher.Mono; -import java.util.List; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - @ExtendWith(SpringExtension.class) @SpringBootTest(classes = FileRecordController.class) @ContextConfiguration(classes = { FileRecordController.class }) diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java index a036011796..d7c084e3ec 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java @@ -7,6 +7,7 @@ import java.util.Optional; import org.junit.jupiter.api.Test; import com.baeldung.webflux.model.Payment; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java index 8ed4cfb6c6..07c54fd531 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java @@ -25,19 +25,19 @@ public class UserControllerUnitTest { User user = new User(userId, "John Doe"); Mockito.when(userService.getUser(userId)) - .thenReturn(Mono.just(user)); + .thenReturn(Mono.just(user)); Mockito.when(emailService.sendEmail(userId)) - .thenReturn(Mono.just(true)); + .thenReturn(Mono.just(true)); Mockito.when(databaseService.saveUserData(user)) - .thenReturn(Mono.just(true)); + .thenReturn(Mono.just(true)); UserController userController = new UserController(userService, emailService, databaseService); Mono> responseMono = userController.combineAllDataFor(userId); StepVerifier.create(responseMono) - .expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody() - .equals("Response: " + user + ", Email Sent: true, Database Result: " + true)) - .verifyComplete(); + .expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody() + .equals("Response: " + user + ", Email Sent: true, Database Result: " + true)) + .verifyComplete(); } } From 2c5307571e6377e436e6f9cc5819e341b6d72cdd Mon Sep 17 00:00:00 2001 From: reza ganji Date: Sat, 30 Mar 2024 13:05:53 +0330 Subject: [PATCH 07/57] Revert "BAEL-7540" This reverts commit a3af6f70fc3c8e168133e1d27cc9e9c65b32644f. --- spring-5-webflux-2/README.md | 1 - spring-5-webflux-2/pom.xml | 6 +-- .../com/baeldung/webflux/caching/Item.java | 6 ++- .../baeldung/webflux/caching/ItemService.java | 10 ++-- .../controller/UserController.java | 35 -------------- .../ex/NotFoundException.java | 12 ----- .../exceptionhandeling/model/User.java | 29 ----------- .../repository/UserRepository.java | 24 ---------- .../webflux/filerecord/FileRecord.java | 4 +- .../filerecord/FileRecordApplication.java | 3 +- .../filerecord/FileRecordController.java | 7 ++- .../webflux/filerecord/FileRecordService.java | 1 - .../com/baeldung/webflux/model/Payment.java | 1 + .../webflux/zipwhen/service/EmailService.java | 10 ++-- .../webflux/zipwhen/web/UserController.java | 16 +++---- .../src/main/resources/logback.xml | 2 +- .../MonoFluxResultCachingLiveTest.java | 41 ++++++++-------- .../UserControllerUnitTest.java | 48 ------------------- .../FileRecordControllerIntegrationTest.java | 11 ++--- .../FirstElementOfFluxUnitTest.java | 1 - .../zipwhen/UserControllerUnitTest.java | 12 ++--- 21 files changed, 63 insertions(+), 217 deletions(-) delete mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java delete mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java delete mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java delete mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java delete mode 100644 spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java diff --git a/spring-5-webflux-2/README.md b/spring-5-webflux-2/README.md index 5579e1cec5..5232d86643 100644 --- a/spring-5-webflux-2/README.md +++ b/spring-5-webflux-2/README.md @@ -3,7 +3,6 @@ This module contains articles about Spring 5 WebFlux ## Relevant articles: - - [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable) - [Comparison Between Mono’s doOnNext() and doOnSuccess()](https://www.baeldung.com/mono-doonnext-doonsuccess) - [How to Access the First Element of a Flux](https://www.baeldung.com/java-flux-first-element) diff --git a/spring-5-webflux-2/pom.xml b/spring-5-webflux-2/pom.xml index 85e451c075..38cbbc8bf0 100644 --- a/spring-5-webflux-2/pom.xml +++ b/spring-5-webflux-2/pom.xml @@ -1,7 +1,7 @@ - + 4.0.0 spring-5-webflux-2 1.0-SNAPSHOT diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java index 6ad03baafc..54b7d63f33 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java @@ -41,6 +41,10 @@ public class Item { @Override public String toString() { - return "Item{" + "id='" + _id + '\'' + ", name='" + name + '\'' + ", price=" + price + '}'; + return "Item{" + + "id='" + _id + '\'' + + ", name='" + name + '\'' + + ", price=" + price + + '}'; } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java index 9286cecef8..9bf934b504 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java @@ -16,8 +16,7 @@ public class ItemService { public ItemService(ItemRepository repository) { this.repository = repository; - this.cache = Caffeine.newBuilder() - .build(this::getItem_withCaffeine); + this.cache = Caffeine.newBuilder().build(this::getItem_withCaffeine); } @Cacheable("items") @@ -31,14 +30,11 @@ public class ItemService { @Cacheable("items") public Mono getItem_withCache(String id) { - return repository.findById(id) - .cache(); + return repository.findById(id).cache(); } @Cacheable("items") public Mono getItem_withCaffeine(String id) { - return cache.asMap() - .computeIfAbsent(id, k -> repository.findById(id) - .cast(Item.class)); + return cache.asMap().computeIfAbsent(id, k -> repository.findById(id).cast(Item.class)); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java deleted file mode 100644 index 6490b997af..0000000000 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling.controller; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; - -import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; -import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; -import com.baeldung.webflux.zipwhen.model.User; - -import reactor.core.publisher.Mono; - -@RestController -public class UserController { - - private final UserRepository userRepository; - - @Autowired - public UserController(UserRepository userRepository) { - this.userRepository = userRepository; - } - - @GetMapping("/user/{id}") - public Mono getUserByIdThrowingException(@PathVariable String id) { - return userRepository.findById(id) - .switchIfEmpty(Mono.error(new NotFoundException("User not found"))); - } - - @GetMapping("/user/{id}") - public Mono getUserByIdUsingMonoError(@PathVariable String id) { - return userRepository.findById(id) - .switchIfEmpty(Mono.error(() -> new NotFoundException("User not found"))); - } -} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java deleted file mode 100644 index 5401a4d133..0000000000 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling.ex; - -public class NotFoundException extends RuntimeException { - - public NotFoundException(String message) { - super(message); - } - - public NotFoundException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java deleted file mode 100644 index 42e1293ee8..0000000000 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling.model; - -public class User { - private String id; - private String username; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public User(String userId, String userName) { - this.id=userId; - this.username=userName; - - } -} - diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java deleted file mode 100644 index 7d4ac0af86..0000000000 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling.repository; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.stereotype.Repository; - -import com.baeldung.webflux.zipwhen.model.User; - -import reactor.core.publisher.Mono; - -@Repository -public class UserRepository { - private final Map userDatabase = new ConcurrentHashMap<>(); - - public UserRepository() { - userDatabase.put("1", new User("1", "John Doe")); - userDatabase.put("2", new User("2", "Jane Smith")); - } - - public Mono findById(String id) { - return Mono.justOrEmpty(userDatabase.get(id)); - } -} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java index bd339bf849..5c0e265e13 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java @@ -1,9 +1,9 @@ package com.baeldung.webflux.filerecord; -import java.util.List; - import org.springframework.data.annotation.Id; +import java.util.List; + public class FileRecord { @Id private int id; diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java index 0388bdb0b8..9c20e10040 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java @@ -1,5 +1,6 @@ package com.baeldung.webflux.filerecord; +import io.r2dbc.spi.ConnectionFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @@ -7,8 +8,6 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer; import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator; -import io.r2dbc.spi.ConnectionFactory; - @SpringBootApplication public class FileRecordApplication { diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java index b3cd0b89e4..943cec9a2d 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java @@ -1,13 +1,12 @@ package com.baeldung.webflux.filerecord; -import java.nio.file.Paths; - import org.springframework.http.codec.multipart.FilePart; import org.springframework.web.bind.annotation.*; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.nio.file.Paths; + @RestController public class FileRecordController { @@ -29,7 +28,7 @@ public class FileRecordController { FileRecord fileRecord = new FileRecord(); return filePartFlux.flatMap(filePart -> filePart.transferTo(Paths.get(filePart.filename())) - .then(Mono.just(filePart.filename()))) + .then(Mono.just(filePart.filename()))) .collectList() .flatMap(filenames -> { fileRecord.setFilenames(filenames); diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java index bce8c82c39..6e74f3577b 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java @@ -1,7 +1,6 @@ package com.baeldung.webflux.filerecord; import org.springframework.stereotype.Service; - import reactor.core.publisher.Mono; @Service diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java index 1fc090446a..f9be73ee44 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java @@ -1,5 +1,6 @@ package com.baeldung.webflux.model; + public class Payment { private final int amount; diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java index c4c5520d24..9c0340b7ee 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java @@ -11,10 +11,10 @@ public class EmailService { public Mono sendEmail(String userId) { return userService.getUser(userId) - .flatMap(user -> { - System.out.println("Sending email to: " + user.getEmail()); - return Mono.just(true); - }) - .defaultIfEmpty(false); + .flatMap(user -> { + System.out.println("Sending email to: " + user.getEmail()); + return Mono.just(true); + }) + .defaultIfEmpty(false); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java index fa0d083beb..dbd89c45d3 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java @@ -28,16 +28,16 @@ public class UserController { public Mono> combineAllDataFor(@PathVariable String userId) { Mono userMono = userService.getUser(userId); Mono emailSentMono = emailService.sendEmail(userId) - .subscribeOn(Schedulers.parallel()); + .subscribeOn(Schedulers.parallel()); Mono databaseResultMono = userMono.flatMap(user -> databaseService.saveUserData(user) - .map(Object::toString)); + .map(Object::toString)); return userMono.zipWhen(user -> emailSentMono, Tuples::of) - .zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> { - User user = tuple.getT1(); - Boolean emailSent = tuple.getT2(); - return ResponseEntity.ok() - .body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult); - }); + .zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> { + User user = tuple.getT1(); + Boolean emailSent = tuple.getT2(); + return ResponseEntity.ok() + .body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult); + }); } } diff --git a/spring-5-webflux-2/src/main/resources/logback.xml b/spring-5-webflux-2/src/main/resources/logback.xml index 122a79945b..48b68c6bf1 100644 --- a/spring-5-webflux-2/src/main/resources/logback.xml +++ b/spring-5-webflux-2/src/main/resources/logback.xml @@ -1,7 +1,7 @@ + class="ch.qos.logback.core.ConsoleAppender"> %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java index 2ff2c15662..2075c1e77e 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java @@ -1,6 +1,5 @@ package com.baeldung.webflux.caching; -import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -13,10 +12,13 @@ import org.testcontainers.utility.DockerImageName; import reactor.core.publisher.Mono; +import static org.assertj.core.api.Assertions.assertThat; + @SpringBootTest @ActiveProfiles("cache") public class MonoFluxResultCachingLiveTest { + @Autowired ItemService itemService; @@ -28,34 +30,32 @@ public class MonoFluxResultCachingLiveTest { registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); } - @Test - public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { - Mono glass = itemService.save(new Item("glass", 1.00)); +@Test +public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { + Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block() - .get_id(); + String id = glass.block().get_id(); - Mono mono = itemService.getItem(id); - Item item = mono.block(); + Mono mono = itemService.getItem(id); + Item item = mono.block(); - assertThat(item).isNotNull(); - assertThat(item.getName()).isEqualTo("glass"); - assertThat(item.getPrice()).isEqualTo(1.00); + assertThat(item).isNotNull(); + assertThat(item.getName()).isEqualTo("glass"); + assertThat(item.getPrice()).isEqualTo(1.00); - Mono mono2 = itemService.getItem(id); - Item item2 = mono2.block(); + Mono mono2 = itemService.getItem(id); + Item item2 = mono2.block(); - assertThat(item2).isNotNull(); - assertThat(item2.getName()).isEqualTo("glass"); - assertThat(item2.getPrice()).isEqualTo(1.00); - } + assertThat(item2).isNotNull(); + assertThat(item2.getName()).isEqualTo("glass"); + assertThat(item2.getPrice()).isEqualTo(1.00); +} @Test public void givenItem_whenGetItemWithCacheIsCalled_thenMonoResultIsCached() { Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block() - .get_id(); + String id = glass.block().get_id(); Mono mono = itemService.getItem_withCache(id); Item item = mono.block(); @@ -76,8 +76,7 @@ public class MonoFluxResultCachingLiveTest { public void givenItem_whenGetItemWithCaffeineIsCalled_thenMonoResultIsCached() { Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block() - .get_id(); + String id = glass.block().get_id(); Mono mono = itemService.getItem_withCaffeine(id); Item item = mono.block(); diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java deleted file mode 100644 index d59ec52f3c..0000000000 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling; - -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import static org.junit.jupiter.api.Assertions.assertThrows; - -import static org.mockito.Mockito.when; - -import com.baeldung.webflux.exceptionhandeling.controller.UserController; -import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; -import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; - -public class UserControllerUnitTest { - @Mock - private UserRepository userRepository; - - @InjectMocks - private UserController userController; - - public UserControllerUnitTest() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testGetUserByIdUsingMonoError_UserNotFound() { - String userId = "3"; - when(userRepository.findById(userId)).thenReturn(Mono.empty()); - StepVerifier.create(userController.getUserByIdUsingMonoError(userId)) - .expectError(NotFoundException.class) - .verify(); - } - - @Test - public void testGetUserByIdThrowingException_UserNotFound() { - String userId = "3"; - when(userRepository.findById(userId)).thenReturn(Mono.empty()); - assertThrows(NotFoundException.class, () -> userController.getUserByIdThrowingException(userId) - .block()); - } - -} - diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java index f8585852c1..c47d53632b 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java @@ -1,10 +1,5 @@ package com.baeldung.webflux.filerecord; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -import java.util.List; - import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -18,9 +13,13 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.LinkedMultiValueMap; - import reactor.core.publisher.Mono; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + @ExtendWith(SpringExtension.class) @SpringBootTest(classes = FileRecordController.class) @ContextConfiguration(classes = { FileRecordController.class }) diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java index d7c084e3ec..a036011796 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java @@ -7,7 +7,6 @@ import java.util.Optional; import org.junit.jupiter.api.Test; import com.baeldung.webflux.model.Payment; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java index 07c54fd531..8ed4cfb6c6 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java @@ -25,19 +25,19 @@ public class UserControllerUnitTest { User user = new User(userId, "John Doe"); Mockito.when(userService.getUser(userId)) - .thenReturn(Mono.just(user)); + .thenReturn(Mono.just(user)); Mockito.when(emailService.sendEmail(userId)) - .thenReturn(Mono.just(true)); + .thenReturn(Mono.just(true)); Mockito.when(databaseService.saveUserData(user)) - .thenReturn(Mono.just(true)); + .thenReturn(Mono.just(true)); UserController userController = new UserController(userService, emailService, databaseService); Mono> responseMono = userController.combineAllDataFor(userId); StepVerifier.create(responseMono) - .expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody() - .equals("Response: " + user + ", Email Sent: true, Database Result: " + true)) - .verifyComplete(); + .expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody() + .equals("Response: " + user + ", Email Sent: true, Database Result: " + true)) + .verifyComplete(); } } From fa1c5598b0429200709856c932301ae682a42678 Mon Sep 17 00:00:00 2001 From: reza ganji Date: Sat, 30 Mar 2024 13:08:12 +0330 Subject: [PATCH 08/57] Revert "Revert "BAEL-7540"" This reverts commit 2c5307571e6377e436e6f9cc5819e341b6d72cdd. --- spring-5-webflux-2/README.md | 1 + spring-5-webflux-2/pom.xml | 6 +-- .../com/baeldung/webflux/caching/Item.java | 6 +-- .../baeldung/webflux/caching/ItemService.java | 10 ++-- .../controller/UserController.java | 35 ++++++++++++++ .../ex/NotFoundException.java | 12 +++++ .../exceptionhandeling/model/User.java | 29 +++++++++++ .../repository/UserRepository.java | 24 ++++++++++ .../webflux/filerecord/FileRecord.java | 4 +- .../filerecord/FileRecordApplication.java | 3 +- .../filerecord/FileRecordController.java | 7 +-- .../webflux/filerecord/FileRecordService.java | 1 + .../com/baeldung/webflux/model/Payment.java | 1 - .../webflux/zipwhen/service/EmailService.java | 10 ++-- .../webflux/zipwhen/web/UserController.java | 16 +++---- .../src/main/resources/logback.xml | 2 +- .../MonoFluxResultCachingLiveTest.java | 41 ++++++++-------- .../UserControllerUnitTest.java | 48 +++++++++++++++++++ .../FileRecordControllerIntegrationTest.java | 11 +++-- .../FirstElementOfFluxUnitTest.java | 1 + .../zipwhen/UserControllerUnitTest.java | 12 ++--- 21 files changed, 217 insertions(+), 63 deletions(-) create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java create mode 100644 spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java diff --git a/spring-5-webflux-2/README.md b/spring-5-webflux-2/README.md index 5232d86643..5579e1cec5 100644 --- a/spring-5-webflux-2/README.md +++ b/spring-5-webflux-2/README.md @@ -3,6 +3,7 @@ This module contains articles about Spring 5 WebFlux ## Relevant articles: + - [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable) - [Comparison Between Mono’s doOnNext() and doOnSuccess()](https://www.baeldung.com/mono-doonnext-doonsuccess) - [How to Access the First Element of a Flux](https://www.baeldung.com/java-flux-first-element) diff --git a/spring-5-webflux-2/pom.xml b/spring-5-webflux-2/pom.xml index 38cbbc8bf0..85e451c075 100644 --- a/spring-5-webflux-2/pom.xml +++ b/spring-5-webflux-2/pom.xml @@ -1,7 +1,7 @@ - + 4.0.0 spring-5-webflux-2 1.0-SNAPSHOT diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java index 54b7d63f33..6ad03baafc 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java @@ -41,10 +41,6 @@ public class Item { @Override public String toString() { - return "Item{" + - "id='" + _id + '\'' + - ", name='" + name + '\'' + - ", price=" + price + - '}'; + return "Item{" + "id='" + _id + '\'' + ", name='" + name + '\'' + ", price=" + price + '}'; } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java index 9bf934b504..9286cecef8 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java @@ -16,7 +16,8 @@ public class ItemService { public ItemService(ItemRepository repository) { this.repository = repository; - this.cache = Caffeine.newBuilder().build(this::getItem_withCaffeine); + this.cache = Caffeine.newBuilder() + .build(this::getItem_withCaffeine); } @Cacheable("items") @@ -30,11 +31,14 @@ public class ItemService { @Cacheable("items") public Mono getItem_withCache(String id) { - return repository.findById(id).cache(); + return repository.findById(id) + .cache(); } @Cacheable("items") public Mono getItem_withCaffeine(String id) { - return cache.asMap().computeIfAbsent(id, k -> repository.findById(id).cast(Item.class)); + return cache.asMap() + .computeIfAbsent(id, k -> repository.findById(id) + .cast(Item.class)); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java new file mode 100644 index 0000000000..6490b997af --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java @@ -0,0 +1,35 @@ +package com.baeldung.webflux.exceptionhandeling.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; +import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; +import com.baeldung.webflux.zipwhen.model.User; + +import reactor.core.publisher.Mono; + +@RestController +public class UserController { + + private final UserRepository userRepository; + + @Autowired + public UserController(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @GetMapping("/user/{id}") + public Mono getUserByIdThrowingException(@PathVariable String id) { + return userRepository.findById(id) + .switchIfEmpty(Mono.error(new NotFoundException("User not found"))); + } + + @GetMapping("/user/{id}") + public Mono getUserByIdUsingMonoError(@PathVariable String id) { + return userRepository.findById(id) + .switchIfEmpty(Mono.error(() -> new NotFoundException("User not found"))); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java new file mode 100644 index 0000000000..5401a4d133 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java @@ -0,0 +1,12 @@ +package com.baeldung.webflux.exceptionhandeling.ex; + +public class NotFoundException extends RuntimeException { + + public NotFoundException(String message) { + super(message); + } + + public NotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java new file mode 100644 index 0000000000..42e1293ee8 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java @@ -0,0 +1,29 @@ +package com.baeldung.webflux.exceptionhandeling.model; + +public class User { + private String id; + private String username; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public User(String userId, String userName) { + this.id=userId; + this.username=userName; + + } +} + diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java new file mode 100644 index 0000000000..7d4ac0af86 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java @@ -0,0 +1,24 @@ +package com.baeldung.webflux.exceptionhandeling.repository; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.stereotype.Repository; + +import com.baeldung.webflux.zipwhen.model.User; + +import reactor.core.publisher.Mono; + +@Repository +public class UserRepository { + private final Map userDatabase = new ConcurrentHashMap<>(); + + public UserRepository() { + userDatabase.put("1", new User("1", "John Doe")); + userDatabase.put("2", new User("2", "Jane Smith")); + } + + public Mono findById(String id) { + return Mono.justOrEmpty(userDatabase.get(id)); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java index 5c0e265e13..bd339bf849 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java @@ -1,9 +1,9 @@ package com.baeldung.webflux.filerecord; -import org.springframework.data.annotation.Id; - import java.util.List; +import org.springframework.data.annotation.Id; + public class FileRecord { @Id private int id; diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java index 9c20e10040..0388bdb0b8 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java @@ -1,6 +1,5 @@ package com.baeldung.webflux.filerecord; -import io.r2dbc.spi.ConnectionFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @@ -8,6 +7,8 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer; import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator; +import io.r2dbc.spi.ConnectionFactory; + @SpringBootApplication public class FileRecordApplication { diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java index 943cec9a2d..b3cd0b89e4 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java @@ -1,12 +1,13 @@ package com.baeldung.webflux.filerecord; +import java.nio.file.Paths; + import org.springframework.http.codec.multipart.FilePart; import org.springframework.web.bind.annotation.*; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import java.nio.file.Paths; - @RestController public class FileRecordController { @@ -28,7 +29,7 @@ public class FileRecordController { FileRecord fileRecord = new FileRecord(); return filePartFlux.flatMap(filePart -> filePart.transferTo(Paths.get(filePart.filename())) - .then(Mono.just(filePart.filename()))) + .then(Mono.just(filePart.filename()))) .collectList() .flatMap(filenames -> { fileRecord.setFilenames(filenames); diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java index 6e74f3577b..bce8c82c39 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java @@ -1,6 +1,7 @@ package com.baeldung.webflux.filerecord; import org.springframework.stereotype.Service; + import reactor.core.publisher.Mono; @Service diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java index f9be73ee44..1fc090446a 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java @@ -1,6 +1,5 @@ package com.baeldung.webflux.model; - public class Payment { private final int amount; diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java index 9c0340b7ee..c4c5520d24 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java @@ -11,10 +11,10 @@ public class EmailService { public Mono sendEmail(String userId) { return userService.getUser(userId) - .flatMap(user -> { - System.out.println("Sending email to: " + user.getEmail()); - return Mono.just(true); - }) - .defaultIfEmpty(false); + .flatMap(user -> { + System.out.println("Sending email to: " + user.getEmail()); + return Mono.just(true); + }) + .defaultIfEmpty(false); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java index dbd89c45d3..fa0d083beb 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java @@ -28,16 +28,16 @@ public class UserController { public Mono> combineAllDataFor(@PathVariable String userId) { Mono userMono = userService.getUser(userId); Mono emailSentMono = emailService.sendEmail(userId) - .subscribeOn(Schedulers.parallel()); + .subscribeOn(Schedulers.parallel()); Mono databaseResultMono = userMono.flatMap(user -> databaseService.saveUserData(user) - .map(Object::toString)); + .map(Object::toString)); return userMono.zipWhen(user -> emailSentMono, Tuples::of) - .zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> { - User user = tuple.getT1(); - Boolean emailSent = tuple.getT2(); - return ResponseEntity.ok() - .body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult); - }); + .zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> { + User user = tuple.getT1(); + Boolean emailSent = tuple.getT2(); + return ResponseEntity.ok() + .body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult); + }); } } diff --git a/spring-5-webflux-2/src/main/resources/logback.xml b/spring-5-webflux-2/src/main/resources/logback.xml index 48b68c6bf1..122a79945b 100644 --- a/spring-5-webflux-2/src/main/resources/logback.xml +++ b/spring-5-webflux-2/src/main/resources/logback.xml @@ -1,7 +1,7 @@ + class="ch.qos.logback.core.ConsoleAppender"> %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java index 2075c1e77e..2ff2c15662 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java @@ -1,5 +1,6 @@ package com.baeldung.webflux.caching; +import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -12,13 +13,10 @@ import org.testcontainers.utility.DockerImageName; import reactor.core.publisher.Mono; -import static org.assertj.core.api.Assertions.assertThat; - @SpringBootTest @ActiveProfiles("cache") public class MonoFluxResultCachingLiveTest { - @Autowired ItemService itemService; @@ -30,32 +28,34 @@ public class MonoFluxResultCachingLiveTest { registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); } -@Test -public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { - Mono glass = itemService.save(new Item("glass", 1.00)); + @Test + public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { + Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block().get_id(); + String id = glass.block() + .get_id(); - Mono mono = itemService.getItem(id); - Item item = mono.block(); + Mono mono = itemService.getItem(id); + Item item = mono.block(); - assertThat(item).isNotNull(); - assertThat(item.getName()).isEqualTo("glass"); - assertThat(item.getPrice()).isEqualTo(1.00); + assertThat(item).isNotNull(); + assertThat(item.getName()).isEqualTo("glass"); + assertThat(item.getPrice()).isEqualTo(1.00); - Mono mono2 = itemService.getItem(id); - Item item2 = mono2.block(); + Mono mono2 = itemService.getItem(id); + Item item2 = mono2.block(); - assertThat(item2).isNotNull(); - assertThat(item2.getName()).isEqualTo("glass"); - assertThat(item2.getPrice()).isEqualTo(1.00); -} + assertThat(item2).isNotNull(); + assertThat(item2.getName()).isEqualTo("glass"); + assertThat(item2.getPrice()).isEqualTo(1.00); + } @Test public void givenItem_whenGetItemWithCacheIsCalled_thenMonoResultIsCached() { Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block().get_id(); + String id = glass.block() + .get_id(); Mono mono = itemService.getItem_withCache(id); Item item = mono.block(); @@ -76,7 +76,8 @@ public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { public void givenItem_whenGetItemWithCaffeineIsCalled_thenMonoResultIsCached() { Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block().get_id(); + String id = glass.block() + .get_id(); Mono mono = itemService.getItem_withCaffeine(id); Item item = mono.block(); diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java new file mode 100644 index 0000000000..d59ec52f3c --- /dev/null +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.webflux.exceptionhandeling; + +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import static org.mockito.Mockito.when; + +import com.baeldung.webflux.exceptionhandeling.controller.UserController; +import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; +import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; + +public class UserControllerUnitTest { + @Mock + private UserRepository userRepository; + + @InjectMocks + private UserController userController; + + public UserControllerUnitTest() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testGetUserByIdUsingMonoError_UserNotFound() { + String userId = "3"; + when(userRepository.findById(userId)).thenReturn(Mono.empty()); + StepVerifier.create(userController.getUserByIdUsingMonoError(userId)) + .expectError(NotFoundException.class) + .verify(); + } + + @Test + public void testGetUserByIdThrowingException_UserNotFound() { + String userId = "3"; + when(userRepository.findById(userId)).thenReturn(Mono.empty()); + assertThrows(NotFoundException.class, () -> userController.getUserByIdThrowingException(userId) + .block()); + } + +} + diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java index c47d53632b..f8585852c1 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java @@ -1,5 +1,10 @@ package com.baeldung.webflux.filerecord; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.util.List; + import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -13,13 +18,9 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.LinkedMultiValueMap; + import reactor.core.publisher.Mono; -import java.util.List; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - @ExtendWith(SpringExtension.class) @SpringBootTest(classes = FileRecordController.class) @ContextConfiguration(classes = { FileRecordController.class }) diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java index a036011796..d7c084e3ec 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java @@ -7,6 +7,7 @@ import java.util.Optional; import org.junit.jupiter.api.Test; import com.baeldung.webflux.model.Payment; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java index 8ed4cfb6c6..07c54fd531 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java @@ -25,19 +25,19 @@ public class UserControllerUnitTest { User user = new User(userId, "John Doe"); Mockito.when(userService.getUser(userId)) - .thenReturn(Mono.just(user)); + .thenReturn(Mono.just(user)); Mockito.when(emailService.sendEmail(userId)) - .thenReturn(Mono.just(true)); + .thenReturn(Mono.just(true)); Mockito.when(databaseService.saveUserData(user)) - .thenReturn(Mono.just(true)); + .thenReturn(Mono.just(true)); UserController userController = new UserController(userService, emailService, databaseService); Mono> responseMono = userController.combineAllDataFor(userId); StepVerifier.create(responseMono) - .expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody() - .equals("Response: " + user + ", Email Sent: true, Database Result: " + true)) - .verifyComplete(); + .expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody() + .equals("Response: " + user + ", Email Sent: true, Database Result: " + true)) + .verifyComplete(); } } From 7c93d400445165fe38d3ba14f46a484e3892428e Mon Sep 17 00:00:00 2001 From: reza ganji Date: Sat, 30 Mar 2024 13:10:46 +0330 Subject: [PATCH 09/57] Revert "Revert "Revert "BAEL-7540""" This reverts commit fa1c5598b0429200709856c932301ae682a42678. --- spring-5-webflux-2/README.md | 1 - spring-5-webflux-2/pom.xml | 6 +-- .../com/baeldung/webflux/caching/Item.java | 6 ++- .../baeldung/webflux/caching/ItemService.java | 10 ++-- .../controller/UserController.java | 35 -------------- .../ex/NotFoundException.java | 12 ----- .../exceptionhandeling/model/User.java | 29 ----------- .../repository/UserRepository.java | 24 ---------- .../webflux/filerecord/FileRecord.java | 4 +- .../filerecord/FileRecordApplication.java | 3 +- .../filerecord/FileRecordController.java | 7 ++- .../webflux/filerecord/FileRecordService.java | 1 - .../com/baeldung/webflux/model/Payment.java | 1 + .../webflux/zipwhen/service/EmailService.java | 10 ++-- .../webflux/zipwhen/web/UserController.java | 16 +++---- .../src/main/resources/logback.xml | 2 +- .../MonoFluxResultCachingLiveTest.java | 41 ++++++++-------- .../UserControllerUnitTest.java | 48 ------------------- .../FileRecordControllerIntegrationTest.java | 11 ++--- .../FirstElementOfFluxUnitTest.java | 1 - .../zipwhen/UserControllerUnitTest.java | 12 ++--- 21 files changed, 63 insertions(+), 217 deletions(-) delete mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java delete mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java delete mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java delete mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java delete mode 100644 spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java diff --git a/spring-5-webflux-2/README.md b/spring-5-webflux-2/README.md index 5579e1cec5..5232d86643 100644 --- a/spring-5-webflux-2/README.md +++ b/spring-5-webflux-2/README.md @@ -3,7 +3,6 @@ This module contains articles about Spring 5 WebFlux ## Relevant articles: - - [Spring Webflux and @Cacheable Annotation](https://www.baeldung.com/spring-webflux-cacheable) - [Comparison Between Mono’s doOnNext() and doOnSuccess()](https://www.baeldung.com/mono-doonnext-doonsuccess) - [How to Access the First Element of a Flux](https://www.baeldung.com/java-flux-first-element) diff --git a/spring-5-webflux-2/pom.xml b/spring-5-webflux-2/pom.xml index 85e451c075..38cbbc8bf0 100644 --- a/spring-5-webflux-2/pom.xml +++ b/spring-5-webflux-2/pom.xml @@ -1,7 +1,7 @@ - + 4.0.0 spring-5-webflux-2 1.0-SNAPSHOT diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java index 6ad03baafc..54b7d63f33 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/Item.java @@ -41,6 +41,10 @@ public class Item { @Override public String toString() { - return "Item{" + "id='" + _id + '\'' + ", name='" + name + '\'' + ", price=" + price + '}'; + return "Item{" + + "id='" + _id + '\'' + + ", name='" + name + '\'' + + ", price=" + price + + '}'; } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java index 9286cecef8..9bf934b504 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/caching/ItemService.java @@ -16,8 +16,7 @@ public class ItemService { public ItemService(ItemRepository repository) { this.repository = repository; - this.cache = Caffeine.newBuilder() - .build(this::getItem_withCaffeine); + this.cache = Caffeine.newBuilder().build(this::getItem_withCaffeine); } @Cacheable("items") @@ -31,14 +30,11 @@ public class ItemService { @Cacheable("items") public Mono getItem_withCache(String id) { - return repository.findById(id) - .cache(); + return repository.findById(id).cache(); } @Cacheable("items") public Mono getItem_withCaffeine(String id) { - return cache.asMap() - .computeIfAbsent(id, k -> repository.findById(id) - .cast(Item.class)); + return cache.asMap().computeIfAbsent(id, k -> repository.findById(id).cast(Item.class)); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java deleted file mode 100644 index 6490b997af..0000000000 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling.controller; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; - -import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; -import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; -import com.baeldung.webflux.zipwhen.model.User; - -import reactor.core.publisher.Mono; - -@RestController -public class UserController { - - private final UserRepository userRepository; - - @Autowired - public UserController(UserRepository userRepository) { - this.userRepository = userRepository; - } - - @GetMapping("/user/{id}") - public Mono getUserByIdThrowingException(@PathVariable String id) { - return userRepository.findById(id) - .switchIfEmpty(Mono.error(new NotFoundException("User not found"))); - } - - @GetMapping("/user/{id}") - public Mono getUserByIdUsingMonoError(@PathVariable String id) { - return userRepository.findById(id) - .switchIfEmpty(Mono.error(() -> new NotFoundException("User not found"))); - } -} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java deleted file mode 100644 index 5401a4d133..0000000000 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling.ex; - -public class NotFoundException extends RuntimeException { - - public NotFoundException(String message) { - super(message); - } - - public NotFoundException(String message, Throwable cause) { - super(message, cause); - } -} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java deleted file mode 100644 index 42e1293ee8..0000000000 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling.model; - -public class User { - private String id; - private String username; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public User(String userId, String userName) { - this.id=userId; - this.username=userName; - - } -} - diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java deleted file mode 100644 index 7d4ac0af86..0000000000 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling.repository; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.stereotype.Repository; - -import com.baeldung.webflux.zipwhen.model.User; - -import reactor.core.publisher.Mono; - -@Repository -public class UserRepository { - private final Map userDatabase = new ConcurrentHashMap<>(); - - public UserRepository() { - userDatabase.put("1", new User("1", "John Doe")); - userDatabase.put("2", new User("2", "Jane Smith")); - } - - public Mono findById(String id) { - return Mono.justOrEmpty(userDatabase.get(id)); - } -} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java index bd339bf849..5c0e265e13 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecord.java @@ -1,9 +1,9 @@ package com.baeldung.webflux.filerecord; -import java.util.List; - import org.springframework.data.annotation.Id; +import java.util.List; + public class FileRecord { @Id private int id; diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java index 0388bdb0b8..9c20e10040 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordApplication.java @@ -1,5 +1,6 @@ package com.baeldung.webflux.filerecord; +import io.r2dbc.spi.ConnectionFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @@ -7,8 +8,6 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.r2dbc.connection.init.ConnectionFactoryInitializer; import org.springframework.r2dbc.connection.init.ResourceDatabasePopulator; -import io.r2dbc.spi.ConnectionFactory; - @SpringBootApplication public class FileRecordApplication { diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java index b3cd0b89e4..943cec9a2d 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordController.java @@ -1,13 +1,12 @@ package com.baeldung.webflux.filerecord; -import java.nio.file.Paths; - import org.springframework.http.codec.multipart.FilePart; import org.springframework.web.bind.annotation.*; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.nio.file.Paths; + @RestController public class FileRecordController { @@ -29,7 +28,7 @@ public class FileRecordController { FileRecord fileRecord = new FileRecord(); return filePartFlux.flatMap(filePart -> filePart.transferTo(Paths.get(filePart.filename())) - .then(Mono.just(filePart.filename()))) + .then(Mono.just(filePart.filename()))) .collectList() .flatMap(filenames -> { fileRecord.setFilenames(filenames); diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java index bce8c82c39..6e74f3577b 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/filerecord/FileRecordService.java @@ -1,7 +1,6 @@ package com.baeldung.webflux.filerecord; import org.springframework.stereotype.Service; - import reactor.core.publisher.Mono; @Service diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java index 1fc090446a..f9be73ee44 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/model/Payment.java @@ -1,5 +1,6 @@ package com.baeldung.webflux.model; + public class Payment { private final int amount; diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java index c4c5520d24..9c0340b7ee 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java @@ -11,10 +11,10 @@ public class EmailService { public Mono sendEmail(String userId) { return userService.getUser(userId) - .flatMap(user -> { - System.out.println("Sending email to: " + user.getEmail()); - return Mono.just(true); - }) - .defaultIfEmpty(false); + .flatMap(user -> { + System.out.println("Sending email to: " + user.getEmail()); + return Mono.just(true); + }) + .defaultIfEmpty(false); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java index fa0d083beb..dbd89c45d3 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java @@ -28,16 +28,16 @@ public class UserController { public Mono> combineAllDataFor(@PathVariable String userId) { Mono userMono = userService.getUser(userId); Mono emailSentMono = emailService.sendEmail(userId) - .subscribeOn(Schedulers.parallel()); + .subscribeOn(Schedulers.parallel()); Mono databaseResultMono = userMono.flatMap(user -> databaseService.saveUserData(user) - .map(Object::toString)); + .map(Object::toString)); return userMono.zipWhen(user -> emailSentMono, Tuples::of) - .zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> { - User user = tuple.getT1(); - Boolean emailSent = tuple.getT2(); - return ResponseEntity.ok() - .body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult); - }); + .zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> { + User user = tuple.getT1(); + Boolean emailSent = tuple.getT2(); + return ResponseEntity.ok() + .body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult); + }); } } diff --git a/spring-5-webflux-2/src/main/resources/logback.xml b/spring-5-webflux-2/src/main/resources/logback.xml index 122a79945b..48b68c6bf1 100644 --- a/spring-5-webflux-2/src/main/resources/logback.xml +++ b/spring-5-webflux-2/src/main/resources/logback.xml @@ -1,7 +1,7 @@ + class="ch.qos.logback.core.ConsoleAppender"> %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java index 2ff2c15662..2075c1e77e 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/caching/MonoFluxResultCachingLiveTest.java @@ -1,6 +1,5 @@ package com.baeldung.webflux.caching; -import static org.assertj.core.api.Assertions.assertThat; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -13,10 +12,13 @@ import org.testcontainers.utility.DockerImageName; import reactor.core.publisher.Mono; +import static org.assertj.core.api.Assertions.assertThat; + @SpringBootTest @ActiveProfiles("cache") public class MonoFluxResultCachingLiveTest { + @Autowired ItemService itemService; @@ -28,34 +30,32 @@ public class MonoFluxResultCachingLiveTest { registry.add("spring.data.mongodb.uri", mongoDBContainer::getReplicaSetUrl); } - @Test - public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { - Mono glass = itemService.save(new Item("glass", 1.00)); +@Test +public void givenItem_whenGetItemIsCalled_thenMonoIsCached() { + Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block() - .get_id(); + String id = glass.block().get_id(); - Mono mono = itemService.getItem(id); - Item item = mono.block(); + Mono mono = itemService.getItem(id); + Item item = mono.block(); - assertThat(item).isNotNull(); - assertThat(item.getName()).isEqualTo("glass"); - assertThat(item.getPrice()).isEqualTo(1.00); + assertThat(item).isNotNull(); + assertThat(item.getName()).isEqualTo("glass"); + assertThat(item.getPrice()).isEqualTo(1.00); - Mono mono2 = itemService.getItem(id); - Item item2 = mono2.block(); + Mono mono2 = itemService.getItem(id); + Item item2 = mono2.block(); - assertThat(item2).isNotNull(); - assertThat(item2.getName()).isEqualTo("glass"); - assertThat(item2.getPrice()).isEqualTo(1.00); - } + assertThat(item2).isNotNull(); + assertThat(item2.getName()).isEqualTo("glass"); + assertThat(item2.getPrice()).isEqualTo(1.00); +} @Test public void givenItem_whenGetItemWithCacheIsCalled_thenMonoResultIsCached() { Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block() - .get_id(); + String id = glass.block().get_id(); Mono mono = itemService.getItem_withCache(id); Item item = mono.block(); @@ -76,8 +76,7 @@ public class MonoFluxResultCachingLiveTest { public void givenItem_whenGetItemWithCaffeineIsCalled_thenMonoResultIsCached() { Mono glass = itemService.save(new Item("glass", 1.00)); - String id = glass.block() - .get_id(); + String id = glass.block().get_id(); Mono mono = itemService.getItem_withCaffeine(id); Item item = mono.block(); diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java deleted file mode 100644 index d59ec52f3c..0000000000 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.baeldung.webflux.exceptionhandeling; - -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import static org.junit.jupiter.api.Assertions.assertThrows; - -import static org.mockito.Mockito.when; - -import com.baeldung.webflux.exceptionhandeling.controller.UserController; -import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; -import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; - -public class UserControllerUnitTest { - @Mock - private UserRepository userRepository; - - @InjectMocks - private UserController userController; - - public UserControllerUnitTest() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testGetUserByIdUsingMonoError_UserNotFound() { - String userId = "3"; - when(userRepository.findById(userId)).thenReturn(Mono.empty()); - StepVerifier.create(userController.getUserByIdUsingMonoError(userId)) - .expectError(NotFoundException.class) - .verify(); - } - - @Test - public void testGetUserByIdThrowingException_UserNotFound() { - String userId = "3"; - when(userRepository.findById(userId)).thenReturn(Mono.empty()); - assertThrows(NotFoundException.class, () -> userController.getUserByIdThrowingException(userId) - .block()); - } - -} - diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java index f8585852c1..c47d53632b 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/filerecord/FileRecordControllerIntegrationTest.java @@ -1,10 +1,5 @@ package com.baeldung.webflux.filerecord; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -import java.util.List; - import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -18,9 +13,13 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.LinkedMultiValueMap; - import reactor.core.publisher.Mono; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + @ExtendWith(SpringExtension.class) @SpringBootTest(classes = FileRecordController.class) @ContextConfiguration(classes = { FileRecordController.class }) diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java index d7c084e3ec..a036011796 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/firstelementofflux/FirstElementOfFluxUnitTest.java @@ -7,7 +7,6 @@ import java.util.Optional; import org.junit.jupiter.api.Test; import com.baeldung.webflux.model.Payment; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java index 07c54fd531..8ed4cfb6c6 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java @@ -25,19 +25,19 @@ public class UserControllerUnitTest { User user = new User(userId, "John Doe"); Mockito.when(userService.getUser(userId)) - .thenReturn(Mono.just(user)); + .thenReturn(Mono.just(user)); Mockito.when(emailService.sendEmail(userId)) - .thenReturn(Mono.just(true)); + .thenReturn(Mono.just(true)); Mockito.when(databaseService.saveUserData(user)) - .thenReturn(Mono.just(true)); + .thenReturn(Mono.just(true)); UserController userController = new UserController(userService, emailService, databaseService); Mono> responseMono = userController.combineAllDataFor(userId); StepVerifier.create(responseMono) - .expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody() - .equals("Response: " + user + ", Email Sent: true, Database Result: " + true)) - .verifyComplete(); + .expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody() + .equals("Response: " + user + ", Email Sent: true, Database Result: " + true)) + .verifyComplete(); } } From 0b1672898e3a5ffcd86871f3ffc658dde6a7752b Mon Sep 17 00:00:00 2001 From: reza ganji Date: Sat, 30 Mar 2024 13:13:45 +0330 Subject: [PATCH 10/57] BAEL-7540 --- .../controller/UserController.java | 35 +++++++++++++++++++ .../ex/NotFoundException.java | 12 +++++++ .../exceptionhandeling/model/User.java | 29 +++++++++++++++ .../repository/UserRepository.java | 24 +++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java new file mode 100644 index 0000000000..6490b997af --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java @@ -0,0 +1,35 @@ +package com.baeldung.webflux.exceptionhandeling.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; +import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; +import com.baeldung.webflux.zipwhen.model.User; + +import reactor.core.publisher.Mono; + +@RestController +public class UserController { + + private final UserRepository userRepository; + + @Autowired + public UserController(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @GetMapping("/user/{id}") + public Mono getUserByIdThrowingException(@PathVariable String id) { + return userRepository.findById(id) + .switchIfEmpty(Mono.error(new NotFoundException("User not found"))); + } + + @GetMapping("/user/{id}") + public Mono getUserByIdUsingMonoError(@PathVariable String id) { + return userRepository.findById(id) + .switchIfEmpty(Mono.error(() -> new NotFoundException("User not found"))); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java new file mode 100644 index 0000000000..5401a4d133 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/ex/NotFoundException.java @@ -0,0 +1,12 @@ +package com.baeldung.webflux.exceptionhandeling.ex; + +public class NotFoundException extends RuntimeException { + + public NotFoundException(String message) { + super(message); + } + + public NotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java new file mode 100644 index 0000000000..42e1293ee8 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java @@ -0,0 +1,29 @@ +package com.baeldung.webflux.exceptionhandeling.model; + +public class User { + private String id; + private String username; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public User(String userId, String userName) { + this.id=userId; + this.username=userName; + + } +} + diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java new file mode 100644 index 0000000000..7d4ac0af86 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java @@ -0,0 +1,24 @@ +package com.baeldung.webflux.exceptionhandeling.repository; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.stereotype.Repository; + +import com.baeldung.webflux.zipwhen.model.User; + +import reactor.core.publisher.Mono; + +@Repository +public class UserRepository { + private final Map userDatabase = new ConcurrentHashMap<>(); + + public UserRepository() { + userDatabase.put("1", new User("1", "John Doe")); + userDatabase.put("2", new User("2", "Jane Smith")); + } + + public Mono findById(String id) { + return Mono.justOrEmpty(userDatabase.get(id)); + } +} From 878751f8efb94ee6ea42cd7829d201c1fa2d86e8 Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Sun, 31 Mar 2024 12:12:48 +0000 Subject: [PATCH 11/57] https://jira.baeldung.com/browse/BAEL-7723 --- .../baeldung/barcodes/BarcodesController.java | 10 ++-- .../ZxingBarcodeGeneratorWithText.java | 58 +++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java index 171d703621..5bef25b94d 100644 --- a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java +++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java @@ -1,9 +1,6 @@ package com.baeldung.barcodes; -import com.baeldung.barcodes.generators.BarbecueBarcodeGenerator; -import com.baeldung.barcodes.generators.Barcode4jBarcodeGenerator; -import com.baeldung.barcodes.generators.QRGenBarcodeGenerator; -import com.baeldung.barcodes.generators.ZxingBarcodeGenerator; +import com.baeldung.barcodes.generators.*; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -76,6 +73,11 @@ public class BarcodesController { return okResponse(ZxingBarcodeGenerator.generateCode128BarcodeImage(barcode)); } + @GetMapping(value = "/zxing/qrcode/text", produces = MediaType.IMAGE_PNG_VALUE) + public ResponseEntity zxingCodeQRcodeText(@RequestParam("barcode") String barcode, @RequestParam("name") String name, @RequestParam("info") String info) throws Exception { + return okResponse(ZxingBarcodeGeneratorWithText.createQRwithText(barcode, name, info)); + } + @PostMapping(value = "/zxing/pdf417", produces = MediaType.IMAGE_PNG_VALUE) public ResponseEntity zxingPDF417Barcode(@RequestBody String barcode) throws Exception { return okResponse(ZxingBarcodeGenerator.generatePDF417BarcodeImage(barcode)); diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java new file mode 100644 index 0000000000..605954704c --- /dev/null +++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java @@ -0,0 +1,58 @@ +package com.baeldung.barcodes.generators; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.IOException; + + +public class ZxingBarcodeGeneratorWithText { + + public static BufferedImage createQRwithText(String data, String name, String info) throws WriterException, IOException { + QRCodeWriter barcodeWriter = new QRCodeWriter(); + BitMatrix matrix = barcodeWriter.encode(data, BarcodeFormat.QR_CODE, 200, 200); + return modifiedQRCode(matrix, name, info); + } + + public static BufferedImage modifiedQRCode(BitMatrix matrix, String topText, String bottomText) throws IOException { + int matrixWidth = matrix.getWidth(); + int matrixHeight = matrix.getHeight(); + + BufferedImage image = new BufferedImage(matrixWidth, matrixHeight, BufferedImage.TYPE_INT_RGB); + Graphics2D graphics = image.createGraphics(); + graphics.setColor(Color.WHITE); + graphics.fillRect(0, 0, matrixWidth, matrixHeight); + graphics.setColor(Color.BLACK); + + for (int i = 0; i < matrixWidth; i++) { + for (int j = 0; j < matrixHeight; j++) { + if (matrix.get(i, j)) { + graphics.fillRect(i, j, 1, 1); + } + } + } + + FontMetrics fontMetrics = graphics.getFontMetrics(); + int topTextWidth = fontMetrics.stringWidth(topText); + int bottomTextWidth = fontMetrics.stringWidth(bottomText); + int finalWidth = Math.max(matrixWidth, Math.max(topTextWidth, bottomTextWidth)) + 10; + int finalHeight = matrixHeight + fontMetrics.getHeight() + fontMetrics.getAscent() + 1; + + BufferedImage finalImage = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_RGB); + Graphics2D finalGraphics = finalImage.createGraphics(); + finalGraphics.setColor(Color.WHITE); + finalGraphics.fillRect(0, 0, finalWidth, finalHeight); + finalGraphics.setColor(Color.BLACK); + + finalGraphics.drawImage(image, (finalWidth - matrixWidth) / 2, fontMetrics.getAscent() + 5, null); + finalGraphics.drawString(topText, (finalWidth - topTextWidth) / 2, fontMetrics.getAscent() + 5); + finalGraphics.drawString(bottomText, (finalWidth - bottomTextWidth) / 2, finalHeight - fontMetrics.getDescent() - 5); + + return finalImage; + } + +} From 8ab93e1573bd80c34200208fd7a0deb4a4771476 Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Sun, 31 Mar 2024 12:28:59 +0000 Subject: [PATCH 12/57] https://jira.baeldung.com/browse/BAEL-7723 --- .../com/baeldung/barcodes/BarcodesController.java | 14 ++++++++++++-- .../generators/ZxingBarcodeGeneratorWithText.java | 5 +++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java index 5bef25b94d..e734b666db 100644 --- a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java +++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java @@ -1,10 +1,20 @@ package com.baeldung.barcodes; -import com.baeldung.barcodes.generators.*; +import com.baeldung.barcodes.generators.BarbecueBarcodeGenerator; +import com.baeldung.barcodes.generators.Barcode4jBarcodeGenerator; +import com.baeldung.barcodes.generators.QRGenBarcodeGenerator; +import com.baeldung.barcodes.generators.ZxingBarcodeGenerator; +import com.baeldung.barcodes.generators.ZxingBarcodeGeneratorWithText; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +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; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import java.awt.image.BufferedImage; diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java index 605954704c..60ae1b427d 100644 --- a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java +++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java @@ -5,11 +5,12 @@ import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.QRCodeWriter; -import java.awt.*; +import java.awt.Graphics2D; +import java.awt.Color; +import java.awt.FontMetrics; import java.awt.image.BufferedImage; import java.io.IOException; - public class ZxingBarcodeGeneratorWithText { public static BufferedImage createQRwithText(String data, String name, String info) throws WriterException, IOException { From 35bdac1c59739c4d59f16e822add3a8482d38344 Mon Sep 17 00:00:00 2001 From: Zeeshan Arif Date: Sun, 31 Mar 2024 17:49:06 +0500 Subject: [PATCH 13/57] BAEL-7692 --- .../spring/data/jpa/joinquery/AppConfig.java | 52 ++++++++ .../data/jpa/joinquery/DTO/ResultDTO.java | 119 ++++++++++++++++++ .../data/jpa/joinquery/entities/Customer.java | 104 +++++++++++++++ .../jpa/joinquery/entities/CustomerOrder.java | 88 +++++++++++++ .../data/jpa/joinquery/entities/Product.java | 84 +++++++++++++ .../repositories/CustomerRepository.java | 9 ++ .../repositories/JoinRepository.java | 26 ++++ .../jpa/joinquery/JoinRepositoryTest.java | 98 +++++++++++++++ 8 files changed, 580 insertions(+) create mode 100644 persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java create mode 100644 persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java create mode 100644 persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java create mode 100644 persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java create mode 100644 persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java create mode 100644 persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java create mode 100644 persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java create mode 100644 persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java new file mode 100644 index 0000000000..840d26edf7 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/AppConfig.java @@ -0,0 +1,52 @@ +package com.baeldung.spring.data.jpa.joinquery; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; +import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; + +import javax.sql.DataSource; +import java.util.Properties; + +@Configuration +@EnableAutoConfiguration +public class AppConfig { + + @Bean + public DataSource dataSource() { + return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2) + .build(); + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { + LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); + emf.setDataSource(dataSource); + emf.setPackagesToScan("com.baeldung.spring.data.jpa.joinquery.entities" + , "com.baeldung.spring.data.jpa.joinquery.DTO" + , "com.baeldung.spring.data.jpa.joinquery.repositories"); + emf.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + emf.setJpaProperties(getHibernateProperties()); + return emf; + } + + @Bean + public JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) { + return new JpaTransactionManager(entityManagerFactory.getObject()); + } + + private Properties getHibernateProperties() { + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", "create"); + properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); + return properties; + } +} + + + + diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java new file mode 100644 index 0000000000..9464c25ce8 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO.java @@ -0,0 +1,119 @@ +package com.baeldung.spring.data.jpa.joinquery.DTO; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; +import org.springframework.context.annotation.Bean; + +import java.time.LocalDate; + +class DTO { + private Long customer_id; + private Long order_id; + private Long product_id; + + public DTO(Long customer_id, Long order_id, Long product_id) { + this.customer_id = customer_id; + this.order_id = order_id; + this.product_id = product_id; + } +} + +@Entity +@IdClass(DTO.class) +public class ResultDTO { + @Id + private Long customer_id; + + @Id + private Long order_id; + + @Id + private Long product_id; + + public void setCustomer_id(Long customer_id) { + this.customer_id = customer_id; + } + + public Long getProduct_id() { + return product_id; + } + + public void setProduct_id(Long product_id) { + this.product_id = product_id; + } + + public ResultDTO(Long customer_id, Long order_id, Long product_id, String customerName, String customerEmail, LocalDate orderDate, String productName, Double productPrice) { + this.customer_id = customer_id; + this.order_id = order_id; + this.product_id = product_id; + this.customerName = customerName; + this.customerEmail = customerEmail; + this.orderDate = orderDate; + this.productName = productName; + this.productPrice = productPrice; + } + + private String customerName; + private String customerEmail; + private LocalDate orderDate; + private String productName; + private Double productPrice; + + public Long getCustomer_id() { + return customer_id; + } + + public void setCustoemr_id(Long custoemr_id) { + this.customer_id = custoemr_id; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerEmail() { + return customerEmail; + } + + public void setCustomerEmail(String customerEmail) { + this.customerEmail = customerEmail; + } + + public Long getOrder_id() { + return order_id; + } + + public void setOrder_id(Long order_id) { + this.order_id = order_id; + } + + public LocalDate getOrderDate() { + return orderDate; + } + + public void setOrderDate(LocalDate orderDate) { + this.orderDate = orderDate; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public Double getProductPrice() { + return productPrice; + } + + public void setProductPrice(Double productPrice) { + this.productPrice = productPrice; + } + +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java new file mode 100644 index 0000000000..8da7aa21a2 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Customer.java @@ -0,0 +1,104 @@ +package com.baeldung.spring.data.jpa.joinquery.entities; + +import jakarta.persistence.*; + +import java.time.LocalDate; +import java.util.Objects; +import java.util.Set; + +@Entity +public class Customer { + public Customer(){} + @Id + //@GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToMany(mappedBy = "customer" + , cascade = CascadeType.ALL) + private Set customerOrders; + + public Customer(Long id, Set customerOrders, String email, LocalDate dob, String name) { + this.id = id; + this.customerOrders = customerOrders; + this.email = email; + this.dob = dob; + this.name = name; + } + + public void setId(Long id) { + this.id = id; + } + + public void setCustomerOrders(Set customerOrders) { + this.customerOrders = customerOrders; + } + + @Override + public String toString() { + return "Patient{" + + "id=" + id + + ", orders=" + customerOrders + + ", email='" + email + '\'' + + ", dob=" + dob + + ", name='" + name + '\'' + + '}'; + } + + public Set getOrders() { + return customerOrders; + } + + public void setOrders(Set orders) { + this.customerOrders = orders; + } + + @Column + private String email; + + @Column(name = "dob", columnDefinition = "DATE") + private LocalDate dob; + + @Column + private String name; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Customer patient = (Customer) o; + return Objects.equals(id, patient.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + public Long getId() { + return id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public LocalDate getDob() { + return dob; + } + + public void setDob(LocalDate dob) { + this.dob = dob; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java new file mode 100644 index 0000000000..d147543e2f --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/CustomerOrder.java @@ -0,0 +1,88 @@ +package com.baeldung.spring.data.jpa.joinquery.entities; + +import jakarta.persistence.*; + +import java.time.LocalDate; +import java.util.Objects; +import java.util.Set; + +@Entity +public class CustomerOrder { + public CustomerOrder(){} + @Id + //@GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + public void setId(Long id) { + this.id = id; + } + + public Set getProducts() { + return products; + } + + public void setProducts(Set products) { + this.products = products; + } + + @OneToMany(mappedBy = "customerOrder" + , cascade = CascadeType.ALL) + private Set products; + + @Column + private LocalDate orderDate; + + public CustomerOrder(Long id, Set products, LocalDate orderDate, Customer customer) { + this.id = id; + this.products = products; + this.orderDate = orderDate; + this.customer = customer; + } + + @Override + public String toString() { + return "Consult{" + + "id=" + id + + ", products=" + products + + ", orderDate=" + orderDate + + ", customer=" + customer + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CustomerOrder co = (CustomerOrder) o; + return Objects.equals(id, co.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="customer_id", nullable = false) + private Customer customer; + + public Long getId() { + return id; + } + + public LocalDate getOrderDate() { + return orderDate; + } + + public void setOrderDate(LocalDate orderDate) { + this.orderDate = orderDate; + } + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java new file mode 100644 index 0000000000..ea18e6225e --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/entities/Product.java @@ -0,0 +1,84 @@ +package com.baeldung.spring.data.jpa.joinquery.entities; + +import jakarta.persistence.*; + +import java.util.Objects; + +@Entity +public class Product { + public Product(){} + @Id + //@GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + public Product(Long id, String productName, Double price, CustomerOrder customerOrder) { + this.id = id; + this.productName = productName; + this.price = price; + this.customerOrder = customerOrder; + } + + @Column + private String productName; + + @Column + private Double price; + + @Override + public String toString() { + return "Dispense{" + + "id=" + id + + ", productName='" + productName + '\'' + + ", price=" + price + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Product dispense = (Product) o; + return Objects.equals(id, dispense.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public CustomerOrder getCustomerOrder() { + return customerOrder; + } + + public void setCustomerOrder(CustomerOrder co) { + this.customerOrder = co; + } + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="customerorder_id", nullable = false) + private CustomerOrder customerOrder; +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java new file mode 100644 index 0000000000..ba7ece74b8 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/CustomerRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.spring.data.jpa.joinquery.repositories; + +import com.baeldung.spring.data.jpa.joinquery.entities.Customer; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface CustomerRepository extends CrudRepository { +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java new file mode 100644 index 0000000000..8630d44f86 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java @@ -0,0 +1,26 @@ +package com.baeldung.spring.data.jpa.joinquery.repositories; + +import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Map; + +@Repository +public interface JoinRepository extends CrudRepository { + @Query(value = "SELECT new com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO(c.id, o.id, p.id, c.name, c.email, o.orderDate, p.productName, p.price) " + + " from Customer c, CustomerOrder o ,Product p " + + " where c.id=o.customer.id " + + " and o.id=p.customerOrder.id " + + " and c.id=?1 ") + List findResultDTOByCustomer(Long id); + + @Query(value = "SELECT c.*, o.*, p.* " + + " from Customer c, CustomerOrder o ,Product p " + + " where c.id=o.customer_id " + + " and o.id=p.customerOrder_id " + + " and c.id=?1 " + , nativeQuery = true) + List> findByCustomer(Long id); +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java new file mode 100644 index 0000000000..b5cf78d5e1 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java @@ -0,0 +1,98 @@ +package com.baeldung.spring.data.jpa.joinquery; + +import com.baeldung.spring.data.jpa.joinquery.entities.Customer; +import com.baeldung.spring.data.jpa.joinquery.entities.CustomerOrder; +import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO; +import com.baeldung.spring.data.jpa.joinquery.entities.Product; +import com.baeldung.spring.data.jpa.joinquery.repositories.CustomerRepository; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.EntityTransaction; +import jakarta.persistence.PersistenceUnit; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import com.baeldung.spring.data.jpa.joinquery.repositories.JoinRepository; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = { AppConfig.class }) +class JoinRepositoryTest { + + @Autowired + JoinRepository joinRepository; + + @Autowired + CustomerRepository customerRepository; + + @PersistenceUnit + EntityManagerFactory entityManagerFactory; + + EntityManager entityManager; + + @BeforeEach + void setUp() { + customerRepository.deleteAll(); + entityManager = entityManagerFactory.createEntityManager(); + Customer c = new Customer(1L, null, "email1@email.com", LocalDate.now(), "Customer"); + CustomerOrder o1 = new CustomerOrder(1L, null, LocalDate.now(), c); + CustomerOrder o2 = new CustomerOrder(2L, null, LocalDate.of(2024,1,1), c); + + Product p1 = new Product(1L,"Product1", 25.20, o1); + Product p2 = new Product(2L, "Product2", 26.20, o1); + Product p3 = new Product(3L, "Product3", 27.20, o2); + + Set cos01 = new HashSet<>(); + cos01.add(o1); + cos01.add(o2); + Set productsO1 = new HashSet<>(); + productsO1.add(p1); + productsO1.add(p2); + Set productsO2 = new HashSet<>(); + productsO1.add(p3); + + c.setCustomerOrders(cos01); + o1.setProducts(productsO1); + o2.setProducts(productsO2); + + EntityTransaction et = getTransaction(); + entityManager.persist(c); + entityManager.flush(); + et.commit(); + } + + @AfterEach + void tearDown() { + } + + @Test + void whenFindResultDTOByCustomer_thenReturnResultDTO() { + List resultDTO = joinRepository.findResultDTOByCustomer(1L); + assertInstanceOf(ResultDTO.class, resultDTO.get(0)); + } + + @Test + void whenFindByCustomerNativeQuery_thenReturnMapsForObjects() { + List> res = joinRepository.findByCustomer(1L); + //the map objects in the res List has 9 String keys aka 9 columns corresponding to the columns of customer, customerOrder, product + res.forEach(map -> { + assertEquals(9, map.keySet().size()); + }); + } + private EntityTransaction getTransaction() { + EntityTransaction transaction = entityManager.getTransaction(); + transaction.begin(); + return transaction; + } +} \ No newline at end of file From fbef22d79dd0d4f742e73db711accb21dab92346 Mon Sep 17 00:00:00 2001 From: Zeeshan Arif Date: Sun, 31 Mar 2024 18:04:22 +0500 Subject: [PATCH 14/57] BAEL-7692 added case for ResultDTO_wo_Ids.java --- .../jpa/joinquery/DTO/ResultDTO_wo_Ids.java | 66 +++++++++++++++++++ .../repositories/JoinRepository.java | 8 +++ .../jpa/joinquery/JoinRepositoryTest.java | 8 +++ 3 files changed, 82 insertions(+) create mode 100644 persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java new file mode 100644 index 0000000000..540ad9fc91 --- /dev/null +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/DTO/ResultDTO_wo_Ids.java @@ -0,0 +1,66 @@ +package com.baeldung.spring.data.jpa.joinquery.DTO; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.IdClass; + +import java.time.LocalDate; + +//@Entity +//@IdClass(DTO.class) +public class ResultDTO_wo_Ids { + public ResultDTO_wo_Ids(String customerName, String customerEmail, LocalDate orderDate, String productName, Double productPrice) { + this.customerName = customerName; + this.customerEmail = customerEmail; + this.orderDate = orderDate; + this.productName = productName; + this.productPrice = productPrice; + } + + private String customerName; + private String customerEmail; + private LocalDate orderDate; + private String productName; + private Double productPrice; + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getCustomerEmail() { + return customerEmail; + } + + public void setCustomerEmail(String customerEmail) { + this.customerEmail = customerEmail; + } + + public LocalDate getOrderDate() { + return orderDate; + } + + public void setOrderDate(LocalDate orderDate) { + this.orderDate = orderDate; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public Double getProductPrice() { + return productPrice; + } + + public void setProductPrice(Double productPrice) { + this.productPrice = productPrice; + } + +} diff --git a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java index 8630d44f86..056c91f973 100644 --- a/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java +++ b/persistence-modules/spring-data-jpa-repo-3/src/main/java/com/baeldung/spring/data/jpa/joinquery/repositories/JoinRepository.java @@ -1,6 +1,7 @@ package com.baeldung.spring.data.jpa.joinquery.repositories; import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO; +import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; @@ -16,6 +17,13 @@ public interface JoinRepository extends CrudRepository { + " and c.id=?1 ") List findResultDTOByCustomer(Long id); + @Query(value = "SELECT new com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids(c.name, c.email, o.orderDate, p.productName, p.price) " + + " from Customer c, CustomerOrder o ,Product p " + + " where c.id=o.customer.id " + + " and o.id=p.customerOrder.id " + + " and c.id=?1 ") + List findResultDTOByCustomerWithoutIds(Long id); + @Query(value = "SELECT c.*, o.*, p.* " + " from Customer c, CustomerOrder o ,Product p " + " where c.id=o.customer_id " diff --git a/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java index b5cf78d5e1..ffc3417adb 100644 --- a/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java +++ b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java @@ -1,5 +1,6 @@ package com.baeldung.spring.data.jpa.joinquery; +import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO_wo_Ids; import com.baeldung.spring.data.jpa.joinquery.entities.Customer; import com.baeldung.spring.data.jpa.joinquery.entities.CustomerOrder; import com.baeldung.spring.data.jpa.joinquery.DTO.ResultDTO; @@ -90,6 +91,13 @@ class JoinRepositoryTest { assertEquals(9, map.keySet().size()); }); } + + @Test + void whenFindResultDTOByCustomerWithoutIds_thenReturnResultDTO() { + List resultDTO = joinRepository.findResultDTOByCustomerWithoutIds(1L); + assertInstanceOf(ResultDTO_wo_Ids.class, resultDTO.get(0)); + } + private EntityTransaction getTransaction() { EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); From 87fcf38d4952549e8dd586d76445b233cc7487e7 Mon Sep 17 00:00:00 2001 From: Zeeshan Arif Date: Sun, 31 Mar 2024 18:35:17 +0500 Subject: [PATCH 15/57] BAEL-7692 added case for ResultDTO_wo_Ids.java --- .../{JoinRepositoryTest.java => JoinRepositoryUnitTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/{JoinRepositoryTest.java => JoinRepositoryUnitTest.java} (99%) diff --git a/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryUnitTest.java similarity index 99% rename from persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java rename to persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryUnitTest.java index ffc3417adb..dd91399128 100644 --- a/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryTest.java +++ b/persistence-modules/spring-data-jpa-repo-3/src/test/java/com/baeldung/spring/data/jpa/joinquery/JoinRepositoryUnitTest.java @@ -29,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.assertInstanceOf; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { AppConfig.class }) -class JoinRepositoryTest { +class JoinRepositoryUnitTest { @Autowired JoinRepository joinRepository; From 4a35b225e76befce142ea0433c316e3f2f7b67de Mon Sep 17 00:00:00 2001 From: michaelin007 Date: Mon, 1 Apr 2024 09:56:31 +0000 Subject: [PATCH 16/57] https://jira.baeldung.com/browse/BAEL-7723 --- .../com/baeldung/barcodes/BarcodesController.java | 4 ++-- .../generators/ZxingBarcodeGeneratorWithText.java | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java index e734b666db..a1318c0519 100644 --- a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java +++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/BarcodesController.java @@ -84,8 +84,8 @@ public class BarcodesController { } @GetMapping(value = "/zxing/qrcode/text", produces = MediaType.IMAGE_PNG_VALUE) - public ResponseEntity zxingCodeQRcodeText(@RequestParam("barcode") String barcode, @RequestParam("name") String name, @RequestParam("info") String info) throws Exception { - return okResponse(ZxingBarcodeGeneratorWithText.createQRwithText(barcode, name, info)); + public ResponseEntity zxingCodeQRcodeText(@RequestParam("barcode") String barcode, @RequestParam("toptext") String toptext, @RequestParam("bottomtext") String bottomtext) throws Exception { + return okResponse(ZxingBarcodeGeneratorWithText.createQRwithText(barcode, toptext, bottomtext)); } @PostMapping(value = "/zxing/pdf417", produces = MediaType.IMAGE_PNG_VALUE) diff --git a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java index 60ae1b427d..e6ebcf9bae 100644 --- a/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java +++ b/spring-boot-modules/spring-boot-libraries/src/main/java/com/baeldung/barcodes/generators/ZxingBarcodeGeneratorWithText.java @@ -13,10 +13,10 @@ import java.io.IOException; public class ZxingBarcodeGeneratorWithText { - public static BufferedImage createQRwithText(String data, String name, String info) throws WriterException, IOException { + public static BufferedImage createQRwithText(String data, String topText, String bottomText) throws WriterException, IOException { QRCodeWriter barcodeWriter = new QRCodeWriter(); BitMatrix matrix = barcodeWriter.encode(data, BarcodeFormat.QR_CODE, 200, 200); - return modifiedQRCode(matrix, name, info); + return modifiedQRCode(matrix, topText, bottomText); } public static BufferedImage modifiedQRCode(BitMatrix matrix, String topText, String bottomText) throws IOException { @@ -40,7 +40,7 @@ public class ZxingBarcodeGeneratorWithText { FontMetrics fontMetrics = graphics.getFontMetrics(); int topTextWidth = fontMetrics.stringWidth(topText); int bottomTextWidth = fontMetrics.stringWidth(bottomText); - int finalWidth = Math.max(matrixWidth, Math.max(topTextWidth, bottomTextWidth)) + 10; + int finalWidth = Math.max(matrixWidth, Math.max(topTextWidth, bottomTextWidth)) + 1; int finalHeight = matrixHeight + fontMetrics.getHeight() + fontMetrics.getAscent() + 1; BufferedImage finalImage = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_RGB); @@ -49,9 +49,9 @@ public class ZxingBarcodeGeneratorWithText { finalGraphics.fillRect(0, 0, finalWidth, finalHeight); finalGraphics.setColor(Color.BLACK); - finalGraphics.drawImage(image, (finalWidth - matrixWidth) / 2, fontMetrics.getAscent() + 5, null); - finalGraphics.drawString(topText, (finalWidth - topTextWidth) / 2, fontMetrics.getAscent() + 5); - finalGraphics.drawString(bottomText, (finalWidth - bottomTextWidth) / 2, finalHeight - fontMetrics.getDescent() - 5); + finalGraphics.drawImage(image, (finalWidth - matrixWidth) / 2, fontMetrics.getAscent() + 2, null); + finalGraphics.drawString(topText, (finalWidth - topTextWidth) / 2, fontMetrics.getAscent() + 2); + finalGraphics.drawString(bottomText, (finalWidth - bottomTextWidth) / 2, finalHeight - fontMetrics.getDescent() - 2); return finalImage; } From 9d258aa50581584c515ce9253dabfc1f409d28c3 Mon Sep 17 00:00:00 2001 From: Marcus Hellberg Date: Mon, 1 Apr 2024 15:36:34 -0700 Subject: [PATCH 17/57] Update the crud example --- .../src/main/java/com/baeldung/IndexView.java | 4 +- .../main/java/com/baeldung/data/Employee.java | 9 +- .../java/com/baeldung/spring/CrudView.java | 69 ----------- .../com/baeldung/spring/EmployeeEditor.java | 117 ++++++++---------- .../com/baeldung/spring/EmployeesView.java | 95 ++++++++++++++ 5 files changed, 160 insertions(+), 134 deletions(-) delete mode 100644 vaadin/src/main/java/com/baeldung/spring/CrudView.java create mode 100644 vaadin/src/main/java/com/baeldung/spring/EmployeesView.java diff --git a/vaadin/src/main/java/com/baeldung/IndexView.java b/vaadin/src/main/java/com/baeldung/IndexView.java index c69b160895..45ab534ef6 100644 --- a/vaadin/src/main/java/com/baeldung/IndexView.java +++ b/vaadin/src/main/java/com/baeldung/IndexView.java @@ -4,7 +4,7 @@ import com.baeldung.introduction.PushView; import com.baeldung.introduction.basics.VaadinFlowBasics; import com.baeldung.introduction.FormView; import com.baeldung.introduction.GridView; -import com.baeldung.spring.CrudView; +import com.baeldung.spring.EmployeesView; import com.vaadin.flow.component.html.H1; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.router.Route; @@ -20,6 +20,6 @@ public class IndexView extends VerticalLayout { add(new RouterLink("Grid", GridView.class)); add(new RouterLink("Form", FormView.class)); add(new RouterLink("Push", PushView.class)); - add(new RouterLink("CRUD", CrudView.class)); + add(new RouterLink("CRUD", EmployeesView.class)); } } diff --git a/vaadin/src/main/java/com/baeldung/data/Employee.java b/vaadin/src/main/java/com/baeldung/data/Employee.java index 2685e38286..cdaa426eeb 100644 --- a/vaadin/src/main/java/com/baeldung/data/Employee.java +++ b/vaadin/src/main/java/com/baeldung/data/Employee.java @@ -4,6 +4,7 @@ package com.baeldung.data; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import jakarta.validation.constraints.Size; @Entity public class Employee { @@ -12,11 +13,13 @@ public class Employee { @GeneratedValue private Long id; + @Size(min = 2, message = "First name must have at least 2 characters") private String firstName; + @Size(min = 2, message = "Last name must have at least 2 characters") private String lastName; - protected Employee() { + public Employee() { } public Employee(String firstName, String lastName) { @@ -28,6 +31,10 @@ public class Employee { return id; } + public void setId(Long id) { + this.id = id; + } + public String getFirstName() { return firstName; } diff --git a/vaadin/src/main/java/com/baeldung/spring/CrudView.java b/vaadin/src/main/java/com/baeldung/spring/CrudView.java deleted file mode 100644 index a77e32e965..0000000000 --- a/vaadin/src/main/java/com/baeldung/spring/CrudView.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.baeldung.spring; - -import com.baeldung.data.Employee; -import com.baeldung.data.EmployeeRepository; -import org.springframework.util.StringUtils; - -import com.vaadin.flow.component.button.Button; -import com.vaadin.flow.component.grid.Grid; -import com.vaadin.flow.component.icon.VaadinIcon; -import com.vaadin.flow.component.orderedlayout.HorizontalLayout; -import com.vaadin.flow.component.orderedlayout.VerticalLayout; -import com.vaadin.flow.component.textfield.TextField; -import com.vaadin.flow.data.value.ValueChangeMode; -import com.vaadin.flow.router.Route; - -@Route("crud") -public class CrudView extends VerticalLayout { - - private final EmployeeRepository employeeRepository; - - private final EmployeeEditor editor; - - final Grid grid; - - final TextField filter; - - private final Button addNewBtn; - - public CrudView(EmployeeRepository repo, EmployeeEditor editor) { - this.employeeRepository = repo; - this.editor = editor; - this.grid = new Grid<>(Employee.class); - this.filter = new TextField(); - this.addNewBtn = new Button("New employee", VaadinIcon.PLUS.create()); - - HorizontalLayout actions = new HorizontalLayout(filter, addNewBtn); - add(actions, grid, editor); - - grid.setHeight("200px"); - grid.setColumns("id", "firstName", "lastName"); - grid.getColumnByKey("id").setWidth("50px").setFlexGrow(0); - - filter.setPlaceholder("Filter by last name"); - - filter.setValueChangeMode(ValueChangeMode.EAGER); - filter.addValueChangeListener(e -> listEmployees(e.getValue())); - - grid.asSingleSelect().addValueChangeListener(e -> { - editor.editEmployee(e.getValue()); - }); - - addNewBtn.addClickListener(e -> editor.editEmployee(new Employee("", ""))); - - editor.setChangeHandler(() -> { - editor.setVisible(false); - listEmployees(filter.getValue()); - }); - - listEmployees(null); - } - - void listEmployees(String filterText) { - if (StringUtils.isEmpty(filterText)) { - grid.setItems(employeeRepository.findAll()); - } else { - grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText)); - } - } -} diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java index 25e447102c..0bc2c61e20 100644 --- a/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java +++ b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java @@ -1,92 +1,85 @@ package com.baeldung.spring; import com.baeldung.data.Employee; -import com.baeldung.data.EmployeeRepository; +import com.vaadin.flow.component.Composite; import com.vaadin.flow.component.Key; -import com.vaadin.flow.component.KeyNotifier; import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.button.ButtonVariant; import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.data.binder.Binder; -import com.vaadin.flow.spring.annotation.SpringComponent; -import com.vaadin.flow.spring.annotation.UIScope; -import org.springframework.beans.factory.annotation.Autowired; -@SpringComponent -@UIScope -public class EmployeeEditor extends VerticalLayout implements KeyNotifier { +public class EmployeeEditor extends Composite { - private final EmployeeRepository repository; + public interface SaveListener { + void onSave(Employee employee); + } + + public interface DeleteListener { + void onDelete(Employee employee); + } + + public interface CancelListener { + void onCancel(); + } private Employee employee; - TextField firstName = new TextField("First name"); - TextField lastName = new TextField("Last name"); + private SaveListener saveListener; + private DeleteListener deleteListener; + private CancelListener cancelListener; - Button save = new Button("Save", VaadinIcon.CHECK.create()); - Button cancel = new Button("Cancel"); - Button delete = new Button("Delete", VaadinIcon.TRASH.create()); - HorizontalLayout actions = new HorizontalLayout(save, cancel, delete); + private final Binder binder = new Binder<>(Employee.class); - Binder binder = new Binder<>(Employee.class); - private ChangeHandler changeHandler; +public EmployeeEditor() { + var firstName = new TextField("First name"); + var lastName = new TextField("Last name"); - @Autowired - public EmployeeEditor(EmployeeRepository repository) { - this.repository = repository; + var save = new Button("Save", VaadinIcon.CHECK.create()); + var cancel = new Button("Cancel"); + var delete = new Button("Delete", VaadinIcon.TRASH.create()); - add(firstName, lastName, actions); + binder.forField(firstName).bind(Employee::getFirstName, Employee::setFirstName); + binder.forField(lastName).bind(Employee::getLastName, Employee::setLastName); - binder.bindInstanceFields(this); + save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + save.addClickListener(e -> save()); + save.addClickShortcut(Key.ENTER); - setSpacing(true); + delete.addThemeVariants(ButtonVariant.LUMO_ERROR); + delete.addClickListener(e -> deleteListener.onDelete(employee)); - save.getElement().getThemeList().add("primary"); - delete.getElement().getThemeList().add("error"); + cancel.addClickListener(e -> cancelListener.onCancel()); - addKeyPressListener(Key.ENTER, e -> save()); + getContent().add(firstName, lastName, new HorizontalLayout(save, cancel, delete)); +} - save.addClickListener(e -> save()); - delete.addClickListener(e -> delete()); - cancel.addClickListener(e -> editEmployee(employee)); - setVisible(false); - } + private void save() { + // Save the form into a new instance of Employee + var updated = new Employee(); + updated.setId(employee.getId()); - void delete() { - repository.delete(employee); - changeHandler.onChange(); - } - - void save() { - repository.save(employee); - changeHandler.onChange(); - } - - public interface ChangeHandler { - void onChange(); - } - - public final void editEmployee(Employee c) { - if (c == null) { - setVisible(false); - return; + if (binder.writeBeanIfValid(updated)) { + saveListener.onSave(updated); } - final boolean persisted = c.getId() != null; - if (persisted) { - employee = repository.findById(c.getId()).get(); - } else { - employee = c; - } - - cancel.setVisible(persisted); - binder.setBean(employee); - setVisible(true); - firstName.focus(); } - public void setChangeHandler(ChangeHandler h) { - changeHandler = h; + public void setEmployee(Employee employee) { + this.employee = employee; + binder.readBean(employee); + } + + public void setSaveListener(SaveListener saveListener) { + this.saveListener = saveListener; + } + + public void setDeleteListener(DeleteListener deleteListener) { + this.deleteListener = deleteListener; + } + + public void setCancelListener(CancelListener cancelListener) { + this.cancelListener = cancelListener; } } diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java new file mode 100644 index 0000000000..8b78b1b1c5 --- /dev/null +++ b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java @@ -0,0 +1,95 @@ +package com.baeldung.spring; + +import com.baeldung.data.Employee; +import com.baeldung.data.EmployeeRepository; + +import com.vaadin.flow.component.button.Button; +import com.vaadin.flow.component.grid.Grid; +import com.vaadin.flow.component.icon.VaadinIcon; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; +import com.vaadin.flow.component.orderedlayout.VerticalLayout; +import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.value.ValueChangeMode; +import com.vaadin.flow.router.Route; + +@Route("employees") +public class EmployeesView extends VerticalLayout { + + private final EmployeeRepository employeeRepository; + + private final TextField filter; + private final Grid grid; + private final EmployeeEditor editor; + + + public EmployeesView(EmployeeRepository repo) { + employeeRepository = repo; + + // Create components + var addButton = new Button("New employee", VaadinIcon.PLUS.create()); + filter = new TextField(); + grid = new Grid<>(Employee.class); + editor = new EmployeeEditor(); + + // Configure components + configureEditor(); + + addButton.addClickListener(e -> editEmployee(new Employee())); + + filter.setPlaceholder("Filter by last name"); + filter.setValueChangeMode(ValueChangeMode.EAGER); + filter.addValueChangeListener(e -> updateEmployees(e.getValue())); + + grid.setHeight("200px"); + grid.asSingleSelect().addValueChangeListener(e -> editEmployee(e.getValue())); + + // Compose layout + var actionsLayout = new HorizontalLayout(filter, addButton); + add(actionsLayout, grid, editor); + + // List customers + updateEmployees(""); + } + + private void configureEditor() { + editor.setVisible(false); + + editor.setSaveListener(employee -> { + var saved = employeeRepository.save(employee); + updateEmployees(filter.getValue()); + editor.setEmployee(null); + grid.asSingleSelect().setValue(saved); + }); + + editor.setDeleteListener(employee -> { + employeeRepository.delete(employee); + updateEmployees(filter.getValue()); + editEmployee(null); + }); + + editor.setCancelListener(() -> { + editEmployee(null); + }); + } + + private void editEmployee(Employee employee) { + editor.setEmployee(employee); + + if (employee != null) { + editor.setVisible(true); + } else { + // Deselect grid + grid.asSingleSelect().setValue(null); + editor.setVisible(false); + } + + } + + private void updateEmployees(String filterText) { + if (filterText.isEmpty()) { + grid.setItems(employeeRepository.findAll()); + } else { + grid.setItems(employeeRepository.findByLastNameStartsWithIgnoreCase(filterText)); + } + } +} From d46ff97367b32ecab01f7dc0f7efda13373cc4c0 Mon Sep 17 00:00:00 2001 From: Marcus Hellberg Date: Tue, 2 Apr 2024 10:02:00 -0700 Subject: [PATCH 18/57] Change form biding to use BeanValidationBinder --- .../src/main/java/com/baeldung/spring/EmployeeEditor.java | 7 ++++--- .../src/main/java/com/baeldung/spring/EmployeesView.java | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java index 0bc2c61e20..7984ecce05 100644 --- a/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java +++ b/vaadin/src/main/java/com/baeldung/spring/EmployeeEditor.java @@ -9,6 +9,7 @@ import com.vaadin.flow.component.icon.VaadinIcon; import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.orderedlayout.VerticalLayout; import com.vaadin.flow.component.textfield.TextField; +import com.vaadin.flow.data.binder.BeanValidationBinder; import com.vaadin.flow.data.binder.Binder; public class EmployeeEditor extends Composite { @@ -31,7 +32,7 @@ public class EmployeeEditor extends Composite { private DeleteListener deleteListener; private CancelListener cancelListener; - private final Binder binder = new Binder<>(Employee.class); + private final Binder binder = new BeanValidationBinder<>(Employee.class); public EmployeeEditor() { var firstName = new TextField("First name"); @@ -41,8 +42,8 @@ public EmployeeEditor() { var cancel = new Button("Cancel"); var delete = new Button("Delete", VaadinIcon.TRASH.create()); - binder.forField(firstName).bind(Employee::getFirstName, Employee::setFirstName); - binder.forField(lastName).bind(Employee::getLastName, Employee::setLastName); + binder.forField(firstName).bind("firstName"); + binder.forField(lastName).bind("lastName"); save.addThemeVariants(ButtonVariant.LUMO_PRIMARY); save.addClickListener(e -> save()); diff --git a/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java index 8b78b1b1c5..edb1f7a75b 100644 --- a/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java +++ b/vaadin/src/main/java/com/baeldung/spring/EmployeesView.java @@ -37,7 +37,7 @@ public class EmployeesView extends VerticalLayout { addButton.addClickListener(e -> editEmployee(new Employee())); filter.setPlaceholder("Filter by last name"); - filter.setValueChangeMode(ValueChangeMode.EAGER); + filter.setValueChangeMode(ValueChangeMode.LAZY); filter.addValueChangeListener(e -> updateEmployees(e.getValue())); grid.setHeight("200px"); From 1864b8e90d28705e09128ddfed2eb23adbf2598e Mon Sep 17 00:00:00 2001 From: hajk1 Date: Wed, 3 Apr 2024 01:32:44 +0330 Subject: [PATCH 19/57] adding new article BAEL-7497 source codes --- .../core-java-collections-6/README.md | 7 ++ .../core-java-collections-6/pom.xml | 54 +++++++++++++++ .../IteratorVsForeachUnitTest.java | 69 +++++++++++++++++++ core-java-modules/pom.xml | 1 + 4 files changed, 131 insertions(+) create mode 100644 core-java-modules/core-java-collections-6/README.md create mode 100644 core-java-modules/core-java-collections-6/pom.xml create mode 100644 core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java diff --git a/core-java-modules/core-java-collections-6/README.md b/core-java-modules/core-java-collections-6/README.md new file mode 100644 index 0000000000..736e91f110 --- /dev/null +++ b/core-java-modules/core-java-collections-6/README.md @@ -0,0 +1,7 @@ +========= + +## Core Java Collections Cookbooks and Examples + +### Relevant Articles: + +- More articles: [[<-- prev]](/core-java-modules/core-java-collections-5) diff --git a/core-java-modules/core-java-collections-6/pom.xml b/core-java-modules/core-java-collections-6/pom.xml new file mode 100644 index 0000000000..8294a4d76a --- /dev/null +++ b/core-java-modules/core-java-collections-6/pom.xml @@ -0,0 +1,54 @@ + + + core-java-collections-6 + + + + maven-compiler-plugin + + 9 + 9 + + org.apache.maven.plugins + + + + + + junit-platform-runner + org.junit.platform + test + ${junit-platform.version} + + + junit-jupiter + org.junit.jupiter + test + ${junit.version} + + + junit-vintage-engine + org.junit.vintage + test + ${junit.version} + + + 4.0.0 + + core-java-collections-6 + + jar + + + core-java-modules + com.baeldung.core-java-modules + 0.0.1-SNAPSHOT + + + + 5.10.2 + + + diff --git a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java new file mode 100644 index 0000000000..a95c1a1e98 --- /dev/null +++ b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java @@ -0,0 +1,69 @@ +package com.baeldung.iteratorvsforeach; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class IteratorVsForeachUnitTest { + + private static Stream listProvider() { + return Stream.of( + Arguments.of( + List.of("String1", "String2", "unwanted"), + List.of("String1", "String2")) + ); + } + + @Test + public void givenEmptyCollection_whenUsingForEach_thenNoElementsAreIterated() { + List names = Collections.emptyList(); + StringBuilder stringBuilder = new StringBuilder(); + names.forEach(stringBuilder::append); + assertEquals("", stringBuilder.toString()); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringForEachIteration_thenElementIsRemoved( + List input, List expected) { + List mutableList = new ArrayList<>(input); + // Separate collection for items to be removed + List toRemove = new ArrayList<>(); + + // Using forEach to identify items to remove + input.forEach(item -> { + if (item.equals("unwanted")) { + toRemove.add(item); + } + }); + + // Removing the identified items from the original list + mutableList.removeAll(toRemove); + assertIterableEquals(expected, mutableList); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringIteratorIteration_thenElementIsRemoved( + List input, List expected) { + List mutableList = new ArrayList<>(input); + Iterator it = mutableList.iterator(); + while (it.hasNext()) { + String item = it.next(); + if (item.equals("unwanted")) { + it.remove(); // Safely remove item + } + } + assertIterableEquals(expected, mutableList); + } + +} diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index 3d26d51a6a..56360d0106 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -89,6 +89,7 @@ core-java-collections-3 core-java-collections-4 core-java-collections-5 + core-java-collections-6 core-java-collections-conversions core-java-collections-set-2 core-java-collections-list From fc31ffd062fabb34622debdfd7f1bde4d963b395 Mon Sep 17 00:00:00 2001 From: hajk1 Date: Fri, 5 Apr 2024 00:41:35 +0330 Subject: [PATCH 20/57] reformat the pom file to be more logical --- .../core-java-collections-6/pom.xml | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/core-java-modules/core-java-collections-6/pom.xml b/core-java-modules/core-java-collections-6/pom.xml index 8294a4d76a..ae95ecac07 100644 --- a/core-java-modules/core-java-collections-6/pom.xml +++ b/core-java-modules/core-java-collections-6/pom.xml @@ -2,19 +2,17 @@ + 4.0.0 core-java-collections-6 - - - - maven-compiler-plugin - - 9 - 9 - - org.apache.maven.plugins - - - + core-java-collections-6 + jar + + + core-java-modules + com.baeldung.core-java-modules + 0.0.1-SNAPSHOT + + junit-platform-runner @@ -35,17 +33,19 @@ ${junit.version} - 4.0.0 - core-java-collections-6 - - jar - - - core-java-modules - com.baeldung.core-java-modules - 0.0.1-SNAPSHOT - + + + + maven-compiler-plugin + + 9 + 9 + + org.apache.maven.plugins + + + 5.10.2 From dab8be8a01c6306f553d0c20d0603e2cb80ad45a Mon Sep 17 00:00:00 2001 From: reza ganji Date: Fri, 5 Apr 2024 13:03:28 +0330 Subject: [PATCH 21/57] BAEL-7540 --- .../UserService.java} | 16 ++++++++++------ .../UserControllerUnitTest.java | 2 ++ 2 files changed, 12 insertions(+), 6 deletions(-) rename spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/{controller/UserController.java => service/UserService.java} (65%) create mode 100644 spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java similarity index 65% rename from spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java rename to spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java index 6490b997af..98d503bb23 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/controller/UserController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java @@ -6,8 +6,8 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; +import com.baeldung.webflux.exceptionhandeling.model.User; import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; -import com.baeldung.webflux.zipwhen.model.User; import reactor.core.publisher.Mono; @@ -17,19 +17,23 @@ public class UserController { private final UserRepository userRepository; @Autowired - public UserController(UserRepository userRepository) { + public UserController(MyRepository userRepository) { this.userRepository = userRepository; } @GetMapping("/user/{id}") public Mono getUserByIdThrowingException(@PathVariable String id) { - return userRepository.findById(id) - .switchIfEmpty(Mono.error(new NotFoundException("User not found"))); + User user= userRepository.findById(id); + if(user==null) + throw new NotFoundException("User Not Found"); + return Mono.justOrEmpty(user); } @GetMapping("/user/{id}") public Mono getUserByIdUsingMonoError(@PathVariable String id) { - return userRepository.findById(id) - .switchIfEmpty(Mono.error(() -> new NotFoundException("User not found"))); + User user= userRepository.findById(id); + if(user==null) + return Mono.error(new NotFoundException("User Not Found")); + return Mono.justOrEmpty(user); } } diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java new file mode 100644 index 0000000000..d81c553d41 --- /dev/null +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java @@ -0,0 +1,2 @@ +package com.baeldung.webflux.exceptionhandeling;public class UserControllerUnitTest { +} From 2b1ef2752765f60bbee97d1dc29c873a6fee81d2 Mon Sep 17 00:00:00 2001 From: reza ganji Date: Fri, 5 Apr 2024 13:06:23 +0330 Subject: [PATCH 22/57] BAEL-7540 --- .../exceptionhandeling/model/User.java | 4 +-- .../repository/UserRepository.java | 8 ++--- .../service/UserService.java | 23 ++++++------ .../UserControllerUnitTest.java | 36 ++++++++++++++++++- 4 files changed, 50 insertions(+), 21 deletions(-) diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java index 42e1293ee8..6bc39da062 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/model/User.java @@ -21,8 +21,8 @@ public class User { } public User(String userId, String userName) { - this.id=userId; - this.username=userName; + this.id = userId; + this.username = userName; } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java index 7d4ac0af86..8c153aa2e6 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/repository/UserRepository.java @@ -5,9 +5,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.springframework.stereotype.Repository; -import com.baeldung.webflux.zipwhen.model.User; - -import reactor.core.publisher.Mono; +import com.baeldung.webflux.exceptionhandeling.model.User; @Repository public class UserRepository { @@ -18,7 +16,7 @@ public class UserRepository { userDatabase.put("2", new User("2", "Jane Smith")); } - public Mono findById(String id) { - return Mono.justOrEmpty(userDatabase.get(id)); + public User findById(String id) { + return userDatabase.get(id); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java index 98d503bb23..eafaf421b9 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java @@ -1,9 +1,8 @@ -package com.baeldung.webflux.exceptionhandeling.controller; +package com.baeldung.webflux.exceptionhandeling.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; import com.baeldung.webflux.exceptionhandeling.model.User; @@ -11,29 +10,27 @@ import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; import reactor.core.publisher.Mono; -@RestController -public class UserController { +public class UserService { private final UserRepository userRepository; @Autowired - public UserController(MyRepository userRepository) { + public UserService(UserRepository userRepository) { this.userRepository = userRepository; } @GetMapping("/user/{id}") public Mono getUserByIdThrowingException(@PathVariable String id) { - User user= userRepository.findById(id); - if(user==null) - throw new NotFoundException("User Not Found"); - return Mono.justOrEmpty(user); + User user = userRepository.findById(id); + if (user == null) + throw new NotFoundException("User Not Found"); + return Mono.justOrEmpty(user); } @GetMapping("/user/{id}") public Mono getUserByIdUsingMonoError(@PathVariable String id) { - User user= userRepository.findById(id); - if(user==null) - return Mono.error(new NotFoundException("User Not Found")); - return Mono.justOrEmpty(user); + User user = userRepository.findById(id); + return (user != null) ? Mono.justOrEmpty(user) : Mono.error(new NotFoundException("User Not Found")); + } } diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java index d81c553d41..e968cfeea3 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/exceptionhandeling/UserControllerUnitTest.java @@ -1,2 +1,36 @@ -package com.baeldung.webflux.exceptionhandeling;public class UserControllerUnitTest { +package com.baeldung.webflux.exceptionhandeling; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.Test; + +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import com.baeldung.webflux.exceptionhandeling.ex.NotFoundException; +import com.baeldung.webflux.exceptionhandeling.model.User; +import com.baeldung.webflux.exceptionhandeling.service.UserService; +import com.baeldung.webflux.exceptionhandeling.repository.UserRepository; + +public class UserControllerUnitTest { + UserRepository repositoryMock = mock(UserRepository.class); + private final UserService userService = new UserService(repositoryMock); + + @Test + public void givenNonExistUser_whenFailureCall_then_Throws_exception() { + assertThrows(NotFoundException.class, () -> userService.getUserByIdThrowingException("3")); + + } + + @Test + public void givenNonExistUser_whenFailureCall_then_returnMonoError() { + Mono result = userService.getUserByIdUsingMonoError("3"); + StepVerifier.create(result) + .expectError(NotFoundException.class) + .verify(); + + } + } From 23f1b4cbf3b64c93ebe1784ebe1ce18b3b06e85b Mon Sep 17 00:00:00 2001 From: reza ganji Date: Fri, 5 Apr 2024 13:24:42 +0330 Subject: [PATCH 23/57] BAEL-7540 --- .../webflux/exceptionhandeling/service/UserService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java index eafaf421b9..da5a672183 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/exceptionhandeling/service/UserService.java @@ -19,16 +19,14 @@ public class UserService { this.userRepository = userRepository; } - @GetMapping("/user/{id}") - public Mono getUserByIdThrowingException(@PathVariable String id) { + public Mono getUserByIdThrowingException(String id) { User user = userRepository.findById(id); if (user == null) throw new NotFoundException("User Not Found"); return Mono.justOrEmpty(user); } - @GetMapping("/user/{id}") - public Mono getUserByIdUsingMonoError(@PathVariable String id) { + public Mono getUserByIdUsingMonoError(String id) { User user = userRepository.findById(id); return (user != null) ? Mono.justOrEmpty(user) : Mono.error(new NotFoundException("User Not Found")); From 74da8faf7f809da13f1aca69a1f93c5f3861da8f Mon Sep 17 00:00:00 2001 From: "Kai.Yuan" Date: Fri, 5 Apr 2024 23:45:34 +0200 Subject: [PATCH 24/57] [improvement-init-Long-list] add long list init --- .../ListInitializationUnitTest.java | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java index 25f39e9a13..a0dca8d6c1 100644 --- a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java +++ b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java @@ -1,16 +1,15 @@ package com.baeldung.java.listInitialization; +import lombok.extern.java.Log; +import org.junit.Assert; +import org.junit.Test; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; -import lombok.extern.java.Log; - -import org.junit.Assert; -import org.junit.Test; - @Log public class ListInitializationUnitTest { @@ -49,11 +48,30 @@ public class ListInitializationUnitTest { Assert.assertEquals("baz", list.get(0)); } + @Test + public void givenIntNumbers_whenRequiredLong_thenCastAutomatically() { + int intNum = 42; + long longNum = intNum; + + Assert.assertEquals(42L, longNum); + } + + @Test + public void givenArrayAsList_whenRequiredLongList_thenGetExpectedResult() { + List listOfLongFixedSize = Arrays.asList(1L, 2L, 3L); + List listOfLong = new ArrayList<>(Arrays.asList(1L, 2L, 3L)); + + List expected = List.of(1L, 2L, 3L); + + Assert.assertEquals(expected, listOfLongFixedSize); + Assert.assertEquals(expected, listOfLong); + } + @Test public void givenStream_thenInitializeList() { List list = Stream.of("foo", "bar") - .collect(Collectors.toList()); + .collect(Collectors.toList()); Assert.assertTrue(list.contains("foo")); } -} +} \ No newline at end of file From 592655fef8718ae3d868b45fd4af3df11afaa808 Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Sun, 7 Apr 2024 15:06:48 +0300 Subject: [PATCH 25/57] JAVA-30177 Upgrade h2 library in the main pom.xml (#16314) Co-authored-by: timis1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 57bc8bbfb3..7496d4ca93 100644 --- a/pom.xml +++ b/pom.xml @@ -1187,7 +1187,7 @@ 3.3.0 3.21.0 1.18.30 - 2.1.214 + 2.2.224 33.0.0-jre 3.3.0 From 2a754ad3372b730792eab64e3b71cd1053731d27 Mon Sep 17 00:00:00 2001 From: hajk1 Date: Sun, 7 Apr 2024 18:25:13 +0330 Subject: [PATCH 26/57] reformat the files using intellij-baeldung-style.xml --- .../core-java-collections-6/pom.xml | 92 +++++++++--------- .../IteratorVsForeachUnitTest.java | 93 +++++++++---------- 2 files changed, 90 insertions(+), 95 deletions(-) diff --git a/core-java-modules/core-java-collections-6/pom.xml b/core-java-modules/core-java-collections-6/pom.xml index ae95ecac07..5140947479 100644 --- a/core-java-modules/core-java-collections-6/pom.xml +++ b/core-java-modules/core-java-collections-6/pom.xml @@ -1,54 +1,54 @@ - 4.0.0 - core-java-collections-6 - core-java-collections-6 - jar + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + core-java-collections-6 + core-java-collections-6 + jar - - core-java-modules - com.baeldung.core-java-modules - 0.0.1-SNAPSHOT - + + core-java-modules + com.baeldung.core-java-modules + 0.0.1-SNAPSHOT + - - - junit-platform-runner - org.junit.platform - test - ${junit-platform.version} - - - junit-jupiter - org.junit.jupiter - test - ${junit.version} - - - junit-vintage-engine - org.junit.vintage - test - ${junit.version} - - + + + junit-platform-runner + org.junit.platform + test + ${junit-platform.version} + + + junit-jupiter + org.junit.jupiter + test + ${junit.version} + + + junit-vintage-engine + org.junit.vintage + test + ${junit.version} + + - - - - maven-compiler-plugin - - 9 - 9 - - org.apache.maven.plugins - - - + + + + maven-compiler-plugin + + 9 + 9 + + org.apache.maven.plugins + + + - - 5.10.2 - + + 5.10.2 + diff --git a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java index a95c1a1e98..ca9390a3ee 100644 --- a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java +++ b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java @@ -8,6 +8,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.stream.Stream; + import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -15,55 +16,49 @@ import org.junit.jupiter.params.provider.MethodSource; class IteratorVsForeachUnitTest { - private static Stream listProvider() { - return Stream.of( - Arguments.of( - List.of("String1", "String2", "unwanted"), - List.of("String1", "String2")) - ); - } - - @Test - public void givenEmptyCollection_whenUsingForEach_thenNoElementsAreIterated() { - List names = Collections.emptyList(); - StringBuilder stringBuilder = new StringBuilder(); - names.forEach(stringBuilder::append); - assertEquals("", stringBuilder.toString()); - } - - @ParameterizedTest - @MethodSource("listProvider") - public void givenCollectionWithElements_whenRemovingElementDuringForEachIteration_thenElementIsRemoved( - List input, List expected) { - List mutableList = new ArrayList<>(input); - // Separate collection for items to be removed - List toRemove = new ArrayList<>(); - - // Using forEach to identify items to remove - input.forEach(item -> { - if (item.equals("unwanted")) { - toRemove.add(item); - } - }); - - // Removing the identified items from the original list - mutableList.removeAll(toRemove); - assertIterableEquals(expected, mutableList); - } - - @ParameterizedTest - @MethodSource("listProvider") - public void givenCollectionWithElements_whenRemovingElementDuringIteratorIteration_thenElementIsRemoved( - List input, List expected) { - List mutableList = new ArrayList<>(input); - Iterator it = mutableList.iterator(); - while (it.hasNext()) { - String item = it.next(); - if (item.equals("unwanted")) { - it.remove(); // Safely remove item - } + private static Stream listProvider() { + return Stream.of(Arguments.of(List.of("String1", "String2", "unwanted"), List.of("String1", "String2"))); + } + + @Test + public void givenEmptyCollection_whenUsingForEach_thenNoElementsAreIterated() { + List names = Collections.emptyList(); + StringBuilder stringBuilder = new StringBuilder(); + names.forEach(stringBuilder::append); + assertEquals("", stringBuilder.toString()); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringForEachIteration_thenElementIsRemoved(List input, List expected) { + List mutableList = new ArrayList<>(input); + // Separate collection for items to be removed + List toRemove = new ArrayList<>(); + + // Using forEach to identify items to remove + input.forEach(item -> { + if (item.equals("unwanted")) { + toRemove.add(item); + } + }); + + // Removing the identified items from the original list + mutableList.removeAll(toRemove); + assertIterableEquals(expected, mutableList); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringIteratorIteration_thenElementIsRemoved(List input, List expected) { + List mutableList = new ArrayList<>(input); + Iterator it = mutableList.iterator(); + while (it.hasNext()) { + String item = it.next(); + if (item.equals("unwanted")) { + it.remove(); // Safely remove item + } + } + assertIterableEquals(expected, mutableList); } - assertIterableEquals(expected, mutableList); - } } From ce618671be5108968d56840cd18a36a09adbd526 Mon Sep 17 00:00:00 2001 From: "Kai.Yuan" Date: Sun, 7 Apr 2024 17:11:14 +0200 Subject: [PATCH 27/57] [improvement-init-Long-list] update --- .../ListInitializationUnitTest.java | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java index a0dca8d6c1..463e15a41c 100644 --- a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java +++ b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java @@ -1,8 +1,7 @@ package com.baeldung.java.listInitialization; -import lombok.extern.java.Log; -import org.junit.Assert; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Arrays; @@ -10,6 +9,10 @@ import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.junit.Test; + +import lombok.extern.java.Log; + @Log public class ListInitializationUnitTest { @@ -23,14 +26,14 @@ public class ListInitializationUnitTest { } }; - Assert.assertTrue(cities.contains("New York")); + assertTrue(cities.contains("New York")); } @Test public void givenArraysAsList_thenInitialiseList() { List list = Arrays.asList("foo", "bar"); - Assert.assertTrue(list.contains("foo")); + assertTrue(list.contains("foo")); } @Test(expected = UnsupportedOperationException.class) @@ -40,12 +43,23 @@ public class ListInitializationUnitTest { list.add("baz"); } + @Test + public void givenArraysAsList_whenUsingArrayListConstructor_thenWeCanAddOrRemove() { + List list = new ArrayList<>(Arrays.asList("foo", "bar")); + + list.add("baz"); + assertEquals(List.of("foo", "bar","baz"), list); + + list.remove("baz"); + assertEquals(List.of("foo", "bar"), list); + } + @Test public void givenArraysAsList_whenCreated_thenShareReference() { String[] array = { "foo", "bar" }; List list = Arrays.asList(array); array[0] = "baz"; - Assert.assertEquals("baz", list.get(0)); + assertEquals("baz", list.get(0)); } @Test @@ -53,7 +67,7 @@ public class ListInitializationUnitTest { int intNum = 42; long longNum = intNum; - Assert.assertEquals(42L, longNum); + assertEquals(42L, longNum); } @Test @@ -63,15 +77,15 @@ public class ListInitializationUnitTest { List expected = List.of(1L, 2L, 3L); - Assert.assertEquals(expected, listOfLongFixedSize); - Assert.assertEquals(expected, listOfLong); + assertEquals(expected, listOfLongFixedSize); + assertEquals(expected, listOfLong); } @Test public void givenStream_thenInitializeList() { List list = Stream.of("foo", "bar") - .collect(Collectors.toList()); + .collect(Collectors.toList()); - Assert.assertTrue(list.contains("foo")); + assertTrue(list.contains("foo")); } } \ No newline at end of file From 8e247e172b856d39d93396e9283a550c8894f17e Mon Sep 17 00:00:00 2001 From: Wynn Teo <49014791+wynnteo@users.noreply.github.com> Date: Mon, 8 Apr 2024 10:30:35 +0800 Subject: [PATCH 28/57] Bael 7668 (#16257) * BAEL-7490 read write file in separate thread * Change the to try resources * Update the code to sync with article * jooq join table * Fix the wildcard import --- .../jooq/jointables/DefaultCatalog.java | 56 +++++ .../baeldung/jooq/jointables/JoinTables.java | 75 ++++++ .../jooq/jointables/public_/Keys.java | 34 +++ .../jooq/jointables/public_/Public.java | 69 +++++ .../jooq/jointables/public_/Tables.java | 32 +++ .../jooq/jointables/public_/tables/Book.java | 238 ++++++++++++++++++ .../jointables/public_/tables/Bookauthor.java | 228 +++++++++++++++++ .../jooq/jointables/public_/tables/Store.java | 223 ++++++++++++++++ .../public_/tables/records/BookRecord.java | 124 +++++++++ .../tables/records/BookauthorRecord.java | 94 +++++++ .../public_/tables/records/StoreRecord.java | 79 ++++++ .../jointables/JoinTablesIntegrationTest.java | 111 ++++++++ .../jooq/src/test/resources/jooq-config-2.xml | 19 ++ 13 files changed, 1382 insertions(+) create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java create mode 100644 persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java create mode 100644 persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesIntegrationTest.java create mode 100644 persistence-modules/jooq/src/test/resources/jooq-config-2.xml diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java new file mode 100644 index 0000000000..a730e9bfc6 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/DefaultCatalog.java @@ -0,0 +1,56 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables; + + +import com.baeldung.jooq.jointables.public_.Public; + +import java.util.Arrays; +import java.util.List; + +import org.jooq.Constants; +import org.jooq.Schema; +import org.jooq.impl.CatalogImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class DefaultCatalog extends CatalogImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of DEFAULT_CATALOG + */ + public static final DefaultCatalog DEFAULT_CATALOG = new DefaultCatalog(); + + /** + * The schema public. + */ + public final Public PUBLIC = Public.PUBLIC; + + /** + * No further instances allowed + */ + private DefaultCatalog() { + super(""); + } + + @Override + public final List getSchemas() { + return Arrays.asList( + Public.PUBLIC + ); + } + + /** + * A reference to the 3.19 minor release of the code generator. If this + * doesn't compile, it's because the runtime library uses an older minor + * release, namely: 3.19. You can turn off the generation of this reference + * by specifying /configuration/generator/generate/jooqVersionReference + */ + private static final String REQUIRE_RUNTIME_JOOQ_VERSION = Constants.VERSION_3_19; +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java new file mode 100644 index 0000000000..2c67ef2ad3 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/JoinTables.java @@ -0,0 +1,75 @@ +package com.baeldung.jooq.jointables; + +import static org.jooq.impl.DSL.field; + +import org.jooq.DSLContext; +import org.jooq.Record; +import org.jooq.Result; +import org.jooq.SelectJoinStep; + +import com.baeldung.jooq.jointables.public_.Tables; + +public class JoinTables { + + public static Result usingJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .join(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))); + return query.fetch(); + } + + public static Result usingMultipleJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .join(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))) + .join(Tables.STORE) + .on(field(Tables.BOOK.STORE_ID).eq(field(Tables.STORE.ID))); + return query.fetch(); + } + + public static Result usingLeftOuterJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .leftOuterJoin(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))); + return query.fetch(); + } + + public static Result usingRightOuterJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .rightOuterJoin(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))); + return query.fetch(); + } + + public static Result usingFullOuterJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .fullOuterJoin(Tables.BOOKAUTHOR) + .on(field(Tables.BOOK.AUTHOR_ID).eq(field(Tables.BOOKAUTHOR.ID))); + return query.fetch(); + } + + public static Result usingNaturalJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.BOOK) + .naturalJoin(Tables.BOOKAUTHOR); + return query.fetch(); + } + + public static Result usingCrossJoinMethod(DSLContext context) { + SelectJoinStep query = context.select() + .from(Tables.STORE) + .crossJoin(Tables.BOOK); + return query.fetch(); + } + + public static void printResult(Result result) { + for (Record record : result) { + System.out.println(record); + } + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java new file mode 100644 index 0000000000..86c1939891 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Keys.java @@ -0,0 +1,34 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_; + + +import com.baeldung.jooq.jointables.public_.tables.Book; +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; +import com.baeldung.jooq.jointables.public_.tables.Store; +import com.baeldung.jooq.jointables.public_.tables.records.BookRecord; +import com.baeldung.jooq.jointables.public_.tables.records.BookauthorRecord; +import com.baeldung.jooq.jointables.public_.tables.records.StoreRecord; + +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.Internal; + + +/** + * A class modelling foreign key relationships and constraints of tables in + * public. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Keys { + + // ------------------------------------------------------------------------- + // UNIQUE and PRIMARY KEY definitions + // ------------------------------------------------------------------------- + + public static final UniqueKey BOOK_PKEY = Internal.createUniqueKey(Book.BOOK, DSL.name("Book_pkey"), new TableField[] { Book.BOOK.ID }, true); + public static final UniqueKey AUTHOR_PKEY = Internal.createUniqueKey(Bookauthor.BOOKAUTHOR, DSL.name("Author_pkey"), new TableField[] { Bookauthor.BOOKAUTHOR.ID }, true); + public static final UniqueKey STORE_PKEY = Internal.createUniqueKey(Store.STORE, DSL.name("Store_pkey"), new TableField[] { Store.STORE.ID }, true); +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java new file mode 100644 index 0000000000..1b2e8dda87 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Public.java @@ -0,0 +1,69 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_; + + +import com.baeldung.jooq.jointables.DefaultCatalog; +import com.baeldung.jooq.jointables.public_.tables.Book; +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; +import com.baeldung.jooq.jointables.public_.tables.Store; + +import java.util.Arrays; +import java.util.List; + +import org.jooq.Catalog; +import org.jooq.Table; +import org.jooq.impl.SchemaImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Public extends SchemaImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of public + */ + public static final Public PUBLIC = new Public(); + + /** + * The table public.Book. + */ + public final Book BOOK = Book.BOOK; + + /** + * The table public.BookAuthor. + */ + public final Bookauthor BOOKAUTHOR = Bookauthor.BOOKAUTHOR; + + /** + * The table public.Store. + */ + public final Store STORE = Store.STORE; + + /** + * No further instances allowed + */ + private Public() { + super("public", null); + } + + + @Override + public Catalog getCatalog() { + return DefaultCatalog.DEFAULT_CATALOG; + } + + @Override + public final List> getTables() { + return Arrays.asList( + Book.BOOK, + Bookauthor.BOOKAUTHOR, + Store.STORE + ); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java new file mode 100644 index 0000000000..789c131a25 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/Tables.java @@ -0,0 +1,32 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_; + + +import com.baeldung.jooq.jointables.public_.tables.Book; +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; +import com.baeldung.jooq.jointables.public_.tables.Store; + + +/** + * Convenience access to all tables in public. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Tables { + + /** + * The table public.Book. + */ + public static final Book BOOK = Book.BOOK; + + /** + * The table public.BookAuthor. + */ + public static final Bookauthor BOOKAUTHOR = Bookauthor.BOOKAUTHOR; + + /** + * The table public.Store. + */ + public static final Store STORE = Store.STORE; +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java new file mode 100644 index 0000000000..4e21648cbd --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Book.java @@ -0,0 +1,238 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables; + + +import com.baeldung.jooq.jointables.public_.Keys; +import com.baeldung.jooq.jointables.public_.Public; +import com.baeldung.jooq.jointables.public_.tables.records.BookRecord; + +import java.util.Collection; + +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.Name; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Book extends TableImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of public.Book + */ + public static final Book BOOK = new Book(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return BookRecord.class; + } + + /** + * The column public.Book.id. + */ + public final TableField ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column public.Book.author_id. + */ + public final TableField AUTHOR_ID = createField(DSL.name("author_id"), SQLDataType.INTEGER, this, ""); + + /** + * The column public.Book.title. + */ + public final TableField TITLE = createField(DSL.name("title"), SQLDataType.VARCHAR, this, ""); + + /** + * The column public.Book.description. + */ + public final TableField DESCRIPTION = createField(DSL.name("description"), SQLDataType.VARCHAR, this, ""); + + /** + * The column public.Book.store_id. + */ + public final TableField STORE_ID = createField(DSL.name("store_id"), SQLDataType.INTEGER, this, ""); + + private Book(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private Book(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased public.Book table reference + */ + public Book(String alias) { + this(DSL.name(alias), BOOK); + } + + /** + * Create an aliased public.Book table reference + */ + public Book(Name alias) { + this(alias, BOOK); + } + + /** + * Create a public.Book table reference + */ + public Book() { + this(DSL.name("Book"), null); + } + + @Override + public Schema getSchema() { + return aliased() ? null : Public.PUBLIC; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.BOOK_PKEY; + } + + @Override + public Book as(String alias) { + return new Book(DSL.name(alias), this); + } + + @Override + public Book as(Name alias) { + return new Book(alias, this); + } + + @Override + public Book as(Table alias) { + return new Book(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public Book rename(String name) { + return new Book(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public Book rename(Name name) { + return new Book(name, null); + } + + /** + * Rename this table + */ + @Override + public Book rename(Table name) { + return new Book(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book where(Condition condition) { + return new Book(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Book where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Book where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Book where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Book where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Book whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java new file mode 100644 index 0000000000..9d828e9add --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Bookauthor.java @@ -0,0 +1,228 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables; + + +import com.baeldung.jooq.jointables.public_.Keys; +import com.baeldung.jooq.jointables.public_.Public; +import com.baeldung.jooq.jointables.public_.tables.records.BookauthorRecord; + +import java.util.Collection; + +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.Name; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Bookauthor extends TableImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of public.BookAuthor + */ + public static final Bookauthor BOOKAUTHOR = new Bookauthor(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return BookauthorRecord.class; + } + + /** + * The column public.BookAuthor.id. + */ + public final TableField ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column public.BookAuthor.name. + */ + public final TableField NAME = createField(DSL.name("name"), SQLDataType.VARCHAR.nullable(false), this, ""); + + /** + * The column public.BookAuthor.country. + */ + public final TableField COUNTRY = createField(DSL.name("country"), SQLDataType.VARCHAR, this, ""); + + private Bookauthor(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private Bookauthor(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased public.BookAuthor table reference + */ + public Bookauthor(String alias) { + this(DSL.name(alias), BOOKAUTHOR); + } + + /** + * Create an aliased public.BookAuthor table reference + */ + public Bookauthor(Name alias) { + this(alias, BOOKAUTHOR); + } + + /** + * Create a public.BookAuthor table reference + */ + public Bookauthor() { + this(DSL.name("BookAuthor"), null); + } + + @Override + public Schema getSchema() { + return aliased() ? null : Public.PUBLIC; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.AUTHOR_PKEY; + } + + @Override + public Bookauthor as(String alias) { + return new Bookauthor(DSL.name(alias), this); + } + + @Override + public Bookauthor as(Name alias) { + return new Bookauthor(alias, this); + } + + @Override + public Bookauthor as(Table alias) { + return new Bookauthor(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public Bookauthor rename(String name) { + return new Bookauthor(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public Bookauthor rename(Name name) { + return new Bookauthor(name, null); + } + + /** + * Rename this table + */ + @Override + public Bookauthor rename(Table name) { + return new Bookauthor(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor where(Condition condition) { + return new Bookauthor(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Bookauthor where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Bookauthor where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Bookauthor where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Bookauthor where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Bookauthor whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java new file mode 100644 index 0000000000..d97f3da21b --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/Store.java @@ -0,0 +1,223 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables; + + +import com.baeldung.jooq.jointables.public_.Keys; +import com.baeldung.jooq.jointables.public_.Public; +import com.baeldung.jooq.jointables.public_.tables.records.StoreRecord; + +import java.util.Collection; + +import org.jooq.Condition; +import org.jooq.Field; +import org.jooq.Name; +import org.jooq.PlainSQL; +import org.jooq.QueryPart; +import org.jooq.SQL; +import org.jooq.Schema; +import org.jooq.Select; +import org.jooq.Stringly; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.TableOptions; +import org.jooq.UniqueKey; +import org.jooq.impl.DSL; +import org.jooq.impl.SQLDataType; +import org.jooq.impl.TableImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class Store extends TableImpl { + + private static final long serialVersionUID = 1L; + + /** + * The reference instance of public.Store + */ + public static final Store STORE = new Store(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return StoreRecord.class; + } + + /** + * The column public.Store.id. + */ + public final TableField ID = createField(DSL.name("id"), SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column public.Store.name. + */ + public final TableField NAME = createField(DSL.name("name"), SQLDataType.VARCHAR.nullable(false), this, ""); + + private Store(Name alias, Table aliased) { + this(alias, aliased, (Field[]) null, null); + } + + private Store(Name alias, Table aliased, Field[] parameters, Condition where) { + super(alias, null, aliased, parameters, DSL.comment(""), TableOptions.table(), where); + } + + /** + * Create an aliased public.Store table reference + */ + public Store(String alias) { + this(DSL.name(alias), STORE); + } + + /** + * Create an aliased public.Store table reference + */ + public Store(Name alias) { + this(alias, STORE); + } + + /** + * Create a public.Store table reference + */ + public Store() { + this(DSL.name("Store"), null); + } + + @Override + public Schema getSchema() { + return aliased() ? null : Public.PUBLIC; + } + + @Override + public UniqueKey getPrimaryKey() { + return Keys.STORE_PKEY; + } + + @Override + public Store as(String alias) { + return new Store(DSL.name(alias), this); + } + + @Override + public Store as(Name alias) { + return new Store(alias, this); + } + + @Override + public Store as(Table alias) { + return new Store(alias.getQualifiedName(), this); + } + + /** + * Rename this table + */ + @Override + public Store rename(String name) { + return new Store(DSL.name(name), null); + } + + /** + * Rename this table + */ + @Override + public Store rename(Name name) { + return new Store(name, null); + } + + /** + * Rename this table + */ + @Override + public Store rename(Table name) { + return new Store(name.getQualifiedName(), null); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store where(Condition condition) { + return new Store(getQualifiedName(), aliased() ? this : null, null, condition); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store where(Collection conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store where(Condition... conditions) { + return where(DSL.and(conditions)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store where(Field condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Store where(SQL condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Store where(@Stringly.SQL String condition) { + return where(DSL.condition(condition)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Store where(@Stringly.SQL String condition, Object... binds) { + return where(DSL.condition(condition, binds)); + } + + /** + * Create an inline derived table from this table + */ + @Override + @PlainSQL + public Store where(@Stringly.SQL String condition, QueryPart... parts) { + return where(DSL.condition(condition, parts)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store whereExists(Select select) { + return where(DSL.exists(select)); + } + + /** + * Create an inline derived table from this table + */ + @Override + public Store whereNotExists(Select select) { + return where(DSL.notExists(select)); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java new file mode 100644 index 0000000000..0636ff2fdf --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookRecord.java @@ -0,0 +1,124 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables.records; + + +import com.baeldung.jooq.jointables.public_.tables.Book; + +import org.jooq.Record1; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class BookRecord extends UpdatableRecordImpl { + + private static final long serialVersionUID = 1L; + + /** + * Setter for public.Book.id. + */ + public void setId(Integer value) { + set(0, value); + } + + /** + * Getter for public.Book.id. + */ + public Integer getId() { + return (Integer) get(0); + } + + /** + * Setter for public.Book.author_id. + */ + public void setAuthorId(Integer value) { + set(1, value); + } + + /** + * Getter for public.Book.author_id. + */ + public Integer getAuthorId() { + return (Integer) get(1); + } + + /** + * Setter for public.Book.title. + */ + public void setTitle(String value) { + set(2, value); + } + + /** + * Getter for public.Book.title. + */ + public String getTitle() { + return (String) get(2); + } + + /** + * Setter for public.Book.description. + */ + public void setDescription(String value) { + set(3, value); + } + + /** + * Getter for public.Book.description. + */ + public String getDescription() { + return (String) get(3); + } + + /** + * Setter for public.Book.store_id. + */ + public void setStoreId(Integer value) { + set(4, value); + } + + /** + * Getter for public.Book.store_id. + */ + public Integer getStoreId() { + return (Integer) get(4); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached BookRecord + */ + public BookRecord() { + super(Book.BOOK); + } + + /** + * Create a detached, initialised BookRecord + */ + public BookRecord(Integer id, Integer authorId, String title, String description, Integer storeId) { + super(Book.BOOK); + + setId(id); + setAuthorId(authorId); + setTitle(title); + setDescription(description); + setStoreId(storeId); + resetChangedOnNotNull(); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java new file mode 100644 index 0000000000..0e99b2d93b --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/BookauthorRecord.java @@ -0,0 +1,94 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables.records; + + +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; + +import org.jooq.Record1; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class BookauthorRecord extends UpdatableRecordImpl { + + private static final long serialVersionUID = 1L; + + /** + * Setter for public.BookAuthor.id. + */ + public void setId(Integer value) { + set(0, value); + } + + /** + * Getter for public.BookAuthor.id. + */ + public Integer getId() { + return (Integer) get(0); + } + + /** + * Setter for public.BookAuthor.name. + */ + public void setName(String value) { + set(1, value); + } + + /** + * Getter for public.BookAuthor.name. + */ + public String getName() { + return (String) get(1); + } + + /** + * Setter for public.BookAuthor.country. + */ + public void setCountry(String value) { + set(2, value); + } + + /** + * Getter for public.BookAuthor.country. + */ + public String getCountry() { + return (String) get(2); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached BookauthorRecord + */ + public BookauthorRecord() { + super(Bookauthor.BOOKAUTHOR); + } + + /** + * Create a detached, initialised BookauthorRecord + */ + public BookauthorRecord(Integer id, String name, String country) { + super(Bookauthor.BOOKAUTHOR); + + setId(id); + setName(name); + setCountry(country); + resetChangedOnNotNull(); + } +} diff --git a/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java new file mode 100644 index 0000000000..f8628818e3 --- /dev/null +++ b/persistence-modules/jooq/src/main/java/com/baeldung/jooq/jointables/public_/tables/records/StoreRecord.java @@ -0,0 +1,79 @@ +/* + * This file is generated by jOOQ. + */ +package com.baeldung.jooq.jointables.public_.tables.records; + + +import com.baeldung.jooq.jointables.public_.tables.Store; + +import org.jooq.Record1; +import org.jooq.impl.UpdatableRecordImpl; + + +/** + * This class is generated by jOOQ. + */ +@SuppressWarnings({ "all", "unchecked", "rawtypes", "this-escape" }) +public class StoreRecord extends UpdatableRecordImpl { + + private static final long serialVersionUID = 1L; + + /** + * Setter for public.Store.id. + */ + public void setId(Integer value) { + set(0, value); + } + + /** + * Getter for public.Store.id. + */ + public Integer getId() { + return (Integer) get(0); + } + + /** + * Setter for public.Store.name. + */ + public void setName(String value) { + set(1, value); + } + + /** + * Getter for public.Store.name. + */ + public String getName() { + return (String) get(1); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached StoreRecord + */ + public StoreRecord() { + super(Store.STORE); + } + + /** + * Create a detached, initialised StoreRecord + */ + public StoreRecord(Integer id, String name) { + super(Store.STORE); + + setId(id); + setName(name); + resetChangedOnNotNull(); + } +} diff --git a/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesIntegrationTest.java b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesIntegrationTest.java new file mode 100644 index 0000000000..5396c27e14 --- /dev/null +++ b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesIntegrationTest.java @@ -0,0 +1,111 @@ +package com.baeldung.jooq.jointables; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.sql.Connection; +import java.sql.DriverManager; + +import org.jooq.DSLContext; +import org.jooq.Record; +import org.jooq.Result; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.baeldung.jooq.jointables.public_.Tables; +import com.baeldung.jooq.jointables.public_.tables.Book; +import com.baeldung.jooq.jointables.public_.tables.Bookauthor; +import com.baeldung.jooq.jointables.public_.tables.Store; + +public class JoinTablesIntegrationTest { + + static DSLContext context; + + @BeforeClass + public static void setUp() throws Exception { + // URL jooqConfigURL = getClass().getClassLoader().getResource("jooq-config-2.xml"); + // File file = new File(jooqConfigURL.getFile()); + // GenerationTool.generate(Files.readString(file.toPath())); + + String url = "jdbc:postgresql://localhost:5432/postgres"; + String username = "postgres"; + String password = ""; + + Connection conn = DriverManager.getConnection(url, username, password); + context = DSL.using(conn, SQLDialect.POSTGRES); + + context.insertInto(Tables.STORE, Store.STORE.ID, Store.STORE.NAME) + .values(1, "ABC Branch I ") + .values(2, "ABC Branch II") + .execute(); + + context.insertInto(Tables.BOOK, Book.BOOK.ID, Book.BOOK.TITLE, Book.BOOK.DESCRIPTION, Book.BOOK.AUTHOR_ID, Book.BOOK.STORE_ID) + .values(1, "Book 1", "This is book 1", 1, 1) + .values(2, "Book 2", "This is book 2", 2, 2) + .values(3, "Book 3", "This is book 3", 1, 2) + .values(4, "Book 4", "This is book 4", 5, 1) + .execute(); + + context.insertInto(Tables.BOOKAUTHOR, Bookauthor.BOOKAUTHOR.ID, Bookauthor.BOOKAUTHOR.NAME, Bookauthor.BOOKAUTHOR.COUNTRY) + .values(1, "John Smith", "Japan") + .values(2, "William Walce", "Japan") + .values(3, "Marry Sity", "South Korea") + .values(4, "Morry Toh", "England") + .execute(); + } + + @AfterClass + public static void cleanup() throws Exception { + context.truncateTable(Store.STORE) + .execute(); + context.truncateTable(Book.BOOK) + .execute(); + context.truncateTable(Bookauthor.BOOKAUTHOR) + .execute(); + } + + @Test + public void _whenUsingJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingJoinMethod(context); + assertEquals(3, result.size()); + } + + @Test + public void _whenUsingMultipleJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingMultipleJoinMethod(context); + assertEquals(3, result.size()); + } + + @Test + public void givenContext_whenUsingLeftOuterJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingLeftOuterJoinMethod(context); + assertEquals(4, result.size()); + } + + @Test + public void whenUsingRightOuterJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingRightOuterJoinMethod(context); + assertEquals(5, result.size()); + } + + @Test + public void whenUsingFullOuterJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingFullOuterJoinMethod(context); + assertEquals(6, result.size()); + } + + @Test + public void whenUsingNaturalJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingNaturalJoinMethod(context); + assertEquals(4, result.size()); + } + + @Test + public void whenUsingCrossJoinMethod_thenQueryExecuted() { + Result result = JoinTables.usingCrossJoinMethod(context); + assertEquals(8, result.size()); + } +} diff --git a/persistence-modules/jooq/src/test/resources/jooq-config-2.xml b/persistence-modules/jooq/src/test/resources/jooq-config-2.xml new file mode 100644 index 0000000000..a644e3fef5 --- /dev/null +++ b/persistence-modules/jooq/src/test/resources/jooq-config-2.xml @@ -0,0 +1,19 @@ + + + org.postgresql.Driver + jdbc:postgresql://localhost:5432/postgres + postgres + + + + + org.jooq.meta.postgres.PostgresDatabase + Store|Book|BookAuthor + + + + com.baeldung.jooq.jointables + src/main/java + + + From 4b5e5192d987fa5fac5101b854071edaa59695d6 Mon Sep 17 00:00:00 2001 From: Ulisses Lima Date: Mon, 8 Apr 2024 03:17:59 -0300 Subject: [PATCH 29/57] BAEL 7619 - Intro to the Apache Commons Compress Project (#16220) * matcher.appendReplacement() takes a StringBuffer, not StringBuilder * First draft * review 1 --- libraries-apache-commons-2/pom.xml | 14 +- .../commons/compress/CompressUtils.java | 119 +++++++++++++++ .../convertunicode/UnicodeConverterUtil.java | 6 +- .../compress/CompressUtilsUnitTest.java | 135 ++++++++++++++++++ .../commons/compress/TestResources.java | 25 ++++ .../test/resources/compress/archive.tar.gz | Bin 0 -> 226 bytes .../src/test/resources/compress/new.txt | 2 + 7 files changed, 297 insertions(+), 4 deletions(-) create mode 100644 libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java create mode 100644 libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java create mode 100644 libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java create mode 100644 libraries-apache-commons-2/src/test/resources/compress/archive.tar.gz create mode 100644 libraries-apache-commons-2/src/test/resources/compress/new.txt diff --git a/libraries-apache-commons-2/pom.xml b/libraries-apache-commons-2/pom.xml index c555b83273..0f00bf5d84 100644 --- a/libraries-apache-commons-2/pom.xml +++ b/libraries-apache-commons-2/pom.xml @@ -44,15 +44,27 @@ ${mockftpserver.version} test + + org.tukaani + xz + ${xz.version} + + + com.github.luben + zstd-jni + ${zstd-jni.version} + - 1.23.0 + 1.26.1 1.10.13 2.9.0 1.10.0 3.6 2.7.1 + 1.9 + 1.5.5-11 \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java new file mode 100644 index 0000000000..796b3fd22b --- /dev/null +++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/compress/CompressUtils.java @@ -0,0 +1,119 @@ +package com.baeldung.commons.compress; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.zip.Deflater; +import java.util.zip.ZipEntry; + +import org.apache.commons.compress.archivers.ArchiveEntry; +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.archivers.ArchiveInputStream; +import org.apache.commons.compress.archivers.ArchiveOutputStream; +import org.apache.commons.compress.archivers.ArchiveStreamFactory; +import org.apache.commons.compress.archivers.examples.Archiver; +import org.apache.commons.compress.archivers.examples.Expander; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.compress.compressors.CompressorInputStream; +import org.apache.commons.compress.compressors.CompressorOutputStream; +import org.apache.commons.compress.compressors.CompressorStreamFactory; +import org.apache.commons.compress.utils.FileNameUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; + +public class CompressUtils { + + private CompressUtils() { + } + + public static void archive(Path directory, Path destination) throws IOException, ArchiveException { + String format = FileNameUtils.getExtension(destination); + new Archiver().create(format, destination, directory); + } + + public static void archiveAndCompress(String directory, Path destination) throws IOException, ArchiveException, CompressorException { + archiveAndCompress(Paths.get(directory), destination); + } + + public static void archiveAndCompress(Path directory, Path destination) throws IOException, ArchiveException, CompressorException { + String compressionFormat = FileNameUtils.getExtension(destination); + String archiveFormat = FilenameUtils.getExtension(destination.getFileName() + .toString() + .replace("." + compressionFormat, "")); + + try (OutputStream archive = Files.newOutputStream(destination); + BufferedOutputStream archiveBuffer = new BufferedOutputStream(archive); + CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(compressionFormat, archiveBuffer); + ArchiveOutputStream archiver = new ArchiveStreamFactory().createArchiveOutputStream(archiveFormat, compressor)) { + new Archiver().create(archiver, directory); + } + } + + public static void decompress(Path file, Path destination) throws IOException, ArchiveException, CompressorException { + decompress(Files.newInputStream(file), destination); + } + + public static void decompress(InputStream file, Path destination) throws IOException, ArchiveException, CompressorException { + try (InputStream in = file; + BufferedInputStream inputBuffer = new BufferedInputStream(in); + OutputStream out = Files.newOutputStream(destination); + CompressorInputStream decompressor = new CompressorStreamFactory().createCompressorInputStream(inputBuffer)) { + IOUtils.copy(decompressor, out); + } + } + + public static void extract(Path archive, Path destination) throws IOException, ArchiveException, CompressorException { + new Expander().expand(archive, destination); + } + + public static void compressFile(Path file, Path destination) throws IOException, CompressorException { + String format = FileNameUtils.getExtension(destination); + + try (OutputStream out = Files.newOutputStream(destination); + BufferedOutputStream buffer = new BufferedOutputStream(out); + CompressorOutputStream compressor = new CompressorStreamFactory().createCompressorOutputStream(format, buffer)) { + IOUtils.copy(Files.newInputStream(file), compressor); + } + } + + public static void zip(Path file, Path destination) throws IOException { + try (InputStream input = Files.newInputStream(file); + OutputStream output = Files.newOutputStream(destination); + ZipArchiveOutputStream archive = new ZipArchiveOutputStream(output)) { + archive.setLevel(Deflater.BEST_COMPRESSION); + archive.setMethod(ZipEntry.DEFLATED); + + archive.putArchiveEntry(new ZipArchiveEntry(file.getFileName() + .toString())); + IOUtils.copy(input, archive); + archive.closeArchiveEntry(); + } + } + + public static void extractOne(Path archivePath, String fileName, Path destinationDirectory) throws IOException, ArchiveException { + try (InputStream input = Files.newInputStream(archivePath); + BufferedInputStream buffer = new BufferedInputStream(input); + ArchiveInputStream archive = new ArchiveStreamFactory().createArchiveInputStream(buffer)) { + + ArchiveEntry entry; + while ((entry = archive.getNextEntry()) != null) { + if (entry.getName() + .equals(fileName)) { + Path outFile = destinationDirectory.resolve(fileName); + Files.createDirectories(outFile.getParent()); + try (OutputStream os = Files.newOutputStream(outFile)) { + IOUtils.copy(archive, os); + } + break; + } + } + } + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java index c788f6ee61..997c5b61ff 100644 --- a/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java +++ b/libraries-apache-commons-2/src/main/java/com/baeldung/commons/convertunicode/UnicodeConverterUtil.java @@ -1,10 +1,10 @@ package com.baeldung.commons.convertunicode; -import org.apache.commons.text.StringEscapeUtils; - import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.text.StringEscapeUtils; + public class UnicodeConverterUtil { public static String decodeWithApacheCommons(String input) { @@ -15,7 +15,7 @@ public class UnicodeConverterUtil { Pattern pattern = Pattern.compile("\\\\u[0-9a-fA-F]{4}"); Matcher matcher = pattern.matcher(input); - StringBuilder decodedString = new StringBuilder(); + StringBuffer decodedString = new StringBuffer(); while (matcher.find()) { String unicodeSequence = matcher.group(); diff --git a/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java new file mode 100644 index 0000000000..9bdaf0dfd4 --- /dev/null +++ b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/CompressUtilsUnitTest.java @@ -0,0 +1,135 @@ +package com.baeldung.commons.compress; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.compressors.CompressorException; +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; + +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +class CompressUtilsUnitTest { + + static Path TMP; + static String ZIP_FILE = "new.txt.zip"; + static String COMPRESSED_FILE = "new.txt.gz"; + static String DECOMPRESSED_FILE = "decompressed-file.txt"; + static String DECOMPRESSED_ARCHIVE = "decompressed-archive.tar"; + static String COMPRESSED_ARCHIVE = "archive.tar.gz"; + static String MODIFIED_ARCHIVE = "modified-archive.tar"; + static String EXTRACTED_DIR = "extracted"; + + @BeforeAll + static void setup() throws IOException { + TMP = Files.createTempDirectory("compress-test") + .toAbsolutePath(); + } + + @AfterAll + static void destroy() throws IOException { + FileUtils.deleteDirectory(TMP.toFile()); + } + + @Test + @Order(1) + void givenFile_whenCompressing_thenCompressed() throws IOException, CompressorException, URISyntaxException { + Path destination = TMP.resolve(COMPRESSED_FILE); + + CompressUtils.compressFile(TestResources.testFile(), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(2) + void givenFile_whenZipping_thenZipFileCreated() throws IOException, URISyntaxException { + Path destination = TMP.resolve(ZIP_FILE); + + CompressUtils.zip(TestResources.testFile(), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(3) + void givenCompressedArchive_whenDecompressing_thenArchiveAvailable() throws IOException, ArchiveException, CompressorException { + Path destination = TMP.resolve(DECOMPRESSED_ARCHIVE); + + CompressUtils.decompress(TestResources.compressedArchive(), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(4) + void givenCompressedFile_whenDecompressing_thenFileAvailable() throws IOException, ArchiveException, CompressorException { + Path destination = TMP.resolve(DECOMPRESSED_FILE); + + CompressUtils.decompress(TMP.resolve(COMPRESSED_FILE), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(5) + void givenDecompressedArchive_whenUnarchiving_thenFilesAvailable() throws IOException, ArchiveException, CompressorException { + Path destination = TMP.resolve(EXTRACTED_DIR); + + CompressUtils.extract(TMP.resolve(DECOMPRESSED_ARCHIVE), destination); + + assertTrue(Files.isDirectory(destination)); + } + + @Test + @Order(6) + void givenDirectory_whenArchivingAndCompressing_thenCompressedArchiveAvailable() throws IOException, ArchiveException, CompressorException { + Path destination = TMP.resolve(COMPRESSED_ARCHIVE); + + CompressUtils.archiveAndCompress(TMP.resolve(EXTRACTED_DIR), destination); + + assertTrue(Files.isRegularFile(destination)); + } + + @Test + @Order(7) + void givenExistingArchive_whenAddingSingleEntry_thenArchiveModified() throws IOException, ArchiveException, CompressorException, URISyntaxException { + Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE); + Path newArchive = TMP.resolve(MODIFIED_ARCHIVE); + Path tmpDir = TMP.resolve(newArchive + "-tmpd"); + + Path newEntry = TestResources.testFile(); + + CompressUtils.extract(archive, tmpDir); + assertTrue(Files.isDirectory(tmpDir)); + + Files.copy(newEntry, tmpDir.resolve(newEntry.getFileName())); + CompressUtils.archive(tmpDir, newArchive); + assertTrue(Files.isRegularFile(newArchive)); + + FileUtils.deleteDirectory(tmpDir.toFile()); + Files.delete(archive); + Files.move(newArchive, archive); + assertTrue(Files.isRegularFile(archive)); + } + + @Test + @Order(8) + void givenExistingArchive_whenExtractingSingleEntry_thenFileExtracted() throws IOException, ArchiveException { + Path archive = TMP.resolve(DECOMPRESSED_ARCHIVE); + String targetFile = "sub/other.txt"; + + CompressUtils.extractOne(archive, targetFile, TMP); + + assertTrue(Files.isRegularFile(TMP.resolve(targetFile))); + } +} diff --git a/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java new file mode 100644 index 0000000000..6e1f4129cf --- /dev/null +++ b/libraries-apache-commons-2/src/test/java/com/baeldung/commons/compress/TestResources.java @@ -0,0 +1,25 @@ +package com.baeldung.commons.compress; + +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; + +public interface TestResources { + + String DIR = "/compress/"; + + static InputStream compressedArchive() { + return TestResources.class.getResourceAsStream(DIR + CompressUtilsUnitTest.COMPRESSED_ARCHIVE); + } + + static Path testFile() throws URISyntaxException { + URL resource = TestResources.class.getResource(DIR + "new.txt"); + if (resource == null) { + throw new IllegalArgumentException("file not found!"); + } else { + return Paths.get(resource.toURI()); + } + } +} \ No newline at end of file diff --git a/libraries-apache-commons-2/src/test/resources/compress/archive.tar.gz b/libraries-apache-commons-2/src/test/resources/compress/archive.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..cdb6fd3fd4ba0f771f1bcbaf5ead212d7528db9d GIT binary patch literal 226 zcmV<803H7yiwFP!00000|Lv2}3c@f9Mfbd~$QNj8)9rhvR-JBEn^vb^Zzl{?5MQi< z_Pm5Nf!uPr?5E=_GKhqwQhD1^eWCnOb<3{-4kJ)T`{u5*!Ypg=5$p8K!p!G9$QGr&lC?)Y>6gY~fY^=t!EYmQr3 zm@Z%YcE?~2+Co2Ws`DwIn`QoOt%>*JG`on=zw$EwQV#h?>fZ$sru=_|##r4#y<^{o cjE4@mc2Kq2rMM>&iNr5+0ZH~$y#NjX07EZsH~;_u literal 0 HcmV?d00001 diff --git a/libraries-apache-commons-2/src/test/resources/compress/new.txt b/libraries-apache-commons-2/src/test/resources/compress/new.txt new file mode 100644 index 0000000000..f207b5eb40 --- /dev/null +++ b/libraries-apache-commons-2/src/test/resources/compress/new.txt @@ -0,0 +1,2 @@ +lorem ipsum +dolor sit amet From d8b5d22fa3ec3f12da62acd997df37a2644f4606 Mon Sep 17 00:00:00 2001 From: "Kai.Yuan" Date: Mon, 8 Apr 2024 11:36:50 +0200 Subject: [PATCH 30/57] [improvement-init-Long-list] rename package --- .../ListInitializationUnitTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/{listInitialization => listinitialization}/ListInitializationUnitTest.java (98%) diff --git a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listinitialization/ListInitializationUnitTest.java similarity index 98% rename from core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java rename to core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listinitialization/ListInitializationUnitTest.java index 463e15a41c..4b06621fef 100644 --- a/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listInitialization/ListInitializationUnitTest.java +++ b/core-java-modules/core-java-collections-list-2/src/test/java/com/baeldung/java/listinitialization/ListInitializationUnitTest.java @@ -1,4 +1,4 @@ -package com.baeldung.java.listInitialization; +package com.baeldung.java.listinitialization; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; From 930f1ce0a5f6cbd7367119e91cbf0430a89fd7a5 Mon Sep 17 00:00:00 2001 From: Eugene Kovko <37694937+eukovko@users.noreply.github.com> Date: Mon, 8 Apr 2024 18:17:38 +0200 Subject: [PATCH 31/57] BAEL-6131: Moving REST Docs to a separate package (#16273) * BAEL-6131: Moving REST Docs to a separate package * BAEL-6131: Removed askii-doctor configurations --- spring-5-rest-docs/.gitignore | 12 ++ spring-5-rest-docs/README.md | 8 ++ spring-5-rest-docs/pom.xml | 118 ++++++++++++++++++ .../src/docs/asciidocs/api-guide.adoc | 0 .../baeldung/queryparamdoc/Application.java | 0 .../java/com/baeldung/queryparamdoc/Book.java | 0 .../queryparamdoc/BookController.java | 0 .../baeldung/queryparamdoc/BookService.java | 0 .../com/baeldung/restdocs/CRUDController.java | 0 .../java/com/baeldung/restdocs/CrudInput.java | 0 .../baeldung/restdocs/IndexController.java | 0 .../restdocs/SpringRestDocsApplication.java | 0 .../BookControllerMvcIntegrationTest.java | 0 ...BookControllerReactiveIntegrationTest.java | 0 ...kControllerRestAssuredIntegrationTest.java | 0 ...ApiDocumentationJUnit4IntegrationTest.java | 0 ...ApiDocumentationJUnit5IntegrationTest.java | 0 spring-5/README.md | 2 - spring-5/pom.xml | 25 ---- 19 files changed, 138 insertions(+), 27 deletions(-) create mode 100644 spring-5-rest-docs/.gitignore create mode 100644 spring-5-rest-docs/README.md create mode 100644 spring-5-rest-docs/pom.xml rename {spring-5 => spring-5-rest-docs}/src/docs/asciidocs/api-guide.adoc (100%) rename {spring-5 => spring-5-rest-docs}/src/main/java/com/baeldung/queryparamdoc/Application.java (100%) rename {spring-5 => spring-5-rest-docs}/src/main/java/com/baeldung/queryparamdoc/Book.java (100%) rename {spring-5 => spring-5-rest-docs}/src/main/java/com/baeldung/queryparamdoc/BookController.java (100%) rename {spring-5 => spring-5-rest-docs}/src/main/java/com/baeldung/queryparamdoc/BookService.java (100%) rename {spring-5 => spring-5-rest-docs}/src/main/java/com/baeldung/restdocs/CRUDController.java (100%) rename {spring-5 => spring-5-rest-docs}/src/main/java/com/baeldung/restdocs/CrudInput.java (100%) rename {spring-5 => spring-5-rest-docs}/src/main/java/com/baeldung/restdocs/IndexController.java (100%) rename {spring-5 => spring-5-rest-docs}/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java (100%) rename {spring-5 => spring-5-rest-docs}/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java (100%) rename {spring-5 => spring-5-rest-docs}/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java (100%) rename {spring-5 => spring-5-rest-docs}/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java (100%) rename {spring-5 => spring-5-rest-docs}/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java (100%) rename {spring-5 => spring-5-rest-docs}/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java (100%) diff --git a/spring-5-rest-docs/.gitignore b/spring-5-rest-docs/.gitignore new file mode 100644 index 0000000000..dec013dfa4 --- /dev/null +++ b/spring-5-rest-docs/.gitignore @@ -0,0 +1,12 @@ +#folders# +.idea +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-5-rest-docs/README.md b/spring-5-rest-docs/README.md new file mode 100644 index 0000000000..02c018a07c --- /dev/null +++ b/spring-5-rest-docs/README.md @@ -0,0 +1,8 @@ +## Spring 5 REST Docs + +This module contains articles about Spring 5 + +### Relevant Articles + +- [Introduction to Spring REST Docs](https://www.baeldung.com/spring-rest-docs) +- [Document Query Parameters with Spring REST Docs](https://www.baeldung.com/spring-rest-document-query-parameters) diff --git a/spring-5-rest-docs/pom.xml b/spring-5-rest-docs/pom.xml new file mode 100644 index 0000000000..c1f5dc0681 --- /dev/null +++ b/spring-5-rest-docs/pom.xml @@ -0,0 +1,118 @@ + + + 4.0.0 + spring-5 + 0.0.1-SNAPSHOT + spring-5 + jar + spring 5 sample project about new features + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../parent-boot-3 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-hateoas + + + com.h2database + h2 + runtime + + + org.springframework + spring-test + + + org.springframework.security + spring-security-test + test + + + org.junit.jupiter + junit-jupiter-api + + + + org.springframework.restdocs + spring-restdocs-mockmvc + test + + + org.springframework.restdocs + spring-restdocs-restassured + test + + + org.springframework.restdocs + spring-restdocs-webtestclient + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.Spring5Application + JAR + + + + org.asciidoctor + asciidoctor-maven-plugin + ${asciidoctor-plugin.version} + + + generate-docs + package + + process-asciidoc + + + html + book + + ${snippetsDirectory} + + src/docs/asciidocs + target/generated-docs + + + + + + + + + 2.2.6 + ${project.build.directory}/generated-snippets + true + + + \ No newline at end of file diff --git a/spring-5/src/docs/asciidocs/api-guide.adoc b/spring-5-rest-docs/src/docs/asciidocs/api-guide.adoc similarity index 100% rename from spring-5/src/docs/asciidocs/api-guide.adoc rename to spring-5-rest-docs/src/docs/asciidocs/api-guide.adoc diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/Application.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Application.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/queryparamdoc/Application.java rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Application.java diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/Book.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Book.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/queryparamdoc/Book.java rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/Book.java diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/BookController.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookController.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/queryparamdoc/BookController.java rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookController.java diff --git a/spring-5/src/main/java/com/baeldung/queryparamdoc/BookService.java b/spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookService.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/queryparamdoc/BookService.java rename to spring-5-rest-docs/src/main/java/com/baeldung/queryparamdoc/BookService.java diff --git a/spring-5/src/main/java/com/baeldung/restdocs/CRUDController.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CRUDController.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/restdocs/CRUDController.java rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CRUDController.java diff --git a/spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CrudInput.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/restdocs/CrudInput.java rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/CrudInput.java diff --git a/spring-5/src/main/java/com/baeldung/restdocs/IndexController.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/IndexController.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/restdocs/IndexController.java rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/IndexController.java diff --git a/spring-5/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java b/spring-5-rest-docs/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java similarity index 100% rename from spring-5/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java rename to spring-5-rest-docs/src/main/java/com/baeldung/restdocs/SpringRestDocsApplication.java diff --git a/spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerMvcIntegrationTest.java diff --git a/spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerReactiveIntegrationTest.java diff --git a/spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/queryparamdoc/BookControllerRestAssuredIntegrationTest.java diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit4IntegrationTest.java diff --git a/spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java b/spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java similarity index 100% rename from spring-5/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java rename to spring-5-rest-docs/src/test/java/com/baeldung/restdocs/ApiDocumentationJUnit5IntegrationTest.java diff --git a/spring-5/README.md b/spring-5/README.md index d1487913ac..9af8bdfaf2 100644 --- a/spring-5/README.md +++ b/spring-5/README.md @@ -6,9 +6,7 @@ This module contains articles about Spring 5 - [Spring 5 Functional Bean Registration](https://www.baeldung.com/spring-5-functional-beans) - [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](https://www.baeldung.com/spring-5-junit-config) -- [Introduction to Spring REST Docs](https://www.baeldung.com/spring-rest-docs) - [Spring ResponseStatusException](https://www.baeldung.com/spring-response-status-exception) - [Spring Assert Statements](https://www.baeldung.com/spring-assert) - [Difference between context:annotation-config vs context:component-scan](https://www.baeldung.com/spring-contextannotation-contextcomponentscan) - [Configuring a Hikari Connection Pool with Spring Boot](https://www.baeldung.com/spring-boot-hikari) -- [Document Query Parameters with Spring REST Docs](https://www.baeldung.com/spring-rest-document-query-parameters) diff --git a/spring-5/pom.xml b/spring-5/pom.xml index d66f0fa01f..46c13cd28c 100644 --- a/spring-5/pom.xml +++ b/spring-5/pom.xml @@ -131,36 +131,11 @@ JAR - - org.asciidoctor - asciidoctor-maven-plugin - ${asciidoctor-plugin.version} - - - generate-docs - package - - process-asciidoc - - - html - book - - ${snippetsDirectory} - - src/docs/asciidocs - target/generated-docs - - - - 1.0 - 2.2.6 - ${project.build.directory}/generated-snippets 5.1.0 true 2.0.1 From 1b0b87bfd2a8d880f359de709d6b179148e341e5 Mon Sep 17 00:00:00 2001 From: Mo Helmy <135069400+BenHelmyBen@users.noreply.github.com> Date: Mon, 8 Apr 2024 18:30:28 +0200 Subject: [PATCH 32/57] This commit is related to BAEL-7722 (#16316) This commit aims to add a test class "SymmetricSubstringMaxLengthUnitTest.java" to find length of longest symmetric substring. --- .../SymmetricSubstringMaxLengthUnitTest.java | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java diff --git a/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java new file mode 100644 index 0000000000..2ae37862dd --- /dev/null +++ b/core-java-modules/core-java-string-operations-8/src/test/java/com/baeldung/symmetricsubstringlength/SymmetricSubstringMaxLengthUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.symmetricsubstringlength; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class SymmetricSubstringMaxLengthUnitTest { + String input = "<>>"; + int expected = 4; + + @Test + public void givenString_whenUsingSymmetricSubstringExpansion_thenFindLongestSymmetricSubstring() { + int start = 0; + int mid = 0; + int last_gt = 0; + int end = 0; + int best = 0; + + while (start < input.length()) { + int current = Math.min(mid - start, end - mid); + if (best < current) { + best = current; + } + + if (end - mid == current && end < input.length()) { + if (input.charAt(end) == '?') { + end++; + } else if (input.charAt(end) == '>') { + end++; + last_gt = end; + } else { + end++; + mid = end; + start = Math.max(start, last_gt); + } + } else if (mid < input.length() && input.charAt(mid) == '?') { + mid++; + } else if (start < mid) { + start++; + } else { + start = Math.max(start, last_gt); + mid++; + end = Math.max(mid, end); + } + } + int result = 2 * best; + + assertEquals(expected, result); + } + + @Test + public void givenString_whenUsingBruteForce_thenFindLongestSymmetricSubstring() { + int max = 0; + for (int i = 0; i < input.length(); i++) { + for (int j = i + 1; j <= input.length(); j++) { + String t = input.substring(i, j); + if (t.length() % 2 == 0) { + int k = 0, l = t.length() - 1; + boolean isSym = true; + while (k < l && isSym) { + if (!(t.charAt(k) == '<' || t.charAt(k) == '?') && (t.charAt(l) == '>' || t.charAt(l) == '?')) { + isSym = false; + } + k++; + l--; + } + if (isSym) { + max = Math.max(max, t.length()); + } + } + } + } + + assertEquals(expected, max); + } + +} From 26f3664371dfcc140ba6d85a49a10cb3a9e7628c Mon Sep 17 00:00:00 2001 From: MohamedHelmyKassab <137485958+MohamedHelmyKassab@users.noreply.github.com> Date: Mon, 8 Apr 2024 18:39:32 +0200 Subject: [PATCH 33/57] This commit is related to BAEL-6298 (#16323) This commit aims to add three classes (Example, GenericExample, ReflectionExample). --- .../passclassasparameter/Example.java | 13 +++++++++++ .../passclassasparameter/GenericExample.java | 22 +++++++++++++++++++ .../ReflectionExample.java | 21 ++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java create mode 100644 core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java create mode 100644 core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java new file mode 100644 index 0000000000..0557e032ad --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/Example.java @@ -0,0 +1,13 @@ +package com.baeldung.passclassasparameter; + +public class Example { + public static void processClass(Class clazz) { + System.out.println("Processing class: " + clazz.getName()); + } + + public static void main(String[] args) { + processClass(String.class); + processClass(Integer.class); + processClass(Double.class); + } +} diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java new file mode 100644 index 0000000000..c72d57743c --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/GenericExample.java @@ -0,0 +1,22 @@ +package com.baeldung.passclassasparameter; + +import java.util.ArrayList; +import java.util.List; + +public class GenericExample { + public static void printListElements(Class clazz, List list) { + System.out.println("Elements of " + clazz.getSimpleName() + " list:"); + for (T element : list) { + System.out.println(element); + } + } + + public static void main(String[] args) { + List stringList = new ArrayList<>(); + stringList.add("Java"); + stringList.add("is"); + stringList.add("awesome"); + + printListElements(String.class, stringList); + } +} diff --git a/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java new file mode 100644 index 0000000000..04c9dc3414 --- /dev/null +++ b/core-java-modules/core-java-lang-oop-others/src/main/java/com/baeldung/passclassasparameter/ReflectionExample.java @@ -0,0 +1,21 @@ +package com.baeldung.passclassasparameter; + +import java.lang.reflect.Method; + +public class ReflectionExample { + public static void processClass(Class clazz, String methodName) throws Exception { + Method method = clazz.getMethod(methodName); + Object instance = clazz.getDeclaredConstructor().newInstance(); + method.invoke(instance); + } + + public static void main(String[] args) throws Exception { + processClass(ReflectionTarget.class, "sayHello"); + } +} + +class ReflectionTarget { + public void sayHello() { + System.out.println("Hello, Reflection!"); + } +} \ No newline at end of file From 90cf4fe1ddca4b29aa74d7227c96d2a369dbdb62 Mon Sep 17 00:00:00 2001 From: Diegom203 <153622681+Diegom203@users.noreply.github.com> Date: Mon, 8 Apr 2024 19:39:16 +0200 Subject: [PATCH 34/57] baeldung-articles : BAEL-7500 (#16329) * Update pom.xml Add collections-6 * baeldung-articles : BAEL-7500 Move the article to /core-java-collections-6 --- .../core-java-collections-6/README.md | 5 ++ .../core-java-collections-6/pom.xml | 71 +++++++++++++++++++ .../listiteration/ListIterationUnitTest.java | 71 +++++++++++++++++++ core-java-modules/pom.xml | 1 + 4 files changed, 148 insertions(+) create mode 100644 core-java-modules/core-java-collections-6/README.md create mode 100644 core-java-modules/core-java-collections-6/pom.xml create mode 100644 core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java diff --git a/core-java-modules/core-java-collections-6/README.md b/core-java-modules/core-java-collections-6/README.md new file mode 100644 index 0000000000..b5f1adbf48 --- /dev/null +++ b/core-java-modules/core-java-collections-6/README.md @@ -0,0 +1,5 @@ +========= + +## Core Java Collections Cookbooks and Examples + +### Relevant Articles: diff --git a/core-java-modules/core-java-collections-6/pom.xml b/core-java-modules/core-java-collections-6/pom.xml new file mode 100644 index 0000000000..3d38c3de35 --- /dev/null +++ b/core-java-modules/core-java-collections-6/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + core-java-collections-6 + jar + core-java-collections-6 + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + org.junit.platform + junit-platform-runner + ${junit-platform.version} + test + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + org.junit.vintage + junit-vintage-engine + ${junit.version} + test + + + org.roaringbitmap + RoaringBitmap + ${roaringbitmap.version} + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + + + org.openjdk.jmh + jmh-core + ${jmh.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + + + + 5.9.2 + 0.9.38 + 1.36 + + + diff --git a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java new file mode 100644 index 0000000000..2f1b2cc083 --- /dev/null +++ b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/listiteration/ListIterationUnitTest.java @@ -0,0 +1,71 @@ +package com.baeldung.listiteration; + +import org.junit.jupiter.api.Test; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +public class ListIterationUnitTest { + + List programmingLanguages = new ArrayList<>(List.of("Java", "Python", "C++")); + List numbers = new ArrayList<>(List.of(1, 2, 3)); + + @Test + public void givenStringList_whenAddElementWithListIterator_thenModifiedList() { + ListIterator listIterator = programmingLanguages.listIterator(); + while (listIterator.hasNext()) { + String language = listIterator.next(); + if (language.equals("Python")) { + listIterator.add("JavaScript"); + } + } + + assertIterableEquals(Arrays.asList("Java", "Python", "JavaScript", "C++"), programmingLanguages); + } + + @Test + public void givenNumericalList_whenMultiplyElementWithListIterator_thenModifiedList() { + ListIterator listIterator = numbers.listIterator(); + while (listIterator.hasNext()) { + int num = listIterator.next(); + if (num == 2) { + listIterator.add(num * 10); + } + } + assertIterableEquals(Arrays.asList(1, 2, 20, 3), numbers); + } + + @Test + public void givenStringList_whenAddElementWithEnhancedForLoopAndCopy_thenModifiedList() { + List copyOfWords = new ArrayList<>(programmingLanguages); + for (String word : copyOfWords) { + programmingLanguages.add(word.toUpperCase()); // Modified: Convert to uppercase + } + assertIterableEquals(Arrays.asList("Java", "Python", "C++", "JAVA", "PYTHON", "C++"), programmingLanguages); + } + + @Test + public void givenNumericalList_whenMultiplyElementWithEnhancedForLoopAndCopy_thenModifiedList() { + List copyOfNumbers = new ArrayList<>(numbers); + for (int num : copyOfNumbers) { + numbers.add(num * 2); + } + assertIterableEquals(Arrays.asList(1, 2, 3, 2, 4, 6), numbers); + } + + @Test + public void givenStringList_whenConvertToUpperCaseWithJava8Stream_thenModifiedList() { + programmingLanguages = programmingLanguages.stream().map(String::toUpperCase).collect(Collectors.toList()); + assertIterableEquals(Arrays.asList("JAVA", "PYTHON", "C++"), programmingLanguages); + } + + @Test + public void givenNumericalList_whenMultiplyByThreeWithJava8Stream_thenModifiedList() { + numbers = numbers.stream().map(num -> num * 3).collect(Collectors.toList()); + assertIterableEquals(Arrays.asList(3, 6, 9), numbers); + } + +} diff --git a/core-java-modules/pom.xml b/core-java-modules/pom.xml index bd7aae6410..f6c5f8191a 100644 --- a/core-java-modules/pom.xml +++ b/core-java-modules/pom.xml @@ -89,6 +89,7 @@ core-java-collections-3 core-java-collections-4 core-java-collections-5 + core-java-collections-6 core-java-collections-conversions core-java-collections-set-2 core-java-collections-list From 4fd081e1b446b008808670e2bbcdc03c6eee5400 Mon Sep 17 00:00:00 2001 From: sam-gardner <53271849+sam-gardner@users.noreply.github.com> Date: Mon, 8 Apr 2024 19:27:56 +0100 Subject: [PATCH 35/57] [JAVA-32669] Move article out of core-java-collections-5 (#16327) --- core-java-modules/core-java-collections-5/README.md | 1 - core-java-modules/core-java-collections-5/pom.xml | 4 ++-- .../core-java-collections-conversions-3/README.md | 1 + .../toarraymethod/ConvertingHashSetToArrayUnitTest.java | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename core-java-modules/{core-java-collections-5 => core-java-collections-conversions-3/src/test/java/com/baeldung}/toarraymethod/ConvertingHashSetToArrayUnitTest.java (100%) diff --git a/core-java-modules/core-java-collections-5/README.md b/core-java-modules/core-java-collections-5/README.md index 4f174b5163..2fc7f7c699 100644 --- a/core-java-modules/core-java-collections-5/README.md +++ b/core-java-modules/core-java-collections-5/README.md @@ -9,7 +9,6 @@ - [Skipping the First Iteration in Java](https://www.baeldung.com/java-skip-first-iteration) - [Remove Elements From a Queue Using Loop](https://www.baeldung.com/java-remove-elements-queue) - [Intro to Vector Class in Java](https://www.baeldung.com/java-vector-guide) -- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray) - [Time Complexity of Java Collections Sort in Java](https://www.baeldung.com/java-time-complexity-collections-sort) - [Check if List Contains at Least One Enum](https://www.baeldung.com/java-list-check-enum-presence) - [Comparison of for Loops and Iterators](https://www.baeldung.com/java-for-loops-vs-iterators) diff --git a/core-java-modules/core-java-collections-5/pom.xml b/core-java-modules/core-java-collections-5/pom.xml index 939e479ba1..227b80ac4a 100644 --- a/core-java-modules/core-java-collections-5/pom.xml +++ b/core-java-modules/core-java-collections-5/pom.xml @@ -55,8 +55,8 @@ org.apache.maven.plugins maven-compiler-plugin - 9 - 9 + 16 + 16 diff --git a/core-java-modules/core-java-collections-conversions-3/README.md b/core-java-modules/core-java-collections-conversions-3/README.md index 959e4e8160..96727e8d88 100644 --- a/core-java-modules/core-java-collections-conversions-3/README.md +++ b/core-java-modules/core-java-collections-conversions-3/README.md @@ -5,3 +5,4 @@ This module contains articles about conversions among Collection types in Java. ### Relevant Articles: - [Converting HashMap Values to an ArrayList in Java](https://www.baeldung.com/java-hashmap-arraylist) - [Joining a List in Java With Commas and “and”](https://www.baeldung.com/java-string-concatenation-natural-language) +- [HashSet toArray() Method in Java](https://www.baeldung.com/java-hashset-toarray) diff --git a/core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java b/core-java-modules/core-java-collections-conversions-3/src/test/java/com/baeldung/toarraymethod/ConvertingHashSetToArrayUnitTest.java similarity index 100% rename from core-java-modules/core-java-collections-5/toarraymethod/ConvertingHashSetToArrayUnitTest.java rename to core-java-modules/core-java-collections-conversions-3/src/test/java/com/baeldung/toarraymethod/ConvertingHashSetToArrayUnitTest.java From cc406d88991b645abea2f782716042bc4b21ef73 Mon Sep 17 00:00:00 2001 From: sam-gardner <53271849+sam-gardner@users.noreply.github.com> Date: Mon, 8 Apr 2024 19:36:19 +0100 Subject: [PATCH 36/57] [JAVA-32662] Move articles from Java Math 3 to Java Math 4 (#16326) --- core-java-modules/core-java-lang-math-3/README.md | 4 ---- core-java-modules/core-java-lang-math-4/README.md | 4 ++++ core-java-modules/core-java-lang-math-4/pom.xml | 4 ++++ .../java/com/baeldung/math/bmicalculator/BMICalculator.java | 0 .../math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java | 0 .../java/com/baeldung/math/rodcutting/RodCuttingProblem.java | 0 .../java/com/baeldung/math/rotatevertex/VertexRotation.java | 0 .../baeldung/math/bmicalculator/BMICalculatorUnitTest.java | 0 .../PointLiesBetweenTwoPointsUnitTest.java | 0 .../baeldung/math/rodcutting/RodCuttingProblemUnitTest.java | 0 .../baeldung/math/rotatevertex/VertexRotationUnitTest.java | 0 11 files changed, 8 insertions(+), 4 deletions(-) rename core-java-modules/{core-java-lang-math-3 => core-java-lang-math-4}/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java (100%) rename core-java-modules/{core-java-lang-math-3 => core-java-lang-math-4}/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java (100%) rename core-java-modules/{core-java-lang-math-3 => core-java-lang-math-4}/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java (100%) rename core-java-modules/{core-java-lang-math-3 => core-java-lang-math-4}/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java (100%) rename core-java-modules/{core-java-lang-math-3 => core-java-lang-math-4}/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java (100%) rename core-java-modules/{core-java-lang-math-3 => core-java-lang-math-4}/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java (100%) rename core-java-modules/{core-java-lang-math-3 => core-java-lang-math-4}/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java (100%) rename core-java-modules/{core-java-lang-math-3 => core-java-lang-math-4}/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java (100%) diff --git a/core-java-modules/core-java-lang-math-3/README.md b/core-java-modules/core-java-lang-math-3/README.md index d4eef0f1b9..473369beef 100644 --- a/core-java-modules/core-java-lang-math-3/README.md +++ b/core-java-modules/core-java-lang-math-3/README.md @@ -7,15 +7,11 @@ - [Evaluating a Math Expression in Java](https://www.baeldung.com/java-evaluate-math-expression-string) - [Swap Two Variables in Java](https://www.baeldung.com/java-swap-two-variables) - [Java Program to Find the Roots of a Quadratic Equation](https://www.baeldung.com/roots-quadratic-equation) -- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator) - [Java Program to Calculate the Standard Deviation](https://www.baeldung.com/java-calculate-standard-deviation) - [Java Program to Print Pascal’s Triangle](https://www.baeldung.com/java-pascal-triangle) - [Java Money and the Currency API](http://www.baeldung.com/java-money-and-currency) - [Clamp Function in Java](https://www.baeldung.com/java-clamp-function) - [Creating a Magic Square in Java](https://www.baeldung.com/java-magic-square) -- [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line) - [Validate if a String Is a Valid Geo Coordinate](https://www.baeldung.com/java-geo-coordinates-validation) -- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point) - [Calculating the Power of Any Number in Java Without Using Math pow() Method](https://www.baeldung.com/java-calculating-the-power-without-math-pow) -- [Solving Rod Cutting Problem in Java](https://www.baeldung.com/java-rod-cutting-problem) - More articles: [[<-- Prev]](/core-java-modules/core-java-lang-math-2) diff --git a/core-java-modules/core-java-lang-math-4/README.md b/core-java-modules/core-java-lang-math-4/README.md index 377c51848d..0efe87f7ff 100644 --- a/core-java-modules/core-java-lang-math-4/README.md +++ b/core-java-modules/core-java-lang-math-4/README.md @@ -2,3 +2,7 @@ ### Relevant articles: - [Calculate Percentiles in Java](https://www.baeldung.com/java-compute-percentiles) +- [Solving Rod Cutting Problem in Java](https://www.baeldung.com/java-rod-cutting-problem) +- [Rotate a Vertex Around a Certain Point in Java](https://www.baeldung.com/java-rotate-vertex-around-point) +- [Create a BMI Calculator in Java](https://www.baeldung.com/java-body-mass-index-calculator) +- [Check if a Point Is Between Two Points Drawn on a Straight Line in Java](https://www.baeldung.com/java-check-point-straight-line) diff --git a/core-java-modules/core-java-lang-math-4/pom.xml b/core-java-modules/core-java-lang-math-4/pom.xml index e818855d36..ccafb4a894 100644 --- a/core-java-modules/core-java-lang-math-4/pom.xml +++ b/core-java-modules/core-java-lang-math-4/pom.xml @@ -12,4 +12,8 @@ 0.0.1-SNAPSHOT + + 17 + + diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/bmicalculator/BMICalculator.java diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPoints.java diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rodcutting/RodCuttingProblem.java diff --git a/core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java b/core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java rename to core-java-modules/core-java-lang-math-4/src/main/java/com/baeldung/math/rotatevertex/VertexRotation.java diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/bmicalculator/BMICalculatorUnitTest.java diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/pointbetweentwopoints/PointLiesBetweenTwoPointsUnitTest.java diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rodcutting/RodCuttingProblemUnitTest.java diff --git a/core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java b/core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java similarity index 100% rename from core-java-modules/core-java-lang-math-3/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java rename to core-java-modules/core-java-lang-math-4/src/test/java/com/baeldung/math/rotatevertex/VertexRotationUnitTest.java From c3939b1850aab727ae84f2953dffc65d9e0714c0 Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Mon, 8 Apr 2024 23:54:14 +0300 Subject: [PATCH 37/57] [JAVA-32833] (#16265) * [JAVA-32833] * [JAVA-32833] Fixed configuration --- .../jpa/simple/config/PersistenceConfig.java | 2 +- .../baeldung/jpa/simple/{entity => model}/Book.java | 2 +- .../baeldung/jpa/simple/{entity => model}/Foo.java | 2 +- .../baeldung/jpa/simple/{entity => model}/User.java | 2 +- .../jpa/simple/repository/BookListRepository.java | 2 +- .../repository/BookPagingAndSortingRepository.java | 2 +- .../com/baeldung/jpa/simple/repository/IFooDAO.java | 2 +- .../jpa/simple/repository/UserRepository.java | 2 +- .../jpa/simple/repository/UserRepositoryCustom.java | 2 +- .../simple/repository/UserRepositoryCustomImpl.java | 2 +- .../com/baeldung/jpa/simple/service/FooService.java | 2 +- .../com/baeldung/jpa/simple/service/IFooService.java | 2 +- .../simple/BookListRepositoryIntegrationTest.java | 7 ++++--- ...ookPagingAndSortingRepositoryIntegrationTest.java | 12 +++++++----- .../jpa/simple/FooServiceIntegrationTest.java | 2 +- .../jpa/simple/UserRepositoryIntegrationTest.java | 2 +- 16 files changed, 25 insertions(+), 22 deletions(-) rename persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/{entity => model}/Book.java (96%) rename persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/{entity => model}/Foo.java (97%) rename persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/{entity => model}/User.java (97%) diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/config/PersistenceConfig.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/config/PersistenceConfig.java index 36a1fa9389..b142933240 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/config/PersistenceConfig.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/config/PersistenceConfig.java @@ -32,7 +32,7 @@ public class PersistenceConfig { public LocalContainerEntityManagerFactoryBean entityManagerFactory() { final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); - em.setPackagesToScan("com.baeldung.jpa.simple.entity"); + em.setPackagesToScan("com.baeldung.jpa.simple.model"); final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Book.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Book.java similarity index 96% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Book.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Book.java index 0e01e983b5..30e9003b2f 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Book.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Book.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.simple.entity; +package com.baeldung.jpa.simple.model; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Foo.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Foo.java similarity index 97% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Foo.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Foo.java index bf82ab61f7..5cabacf389 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/Foo.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/Foo.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.simple.entity; +package com.baeldung.jpa.simple.model; import java.io.Serializable; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/User.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/User.java similarity index 97% rename from persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/User.java rename to persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/User.java index 07759af0fb..f9a2db8437 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/entity/User.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/model/User.java @@ -1,4 +1,4 @@ -package com.baeldung.jpa.simple.entity; +package com.baeldung.jpa.simple.model; import java.time.ZonedDateTime; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookListRepository.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookListRepository.java index e1540c64bf..e7a781defd 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookListRepository.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookListRepository.java @@ -5,7 +5,7 @@ import java.util.List; import org.springframework.data.repository.ListCrudRepository; import org.springframework.stereotype.Repository; -import com.baeldung.jpa.simple.entity.Book; +import com.baeldung.jpa.simple.model.Book; @Repository public interface BookListRepository extends ListCrudRepository { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookPagingAndSortingRepository.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookPagingAndSortingRepository.java index cb519ed5ea..b802406c1b 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookPagingAndSortingRepository.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/BookPagingAndSortingRepository.java @@ -7,7 +7,7 @@ import org.springframework.data.repository.ListCrudRepository; import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository; -import com.baeldung.jpa.simple.entity.Book; +import com.baeldung.jpa.simple.model.Book; @Repository public interface BookPagingAndSortingRepository extends PagingAndSortingRepository, ListCrudRepository { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/IFooDAO.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/IFooDAO.java index d6d1d46122..20123c73cd 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/IFooDAO.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/IFooDAO.java @@ -4,7 +4,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import com.baeldung.jpa.simple.entity.Foo; +import com.baeldung.jpa.simple.model.Foo; public interface IFooDAO extends JpaRepository { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepository.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepository.java index cc13aac5db..368a0bcb5b 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepository.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepository.java @@ -6,7 +6,7 @@ import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -import com.baeldung.jpa.simple.entity.User; +import com.baeldung.jpa.simple.model.User; public interface UserRepository extends JpaRepository, UserRepositoryCustom { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustom.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustom.java index 8584f3f3bb..e4e1a3e73b 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustom.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustom.java @@ -5,7 +5,7 @@ import java.util.List; import java.util.Set; import java.util.function.Predicate; -import com.baeldung.jpa.simple.entity.User; +import com.baeldung.jpa.simple.model.User; public interface UserRepositoryCustom { diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustomImpl.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustomImpl.java index b60ca65d0a..b702735b97 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustomImpl.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/repository/UserRepositoryCustomImpl.java @@ -7,7 +7,7 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.baeldung.jpa.simple.entity.User; +import com.baeldung.jpa.simple.model.User; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/FooService.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/FooService.java index f02c1eebad..93d405c689 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/FooService.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/FooService.java @@ -3,7 +3,7 @@ package com.baeldung.jpa.simple.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.baeldung.jpa.simple.entity.Foo; +import com.baeldung.jpa.simple.model.Foo; import com.baeldung.jpa.simple.repository.IFooDAO; @Service diff --git a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/IFooService.java b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/IFooService.java index 4fc56bde87..f2950b81fb 100644 --- a/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/IFooService.java +++ b/persistence-modules/spring-data-jpa-simple/src/main/java/com/baeldung/jpa/simple/service/IFooService.java @@ -1,6 +1,6 @@ package com.baeldung.jpa.simple.service; -import com.baeldung.jpa.simple.entity.Foo; +import com.baeldung.jpa.simple.model.Foo; public interface IFooService { Foo create(Foo foo); diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookListRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookListRepositoryIntegrationTest.java index ec2ada1e52..f393e305bc 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookListRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookListRepositoryIntegrationTest.java @@ -1,14 +1,15 @@ package com.baeldung.jpa.simple; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.util.Arrays; import java.util.List; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import com.baeldung.jpa.simple.entity.Book; +import com.baeldung.jpa.simple.model.Book; import com.baeldung.jpa.simple.repository.BookListRepository; @SpringBootTest(classes = JpaApplication.class) @@ -25,6 +26,6 @@ class BookListRepositoryIntegrationTest { bookListRepository.saveAll(Arrays.asList(book1, book2, book3)); List books = bookListRepository.findBooksByAuthor("John Doe"); - Assertions.assertEquals(3, books.size()); + assertEquals(3, books.size()); } } \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookPagingAndSortingRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookPagingAndSortingRepositoryIntegrationTest.java index d5c8c1bca0..390308b5ba 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookPagingAndSortingRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/BookPagingAndSortingRepositoryIntegrationTest.java @@ -1,9 +1,11 @@ package com.baeldung.jpa.simple; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.util.Arrays; import java.util.List; -import org.junit.jupiter.api.Assertions; + import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -11,7 +13,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import com.baeldung.jpa.simple.entity.Book; +import com.baeldung.jpa.simple.model.Book; import com.baeldung.jpa.simple.repository.BookPagingAndSortingRepository; @SpringBootTest @@ -29,8 +31,8 @@ class BookPagingAndSortingRepositoryIntegrationTest { Pageable pageable = PageRequest.of(0, 2, Sort.by("title").descending()); List books = bookPagingAndSortingRepository.findBooksByAuthor("John Miller", pageable); - Assertions.assertEquals(2, books.size()); - Assertions.assertEquals(book3.getId(), books.get(0).getId()); - Assertions.assertEquals(book2.getId(), books.get(1).getId()); + assertEquals(2, books.size()); + assertEquals(book3.getId(), books.get(0).getId()); + assertEquals(book2.getId(), books.get(1).getId()); } } \ No newline at end of file diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/FooServiceIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/FooServiceIntegrationTest.java index 7e2dd98ada..d4a4c2a2f7 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/FooServiceIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/FooServiceIntegrationTest.java @@ -10,7 +10,7 @@ import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.jpa.simple.entity.Foo; +import com.baeldung.jpa.simple.model.Foo; import com.baeldung.jpa.simple.service.IFooService; @RunWith(SpringRunner.class) diff --git a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/UserRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/UserRepositoryIntegrationTest.java index 37afc90b59..c690d601e2 100644 --- a/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/UserRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-simple/src/test/java/com/baeldung/jpa/simple/UserRepositoryIntegrationTest.java @@ -14,7 +14,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit.jupiter.SpringExtension; -import com.baeldung.jpa.simple.entity.User; +import com.baeldung.jpa.simple.model.User; import com.baeldung.jpa.simple.repository.UserRepository; @ExtendWith(SpringExtension.class) From 84d52773590ccfebf81c1398ad0ae5cc5bb3f641 Mon Sep 17 00:00:00 2001 From: sam-gardner <53271849+sam-gardner@users.noreply.github.com> Date: Tue, 9 Apr 2024 07:22:57 +0100 Subject: [PATCH 38/57] [JAVA-27821] Upgrade Azure to Spring Boot 3 (#16304) --- azure/pom.xml | 14 +++++++++++--- .../java/com/baeldung/springboot/azure/User.java | 8 ++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/azure/pom.xml b/azure/pom.xml index 61ae0c7d68..52d7fa4864 100644 --- a/azure/pom.xml +++ b/azure/pom.xml @@ -11,9 +11,9 @@ com.baeldung - parent-boot-2 + parent-boot-3 0.0.1-SNAPSHOT - ../parent-boot-2 + ../parent-boot-3 @@ -98,7 +98,7 @@ spring.datasource.password - + test @@ -113,6 +113,14 @@ + + + + javax.xml.bind + jaxb-api + 2.4.0-b180830.0359 + + diff --git a/azure/src/main/java/com/baeldung/springboot/azure/User.java b/azure/src/main/java/com/baeldung/springboot/azure/User.java index d7a25aa246..1e7954d9b0 100644 --- a/azure/src/main/java/com/baeldung/springboot/azure/User.java +++ b/azure/src/main/java/com/baeldung/springboot/azure/User.java @@ -1,9 +1,9 @@ package com.baeldung.springboot.azure; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; /** * @author aiet From eead7a451cf424e21c46228f2c605b479fc778b6 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Tue, 9 Apr 2024 08:35:21 +0200 Subject: [PATCH 39/57] [JAVA-32874] Fix Errors related to Maven upgrade (#16331) --- image-processing/pom.xml | 7 +++++++ maven-modules/maven-plugins/jaxws/pom.xml | 8 ++++++-- microservices-modules/msf4j/pom.xml | 9 ++++++++- web-modules/jee-7/pom.xml | 7 +++++++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/image-processing/pom.xml b/image-processing/pom.xml index 5c59a53337..b40c56e539 100644 --- a/image-processing/pom.xml +++ b/image-processing/pom.xml @@ -12,6 +12,13 @@ 1.0.0-SNAPSHOT + + + maven + https://maven.openimaj.org/ + + + net.imagej diff --git a/maven-modules/maven-plugins/jaxws/pom.xml b/maven-modules/maven-plugins/jaxws/pom.xml index f17d70c182..a30fca8c87 100644 --- a/maven-modules/maven-plugins/jaxws/pom.xml +++ b/maven-modules/maven-plugins/jaxws/pom.xml @@ -36,7 +36,7 @@ com.sun.xml.ws jaxws-ri - 2.3.0 + ${jaxws.version} pom @@ -46,7 +46,7 @@ com.sun.xml.ws jaxws-maven-plugin - 4.0.1 + ${jaxws.version} @@ -73,4 +73,8 @@ + + 4.0.2 + + \ No newline at end of file diff --git a/microservices-modules/msf4j/pom.xml b/microservices-modules/msf4j/pom.xml index 642795e5fe..6d6315903b 100644 --- a/microservices-modules/msf4j/pom.xml +++ b/microservices-modules/msf4j/pom.xml @@ -14,6 +14,13 @@ 1.0.0-SNAPSHOT + + + wso2-https + https://maven.wso2.org/nexus/content/groups/wso2-public/ + + + @@ -40,7 +47,7 @@ com.baeldung.msf4j.msf4jintro.Application - 2.6.3 + 2.8.11 \ No newline at end of file diff --git a/web-modules/jee-7/pom.xml b/web-modules/jee-7/pom.xml index b26027d9bf..47d79f12ac 100644 --- a/web-modules/jee-7/pom.xml +++ b/web-modules/jee-7/pom.xml @@ -16,6 +16,13 @@ 1.0.0-SNAPSHOT + + + jboss-https + https://repository.jboss.org/nexus/content/groups/public/ + + + From e4c43225b93bed075d5edca626351b9bc372a9d4 Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Tue, 9 Apr 2024 07:59:09 +0100 Subject: [PATCH 40/57] BAEL-7335: Polymorphism with Gson (#16320) --- .../com/baeldung/gson/polymorphic/Shape.java | 5 + .../gson/polymorphic/ShapeTypeAdapter.java | 27 ++++ .../gson/polymorphic/TypeAdapterUnitTest.java | 117 ++++++++++++++ .../gson/polymorphic/TypeFieldUnitTest.java | 67 ++++++++ .../gson/polymorphic/WrapperUnitTest.java | 148 ++++++++++++++++++ 5 files changed, 364 insertions(+) create mode 100644 json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java create mode 100644 json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java create mode 100644 json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java create mode 100644 json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java create mode 100644 json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java new file mode 100644 index 0000000000..b5d32a529b --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/Shape.java @@ -0,0 +1,5 @@ +package com.baeldung.gson.polymorphic; + +public interface Shape { + double getArea(); +} diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java new file mode 100644 index 0000000000..cbdff9c6be --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/ShapeTypeAdapter.java @@ -0,0 +1,27 @@ +package com.baeldung.gson.polymorphic; + +import com.google.gson.*; + +import java.lang.reflect.Type; + +public class ShapeTypeAdapter implements JsonSerializer, JsonDeserializer { + @Override + public JsonElement serialize(Shape shape, Type type, JsonSerializationContext context) { + JsonElement elem = new Gson().toJsonTree(shape); + elem.getAsJsonObject().addProperty("type", shape.getClass().getName()); + return elem; + } + + @Override + public Shape deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + JsonObject jsonObject = json.getAsJsonObject(); + String typeName = jsonObject.get("type").getAsString(); + + try { + Class cls = (Class) Class.forName(typeName); + return new Gson().fromJson(json, cls); + } catch (ClassNotFoundException e) { + throw new JsonParseException(e); + } + } +} diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java new file mode 100644 index 0000000000..81d5f5a9f2 --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeAdapterUnitTest.java @@ -0,0 +1,117 @@ +package com.baeldung.gson.polymorphic; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TypeAdapterUnitTest { + @Test + void testSerialize() { + List shapes = Arrays.asList( + new Circle(4d), + new Square(5d) + ); + + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeHierarchyAdapter(Shape.class, new ShapeTypeAdapter()); + Gson gson = builder.create(); + + String json = gson.toJson(shapes); + + assertEquals("[" + + "{" + + "\"radius\":4.0," + + "\"area\":50.26548245743669," + + "\"type\":\"com.baeldung.gson.polymorphic.TypeAdapterUnitTest$Circle\"" + + "},{" + + "\"side\":5.0," + + "\"area\":25.0," + + "\"type\":\"com.baeldung.gson.polymorphic.TypeAdapterUnitTest$Square\"" + + "}]", json); + } + + + @Test + void testDeserializeWrapper() { + List shapes = Arrays.asList( + new Circle(4d), + new Square(5d) + ); + + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeHierarchyAdapter(Shape.class, new ShapeTypeAdapter()); + Gson gson = builder.create(); + + String json = gson.toJson(shapes); + + Type collectionType = new TypeToken>(){}.getType(); + List result = gson.fromJson(json, collectionType); + + assertEquals(shapes, result); + } + + private static class Square implements Shape { + private final double side; + private final double area; + + public Square(double side) { + this.side = side; + this.area = side * side; + } + + @Override + public double getArea() { + return area; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Square square = (Square) o; + return Double.compare(square.side, side) == 0 && Double.compare(square.area, area) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(side, area); + } + } + + private static class Circle implements Shape { + private final double radius; + + private final double area; + + public Circle(double radius) { + this.radius = radius; + this.area = Math.PI * radius * radius; + } + + @Override + public double getArea() { + return area; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Circle circle = (Circle) o; + return Double.compare(circle.radius, radius) == 0 && Double.compare(circle.area, area) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(radius, area); + } + } +} diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java new file mode 100644 index 0000000000..e6917b2065 --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/TypeFieldUnitTest.java @@ -0,0 +1,67 @@ +package com.baeldung.gson.polymorphic; + +import com.google.gson.Gson; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TypeFieldUnitTest { + @Test + void testSerialize() { + List shapes = Arrays.asList( + new Circle(4d), + new Square(5d) + ); + + Gson gson = new Gson(); + String json = gson.toJson(shapes); + + assertEquals("[" + + "{" + + "\"type\":\"circle\"," + + "\"radius\":4.0," + + "\"area\":50.26548245743669" + + "},{" + + "\"type\":\"square\"," + + "\"side\":5.0," + + "\"area\":25.0" + + "}]", json); + } + + private static class Square implements Shape { + private final String type = "square"; + private final double side; + private final double area; + + public Square(double side) { + this.side = side; + this.area = side * side; + } + + @Override + public double getArea() { + return area; + } + } + + private static class Circle implements Shape { + private final String type = "circle"; + private final double radius; + + private final double area; + + public Circle(double radius) { + this.radius = radius; + this.area = Math.PI * radius * radius; + } + + @Override + public double getArea() { + return area; + } + } + +} diff --git a/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java new file mode 100644 index 0000000000..841f9c64d5 --- /dev/null +++ b/json-modules/gson-2/src/test/java/com/baeldung/gson/polymorphic/WrapperUnitTest.java @@ -0,0 +1,148 @@ +package com.baeldung.gson.polymorphic; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class WrapperUnitTest { + @Test + void testSerializeWrapper() { + List shapes = Arrays.asList( + new Wrapper(new Circle(4d)), + new Wrapper(new Square(5d)) + ); + + Gson gson = new Gson(); + String json = gson.toJson(shapes); + + assertEquals("[" + + "{" + + "\"circle\":{" + + "\"radius\":4.0," + + "\"area\":50.26548245743669" + + "}" + + "},{" + + "\"square\":{" + + "\"side\":5.0," + + "\"area\":25.0" + + "}" + + "}]", json); + } + + @Test + void testDeserializeWrapper() { + List shapes = Arrays.asList( + new Wrapper(new Circle(4d)), + new Wrapper(new Square(5d)) + ); + + Gson gson = new Gson(); + String json = gson.toJson(shapes); + + Type collectionType = new TypeToken>(){}.getType(); + List result = gson.fromJson(json, collectionType); + + assertEquals(shapes, result); + } + + private static class Square implements Shape { + private final double side; + private final double area; + + public Square(double side) { + this.side = side; + this.area = side * side; + } + + @Override + public double getArea() { + return area; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Square square = (Square) o; + return Double.compare(square.side, side) == 0 && Double.compare(square.area, area) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(side, area); + } + } + + private static class Circle implements Shape { + private final double radius; + + private final double area; + + public Circle(double radius) { + this.radius = radius; + this.area = Math.PI * radius * radius; + } + + @Override + public double getArea() { + return area; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Circle circle = (Circle) o; + return Double.compare(circle.radius, radius) == 0 && Double.compare(circle.area, area) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(radius, area); + } + } + + private static class Wrapper { + private final Circle circle; + private final Square square; + + public Wrapper(Circle circle) { + this.circle = circle; + this.square = null; + } + + public Wrapper(Square square) { + this.square = square; + this.circle = null; + } + + public Circle getCircle() { + return circle; + } + + public Square getSquare() { + return square; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Wrapper wrapper = (Wrapper) o; + return Objects.equals(circle, wrapper.circle) && Objects.equals(square, wrapper.square); + } + + @Override + public int hashCode() { + return Objects.hash(circle, square); + } + } + +} From 27e451cd97d6382d0d0e0f1a5c60dc864dd38b68 Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Tue, 9 Apr 2024 19:23:47 +0300 Subject: [PATCH 41/57] Update README.md --- core-java-modules/core-java-io-apis/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/core-java-modules/core-java-io-apis/README.md b/core-java-modules/core-java-io-apis/README.md index ee8547f0c5..faf7067f74 100644 --- a/core-java-modules/core-java-io-apis/README.md +++ b/core-java-modules/core-java-io-apis/README.md @@ -13,4 +13,3 @@ This module contains articles about core Java input/output(IO) APIs. - [Difference Between FileReader and BufferedReader in Java](https://www.baeldung.com/java-filereader-vs-bufferedreader) - [Read Multiple Inputs on the Same Line in Java](https://www.baeldung.com/java-read-multiple-inputs-same-line) - [Write Console Output to Text File in Java](https://www.baeldung.com/java-write-console-output-file) -- [Java InputStream vs. InputStreamReader](https://www.baeldung.com/java-inputstream-vs-inputstreamreader) From 9dc160cccaadee34f90e1fb5d46f6099e0d8ab2b Mon Sep 17 00:00:00 2001 From: Loredana Crusoveanu Date: Tue, 9 Apr 2024 19:24:00 +0300 Subject: [PATCH 42/57] Update README.md --- core-java-modules/core-java-io-apis-2/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/core-java-modules/core-java-io-apis-2/README.md b/core-java-modules/core-java-io-apis-2/README.md index 2b08736a11..c8472f088e 100644 --- a/core-java-modules/core-java-io-apis-2/README.md +++ b/core-java-modules/core-java-io-apis-2/README.md @@ -12,3 +12,4 @@ This module contains articles about core Java input/output(IO) APIs. - [Read Input Character-by-Character in Java](https://www.baeldung.com/java-read-input-character) - [Difference Between flush() and close() in Java FileWriter](https://www.baeldung.com/java-filewriter-flush-vs-close) - [Get a Path to a Resource in a Java JAR File](https://www.baeldung.com/java-get-path-resource-jar) +- [Java InputStream vs. InputStreamReader](https://www.baeldung.com/java-inputstream-vs-inputstreamreader) From eea7bccf8657e4feaf2814c94667f5eb0b7e09d9 Mon Sep 17 00:00:00 2001 From: vunamtien Date: Wed, 10 Apr 2024 04:16:14 +0700 Subject: [PATCH 43/57] [JAVA-31831] Split-or-move-core-java-8-datetime-2 (#16325) --- .../core-java-8-datetime-2/README.md | 7 +- .../core-java-8-datetime-3/README.md | 8 ++ .../core-java-8-datetime-3/pom.xml | 55 ++++++++++++ .../DateRangeOverlapChecker.java | 6 +- .../localdatetoiso/LocalDateToISO.java | 14 ++- .../MonthInterval.java | 0 .../CheckIfTimeBetweenTwoTimesUnitTest.java | 88 +++++++++---------- .../DateRangeOverlapCheckerUnitTest.java | 8 +- .../LocalDateToISOUnitTest.java | 16 ++-- .../MonthIntervalUnitTest.java | 0 .../ZoneOffSetAndZoneIdOfUnitTest.java | 50 +++++------ 11 files changed, 154 insertions(+), 98 deletions(-) create mode 100644 core-java-modules/core-java-8-datetime-3/README.md create mode 100644 core-java-modules/core-java-8-datetime-3/pom.xml rename core-java-modules/{core-java-8-datetime-2 => core-java-8-datetime-3}/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java (100%) rename core-java-modules/{core-java-8-datetime-2 => core-java-8-datetime-3}/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java (92%) rename core-java-modules/{core-java-8-datetime-2 => core-java-8-datetime-3}/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java (100%) rename core-java-modules/{core-java-8-datetime-2 => core-java-8-datetime-3}/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java (97%) rename core-java-modules/{core-java-8-datetime-2 => core-java-8-datetime-3}/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java (100%) rename core-java-modules/{core-java-8-datetime-2 => core-java-8-datetime-3}/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java (81%) rename core-java-modules/{core-java-8-datetime-2 => core-java-8-datetime-3}/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java (100%) rename core-java-modules/{core-java-8-datetime-2 => core-java-8-datetime-3}/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java (96%) diff --git a/core-java-modules/core-java-8-datetime-2/README.md b/core-java-modules/core-java-8-datetime-2/README.md index 04461663e3..29ceaf29e1 100644 --- a/core-java-modules/core-java-8-datetime-2/README.md +++ b/core-java-modules/core-java-8-datetime-2/README.md @@ -9,9 +9,4 @@ - [Round the Date in Java](https://www.baeldung.com/java-round-the-date) - [Representing Furthest Possible Date in Java](https://www.baeldung.com/java-date-represent-max) - [Retrieving Unix Time in Java](https://www.baeldung.com/java-retrieve-unix-time) -- [Calculate Months Between Two Dates in Java](https://www.baeldung.com/java-months-difference-two-dates) -- [Format LocalDate to ISO 8601 With T and Z](https://www.baeldung.com/java-format-localdate-iso-8601-t-z) -- [Check if Two Date Ranges Overlap](https://www.baeldung.com/java-check-two-date-ranges-overlap) -- [Difference between ZoneOffset.UTC and ZoneId.of(“UTC”)](https://www.baeldung.com/java-zoneoffset-utc-zoneid-of) -- [Check if a Given Time Lies Between Two Times Regardless of Date](https://www.baeldung.com/java-check-between-two-times) -- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) +- [[<-- Prev]](/core-java-modules/core-java-datetime-java8-1) [[Next -->]](/core-java-modules/core-java-8-datetime-3) diff --git a/core-java-modules/core-java-8-datetime-3/README.md b/core-java-modules/core-java-8-datetime-3/README.md new file mode 100644 index 0000000000..d320466814 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-3/README.md @@ -0,0 +1,8 @@ +### Relevant Articles: + +- [Calculate Months Between Two Dates in Java](https://www.baeldung.com/java-months-difference-two-dates) +- [Format LocalDate to ISO 8601 With T and Z](https://www.baeldung.com/java-format-localdate-iso-8601-t-z) +- [Check if Two Date Ranges Overlap](https://www.baeldung.com/java-check-two-date-ranges-overlap) +- [Difference between ZoneOffset.UTC and ZoneId.of(“UTC”)](https://www.baeldung.com/java-zoneoffset-utc-zoneid-of) +- [Check if a Given Time Lies Between Two Times Regardless of Date](https://www.baeldung.com/java-check-between-two-times) +- [[<-- Prev]](/core-java-modules/core-java-8-datetime-2) diff --git a/core-java-modules/core-java-8-datetime-3/pom.xml b/core-java-modules/core-java-8-datetime-3/pom.xml new file mode 100644 index 0000000000..4e32190fcf --- /dev/null +++ b/core-java-modules/core-java-8-datetime-3/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + core-java-8-datetime-3 + jar + core-java-8-datetime-3 + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + joda-time + joda-time + ${joda-time.version} + + + + + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + + + + + + + 1.8 + 1.8 + 2.12.5 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java similarity index 100% rename from core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java rename to core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java index 9b898c87f5..9fbe4bc7fe 100644 --- a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java +++ b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/daterangeoverlap/DateRangeOverlapChecker.java @@ -1,11 +1,11 @@ package com.baeldung.daterangeoverlap; -import java.time.LocalDate; -import java.util.Calendar; - import org.joda.time.DateTime; import org.joda.time.Interval; +import java.time.LocalDate; +import java.util.Calendar; + public class DateRangeOverlapChecker { public static boolean isOverlapUsingCalendarAndDuration(Calendar start1, Calendar end1, Calendar start2, Calendar end2) { diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java similarity index 92% rename from core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java rename to core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java index e09d823ce4..adf6c09107 100644 --- a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java +++ b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/localdatetoiso/LocalDateToISO.java @@ -1,20 +1,16 @@ package com.baeldung.localdatetoiso; +import org.apache.commons.lang3.time.FastDateFormat; +import org.joda.time.DateTimeZone; +import org.joda.time.format.ISODateTimeFormat; + import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.Date; - -import org.apache.commons.lang3.time.DateFormatUtils; - -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.ISODateTimeFormat; - -import org.apache.commons.lang3.time.FastDateFormat; +import java.util.TimeZone; public class LocalDateToISO { public String formatUsingDateTimeFormatter(LocalDate localDate) { diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java b/core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java similarity index 100% rename from core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java rename to core-java-modules/core-java-8-datetime-3/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java similarity index 97% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java index 1ffddaa241..e2f526947e 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java +++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/checkiftimebetweentwotimes/CheckIfTimeBetweenTwoTimesUnitTest.java @@ -1,45 +1,45 @@ -package com.baeldung.checkiftimebetweentwotimes; - -import org.junit.Test; - -import java.time.LocalTime; -import java.util.Calendar; -import java.util.Date; - -import static org.junit.Assert.assertTrue; - -public class CheckIfTimeBetweenTwoTimesUnitTest { - private LocalTime startTime = LocalTime.parse("09:00:00"); - private LocalTime endTime = LocalTime.parse("17:00:00"); - private LocalTime targetTime = LocalTime.parse("12:30:00"); - - @Test - public void givenLocalTime_whenUsingIsAfterIsBefore_thenTimeIsBetween() { - assertTrue(!targetTime.isBefore(startTime) && !targetTime.isAfter(endTime)); - } - - @Test - public void givenLocalTime_whenUsingCompareTo_thenTimeIsBetween() { - assertTrue(targetTime.compareTo(startTime) >= 0 && targetTime.compareTo(endTime) <= 0); - } - - @Test - public void givenDate_whenUsingAfterBefore_thenTimeIsBetween() { - Calendar startCalendar = Calendar.getInstance(); - startCalendar.set(Calendar.HOUR_OF_DAY, 9); - startCalendar.set(Calendar.MINUTE, 0); - Date startTime = startCalendar.getTime(); - - Calendar endCalendar = Calendar.getInstance(); - endCalendar.set(Calendar.HOUR_OF_DAY, 17); - endCalendar.set(Calendar.MINUTE, 0); - Date endTime = endCalendar.getTime(); - - Calendar targetCalendar = Calendar.getInstance(); - targetCalendar.set(Calendar.HOUR_OF_DAY, 12); - targetCalendar.set(Calendar.MINUTE, 30); - Date targetTime = targetCalendar.getTime(); - - assertTrue(!targetTime.before(startTime) && !targetTime.after(endTime)); - } +package com.baeldung.checkiftimebetweentwotimes; + +import org.junit.Test; + +import java.time.LocalTime; +import java.util.Calendar; +import java.util.Date; + +import static org.junit.Assert.assertTrue; + +public class CheckIfTimeBetweenTwoTimesUnitTest { + private LocalTime startTime = LocalTime.parse("09:00:00"); + private LocalTime endTime = LocalTime.parse("17:00:00"); + private LocalTime targetTime = LocalTime.parse("12:30:00"); + + @Test + public void givenLocalTime_whenUsingIsAfterIsBefore_thenTimeIsBetween() { + assertTrue(!targetTime.isBefore(startTime) && !targetTime.isAfter(endTime)); + } + + @Test + public void givenLocalTime_whenUsingCompareTo_thenTimeIsBetween() { + assertTrue(targetTime.compareTo(startTime) >= 0 && targetTime.compareTo(endTime) <= 0); + } + + @Test + public void givenDate_whenUsingAfterBefore_thenTimeIsBetween() { + Calendar startCalendar = Calendar.getInstance(); + startCalendar.set(Calendar.HOUR_OF_DAY, 9); + startCalendar.set(Calendar.MINUTE, 0); + Date startTime = startCalendar.getTime(); + + Calendar endCalendar = Calendar.getInstance(); + endCalendar.set(Calendar.HOUR_OF_DAY, 17); + endCalendar.set(Calendar.MINUTE, 0); + Date endTime = endCalendar.getTime(); + + Calendar targetCalendar = Calendar.getInstance(); + targetCalendar.set(Calendar.HOUR_OF_DAY, 12); + targetCalendar.set(Calendar.MINUTE, 30); + Date targetTime = targetCalendar.getTime(); + + assertTrue(!targetTime.before(startTime) && !targetTime.after(endTime)); + } } \ No newline at end of file diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java similarity index 100% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java index 5811cb6552..fa8145f71c 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java +++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/daterangeoverlap/DateRangeOverlapCheckerUnitTest.java @@ -1,13 +1,13 @@ package com.baeldung.daterangeoverlap; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import org.joda.time.DateTime; +import org.junit.Test; import java.time.LocalDate; import java.util.Calendar; -import org.joda.time.DateTime; -import org.junit.Test; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; public class DateRangeOverlapCheckerUnitTest { diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java similarity index 81% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java index 1979c91eca..c82cc2766d 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java +++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/localdatetoiso/LocalDateToISOUnitTest.java @@ -1,13 +1,14 @@ package com.baeldung.localdatetoiso; +import org.junit.Test; + +import java.time.LocalDate; + import static org.junit.Assert.assertEquals; -import org.junit.Test; -import java.time.LocalDate; - public class LocalDateToISOUnitTest { @Test - void givenLocalDate_whenUsingDateTimeFormatter_thenISOFormat(){ + public void givenLocalDate_whenUsingDateTimeFormatter_thenISOFormat(){ LocalDateToISO localDateToISO = new LocalDateToISO(); LocalDate localDate = LocalDate.of(2023, 11, 6); @@ -17,7 +18,7 @@ public class LocalDateToISOUnitTest { } @Test - void givenLocalDate_whenUsingSimpleDateFormat_thenISOFormat(){ + public void givenLocalDate_whenUsingSimpleDateFormat_thenISOFormat(){ LocalDateToISO localDateToISO = new LocalDateToISO(); LocalDate localDate = LocalDate.of(2023, 11, 6); @@ -27,17 +28,18 @@ public class LocalDateToISOUnitTest { } @Test - void givenLocalDate_whenUsingJodaTime_thenISOFormat() { + public void givenLocalDate_whenUsingJodaTime_thenISOFormat() { LocalDateToISO localDateToISO = new LocalDateToISO(); org.joda.time.LocalDate localDate = new org.joda.time.LocalDate(2023, 11, 6); String expected = "2023-11-06T00:00:00.000Z"; String actual = localDateToISO.formatUsingJodaTime(localDate); assertEquals(expected, actual); + assertEquals(expected, actual); } @Test - void givenLocalDate_whenUsingApacheCommonsLang_thenISOFormat() { + public void givenLocalDate_whenUsingApacheCommonsLang_thenISOFormat() { LocalDateToISO localDateToISO = new LocalDateToISO(); LocalDate localDate = LocalDate.of(2023, 11, 6); diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java similarity index 100% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java similarity index 96% rename from core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java rename to core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java index 84f40c3cd5..298963fd70 100644 --- a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java +++ b/core-java-modules/core-java-8-datetime-3/src/test/java/com/baeldung/zoneoffsetandzoneidof/ZoneOffSetAndZoneIdOfUnitTest.java @@ -1,25 +1,25 @@ -package com.baeldung.zoneoffsetandzoneidof; - -import org.junit.jupiter.api.Test; - -import java.time.OffsetDateTime; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class ZoneOffSetAndZoneIdOfUnitTest { - - @Test - public void givenOffsetDateTimeWithUTCZoneOffset_thenOffsetShouldBeUTC() { - OffsetDateTime dateTimeWithOffset = OffsetDateTime.now(ZoneOffset.UTC); - assertEquals(dateTimeWithOffset.getOffset(), ZoneOffset.UTC); - } - - @Test - public void givenZonedDateTimeWithUTCZoneId_thenZoneShouldBeUTC() { - ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC")); - assertEquals(zonedDateTime.getZone(), ZoneId.of("UTC")); - } -} +package com.baeldung.zoneoffsetandzoneidof; + +import org.junit.jupiter.api.Test; + +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ZoneOffSetAndZoneIdOfUnitTest { + + @Test + public void givenOffsetDateTimeWithUTCZoneOffset_thenOffsetShouldBeUTC() { + OffsetDateTime dateTimeWithOffset = OffsetDateTime.now(ZoneOffset.UTC); + assertEquals(dateTimeWithOffset.getOffset(), ZoneOffset.UTC); + } + + @Test + public void givenZonedDateTimeWithUTCZoneId_thenZoneShouldBeUTC() { + ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC")); + assertEquals(zonedDateTime.getZone(), ZoneId.of("UTC")); + } +} From e812b299bdca48a59051c2893105bb4602a1e0c4 Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Wed, 10 Apr 2024 01:03:56 +0300 Subject: [PATCH 44/57] JAVA-32783 Split or move algorithms-miscellaneous-7 (#16317) Co-authored-by: timis1 --- algorithms-modules/algorithms-miscellaneous-7/README.md | 4 ---- .../test/java/com/baeldung/algorithms/connect4/README.md | 2 -- algorithms-modules/algorithms-miscellaneous-8/README.md | 6 ++++++ .../largestNumberRemovingK/LargestNumberRemoveKDigits.java | 2 +- .../parentnodebinarytree/ParentKeeperTreeNode.java | 0 .../baeldung/algorithms/parentnodebinarytree/TreeNode.java | 0 .../java/com/baeldung/algorithms/connect4/GameBoard.java | 0 .../java/com/baeldung/algorithms/connect4/GameUnitTest.java | 0 .../test/java/com/baeldung/algorithms/connect4/Piece.java | 0 .../algorithms/happynumber/HappyNumberUnitTest.java | 0 .../algorithms/jugglersequence/JugglerSequenceUnitTest.java | 0 .../LargestNumberRemoveKDigitsUnitTest.java | 0 .../BinaryTreeParentNodeFinderUnitTest.java | 4 +++- 13 files changed, 10 insertions(+), 8 deletions(-) delete mode 100644 algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java (98%) rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java (100%) rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java (100%) rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java (100%) rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java (100%) rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/test/java/com/baeldung/algorithms/connect4/Piece.java (100%) rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java (100%) rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java (100%) rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java (100%) rename algorithms-modules/{algorithms-miscellaneous-7 => algorithms-miscellaneous-8}/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java (94%) diff --git a/algorithms-modules/algorithms-miscellaneous-7/README.md b/algorithms-modules/algorithms-miscellaneous-7/README.md index a08948eda5..266d79cdfa 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/README.md +++ b/algorithms-modules/algorithms-miscellaneous-7/README.md @@ -10,8 +10,4 @@ - [Check if Two Strings Are Rotations of Each Other](https://www.baeldung.com/java-string-check-strings-rotations) - [Find the Largest Prime Under the Given Number in Java](https://www.baeldung.com/java-largest-prime-lower-threshold) - [Count the Number of Unique Digits in an Integer using Java](https://www.baeldung.com/java-int-count-unique-digits) -- [Generate Juggler Sequence in Java](https://www.baeldung.com/java-generate-juggler-sequence) -- [Finding the Parent of a Node in a Binary Search Tree with Java](https://www.baeldung.com/java-find-parent-node-binary-search-tree) -- [Check if a Number Is a Happy Number in Java](https://www.baeldung.com/java-happy-sad-number-test) -- [Find the Largest Number Possible After Removing k Digits of a Number](https://www.baeldung.com/java-find-largest-number-remove-k-digits) - More articles: [[<-- prev]](/algorithms-miscellaneous-6) diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md b/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md deleted file mode 100644 index 55bc2abec5..0000000000 --- a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/README.md +++ /dev/null @@ -1,2 +0,0 @@ -## Relevant Articles -- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game) diff --git a/algorithms-modules/algorithms-miscellaneous-8/README.md b/algorithms-modules/algorithms-miscellaneous-8/README.md index e2c5047136..8bd185a7ba 100644 --- a/algorithms-modules/algorithms-miscellaneous-8/README.md +++ b/algorithms-modules/algorithms-miscellaneous-8/README.md @@ -1,3 +1,9 @@ ### Relevant Articles: - [Vigenère Cipher in Java](https://www.baeldung.com/java-vigenere-cipher) - [Merge Overlapping Intervals in a Java Collection](https://www.baeldung.com/java-collection-merge-overlapping-intervals) +- [Generate Juggler Sequence in Java](https://www.baeldung.com/java-generate-juggler-sequence) +- [Finding the Parent of a Node in a Binary Search Tree with Java](https://www.baeldung.com/java-find-parent-node-binary-search-tree) +- [Check if a Number Is a Happy Number in Java](https://www.baeldung.com/java-happy-sad-number-test) +- [Find the Largest Number Possible After Removing k Digits of a Number](https://www.baeldung.com/java-find-largest-number-remove-k-digits) +- [Implement Connect 4 Game with Java](https://www.baeldung.com/java-connect-4-game) +- More articles: [[<-- prev]](/algorithms-miscellaneous-7) \ No newline at end of file diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java similarity index 98% rename from algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java rename to algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java index 79086fc61f..51e8350afc 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java +++ b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigits.java @@ -1,6 +1,6 @@ package com.baeldung.algorithms.largestNumberRemovingK; -import java.util.*; +import java.util.Stack; public class LargestNumberRemoveKDigits { public static int findLargestNumberUsingArithmetic(int num, int k) { diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java rename to algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/ParentKeeperTreeNode.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java b/algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java rename to algorithms-modules/algorithms-miscellaneous-8/src/main/java/com/baeldung/algorithms/parentnodebinarytree/TreeNode.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameBoard.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/GameUnitTest.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/Piece.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/Piece.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/connect4/Piece.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/connect4/Piece.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/happynumber/HappyNumberUnitTest.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/jugglersequence/JugglerSequenceUnitTest.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java similarity index 100% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/largestNumberRemovingK/LargestNumberRemoveKDigitsUnitTest.java diff --git a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java similarity index 94% rename from algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java rename to algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java index d3f0ec7997..ff31f99ed6 100644 --- a/algorithms-modules/algorithms-miscellaneous-7/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java +++ b/algorithms-modules/algorithms-miscellaneous-8/src/test/java/com/baeldung/algorithms/parentnodebinarytree/BinaryTreeParentNodeFinderUnitTest.java @@ -5,7 +5,9 @@ import org.junit.jupiter.api.Test; import java.util.NoSuchElementException; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertNull; class BinaryTreeParentNodeFinderUnitTest { From a9f5f9fab50e3e6035532a99b1c7262c1a701a42 Mon Sep 17 00:00:00 2001 From: timis1 <12120641+timis1@users.noreply.github.com> Date: Wed, 10 Apr 2024 02:24:50 +0300 Subject: [PATCH 45/57] JAVA-33597 Fix all modules here have incorrect parent (#16324) Co-authored-by: timis1 --- spring-boot-modules/spring-boot-3-2/pom.xml | 7 +++---- spring-boot-modules/spring-boot-3/pom.xml | 7 +++---- spring-boot-modules/spring-boot-aws/pom.xml | 7 +++---- .../spring-boot-basic-customization-3/pom.xml | 7 +++---- spring-boot-modules/spring-boot-data-3/pom.xml | 7 +++---- spring-boot-modules/spring-boot-groovy/pom.xml | 7 +++---- spring-boot-modules/spring-boot-libraries-3/pom.xml | 7 +++---- spring-boot-modules/spring-boot-swagger/pom.xml | 7 +++---- 8 files changed, 24 insertions(+), 32 deletions(-) diff --git a/spring-boot-modules/spring-boot-3-2/pom.xml b/spring-boot-modules/spring-boot-3-2/pom.xml index 29d9332ca5..d427aff835 100644 --- a/spring-boot-modules/spring-boot-3-2/pom.xml +++ b/spring-boot-modules/spring-boot-3-2/pom.xml @@ -9,10 +9,9 @@ Demo project for Spring Boot - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-3/pom.xml b/spring-boot-modules/spring-boot-3/pom.xml index ae9e9d7308..0c00a8af34 100644 --- a/spring-boot-modules/spring-boot-3/pom.xml +++ b/spring-boot-modules/spring-boot-3/pom.xml @@ -9,10 +9,9 @@ Demo project for Spring Boot - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-aws/pom.xml b/spring-boot-modules/spring-boot-aws/pom.xml index 8be0b230cd..966dfec6fa 100644 --- a/spring-boot-modules/spring-boot-aws/pom.xml +++ b/spring-boot-modules/spring-boot-aws/pom.xml @@ -11,10 +11,9 @@ - org.springframework.boot - spring-boot-starter-parent - 3.1.5 - + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-basic-customization-3/pom.xml b/spring-boot-modules/spring-boot-basic-customization-3/pom.xml index 1b09162cf4..9018b21e03 100644 --- a/spring-boot-modules/spring-boot-basic-customization-3/pom.xml +++ b/spring-boot-modules/spring-boot-basic-customization-3/pom.xml @@ -9,10 +9,9 @@ Module For Spring Boot Basic Customization 3 - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-data-3/pom.xml b/spring-boot-modules/spring-boot-data-3/pom.xml index 0d35da3a0a..c6cd426bb2 100644 --- a/spring-boot-modules/spring-boot-data-3/pom.xml +++ b/spring-boot-modules/spring-boot-data-3/pom.xml @@ -10,10 +10,9 @@ spring-boot-data-3 - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-groovy/pom.xml b/spring-boot-modules/spring-boot-groovy/pom.xml index 677e07db2d..b03bc3b004 100644 --- a/spring-boot-modules/spring-boot-groovy/pom.xml +++ b/spring-boot-modules/spring-boot-groovy/pom.xml @@ -10,10 +10,9 @@ Spring Boot Todo Application with Groovy - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-libraries-3/pom.xml b/spring-boot-modules/spring-boot-libraries-3/pom.xml index e88ae4c078..223a39f1de 100644 --- a/spring-boot-modules/spring-boot-libraries-3/pom.xml +++ b/spring-boot-modules/spring-boot-libraries-3/pom.xml @@ -6,10 +6,9 @@ spring-boot-libraries-3 - com.baeldung - parent-boot-3 - 0.0.1-SNAPSHOT - ../../parent-boot-3 + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT diff --git a/spring-boot-modules/spring-boot-swagger/pom.xml b/spring-boot-modules/spring-boot-swagger/pom.xml index bd74c3ea88..20dec5410c 100644 --- a/spring-boot-modules/spring-boot-swagger/pom.xml +++ b/spring-boot-modules/spring-boot-swagger/pom.xml @@ -10,10 +10,9 @@ Module For Spring Boot Swagger - com.baeldung - parent-boot-3 - ../../parent-boot-3 - 0.0.1-SNAPSHOT + com.baeldung.spring-boot-modules + spring-boot-modules + 1.0.0-SNAPSHOT From 28bb26ceb246efd58f591fa3813a5c2488103358 Mon Sep 17 00:00:00 2001 From: Pedro Lopes Date: Wed, 10 Apr 2024 02:32:21 -0300 Subject: [PATCH 46/57] BAEL-6852: Can @Transactional and @Async work together? (#16126) * adding tests and repo classes * wrapping up logic] * removing test * removing sql files * changing to throw exception on optional] * introducing property in pom --- .../spring-boot-persistence-4/pom.xml | 6 +++ .../transactionalandasync/Account.java | 23 +++++++++++ .../AccountRepository.java | 6 +++ .../transactionalandasync/AccountService.java | 41 +++++++++++++++++++ .../BankAccountApplication.java | 12 ++++++ 5 files changed, 88 insertions(+) create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java create mode 100644 persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java diff --git a/persistence-modules/spring-boot-persistence-4/pom.xml b/persistence-modules/spring-boot-persistence-4/pom.xml index 75b444f7cc..d4bf8ba5cb 100644 --- a/persistence-modules/spring-boot-persistence-4/pom.xml +++ b/persistence-modules/spring-boot-persistence-4/pom.xml @@ -60,6 +60,11 @@ ${lombok.version} provided + + org.springframework + spring-tx + ${spring.tx.version} + @@ -84,6 +89,7 @@ 3.2.0 1.16.1 1.18.30 + 6.1.4 \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java new file mode 100644 index 0000000000..6bb070cad2 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/Account.java @@ -0,0 +1,23 @@ +package com.baeldung.transactionalandasync; + +import jakarta.persistence.*; +import lombok.*; + +import java.math.BigDecimal; + +@Entity +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode(of = {"id"}) +@Table(name = "account") +@Data +public class Account { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + + @Column(name = "balance") + private BigDecimal balance; +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java new file mode 100644 index 0000000000..a3c15e25eb --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountRepository.java @@ -0,0 +1,6 @@ +package com.baeldung.transactionalandasync; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AccountRepository extends JpaRepository { +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java new file mode 100644 index 0000000000..d54f90e2e5 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/AccountService.java @@ -0,0 +1,41 @@ +package com.baeldung.transactionalandasync; + +import jakarta.transaction.Transactional; +import lombok.AllArgsConstructor; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; + +@Service +@AllArgsConstructor +@Transactional +public class AccountService { + + private final AccountRepository accountRepository; + + @Async + public void transferAsync(Long depositorId, Long favoredId, BigDecimal amount) { + transfer(depositorId, favoredId, amount); + + printReceipt(); + } + + @Transactional + public void transfer(Long depositorId, Long favoredId, BigDecimal amount) { + Account depositorAccount = accountRepository.findById(depositorId) + .orElseThrow(IllegalArgumentException::new); + Account favoredAccount = accountRepository.findById(favoredId) + .orElseThrow(IllegalArgumentException::new); + + depositorAccount.setBalance(depositorAccount.getBalance().subtract(amount)); + favoredAccount.setBalance(favoredAccount.getBalance().add(amount)); + + accountRepository.save(depositorAccount); + accountRepository.save(favoredAccount); + } + + public void printReceipt() { + // logic to print the receipt + } +} diff --git a/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java new file mode 100644 index 0000000000..403a098df8 --- /dev/null +++ b/persistence-modules/spring-boot-persistence-4/src/main/java/com/baeldung/transactionalandasync/BankAccountApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.transactionalandasync; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class BankAccountApplication { + public static void main(String[] args) { + SpringApplication.run(BankAccountApplication.class, args); + } + +} From 4bdfd9699f8a0f3c6a1ecc92f7bb9243b73b91fe Mon Sep 17 00:00:00 2001 From: hajk1 Date: Wed, 3 Apr 2024 01:32:44 +0330 Subject: [PATCH 47/57] adding new article BAEL-7497 source codes --- .../core-java-collections-6/README.md | 2 + .../IteratorVsForeachUnitTest.java | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java diff --git a/core-java-modules/core-java-collections-6/README.md b/core-java-modules/core-java-collections-6/README.md index b5f1adbf48..736e91f110 100644 --- a/core-java-modules/core-java-collections-6/README.md +++ b/core-java-modules/core-java-collections-6/README.md @@ -3,3 +3,5 @@ ## Core Java Collections Cookbooks and Examples ### Relevant Articles: + +- More articles: [[<-- prev]](/core-java-modules/core-java-collections-5) diff --git a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java new file mode 100644 index 0000000000..a95c1a1e98 --- /dev/null +++ b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java @@ -0,0 +1,69 @@ +package com.baeldung.iteratorvsforeach; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class IteratorVsForeachUnitTest { + + private static Stream listProvider() { + return Stream.of( + Arguments.of( + List.of("String1", "String2", "unwanted"), + List.of("String1", "String2")) + ); + } + + @Test + public void givenEmptyCollection_whenUsingForEach_thenNoElementsAreIterated() { + List names = Collections.emptyList(); + StringBuilder stringBuilder = new StringBuilder(); + names.forEach(stringBuilder::append); + assertEquals("", stringBuilder.toString()); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringForEachIteration_thenElementIsRemoved( + List input, List expected) { + List mutableList = new ArrayList<>(input); + // Separate collection for items to be removed + List toRemove = new ArrayList<>(); + + // Using forEach to identify items to remove + input.forEach(item -> { + if (item.equals("unwanted")) { + toRemove.add(item); + } + }); + + // Removing the identified items from the original list + mutableList.removeAll(toRemove); + assertIterableEquals(expected, mutableList); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringIteratorIteration_thenElementIsRemoved( + List input, List expected) { + List mutableList = new ArrayList<>(input); + Iterator it = mutableList.iterator(); + while (it.hasNext()) { + String item = it.next(); + if (item.equals("unwanted")) { + it.remove(); // Safely remove item + } + } + assertIterableEquals(expected, mutableList); + } + +} From a1e28048a67da7eedbef659085a6fb8850bbd98a Mon Sep 17 00:00:00 2001 From: hajk1 Date: Sun, 7 Apr 2024 18:25:13 +0330 Subject: [PATCH 48/57] reformat the files using intellij-baeldung-style.xml --- .../IteratorVsForeachUnitTest.java | 93 +++++++++---------- 1 file changed, 44 insertions(+), 49 deletions(-) diff --git a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java index a95c1a1e98..ca9390a3ee 100644 --- a/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java +++ b/core-java-modules/core-java-collections-6/src/test/java/com/baeldung/iteratorvsforeach/IteratorVsForeachUnitTest.java @@ -8,6 +8,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.stream.Stream; + import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -15,55 +16,49 @@ import org.junit.jupiter.params.provider.MethodSource; class IteratorVsForeachUnitTest { - private static Stream listProvider() { - return Stream.of( - Arguments.of( - List.of("String1", "String2", "unwanted"), - List.of("String1", "String2")) - ); - } - - @Test - public void givenEmptyCollection_whenUsingForEach_thenNoElementsAreIterated() { - List names = Collections.emptyList(); - StringBuilder stringBuilder = new StringBuilder(); - names.forEach(stringBuilder::append); - assertEquals("", stringBuilder.toString()); - } - - @ParameterizedTest - @MethodSource("listProvider") - public void givenCollectionWithElements_whenRemovingElementDuringForEachIteration_thenElementIsRemoved( - List input, List expected) { - List mutableList = new ArrayList<>(input); - // Separate collection for items to be removed - List toRemove = new ArrayList<>(); - - // Using forEach to identify items to remove - input.forEach(item -> { - if (item.equals("unwanted")) { - toRemove.add(item); - } - }); - - // Removing the identified items from the original list - mutableList.removeAll(toRemove); - assertIterableEquals(expected, mutableList); - } - - @ParameterizedTest - @MethodSource("listProvider") - public void givenCollectionWithElements_whenRemovingElementDuringIteratorIteration_thenElementIsRemoved( - List input, List expected) { - List mutableList = new ArrayList<>(input); - Iterator it = mutableList.iterator(); - while (it.hasNext()) { - String item = it.next(); - if (item.equals("unwanted")) { - it.remove(); // Safely remove item - } + private static Stream listProvider() { + return Stream.of(Arguments.of(List.of("String1", "String2", "unwanted"), List.of("String1", "String2"))); + } + + @Test + public void givenEmptyCollection_whenUsingForEach_thenNoElementsAreIterated() { + List names = Collections.emptyList(); + StringBuilder stringBuilder = new StringBuilder(); + names.forEach(stringBuilder::append); + assertEquals("", stringBuilder.toString()); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringForEachIteration_thenElementIsRemoved(List input, List expected) { + List mutableList = new ArrayList<>(input); + // Separate collection for items to be removed + List toRemove = new ArrayList<>(); + + // Using forEach to identify items to remove + input.forEach(item -> { + if (item.equals("unwanted")) { + toRemove.add(item); + } + }); + + // Removing the identified items from the original list + mutableList.removeAll(toRemove); + assertIterableEquals(expected, mutableList); + } + + @ParameterizedTest + @MethodSource("listProvider") + public void givenCollectionWithElements_whenRemovingElementDuringIteratorIteration_thenElementIsRemoved(List input, List expected) { + List mutableList = new ArrayList<>(input); + Iterator it = mutableList.iterator(); + while (it.hasNext()) { + String item = it.next(); + if (item.equals("unwanted")) { + it.remove(); // Safely remove item + } + } + assertIterableEquals(expected, mutableList); } - assertIterableEquals(expected, mutableList); - } } From 44ef962a82cf3a6ac6b18e263724a1d774ef118e Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Wed, 10 Apr 2024 19:25:52 +0200 Subject: [PATCH 49/57] BAEL-7676: Get the Response Body in Spring Boot Filter (#16186) --- .../baeldung/responsebody/FilterConfig.java | 16 +++++++ .../responsebody/HelloWorldController.java | 15 ++++++ .../com/baeldung/responsebody/MD5Filter.java | 39 +++++++++++++++ .../responsebody/ResponseBodyApplication.java | 12 +++++ .../responsebody/ResponseBodyUnitTest.java | 48 +++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java create mode 100644 spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java new file mode 100644 index 0000000000..212dbd8626 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/FilterConfig.java @@ -0,0 +1,16 @@ +package com.baeldung.responsebody; + +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FilterConfig { + + @Bean + public FilterRegistrationBean loggingFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new MD5Filter()); + return registrationBean; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java new file mode 100644 index 0000000000..657b7972bb --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/HelloWorldController.java @@ -0,0 +1,15 @@ +package com.baeldung.responsebody; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/example") +public class HelloWorldController { + + @GetMapping + public String getExample() { + return "Hello, World!"; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java new file mode 100644 index 0000000000..8f6e86f17e --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/MD5Filter.java @@ -0,0 +1,39 @@ +package com.baeldung.responsebody; + +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.logging.Logger; + +import org.springframework.stereotype.Component; +import org.springframework.web.util.ContentCachingResponseWrapper; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.xml.bind.DatatypeConverter; + +@Component +public class MD5Filter implements Filter { + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + ContentCachingResponseWrapper responseCacheWrapperObject = new ContentCachingResponseWrapper((HttpServletResponse) servletResponse); + filterChain.doFilter(servletRequest, responseCacheWrapperObject); + + byte[] responseBody = responseCacheWrapperObject.getContentAsByteArray(); + + try { + MessageDigest md5Digest = MessageDigest.getInstance("MD5"); + byte[] md5Hash = md5Digest.digest(responseBody); + String md5HashString = DatatypeConverter.printHexBinary(md5Hash); + responseCacheWrapperObject.setHeader("Response-Body-MD5", md5HashString); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + responseCacheWrapperObject.copyBodyToResponse(); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java new file mode 100644 index 0000000000..4084dffccf --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/main/java/com/baeldung/responsebody/ResponseBodyApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.responsebody; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = "com.baeldung.responsebody") +public class ResponseBodyApplication { + + public static void main(String[] args) { + SpringApplication.run(ResponseBodyApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java b/spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java new file mode 100644 index 0000000000..bebbd5a4b9 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization-3/src/test/java/com/baeldung/responsebody/ResponseBodyUnitTest.java @@ -0,0 +1,48 @@ +package com.baeldung.responsebody; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.junit.jupiter.api.Test; +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.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + +import jakarta.xml.bind.DatatypeConverter; + +@SpringBootTest(classes = ResponseBodyApplication.class) +@AutoConfigureMockMvc +class ResponseBodyUnitTest { + + @Autowired + private MockMvc mockMvc; + + @Test + void whenExampleApiCallThenResponseHasMd5Header() throws Exception { + String endpoint = "/api/example"; + String expectedResponse = "Hello, World!"; + String expectedMD5 = getMD5Hash(expectedResponse); + + MvcResult mvcResult = mockMvc.perform(get(endpoint).accept(MediaType.TEXT_PLAIN_VALUE)) + .andExpect(status().isOk()) + .andReturn(); + + String md5Header = mvcResult.getResponse() + .getHeader("Response-Body-MD5"); + assertThat(md5Header).isEqualTo(expectedMD5); + } + + private String getMD5Hash(String input) throws NoSuchAlgorithmException { + MessageDigest md5Digest = MessageDigest.getInstance("MD5"); + byte[] md5Hash = md5Digest.digest(input.getBytes(StandardCharsets.UTF_8)); + return DatatypeConverter.printHexBinary(md5Hash); + } +} \ No newline at end of file From f1af9d5e5594a707aeaca27cfeab3601f90cfbf9 Mon Sep 17 00:00:00 2001 From: Mikhail Polivakha <68962645+mipo256@users.noreply.github.com> Date: Thu, 11 Apr 2024 00:06:14 +0300 Subject: [PATCH 50/57] BAEL-6174 Moved subselect package to newly created hibernate-annotations-2 (#16342) * BAEL-6174 * Moved subselect package to newly created hibernate-annotations-2 --- .../hibernate-annotations-2/README.md | 6 + .../hibernate-annotations-2/pom.xml | 109 ++++++++++++++++++ .../hibernate/HibernateAnnotationUtil.java | 50 ++++++++ .../baeldung/hibernate/PersistenceConfig.java | 67 +++++++++++ .../subselect/RuntimeConfiguration.java | 0 .../main/resources/migrations/V1__init.xml | 0 .../src/main/resources/migrations/master.xml | 0 .../main/resources/persistence-h2.properties | 15 +++ .../java/com/baeldung/SpringContextTest.java | 18 +++ .../subselect/SubselectIntegrationTest.java | 2 +- .../config/HibernateAnnotationUtil.java | 2 - 11 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 persistence-modules/hibernate-annotations-2/README.md create mode 100644 persistence-modules/hibernate-annotations-2/pom.xml create mode 100644 persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java create mode 100644 persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java rename persistence-modules/{hibernate-annotations => hibernate-annotations-2}/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java (100%) rename persistence-modules/{hibernate-annotations => hibernate-annotations-2}/src/main/resources/migrations/V1__init.xml (100%) rename persistence-modules/{hibernate-annotations => hibernate-annotations-2}/src/main/resources/migrations/master.xml (100%) create mode 100644 persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties create mode 100644 persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java rename persistence-modules/{hibernate-annotations => hibernate-annotations-2}/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java (96%) diff --git a/persistence-modules/hibernate-annotations-2/README.md b/persistence-modules/hibernate-annotations-2/README.md new file mode 100644 index 0000000000..9da9b37245 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/README.md @@ -0,0 +1,6 @@ +## Hibernate Annotations + +This module contains articles about Annotations used in Hibernate. + +### Relevant Articles: +- [@Subselect Annotation in Hibernate](https://www.baeldung.com/hibernate-subselect) diff --git a/persistence-modules/hibernate-annotations-2/pom.xml b/persistence-modules/hibernate-annotations-2/pom.xml new file mode 100644 index 0000000000..046fbae619 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/pom.xml @@ -0,0 +1,109 @@ + + + 4.0.0 + + hibernate-annotations-2 + 0.1-SNAPSHOT + hibernate-annotations-2 + jar + Hibernate annotations module, part 2 + + + com.baeldung + persistence-modules + 1.0.0-SNAPSHOT + + + + + + org.springframework + spring-context + ${org.springframework.version} + + + org.springframework.data + spring-data-jpa + ${org.springframework.data.version} + + + org.hibernate.orm + hibernate-core + ${hibernate-core.version} + + + org.hsqldb + hsqldb + ${hsqldb.version} + + + com.h2database + h2 + ${h2.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + org.hibernate.orm + hibernate-testing + ${hibernate-core.version} + + + org.hibernate.orm + hibernate-spatial + ${hibernate-core.version} + + + org.apache.tomcat + tomcat-dbcp + ${tomcat-dbcp.version} + + + + + com.google.guava + guava + ${guava.version} + + + + org.springframework + spring-test + ${org.springframework.version} + test + + + io.hypersistence + hypersistence-utils-hibernate-60 + ${hypersistance-utils-hibernate-60.version} + + + org.liquibase + liquibase-core + ${liquibase-core.version} + + + org.projectlombok + lombok + ${lombok.version} + + + + + + 6.0.6 + 3.0.3 + 6.4.2.Final + true + 9.0.0.M26 + 3.3.1 + 1.18.30 + 4.24.0 + + + \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java new file mode 100644 index 0000000000..74046854e7 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/HibernateAnnotationUtil.java @@ -0,0 +1,50 @@ +package com.baeldung.hibernate; + +import com.baeldung.hibernate.subselect.RuntimeConfiguration; +import java.util.HashMap; +import java.util.Map; +import org.hibernate.SessionFactory; +import org.hibernate.boot.Metadata; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.Environment; +import org.hibernate.service.ServiceRegistry; + +public class HibernateAnnotationUtil { + + private static final SessionFactory SESSION_FACTORY = buildSessionFactory(); + + /** + * Utility class + */ + private HibernateAnnotationUtil() { + } + + public static SessionFactory getSessionFactory() { + return SESSION_FACTORY; + } + + private static SessionFactory buildSessionFactory() { + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() + .applySettings(dbSettings()) + .build(); + + Metadata metadata = new MetadataSources(serviceRegistry) + .addAnnotatedClass(RuntimeConfiguration.class) + .buildMetadata(); + + return metadata.buildSessionFactory(); + } + + private static Map dbSettings() { + Map dbSettings = new HashMap<>(); + dbSettings.put(Environment.URL, "jdbc:h2:mem:spring_hibernate_one_to_many"); + dbSettings.put(Environment.USER, "sa"); + dbSettings.put(Environment.PASS, ""); + dbSettings.put(Environment.DRIVER, "org.h2.Driver"); + dbSettings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread"); + dbSettings.put(Environment.SHOW_SQL, "true"); + dbSettings.put(Environment.HBM2DDL_AUTO, "create"); + return dbSettings; + } +} diff --git a/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java new file mode 100644 index 0000000000..c34b77282c --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/PersistenceConfig.java @@ -0,0 +1,67 @@ +package com.baeldung.hibernate; + +import com.google.common.base.Preconditions; +import java.util.Properties; +import javax.sql.DataSource; +import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; +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.orm.hibernate5.HibernateTransactionManager; +import org.springframework.orm.hibernate5.LocalSessionFactoryBean; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +@PropertySource({ "classpath:persistence-h2.properties" }) +public class PersistenceConfig { + + @Autowired + private Environment env; + + @Bean + public LocalSessionFactoryBean sessionFactory() { + final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); + sessionFactory.setDataSource(dataSource()); + sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate" }); + sessionFactory.setHibernateProperties(hibernateProperties()); + return sessionFactory; + } + + @Bean + public DataSource dataSource() { + final BasicDataSource dataSource = new BasicDataSource(); + dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName"))); + dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url"))); + dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user"))); + dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass"))); + + return dataSource; + } + + @Bean + public PlatformTransactionManager hibernateTransactionManager() { + final HibernateTransactionManager transactionManager = new HibernateTransactionManager(); + transactionManager.setSessionFactory(sessionFactory().getObject()); + return transactionManager; + } + + @Bean + public PersistenceExceptionTranslationPostProcessor exceptionTranslation() { + return new PersistenceExceptionTranslationPostProcessor(); + } + + private final Properties hibernateProperties() { + 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.show_sql", "false"); + return hibernateProperties; + } + +} \ No newline at end of file diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java b/persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java similarity index 100% rename from persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java rename to persistence-modules/hibernate-annotations-2/src/main/java/com/baeldung/hibernate/subselect/RuntimeConfiguration.java diff --git a/persistence-modules/hibernate-annotations/src/main/resources/migrations/V1__init.xml b/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/V1__init.xml similarity index 100% rename from persistence-modules/hibernate-annotations/src/main/resources/migrations/V1__init.xml rename to persistence-modules/hibernate-annotations-2/src/main/resources/migrations/V1__init.xml diff --git a/persistence-modules/hibernate-annotations/src/main/resources/migrations/master.xml b/persistence-modules/hibernate-annotations-2/src/main/resources/migrations/master.xml similarity index 100% rename from persistence-modules/hibernate-annotations/src/main/resources/migrations/master.xml rename to persistence-modules/hibernate-annotations-2/src/main/resources/migrations/master.xml diff --git a/persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties b/persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties new file mode 100644 index 0000000000..4bc5e98f56 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/main/resources/persistence-h2.properties @@ -0,0 +1,15 @@ +# jdbc.X +jdbc.driverClassName=org.h2.Driver +jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 +jdbc.eventGeneratedId=sa +jdbc.user=sa +jdbc.pass= + +# hibernate.X +hibernate.dialect=org.hibernate.dialect.H2Dialect +hibernate.show_sql=false +hibernate.hbm2ddl.auto=create-drop +hibernate.cache.use_second_level_cache=true +hibernate.cache.use_query_cache=true +hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory + diff --git a/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java new file mode 100644 index 0000000000..2db3ec53d5 --- /dev/null +++ b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/SpringContextTest.java @@ -0,0 +1,18 @@ +package com.baeldung; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +import com.baeldung.hibernate.PersistenceConfig; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class) +public class SpringContextTest { + + @Test + public void whenSpringContextIsBootstrapped_thenNoExceptions() { + } +} diff --git a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java similarity index 96% rename from persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java rename to persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java index 074468ca37..fee67240e4 100644 --- a/persistence-modules/hibernate-annotations/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java +++ b/persistence-modules/hibernate-annotations-2/src/test/java/com/baeldung/hibernate/subselect/SubselectIntegrationTest.java @@ -1,6 +1,6 @@ package com.baeldung.hibernate.subselect; -import com.baeldung.hibernate.oneToMany.config.HibernateAnnotationUtil; +import com.baeldung.hibernate.HibernateAnnotationUtil; import jakarta.persistence.criteria.Root; import liquibase.Contexts; import liquibase.LabelExpression; diff --git a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java index 0bf03e3fee..99410e1f76 100644 --- a/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java +++ b/persistence-modules/hibernate-annotations/src/main/java/com/baeldung/hibernate/oneToMany/config/HibernateAnnotationUtil.java @@ -4,7 +4,6 @@ import com.baeldung.hibernate.oneToMany.model.Cart; import com.baeldung.hibernate.oneToMany.model.CartOIO; import com.baeldung.hibernate.oneToMany.model.Item; import com.baeldung.hibernate.oneToMany.model.ItemOIO; -import com.baeldung.hibernate.subselect.RuntimeConfiguration; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; @@ -39,7 +38,6 @@ public class HibernateAnnotationUtil { .addAnnotatedClass(CartOIO.class) .addAnnotatedClass(Item.class) .addAnnotatedClass(ItemOIO.class) - .addAnnotatedClass(RuntimeConfiguration.class) .buildMetadata(); return metadata.buildSessionFactory(); From 4394e828c1425c55fc8af955d0c37d2aa2079379 Mon Sep 17 00:00:00 2001 From: Harry9656 Date: Thu, 11 Apr 2024 01:26:19 +0200 Subject: [PATCH 51/57] JAVA-32410: Update mockito-core to version 5.11.0 (#16199) * JAVA-32410: Update mockito-core to version 5.11.0 * Fix rollback mockito upgrade. * wip * WIP: Update jee-7 wildfly versions * WIP: Fix jersey tests * WIP: rollback powermock module * wip: fix test in spring-data-dynamodb * wip: fix test in spring-security-legacy-oidc * wip: rollback quarkus * wip: fix greeter-spring-boot-autoconfigure * JAVA-33535: Fix spring-core module integration test JAVA-33535: rollback junit-5 module mockito version. * Fix byte-buddy * Fix log4j dependency in apache-poi --- apache-poi/pom.xml | 11 +++++ .../todo-reminder-lambda/ToDoFunction/pom.xml | 3 +- core-java-modules/core-java-jar/pom.xml | 1 - graphql-modules/pom.xml | 7 ++- libraries-http-2/pom.xml | 3 +- messaging-modules/spring-jms/pom.xml | 3 +- .../design-patterns-creational-2/pom.xml | 6 ++- .../spring-boot-persistence/pom.xml | 1 - .../spring-data-dynamodb/pom.xml | 6 +++ .../java/com/baeldung/SpringContextTest.java | 2 - pom.xml | 2 +- .../quarkus-virtual-threads/pom.xml | 3 +- quarkus-modules/quarkus/pom.xml | 2 +- spring-aop-2/pom.xml | 1 + .../greeter-spring-boot-autoconfigure/pom.xml | 7 +++ spring-core/pom.xml | 4 +- spring-ejb-modules/ejb-beans/pom.xml | 1 - .../spring-security-legacy-oidc/pom.xml | 6 +++ .../accessing-session-attributes/pom.xml | 1 - testing-modules/junit-5-basics-2/pom.xml | 3 +- testing-modules/junit-5/pom.xml | 7 +-- testing-modules/mockito-2/pom.xml | 2 +- testing-modules/mockito-simple/pom.xml | 1 - testing-modules/powermock/pom.xml | 2 +- web-modules/jakarta-ee/pom.xml | 5 +- .../eclipse/krazo/UserControllerUnitTest.java | 28 ++++++----- web-modules/javax-servlets-2/pom.xml | 1 - web-modules/jee-7/pom.xml | 9 ++-- .../com/baeldung/jersey/server/Greetings.java | 2 + .../GreetingsResourceIntegrationTest.java | 14 +++--- .../rest/FruitResourceIntegrationTest.java | 46 +++++++++---------- 31 files changed, 106 insertions(+), 84 deletions(-) diff --git a/apache-poi/pom.xml b/apache-poi/pom.xml index 876fca0efe..027ee06968 100644 --- a/apache-poi/pom.xml +++ b/apache-poi/pom.xml @@ -40,6 +40,16 @@ fastexcel-reader ${fastexcel.version} + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + @@ -64,6 +74,7 @@ 1.0.9 0.17.0 3.3.1 + 2.23.1 \ No newline at end of file diff --git a/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml index acc14b55ff..2aa48a2f92 100644 --- a/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml +++ b/aws-modules/aws-lambda-modules/todo-reminder-lambda/ToDoFunction/pom.xml @@ -71,7 +71,7 @@ org.mockito mockito-core - ${mockito-core.version} + ${mockito.version} test @@ -112,7 +112,6 @@ 11.2 5.1.0 2.0.2 - 4.1.0 3.19.0 5.8.1 diff --git a/core-java-modules/core-java-jar/pom.xml b/core-java-modules/core-java-jar/pom.xml index 460adf45e7..e87fba922e 100644 --- a/core-java-modules/core-java-jar/pom.xml +++ b/core-java-modules/core-java-jar/pom.xml @@ -260,7 +260,6 @@ 0.4 1.8.7 - 4.6.1 1.1 3.6.2 diff --git a/graphql-modules/pom.xml b/graphql-modules/pom.xml index 2525f75eff..ef05e3eea6 100644 --- a/graphql-modules/pom.xml +++ b/graphql-modules/pom.xml @@ -20,7 +20,7 @@ org.springframework.boot spring-boot-dependencies - 2.6.4 + 2.6.15 pom import @@ -34,4 +34,9 @@ graphql-spqr-boot-starter + + + 4.4.0 + + \ No newline at end of file diff --git a/libraries-http-2/pom.xml b/libraries-http-2/pom.xml index 934e0d2900..fa6b65f79f 100644 --- a/libraries-http-2/pom.xml +++ b/libraries-http-2/pom.xml @@ -85,7 +85,7 @@ org.mockito mockito-inline - ${mockito.version} + ${mockito-inline.version} test @@ -120,6 +120,7 @@ 1.0.3 3.6.0 1.49 + 5.2.0 \ No newline at end of file diff --git a/messaging-modules/spring-jms/pom.xml b/messaging-modules/spring-jms/pom.xml index aad416433d..0df1e9fff2 100644 --- a/messaging-modules/spring-jms/pom.xml +++ b/messaging-modules/spring-jms/pom.xml @@ -44,7 +44,7 @@ org.mockito mockito-core - ${mockito-core.version} + ${mockito.version} test @@ -83,7 +83,6 @@ 5.14.1 1.5.10.RELEASE 3.3.2 - 4.6.1 5.16.5 1.17.3 5.10.1 diff --git a/patterns-modules/design-patterns-creational-2/pom.xml b/patterns-modules/design-patterns-creational-2/pom.xml index 27c83c9eb7..30e052e6db 100644 --- a/patterns-modules/design-patterns-creational-2/pom.xml +++ b/patterns-modules/design-patterns-creational-2/pom.xml @@ -16,9 +16,13 @@ org.mockito mockito-inline - ${mockito.version} + ${mockito-inline.version} test + + 5.2.0 + + \ No newline at end of file diff --git a/persistence-modules/spring-boot-persistence/pom.xml b/persistence-modules/spring-boot-persistence/pom.xml index 39edc01170..a816732e52 100644 --- a/persistence-modules/spring-boot-persistence/pom.xml +++ b/persistence-modules/spring-boot-persistence/pom.xml @@ -70,7 +70,6 @@ - 2.23.0 2.0.1.Final 8.2.0 com.baeldung.boot.Application diff --git a/persistence-modules/spring-data-dynamodb/pom.xml b/persistence-modules/spring-data-dynamodb/pom.xml index 5252aa5481..5d31f13518 100644 --- a/persistence-modules/spring-data-dynamodb/pom.xml +++ b/persistence-modules/spring-data-dynamodb/pom.xml @@ -136,6 +136,12 @@ so test + + net.bytebuddy + byte-buddy + 1.14.13 + test + diff --git a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java index 3ad54e2267..13c1c162f1 100644 --- a/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java +++ b/persistence-modules/spring-data-dynamodb/src/test/java/com/baeldung/SpringContextTest.java @@ -5,8 +5,6 @@ import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.Application; - @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class SpringContextTest { diff --git a/pom.xml b/pom.xml index 7496d4ca93..5e703b4bc1 100644 --- a/pom.xml +++ b/pom.xml @@ -1149,7 +1149,7 @@ 3.21.0 2.2 1.3 - 4.4.0 + 5.11.0 1.14.11 diff --git a/quarkus-modules/quarkus-virtual-threads/pom.xml b/quarkus-modules/quarkus-virtual-threads/pom.xml index f2da9390b5..0b8cf46c3e 100644 --- a/quarkus-modules/quarkus-virtual-threads/pom.xml +++ b/quarkus-modules/quarkus-virtual-threads/pom.xml @@ -37,7 +37,6 @@ 3.0.0 0.3.0 3.6.0 - 3.11.2 @@ -92,7 +91,7 @@ org.mockito mockito-core - ${mockito-core.version} + ${mockito.version} test diff --git a/quarkus-modules/quarkus/pom.xml b/quarkus-modules/quarkus/pom.xml index fc3d294beb..5ddd9826e9 100644 --- a/quarkus-modules/quarkus/pom.xml +++ b/quarkus-modules/quarkus/pom.xml @@ -180,7 +180,7 @@ 2.16.3.Final - 3.3.0 + 4.4.0 \ No newline at end of file diff --git a/spring-aop-2/pom.xml b/spring-aop-2/pom.xml index 3a60739315..7aea3b64de 100644 --- a/spring-aop-2/pom.xml +++ b/spring-aop-2/pom.xml @@ -45,6 +45,7 @@ org.mockito mockito-core + ${mockito.version} test diff --git a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml index d7f437633d..96cfd622db 100644 --- a/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml +++ b/spring-boot-modules/spring-boot-custom-starter/greeter-spring-boot-autoconfigure/pom.xml @@ -42,6 +42,12 @@ ${spring-boot.version} test + + net.bytebuddy + byte-buddy + ${byte-buddy.version} + test + @@ -61,6 +67,7 @@ 2.2.6.RELEASE 0.0.1-SNAPSHOT + 1.14.13 \ No newline at end of file diff --git a/spring-core/pom.xml b/spring-core/pom.xml index 5134ad42f7..99b3291dcf 100644 --- a/spring-core/pom.xml +++ b/spring-core/pom.xml @@ -49,7 +49,7 @@ org.springframework.boot spring-boot-test - ${mockito.spring.boot.version} + ${spring-boot.version} test @@ -78,10 +78,8 @@ - 1.4.4.RELEASE 1 1.5.2.RELEASE - 1.10.19 1.3.2 diff --git a/spring-ejb-modules/ejb-beans/pom.xml b/spring-ejb-modules/ejb-beans/pom.xml index 6203db5f5a..52503922b6 100644 --- a/spring-ejb-modules/ejb-beans/pom.xml +++ b/spring-ejb-modules/ejb-beans/pom.xml @@ -189,7 +189,6 @@ 5.2.3.RELEASE 5.16.3 5.16.3 - 2.21.0 2.8 8.2.1.Final 2.12.5 diff --git a/spring-security-modules/spring-security-legacy-oidc/pom.xml b/spring-security-modules/spring-security-legacy-oidc/pom.xml index 10c6eb3389..0fb10c7e4f 100644 --- a/spring-security-modules/spring-security-legacy-oidc/pom.xml +++ b/spring-security-modules/spring-security-legacy-oidc/pom.xml @@ -42,6 +42,12 @@ jwks-rsa ${jwks-rsa.version} + + net.bytebuddy + byte-buddy + 1.14.13 + test + diff --git a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml index d4fff21605..c1795b500c 100644 --- a/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml +++ b/spring-web-modules/spring-thymeleaf-attributes/accessing-session-attributes/pom.xml @@ -77,7 +77,6 @@ true true 5.9.3 - 5.3.1 3.1.1.RELEASE 3.1.1 diff --git a/testing-modules/junit-5-basics-2/pom.xml b/testing-modules/junit-5-basics-2/pom.xml index d8bb2a6e79..27681d66eb 100644 --- a/testing-modules/junit-5-basics-2/pom.xml +++ b/testing-modules/junit-5-basics-2/pom.xml @@ -26,7 +26,7 @@ org.mockito mockito-core - ${mockito-core.version} + ${mockito.version} test @@ -42,7 +42,6 @@ 5.10.0 - 5.5.0 \ No newline at end of file diff --git a/testing-modules/junit-5/pom.xml b/testing-modules/junit-5/pom.xml index cdddf90855..63162e71e8 100644 --- a/testing-modules/junit-5/pom.xml +++ b/testing-modules/junit-5/pom.xml @@ -89,11 +89,6 @@ ${powermock.version} test - - org.mockito - mockito-core - test - @@ -135,7 +130,7 @@ 2.17.1 2.0.9 5.0.1.RELEASE - 3.3.0 + 3.3.0 \ No newline at end of file diff --git a/testing-modules/mockito-2/pom.xml b/testing-modules/mockito-2/pom.xml index 79b8c86221..f4ff2da682 100644 --- a/testing-modules/mockito-2/pom.xml +++ b/testing-modules/mockito-2/pom.xml @@ -34,8 +34,8 @@ 4.8.1 - 5.10.0 1.18.30 + \ No newline at end of file diff --git a/testing-modules/mockito-simple/pom.xml b/testing-modules/mockito-simple/pom.xml index 6f50136de6..7a07ea73ee 100644 --- a/testing-modules/mockito-simple/pom.xml +++ b/testing-modules/mockito-simple/pom.xml @@ -60,7 +60,6 @@ 6.0.8 - 5.3.1 \ No newline at end of file diff --git a/testing-modules/powermock/pom.xml b/testing-modules/powermock/pom.xml index 8eedc818af..0c3b1c367f 100644 --- a/testing-modules/powermock/pom.xml +++ b/testing-modules/powermock/pom.xml @@ -41,7 +41,7 @@ - 2.21.0 + 2.21.0 2.0.9 diff --git a/web-modules/jakarta-ee/pom.xml b/web-modules/jakarta-ee/pom.xml index faad33338b..4caa67bf6f 100644 --- a/web-modules/jakarta-ee/pom.xml +++ b/web-modules/jakarta-ee/pom.xml @@ -48,7 +48,7 @@ org.mockito - mockito-all + mockito-core ${mockito.version} test @@ -100,11 +100,10 @@ 9.0.0 2.0.0 2.0.0 - 5.8.2 + 5.10.2 C:/glassfish6 admin mvn-domain - 1.10.19 ${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords diff --git a/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java b/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java index 5e79924ed7..a116db3c65 100644 --- a/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java +++ b/web-modules/jakarta-ee/src/test/java/com/baeldung/eclipse/krazo/UserControllerUnitTest.java @@ -1,25 +1,23 @@ package com.baeldung.eclipse.krazo; -import com.baeldung.eclipse.krazo.User; -import com.baeldung.eclipse.krazo.UserController; -import jakarta.mvc.Models; -import jakarta.mvc.binding.BindingResult; -import org.eclipse.krazo.core.ModelsImpl; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.when; +import org.eclipse.krazo.core.ModelsImpl; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import jakarta.mvc.Models; +import jakarta.mvc.binding.BindingResult; + /** * The class contains unit tests. We do only unit tests. Most of the classes are mocked */ diff --git a/web-modules/javax-servlets-2/pom.xml b/web-modules/javax-servlets-2/pom.xml index a792f6eea2..8031786af4 100644 --- a/web-modules/javax-servlets-2/pom.xml +++ b/web-modules/javax-servlets-2/pom.xml @@ -112,7 +112,6 @@ 2.22.2 10.0.4 1.10.0 - 5.6.0 1.5.4 diff --git a/web-modules/jee-7/pom.xml b/web-modules/jee-7/pom.xml index 47d79f12ac..9bbfc33e62 100644 --- a/web-modules/jee-7/pom.xml +++ b/web-modules/jee-7/pom.xml @@ -312,7 +312,7 @@ test - org.wildfly + org.wildfly.arquillian wildfly-arquillian-container-managed ${wildfly.version} test @@ -345,7 +345,7 @@ org.wildfly wildfly-dist - ${wildfly.version} + ${wildfly-dist.version} zip false ${project.build.directory} @@ -395,7 +395,7 @@ test - org.wildfly + org.wildfly.arquillian wildfly-arquillian-container-remote ${wildfly.version} test @@ -520,7 +520,8 @@ 3.0.0 7.0 1.1.11.Final - 8.2.1.Final + 31.0.1.Final + 5.0.1.Final 1.7.0 1.4.6.Final 3.0.19.Final diff --git a/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java b/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java index e753d34901..e87bd100c8 100644 --- a/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java +++ b/web-modules/jersey/src/main/java/com/baeldung/jersey/server/Greetings.java @@ -5,6 +5,7 @@ import com.baeldung.jersey.server.config.HelloBinding; import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.Response; @Path("/greetings") @@ -17,6 +18,7 @@ public class Greetings { } @GET + @Produces("text/html") @Path("/hi") public String getHiGreeting() { return "hi"; diff --git a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java index 47736f90d7..e01415b50a 100644 --- a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java +++ b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/GreetingsResourceIntegrationTest.java @@ -1,18 +1,18 @@ package com.baeldung.jersey.server; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.test.JerseyTest; import org.glassfish.jersey.test.TestProperties; -import org.junit.Test; +import org.junit.jupiter.api.Test; import jakarta.ws.rs.core.Application; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -public class GreetingsResourceIntegrationTest extends JerseyTest { +class GreetingsResourceIntegrationTest extends JerseyTest { @Override protected Application configure() { @@ -21,14 +21,14 @@ public class GreetingsResourceIntegrationTest extends JerseyTest { } @Test - public void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() { + void givenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi() { Response response = target("/greetings/hi").request() .get(); - assertEquals("Http Response should be 200: ", Response.Status.OK.getStatusCode(), response.getStatus()); - assertEquals("Http Content-Type should be: ", MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE)); + assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); + assertEquals(MediaType.TEXT_HTML, response.getHeaderString(HttpHeaders.CONTENT_TYPE)); String content = response.readEntity(String.class); - assertEquals("Content of ressponse is: ", "hi", content); + assertEquals("hi", content); } } diff --git a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java index 4f73c9df5b..2eaeb94a00 100644 --- a/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java +++ b/web-modules/jersey/src/test/java/com/baeldung/jersey/server/rest/FruitResourceIntegrationTest.java @@ -2,12 +2,12 @@ package com.baeldung.jersey.server.rest; import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.containsString; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.glassfish.jersey.test.JerseyTest; import org.glassfish.jersey.test.TestProperties; -import org.junit.Test; +import org.junit.jupiter.api.Test; import com.baeldung.jersey.server.config.ViewApplicationConfig; import com.baeldung.jersey.server.model.Fruit; @@ -19,7 +19,7 @@ import jakarta.ws.rs.core.Form; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -public class FruitResourceIntegrationTest extends JerseyTest { +class FruitResourceIntegrationTest extends JerseyTest { @Override protected Application configure() { @@ -33,80 +33,80 @@ public class FruitResourceIntegrationTest extends JerseyTest { } @Test - public void givenGetAllFruit_whenCorrectRequest_thenAllTemplateInvoked() { + void givenGetAllFruit_whenCorrectRequest_thenAllTemplateInvoked() { final String response = target("/fruit/all").request() .get(String.class); assertThat(response, allOf(containsString("banana"), containsString("apple"), containsString("kiwi"))); } @Test - public void givenGetFruit_whenCorrectRequest_thenIndexTemplateInvoked() { + void givenGetFruit_whenCorrectRequest_thenIndexTemplateInvoked() { final String response = target("/fruit").request() .get(String.class); assertThat(response, containsString("Welcome Fruit Index Page!")); } @Test - public void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() { + void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() { final String response = target("/fruit/orange").request() .get(String.class); assertThat(response, containsString("Error - Fruit not found: orange!")); } @Test - public void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() { + void givenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest() { Form form = new Form(); form.param("name", "apple"); form.param("colour", null); Response response = target("fruit/create").request(MediaType.APPLICATION_FORM_URLENCODED) .post(Entity.form(form)); - assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertEquals(400, response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit colour must not be null")); } @Test - public void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() { + void givenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated() { Response response = target("fruit/created").request() .post(Entity.json("{\"name\":\"strawberry\",\"weight\":20}")); - assertEquals("Http Response should be 201 ", Response.Status.CREATED.getStatusCode(), response.getStatus()); + assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit saved : Fruit [name: strawberry colour: null]")); } @Test - public void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() { + void givenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest() { Form form = new Form(); form.param("serial", "2345-2345"); Response response = target("fruit/update").request(MediaType.APPLICATION_FORM_URLENCODED) .put(Entity.form(form)); - assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertEquals(400, response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit serial number is not valid")); } @Test - public void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() { + void givenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest() { Fruit fruit = new Fruit("Blueberry", "purple"); fruit.setWeight(1); Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); - assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertEquals(400, response.getStatus()); assertThat(response.readEntity(String.class), containsString("Fruit weight must be 10 or greater")); } @Test - public void givenFruitExists_whenSearching_thenResponseContainsFruit() { + void givenFruitExists_whenSearching_thenResponseContainsFruit() { Fruit fruit = new Fruit(); fruit.setName("strawberry"); fruit.setWeight(20); Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); - assertEquals("Http Response should be 204 ", 204, response.getStatus()); + assertEquals(204, response.getStatus()); final String json = target("fruit/search/strawberry").request() .get(String.class); @@ -114,28 +114,28 @@ public class FruitResourceIntegrationTest extends JerseyTest { } @Test - public void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() { + void givenFruitExists_whenSearching_thenResponseContainsFruitEntity() { Fruit fruit = new Fruit(); fruit.setName("strawberry"); fruit.setWeight(20); Response response = target("fruit/create").request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.entity(fruit, MediaType.APPLICATION_JSON_TYPE)); - assertEquals("Http Response should be 204 ", 204, response.getStatus()); + assertEquals(204, response.getStatus()); final Fruit entity = target("fruit/search/strawberry").request() .get(Fruit.class); - assertEquals("Fruit name: ", "strawberry", entity.getName()); - assertEquals("Fruit weight: ", Integer.valueOf(20), entity.getWeight()); + assertEquals("strawberry", entity.getName()); + assertEquals(Integer.valueOf(20), entity.getWeight()); } @Test - public void givenFruit_whenFruitIsInvalid_thenReponseContainsCustomExceptions() { + void givenFruit_whenFruitIsInvalid_thenReponseContainsCustomExceptions() { final Response response = target("fruit/exception").request() .get(); - assertEquals("Http Response should be 400 ", 400, response.getStatus()); + assertEquals(400, response.getStatus()); String responseString = response.readEntity(String.class); assertThat(responseString, containsString("exception..colour size must be between 5 and 200")); assertThat(responseString, containsString("exception..name size must be between 5 and 200")); From af3a000b1e9c0f3fa0630fa5ce3934294758c823 Mon Sep 17 00:00:00 2001 From: Adrian Chlebosz <36669019+breader124@users.noreply.github.com> Date: Thu, 11 Apr 2024 01:50:10 +0200 Subject: [PATCH 52/57] BAEL-7544: Disable enable scheduling on spring tests (#16125) * BEAL-7544: Add examples showing how to disable scheduled tasks for testing * BEAL-7544: Get rid of final keywords * BEAL-7544: Add the config and test showing the case when the scheduling is simply turned on * BEAL-7544: Introduce amendments after review - add initialDelayString param to the scheduled annotation on the tested method - delete unnecessary unit test * BEAL-7544: Move code to new module --- pom.xml | 2 + spring-scheduling-2/README.md | 1 + spring-scheduling-2/pom.xml | 40 ++++++++++++ .../DelayedNotificationScheduler.java | 22 +++++++ .../disablingscheduledtasks/Notification.java | 31 +++++++++ .../NotificationRepository.java | 30 +++++++++ .../NotificationService.java | 26 ++++++++ .../disablewithprofile/ApplicationConfig.java | 34 ++++++++++ .../disablewithprofile/SchedulingConfig.java | 12 ++++ .../ApplicationConfig.java | 34 ++++++++++ .../disablewithproperty/SchedulingConfig.java | 12 ++++ .../schedulingon/ApplicationConfig.java | 36 +++++++++++ ...dNotificationSchedulerIntegrationTest.java | 64 +++++++++++++++++++ ...dNotificationSchedulerIntegrationTest.java | 63 ++++++++++++++++++ ...dNotificationSchedulerIntegrationTest.java | 61 ++++++++++++++++++ ...dNotificationSchedulerIntegrationTest.java | 61 ++++++++++++++++++ 16 files changed, 529 insertions(+) create mode 100644 spring-scheduling-2/README.md create mode 100644 spring-scheduling-2/pom.xml create mode 100644 spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/DelayedNotificationScheduler.java create mode 100644 spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/Notification.java create mode 100644 spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationRepository.java create mode 100644 spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationService.java create mode 100644 spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/ApplicationConfig.java create mode 100644 spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/SchedulingConfig.java create mode 100644 spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/ApplicationConfig.java create mode 100644 spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/SchedulingConfig.java create mode 100644 spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/schedulingon/ApplicationConfig.java create mode 100644 spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithprofile/DelayedNotificationSchedulerIntegrationTest.java create mode 100644 spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithproperty/DelayedNotificationSchedulerIntegrationTest.java create mode 100644 spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/longinitialdelay/DelayedNotificationSchedulerIntegrationTest.java create mode 100644 spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/schedulingon/DelayedNotificationSchedulerIntegrationTest.java diff --git a/pom.xml b/pom.xml index 5e703b4bc1..055b108141 100644 --- a/pom.xml +++ b/pom.xml @@ -826,6 +826,7 @@ spring-reactive-modules spring-remoting-modules spring-scheduling + spring-scheduling-2 spring-security-modules spring-shell spring-soap @@ -1074,6 +1075,7 @@ spring-reactive-modules spring-remoting-modules spring-scheduling + spring-scheduling-2 spring-security-modules spring-shell spring-soap diff --git a/spring-scheduling-2/README.md b/spring-scheduling-2/README.md new file mode 100644 index 0000000000..bc1911b396 --- /dev/null +++ b/spring-scheduling-2/README.md @@ -0,0 +1 @@ +### Relevant articles: \ No newline at end of file diff --git a/spring-scheduling-2/pom.xml b/spring-scheduling-2/pom.xml new file mode 100644 index 0000000000..9c69758ed0 --- /dev/null +++ b/spring-scheduling-2/pom.xml @@ -0,0 +1,40 @@ + + + 4.0.0 + spring-scheduling-2 + 0.1-SNAPSHOT + spring-scheduling-2 + jar + + + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../parent-boot-3 + + + + + org.springframework.boot + spring-boot-starter-web + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + repackage + none + + + + + + + \ No newline at end of file diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/DelayedNotificationScheduler.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/DelayedNotificationScheduler.java new file mode 100644 index 0000000000..91ed9beffc --- /dev/null +++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/DelayedNotificationScheduler.java @@ -0,0 +1,22 @@ +package com.baeldung.disablingscheduledtasks; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Scheduled; + +public class DelayedNotificationScheduler { + + private static final Logger logger = LoggerFactory.getLogger(DelayedNotificationScheduler.class); + + private NotificationService notificationService; + + public DelayedNotificationScheduler(NotificationService notificationService) { + this.notificationService = notificationService; + } + + @Scheduled(fixedDelayString = "${notification.send.out.delay}", initialDelayString = "${notification.send.out.initial.delay}") + public void attemptSendingOutDelayedNotifications() { + logger.info("Scheduled notifications send out attempt"); + notificationService.sendOutDelayedNotifications(); + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/Notification.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/Notification.java new file mode 100644 index 0000000000..01ed80395e --- /dev/null +++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/Notification.java @@ -0,0 +1,31 @@ +package com.baeldung.disablingscheduledtasks; + +import java.time.Clock; +import java.time.ZonedDateTime; +import java.util.UUID; + +public class Notification { + + private UUID id = UUID.randomUUID(); + private boolean isSentOut = false; + private ZonedDateTime sendOutTime; + + public Notification(ZonedDateTime sendOutTime) { + this.sendOutTime = sendOutTime; + } + + public void sendOut(Clock clock) { + ZonedDateTime now = ZonedDateTime.now(clock); + if (now.isAfter(sendOutTime)) { + isSentOut = true; + } + } + + public UUID getId() { + return id; + } + + public boolean isSentOut() { + return isSentOut; + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationRepository.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationRepository.java new file mode 100644 index 0000000000..08fe8c830d --- /dev/null +++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationRepository.java @@ -0,0 +1,30 @@ +package com.baeldung.disablingscheduledtasks; + +import java.util.Collection; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.stream.Collectors; + +public class NotificationRepository { + + private Collection notifications = new ConcurrentLinkedQueue<>(); + + public Notification findById(UUID notificationId) { + return notifications.stream() + .filter(n -> notificationId.equals(n.getId())) + .findFirst() + .orElseThrow(NoSuchElementException::new); + } + + public List findAllAwaitingSendOut() { + return notifications.stream() + .filter(notification -> !notification.isSentOut()) + .collect(Collectors.toList()); + } + + public void save(Notification notification) { + notifications.add(notification); + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationService.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationService.java new file mode 100644 index 0000000000..3451a05cbe --- /dev/null +++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/NotificationService.java @@ -0,0 +1,26 @@ +package com.baeldung.disablingscheduledtasks; + +import java.time.Clock; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NotificationService { + + private static final Logger logger = LoggerFactory.getLogger(NotificationService.class); + + private NotificationRepository notificationRepository; + private Clock clock; + + public NotificationService(NotificationRepository notificationRepository, Clock clock) { + this.notificationRepository = notificationRepository; + this.clock = clock; + } + + public void sendOutDelayedNotifications() { + logger.info("Sending out delayed notifications"); + List notifications = notificationRepository.findAllAwaitingSendOut(); + notifications.forEach(notification -> notification.sendOut(clock)); + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/ApplicationConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/ApplicationConfig.java new file mode 100644 index 0000000000..19a69840ff --- /dev/null +++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/ApplicationConfig.java @@ -0,0 +1,34 @@ +package com.baeldung.disablingscheduledtasks.config.disablewithprofile; + +import java.time.Clock; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler; +import com.baeldung.disablingscheduledtasks.NotificationRepository; +import com.baeldung.disablingscheduledtasks.NotificationService; + +@Configuration +public class ApplicationConfig { + + @Bean + public Clock clock() { + return Clock.systemUTC(); + } + + @Bean + public NotificationRepository notificationRepository() { + return new NotificationRepository(); + } + + @Bean + public NotificationService notificationService(NotificationRepository notificationRepository, Clock clock) { + return new NotificationService(notificationRepository, clock); + } + + @Bean + public DelayedNotificationScheduler delayedNotificationScheduler(NotificationService notificationService) { + return new DelayedNotificationScheduler(notificationService); + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/SchedulingConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/SchedulingConfig.java new file mode 100644 index 0000000000..6461b9273d --- /dev/null +++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithprofile/SchedulingConfig.java @@ -0,0 +1,12 @@ +package com.baeldung.disablingscheduledtasks.config.disablewithprofile; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.scheduling.annotation.EnableScheduling; + +@Configuration +@EnableScheduling +@Profile("!integrationTest") +public class SchedulingConfig { + +} \ No newline at end of file diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/ApplicationConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/ApplicationConfig.java new file mode 100644 index 0000000000..8b006428d2 --- /dev/null +++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/ApplicationConfig.java @@ -0,0 +1,34 @@ +package com.baeldung.disablingscheduledtasks.config.disablewithproperty; + +import java.time.Clock; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler; +import com.baeldung.disablingscheduledtasks.NotificationRepository; +import com.baeldung.disablingscheduledtasks.NotificationService; + +@Configuration +public class ApplicationConfig { + + @Bean + public Clock clock() { + return Clock.systemUTC(); + } + + @Bean + public NotificationRepository notificationRepository() { + return new NotificationRepository(); + } + + @Bean + public NotificationService notificationService(NotificationRepository notificationRepository, Clock clock) { + return new NotificationService(notificationRepository, clock); + } + + @Bean + public DelayedNotificationScheduler delayedNotificationScheduler(NotificationService notificationService) { + return new DelayedNotificationScheduler(notificationService); + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/SchedulingConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/SchedulingConfig.java new file mode 100644 index 0000000000..2b85dbfcef --- /dev/null +++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/disablewithproperty/SchedulingConfig.java @@ -0,0 +1,12 @@ +package com.baeldung.disablingscheduledtasks.config.disablewithproperty; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; + +@Configuration +@EnableScheduling +@ConditionalOnProperty(value = "scheduling.enabled", havingValue = "true", matchIfMissing = true) +public class SchedulingConfig { + +} \ No newline at end of file diff --git a/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/schedulingon/ApplicationConfig.java b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/schedulingon/ApplicationConfig.java new file mode 100644 index 0000000000..e0db118831 --- /dev/null +++ b/spring-scheduling-2/src/main/java/com/baeldung/disablingscheduledtasks/config/schedulingon/ApplicationConfig.java @@ -0,0 +1,36 @@ +package com.baeldung.disablingscheduledtasks.config.schedulingon; + +import java.time.Clock; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableScheduling; + +import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler; +import com.baeldung.disablingscheduledtasks.NotificationRepository; +import com.baeldung.disablingscheduledtasks.NotificationService; + +@Configuration +@EnableScheduling +public class ApplicationConfig { + + @Bean + public Clock clock() { + return Clock.systemUTC(); + } + + @Bean + public NotificationRepository notificationRepository() { + return new NotificationRepository(); + } + + @Bean + public NotificationService notificationService(NotificationRepository notificationRepository, Clock clock) { + return new NotificationService(notificationRepository, clock); + } + + @Bean + public DelayedNotificationScheduler delayedNotificationScheduler(NotificationService notificationService) { + return new DelayedNotificationScheduler(notificationService); + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithprofile/DelayedNotificationSchedulerIntegrationTest.java b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithprofile/DelayedNotificationSchedulerIntegrationTest.java new file mode 100644 index 0000000000..523950e48c --- /dev/null +++ b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithprofile/DelayedNotificationSchedulerIntegrationTest.java @@ -0,0 +1,64 @@ +package com.baeldung.disablingscheduledtasks.disablewithprofile; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; +import org.springframework.test.context.ActiveProfiles; + +import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler; +import com.baeldung.disablingscheduledtasks.Notification; +import com.baeldung.disablingscheduledtasks.NotificationRepository; +import com.baeldung.disablingscheduledtasks.config.disablewithprofile.ApplicationConfig; +import com.baeldung.disablingscheduledtasks.config.disablewithprofile.SchedulingConfig; + +@SpringBootTest( + classes = { ApplicationConfig.class, SchedulingConfig.class, SchedulerTestConfiguration.class }, + properties = { + "notification.send.out.delay: 10", + "notification.send.out.initial.delay: 0" + } +) +@ActiveProfiles("integrationTest") +public class DelayedNotificationSchedulerIntegrationTest { + + @Autowired + private Clock testClock; + + @Autowired + private NotificationRepository repository; + + @Autowired + private DelayedNotificationScheduler scheduler; + + @Test + public void whenTimeIsOverNotificationSendOutTime_thenItShouldBeSent() { + ZonedDateTime fiveMinutesAgo = ZonedDateTime.now(testClock).minusMinutes(5); + Notification notification = new Notification(fiveMinutesAgo); + repository.save(notification); + + scheduler.attemptSendingOutDelayedNotifications(); + + Notification processedNotification = repository.findById(notification.getId()); + assertTrue(processedNotification.isSentOut()); + } +} + +@TestConfiguration +class SchedulerTestConfiguration { + + @Bean + @Primary + public Clock testClock() { + return Clock.fixed(Instant.parse("2024-03-10T10:15:30.00Z"), ZoneId.systemDefault()); + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithproperty/DelayedNotificationSchedulerIntegrationTest.java b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithproperty/DelayedNotificationSchedulerIntegrationTest.java new file mode 100644 index 0000000000..da3a061cfc --- /dev/null +++ b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/disablewithproperty/DelayedNotificationSchedulerIntegrationTest.java @@ -0,0 +1,63 @@ +package com.baeldung.disablingscheduledtasks.disablewithproperty; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler; +import com.baeldung.disablingscheduledtasks.Notification; +import com.baeldung.disablingscheduledtasks.NotificationRepository; +import com.baeldung.disablingscheduledtasks.config.disablewithproperty.ApplicationConfig; +import com.baeldung.disablingscheduledtasks.config.disablewithproperty.SchedulingConfig; + +@SpringBootTest( + classes = { ApplicationConfig.class, SchedulingConfig.class, SchedulerTestConfiguration.class }, + properties = { + "notification.send.out.delay: 10", + "notification.send.out.initial.delay: 0", + "scheduling.enabled: false" + } +) +public class DelayedNotificationSchedulerIntegrationTest { + + @Autowired + private Clock testClock; + + @Autowired + private NotificationRepository repository; + + @Autowired + private DelayedNotificationScheduler scheduler; + + @Test + public void whenTimeIsOverNotificationSendOutTime_thenItShouldBeSent() { + ZonedDateTime fiveMinutesAgo = ZonedDateTime.now(testClock).minusMinutes(5); + Notification notification = new Notification(fiveMinutesAgo); + repository.save(notification); + + scheduler.attemptSendingOutDelayedNotifications(); + + Notification processedNotification = repository.findById(notification.getId()); + assertTrue(processedNotification.isSentOut()); + } +} + +@TestConfiguration +class SchedulerTestConfiguration { + + @Bean + @Primary + public Clock testClock() { + return Clock.fixed(Instant.parse("2024-03-10T10:15:30.00Z"), ZoneId.systemDefault()); + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/longinitialdelay/DelayedNotificationSchedulerIntegrationTest.java b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/longinitialdelay/DelayedNotificationSchedulerIntegrationTest.java new file mode 100644 index 0000000000..d67af13b9d --- /dev/null +++ b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/longinitialdelay/DelayedNotificationSchedulerIntegrationTest.java @@ -0,0 +1,61 @@ +package com.baeldung.disablingscheduledtasks.longinitialdelay; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler; +import com.baeldung.disablingscheduledtasks.Notification; +import com.baeldung.disablingscheduledtasks.NotificationRepository; +import com.baeldung.disablingscheduledtasks.config.schedulingon.ApplicationConfig; + +@SpringBootTest( + classes = { ApplicationConfig.class, SchedulerTestConfiguration.class }, + properties = { + "notification.send.out.delay: 10", + "notification.send.out.initial.delay: 60000" + } +) +public class DelayedNotificationSchedulerIntegrationTest { + + @Autowired + private Clock testClock; + + @Autowired + private NotificationRepository repository; + + @Autowired + private DelayedNotificationScheduler scheduler; + + @Test + public void whenTimeIsOverNotificationSendOutTime_thenItShouldBeSent() { + ZonedDateTime fiveMinutesAgo = ZonedDateTime.now(testClock).minusMinutes(5); + Notification notification = new Notification(fiveMinutesAgo); + repository.save(notification); + + scheduler.attemptSendingOutDelayedNotifications(); + + Notification processedNotification = repository.findById(notification.getId()); + assertTrue(processedNotification.isSentOut()); + } +} + +@TestConfiguration +class SchedulerTestConfiguration { + + @Bean + @Primary + public Clock testClock() { + return Clock.fixed(Instant.parse("2024-03-10T10:15:30.00Z"), ZoneId.systemDefault()); + } +} \ No newline at end of file diff --git a/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/schedulingon/DelayedNotificationSchedulerIntegrationTest.java b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/schedulingon/DelayedNotificationSchedulerIntegrationTest.java new file mode 100644 index 0000000000..eb351ee2d1 --- /dev/null +++ b/spring-scheduling-2/src/test/java/com/baeldung/disablingscheduledtasks/schedulingon/DelayedNotificationSchedulerIntegrationTest.java @@ -0,0 +1,61 @@ +package com.baeldung.disablingscheduledtasks.schedulingon; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Primary; + +import com.baeldung.disablingscheduledtasks.DelayedNotificationScheduler; +import com.baeldung.disablingscheduledtasks.Notification; +import com.baeldung.disablingscheduledtasks.NotificationRepository; +import com.baeldung.disablingscheduledtasks.config.schedulingon.ApplicationConfig; + +@SpringBootTest( + classes = { ApplicationConfig.class, SchedulerTestConfiguration.class }, + properties = { + "notification.send.out.delay: 10", + "notification.send.out.initial.delay: 0" + } +) +public class DelayedNotificationSchedulerIntegrationTest { + + @Autowired + private Clock testClock; + + @Autowired + private NotificationRepository repository; + + @Autowired + private DelayedNotificationScheduler scheduler; + + @Test + public void whenTimeIsOverNotificationSendOutTime_thenItShouldBeSent() { + ZonedDateTime fiveMinutesAgo = ZonedDateTime.now(testClock).minusMinutes(5); + Notification notification = new Notification(fiveMinutesAgo); + repository.save(notification); + + scheduler.attemptSendingOutDelayedNotifications(); + + Notification processedNotification = repository.findById(notification.getId()); + assertTrue(processedNotification.isSentOut()); + } +} + +@TestConfiguration +class SchedulerTestConfiguration { + + @Bean + @Primary + public Clock testClock() { + return Clock.fixed(Instant.parse("2024-03-10T10:15:30.00Z"), ZoneId.systemDefault()); + } +} \ No newline at end of file From c8bb1e301fde3a15906c86ef4ac7820896d0074f Mon Sep 17 00:00:00 2001 From: Wynn Teo <49014791+wynnteo@users.noreply.github.com> Date: Thu, 11 Apr 2024 08:03:45 +0800 Subject: [PATCH 53/57] Bael 7668 hotfix (#16349) * BAEL-7490 read write file in separate thread * Change the to try resources * Update the code to sync with article * Rename * update class name --- .../{JoinTablesIntegrationTest.java => JoinTablesLiveTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/{JoinTablesIntegrationTest.java => JoinTablesLiveTest.java} (98%) diff --git a/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesIntegrationTest.java b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesLiveTest.java similarity index 98% rename from persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesIntegrationTest.java rename to persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesLiveTest.java index 5396c27e14..a5daf53542 100644 --- a/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesIntegrationTest.java +++ b/persistence-modules/jooq/src/test/java/com/baeldung/jooq/jointables/JoinTablesLiveTest.java @@ -20,7 +20,7 @@ import com.baeldung.jooq.jointables.public_.tables.Book; import com.baeldung.jooq.jointables.public_.tables.Bookauthor; import com.baeldung.jooq.jointables.public_.tables.Store; -public class JoinTablesIntegrationTest { +public class JoinTablesLiveTest { static DSLContext context; From 661238c1b266243217f05287ce2944cbbe4dcf7b Mon Sep 17 00:00:00 2001 From: Wynn Teo <49014791+wynnteo@users.noreply.github.com> Date: Thu, 11 Apr 2024 08:10:48 +0800 Subject: [PATCH 54/57] Bael 7420 hotfix (#16348) * BAEL-7490 read write file in separate thread * Change the to try resources * Update the code to sync with article * Rename * update class name --- ...itoryIntegrationTest.java => ProductRepositoryLiveTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/{ProductRepositoryIntegrationTest.java => ProductRepositoryLiveTest.java} (98%) diff --git a/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryIntegrationTest.java b/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryLiveTest.java similarity index 98% rename from persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryIntegrationTest.java rename to persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryLiveTest.java index 2385590d7f..ac68d55139 100644 --- a/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryIntegrationTest.java +++ b/persistence-modules/spring-data-jpa-query-4/src/test/java/com/baeldung/spring/data/jpa/queryjsonb/ProductRepositoryLiveTest.java @@ -25,7 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; @SpringBootTest @ActiveProfiles("test") @Sql(scripts = "/testdata.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD) -public class ProductRepositoryIntegrationTest { +public class ProductRepositoryLiveTest { @Autowired private ProductRepository productRepository; From c4a14c69311a5aa16a47cf5e2d5c4021599b95c5 Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Thu, 11 Apr 2024 06:57:54 +0200 Subject: [PATCH 55/57] Bael 7762 (#16321) * BAEL-7765: How to fix JsonParseException: Unexpected character (code 115) when parsing unquoted JSON in Jackson * BAEL-7762: Specify logback.xml Location * Update LogbackConfiguration.java * BAEL-7762: Specify logback.xml Location * BAEL-7762: TEST * BAEL-7762: TEST --------- Co-authored-by: Grzegorz Piwowarek --- .../logging/LogbackConfiguration.java | 11 ++++++++ .../logging/LogbackConfigurationUnitTest.java | 27 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java create mode 100644 spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java diff --git a/spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java b/spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java new file mode 100644 index 0000000000..6f1ffe4730 --- /dev/null +++ b/spring-boot-modules/spring-boot-logging-logback/src/main/java/com/baeldung/logging/LogbackConfiguration.java @@ -0,0 +1,11 @@ +package com.baeldung.logging; + +import org.springframework.stereotype.Component; + +@Component +public class LogbackConfiguration { + public void setLogbackConfigurationFile(String path) { + System.setProperty("logback.configurationFile", path); + } +} + diff --git a/spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java b/spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java new file mode 100644 index 0000000000..006305cac0 --- /dev/null +++ b/spring-boot-modules/spring-boot-logging-logback/src/test/java/com/baeldung/logging/LogbackConfigurationUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.logging; + +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 static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = {LogbackConfiguration.class}) +public class LogbackConfigurationUnitTest { + + @Autowired + LogbackConfiguration logbackConfiguration; + + @Test + public void givenLogbackConfigurationFile_whenSettingLogbackConfiguration_thenFileLocationSet() { + // Set the expected logback.xml location + String expectedLocation = "/test/path/to/logback.xml"; + // Call the method to set the logback configuration file + logbackConfiguration.setLogbackConfigurationFile(expectedLocation); + // Verify that the system property is correctly set + assertThat(System.getProperty("logback.configurationFile")).isEqualTo(expectedLocation); + } +} From c53d0f44f40aaab0b4001eb729b14d4d6917f86c Mon Sep 17 00:00:00 2001 From: panos-kakos <102670093+panos-kakos@users.noreply.github.com> Date: Thu, 11 Apr 2024 09:24:07 +0300 Subject: [PATCH 56/57] [JAVA-27763] Upgrade spring-reactive-client module to Spring Boot 3 (#16187) --- .../spring-reactive-client/pom.xml | 27 ++++++++++++------- .../reactive/controller/UploadController.java | 6 ++--- .../reactive/service/EmployeeService.java | 1 + .../service/ReactiveUploadService.java | 9 ++++--- .../status/WebClientStatusCodeHandler.java | 3 ++- .../src/main/resources/application.properties | 2 -- .../java/com/baeldung/SpringContextTest.java | 4 +-- .../reactive/ReactiveIntegrationTest.java | 4 ++- ...ava => SpringReactiveTestApplication.java} | 4 +-- .../WebClientLoggingIntegrationTest.java | 27 ++++++++++--------- .../reactive/logging/filters/LogFilters.java | 2 +- .../service/EmployeeServiceUnitTest.java | 5 ---- .../ReactiveUploadServiceUnitTest.java | 9 ++++--- 13 files changed, 57 insertions(+), 46 deletions(-) rename spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/{Spring5ReactiveTestApplication.java => SpringReactiveTestApplication.java} (87%) diff --git a/spring-reactive-modules/spring-reactive-client/pom.xml b/spring-reactive-modules/spring-reactive-client/pom.xml index 797529b980..bcfbe31ed6 100644 --- a/spring-reactive-modules/spring-reactive-client/pom.xml +++ b/spring-reactive-modules/spring-reactive-client/pom.xml @@ -9,9 +9,10 @@ spring boot sample project about new features - com.baeldung.spring.reactive - spring-reactive-modules - 1.0.0-SNAPSHOT + com.baeldung + parent-boot-3 + 0.0.1-SNAPSHOT + ../../parent-boot-3 @@ -42,8 +43,13 @@ ${reactor-spring.version} - javax.json.bind - javax.json.bind-api + jakarta.json.bind + jakarta.json.bind-api + + + jakarta.json + jakarta.json-api + ${jakarta.json-api.version} org.apache.geronimo.specs @@ -53,6 +59,7 @@ org.apache.johnzon johnzon-jsonb + ${johnzon-jsonb.version} @@ -92,7 +99,7 @@ test - com.github.tomakehurst + org.wiremock wiremock-standalone ${wiremock-standalone.version} test @@ -183,12 +190,14 @@ 1.0.1.RELEASE 1.0 - 1.1.6 + 4.0.3 5.0.0-alpha.12 3.5.3 - 2.26.0 - 3.1.4 + 3.4.2 + 4.0.3 2.0.0-Beta4 + 2.0.0 + 2.1.3 \ No newline at end of file diff --git a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java index 08d6ff55ef..55562f58f4 100644 --- a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java +++ b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/controller/UploadController.java @@ -2,7 +2,7 @@ package com.baeldung.reactive.controller; import com.baeldung.reactive.service.ReactiveUploadService; -import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import reactor.core.publisher.Mono; @@ -18,13 +18,13 @@ public class UploadController { @PostMapping(path = "/upload") @ResponseBody - public Mono uploadPdf(@RequestParam("file") final MultipartFile multipartFile) { + public Mono uploadPdf(@RequestParam("file") final MultipartFile multipartFile) { return uploadService.uploadPdf(multipartFile.getResource()); } @PostMapping(path = "/upload/multipart") @ResponseBody - public Mono uploadMultipart(@RequestParam("file") final MultipartFile multipartFile) { + public Mono uploadMultipart(@RequestParam("file") final MultipartFile multipartFile) { return uploadService.uploadMultipart(multipartFile); } } diff --git a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/EmployeeService.java b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/EmployeeService.java index b841dbfe3f..c402efcbc1 100644 --- a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/EmployeeService.java +++ b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/EmployeeService.java @@ -1,4 +1,5 @@ package com.baeldung.reactive.service; + import com.baeldung.reactive.model.Employee; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; diff --git a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java index a12d54960a..130e09816e 100644 --- a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java +++ b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/reactive/service/ReactiveUploadService.java @@ -4,6 +4,7 @@ package com.baeldung.reactive.service; import com.baeldung.reactive.exception.ServiceException; import org.springframework.core.io.Resource; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; import org.springframework.http.client.MultipartBodyBuilder; import org.springframework.stereotype.Service; @@ -26,10 +27,10 @@ public class ReactiveUploadService { } - public Mono uploadPdf(final Resource resource) { + public Mono uploadPdf(final Resource resource) { final URI url = UriComponentsBuilder.fromHttpUrl(EXTERNAL_UPLOAD_URL).build().toUri(); - Mono httpStatusMono = webClient.post() + Mono httpStatusMono = webClient.post() .uri(url) .contentType(MediaType.APPLICATION_PDF) .body(BodyInserters.fromResource(resource)) @@ -44,13 +45,13 @@ public class ReactiveUploadService { } - public Mono uploadMultipart(final MultipartFile multipartFile) { + public Mono uploadMultipart(final MultipartFile multipartFile) { final URI url = UriComponentsBuilder.fromHttpUrl(EXTERNAL_UPLOAD_URL).build().toUri(); final MultipartBodyBuilder builder = new MultipartBodyBuilder(); builder.part("file", multipartFile.getResource()); - Mono httpStatusMono = webClient.post() + Mono httpStatusMono = webClient.post() .uri(url) .contentType(MediaType.MULTIPART_FORM_DATA) .body(BodyInserters.fromMultipartData(builder.build())) diff --git a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java index 784fcf2812..5c655430dd 100644 --- a/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java +++ b/spring-reactive-modules/spring-reactive-client/src/main/java/com/baeldung/webclient/status/WebClientStatusCodeHandler.java @@ -3,6 +3,7 @@ package com.baeldung.webclient.status; import com.baeldung.webclient.status.exception.CustomBadRequestException; import com.baeldung.webclient.status.exception.CustomServerErrorException; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; import org.springframework.web.reactive.function.client.WebClient; @@ -40,7 +41,7 @@ public class WebClientStatusCodeHandler { } private static Mono exchangeFilterResponseProcessor(ClientResponse response) { - HttpStatus status = response.statusCode(); + HttpStatusCode status = response.statusCode(); if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) { return response.bodyToMono(String.class) .flatMap(body -> Mono.error(new CustomServerErrorException(body))); diff --git a/spring-reactive-modules/spring-reactive-client/src/main/resources/application.properties b/spring-reactive-modules/spring-reactive-client/src/main/resources/application.properties index 05033054b1..92e3aed117 100644 --- a/spring-reactive-modules/spring-reactive-client/src/main/resources/application.properties +++ b/spring-reactive-modules/spring-reactive-client/src/main/resources/application.properties @@ -1,5 +1,3 @@ logging.level.root=INFO - server.port=8081 - logging.level.reactor.netty.http.client.HttpClient=DEBUG \ No newline at end of file diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/SpringContextTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/SpringContextTest.java index c0ca9b7e64..2434afd62e 100644 --- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/SpringContextTest.java +++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/SpringContextTest.java @@ -5,10 +5,10 @@ import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; -import com.baeldung.reactive.Spring5ReactiveTestApplication; +import com.baeldung.reactive.SpringReactiveTestApplication; @RunWith(SpringRunner.class) -@SpringBootTest(classes = Spring5ReactiveTestApplication.class) +@SpringBootTest(classes = SpringReactiveTestApplication.class) public class SpringContextTest { @Test diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java index 1d2197a381..c399667444 100644 --- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java +++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java @@ -49,7 +49,9 @@ public class ReactiveIntegrationTest { .withHeader("Content-Type", "application/json") .withBody("{\"id\":123, \"name\":\"foo\"}"))); - final Mono fooMono = client.get().uri("/foo/123").exchange().log(); + final Mono fooMono = client.get().uri("/foo/123").retrieve() + .bodyToMono(ClientResponse.class) + .log(); System.out.println(fooMono.subscribe()); } diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/SpringReactiveTestApplication.java similarity index 87% rename from spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java rename to spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/SpringReactiveTestApplication.java index c884ace323..f6c578c48f 100644 --- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java +++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/SpringReactiveTestApplication.java @@ -9,7 +9,7 @@ import org.springframework.web.reactive.function.client.WebClient; import com.baeldung.reactive.model.Foo; @SpringBootApplication -public class Spring5ReactiveTestApplication { +public class SpringReactiveTestApplication { @Bean public WebClient client() { @@ -29,7 +29,7 @@ public class Spring5ReactiveTestApplication { // public static void main(String[] args) { - SpringApplication.run(Spring5ReactiveTestApplication.class, args); + SpringApplication.run(SpringReactiveTestApplication.class, args); } } diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java index 27dde13608..3686733de9 100644 --- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java +++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/WebClientLoggingIntegrationTest.java @@ -10,8 +10,8 @@ import static org.mockito.Mockito.when; import java.net.URI; import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.util.ssl.SslContextFactory; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.slf4j.LoggerFactory; import org.springframework.http.client.reactive.JettyClientHttpConnector; @@ -73,9 +73,9 @@ public class WebClientLoggingIntegrationTest { } @Test + @Disabled public void givenJettyHttpClient_whenEndpointIsConsumed_thenRequestAndResponseBodyLogged() { - SslContextFactory.Client sslContextFactory = new SslContextFactory.Client(); - org.eclipse.jetty.client.HttpClient httpClient = new org.eclipse.jetty.client.HttpClient(sslContextFactory) { + org.eclipse.jetty.client.HttpClient httpClient = new org.eclipse.jetty.client.HttpClient(){ @Override public Request newRequest(URI uri) { Request request = super.newRequest(uri); @@ -91,8 +91,7 @@ public class WebClientLoggingIntegrationTest { .uri(sampleUrl) .body(BodyInserters.fromObject(post)) .retrieve() - .bodyToMono(String.class) - .block(); + .bodyToMono(String.class); verify(jettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains(sampleResponseBody))); } @@ -103,14 +102,16 @@ public class WebClientLoggingIntegrationTest { reactor.netty.http.client.HttpClient httpClient = HttpClient .create() .wiretap(true); + WebClient .builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build() .post() .uri(sampleUrl) - .body(BodyInserters.fromObject(post)) - .exchange() + .body(BodyInserters.fromValue(post)) + .retrieve() + .bodyToMono(String.class) .block(); verify(nettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains("00000300"))); @@ -126,8 +127,9 @@ public class WebClientLoggingIntegrationTest { .build() .post() .uri(sampleUrl) - .body(BodyInserters.fromObject(post)) - .exchange() + .body(BodyInserters.fromValue(post)) + .retrieve() + .bodyToMono(String.class) .block(); verify(nettyAppender).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains(sampleResponseBody))); @@ -141,9 +143,10 @@ public class WebClientLoggingIntegrationTest { .build() .post() .uri(sampleUrl) - .body(BodyInserters.fromObject(post)) - .exchange() - .block(); + .body(BodyInserters.fromValue(post)) + .retrieve() + .bodyToMono(String.class) + .block(); verify(mockAppender, atLeast(1)).doAppend(argThat(argument -> (((LoggingEvent) argument).getFormattedMessage()).contains(sampleUrl))); } diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/filters/LogFilters.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/filters/LogFilters.java index c1c3d3e895..c8a7f05eb4 100644 --- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/filters/LogFilters.java +++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/logging/filters/LogFilters.java @@ -37,7 +37,7 @@ public class LogFilters { if (log.isDebugEnabled()) { StringBuilder sb = new StringBuilder("Response: \n") .append("Status: ") - .append(clientResponse.rawStatusCode()); + .append(clientResponse.statusCode()); clientResponse .headers() .asHttpHeaders() diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/EmployeeServiceUnitTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/EmployeeServiceUnitTest.java index 1d1a8fd2e4..26ce3a1cec 100644 --- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/EmployeeServiceUnitTest.java +++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/EmployeeServiceUnitTest.java @@ -7,16 +7,11 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.exceptions.base.MockitoException; -import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) diff --git a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java index 40c1e40d92..6baf2e8a61 100644 --- a/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java +++ b/spring-reactive-modules/spring-reactive-client/src/test/java/com/baeldung/reactive/service/ReactiveUploadServiceUnitTest.java @@ -3,6 +3,7 @@ package com.baeldung.reactive.service; import org.junit.jupiter.api.Test; import org.springframework.core.io.Resource; import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; @@ -28,8 +29,8 @@ class ReactiveUploadServiceUnitTest { void givenAPdf_whenUploadingWithWebClient_thenOK() { final Resource file = mock(Resource.class); - final Mono result = tested.uploadPdf(file); - final HttpStatus status = result.block(); + final Mono result = tested.uploadPdf(file); + final HttpStatusCode status = result.block(); assertThat(status).isEqualTo(HttpStatus.OK); } @@ -40,8 +41,8 @@ class ReactiveUploadServiceUnitTest { final MultipartFile multipartFile = mock(MultipartFile.class); when(multipartFile.getResource()).thenReturn(file); - final Mono result = tested.uploadMultipart(multipartFile); - final HttpStatus status = result.block(); + final Mono result = tested.uploadMultipart(multipartFile); + final HttpStatusCode status = result.block(); assertThat(status).isEqualTo(HttpStatus.OK); } From c8c719f1e0026a4699b7e8187442bb804a0aa02b Mon Sep 17 00:00:00 2001 From: ACHRAF TAITAI <43656331+achraftt@users.noreply.github.com> Date: Thu, 11 Apr 2024 13:35:00 +0200 Subject: [PATCH 57/57] Bael 7744 (#16365) * BAEL-7765: How to fix JsonParseException: Unexpected character (code 115) when parsing unquoted JSON in Jackson * BAEL-7744: fix unit test * BAEL-7744: fix unit test --- .../src/main/java/com/baeldung/Unrelated.java | 4 ++++ .../src/test/java/com/baeldung/OuterUnitTest.java | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java diff --git a/core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java b/core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java new file mode 100644 index 0000000000..f122b89f6e --- /dev/null +++ b/core-java-modules/core-java-11/src/main/java/com/baeldung/Unrelated.java @@ -0,0 +1,4 @@ +package com.baeldung; + +public class Unrelated { +} diff --git a/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java b/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java index 9e6bd72680..8699e94b47 100644 --- a/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java +++ b/core-java-modules/core-java-11/src/test/java/com/baeldung/OuterUnitTest.java @@ -1,7 +1,7 @@ package com.baeldung; -import static org.junit.Assert.assertTrue; import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.*; import java.util.Arrays; import java.util.Set; @@ -14,22 +14,22 @@ public class OuterUnitTest { @Test public void whenGetNestHostFromOuter_thenGetNestHost() { - is(Outer.class.getNestHost().getName()).equals(NEST_HOST_NAME); + assertEquals(NEST_HOST_NAME, Outer.class.getNestHost().getName()); } @Test public void whenGetNestHostFromInner_thenGetNestHost() { - is(Outer.Inner.class.getNestHost().getName()).equals(NEST_HOST_NAME); + assertEquals(NEST_HOST_NAME, Outer.Inner.class.getNestHost().getName()); } @Test public void whenCheckNestmatesForNestedClasses_thenGetTrue() { - is(Outer.Inner.class.isNestmateOf(Outer.class)).equals(true); + assertTrue(Outer.Inner.class.isNestmateOf(Outer.class)); } @Test public void whenCheckNestmatesForUnrelatedClasses_thenGetFalse() { - is(Outer.Inner.class.isNestmateOf(Outer.class)).equals(false); + assertFalse(Outer.Inner.class.isNestmateOf(Unrelated.class)); } @Test