Skip to content

Commit faa2e29

Browse files
committed
Reformat files to comply with Checkstyle rules
1 parent 235a161 commit faa2e29

File tree

7 files changed

+353
-330
lines changed

7 files changed

+353
-330
lines changed

src/main/java/com/codesungrape/hmcts/bookapi/BookApiApplication.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
@SpringBootApplication
1212
public class BookApiApplication {
1313
/**
14-
* * Main entry point — starts the Spring Boot application.
15-
*/
14+
* * Main entry point — starts the Spring Boot application.
15+
*/
1616
public static void main(String[] args) {
1717
SpringApplication.run(BookApiApplication.class, args);
1818
}
Lines changed: 72 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,39 @@
11
package com.codesungrape.hmcts.bookapi.entity;
22

3-
import jakarta.persistence.*;
4-
import java.util.UUID;
5-
import lombok.*;
3+
import jakarta.persistence.Column;
4+
import jakarta.persistence.Entity;
5+
import jakarta.persistence.GeneratedValue;
6+
import jakarta.persistence.GenerationType;
7+
import jakarta.persistence.Id;
8+
import jakarta.persistence.PrePersist;
9+
import jakarta.persistence.PreUpdate;
10+
import jakarta.persistence.Table;
611
import java.time.Instant;
12+
import java.util.UUID;
13+
import lombok.AccessLevel;
14+
import lombok.AllArgsConstructor;
15+
import lombok.Builder;
16+
import lombok.Getter;
17+
import lombok.NoArgsConstructor;
18+
import lombok.Setter;
719

820
/**
9-
* JPA Entity representing the Book table in PostgreSQL.
10-
* This holds the persisted state of the resource.
11-
* HMCTS Rule Check: IDs must be opaque strings. Using UUID for distributed ID generation.
12-
* @Entity: Marks the class as a JPA entity - tells hibernate to map Java classes to database tables.
13-
* @Table: Defines which database table this entity maps to. HMCTS Naming: Lowercase, singular table name is common practice.
14-
* Lombok annotations:
15-
* @Getter: Automatically generates getters for all fields.
16-
* @Setter: Automatically generates setters.
17-
* @AllArgsConstructor: Generates a no-argument constructor (required by JPA).
18-
* JPA needs to instantiate the entity using reflection. 'PROTECTED' prevents misuse.
19-
* @Builder: Adds a builder pattern for clean object creation.
20-
* You can do Book.builder().title("A").author("B").build();
21+
* Represents the Book table in PostgreSQL as a JPA entity.
22+
* Stores the persisted state of a Book resource.
23+
* HMCTS Rule: IDs must be opaque; using UUID for distributed ID generation.
24+
*
25+
* @Entity: Marks the class as a JPA entity for Hibernate table mapping.
26+
* @Table: Specifies the database table; HMCTS: lowercase, singular table name.
27+
* Lombok Annotations:
28+
* @Getter: Generates getters for all fields.
29+
* @Setter: Generates setters for all fields.
30+
* @NoArgsConstructor: Protected no-arg constructor for JPA instantiation.
31+
* @AllArgsConstructor: Constructor with all fields for test convenience.
32+
* @Builder: Adds builder pattern for easy object creation.
33+
* Example: Book.builder()
34+
* .title("A")
35+
* .author("B")
36+
* .build();
2137
*/
2238
@Entity
2339
@Table(name = "book")
@@ -28,49 +44,53 @@
2844
@Builder // For convenience in creating instances
2945
public class Book {
3046

31-
@Id // Primary key of the table
32-
@GeneratedValue(strategy = GenerationType.UUID)
33-
@Column(name = "id", nullable = false) // maps the field to a database column named 'id' + 'nullable =false' database column cannot be NULL.
34-
private UUID id;
35-
36-
@Column(name = "title", nullable = false)
37-
private String title;
38-
39-
@Column(name = "synopsis", nullable = false, columnDefinition = "TEXT")
40-
private String synopsis;
47+
@Id // Primary key of the table
48+
@GeneratedValue(strategy = GenerationType.UUID)
49+
@Column(name = "id", nullable = false)
50+
private UUID id;
4151

42-
@Column(name = "author", nullable = false)
43-
private String author;
52+
@Column(name = "title", nullable = false)
53+
private String title;
4454

45-
// Soft delete - makes DELETE operations idempotent (safe to repeat)
46-
// Soft delete - using @Builder.Default to ensure the builder
47-
// respects this initialization if the field is not set explicitly.
48-
@Column(name = "deleted", nullable = false)
49-
@Builder.Default
50-
private boolean deleted = false;
55+
@Column(name = "synopsis", nullable = false, columnDefinition = "TEXT")
56+
private String synopsis;
5157

52-
// `createdAt` is null upon object creation.
53-
// It will be set by the `onCreate()` method right before persistence.
54-
@Column(name = "created_at", nullable = false, updatable = false)
55-
private Instant createdAt;
58+
@Column(name = "author", nullable = false)
59+
private String author;
5660

57-
@Column(name = "modified_at")
58-
private java.time.Instant modifiedAt;
61+
// Soft delete - makes DELETE operations idempotent (safe to repeat)
62+
// Using @Builder.Default to ensure the builder respects this initialization
63+
// if the field is not set explicitly.
64+
@Column(name = "deleted", nullable = false)
65+
@Builder.Default
66+
private boolean deleted = false;
5967

60-
// --- JPA lifecycle callbacks ---
61-
@PrePersist
62-
protected void onCreate() {
63-
this.createdAt = java.time.Instant.now();
64-
}
68+
// `createdAt` is null upon object creation.
69+
// It will be set by the `onCreate()` method right before persistence.
70+
@Column(name = "created_at", nullable = false, updatable = false)
71+
private Instant createdAt;
6572

66-
// --- Business Logic Helper ---
67-
// HMCTS mandates business logic in services, but a setter hook is acceptable.
68-
// Lifecycle callback - special method runs automatically before Hibernate updates a record in the database.
69-
@PreUpdate
70-
protected void onUpdate() {
73+
@Column(name = "modified_at")
74+
private Instant modifiedAt;
7175

72-
this.modifiedAt = java.time.Instant.now();
73-
}
76+
// --- JPA lifecycle callbacks ---
77+
/**
78+
* Sets createdAt before persisting a new Book record.
79+
*/
80+
@PrePersist
81+
protected void onCreate() {
82+
this.createdAt = Instant.now();
83+
}
7484

85+
// --- Business Logic Helper ---
86+
// HMCTS requires business logic to live in services; setter hooks are allowed.
87+
// Lifecycle callback: runs automatically before Hibernate updates a database record.
7588

76-
}
89+
/**
90+
* Updates modifiedAt before updating an existing Book record.
91+
*/
92+
@PreUpdate
93+
protected void onUpdate() {
94+
this.modifiedAt = Instant.now();
95+
}
96+
}
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
package com.codesungrape.hmcts.bookapi.repository;
22

