com.qcadoo.model.api.search.SearchRestrictions.java Source code

Java tutorial

Introduction

Here is the source code for com.qcadoo.model.api.search.SearchRestrictions.java

Source

/**
 * ***************************************************************************
 * Copyright (c) 2010 Qcadoo Limited
 * Project: Qcadoo Framework
 * Version: 1.3
 *
 * This file is part of Qcadoo.
 *
 * Qcadoo is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation; either version 3 of the License,
 * or (at your option) any later version.
 *
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ***************************************************************************
 */
package com.qcadoo.model.api.search;

import java.util.Collection;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.qcadoo.model.api.DataDefinition;
import com.qcadoo.model.api.Entity;
import com.qcadoo.model.internal.api.DataAccessService;
import com.qcadoo.model.internal.api.InternalDataDefinition;
import com.qcadoo.model.internal.search.SearchConjunctionImpl;
import com.qcadoo.model.internal.search.SearchCriterionImpl;
import com.qcadoo.model.internal.search.SearchDisjunctionImpl;

/**
 * Utility with factory methods for {@link SearchCriterion}.
 * 
 * @since 0.4.1
 */
@Component
public final class SearchRestrictions {

    private static DataAccessService dataAccessService;

    private static final String[] QCADOO_WILDCARDS = new String[] { "*", "?" };

    private static final String[] HIBERNATE_WILDCARDS = new String[] { "%", "_" };

    private static void setStaticDataAccessService(final DataAccessService dataAccessService) {
        SearchRestrictions.dataAccessService = dataAccessService;
    }

    @Autowired
    protected void setDataAccessService(final DataAccessService dataAccessService) {
        SearchRestrictions.setStaticDataAccessService(dataAccessService);
    }

    /**
     * Match mode for "like" criterion.
     */
    public static enum SearchMatchMode {

        /**
         * Match anywhere.
         */
        ANYWHERE(MatchMode.ANYWHERE),

        /**
         * Match at the end.
         */
        END(MatchMode.END),

        /**
         * Match exact value.
         */
        EXACT(MatchMode.EXACT),

        /**
         * Match at the beginning.
         */
        START(MatchMode.START);

        private final MatchMode matchMode;

        private SearchMatchMode(final MatchMode matchMode) {
            this.matchMode = matchMode;
        }

        public MatchMode getHibernateMatchMode() {
            return matchMode;
        }

    }

    /**
     * Creates restriction which join given restrictions with "OR" operator.
     * 
     * @param firstCriterion
     *            first criterion
     * @param secondCriterion
     *            second criterion
     * @param otherCriteria
     *            other criteria
     * @return criterion
     */
    public static SearchCriterion or(final SearchCriterion firstCriterion, final SearchCriterion secondCriterion,
            final SearchCriterion... otherCriteria) {
        Disjunction disjunction = Restrictions.disjunction();
        disjunction.add(firstCriterion.getHibernateCriterion());
        disjunction.add(secondCriterion.getHibernateCriterion());

        for (SearchCriterion criterion : otherCriteria) {
            disjunction.add(criterion.getHibernateCriterion());
        }

        return new SearchCriterionImpl(disjunction);
    }

    /**
     * Creates restriction which join given restrictions with "AND" operator.
     * 
     * @param firstCriterion
     *            first criterion
     * @param secondCriterion
     *            second criterion
     * @param otherCriteria
     *            other criteria
     * @return criterion
     */
    public static SearchCriterion and(final SearchCriterion firstCriterion, final SearchCriterion secondCriterion,
            final SearchCriterion... otherCriteria) {
        Conjunction conjunction = Restrictions.conjunction();
        conjunction.add(firstCriterion.getHibernateCriterion());
        conjunction.add(secondCriterion.getHibernateCriterion());

        for (SearchCriterion criterion : otherCriteria) {
            conjunction.add(criterion.getHibernateCriterion());
        }

        return new SearchCriterionImpl(conjunction);
    }

    /**
     * Wraps given criterion with "not" criterion.
     * 
     * @param criterion
     *            criterion
     * @return negated criterion
     */
    public static SearchCriterion not(final SearchCriterion criterion) {
        return new SearchCriterionImpl(Restrictions.not(criterion.getHibernateCriterion()));
    }

