diff --git a/patterns/design-patterns-2/pom.xml b/patterns/design-patterns-2/pom.xml index 392035ab84..17afff87ae 100644 --- a/patterns/design-patterns-2/pom.xml +++ b/patterns/design-patterns-2/pom.xml @@ -30,6 +30,17 @@ org.apache.commons commons-lang3 ${commons-lang3.version} + + + org.inferred + freebuilder + ${freebuilder.version} + true + + + com.google.code.findbugs + jsr305 + ${javax.annotations.version} @@ -38,5 +49,7 @@ 1.8 1.8 16.0.2 + 2.4.1 + 3.0.2 diff --git a/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Address.java b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Address.java new file mode 100644 index 0000000000..6d727f6d9f --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Address.java @@ -0,0 +1,25 @@ +package com.baeldung.freebuilder; + +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/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Employee.java b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Employee.java new file mode 100644 index 0000000000..06558dde0b --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/Employee.java @@ -0,0 +1,65 @@ +package com.baeldung.freebuilder; + +import org.inferred.freebuilder.FreeBuilder; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@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(); + + Optional getSalaryInUSD(); + + + 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/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/builder/Employee.java b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/builder/Employee.java new file mode 100644 index 0000000000..141d734c43 --- /dev/null +++ b/patterns/design-patterns-2/src/main/java/com/baeldung/freebuilder/builder/Employee.java @@ -0,0 +1,53 @@ +package com.baeldung.freebuilder.builder; + +public class Employee { + + private final String name; + private final int age; + private final String department; + + private Employee(String name, int age, String department) { + this.name = name; + this.age = age; + this.department = department; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public String getDepartment() { + return department; + } + + public static class Builder { + + private String name; + private int age; + private String department; + + 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 Employee build() { + return new Employee(name, age, department); + } + } + +} diff --git a/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/EmployeeBuilderUnitTest.java b/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/EmployeeBuilderUnitTest.java new file mode 100644 index 0000000000..d28edfcf3d --- /dev/null +++ b/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/EmployeeBuilderUnitTest.java @@ -0,0 +1,226 @@ +package com.baeldung.freebuilder; + +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"; + public static final int INPUT_SALARY_EUROS = 10000; + public static final double EUROS_TO_USD_RATIO = 0.6; + + @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 whenMapSalary_thenReturnEmployeeWithSalaryInUSD() { + + // when + Address.Builder addressBuilder = new Address.Builder(); + Address address = addressBuilder.setCity(CITY_NAME).setPinCode(PIN_CODE).build(); + + long salaryInEuros = INPUT_SALARY_EUROS; + 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) + .mapSalaryInUSD(sal -> salaryInEuros * EUROS_TO_USD_RATIO) + .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) + .setPermanent(true) + .setRole("developer") + .setAddress(address) + .build(); + + // then + assertTrue(employee.getPermanent().isPresent()); + assertTrue(employee.getPermanent().get()); + 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/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/builder/EmployeeBuilderUnitTest.java b/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/builder/EmployeeBuilderUnitTest.java new file mode 100644 index 0000000000..1394f851b6 --- /dev/null +++ b/patterns/design-patterns-2/src/test/java/com/baeldung/freebuilder/builder/EmployeeBuilderUnitTest.java @@ -0,0 +1,27 @@ +package com.baeldung.freebuilder.builder; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + + +class EmployeeBuilderUnitTest { + + public static final String NAME = "baeldung"; + + @Test + public void whenBuildEmployee_thenReturnValidEmployee() { + + // when + Employee.Builder emplBuilder = new Employee.Builder(); + + Employee employee = emplBuilder + .setName(NAME) + .setAge(12) + .setDepartment("Builder Pattern") + .build(); + + //then + Assertions.assertTrue(employee.getName().equalsIgnoreCase(NAME)); + } + +} \ No newline at end of file