diff --git a/libraries-2/pom.xml b/libraries-2/pom.xml
index ff73888b69..c6be8df38d 100644
--- a/libraries-2/pom.xml
+++ b/libraries-2/pom.xml
@@ -142,9 +142,15 @@
org.apache.mesos
mesos
${mesos.library.version}
+
+
+ org.inferred
+ freebuilder
+ ${freebuilder.version}
+ true
-
+
3.0.7
3.6.2
@@ -165,5 +171,6 @@
2.8.5
3.14.2
4.1.2
-
+ 2.4.1
+
diff --git a/libraries-2/src/main/java/com/baeldung/freebuilder/Employee.java b/libraries-2/src/main/java/com/baeldung/freebuilder/Employee.java
new file mode 100644
index 0000000000..08470cc5cd
--- /dev/null
+++ b/libraries-2/src/main/java/com/baeldung/freebuilder/Employee.java
@@ -0,0 +1,65 @@
+package com.baeldung.freebuilder;
+
+import com.baeldung.freebuilder.builder.classic.Address;
+import org.inferred.freebuilder.FreeBuilder;
+
+import javax.annotation.Nullable;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.UnaryOperator;
+
+@FreeBuilder
+public interface Employee {
+
+ String getName();
+
+ int getAge();
+
+ String getDepartment();
+
+ String getRole();
+
+ String getSupervisorName();
+
+ String getDesignation();
+
+ String getEmail();
+
+ long getPhoneNumber();
+
+ Optional getPermanent();
+
+ Optional getDateOfJoining();
+
+ @Nullable
+ String getCurrentProject();
+
+ Address getAddress();
+
+ List getAccessTokens();
+
+ Map getAssetsSerialIdMapping();
+
+
+ class Builder extends Employee_Builder {
+
+ public Builder() {
+ // setting default value for department
+ setDepartment("Builder Pattern");
+ }
+
+ @Override
+ public Builder setEmail(String email) {
+ if (checkValidEmail(email))
+ return super.setEmail(email);
+ else
+ throw new IllegalArgumentException("Invalid email");
+
+ }
+
+ private boolean checkValidEmail(String email) {
+ return email.contains("@");
+ }
+ }
+}
diff --git a/libraries-2/src/main/java/com/baeldung/freebuilder/builder/classic/Address.java b/libraries-2/src/main/java/com/baeldung/freebuilder/builder/classic/Address.java
new file mode 100644
index 0000000000..8e53a9f155
--- /dev/null
+++ b/libraries-2/src/main/java/com/baeldung/freebuilder/builder/classic/Address.java
@@ -0,0 +1,25 @@
+package com.baeldung.freebuilder.builder.classic;
+
+import org.inferred.freebuilder.FreeBuilder;
+
+import java.util.Optional;
+
+@FreeBuilder
+public interface Address {
+
+ Optional getAddressLine1();
+
+ Optional getAddressLine2();
+
+ Optional getAddressLine3();
+
+ String getCity();
+
+ Optional getState();
+
+ Optional getPinCode();
+
+ class Builder extends Address_Builder {
+
+ }
+}
\ No newline at end of file
diff --git a/libraries-2/src/main/java/com/baeldung/freebuilder/builder/classic/Employee.java b/libraries-2/src/main/java/com/baeldung/freebuilder/builder/classic/Employee.java
new file mode 100644
index 0000000000..bd9c8b0a17
--- /dev/null
+++ b/libraries-2/src/main/java/com/baeldung/freebuilder/builder/classic/Employee.java
@@ -0,0 +1,181 @@
+package com.baeldung.freebuilder.builder.classic;
+
+public class Employee {
+
+ private String name;
+ private int age;
+ private String department;
+ private String role;
+ private String supervisorName;
+ private String designation;
+ private String email;
+ private long phoneNumber;
+ private boolean isPermanent;
+ private Address address;
+
+ private Employee() {
+
+ }
+
+ private void setName(String name) {
+ this.name = name;
+ }
+
+ private void setAge(int age) {
+ this.age = age;
+ }
+
+ private void setDepartment(String department) {
+ this.department = department;
+ }
+
+ private void setRole(String role) {
+ this.role = role;
+ }
+
+ private void setSupervisorName(String supervisorName) {
+ this.supervisorName = supervisorName;
+ }
+
+ private void setDesignation(String designation) {
+ this.designation = designation;
+ }
+
+ private void setEmail(String email) {
+ this.email = email;
+ }
+
+ private void setPhoneNumber(long phoneNumber) {
+ this.phoneNumber = phoneNumber;
+ }
+
+ private void setPermanent(boolean permanent) {
+ isPermanent = permanent;
+ }
+
+ private void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public String getDepartment() {
+ return department;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public String getSupervisorName() {
+ return supervisorName;
+ }
+
+ public String getDesignation() {
+ return designation;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public long getPhoneNumber() {
+ return phoneNumber;
+ }
+
+ public boolean isPermanent() {
+ return isPermanent;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public static class Builder {
+
+ private String name;
+ private int age;
+ private String department;
+ private String role;
+ private String supervisorName;
+ private String designation;
+ private String email;
+ private long phoneNumber;
+ private boolean isPermanent;
+ private Address address;
+
+ public Builder setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder setAge(int age) {
+ this.age = age;
+ return this;
+ }
+
+ public Builder setDepartment(String department) {
+ this.department = department;
+ return this;
+ }
+
+ public Builder setRole(String role) {
+ this.role = role;
+ return this;
+ }
+
+ public Builder setSupervisorName(String supervisorName) {
+ this.supervisorName = supervisorName;
+ return this;
+ }
+
+ public Builder setDesignation(String designation) {
+ this.designation = designation;
+ return this;
+ }
+
+ public Builder setEmail(String email) {
+ this.email = email;
+ return this;
+ }
+
+ public Builder setPhoneNumber(long phoneNumber) {
+ this.phoneNumber = phoneNumber;
+ return this;
+ }
+
+ public Builder setPermanent(boolean permanent) {
+ isPermanent = permanent;
+ return this;
+ }
+
+ public Builder setAddress(Address address) {
+ this.address = address;
+ return this;
+ }
+
+ public Employee build() {
+ Employee employee = new Employee();
+ employee.setName(this.name);
+ employee.setAge(this.age);
+ employee.setDepartment(this.department);
+ employee.setAddress(this.address);
+ employee.setDesignation(this.designation);
+ employee.setEmail(this.email);
+ employee.setPermanent(this.isPermanent);
+ employee.setName(this.name);
+ employee.setSupervisorName(this.supervisorName);
+ employee.setPhoneNumber(this.phoneNumber);
+
+ return employee;
+
+ }
+ }
+
+}
diff --git a/libraries-2/src/test/java/com/baeldung/freebuilder/EmployeeBuilderUnitTest.java b/libraries-2/src/test/java/com/baeldung/freebuilder/EmployeeBuilderUnitTest.java
new file mode 100644
index 0000000000..e3a9e49633
--- /dev/null
+++ b/libraries-2/src/test/java/com/baeldung/freebuilder/EmployeeBuilderUnitTest.java
@@ -0,0 +1,150 @@
+package com.baeldung.freebuilder;
+
+import com.baeldung.freebuilder.builder.classic.Address;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class EmployeeBuilderUnitTest {
+
+ private static final int PIN_CODE = 223344;
+ public static final String CITY_NAME = "New York";
+
+ @Test
+ public void whenBuildEmployeeWithAddress_thenReturnEmployeeWithValidAddress() {
+
+ // when
+ Address.Builder addressBuilder = new Address.Builder();
+ Address address = addressBuilder.setCity(CITY_NAME).build();
+
+ Employee.Builder builder = new Employee.Builder();
+
+ Employee employee = builder.setName("baeldung").setAge(10).setDesignation("author").setEmail("abc@xyz.com").setSupervisorName("Admin").setPhoneNumber(4445566).setPermanent(true).setRole("developer").setAddress(address).build();
+
+ // then
+ assertTrue(employee.getAddress().getCity().equalsIgnoreCase(CITY_NAME));
+
+ }
+
+ @Test
+ public void whenMapPincodeInAddress_thenReturnEmployeeWithValidAddressPincode() {
+
+ // when
+ Address.Builder addressBuilder = new Address.Builder();
+ Address address = addressBuilder.setCity(CITY_NAME).setPinCode(PIN_CODE).build();
+
+ Employee.Builder builder = new Employee.Builder();
+
+ Employee employee = builder.setName("baeldung").setAge(10).setDesignation("author").setEmail("abc@xyz.com").setSupervisorName("Admin").setPhoneNumber(4445566).setPermanent(true).setRole("developer").setAddress(address).build();
+
+ // then
+ assertTrue(employee.getAddress().getPinCode().get() == PIN_CODE);
+
+ }
+
+ @Test
+ public void whenOptionalFields_thenReturnEmployeeWithEmptyValues() {
+
+ // when
+ Address.Builder addressBuilder = new Address.Builder();
+ Address address = addressBuilder.setCity(CITY_NAME).build();
+
+ Employee.Builder builder = new Employee.Builder();
+
+ Employee employee = builder.setName("baeldung").setAge(10).setDesignation("author").setEmail("abc@xyz.com").setSupervisorName("Admin").setPhoneNumber(4445566).setNullablePermanent(null).setDateOfJoining(Optional.empty()).setRole("developer")
+ .setAddress(address).build();
+
+ // then
+ assertFalse(employee.getDateOfJoining().isPresent());
+
+ }
+
+ @Test
+ public void whenNullableFields_thenReturnEmployeeWithNullValueForField() {
+
+ // when
+ Address.Builder addressBuilder = new Address.Builder();
+ Address address = addressBuilder.setCity(CITY_NAME).build();
+
+ Employee.Builder builder = new Employee.Builder();
+
+ Employee employee = builder.setName("baeldung").setAge(10).setDesignation("author").setEmail("abc@xyz.com").setSupervisorName("Admin").setPhoneNumber(4445566).setNullablePermanent(null).setDateOfJoining(Optional.empty()).setRole("developer")
+ .setAddress(address).build();
+
+ // then
+ assertNull(employee.getCurrentProject());
+
+ }
+
+ @Test
+ public void whenCollectionFields_thenReturnEmployeeWithValues() {
+
+ // when
+ Address.Builder addressBuilder = new Address.Builder();
+ Address address = addressBuilder.setCity(CITY_NAME).build();
+
+ Employee.Builder builder = new Employee.Builder();
+
+ Employee employee = builder.setName("baeldung").setAge(10).setDesignation("author").setEmail("abc@xyz.com").setSupervisorName("Admin").setPhoneNumber(4445566).setNullablePermanent(null).setDateOfJoining(Optional.empty()).setRole("developer")
+ .addAccessTokens(1221819L).addAccessTokens(1223441L, 134567L).setAddress(address).build();
+
+ // then
+ assertTrue(employee.getAccessTokens().size() == 3);
+
+ }
+
+ @Test
+ public void whenMapFields_thenReturnEmployeeWithValues() {
+
+ // when
+ Address.Builder addressBuilder = new Address.Builder();
+ Address address = addressBuilder.setCity(CITY_NAME).build();
+
+ Employee.Builder builder = new Employee.Builder();
+
+ Employee employee = builder.setName("baeldung").setAge(10).setDesignation("author").setEmail("abc@xyz.com").setSupervisorName("Admin").setPhoneNumber(4445566).setNullablePermanent(null).setDateOfJoining(Optional.empty()).setRole("developer")
+ .addAccessTokens(1221819L).addAccessTokens(1223441L, 134567L).putAssetsSerialIdMapping("Laptop", 12345L).setAddress(address).build();
+
+ // then
+ assertTrue(employee.getAssetsSerialIdMapping().size() == 1);
+
+ }
+
+ @Test
+ public void whenNestedBuilderTypes_thenReturnEmployeeWithValues() {
+
+ // when
+ Address.Builder addressBuilder = new Address.Builder();
+ Address address = addressBuilder.setCity(CITY_NAME).build();
+
+ Employee.Builder builder = new Employee.Builder();
+
+ Employee employee = builder.setName("baeldung").setAge(10).setDesignation("author").setEmail("abc@xyz.com").setSupervisorName("Admin").setPhoneNumber(4445566).setNullablePermanent(null).setDateOfJoining(Optional.empty()).setRole("developer")
+ .addAccessTokens(1221819L).addAccessTokens(1223441L, 134567L).putAssetsSerialIdMapping("Laptop", 12345L).setAddress(address).mutateAddress(a -> a.setPinCode(112200)).build();
+
+ // then
+ assertTrue(employee.getAssetsSerialIdMapping().size() == 1);
+
+ }
+
+ @Test()
+ public void whenPartialEmployeeWithValidEmail_thenReturnEmployeeWithEmail() {
+
+ // when
+ Employee.Builder builder = new Employee.Builder();
+
+ Employee employee = builder.setName("baeldung")
+ .setAge(10)
+ .setEmail("abc@xyz.com")
+ .buildPartial();
+
+ assertNotNull(employee.getEmail());
+ }
+
+}
diff --git a/libraries-2/src/test/java/com/baeldung/freebuilder/builder/classic/EmployeeBuilderUnitTest.java b/libraries-2/src/test/java/com/baeldung/freebuilder/builder/classic/EmployeeBuilderUnitTest.java
new file mode 100644
index 0000000000..930820009c
--- /dev/null
+++ b/libraries-2/src/test/java/com/baeldung/freebuilder/builder/classic/EmployeeBuilderUnitTest.java
@@ -0,0 +1,32 @@
+package com.baeldung.freebuilder.builder.classic;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+
+class EmployeeBuilderUnitTest {
+
+ private static final String CITY = "New York";
+
+ @Test
+ public void whenBuildEmployeeWithAddress_thenReturnEmployeeWithValidAddress() {
+
+ // when
+ Employee.Builder emplBuilder = new Employee.Builder();
+
+ Employee employee = emplBuilder
+ .setName("baeldung")
+ .setAge(12)
+ .setDepartment("Builder Pattern")
+ .setDesignation("Author")
+ .setEmail("abc@xyz.com")
+ .setPermanent(true)
+ .setSupervisorName("Admin")
+ .setPhoneNumber(4445566)
+ .build();
+
+ //then
+ Assertions.assertTrue(employee.getAddress().getCity().equalsIgnoreCase(CITY));
+ }
+
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 05c719ec7c..90cea73a9d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1571,7 +1571,7 @@
0.3.1
2.5.1
0.0.1
- 3.8
+ 3.7
2.3
3.8