    /**
     * Creates criterion which checks if id is equal to given value.
     * 
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion idEq(final long value) {
        return new SearchCriterionImpl(Restrictions.idEq(value));
    }

    /**
     * Creates criterion which checks if id isn't equal to given value.
     * 
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion idNe(final long value) {
        return new SearchCriterionImpl(Restrictions.not(Restrictions.idEq(value)));
    }

    /**
     * Creates criterion which checks if all given fields match given values.
     * 
     * @param values
     *            map where key is a field's name and value is the expected value
     * @return criterion
     */
    public static SearchCriterion allEq(final Map<String, Object> values) {
        return new SearchCriterionImpl(Restrictions.allEq(values));
    }

    /**
     * Creates criterion which checks if field is equal (using "like" operator) to given value.
     * 
     * @param field
     *            field
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion like(final String field, final String value) {
        if (value == null) {
            return isNull(field);
        }
        return new SearchCriterionImpl(Restrictions.like(field, convertWildcards(value)));
    }

    /**
     * Creates criterion which checks if field is equal (using "like" operator) to given value.
     * 
     * @param field
     *            field
     * @param mode
     *            match mode
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion like(final String field, final String value, final SearchMatchMode mode) {
        if (value == null) {
            return isNull(field);
        }
        return new SearchCriterionImpl(
                Restrictions.like(field, convertWildcards(value), mode.getHibernateMatchMode()));
    }

    /**
     * Creates criterion which checks if field is equal (using case-insensitive "like" operator) to given value.
     * 
     * @param field
     *            field
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion ilike(final String field, final String value) {
        if (value == null) {
            return isNull(field);
        }
        return new SearchCriterionImpl(Restrictions.ilike(field, convertWildcards(value)));
    }

    /**
     * Creates criterion which checks if field is equal (using case-insensitive "like" operator) to given value.
     * 
     * @param field
     *            field
     * @param mode
     *            match mode
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion ilike(final String field, final String value, final SearchMatchMode mode) {
        if (value == null) {
            return isNull(field);
        }
        return new SearchCriterionImpl(
                Restrictions.ilike(field, convertWildcards(value), mode.getHibernateMatchMode()));
    }

    private static String convertWildcards(final String value) {
        return StringUtils.replaceEach(value, QCADOO_WILDCARDS, HIBERNATE_WILDCARDS);
    }

    /**
     * Creates criterion which checks if field is less than or equal to given value.
     * 
     * @param field
     *            field
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion le(final String field, final Object value) {
        return new SearchCriterionImpl(Restrictions.le(field, value));
    }

    /**
     * Creates criterion which checks if field is less than given value.
     * 
     * @param field
     *            field
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion lt(final String field, final Object value) {
        return new SearchCriterionImpl(Restrictions.lt(field, value));
    }

    /**
     * Creates criterion which checks if field is greater than or equal to given value.
     * 
     * @param field
     *            field
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion ge(final String field, final Object value) {
        return new SearchCriterionImpl(Restrictions.ge(field, value));
    }

    /**
     * Creates criterion which checks if field is greater than given value.
     * 
     * @param field
     *            field
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion gt(final String field, final Object value) {
        return new SearchCriterionImpl(Restrictions.gt(field, value));
    }

    /**
     * Creates criterion which checks if field isn't equal to given value.
     * 
     * @param field
     *            field
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion ne(final String field, final Object value) {
        return new SearchCriterionImpl(Restrictions.ne(field, value));
    }

    /**
     * Creates criterion which checks if field is equal to given value.
     * 
     * @param field
     *            field
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion eq(final String field, final Object value) {
        return new SearchCriterionImpl(Restrictions.eq(field, value));
    }

    /**
     * Creates criterion which checks if field is equal (using case-insensitive "eq" operator) to given value.
     * 
     * @param field
     *            field
     * @param value
     *            value
     * @return criterion
     */
    public static SearchCriterion iEq(final String field, final Object value) {
        return new SearchCriterionImpl(Restrictions.eq(field, value).ignoreCase());
    }

