-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #336 from devgateway/task/3.x/unique-property-vali…
…dator unique property validator (3.x)
- Loading branch information
Showing
9 changed files
with
170 additions
and
2 deletions.
There are no files selected for viewing
60 changes: 60 additions & 0 deletions
60
forms/src/main/java/org/devgateway/toolkit/forms/validators/UniquePropertyValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package org.devgateway.toolkit.forms.validators; | ||
|
||
import org.apache.wicket.Component; | ||
import org.apache.wicket.model.IModel; | ||
import org.apache.wicket.model.StringResourceModel; | ||
import org.apache.wicket.validation.IValidatable; | ||
import org.apache.wicket.validation.IValidator; | ||
import org.apache.wicket.validation.ValidationError; | ||
import org.devgateway.toolkit.persistence.dao.GenericPersistable; | ||
import org.devgateway.toolkit.persistence.service.UniquePropertyService; | ||
|
||
import java.io.Serializable; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
|
||
/** | ||
* @author Nadejda Mandrescu | ||
*/ | ||
public class UniquePropertyValidator<T extends GenericPersistable & Serializable, V> implements IValidator<V> { | ||
private static final long serialVersionUID = -7185120038483258730L; | ||
|
||
protected final UniquePropertyService<T> uniquePropertyService; | ||
protected final Collection<Long> entityIdsToIgnore; | ||
protected final String propertyName; | ||
protected final IModel<String> propertyLabel; | ||
|
||
public UniquePropertyValidator(final UniquePropertyService<T> uniquePropertyService, | ||
final long entityIdToIgnore, final String propertyName, final Component component) { | ||
this(uniquePropertyService, Collections.singleton(entityIdToIgnore), propertyName, component); | ||
} | ||
|
||
public UniquePropertyValidator(final UniquePropertyService<T> uniquePropertyService, | ||
final Collection<Long> entityIdsToIgnore, final String propertyName, final Component component) { | ||
this(uniquePropertyService, entityIdsToIgnore, propertyName, | ||
new StringResourceModel(propertyName + ".label", component)); | ||
} | ||
|
||
public UniquePropertyValidator(final UniquePropertyService<T> uniquePropertyService, | ||
final Collection<Long> entityIdsToIgnore, final String propertyName, final IModel<String> propertyLabel) { | ||
if (entityIdsToIgnore.isEmpty()) { | ||
entityIdsToIgnore.add(-1L); | ||
} | ||
this.uniquePropertyService = uniquePropertyService; | ||
this.entityIdsToIgnore = entityIdsToIgnore; | ||
this.propertyName = propertyName; | ||
this.propertyLabel = propertyLabel; | ||
} | ||
|
||
@Override | ||
public void validate(final IValidatable<V> validatable) { | ||
final V value = validatable.getValue(); | ||
if (uniquePropertyService.existsByProperty(propertyName, value, entityIdsToIgnore)) { | ||
ValidationError error = new ValidationError(this); | ||
error.setVariable("label", propertyLabel.getObject()); | ||
error.setVariable("input", value); | ||
validatable.error(error); | ||
} | ||
} | ||
|
||
} |
1 change: 1 addition & 0 deletions
1
.../src/main/java/org/devgateway/toolkit/forms/validators/UniquePropertyValidator.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
UniquePropertyValidator=${label} equal to '${input}' already exists |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
...n/java/org/devgateway/toolkit/persistence/repository/norepository/SpecificationUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package org.devgateway.toolkit.persistence.repository.norepository; | ||
|
||
import org.apache.commons.lang3.StringUtils; | ||
|
||
import javax.persistence.criteria.CriteriaBuilder; | ||
import javax.persistence.criteria.Expression; | ||
import javax.persistence.criteria.Predicate; | ||
import javax.persistence.criteria.Root; | ||
|
||
/** | ||
* @author Nadejda Mandrescu | ||
*/ | ||
public final class SpecificationUtils { | ||
private SpecificationUtils() { | ||
} | ||
|
||
public static Expression<String> ignoreCaseLikeValue(final CriteriaBuilder cb, final String value) { | ||
return cb.lower(cb.concat(cb.concat(cb.literal("%"), value), "%")); | ||
} | ||
|
||
public static Predicate equalIgnoreCaseValue(final Root<?> root, final CriteriaBuilder cb, | ||
final String propertyName, final String value) { | ||
return cb.equal(cb.lower(root.get(propertyName)), StringUtils.lowerCase(value)); | ||
} | ||
|
||
} |
38 changes: 38 additions & 0 deletions
38
.../org/devgateway/toolkit/persistence/repository/norepository/UniquePropertyRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package org.devgateway.toolkit.persistence.repository.norepository; | ||
|
||
import org.devgateway.toolkit.persistence.dao.GenericPersistable; | ||
import org.springframework.data.jpa.domain.Specification; | ||
import org.springframework.data.repository.NoRepositoryBean; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import javax.persistence.criteria.Path; | ||
import javax.persistence.criteria.Predicate; | ||
import java.io.Serializable; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
|
||
/** | ||
* @author Nadejda Mandrescu | ||
*/ | ||
@NoRepositoryBean | ||
@Transactional | ||
public interface UniquePropertyRepository<T extends GenericPersistable, ID extends Serializable> | ||
extends BaseJpaRepository<T, ID> { | ||
|
||
default Specification<T> getFindByPropertySpecification(final String propertyName, final Object propertyValue, | ||
final Collection<ID> ignoreIds) { | ||
return (root, query, cb) -> { | ||
List<Predicate> predicates = new ArrayList<>(); | ||
Path<?> propertyPath = root.get(propertyName); | ||
if (String.class.isAssignableFrom(propertyPath.getJavaType())) { | ||
predicates.add(SpecificationUtils.equalIgnoreCaseValue(root, cb, propertyName, (String) propertyValue)); | ||
} else { | ||
predicates.add(cb.equal(propertyPath, propertyValue)); | ||
} | ||
predicates.add(root.get("id").in(ignoreIds).not()); | ||
return cb.and(predicates.toArray(new Predicate[predicates.size()])); | ||
}; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
...tence/src/main/java/org/devgateway/toolkit/persistence/service/UniquePropertyService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.devgateway.toolkit.persistence.service; | ||
|
||
import org.devgateway.toolkit.persistence.dao.GenericPersistable; | ||
import org.devgateway.toolkit.persistence.repository.norepository.UniquePropertyRepository; | ||
import org.springframework.data.jpa.domain.Specification; | ||
|
||
import java.io.Serializable; | ||
import java.util.Collection; | ||
|
||
/** | ||
* @author Nadejda Mandrescu | ||
*/ | ||
public interface UniquePropertyService<T extends GenericPersistable & Serializable> { | ||
UniquePropertyRepository<T, Long> uniquePropertyRepository(); | ||
|
||
default T findByProperty(final String propertyName, final Object propertyValue, final Collection<Long> ignoreIds) { | ||
final Specification<T> spec = | ||
uniquePropertyRepository().getFindByPropertySpecification(propertyName, propertyValue, ignoreIds); | ||
|
||
return uniquePropertyRepository().findOne(spec).orElse(null); | ||
} | ||
|
||
default boolean existsByProperty(final String propertyName, final Object propertyValue, | ||
final Collection<Long> ignoreIds) { | ||
final Specification<T> spec = | ||
uniquePropertyRepository().getFindByPropertySpecification(propertyName, propertyValue, ignoreIds); | ||
|
||
return uniquePropertyRepository().count(spec) > 0; | ||
} | ||
|
||
} |