de.cosmocode.hibernate.CustomRestrictions.java Source code

Java tutorial

Introduction

Here is the source code for de.cosmocode.hibernate.CustomRestrictions.java

Source

/**
 * Copyright 2010 CosmoCode GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.cosmocode.hibernate;

import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

/**
 * A custom version of {@link Restrictions}.
 * 
 * @author Willi Schoenborn
 */
public final class CustomRestrictions {

    /**
     * Prevent instantiation.
     */
    private CustomRestrictions() {

    }

    /**
     * Group expressions together in a single disjunction (A or B or C...).
     * 
     * @param first the first {@link Criterion}
     * @param second the second {@link Criterion}
     * @param rest the rest
     * @return a {@link Criterion} containing all parameters combined in disjunct style
     */
    public static Criterion disjunction(Criterion first, Criterion second, Criterion... rest) {
        final Disjunction disjunction = Restrictions.disjunction();
        disjunction.add(first).add(second);
        for (Criterion criterion : rest) {
            disjunction.add(criterion);
        }
        return disjunction;
    }

    /**
     * Group expressions together in a single conjunction (A and B and C...).
     * 
     * @param first the first {@link Criterion}
     * @param second the second {@link Criterion}
     * @param rest the rest
     * @return a {@link Criterion} containing all parameters combined in conjuct style
     */
    public static Criterion conjunction(Criterion first, Criterion second, Criterion... rest) {
        final Conjunction conjunction = Restrictions.conjunction();
        conjunction.add(first).add(second);
        for (Criterion criterion : rest) {
            conjunction.add(criterion);
        }
        return conjunction;
    }

    /**
     * Apply an "equal" constraint to the named property.
     * 
     * <p>
     *   Note: This implementation differs from {@link Restrictions#eq(String, Object)}
     *   because it checks for empty strings and applies {@link CustomRestrictions#isEmpty(String)}
     *   instead.
     * </p>
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value the property should be equals to
     * @return a new {@link Criterion}
     */
    public static Criterion eq(String propertyName, String value) {
        return StringUtils.isEmpty(value) ? CustomRestrictions.isEmpty(propertyName)
                : Restrictions.eq(propertyName, value);
    }

    /**
     * Apply a "not equal" constraint to the named property.
     * 
     * <p>
     *   Note: This implementation differs from {@link Restrictions#ne(String, Object)}
     *   because it returns {@link CustomRestrictions#isNotEmpty(String)}
     *   in case value is an empty string and returns an logical or expression
     *   of {@link Restrictions#ne(String, Object)} and {@link Restrictions#isNull(String)}.
     * </p>
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value the property should be not equals to
     * @return a new {@link Criterion}
     */
    public static Criterion ne(String propertyName, String value) {
        if (StringUtils.isEmpty(value)) {
            return CustomRestrictions.isNotEmpty(propertyName);
        } else {
            return Restrictions.or(Restrictions.ne(propertyName, value), Restrictions.isNull(propertyName));
        }
    }

    /**
     * Apply an "empty" constraint on the named property.
     * 
     * <p>
     *   See also {@link StringUtils#isEmpty(String)}
     * </p>
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @return a new {@link Criterion}
     */
    public static Criterion isEmpty(String propertyName) {
        return Restrictions.or(Restrictions.eq(propertyName, ""), Restrictions.isNull(propertyName));
    }

    /**
     * Apply a "not empty" constraint to the named property.
     * 
     * <p>
     *   See also {@link StringUtils#isNotEmpty(String)}
     * </p>
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @return a new {@link Criterion}
     */
    public static Criterion isNotEmpty(String propertyName) {
        return Restrictions.not(CustomRestrictions.isEmpty(propertyName));
    }

    /**
     * Apply an "ilike" constraint on the named property.
     * 
     * <p>
     *   Note: This implementation differs from {@link Restrictions#ilike(String, String, MatchMode)}
     *   because it checks for empty strings and applies {@link CustomRestrictions#isEmpty(String)}
     *   instead.
     * </p>
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value the property should be similiar to
     * @param matchMode the {@link MatchMode} being used
     * @return a new {@link Criterion}
     */
    public static Criterion ilike(String propertyName, String value, MatchMode matchMode) {
        return StringUtils.isEmpty(value) ? CustomRestrictions.isEmpty(propertyName)
                : Restrictions.ilike(propertyName, value, matchMode);
    }

    /**
     * Apply an "ilike" constraint on the named property.
     * 
     * <p>
     *   Note: This implementation differs from {@link Restrictions#ilike(String, Object)}
     *   because it checks for empty strings and applies {@link CustomRestrictions#isEmpty(String)}
     *   instead.
     * </p>
     * 
     * <p>
     *   Its equivalent to calling {@link CustomRestrictions#ilike(String, String, MatchMode)}
     *   using {@link MatchMode#ANYWHERE}.
     * </p>
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value the property should be similiar to
     * @return a new {@link Criterion}
     */
    public static Criterion ilike(String propertyName, String value) {
        return ilike(propertyName, value, MatchMode.ANYWHERE);
    }

