Merge pull request #7327 from dev-chirag/master
BAEL-2990 Automatic generation of the Builder pattern with FreeBuilder
This commit is contained in:
commit
f90828bfc0
@ -30,6 +30,17 @@
|
|||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang3.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.inferred</groupId>
|
||||||
|
<artifactId>freebuilder</artifactId>
|
||||||
|
<version>${freebuilder.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.findbugs</groupId>
|
||||||
|
<artifactId>jsr305</artifactId>
|
||||||
|
<version>${javax.annotations.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
@ -38,5 +49,7 @@
|
|||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<intellij.annotations.version>16.0.2</intellij.annotations.version>
|
<intellij.annotations.version>16.0.2</intellij.annotations.version>
|
||||||
|
<freebuilder.version>2.4.1</freebuilder.version>
|
||||||
|
<javax.annotations.version>3.0.2</javax.annotations.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.baeldung.freebuilder;
|
||||||
|
|
||||||
|
import org.inferred.freebuilder.FreeBuilder;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@FreeBuilder
|
||||||
|
public interface Address {
|
||||||
|
|
||||||
|
Optional<String> getAddressLine1();
|
||||||
|
|
||||||
|
Optional<String> getAddressLine2();
|
||||||
|
|
||||||
|
Optional<String> getAddressLine3();
|
||||||
|
|
||||||
|
String getCity();
|
||||||
|
|
||||||
|
Optional<String> getState();
|
||||||
|
|
||||||
|
Optional<Long> getPinCode();
|
||||||
|
|
||||||
|
class Builder extends Address_Builder {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -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<Boolean> getPermanent();
|
||||||
|
|
||||||
|
Optional<String> getDateOfJoining();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
String getCurrentProject();
|
||||||
|
|
||||||
|
Address getAddress();
|
||||||
|
|
||||||
|
List<Long> getAccessTokens();
|
||||||
|
|
||||||
|
Map<String, Long> getAssetsSerialIdMapping();
|
||||||
|
|
||||||
|
Optional<Double> 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("@");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user