Skip to content

Commit b8d9197

Browse files
authored
Merge pull request #183 from companieshouse/feature/sonar-fixes-and-use-java-records-1
Code improvements using Java records 1
2 parents d34d65c + 494fd1a commit b8d9197

File tree

11 files changed

+122
-191
lines changed

11 files changed

+122
-191
lines changed

src/main/java/uk/gov/companieshouse/efs/api/categorytemplates/mapper/CategoryTemplateMapper.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@
99
import uk.gov.companieshouse.api.model.efs.categorytemplates.CategoryTemplateListApi;
1010
import uk.gov.companieshouse.efs.api.categorytemplates.model.CategoryTemplate;
1111

12+
/**
13+
* Mapper for converting CategoryTemplate model objects to API representations.
14+
* <p>
15+
* This class provides methods to map a list of {@link CategoryTemplate} objects to a {@link CategoryTemplateListApi},
16+
* and a single {@link CategoryTemplate} to a {@link CategoryTemplateApi}. It is used to bridge the internal data model
17+
* and the external API layer, ensuring that the data is transformed appropriately for external consumption.
18+
* </p>
19+
*
20+
* <ul>
21+
* <li>{@link #map(List)}: Maps a list of CategoryTemplate objects to a CategoryTemplateListApi.</li>
22+
* <li>{@link #map(CategoryTemplate)}: Maps a single CategoryTemplate object to a CategoryTemplateApi.</li>
23+
* </ul>
24+
*/
1225
@Component
1326
public class CategoryTemplateMapper {
1427

@@ -32,10 +45,10 @@ public CategoryTemplateListApi map(List<CategoryTemplate> categoryTemplates) {
3245
*/
3346
public CategoryTemplateApi map(CategoryTemplate categoryTemplate) {
3447
return new CategoryTemplateApi(
35-
categoryTemplate.getCategoryType(),
36-
categoryTemplate.getCategoryName(),
37-
categoryTemplate.getParent(),
38-
categoryTemplate.getCategoryHint(),
39-
categoryTemplate.getGuidanceTexts());
48+
categoryTemplate.categoryType(),
49+
categoryTemplate.categoryName(),
50+
categoryTemplate.parent(),
51+
categoryTemplate.categoryHint(),
52+
categoryTemplate.guidanceTexts());
4053
}
4154
}

src/main/java/uk/gov/companieshouse/efs/api/categorytemplates/model/CategoryTemplate.java

Lines changed: 26 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,130 +5,56 @@
55
import java.util.Collections;
66
import java.util.List;
77
import java.util.Objects;
8-
import java.util.Optional;
9-
import org.apache.commons.lang3.builder.ToStringBuilder;
10-
import org.apache.commons.lang3.builder.ToStringStyle;
8+
119
import org.springframework.data.annotation.Id;
1210
import org.springframework.data.mongodb.core.mapping.Document;
1311
import org.springframework.data.mongodb.core.mapping.Field;
1412

