py.una.pol.karaku.dao.where.NumberLike.java Source code

Java tutorial

Introduction

Here is the source code for py.una.pol.karaku.dao.where.NumberLike.java

Source

/*-
 * Copyright (c)
 *
 *       2012-2014, Facultad Politcnica, Universidad Nacional de Asuncin.
 *       2012-2014, Facultad de Ciencias Mdicas, Universidad Nacional de Asuncin.
 *       2012-2013, Centro Nacional de Computacin, Universidad Nacional de Asuncin.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */
package py.una.pol.karaku.dao.where;

import javax.annotation.Nonnull;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.TypedValue;

/**
 * Clase que representa una condicin de Where para hacer bsqueda en similitud
 * entre numeros, por ejemplo, si buscamos <code>787</code> entre los numeros,
 * convertir a cadena la columna y har un like convencional.
 * 
 * <p>
 * <h3>Ejemplos de uso:</h3>
 * 
 * <pre>
 * new NumberLike("codigoIso", "12", {@link MatchMode#CONTAIN})
 * </pre>
 * 
 * Generar la siguiente clusula:
 * 
 * <pre>
 * ::codigoIso ilike %12%
 * </pre>
 * 
 * Notese que para postgresql, si agregamos <code>::</code> antes de una
 * columna, la convertir automticamente a String.
 * </p>
 * 
 * TODO ver para agregar comparacin con decimales.
 * 
 * @author Arturo Volpe
 * @version 1.0
 * @since 1.0 08/02/2013
 * 
 */
public class NumberLike implements Criterion, Clause {

    @Nonnull
    private String propiedad;
    @Nonnull
    private final String valor;
    @Nonnull
    private final MatchMode matchMode;

    /**
     * Define la propiedad por la cual se buscara, la propiedad, es el path a un
     * atributo de una entidad.
     * 
     * @param propiedad
     */
    public void setPropiedad(@Nonnull String propiedad) {

        this.propiedad = propiedad;
    }

    /**
     * Retorna una cadena que representa el atributo por el cual se buscar
     * 
     * @return path al atributo
     */
    @Nonnull
    public String getPropiedad() {

        return propiedad;
    }

    /**
     * Define una nueva clusula del tipo like entre nmeros, la clusula se
     * lee: <i>todos los los registros que en <b>propiedad</b> contengan al
     * nmero <b>valor</b>, se dice que la propiedad <code>x</code> contiene al
     * numero <code>y</code>, s el <b>valor</b> es una subcadena* de la
     * propiedad</b> convertida a cadena</i>
     * <p>
     * 
     * <p>
     * *: esto depende del {@link MatchMode}
     * </p>
     * 
     * @param propiedad
     *            atributo a ser buscado
     * @param valor
     *            numero con el cual se comparar
     * @param matchMode
     *            por el cual se buscar la subcadena
     */
    public NumberLike(@Nonnull String propiedad, @Nonnull String valor, @Nonnull MatchMode matchMode) {

        super();
        this.matchMode = matchMode;
        this.propiedad = propiedad;
        this.valor = valor;
    }

    /**
     * Define una nueva clusula del tipo like entre nmeros, la clusula se
     * lee: <i>todos los los registros que en <b>propiedad</b> contengan al
     * nmero <b>valor</b>, se dice que la propiedad <code>x</code> contiene al
     * numero <code>y</code>, s el <b>valor</b> es una subcadena de la
     * propiedad</b> convertida a cadena</i>
     * <p>
     * 
     * 
     * @param propiedad
     *            atributo a ser buscado
     * @param valor
     *            numero con el cual se comparar
     */
    public NumberLike(@Nonnull String propiedad, @Nonnull String valor) {

        this(propiedad, valor, MatchMode.CONTAIN);
    }

    private static final long serialVersionUID = 46392094642533751L;

    @Override
    public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {

        String[] columns = criteriaQuery.findColumns(getPropiedad(), criteria);
        if (columns.length != 1) {
            throw new HibernateException("NumberLike may only be used with single-column properties");
        }
        SessionFactoryImplementor factory = criteriaQuery.getFactory();

        if (factory.getDialect() instanceof H2Dialect) {
            return "cast(cast(" + columns[0] + " as int) as VARCHAR) " + "like ?";
        } else {
            // XXX ver consistencia entre bases de datos
            return columns[0] + "::text like ?";
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) {

        TypedValue tv = new TypedValue(new org.hibernate.type.StringType(), matchMode.toString(valor),
                EntityMode.POJO);
        return new TypedValue[] { tv };
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Criterion getCriterion() {

        return this;
    }

    public String getValor() {

        return valor;
    }

    public MatchMode getMatchMode() {

        return matchMode;
    }

}