    /**
     * Creates criterion which checks if field is less than or equal to other field.
     * 
     * @param field
     *            field
     * @param otherField
     *            other field
     * @return criterion
     */
    public static SearchCriterion leField(final String field, final String otherField) {
        return new SearchCriterionImpl(Restrictions.leProperty(field, otherField));
    }

    /**
     * Creates criterion which checks if field is less than other field.
     * 
     * @param field
     *            field
     * @param otherField
     *            other field
     * @return criterion
     */
    public static SearchCriterion ltField(final String field, final String otherField) {
        return new SearchCriterionImpl(Restrictions.ltProperty(field, otherField));
    }

    /**
     * Creates criterion which checks if field is greater than or equal to other field.
     * 
     * @param field
     *            field
     * @param otherField
     *            other field
     * @return criterion
     */
    public static SearchCriterion geField(final String field, final String otherField) {
        return new SearchCriterionImpl(Restrictions.geProperty(field, otherField));
    }

    /**
     * Creates criterion which checks if field is greater than other field.
     * 
     * @param field
     *            field
     * @param otherField
     *            other field
     * @return criterion
     */
    public static SearchCriterion gtField(final String field, final String otherField) {
        return new SearchCriterionImpl(Restrictions.gtProperty(field, otherField));
    }

    /**
     * Creates criterion which checks if field isn't equal to other field.
     * 
     * @param field
     *            field
     * @param otherField
     *            other field
     * @return criterion
     */
    public static SearchCriterion neField(final String field, final String otherField) {
        return new SearchCriterionImpl(Restrictions.neProperty(field, otherField));
    }

    /**
     * Creates criterion which checks if field is equal to other field.
     * 
     * @param field
     *            field
     * @param otherField
     *            other field
     * @return criterion
     */
    public static SearchCriterion eqField(final String field, final String otherField) {
        return new SearchCriterionImpl(Restrictions.eqProperty(field, otherField));
    }

    /**
     * Creates criterion which checks if field is not null.
     * 
     * @param field
     *            field
     * @return criterion
     */
    public static SearchCriterion isNotNull(final String field) {
        return new SearchCriterionImpl(Restrictions.isNotNull(field));
    }

    /**
     * Creates criterion which checks if field is null.
     * 
     * @param field
     *            field
     * @return criterion
     */
    public static SearchCriterion isNull(final String field) {
        return new SearchCriterionImpl(Restrictions.isNull(field));
    }

    /**
     * Creates criterion which checks if "collection" field's size is equal to given size.
     * 
     * @param field
     *            field
     * @param size
     *            size
     * @return criterion
     */
    public static SearchCriterion sizeEq(final String field, final int size) {
        return new SearchCriterionImpl(Restrictions.sizeEq(field, size));
    }

    /**
     * Creates criterion which checks if "collection" field's size is less than or equal to given size.
     * 
     * @param field
     *            field
     * @param size
     *            size
     * @return criterion
     */
    public static SearchCriterion sizeLe(final String field, final int size) {
        return new SearchCriterionImpl(Restrictions.sizeLe(field, size));
    }

    /**
     * Creates criterion which checks if "collection" field's size is less than given size.
     * 
     * @param field
     *            field
     * @param size
     *            size
     * @return criterion
     */
    public static SearchCriterion sizeLt(final String field, final int size) {
        return new SearchCriterionImpl(Restrictions.sizeLt(field, size));
    }

    /**
     * Creates criterion which checks if "collection" field's size is greater than or equal to given size.
     * 
     * @param field
     *            field
     * @param size
     *            size
     * @return criterion
     */
    public static SearchCriterion sizeGe(final String field, final int size) {
        return new SearchCriterionImpl(Restrictions.sizeGe(field, size));
    }

    /**
     * Creates criterion which checks if "collection" field's size is greater than given size.
     * 
     * @param field
     *            field
     * @param size
     *            size
     * @return criterion
     */
    public static SearchCriterion sizeGt(final String field, final int size) {
        return new SearchCriterionImpl(Restrictions.sizeGt(field, size));
    }

