
paa.coder.noodleCriteriaBuilder.queryBuilder.specifications.NoodleSpecificationBuilder Maven / Gradle / Ivy
package paa.coder.noodleCriteriaBuilder.queryBuilder.specifications;
import paa.coder.noodleCriteriaBuilder.NoodleFactory;
import paa.coder.noodleCriteriaBuilder.interfaces.NoodlePredicate;
import paa.coder.noodleCriteriaBuilder.interfaces.PathFinder;
import paa.coder.noodleCriteriaBuilder.queryBuilder.SubqueryBuilder;
import paa.coder.noodleCriteriaBuilder.queryBuilder.expressions.SelectStore;
import javax.persistence.criteria.CommonAbstractCriteria;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class NoodleSpecificationBuilder implements NoodlePredicate {
private final NoodleFactory noodleFactory;
private Boolean isNot;
private List predicates = new ArrayList<>();
private Predicate.BooleanOperator operator = null;
public static Optional getField(Object value){
if(value != null && String.class.isAssignableFrom(value.getClass())){
String field = ((String) value).trim();
if(field.startsWith("#")){
return Optional.of(field.replaceFirst("#", ""));
}
}
return Optional.empty();
}
private NoodleSpecificationBuilder(NoodleFactory noodleFactory, Boolean isNot){
this.noodleFactory = noodleFactory;
this.isNot = isNot;
}
private NoodleSpecificationBuilder(NoodleFactory noodleFactory, NoodlePredicate init, Boolean isNot){
this.noodleFactory = noodleFactory;
predicates.add(init);
this.isNot = isNot;
}
private NoodleSpecificationBuilder(NoodleFactory noodleFactory, NoodlePredicate left, NoodlePredicate right, Predicate.BooleanOperator operator){
this.noodleFactory = noodleFactory;
predicates.add(left);
predicates.add(right);
this.operator = operator;
isNot = false;
}
private NoodleSpecificationBuilder(NoodleSpecificationBuilder noodleSpecificationBuilder){
this.noodleFactory = noodleSpecificationBuilder.noodleFactory;
this.isNot = noodleSpecificationBuilder.isNot;
this.predicates = noodleSpecificationBuilder.predicates;
this.operator = noodleSpecificationBuilder.operator;
}
@Override
public Predicate apply(PathFinder pathFinder, CommonAbstractCriteria criteriaQuery, CriteriaBuilder criteriaBuilder){
Predicate[] result = predicates
.stream()
.map(i -> i.apply(pathFinder, criteriaQuery, criteriaBuilder))
.filter(Objects::nonNull)
.toArray(Predicate[]::new);
if(result.length == 0){
return null;
}
Predicate p = Objects.equals(Predicate.BooleanOperator.OR, this.operator) ? criteriaBuilder.or(result) : criteriaBuilder.and(result);
return isNot ? p.not() : p;
}
private NoodleSpecificationBuilder update(NoodlePredicate specification, Predicate.BooleanOperator operator){
if(specification == null){
return this;
}
if(this.operator == null || Objects.equals(operator, this.operator)){
predicates.add(specification);
}else{
this.predicates = Stream.of(new NoodleSpecificationBuilder(this), specification).collect(Collectors.toList());
}
this.operator = operator;
return this;
}
public NoodleSpecificationBuilder update(String field, String operator, Object value, Predicate.BooleanOperator predicateOperator){
return update(toPredicate(field, operator, value, false), predicateOperator);
}
public NoodleSpecificationBuilder update(Consumer consumer, String operator, Object value,
Predicate.BooleanOperator predicateOperator){
return update(toPredicate(consumer, operator, value, false), predicateOperator);
}
public NoodleSpecificationBuilder update(Function fPred,
Predicate.BooleanOperator predicateOperator){
return update(fPred.apply(new Builder(noodleFactory)), predicateOperator);
}
public NoodleSpecificationBuilder updateNot(String field, String operator, Object value, Predicate.BooleanOperator predicateOperator){
return update(toPredicate(field, operator, value, true), predicateOperator);
}
public NoodleSpecificationBuilder updateNot(Consumer consumer, String operator, Object value,
Predicate.BooleanOperator predicateOperator){
return update(toPredicate(consumer, operator, value, true), predicateOperator);
}
public NoodleSpecificationBuilder updateNot(Function fPred,
Predicate.BooleanOperator predicateOperator){
return update(fPred.apply(new Builder(noodleFactory, true)), predicateOperator);
}
public NoodleSpecificationBuilder andIsNotNul(String field){
return and(field, "IS NOT NULL", null);
}
public NoodleSpecificationBuilder andIsNul(String field){
return and(field, "IS NULL", null);
}
public NoodleSpecificationBuilder and(String field, Object value){
return and(field, "=", value);
}
public NoodleSpecificationBuilder and(Consumer consumer, Object value){
return and(consumer, "=", value);
}
public NoodleSpecificationBuilder andNot(String field, Object value){
return andNot(field, "=", value);
}
public NoodleSpecificationBuilder andNot(Consumer consumer, Object value){
return andNot(consumer, "=", value);
}
private static NoodlePredicate toPredicate(NoodleFactory noodleFactory, String field, String operator, Object value, Boolean isNot){
return NoodleSpecificationBuilder
.getField(value)
.map(f -> (NoodlePredicate) new FieldToFieldSpecification(field, operator, f, isNot))
.orElse(new SampleSpecification(noodleFactory, field, operator, value, isNot));
}
private static NoodlePredicate toPredicate(NoodleFactory noodleFactory, Consumer consumer, String operator, Object value,
Boolean isNot){
SelectStore.Single s = new SelectStore.Single();
consumer.accept(s);
return Optional
.ofNullable(s.getExpression())
.map(expression -> NoodleSpecificationBuilder
.getField(value)
.map(f -> (NoodlePredicate) new FieldToFieldSpecification(expression, operator, f, isNot))
.orElse(new SampleSpecification(noodleFactory, expression, operator, value, isNot)))
.orElse(null);
}
private NoodlePredicate toPredicate(String field, String operator, Object value, Boolean isNot){
return toPredicate(noodleFactory, field, operator, value, isNot);
}
private NoodlePredicate toPredicate(Consumer consumer, String operator, Object value, Boolean isNot){
return toPredicate(noodleFactory, consumer, operator, value, isNot);
}
public NoodleSpecificationBuilder and(String field, String operator, Object value){
return update(field, operator, value, Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder and(Consumer consumer, String operator, Object value){
return update(consumer, operator, value, Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder andNot(String field, String operator, Object value){
return updateNot(field, operator, value, Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder andNot(Consumer consumer, String operator, Object value){
return updateNot(consumer, operator, value, Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder and(Function fPred){
return update(fPred, Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder andNot(Function fPred){
return updateNot(fPred, Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder orIsNotNul(String field){
return or(field, "IS NOT NULL", null);
}
public NoodleSpecificationBuilder orIsNul(String field){
return or(field, "IS NULL", null);
}
public NoodleSpecificationBuilder or(String field, Object value){
return or(field, "=", value);
}
public NoodleSpecificationBuilder or(Consumer consumer, Object value){
return or(consumer, "=", value);
}
public NoodleSpecificationBuilder orNot(String field, Object value){
return orNot(field, "=", value);
}
public NoodleSpecificationBuilder orNot(Consumer consumer, Object value){
return orNot(consumer, "=", value);
}
public NoodleSpecificationBuilder or(String field, String operator, Object value){
return update(field, operator, value, Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder or(Consumer consumer, String operator, Object value){
return update(consumer, operator, value, Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder orNot(String field, String operator, Object value){
return updateNot(field, operator, value, Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder orNot(Consumer consumer, String operator, Object value){
return updateNot(consumer, operator, value, Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder or(Function fPred){
return update(fPred, Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder orNot(Function fPred){
return updateNot(fPred, Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder andSubquery(String field, SubqueryBuilder.Initiator.Runner value){
return andSubquery(field, "=", value);
}
public NoodleSpecificationBuilder andSubquery(String field, String operator, SubqueryBuilder.Initiator.Runner value){
return update(new FieldSubquerySpecification<>(field, operator, value.apply(new SubqueryBuilder.Initiator(noodleFactory))),
Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder andSubqueryNot(String field, SubqueryBuilder.Initiator.Runner value){
return andSubqueryNot(field, "=", value);
}
public NoodleSpecificationBuilder andSubqueryNot(String field, String operator, SubqueryBuilder.Initiator.Runner value){
return update(new FieldSubquerySpecification<>(field, operator, value.apply(new SubqueryBuilder.Initiator(noodleFactory)), true),
Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder orSubquery(String field, SubqueryBuilder.Initiator.Runner value){
return orSubquery(field, "=", value);
}
public NoodleSpecificationBuilder orSubquery(String field, String operator, SubqueryBuilder.Initiator.Runner value){
return update(new FieldSubquerySpecification<>(field, operator, value.apply(new SubqueryBuilder.Initiator(noodleFactory))),
Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder orSubqueryNot(String field, SubqueryBuilder.Initiator.Runner value){
return orSubqueryNot(field, "=", value);
}
public NoodleSpecificationBuilder orSubqueryNot(String field, String operator, SubqueryBuilder.Initiator.Runner value){
return update(new FieldSubquerySpecification<>(field, operator, value.apply(new SubqueryBuilder.Initiator(noodleFactory)), true),
Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder andSubquery(SubqueryBuilder.Initiator.Runner value, Object o){
return andSubquery(value, "=", o);
}
public NoodleSpecificationBuilder andSubquery( SubqueryBuilder.Initiator.Runner value,String operator,Object o){
return update(new LiteralSubquerySpecification<>(o, operator, value.apply(new SubqueryBuilder.Initiator(noodleFactory))),
Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder andSubqueryNot(SubqueryBuilder.Initiator.Runner value, Object o){
return andSubqueryNot(value, "=", o);
}
public NoodleSpecificationBuilder andSubqueryNot(SubqueryBuilder.Initiator.Runner value, String operator, Object o){
return update(new LiteralSubquerySpecification<>(o, operator, value.apply(new SubqueryBuilder.Initiator(noodleFactory)), true),
Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder orSubquery(SubqueryBuilder.Initiator.Runner value,Object o){
return orSubquery(value, "=", o);
}
public NoodleSpecificationBuilder orSubquery(SubqueryBuilder.Initiator.Runner value, String operator, Object o){
return update(new LiteralSubquerySpecification<>(o, operator, value.apply(new SubqueryBuilder.Initiator(noodleFactory))),
Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder orSubqueryNot( SubqueryBuilder.Initiator.Runner value,Object o){
return orSubqueryNot(value, "=", o);
}
public NoodleSpecificationBuilder orSubqueryNot(SubqueryBuilder.Initiator.Runner value, String operator,Object o){
return update(new LiteralSubquerySpecification<>(o, operator, value.apply(new SubqueryBuilder.Initiator(noodleFactory)), true),
Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder andExists(SubqueryBuilder.Initiator.Runner value){
return update(new ExistSpecification(value.apply(new SubqueryBuilder.Initiator(noodleFactory)), false),
Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder andNotExists(SubqueryBuilder.Initiator.Runner value){
return update(new ExistSpecification(value.apply(new SubqueryBuilder.Initiator(noodleFactory)), true),
Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder orExists(SubqueryBuilder.Initiator.Runner value){
return update(new ExistSpecification(value.apply(new SubqueryBuilder.Initiator(noodleFactory)), false),
Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder orNotExists(SubqueryBuilder.Initiator.Runner value){
return update(new ExistSpecification(value.apply(new SubqueryBuilder.Initiator(noodleFactory)), true),
Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder andSame(Object value){
return andSame(value,null);
}
public NoodleSpecificationBuilder andSame(Object value, String prefix){
return update(new SameSpecification(new Builder(noodleFactory, false),value,prefix),Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder andNotSame(Object value){
return andNotSame(value,null);
}
public NoodleSpecificationBuilder andNotSame(Object value, String prefix){
return update(new SameSpecification(new Builder(noodleFactory, true),value,prefix),Predicate.BooleanOperator.AND);
}
public NoodleSpecificationBuilder orSame(Object value){
return orSame(value,null);
}
public NoodleSpecificationBuilder orSame(Object value, String prefix){
return update(new SameSpecification(new Builder(noodleFactory, false),value,prefix),Predicate.BooleanOperator.OR);
}
public NoodleSpecificationBuilder orNotSame(Object value){
return orNotSame(value,null);
}
public NoodleSpecificationBuilder orNotSame(Object value, String prefix){
return update(new SameSpecification(new Builder(noodleFactory, true),value,prefix),Predicate.BooleanOperator.OR);
}
public static class Builder implements NoodlePredicate.Builder {
private final NoodleFactory noodleFactory;
private final Boolean isNot;
public Builder(NoodleFactory noodleFactory){
this(noodleFactory, false);
}
public Builder(NoodleFactory noodleFactory, Boolean isNot){
this.noodleFactory = noodleFactory;
this.isNot = isNot;
}
@Override
public NoodleSpecificationBuilder where(String field, String operator, Object value){
return new NoodleSpecificationBuilder(noodleFactory,
NoodleSpecificationBuilder.toPredicate(noodleFactory, field, operator, value, false),
isNot);
}
@Override
public NoodleSpecificationBuilder whereNot(String field, String operator, Object value){
return new NoodleSpecificationBuilder(noodleFactory,
NoodleSpecificationBuilder.toPredicate(noodleFactory, field, operator, value, true),
isNot);
}
@Override
public NoodleSpecificationBuilder whereSubquery(String field, String operator, SubqueryBuilder.Initiator.Runner value){
return new NoodleSpecificationBuilder(noodleFactory,
new FieldSubquerySpecification<>(field,
operator,
value.apply(new SubqueryBuilder.Initiator(noodleFactory))),
isNot);
}
@Override
public NoodleSpecificationBuilder whereSubqueryNot(String field, String operator, SubqueryBuilder.Initiator.Runner value){
return new NoodleSpecificationBuilder(noodleFactory,
new FieldSubquerySpecification<>(field,
operator,
value.apply(new SubqueryBuilder.Initiator(noodleFactory)),
true),
isNot);
}
@Override
public NoodleSpecificationBuilder whereSubquery(SubqueryBuilder.Initiator.Runner value,String operator,Object o){
return new NoodleSpecificationBuilder(noodleFactory,
new LiteralSubquerySpecification<>(o,
operator,
value.apply(new SubqueryBuilder.Initiator(noodleFactory))),
isNot);
}
@Override
public NoodleSpecificationBuilder whereSubqueryNot(SubqueryBuilder.Initiator.Runner value,String operator,Object o){
return new NoodleSpecificationBuilder(noodleFactory,
new LiteralSubquerySpecification<>(o,
operator,
value.apply(new SubqueryBuilder.Initiator(noodleFactory)),
true),
isNot);
}
@Override
public NoodleSpecificationBuilder where(Function fPred){
return new NoodleSpecificationBuilder(noodleFactory, fPred.apply(new Builder(noodleFactory)), isNot);
}
@Override
public NoodleSpecificationBuilder whereNot(Function fPred){
return new NoodleSpecificationBuilder(noodleFactory, fPred.apply(new Builder(noodleFactory, true)), isNot);
}
@Override
public NoodleSpecificationBuilder where(Consumer consumer, String operator, Object value){
return new NoodleSpecificationBuilder(noodleFactory,
NoodleSpecificationBuilder.toPredicate(noodleFactory, consumer, operator, value, false),
isNot);
}
@Override
public NoodleSpecificationBuilder whereNot(Consumer consumer, String operator, Object value){
return new NoodleSpecificationBuilder(noodleFactory,
NoodleSpecificationBuilder.toPredicate(noodleFactory, consumer, operator, value, true),
isNot);
}
@Override
public NoodleSpecificationBuilder same(Object value, String prefix){
return new NoodleSpecificationBuilder(noodleFactory,
new SameSpecification(new Builder(noodleFactory, false),value,prefix),
isNot);
}
@Override
public NoodleSpecificationBuilder notSame(Object value, String prefix){
return new NoodleSpecificationBuilder(noodleFactory,
new SameSpecification(new Builder(noodleFactory, true),value,prefix),
isNot);
}
@Override
public NoodleSpecificationBuilder empty(){
return new NoodleSpecificationBuilder(noodleFactory, isNot);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy