Skip to content

Commit

Permalink
Merge pull request #4 from szymonpoltorak/data-validation
Browse files Browse the repository at this point in the history
Data validation
  • Loading branch information
szymonpoltorak authored Nov 19, 2023
2 parents 448ca95 + 4ec50e9 commit 1459828
Show file tree
Hide file tree
Showing 32 changed files with 1,730 additions and 47 deletions.
1 change: 1 addition & 0 deletions corn-backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.projectlombok:lombok:1.18.28'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'org.postgresql:postgresql'
annotationProcessor 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

@SpringBootApplication
public class CornBackendApplication {
public static void main(String[] args) {
SpringApplication.run(CornBackendApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(CornBackendApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.corn.cornbackend.entities.backlog.comment;

import dev.corn.cornbackend.entities.backlog.comment.constants.BacklogItemCommentConstants;
import dev.corn.cornbackend.entities.backlog.item.BacklogItem;
import dev.corn.cornbackend.entities.user.User;
import dev.corn.cornbackend.utils.json.JsonMapper;
Expand All @@ -9,6 +10,9 @@
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -30,12 +34,17 @@ public class BacklogItemComment implements Jsonable {
@GeneratedValue(strategy = GenerationType.AUTO)
private long backlogItemCommentId;

@NotBlank(message = BacklogItemCommentConstants.BACKLOG_ITEM_COMMENT_COMMENT_BLANK_MSG)
@Size(max = BacklogItemCommentConstants.BACKLOG_ITEM_COMMENT_MAX_SIZE,
message = BacklogItemCommentConstants.BACKLOG_ITEM_COMMENT_COMMENT_WRONG_SIZE_MSG)
private String comment;

@ManyToOne
@NotNull(message = BacklogItemCommentConstants.BACKLOG_ITEM_COMMENT_USER_NULL_MSG)
private User user;

@ManyToOne
@NotNull(message = BacklogItemCommentConstants.BACKLOG_ITEM_COMMENT_BACKLOG_ITEM_NULL_MSG)
private BacklogItem backlogItem;

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package dev.corn.cornbackend.entities.backlog.comment.constants;

public final class BacklogItemCommentConstants {
public static final String BACKLOG_ITEM_COMMENT_COMMENT_BLANK_MSG = "Comment cannot be null and has to contain at least one non-whitespace character";
public static final String BACKLOG_ITEM_COMMENT_COMMENT_WRONG_SIZE_MSG = "Comment must consist of max 500 characters";
public static final int BACKLOG_ITEM_COMMENT_MAX_SIZE = 500;
public static final String BACKLOG_ITEM_COMMENT_COMMENT_FIELD_NAME = "comment";

public static final String BACKLOG_ITEM_COMMENT_USER_NULL_MSG = "User cannot be null";
public static final String BACKLOG_ITEM_COMMENT_USER_FIELD_NAME = "user";

public static final String BACKLOG_ITEM_COMMENT_BACKLOG_ITEM_NULL_MSG = "BackLogItem cannot be null";
public static final String BACKLOG_ITEM_COMMENT_BACKLOG_ITEM_FIELD_NAME = "backlogItem";

private BacklogItemCommentConstants() {

}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package dev.corn.cornbackend.entities.backlog.item;

import dev.corn.cornbackend.entities.backlog.comment.BacklogItemComment;
import dev.corn.cornbackend.entities.backlog.item.constants.BacklogItemConstants;
import dev.corn.cornbackend.entities.project.Project;
import dev.corn.cornbackend.entities.project.member.ProjectMember;
import dev.corn.cornbackend.entities.sprint.Sprint;
import dev.corn.cornbackend.utils.json.JsonMapper;
import dev.corn.cornbackend.utils.json.interfaces.Jsonable;
import dev.corn.cornbackend.utils.validators.interfaces.NoNullElements;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
Expand All @@ -14,6 +16,9 @@
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -36,24 +41,35 @@ public class BacklogItem implements Jsonable {
@GeneratedValue(strategy = GenerationType.AUTO)
private long backlogItemId;

@NotBlank(message = BacklogItemConstants.BACKLOG_ITEM_TITLE_BLANK_MSG)
@Size(max = BacklogItemConstants.BACKLOG_ITEM_TITLE_MAX_SIZE,
message = BacklogItemConstants.BACKLOG_ITEM_TITLE_WRONG_SIZE_MSG)
private String title;

@NotBlank(message = BacklogItemConstants.BACKLOG_ITEM_DESCRIPTION_BLANK_MSG)
@Size(max = BacklogItemConstants.BACKLOG_ITEM_DESCRIPTION_MAX_SIZE,
message = BacklogItemConstants.BACKLOG_ITEM_DESCRIPTION_WRONG_SIZE_MSG)
private String description;

@Enumerated(value = EnumType.STRING)
@NotNull(message = BacklogItemConstants.BACKLOG_ITEM_STATUS_NULL_MSG)
private ItemStatus status;

@OneToMany
@ToString.Exclude
@NoNullElements(message = BacklogItemConstants.BACKLOG_ITEM_COMMENTS_NULL_ELEMENTS_MSG)
private List<BacklogItemComment> comments;

@ManyToOne
@NotNull(message = BacklogItemConstants.BACKLOG_ITEM_ASSIGNEE_NULL_MSG)
private ProjectMember assignee;

@ManyToOne
@NotNull(message = BacklogItemConstants.BACKLOG_ITEM_SPRINT_NULL_MSG)
private Sprint sprint;

@ManyToOne
@NotNull(message = BacklogItemConstants.BACKLOG_ITEM_PROJECT_NULL_MSG)
private Project project;

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.corn.cornbackend.entities.backlog.item.constants;

public final class BacklogItemConstants {
public static final String BACKLOG_ITEM_TITLE_BLANK_MSG = "Title cannot be null and has to contain at least one non-whitespace character";
public static final String BACKLOG_ITEM_TITLE_WRONG_SIZE_MSG = "Title must consist of max 100 characters";
public static final String BACKLOG_ITEM_TITLE_FIELD_NAME = "title";
public static final int BACKLOG_ITEM_TITLE_MAX_SIZE = 100;

public static final String BACKLOG_ITEM_DESCRIPTION_BLANK_MSG = "Title cannot be null and has to contain at least one non-whitespace character";
public static final String BACKLOG_ITEM_DESCRIPTION_WRONG_SIZE_MSG = "Description must consist of max 500 characters";
public static final String BACKLOG_ITEM_DESCRIPTION_FIELD_NAME = "description";
public static final int BACKLOG_ITEM_DESCRIPTION_MAX_SIZE = 500;

public static final String BACKLOG_ITEM_STATUS_NULL_MSG = "Item status cannot be null";
public static final String BACKLOG_ITEM_STATUS_FIELD_NAME = "status";

public static final String BACKLOG_ITEM_COMMENTS_NULL_ELEMENTS_MSG = "Comments cannot be null nor contain null elements";
public static final String BACKLOG_ITEM_COMMENTS_FIELD_NAME = "comments";

public static final String BACKLOG_ITEM_ASSIGNEE_NULL_MSG = "Assignee cannot be null";
public static final String BACKLOG_ITEM_ASSIGNEE_FIELD_NAME = "assignee";

public static final String BACKLOG_ITEM_SPRINT_NULL_MSG = "Sprint cannot be null";
public static final String BACKLOG_ITEM_SPRINT_FIELD_NAME = "sprint";

public static final String BACKLOG_ITEM_PROJECT_NULL_MSG = "Project cannot be null";
public static final String BACKLOG_ITEM_PROJECT_FIELD_NAME = "project";

private BacklogItemConstants() {

}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package dev.corn.cornbackend.entities.project;

import dev.corn.cornbackend.entities.project.constants.ProjectConstants;
import dev.corn.cornbackend.entities.sprint.Sprint;
import dev.corn.cornbackend.entities.user.User;
import dev.corn.cornbackend.utils.json.JsonMapper;
import dev.corn.cornbackend.utils.json.interfaces.Jsonable;
import dev.corn.cornbackend.utils.validators.interfaces.NoNullElements;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -32,13 +37,18 @@ public class Project implements Jsonable {
@GeneratedValue(strategy = GenerationType.AUTO)
private long projectId;

@NotBlank(message = ProjectConstants.PROJECT_NAME_BLANK_MSG)
@Size(max = ProjectConstants.PROJECT_NAME_MAX_SIZE,
message = ProjectConstants.PROJECT_NAME_WRONG_SIZE_MSG)
private String name;

@OneToMany
@ToString.Exclude
private List<Sprint> sprint;
@NoNullElements(message = ProjectConstants.PROJECT_SPRINTS_NULL_ELEMENTS_MSG)
private List<Sprint> sprints;

@ManyToOne
@NotNull(message = ProjectConstants.PROJECT_OWNER_NULL_MSG)
private User owner;

@Override
Expand All @@ -52,15 +62,15 @@ public final boolean equals(Object object) {
if (projectId != project.projectId || !Objects.equals(name, project.name)) {
return false;
}
return Objects.equals(sprint, project.sprint);
return Objects.equals(sprints, project.sprints);
}

@Override
public final int hashCode() {
int result = (int) (projectId ^ (projectId >>> 32));

result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (sprint != null ? sprint.hashCode() : 0);
result = 31 * result + (sprints != null ? sprints.hashCode() : 0);

return result;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.corn.cornbackend.entities.project.constants;


public final class ProjectConstants {
public static final String PROJECT_NAME_FIELD_NAME = "name";
public static final String PROJECT_NAME_BLANK_MSG = "Name cannot be null and has to contain at least one non-whitespace character";
public static final String PROJECT_NAME_WRONG_SIZE_MSG = "Name must consist of max 100 characters";
public static final int PROJECT_NAME_MAX_SIZE = 100;

public static final String PROJECT_SPRINTS_FIELD_NAME = "sprints";
public static final String PROJECT_SPRINTS_NULL_ELEMENTS_MSG = "Sprints cannot be null nor contain null elements";

public static final String PROJECT_OWNER_FIELD_NAME = "owner";
public static final String PROJECT_OWNER_NULL_MSG = "Owner cannot be null";

private ProjectConstants() {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

import dev.corn.cornbackend.entities.backlog.item.BacklogItem;
import dev.corn.cornbackend.entities.project.Project;
import dev.corn.cornbackend.entities.project.member.constants.ProjectMemberConstants;
import dev.corn.cornbackend.entities.user.User;
import dev.corn.cornbackend.utils.json.JsonMapper;
import dev.corn.cornbackend.utils.json.interfaces.Jsonable;
import dev.corn.cornbackend.utils.validators.interfaces.NoNullElements;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -35,12 +38,15 @@ public class ProjectMember implements Jsonable {

@OneToMany
@ToString.Exclude
private List<BacklogItem> backlogItem;
@NoNullElements(message = ProjectMemberConstants.PROJECT_MEMBER_BACKLOG_ITEM_NULL_ELEMENTS_MSG)
private List<BacklogItem> backlogItems;

@ManyToOne
@NotNull(message = ProjectMemberConstants.PROJECT_MEMBER_PROJECT_NULL_MSG)
private Project project;

@ManyToOne
@NotNull(message = ProjectMemberConstants.PROJECT_MEMBER_USER_NULL_MSG)
private User user;

@Override
Expand All @@ -51,7 +57,7 @@ public final boolean equals(Object object) {
if (!(object instanceof ProjectMember member)) {
return false;
}
if (projectMemberId != member.projectMemberId || !Objects.equals(backlogItem, member.backlogItem)) {
if (projectMemberId != member.projectMemberId || !Objects.equals(backlogItems, member.backlogItems)) {
return false;
}
if (!Objects.equals(project, member.project)) {
Expand All @@ -64,7 +70,7 @@ public final boolean equals(Object object) {
public final int hashCode() {
int result = (int) (projectMemberId ^ (projectMemberId >>> 32));

result = 31 * result + (backlogItem != null ? backlogItem.hashCode() : 0);
result = 31 * result + (backlogItems != null ? backlogItems.hashCode() : 0);
result = 31 * result + (project != null ? project.hashCode() : 0);
result = 31 * result + (user != null ? user.hashCode() : 0);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package dev.corn.cornbackend.entities.project.member.constants;

public final class ProjectMemberConstants {
public static final String PROJECT_MEMBER_BACKLOG_ITEM_FIELD_NAME = "backlogItems";
public static final String PROJECT_MEMBER_BACKLOG_ITEM_NULL_ELEMENTS_MSG = "BacklogItems cannot be null nor contain null elements";

public static final String PROJECT_MEMBER_PROJECT_FIELD_NAME = "project";
public static final String PROJECT_MEMBER_PROJECT_NULL_MSG = "Project cannot be null";

public static final String PROJECT_MEMBER_USER_FIELD_NAME = "user";
public static final String PROJECT_MEMBER_USER_NULL_MSG = "User cannot be null";


private ProjectMemberConstants() {

}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
package dev.corn.cornbackend.entities.sprint;

import dev.corn.cornbackend.entities.project.Project;
import dev.corn.cornbackend.entities.sprint.constants.SprintConstants;
import dev.corn.cornbackend.utils.json.JsonMapper;
import dev.corn.cornbackend.utils.json.interfaces.Jsonable;
import dev.corn.cornbackend.utils.validators.interfaces.LaterThan;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.validation.constraints.Future;
import jakarta.validation.constraints.FutureOrPresent;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -25,20 +32,34 @@
@Builder
@NoArgsConstructor
@AllArgsConstructor
@LaterThan(firstDateGetterName = SprintConstants.SPRINT_FIRST_DATE_GETTER_NAME,
secondDateGetterName = SprintConstants.SPRINT_SECOND_DATE_GETTER_NAME,
message = SprintConstants.SPRINT_LATER_THAN_MSG)
public class Sprint implements Jsonable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long sprintId;

@ManyToOne
@NotNull(message = SprintConstants.SPRINT_PROJECT_NULL_MSG)
private Project project;

@NotBlank(message = SprintConstants.SPRINT_NAME_BLANK_MSG)
@Size(max = SprintConstants.SPRINT_NAME_MAX_SIZE,
message = SprintConstants.SPRINT_NAME_WRONG_SIZE_MSG)
private String sprintName;

@NotBlank(message = SprintConstants.SPRINT_DESCRIPTION_BLANK_MSG)
@Size(max = SprintConstants.SPRINT_DESCRIPTION_MAX_SIZE,
message = SprintConstants.SPRINT_DESCRIPTION_WRONG_SIZE_MSG)
private String sprintDescription;

@NotNull(message = SprintConstants.SPRINT_START_DATE_NULL_MSG)
@FutureOrPresent(message = SprintConstants.SPRINT_START_DATE_FUTURE_OR_PRESENT_MSG)
private LocalDate sprintStartDate;

@NotNull(message = SprintConstants.SPRINT_END_DATE_NULL_MSG)
@Future(message = SprintConstants.SPRINT_END_DATE_FUTURE_MSG)
private LocalDate sprintEndDate;

@Override
Expand Down
Loading

0 comments on commit 1459828

Please sign in to comment.