Package com.dottydingo.hyperion.service.query

Source Code of com.dottydingo.hyperion.service.query.RsqlPredicateBuilder$InternalExpressionBuilder

package com.dottydingo.hyperion.service.query;

import com.dottydingo.hyperion.exception.BadRequestException;
import com.dottydingo.hyperion.exception.InternalException;
import cz.jirutka.rsql.parser.ParseException;
import cz.jirutka.rsql.parser.RSQLParser;
import cz.jirutka.rsql.parser.TokenMgrError;
import cz.jirutka.rsql.parser.model.Comparison;
import cz.jirutka.rsql.parser.model.ComparisonExpression;
import cz.jirutka.rsql.parser.model.Expression;
import cz.jirutka.rsql.parser.model.LogicalExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.EntityManagerFactory;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.From;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.EntityType;
import java.util.List;

/**
* User: mark
* Date: 9/16/12
* Time: 11:24 AM
*/
public class RsqlPredicateBuilder implements PredicateBuilder
{
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private List<AbstractPredicateBuilder> builders;
    private ArgumentParser argumentParser;
    private EntityManagerFactory entityManagerFactory;
    private Mapper mapper;

    public void setBuilders(List<AbstractPredicateBuilder> builders)
    {
        this.builders = builders;
    }

    public void setArgumentParser(ArgumentParser argumentParser)
    {
        this.argumentParser = argumentParser;
    }

    public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory)
    {
        this.entityManagerFactory = entityManagerFactory;
    }

    public void setMapper(Mapper mapper)
    {
        this.mapper = mapper;
    }

    @Override
    public Predicate buildPredicate(String query, Class entityClass, Root root, CriteriaBuilder cb)
    {
        Expression queryTree;
        try
        {
            logger.info("Parsing query: {}", query);
            queryTree = RSQLParser.parse(query);

        }
        catch (ParseException ex)
        {
            throw new BadRequestException("Error parsing query.", ex);
        }
        catch (TokenMgrError er)
        {
            throw new BadRequestException("Invalid query", er);
        }
        return new InternalExpressionBuilder(cb).buildPredicate(queryTree,root);
    }

    private class InternalExpressionBuilder implements ExpressionPredicateBuilder
    {

        private CriteriaBuilder cb;


        private InternalExpressionBuilder(CriteriaBuilder cb)
        {
            this.cb = cb;
        }

        private Predicate buildPredicate(Expression expression,  Root entityRoot)
        {
            logger.trace("Creating criterion for: {}", expression);

            if (expression.isLogical())
            {
                return buildPredicate((LogicalExpression) expression,entityRoot);
            }
            if (expression.isComparison())
            {
                return buildPredicate((ComparisonExpression) expression,entityRoot);
            }

            throw new BadRequestException("Invalid expression.");
        }

        private Predicate buildPredicate(LogicalExpression logical,  Root entityRoot)
        {
            switch (logical.getOperator())
            {
                case AND:
                    return cb.and(
                            buildPredicate(logical.getLeft(),entityRoot),
                            buildPredicate(logical.getRight(),entityRoot));

                case OR:
                    return cb.or(
                            buildPredicate(logical.getLeft(),entityRoot),
                            buildPredicate(logical.getRight(),entityRoot));
            }
            throw new BadRequestException("Invalid expression.");
        }

        private Predicate buildPredicate(ComparisonExpression comparison,  Root entityRoot)
        {
            String property = mapper.translate(comparison.getSelector(), entityRoot.getModel().getJavaType());

            try
            {
                return buildPredicate(entityRoot, property, comparison.getOperator(), comparison.getArgument());

            }
            catch (ArgumentFormatException ex)
            {
                throw new BadRequestException(null,
                        new ArgumentFormatException(comparison.getSelector(), ex.getArgument(), ex.getPropertyType()));
            }
            catch (UnknownSelectorException ex)
            {
                throw new BadRequestException(null,ex);
            }
        }

        @Override
        public Predicate buildPredicate(From entityRoot, String property, Comparison operator, String argument)
                throws ArgumentFormatException, UnknownSelectorException, IllegalArgumentException
        {
            Class<?> entityClass = entityRoot.getJavaType();
            for (AbstractPredicateBuilder builder : builders) {
                if (builder.accept(property, entityClass, this)) {
                    logger.debug("Delegating comparison [{} {} {}] on entity {} to builder: {}",
                            new Object[]{property, operator, argument, entityClass.getSimpleName(), builder.getClass().getSimpleName()});

                    return builder.createPredicate(property, operator, argument, entityRoot, this);
                }
            }

            throw new InternalException("No Criterion Builder found for property " + property + " of " + entityClass);
        }

        @Override
        public ArgumentParser getArgumentParser() {
            return argumentParser;
        }

        @Override
        public EntityType getEntityType(Class<?> entityClass) {
            return entityManagerFactory.getMetamodel().entity(entityClass);
        }

        @Override
        public CriteriaBuilder getCriteriaBuilder()
        {
            return cb;
        }

        @Override
        public Mapper getMapper() {
            return mapper;
        }

    }


}
TOP

Related Classes of com.dottydingo.hyperion.service.query.RsqlPredicateBuilder$InternalExpressionBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.