3+
import com.codesungrape.hmcts.bookapi.entity.Book;
34
import java.util.List;
45
import java.util.Optional;
56
import java.util.UUID;
6-
7-
import com.codesungrape.hmcts.bookapi.entity.Book;
87
import org.springframework.data.jpa.repository.JpaRepository;
98
import org.springframework.stereotype.Repository;
109

1110
/**
12-
* Repository interface for Book Entity.
13-
* Spring Data JPA automatically provides CRUD operations based on the Entity and ID type.
11+
* Repository interface for Book entities.
12+
* Provides CRUD operations and custom queries for non-deleted books.
13+
* Spring Data JPA automatically implements this interface at runtime.
1414
*/
1515
@Repository
1616
public interface BookRepository extends JpaRepository<Book, UUID> {
1717

18-
// Custom query to find books that have NOT been soft-deleted
19-
List<Book> findAllByDeletedFalse();
18+
/**
19+
* Custom query retrieves all Book records that have not been soft-deleted.
20+
*/
21+
List<Book> findAllByDeletedFalse();
2022

21-
// Custom query to find a specific, non-deleted book by ID.
22-
Optional<Book> findByIdAndDeletedFalse(UUID id);
23+
/**
24+
* Retrieves a single Book by ID, if it exists and has not been soft-deleted.
25+
*/
26+
Optional<Book> findByIdAndDeletedFalse(UUID id);
2327

2428
}
Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package com.codesungrape.hmcts.bookapi.service;
22

