All Downloads are FREE. Search and download functionalities are using the official Maven repository.

paa.coder.noodleCriteriaBuilder.queryBuilder.expressions.ArithmeticExpression Maven / Gradle / Ivy

package paa.coder.noodleCriteriaBuilder.queryBuilder.expressions;

import paa.coder.noodleCriteriaBuilder.exceptions.NoodleException;
import paa.coder.noodleCriteriaBuilder.interfaces.*;

import javax.persistence.criteria.CommonAbstractCriteria;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Path;
import java.util.Optional;
import java.util.function.Function;

public class ArithmeticExpression implements NoodleExpression {

    private final ThreeFunction> expresion;

    public ThreeFunction> getExpresion(){
        return expresion;
    }

    private ArithmeticExpression(ThreeFunction> expresion){
        this.expresion = expresion;
    }

    @Override
    public Optional> apply(PathFinder pathFinder, CommonAbstractCriteria query, CriteriaBuilder criteriaBuilder){
        return Optional.ofNullable(expresion).map(i -> i.apply(pathFinder,query, criteriaBuilder));
    }

    private ArithmeticExpression action(ThreeFunction,Expression,CriteriaBuilder,Expression> updater,
                                        Number... numbers){
        if(numbers.length == 0){
            return this;
        }
        return new ArithmeticExpression((root,query, criteriaBuilder) -> {
            Expression expression = expresion.apply(root,query, criteriaBuilder);
            for(Number number : numbers){
                expression = updater.apply(expression, criteriaBuilder.literal(number), criteriaBuilder);
            }
            return expression;
        });
    }

    private ArithmeticExpression action(ThreeFunction,Path,CriteriaBuilder,Expression> updater, String... fields){
        if(fields.length == 0){
            return this;
        }
        return new ArithmeticExpression((root,query, criteriaBuilder) -> {
            Expression expression = expresion.apply(root,query, criteriaBuilder);
            for(String name : fields){
                expression = updater.apply(expression, path(root, name), criteriaBuilder);
            }
            return expression;
        });
    }

    private static Path path(PathFinder pathFinder, String fieldName){
        Path path = pathFinder
                .apply(SampleColumn.build(fieldName).getName())
                .orElseThrow(() -> new NoodleException(String.format("Field %s not found", fieldName)));
        if(Number.class.isAssignableFrom(path.getJavaType())){
            return (Path) path;
        }
        throw new NoodleException(String.format("Field %s must instance from %s", fieldName, Number.class.getName()));
    }

    private ArithmeticExpression action(ThreeFunction,Expression,CriteriaBuilder,Expression> updater,
                                        Function builderFunction){
        return new ArithmeticExpression((root,query, criteriaBuilder) -> {
            Expression expression = expresion.apply(root,query, criteriaBuilder);
            return Optional
                    .ofNullable(builderFunction.apply(new Builder()))
                    .flatMap(i -> Optional.ofNullable(i.getExpresion()))
                    .flatMap(i -> Optional.ofNullable(i.apply(root,query, criteriaBuilder)))
                    .map(i -> updater.apply(expression, i, criteriaBuilder))
                    .orElse(expression);
        });
    }

    public ArithmeticExpression plus(String... fields){
        return action((e, p, c) -> c.sum(e, p), fields);
    }

    public ArithmeticExpression plus(Number... fields){
        return action((e, p, c) -> c.sum(e, p), fields);
    }

    public ArithmeticExpression plus(Function builderFunction){
        return action((l, r, c) -> c.sum(l, r), builderFunction);
    }

    public ArithmeticExpression minus(String... fields){
        return action((e, p, c) -> c.diff(e, p), fields);
    }

    public ArithmeticExpression minus(Function builderFunction){
        return action((l, r, c) -> c.diff(l, r), builderFunction);
    }

    public ArithmeticExpression minus(Number... fields){
        return action((e, p, c) -> c.diff(e, p), fields);
    }

    public ArithmeticExpression multiply(String... fields){
        return action((e, p, c) -> c.prod(e, p), fields);
    }

    public ArithmeticExpression multiply(Function builderFunction){
        return action((l, r, c) -> c.prod(l, r), builderFunction);
    }

    public ArithmeticExpression multiply(Number... fields){
        return action((e, p, c) -> c.prod(e, p), fields);
    }

    public ArithmeticExpression divide(String... fields){
        return action((e, p, c) -> c.quot(e, p), fields);
    }

    public ArithmeticExpression divide(Function builderFunction){
        return action((l, r, c) -> c.quot(l, r), builderFunction);
    }

    public ArithmeticExpression divide(Number... fields){
        return action((e, p, c) -> c.quot(e, p), fields);
    }


    public static class Builder implements ArithmeticBuilder {

        @Override
        public ArithmeticExpression from(String field){
            return new ArithmeticExpression((root,query, criteriaBuilder) -> path(root, field));
        }

        @Override
        public ArithmeticExpression from(Number field){
            return new ArithmeticExpression((root,query, criteriaBuilder) -> criteriaBuilder.literal(field));
        }

        @Override
        public ArithmeticExpression coalesce(Function uFunc){
            return new ArithmeticExpression((root,query, criteriaBuilder) -> (Expression) uFunc
                    .apply(new CoalesceExpression.Builder())
                    .getExpresion()
                    .apply(s -> Optional.of(path(root, s)),query, criteriaBuilder));
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy