/* * Hibernate, Relational Persistence for Idiomatic Java * * License: Apache License, Version 2.0 * See the LICENSE file in the root directory or visit http://www.apache.org/licenses/LICENSE-2.0 */ package org.hibernate.test.sqm.parser.criteria.tree.predicate; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import javax.persistence.criteria.Expression; import javax.persistence.criteria.Predicate; import org.hibernate.query.sqm.ParsingException; import org.hibernate.query.sqm.produce.spi.criteria.CriteriaVisitor; import org.hibernate.query.sqm.produce.spi.criteria.JpaPredicate; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.predicate.SqmPredicate; import org.hibernate.test.sqm.parser.criteria.tree.CriteriaBuilderImpl; import org.hibernate.test.sqm.parser.criteria.tree.expression.AbstractJpaExpressionImpl; /** * @author Steve Ebersole */ public class NegatedPredicateWrapper extends AbstractJpaExpressionImpl<Boolean> implements JpaPredicate, Serializable { private final JpaPredicate predicate; private final BooleanOperator negatedOperator; private final List<JpaPredicate> negatedPredicates; @SuppressWarnings("unchecked") public NegatedPredicateWrapper(JpaPredicate predicate) { super( (CriteriaBuilderImpl) predicate.criteriaBuilder(), null, Boolean.class ); this.predicate = predicate; this.negatedOperator = predicate.getOperator() == BooleanOperator.AND ? CompoundPredicate.reverseOperator( predicate.getOperator() ) : predicate.getOperator(); this.negatedPredicates = negateCompoundExpressions( predicate.getExpressions(), (CriteriaBuilderImpl) predicate.criteriaBuilder() ); } private static List<JpaPredicate> negateCompoundExpressions( List<Expression<Boolean>> expressions, CriteriaBuilderImpl criteriaBuilder) { if ( expressions == null || expressions.isEmpty() ) { return Collections.emptyList(); } final List<JpaPredicate> negatedExpressions = new ArrayList<>(); for ( Expression<Boolean> expression : expressions ) { if ( Predicate.class.isInstance( expression ) ) { negatedExpressions.add( ( (JpaPredicate) expression ).not() ); } else { negatedExpressions.add( criteriaBuilder.not( expression ) ); } } return negatedExpressions; } @Override public BooleanOperator getOperator() { return negatedOperator; } @Override public boolean isNegated() { return !predicate.isNegated(); } @Override public List<Expression<Boolean>> getExpressions() { return negatedPredicates.stream().collect( Collectors.toList() ); } @Override public JpaPredicate not() { return new NegatedPredicateWrapper( this ); } @Override public SqmPredicate visitPredicate(CriteriaVisitor visitor) { return visitor.visitNegatedPredicate( this ); } @Override public SqmExpression visitExpression(CriteriaVisitor visitor) { throw new ParsingException( "Unexpected call to visitExpression on JpaPredicate" ); } }