33
import com.codesungrape.hmcts.bookapi.dto.BookRequest;
4+
import com.codesungrape.hmcts.bookapi.entity.Book;
45
import com.codesungrape.hmcts.bookapi.repository.BookRepository;
5-
import org.springframework.stereotype.Service; // Marks a class as a Service Layer component.
66
import lombok.RequiredArgsConstructor;
7-
8-
import com.codesungrape.hmcts.bookapi.entity.Book;
7+
import org.springframework.stereotype.Service;
98

109
/**
1110
* Service layer responsible for all business logic related to the Book resource.
@@ -14,43 +13,47 @@
1413
@RequiredArgsConstructor // Lombok creates constructor for dependency injection
1514
public class BookService {
1615

17-
// Create a field to store the repo
18-
private final BookRepository bookRepository;
19-
20-
// 1. CREATE Operation (POST /books)
21-
public Book createBook(BookRequest request) {
22-
// Validation check for business rules (e.g., uniqueness, if required)
23-
if (request == null) {
24-
throw new NullPointerException("BookRequest cannot be null");
25-
}
26-
27-
28-
// REVISIT: Leaving this here for now as i haven't implemented the Controller Layer yet
29-
// The service layer is duplicating validation that already exists in the
30-
// BookRequest DTO with @notblank annotations. Since the DTO has validation
31-
// constraints, this manual check is redundant when Spring's validation
32-
// framework is properly configured in the controller layer.
33-
// Consider removing this duplication or adding a comment explaining
34-
// why service-level validation is necessary in addition to DTO validation.
35-
if (request.getTitle() == null || request.getTitle().isBlank()) {
36-
throw new IllegalArgumentException("Book title cannot be null or blank");
37-
}
38-
39-
// Map DTO to Entity
40-
Book newBook = Book.builder()
41-
.title(request.getTitle())
42-
.author(request.getAuthor())
43-
.synopsis(request.getSynopsis())
44-
// ID and created_at are auto-generated by JPA/DB
45-
.build();
46-
47-
Book savedBook = bookRepository.save(newBook);
48-
49-
// Defensive check (even though it "shouldn't" happen aka follows JPA contract)
50-
if (savedBook == null) {
51-
throw new IllegalStateException("Failed to save book - repository returned null");
52-
}
53-
54-
return savedBook;
16+
// Create a field to store the repo
17+
private final BookRepository bookRepository;
18+
19+
/**
20+
* Creates a new Book entity from the given BookRequest DTO and persists it.
21+
*
22+
* @param request DTO containing book details (title, author, synopsis)
23+
* @return The saved Book entity
24+
* @throws NullPointerException if request is null
25+
* @throws IllegalArgumentException if title is null or blank
26+
* @throws IllegalStateException if the repository fails to save the book
27+
*/
28+
29+
public Book createBook(BookRequest request) {
30+
// Validation check for business rules (e.g., uniqueness, if required)
31+
if (request == null) {
32+
throw new NullPointerException("BookRequest cannot be null");
5533
}
34+
35+
36+
// TODO: Leaving this here for now as i haven't implemented the Controller Layer yet
37+
// The service layer is duplicating validation that already exists in the
38+
// BookRequest DTO with @notblank annotations. Since the DTO has validation
39+
// constraints, this manual check is redundant when Spring's validation
40+
// framework is properly configured in the controller layer.
41+
// Consider removing this duplication or adding a comment explaining
42+
// why service-level validation is necessary in addition to DTO validation.
43+
if (request.title() == null || request.title().isBlank()) {
44+
throw new IllegalArgumentException("Book title cannot be null or blank");
45+
}
46+
47+
// Map DTO to Entity
48+
Book newBook = Book.builder()
49+
.title(request.title())
50+
.author(request.author())
51+
.synopsis(request.synopsis())
52+
// ID and created_at are auto-generated by JPA/DB
53+
.build();
54+
55+
Book savedBook = bookRepository.save(newBook);
56+
57+
return savedBook;
58+
}
5659
}

src/test/java/com/codesungrape/hmcts/bookapi/BookApiApplicationTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
@ActiveProfiles("test")
99
class BookApiApplicationTests {
1010

11-
@Test
12-
void contextLoads() {
13-
}
11+
@Test
12+
void contextLoads() {
13+
}
1414

1515
}

0 commit comments

Comments
 (0)