    /**
     * Apply a "not ilike" constraint on the named property.
     * 
     * <p>
     *   This implementation handles empty values correctly.
     * </p>
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value the property should be similiar to
     * @param matchMode the {@link MatchMode} being used
     * @return a new {@link Criterion}
     */
    public static Criterion notIlike(String propertyName, String value, MatchMode matchMode) {
        if (StringUtils.isEmpty(value)) {
            return CustomRestrictions.isNotEmpty(propertyName);
        } else {
            return Restrictions.or(Restrictions.not(Restrictions.ilike(propertyName, value, matchMode)),
                    CustomRestrictions.isEmpty(propertyName));
        }
    }

    /**
     * Apply a "not ilike" constraint on the named property.
     * 
     * <p>
     *   This implementation handles empty values correctly.
     * </p>
     * 
     * <p>
     *   Its equivalent to calling {@link CustomRestrictions#notIlike(String, String, MatchMode)}
     *   using {@link MatchMode#ANYWHERE}.
     * </p>
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value the property should be similiar to
     * @return a new {@link Criterion}
     */
    public static Criterion notIlike(String propertyName, String value) {
        return notIlike(propertyName, value, MatchMode.ANYWHERE);
    }

    /**
     * Apply a "reverse ilike" expression on the named property.
     * 
     * @see ReverseIlikeExpression
     * @see PropertyMatchMode
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value which should be similiar to the named property
     * @param matchMode the {@link PropertyMatchMode} being used
     * @return a new {@link Criterion}
     */
    public static Criterion reverseIlike(String propertyName, String value, PropertyMatchMode matchMode) {
        return new ReverseIlikeExpression(propertyName, value, matchMode);
    }

    /**
     * Apply a "reverse ilike" expression on the named property.
     * 
     * <p>
     *   Its equivalent to calling {@link CustomRestrictions#reverseIlike(String, String, PropertyMatchMode)}
     *   using {@link PropertyMatchMode#ANYWHERE}
     * </p>
     * 
     * @see ReverseIlikeExpression
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value which should be similiar to the named property
     * @return a new {@link Criterion}
     */
    public static Criterion reverseIlike(String propertyName, String value) {
        return CustomRestrictions.reverseIlike(propertyName, value, PropertyMatchMode.ANYWHERE);
    }

    /**
     * Apply a "not reverse ilike" expression on the named property.
     * 
     * @see ReverseIlikeExpression
     * @see PropertyMatchMode
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value which should not be similiar to the named property
     * @param matchMode the {@link PropertyMatchMode} being used
     * @return a new {@link Criterion}
     */
    public static Criterion notReverseIlike(String propertyName, String value, PropertyMatchMode matchMode) {
        return Restrictions.not(CustomRestrictions.reverseIlike(propertyName, value, matchMode));
    }

    /**
     * Apply a "not reverse ilike" expression on the named property.
     * 
     * <p>
     *   Its equivalent to calling {@link CustomRestrictions#notReverseIlike(String, String, PropertyMatchMode)}
     *   using {@link PropertyMatchMode#ANYWHERE}
     * </p>
     * 
     * @see ReverseIlikeExpression
     * 
     * @param propertyName the name of the property the constraint should be applied to
     * @param value the actual value which should not be similiar to the named property
     * @return a new {@link Criterion}
     */
    public static Criterion notReverseIlike(String propertyName, String value) {
        return CustomRestrictions.notReverseIlike(propertyName, value, PropertyMatchMode.ANYWHERE);
    }

    /**
     * Apply a "has" constraint to the named enumset property.
     * 
     * @param <E> the generic enum type
     * @param propertyName the name of the property the constraint should be applied to
     * @param e the enum value the named property should contain
     * @return a new {@link Criterion}
     */
    public static <E extends Enum<E>> Criterion has(String propertyName, E e) {
        return new EnumSetRestriction<E>(propertyName, "&", e, ">", 0);
    }

    /**
     * Apply a "all" constraint to the named enumset property.
     * 
     * @param <E> the generic enum type
     * @param propertyName the name of the property the constraint should be applied to
     * @param enums the set of enums the named property should contain
     * @return a new {@link Criterion}
     */
    public static <E extends Enum<E>> Criterion all(String propertyName, Set<E> enums) {
        return new EnumSetRestriction<E>(propertyName, "&", enums, ">", 0);
    }

    /**
     * Apply a "not has" constraint to the named enumset property.
     * 
     * @param <E> the generic enum type
     * @param propertyName the name of the property the constraint should be applied to
     * @param e the enum value the named property should not contain
     * @return a new {@link Criterion}
     */
    public static <E extends Enum<E>> Criterion notHas(String propertyName, E e) {
        return new EnumSetRestriction<E>(propertyName, "&", e, "=", 0);
    }

    /**
     * Apply a "none" constraint to the named enumset property.
     * 
     * @param <E> the generic enum type
     * @param propertyName the name of the property the constraint should be applied to
     * @param enums the set of enums the named property should not contain
     * @return a new {@link Criterion}
     */
    public static <E extends Enum<E>> Criterion none(String propertyName, Set<E> enums) {
        return new EnumSetRestriction<E>(propertyName, "&", enums, "=", 0);
    }

}