1513
/**
16-
* Builder class for the {@code CategoryTemplate}.
14+
* Represents a category template document stored in the MongoDB collection "category_templates".
15+
* <p>
16+
* This record is used to model category metadata for forms, including type, name, parent category,
17+
* display order, hints, and associated guidance text IDs. It is annotated for use with Spring Data MongoDB
18+
* and Jackson for serialization/deserialization.
19+
* </p>
20+
*
21+
* <ul>
22+
* <li>{@code categoryType}: Unique identifier for the category type.</li>
23+
* <li>{@code orderIndex}: Display order index for sorting categories.</li>
24+
* <li>{@code categoryName}: Human-readable name of the category.</li>
25+
* <li>{@code parent}: Parent category type, if applicable.</li>
26+
* <li>{@code categoryHint}: Optional hint or description for the category.</li>
27+
* <li>{@code guidanceTexts}: List of guidance text IDs associated with the category and converted to an empty list if null.</li>
28+
* </ul>
1729
*/
1830
@Document(collection = "category_templates")
1931
@JsonInclude(JsonInclude.Include.NON_NULL)
20-
public class CategoryTemplate {
21-
22-
private CategoryTemplate() {
23-
// required by Spring Data
24-
}
25-
32+
public record CategoryTemplate(
2633
@JsonProperty("category_type")
2734
@Id
28-
private String categoryType;
35+
String categoryType,
2936

3037
@JsonProperty("order_index")
3138
@Field
32-
private Integer orderIndex;
39+
Integer orderIndex,
3340

3441
@JsonProperty("category_name")
3542
@Field
36-
private String categoryName;
43+
String categoryName,
3744

3845
@JsonProperty("parent")
3946
@Field
40-
private String parent;
47+
String parent,
4148

4249
@JsonProperty("category_hint")
4350
@Field
44-
private String categoryHint;
51+
String categoryHint,
4552

4653
@JsonProperty("guidance_text_list")
4754
@Field
48-
private List<Integer> guidanceTexts;
49-
50-
/**
51-
* Constructor which sets the submission form category data.
52-
*
53-
* @param categoryType the category type
54-
* @param orderIndex the ordering within the category
55-
* @param categoryName the category name
56-
* @param parent used when the category has a parent category
57-
* @param categoryHint the category hint
58-
* @param guidanceTexts a list of id's of guidance fragments to show on the category
59-
* selection screen
60-
*/
61-
public CategoryTemplate(String categoryType, final Integer orderIndex, String categoryName,
62-
String parent, String categoryHint, final List<Integer> guidanceTexts) {
63-
this.categoryType = categoryType;
64-
this.orderIndex = orderIndex;
65-
this.categoryName = categoryName;
66-
this.parent = parent;
67-
this.categoryHint = categoryHint;
68-
this.guidanceTexts = guidanceTexts;
69-
}
70-
71-
public String getCategoryType() {
72-
return categoryType;
73-
}
74-
75-
public Integer getOrderIndex() {
76-
return orderIndex;
77-
}
78-
79-
public String getCategoryName() {
80-
return categoryName;
81-
}
82-
83-
public String getParent() {
84-
return parent;
85-
}
86-
87-
public String getCategoryHint() {
88-
return categoryHint;
89-
}
90-
91-
public List<Integer> getGuidanceTexts() {
92-
return Optional.ofNullable(guidanceTexts)
93-
.orElse(Collections.emptyList());
94-
}
95-
96-
public void setGuidanceTexts(List<Integer> guidanceTexts) {
97-
this.guidanceTexts = guidanceTexts;
98-
}
99-
100-
@Override
101-
public boolean equals(final Object o) {
102-
if (this == o) {
103-
return true;
104-
}
105-
if (o == null || getClass() != o.getClass()) {
106-
return false;
107-
}
108-
final CategoryTemplate that = (CategoryTemplate) o;
109-
return Objects.equals(getCategoryType(), that.getCategoryType()) &&
110-
Objects.equals(getOrderIndex(), that.getOrderIndex()) &&
111-
Objects.equals(getCategoryName(), that.getCategoryName()) &&
112-
Objects.equals(getParent(), that.getParent()) &&
113-
Objects.equals(getCategoryHint(), that.getCategoryHint()) &&
114-
Objects.equals(getGuidanceTexts(), that.getGuidanceTexts());
115-
}
116-
117-
@Override
118-
public int hashCode() {
119-
return Objects.hash(getCategoryType(), getOrderIndex(), getCategoryName(), getParent(),
120-
getCategoryHint(), getGuidanceTexts());
121-
}
122-
123-
@Override
124-
public String toString() {
125-
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
126-
.append("categoryType", getCategoryType())
127-
.append("orderIndex", getOrderIndex())
128-
.append("categoryName", getCategoryName())
129-
.append("parent", getParent())
130-
.append("categoryHint", getCategoryHint())
131-
.append("guidanceTexts", getGuidanceTexts())
132-
.toString();
55+
List<Integer> guidanceTexts
56+
) {
57+
public CategoryTemplate {
58+
guidanceTexts = Objects.requireNonNullElse(guidanceTexts, Collections.emptyList());
13359
}
13460
}

src/main/java/uk/gov/companieshouse/efs/api/categorytemplates/service/CategoryTemplateServiceImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
@Import(Config.class)
2323
public class CategoryTemplateServiceImpl implements CategoryTemplateService {
2424

25-
private CategoryTemplateRepository repository;
26-
private CategoryTemplateMapper mapper;
25+
private final CategoryTemplateRepository repository;
26+
private final CategoryTemplateMapper mapper;
2727

2828
/**
2929
* FormTemplateService constructor.
@@ -63,7 +63,7 @@ public CategoryTypeConstants getTopLevelCategory(final String category) {
6363
CategoryTemplate categoryTemplate = repository.findById(currentCategory).orElse(null);
6464

6565
if (categoryTemplate != null) {
66-
final String parentCategory = categoryTemplate.getParent();
66+
final String parentCategory = categoryTemplate.parent();
6767
final CategoryTypeConstants parentCategoryType =
6868
CategoryTypeConstants.nameOf(parentCategory).orElse(OTHER);
6969

src/main/java/uk/gov/companieshouse/efs/api/email/EmailServiceImpl.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818

1919
import static java.lang.String.format;
2020

21+
/**
22+
* Service implementation for sending various types of email notifications related to submissions.
23+
* <p>
24+
* This class coordinates the mapping of submission models to email documents and delegates the actual
25+
* sending of emails to the {@link EmailClient}. It supports external and internal notifications, payment
26+
* reports, delayed submission notifications, and more. Each public method corresponds to a specific type
27+
* of email notification and uses the appropriate mapper from {@link EmailMapperFactory}.
28+
* <p>
29+
* Error handling is performed for failed email sends, and all operations are logged for traceability.
30+
*/
2131
@Service
2232
public class EmailServiceImpl implements EmailService {
2333

@@ -39,13 +49,13 @@ public EmailServiceImpl(EmailMapperFactory emailMapperFactory, EmailClient email
3949

4050
@Override
4151
public void sendExternalConfirmation(ExternalNotificationEmailModel emailModel) {
42-
LOGGER.debug(format("Sending external email confirming submission [%s]", emailModel.getSubmission().getId()));
52+
LOGGER.debug(format("Sending external email confirming submission [%s]", emailModel.submission().getId()));
4353
sendMessage(this.emailMapperFactory.getConfirmationEmailMapper().map(emailModel));
4454
}
4555

4656
@Override
4757
public void sendExternalPaymentFailedNotification(ExternalNotificationEmailModel emailModel) {
48-
LOGGER.debug(format("Sending external email notifying payment failed for submission [%s]", emailModel.getSubmission().getId()));
58+
LOGGER.debug(format("Sending external email notifying payment failed for submission [%s]", emailModel.submission().getId()));
4959
sendMessage(this.emailMapperFactory.getPaymentFailedEmailMapper().map(emailModel));
5060
}
5161

src/main/java/uk/gov/companieshouse/efs/api/email/mapper/ExternalNotificationEmailMapper.java

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,23 @@
1616
import uk.gov.companieshouse.efs.api.util.IdentifierGeneratable;
1717
import uk.gov.companieshouse.efs.api.util.TimestampGenerator;
1818

19+
/**
20+
* Maps {@link ExternalNotificationEmailModel} to {@link EmailDocument} for external notification emails.
21+
* <p>
22+
* This class is responsible for transforming submission data into the format required for sending
23+
* external notification emails. It uses configuration, identifier and timestamp generators, and services
24+
* for category and form templates to build the email payload.
25+
* <p>
26+
* Typical usage involves calling {@link #map(ExternalNotificationEmailModel)} with a model containing
27+
* submission details, which returns a fully populated {@link EmailDocument} ready for sending.
28+
*/
1929
public class ExternalNotificationEmailMapper {
2030

21-
private NotificationConfig config;
22-
private IdentifierGeneratable idGenerator;
23-
private TimestampGenerator<LocalDateTime> timestampGenerator;
24-
private CategoryTemplateService categoryTemplateService;
25-
private FormTemplateService formTemplateService;
31+
private final NotificationConfig config;
32+
private final IdentifierGeneratable idGenerator;
33+
private final TimestampGenerator<LocalDateTime> timestampGenerator;
34+
private final CategoryTemplateService categoryTemplateService;
35+
private final FormTemplateService formTemplateService;
2636

2737
public ExternalNotificationEmailMapper(NotificationConfig config,
2838
IdentifierGeneratable idGenerator, TimestampGenerator<LocalDateTime> timestampGenerator,
@@ -39,7 +49,7 @@ public EmailDocument<ExternalConfirmationEmailData> map(ExternalNotificationEmai
3949
return EmailDocument.<ExternalConfirmationEmailData>builder()
4050
.withTopic(config.getTopic())
4151
.withMessageId(idGenerator.generateId())
42-
.withRecipientEmailAddress(model.getSubmission().getPresenter().getEmail())
52+
.withRecipientEmailAddress(model.submission().getPresenter().getEmail())
4353
.withEmailTemplateAppId(config.getAppId())
4454
.withEmailTemplateMessageType(config.getMessageType())
4555
.withData(fromSubmission(model))
@@ -49,15 +59,15 @@ public EmailDocument<ExternalConfirmationEmailData> map(ExternalNotificationEmai
4959

5060
private ExternalConfirmationEmailData fromSubmission(ExternalNotificationEmailModel model) {
5161
return ExternalConfirmationEmailData.builder()
52-
.withTo(model.getSubmission().getPresenter().getEmail())
53-
.withPresenter(model.getSubmission().getPresenter())
62+
.withTo(model.submission().getPresenter().getEmail())
63+
.withPresenter(model.submission().getPresenter())
5464
.withSubject(config.getSubject())
55-
.withCompany(model.getSubmission().getCompany())
56-
.withConfirmationReference(model.getSubmission().getConfirmationReference())
57-
.withFormType(model.getSubmission().getFormDetails().getFormType())
65+
.withCompany(model.submission().getCompany())
66+
.withConfirmationReference(model.submission().getConfirmationReference())
67+
.withFormType(model.submission().getFormDetails().getFormType())
5868
.withTopLevelCategory(getTopLevelCategoryForFormType(model))
59-
.withEmailFileDetailsList(createEmailFileDetailsList(model.getSubmission().getFormDetails().getFileDetailsList()))
60-
.withFeeOnSubmission(model.getSubmission().getFeeOnSubmission())
69+
.withEmailFileDetailsList(createEmailFileDetailsList(model.submission().getFormDetails().getFileDetailsList()))
70+
.withFeeOnSubmission(model.submission().getFeeOnSubmission())
6171
.build();
6272
}
6373

@@ -71,7 +81,7 @@ private EmailFileDetails emailFileDetails(FileDetails fileDetails) {
7181

7282
private CategoryTypeConstants getTopLevelCategoryForFormType(final ExternalNotificationEmailModel model) {
7383
FormTemplateApi formTemplate = formTemplateService
74-
.getFormTemplate(model.getSubmission().getFormDetails().getFormType());
84+
.getFormTemplate(model.submission().getFormDetails().getFormType());
7585
return categoryTemplateService.getTopLevelCategory(formTemplate.getFormCategory());
7686
}
7787
}
Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,8 @@
11
package uk.gov.companieshouse.efs.api.email.model;
22

3-
import java.util.Objects;
43
import uk.gov.companieshouse.efs.api.submissions.model.Submission;
54

6-
public class ExternalNotificationEmailModel {
7-
8-
private final Submission submission;
9-
10-
public ExternalNotificationEmailModel(Submission submission) {
11-
this.submission = submission;
12-
}
13-
14-
public Submission getSubmission() {
15-
return submission;
16-
}
17-
18-
@Override
19-
public int hashCode() {
20-
return Objects.hash(submission);
21-
}
22-
23-
@Override
24-
public boolean equals(Object obj) {
25-
if (this == obj) {
26-
return true;
27-
}
28-
if (obj == null) {
29-
return false;
30-
}
31-
if (getClass() != obj.getClass()) {
32-
return false;
33-
}
34-
ExternalNotificationEmailModel other = (ExternalNotificationEmailModel) obj;
35-
return Objects.equals(submission, other.submission);
36-
}
37-
38-
}
5+
/**
6+
* Represents an external notification email model containing a submission.
7+
*/
8+
public record ExternalNotificationEmailModel(Submission submission) {}

src/test/java/uk/gov/companieshouse/efs/api/categorytemplates/mapper/CategoryTemplateMapperTest.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,7 @@ void testMapperMapsCategoryToCategoryTemplateApi() {
4545
}
4646

4747
private CategoryTemplate getCategory() {
48-
final CategoryTemplate category =
49-
new CategoryTemplate("MA", 1, "New Incorporation", "", "", null);
50-
51-
category.setGuidanceTexts(Collections.singletonList(3000));
52-
53-
return category;
48+
return new CategoryTemplate("MA", 1, "New Incorporation", "", "", Collections.singletonList(3000));
5449
}
5550

5651
private CategoryTemplateListApi expectedList() {
@@ -60,8 +55,7 @@ private CategoryTemplateListApi expectedList() {
6055
}
6156

6257
private CategoryTemplateApi expectedSingle() {
63-
CategoryTemplateApi element = new CategoryTemplateApi("MA", "New Incorporation", "", "",
58+
return new CategoryTemplateApi("MA", "New Incorporation", "", "",
6459
Collections.singletonList(3000));
65-
return new CategoryTemplateApi(element);
6660
}
6761
}

0 commit comments

Comments
 (0)