-
Notifications
You must be signed in to change notification settings - Fork 39
Implemented all items on checklist #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,6 +18,26 @@ public class User { | |
| @Column(name = "id") | ||
| private String id; | ||
|
|
||
| public void setFirstName(String firstName) { | ||
| this.firstName = firstName; | ||
| } | ||
|
|
||
| public void setMiddleName(String middleName) { | ||
| this.middleName = middleName; | ||
| } | ||
|
|
||
| public void setLastName(String lastName) { | ||
| this.lastName = lastName; | ||
| } | ||
|
|
||
| public void setPhoneNumber(Integer phoneNumber) { | ||
| this.phoneNumber = phoneNumber; | ||
| } | ||
|
|
||
| public void setUpdated(LocalDateTime updated) { | ||
| this.updated = updated; | ||
| } | ||
|
|
||
| @Column(name = "first_name", nullable = false) | ||
| private String firstName; | ||
|
|
||
|
|
@@ -27,9 +47,37 @@ public class User { | |
| @Column(name = "last_name", nullable = false) | ||
| private String lastName; | ||
|
|
||
| public String getId() { | ||
| return id; | ||
| } | ||
|
|
||
| public String getFirstName() { | ||
| return firstName; | ||
| } | ||
|
|
||
| public String getMiddleName() { | ||
| return middleName; | ||
| } | ||
|
|
||
| public String getLastName() { | ||
| return lastName; | ||
| } | ||
|
|
||
| public Integer getPhoneNumber() { | ||
| return phoneNumber; | ||
| } | ||
|
|
||
| public LocalDateTime getUpdated() { | ||
| return updated; | ||
| } | ||
|
|
||
| @Column(name = "phone_number", nullable = false) | ||
| private Integer phoneNumber; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| @Column(name = "updated", nullable = false) | ||
| private LocalDateTime updated; | ||
|
|
||
|
|
||
| public User(){ | ||
| super(); | ||
| this.id = UUID.randomUUID().toString(); | ||
|
|
@@ -41,5 +89,6 @@ public User(final UserSaveDto user){ | |
| this.firstName = user.getFirstName(); | ||
| this.middleName = user.getMiddleName(); | ||
| this.lastName = user.getLastName(); | ||
| this.phoneNumber = user.getPhoneNumber(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,6 +68,17 @@ protected <X, Y extends Collection<X>> void applyInFilter( | |
| predicates.add(path.in(values)); | ||
| } | ||
|
|
||
| protected <X, Y extends Collection<X>> void applyInLengthFilter( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| final Expression<X> path, | ||
| final Y values, | ||
| final Integer length | ||
| ){ | ||
| if(ValidatorUtil.isInvalidLength(values, length)){ | ||
| return; | ||
| } | ||
| predicates.add(path.in(values)); | ||
| } | ||
|
|
||
| protected <X extends Collection<String>> void applyStringFilter( | ||
| final Expression<String> path, | ||
| final X values | ||
|
|
@@ -103,4 +114,5 @@ protected <X extends Collection<String>> void applyStringFilter( | |
| applyInFilter(targetPath, inClause); | ||
| } | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,9 @@ | |
| import com.bravo.user.model.filter.UserFilter; | ||
| import javax.persistence.criteria.CriteriaBuilder; | ||
| import javax.persistence.criteria.CriteriaQuery; | ||
| import javax.persistence.criteria.Path; | ||
| import javax.persistence.criteria.Root; | ||
| import java.util.Set; | ||
|
|
||
| public class UserSpecification extends AbstractSpecification<User> { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to |
||
|
|
||
|
|
@@ -27,5 +29,14 @@ public void doFilter( | |
| applyStringFilter(root.get("firstName"), filter.getFirstNames()); | ||
| applyStringFilter(root.get("lastName"), filter.getLastNames()); | ||
| applyStringFilter(root.get("middleName"), filter.getMiddleNames()); | ||
|
|
||
| // Validates whether phone number contains only digits | ||
| applyInFilter(root.get("phoneNumber"), filter.getPhoneNumbers()); | ||
|
|
||
| // Validates whether phone number complies with correct length | ||
| applyInLengthFilter(root.get("phoneNumber"), filter.getPhoneNumbers(), filter.getPhoneNumberLength()); | ||
|
|
||
| } | ||
|
|
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,5 +8,19 @@ public class UserReadDto { | |
|
|
||
| private String id; | ||
| private String name; | ||
| private Integer phoneNumber; | ||
| private LocalDateTime updated; | ||
|
|
||
| public void setName(String name) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These getters/setters are not necessary since the Lombok |
||
| this.name = name; | ||
| } | ||
|
|
||
| public void setPhoneNumber(Integer phoneNumber) { | ||
| this.phoneNumber = phoneNumber; | ||
| } | ||
|
|
||
| public void setUpdated(LocalDateTime updated) { | ||
| this.updated = updated; | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,4 +8,23 @@ public class UserSaveDto { | |
| private String firstName; | ||
| private String middleName; | ||
| private String lastName; | ||
| private Integer phoneNumber; | ||
|
|
||
| public String getFirstName() { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These getters/setters are not necessary since the Lombok |
||
| return firstName; | ||
| } | ||
|
|
||
| public String getMiddleName() { | ||
| return middleName; | ||
| } | ||
|
|
||
| public String getLastName() { | ||
| return lastName; | ||
| } | ||
|
|
||
| public Integer getPhoneNumber() { | ||
| return phoneNumber; | ||
| } | ||
|
|
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,9 +7,40 @@ | |
| @Data | ||
| public class UserFilter { | ||
|
|
||
| public Set<String> getIds() { | ||
| return ids; | ||
| } | ||
|
|
||
| private Set<String> ids; | ||
| private Set<String> firstNames; | ||
| private Set<String> lastNames; | ||
| private Set<String> middleNames; | ||
| private Set<Integer> phoneNumbers; | ||
|
|
||
| public Set<String> getFirstNames() { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These getters/setters are not necessary since the Lombok |
||
| return firstNames; | ||
| } | ||
|
|
||
| public Set<String> getLastNames() { | ||
| return lastNames; | ||
| } | ||
|
|
||
| public Set<String> getMiddleNames() { | ||
| return middleNames; | ||
| } | ||
|
|
||
| public Set<Integer> getPhoneNumbers() { | ||
| return phoneNumbers; | ||
| } | ||
|
|
||
| public Integer getPhoneNumberLength() { | ||
| return phoneNumberLength; | ||
| } | ||
|
|
||
| public DateFilter<LocalDateTime> getDateFilter() { | ||
| return dateFilter; | ||
| } | ||
|
|
||
| private final Integer phoneNumberLength = 10; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree and I made a comment to your point. I just did not have time to either add a validator or be familiar enough w/your code to know the proper place to put this. static of course should have been added. |
||
| private DateFilter<LocalDateTime> dateFilter; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -41,12 +41,27 @@ else if(value instanceof DateFilter<?>){ | |
| else if(value instanceof String){ | ||
| isValid = isStringValid((String)value); | ||
| } | ||
| else if(value instanceof Integer) { | ||
| isValid = isIntegerValid((Integer)value); | ||
| } | ||
| else { | ||
| isValid = value != null; | ||
| } | ||
| return isValid; | ||
| } | ||
|
|
||
| public static <T> boolean isInvalidLength(T value, T length){ | ||
| return !isValidLength(value, length); | ||
| } | ||
|
|
||
| public static <T> boolean isValidLength(T value, T length){ | ||
| boolean isValid = false; | ||
| if(value instanceof Integer){ | ||
| isValid = isIntegerLengthValid((Integer) value, (Integer) length); | ||
| } | ||
| return isValid; | ||
| } | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the implementation of this method is very effective. It would be better if it took a min and max range and then compared the value for numbers and the length for strings. Then if you really wanted you can overload a version that assumes 0 as the min value.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking in a purely linear way here in regards to testing only Integer values. With that in mind, I am not sure if using a range where I would have to set both a min and max arg to, say values which only differ by two in order to test the ceiling of an Integer value would be more effective than my isValidLength function which when all told should handle checks on only Integers in less code than your re-factored example(unless your point was to emphasize additional data types being covered as well as the extensibility of testing for both a range on an Integer as well as a single value). |
||
|
|
||
|
|
||
| private static boolean isCollectionValid(final Collection<?> collection){ | ||
| return !collection.isEmpty() && !collection.stream() | ||
|
|
@@ -62,4 +77,16 @@ private static boolean isDateFilterValid(final DateFilter<?> date){ | |
| private static boolean isStringValid(final String string){ | ||
| return string != null && !string.trim().isEmpty(); | ||
| } | ||
|
|
||
| private static boolean isIntegerValid(final Integer integer) { | ||
| if(integer == null || integer == 0) | ||
| return false; | ||
| String onlyDigits = "\\d+"; | ||
| String inString = integer.toString(); | ||
| return inString.matches(onlyDigits); | ||
| } | ||
|
|
||
| private static boolean isIntegerLengthValid(final Integer integer, final Integer length) { | ||
| return String.valueOf(integer).length() == length; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |
| import com.bravo.user.utility.ValidatorUtil; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.validation.Errors; | ||
| import com.bravo.user.model.filter.UserFilter; | ||
|
|
||
| @Component | ||
| public class UserValidator extends CrudValidator { | ||
|
|
@@ -20,13 +21,25 @@ protected void validateCreate(Object o, Errors errors) { | |
|
|
||
| UserSaveDto instance = (UserSaveDto) o; | ||
|
|
||
| /* Admittedly, this is a bit of a hack storing the phone number length in | ||
| * the UserFilter class and having to new up an instance here :( | ||
| */ | ||
| UserFilter userFilter = new UserFilter(); | ||
|
|
||
| // required fields | ||
| if(ValidatorUtil.isInvalid(instance.getFirstName())){ | ||
| errors.reject("'firstName' is required"); | ||
| } | ||
| if(ValidatorUtil.isInvalid(instance.getLastName())){ | ||
| errors.reject("'lastName' is required"); | ||
| } | ||
| if(ValidatorUtil.isInvalid(instance.getPhoneNumber())){ | ||
| errors.reject("'phoneNumber' is required and must contain only digits"); | ||
| } | ||
| if(ValidatorUtil.isInvalidLength(instance.getPhoneNumber(), userFilter.getPhoneNumberLength())){ | ||
| errors.reject("'phoneNumber' must be 10 digits in length"); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -37,5 +50,9 @@ protected void validateUpdate(Object o, Errors errors) { | |
| if(ValidatorUtil.isEmpty(instance, "id", "updated")){ | ||
| errors.reject("'request' modifiable field(s) are required"); | ||
| } | ||
|
|
||
| if(String.valueOf(instance.getPhoneNumber()).length() > 0 && ValidatorUtil.isInvalid(instance.getPhoneNumber())){ | ||
| errors.reject("'phoneNumber' is must contain only digits"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Weird wording on this error message. |
||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,12 +5,13 @@ create table user ( | |
| first_name varchar(100) not null, | ||
| middle_name varchar(100) null, | ||
| last_name varchar(100) not null, | ||
| phone_number integer not null, | ||
| updated timestamp not null default current_timestamp() | ||
| ); | ||
|
|
||
| insert into user (id, first_name, middle_name, last_name) values | ||
| ('097e1c2e-8ba3-463e-96d2-7a08f32944a6','Justin','Marquis','Wheeler'), | ||
| ('b1f6c877-c4a2-4e00-a986-2cbed56e257f','James',null,'Wagon'), | ||
| ('d7d77a1b-d0e4-49bb-804d-895db58027cb','John','Smith','Doe'), | ||
| ('5f99aae9-7426-4e5b-932a-4f7066785e63','Jack',null,'Pool'), | ||
| ('d54cbbb5-96f7-496e-8142-ce4966061940','Joan','Marie','River'); | ||
| ('097e1c2e-8ba3-463e-96d2-7a08f32944a6','Justin','Marquis','Wheeler', 6161112222), | ||
| ('b1f6c877-c4a2-4e00-a986-2cbed56e257f','James',null,'Wagon', 6162223333), | ||
| ('d7d77a1b-d0e4-49bb-804d-895db58027cb','John','Smith','Doe', 6163334444), | ||
| ('5f99aae9-7426-4e5b-932a-4f7066785e63','Jack',null,'Pool', 6164445555), | ||
| ('d54cbbb5-96f7-496e-8142-ce4966061940','Joan','Marie','River', 6165556666); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have a bug in this h2 seed file that is preventing the app from running with the following exception. You should've updated the |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These getters/setters are not necessary since the Lombok
@Dataannotation provides them.