/************************************************************************* * Copyright 2009-2015 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. ************************************************************************/ package com.eucalyptus.entities; import java.util.Collection; import java.util.Date; import javax.annotation.Nonnull; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.Expression; import javax.persistence.criteria.Path; import javax.persistence.metamodel.PluralAttribute; import javax.persistence.metamodel.SingularAttribute; /** * Type-safe immutable entity restriction specification. */ public abstract class EntityRestriction<E> { /** * Get the entity class. * * @return The entity class being restricted. */ @Nonnull public abstract Class<E> getEntityClass( ); abstract Expression<Boolean> build( CriteriaBuilder builder, Path<E> path ); static final class ConjunctionEntityRestriction<E> extends EntityRestriction<E> { private final Class<E> entityClass; private final Iterable<EntityRestriction<E>> restrictions; ConjunctionEntityRestriction( final Class<E> entityClass, final Iterable<EntityRestriction<E>> restrictions ) { this.entityClass = entityClass; this.restrictions = restrictions; } @Nonnull @Override public Class<E> getEntityClass( ) { return entityClass; } @Override public Expression<Boolean> build( final CriteriaBuilder builder, final Path<E> root ) { final javax.persistence.criteria.Predicate conjunction = builder.conjunction( ); for ( final EntityRestriction<E> restriction : restrictions ) { conjunction.getExpressions( ).add( restriction.build( builder, root ) ); } return conjunction; } } static final class DisjunctionEntityRestriction<E> extends EntityRestriction<E> { private final Class<E> entityClass; private final Iterable<EntityRestriction<E>> restrictions; DisjunctionEntityRestriction( final Class<E> entityClass, final Iterable<EntityRestriction<E>> restrictions ) { this.entityClass = entityClass; this.restrictions = restrictions; } @Nonnull @Override public Class<E> getEntityClass( ) { return entityClass; } @Override public Expression<Boolean> build( final CriteriaBuilder builder, final Path<E> root ) { final javax.persistence.criteria.Predicate disjunction = builder.disjunction( ); for ( final EntityRestriction<E> restriction : restrictions ) { disjunction.getExpressions( ).add( restriction.build( builder, root ) ); } return disjunction; } } static abstract class PropertyEntityRestrictionSupport<E,V> extends EntityRestriction<E> { private final Class<E> entityClass; private final SingularAttribute<? super E,V> attribute; PropertyEntityRestrictionSupport( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute ) { this.entityClass = entityClass; this.attribute = attribute; } @Nonnull @Override public Class<E> getEntityClass( ) { return entityClass; } public SingularAttribute<? super E, V> getAttribute( ) { return attribute; } } static abstract class PropertyEntityValueRestrictionSupport<E,V> extends PropertyEntityRestrictionSupport<E,V> { private final V value; PropertyEntityValueRestrictionSupport( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute, final V value ) { super( entityClass, attribute ); this.value = value; } public V getValue( ) { return value; } } static final class EqualPropertyEntityValueRestriction<E,V> extends PropertyEntityValueRestrictionSupport<E,V> { EqualPropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute, final V value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.equal( root.get( getAttribute( ) ), getValue( ) ); } } static final class EqualIgnoreCasePropertyEntityValueRestriction<E> extends PropertyEntityValueRestrictionSupport<E,String> { EqualIgnoreCasePropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, String> attribute, final String value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.equal( builder.lower( root.get( getAttribute( ) ) ), getValue( ).toLowerCase( ) ); } } static final class NotEqualPropertyEntityValueRestriction<E,V> extends PropertyEntityValueRestrictionSupport<E,V> { NotEqualPropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute, final V value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.notEqual( root.get( getAttribute( ) ), getValue( ) ); } } static final class LikePropertyEntityValueRestriction<E> extends PropertyEntityValueRestrictionSupport<E,String> { LikePropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, String> attribute, final String value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.like( root.get( getAttribute( ) ), getValue( ) ); } } static final class NotLikePropertyEntityValueRestriction<E> extends PropertyEntityValueRestrictionSupport<E,String> { NotLikePropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, String> attribute, final String value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.notLike( root.get( getAttribute( ) ), getValue( ) ); } } static final class GreaterThanPropertyEntityValueRestriction<E,V extends Number> extends PropertyEntityValueRestrictionSupport<E,V> { GreaterThanPropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute, final V value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.gt( root.get( getAttribute( ) ), getValue( ) ); } } static final class GreaterThanOrEqualToPropertyEntityValueRestriction<E,V extends Number> extends PropertyEntityValueRestrictionSupport<E,V> { GreaterThanOrEqualToPropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute, final V value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.ge( root.get( getAttribute( ) ), getValue( ) ); } } static final class LessThanPropertyEntityValueRestriction<E,V extends Number> extends PropertyEntityValueRestrictionSupport<E,V> { LessThanPropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute, final V value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.lt( root.get( getAttribute( ) ), getValue( ) ); } } static final class LessThanOrEqualToPropertyEntityValueRestriction<E,V extends Number> extends PropertyEntityValueRestrictionSupport<E,V> { LessThanOrEqualToPropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute, final V value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.le( root.get( getAttribute( ) ), getValue( ) ); } } static final class DateBeforePropertyEntityValueRestriction<E> extends PropertyEntityValueRestrictionSupport<E,Date> { DateBeforePropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, Date> attribute, final Date value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.lessThan( root.get( getAttribute( ) ), getValue( ) ); } } static final class DateAfterPropertyEntityValueRestriction<E> extends PropertyEntityValueRestrictionSupport<E,Date> { DateAfterPropertyEntityValueRestriction( final Class<E> entityClass, final SingularAttribute<? super E, Date> attribute, final Date value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.greaterThan( root.get( getAttribute( ) ), getValue( ) ); } } static final class NullPropertyEntityRestriction<E,V> extends PropertyEntityRestrictionSupport<E,V> { NullPropertyEntityRestriction( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute ) { super( entityClass, attribute ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.isNull( root.get( getAttribute( ) ) ); } } static final class NotNullPropertyEntityRestriction<E,V> extends PropertyEntityRestrictionSupport<E,V> { NotNullPropertyEntityRestriction( final Class<E> entityClass, final SingularAttribute<? super E, V> attribute ) { super( entityClass, attribute ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.isNotNull( root.get( getAttribute( ) ) ); } } static final class TruePropertyEntityRestriction<E> extends PropertyEntityRestrictionSupport<E,Boolean> { TruePropertyEntityRestriction( final Class<E> entityClass, final SingularAttribute<? super E, Boolean> attribute ) { super( entityClass, attribute ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.isTrue( root.get( getAttribute( ) ) ); } } static final class FalsePropertyEntityRestriction<E> extends PropertyEntityRestrictionSupport<E,Boolean> { FalsePropertyEntityRestriction( final Class<E> entityClass, final SingularAttribute<? super E, Boolean> attribute ) { super( entityClass, attribute ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.isFalse( root.get( getAttribute( ) ) ); } } static abstract class CollectionPropertyEntityRestrictionSupport<E,C extends Collection<V>,V> extends EntityRestriction<E> { private final Class<E> entityClass; private final PluralAttribute<E, C, V> attribute; CollectionPropertyEntityRestrictionSupport( final Class<E> entityClass, final PluralAttribute<E, C, V> attribute ) { this.entityClass = entityClass; this.attribute = attribute; } @Nonnull @Override public Class<E> getEntityClass( ) { return entityClass; } public PluralAttribute<E, C, V> getAttribute( ) { return attribute; } } static abstract class CollectionPropertyEntityValueRestrictionSupport<E,C extends Collection<V>,V> extends CollectionPropertyEntityRestrictionSupport<E,C,V> { private final V value; CollectionPropertyEntityValueRestrictionSupport( final Class<E> entityClass, final PluralAttribute<E, C, V> attribute, final V value ) { super( entityClass, attribute ); this.value = value; } public V getValue( ) { return value; } } static final class EmptyPropertyEntityRestriction<E,C extends Collection<V>,V> extends CollectionPropertyEntityRestrictionSupport<E,C,V> { EmptyPropertyEntityRestriction( final Class<E> entityClass, final PluralAttribute<E, C, V> attribute ) { super( entityClass, attribute ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.isEmpty( root.get( getAttribute( ) ) ); } } static final class NotEmptyPropertyEntityRestriction<E,C extends Collection<V>,V> extends CollectionPropertyEntityRestrictionSupport<E,C,V> { NotEmptyPropertyEntityRestriction( final Class<E> entityClass, final PluralAttribute<E, C, V> attribute ) { super( entityClass, attribute ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.isNotEmpty( root.get( getAttribute( ) ) ); } } static final class MemberPropertyEntityValueRestriction<E,C extends Collection<V>,V> extends CollectionPropertyEntityValueRestrictionSupport<E,C,V> { MemberPropertyEntityValueRestriction( final Class<E> entityClass, final PluralAttribute<E, C, V> attribute, final V value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.isMember( getValue( ), root.get( getAttribute( ) ) ); } } static final class NotMemberPropertyEntityValueRestriction<E,C extends Collection<V>,V> extends CollectionPropertyEntityValueRestrictionSupport<E,C,V> { NotMemberPropertyEntityValueRestriction( final Class<E> entityClass, final PluralAttribute<E, C, V> attribute, final V value ) { super( entityClass, attribute, value ); } public Expression<Boolean> build( CriteriaBuilder builder, Path<E> root ) { return builder.isNotMember( getValue( ), root.get( getAttribute( ) ) ); } } }