    /**
     * Creates criterion which checks if "collection" field's size isn't equal to given size.
     * 
     * @param field
     *            field
     * @param size
     *            size
     * @return criterion
     */
    public static SearchCriterion sizeNe(final String field, final int size) {
        return new SearchCriterionImpl(Restrictions.sizeNe(field, size));
    }

    /**
     * Creates criterion which checks if "collection" field's size is empty.
     * 
     * @param field
     *            field
     * @return criterion
     */
    public static SearchCriterion isEmpty(final String field) {
        return new SearchCriterionImpl(Restrictions.isEmpty(field));
    }

    /**
     * Creates criterion which checks if "collection" field's size isn't empty.
     * 
     * @param field
     *            field
     * @return criterion
     */
    public static SearchCriterion isNotEmpty(final String field) {
        return new SearchCriterionImpl(Restrictions.isNotEmpty(field));
    }

    /**
     * Creates criterion which checks if field is between given values.
     * 
     * @param field
     *            field
     * @param lo
     *            low value
     * @param hi
     *            high value
     * @return criterion
     */
    public static SearchCriterion between(final String field, final Object lo, final Object hi) {
        return new SearchCriterionImpl(Restrictions.between(field, lo, hi));
    }

    /**
     * Creates criterion which checks if field is in given values.
     * 
     * @param field
     *            field
     * @param values
     *            values
     * @return criterion
     */
    public static SearchCriterion in(final String field, final Collection<?> values) {
        return new SearchCriterionImpl(Restrictions.in(field, values));
    }

    /**
     * Creates criterion which checks if field is in given values.
     * 
     * @param field
     *            field
     * @param values
     *            values
     * @return criterion
     */
    public static SearchCriterion in(final String field, final Object... values) {
        return new SearchCriterionImpl(Restrictions.in(field, values));
    }

    /**
     * Creates criterion which checks if "belongsTo" field is equal to given entity.
     * 
     * Current implementation of this method performs Entity loading and may cause StackOverflowError when used (for example)
     * within onView hook.
     * 
     * Therefore prefer belongsTo(String, Entity) and use this method only in case when you can't obtain reference to a whole
     * Entity.
     * 
     * @param field
     *            field
     * @param pluginIdentifier
     *            plugin's identifier
     * @param modelName
     *            model's name
     * @param id
     *            id
     * @return criterion
     */
    public static SearchCriterion belongsTo(final String field, final String pluginIdentifier,
            final String modelName, final long id) {
        return belongsTo(field, dataAccessService.getDataDefinition(pluginIdentifier, modelName), id);
    }

    /**
     * Creates criterion which checks if "belongsTo" field is equal to given entity.
     * 
     * Current implementation of this method performs Entity loading and may cause StackOverflowError when used (for example)
     * within onView hook.
     * 
     * Therefore prefer belongsTo(String, Entity) and use this method only in case when you can't obtain reference to a whole
     * Entity.
     * 
     * @param field
     *            field
     * @param dataDefinition
     *            data's definition
     * @param id
     *            id
     * @return criterion
     */
    public static SearchCriterion belongsTo(final String field, final DataDefinition dataDefinition,
            final long id) {
        return belongsTo(field, dataAccessService.get((InternalDataDefinition) dataDefinition, id));
    }

    /**
     * Creates criterion which checks if "belongsTo" field is equal to given entity.
     * 
     * @param field
     *            field
     * @param entity
     *            entity
     * @return criterion
     */
    public static SearchCriterion belongsTo(final String field, final Entity entity) {
        Object databaseEntity = null;

        if (entity != null) {
            databaseEntity = dataAccessService.convertToDatabaseEntity(entity);
        }

        if (databaseEntity == null) {
            return isNull(field);
        } else {
            return eq(field, databaseEntity);
        }
    }

    /**
     * Creates disjunction - (... OR ... OR ...).
     * 
     * @return disjunction
     */
    public static SearchDisjunction disjunction() {
        return new SearchDisjunctionImpl();
    }

    /**
     * Creates conjunction - (... AND ... AND ...).
     * 
     * @return conjunction
     */
    public static SearchConjunction conjunction() {
        return new SearchConjunctionImpl();
    }

}