org.beangle.model.persist.hibernate.CriterionUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.beangle.model.persist.hibernate.CriterionUtils.java

Source

/* Copyright c 2005-2012.
 * Licensed under GNU  LESSER General Public License, Version 3.
 * http://www.gnu.org/licenses
 */
package org.beangle.model.persist.hibernate;

import java.sql.Date;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.beangle.commons.collection.CollectUtils;
import org.beangle.model.Component;
import org.beangle.model.Entity;
import org.beangle.model.persist.hibernate.support.NotEmptyPropertySelector;
import org.beangle.model.predicates.ValidEntityKeyPredicate;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ? ????. Example???""0???
 * ????. Component?Example?????.
 * 
 * @deprecated
 * @author chaostone 2005-10-28
 */
@SuppressWarnings("unchecked")
public final class CriterionUtils {

    private CriterionUtils() {
    }

    private static final Logger logger = LoggerFactory.getLogger(CriterionUtils.class);

    public static void addCriterionsFor(Criteria criteria, List<? extends Criterion> criterions) {
        for (Iterator<? extends Criterion> iter = criterions.iterator(); iter.hasNext();) {
            criteria.add(iter.next());
        }
    }

    public static List<Criterion> getEntityCriterions(Object entity) {
        return getEntityCriterions("", entity, null, MatchMode.ANYWHERE, true);
    }

    public static List<Criterion> getEntityCriterions(Object entity, boolean ignoreZero) {
        return getEntityCriterions("", entity, null, MatchMode.ANYWHERE, ignoreZero);
    }

    public static List<Criterion> getEntityCriterions(Object entity, String[] excludePropertes) {
        return getEntityCriterions("", entity, excludePropertes, MatchMode.ANYWHERE, true);
    }

    public static List<Criterion> getEntityCriterions(String nestedName, Object entity) {
        return getEntityCriterions(nestedName, entity, null, MatchMode.ANYWHERE, true);
    }

    public static List<Criterion> getEntityCriterions(String nestedName, Object entity, String[] excludePropertes) {
        return getEntityCriterions(nestedName, entity, excludePropertes, MatchMode.ANYWHERE, true);
    }

    public static Example getExampleCriterion(Object entity) {
        return getExampleCriterion(entity, null, MatchMode.ANYWHERE);
    }

    public static Example getExampleCriterion(Object entity, String[] excludePropertes, MatchMode mode) {
        Example example = Example.create(entity).setPropertySelector(new NotEmptyPropertySelector());
        if (null != mode) {
            example.enableLike(mode);
        }
        if (null != excludePropertes) {
            for (int i = 0; i < excludePropertes.length; i++) {
                example.excludeProperty(excludePropertes[i]);
            }
        }
        return example;
    }

    /**
     * ?. ??.
     * 
     * @param entity
     * @param excludePropertes
     * @param mode
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static List<Criterion> getEntityCriterions(String nestedName, Object entity, String[] excludePropertes,
            MatchMode mode, boolean ignoreZero) {
        if (null == entity) {
            return Collections.emptyList();
        }
        List<Criterion> criterions = CollectUtils.newArrayList();
        BeanMap map = new BeanMap(entity);
        Set keySet = map.keySet();
        Collection properties = null;
        if (null == excludePropertes) {
            List proList = CollectUtils.newArrayList();
            proList.addAll(keySet);
            properties = proList;
        } else {
            properties = CollectionUtils.subtract(keySet, Arrays.asList(excludePropertes));
        }
        properties.remove("class");

        for (Iterator iter = properties.iterator(); iter.hasNext();) {
            String propertyName = (String) iter.next();
            if (!PropertyUtils.isWriteable(entity, propertyName)) {
                continue;
            }
            Object value = map.get(propertyName);
            addCriterion(nestedName, entity, excludePropertes, propertyName, value, criterions, mode, ignoreZero);
        }
        return criterions;
    }

    public static List<Criterion> getEqCriterions(Object entity, String[] properties) {
        List<Criterion> criterions = CollectUtils.newArrayList();
        BeanMap map = new BeanMap(entity);
        for (int i = 0; i < properties.length; i++) {
            criterions.add(Restrictions.eq(properties[i], map.get(properties[i])));
        }
        return criterions;
    }

    public static List<Criterion> getForeignerCriterions(Object entity) {
        BeanMap map = new BeanMap(entity);
        return getForeignerCriterions(entity, map.keySet());
    }

    public static List<Criterion> getForeignerCriterions(Object entity, Collection<String> properties) {
        List<Criterion> criterions = CollectUtils.newArrayList();
        BeanMap map = new BeanMap(entity);
        for (Iterator<String> iter = properties.iterator(); iter.hasNext();) {
            String propertyName = iter.next();
            Object foreigner = map.get(propertyName);
            if (foreigner instanceof Entity) {
                BeanMap foreignerMap = new BeanMap(foreigner);
                Object foreignKey = foreignerMap.get("id");
                // ???String??String??.
                if (ValidEntityKeyPredicate.getInstance().evaluate(foreignKey)) {
                    // .
                    criterions.add(Restrictions.eq(propertyName + ".id", foreignKey));
                }
            }
        }
        return criterions;
    }

    public static List<Criterion> getForeignerCriterions(Object entity, String[] properties) {
        return getForeignerCriterions(entity, Arrays.asList(properties));
    }

    public static List<Criterion> getLikeCriterions(Object entity, String[] Properties) {
        return getLikeCriterions(entity, Properties, MatchMode.ANYWHERE);
    }

    /**
     * ?like?
     * 
     * @param entity
     * @param properties
     * @param mode
     * @return
     */
    public static List<Criterion> getLikeCriterions(Object entity, String[] properties, MatchMode mode) {
        List<Criterion> criterions = CollectUtils.newArrayList();
        BeanMap map = new BeanMap(entity);
        for (int i = 0; i < properties.length; i++) {
            Object value = map.get(properties[i]);
            if ((value instanceof String) && (StringUtils.isNotEmpty((String) value))) {
                criterions.add(Restrictions.like(properties[i], (String) value, mode));
            }
        }
        return criterions;
    }

    /**
     * ?MatchMode.ANYWHERE?map
     * 
     * @param entity
     * @return
     */
    public static Map<String, Object> getParamsMap(Entity<?> entity) {
        if (null == entity) {
            return Collections.EMPTY_MAP;
        }
        return getParamsMap(entity, MatchMode.ANYWHERE);
    }

    /**
     * ??.<br>
     * component???<br>
     * componentmap??component.attr?.
     * 
     * @param entity
     *            ,null,map.
     * @param mode
     *            ??like
     * @return
     */
    public static Map<String, Object> getParamsMap(Entity<?> entity, MatchMode mode) {
        if (null == entity) {
            return Collections.EMPTY_MAP;
        }
        Map<String, Object> datas = CollectUtils.newHashMap();
        String attr = "";
        try {
            Map<String, Object> beanMap = PropertyUtils.describe(entity);
            for (Iterator<String> iter = beanMap.keySet().iterator(); iter.hasNext();) {
                attr = iter.next();
                Object value = PropertyUtils.getProperty(entity, attr);
                if (value == null) {
                    continue;
                } else {
                    addTrivialAttr(datas, attr, value, mode);
                    if (value instanceof Entity) {
                        String key = "id";
                        value = PropertyUtils.getProperty(entity, attr + "." + key);
                        if (ValidEntityKeyPredicate.getInstance().evaluate(value)) {
                            datas.put(attr + "." + key, value);
                        }
                    }
                }
            }
            return datas;
        } catch (Exception e) {
            logger.error("[converToMap]:error occur in converToMap of bean" + entity + "with attr named " + attr,
                    e);
        }
        return Collections.emptyMap();
    }

    static Criterion eqCriterion(String name, Object value) {
        logger.debug("[CriterionUtils]:name {} value {}", name, value);
        return Restrictions.eq(name, value);
    }

    static Criterion likeCriterion(String name, String value, MatchMode mode) {
        logger.debug("[CriterionUtils]:name {} value {}", name, value);
        return Restrictions.like(name, value, mode);
    }

    /**
     * ?
     * 
     * @param entity
     * @param excludePropertes
     * @param path
     * @param value
     * @param criterions
     * @param mode
     */
    private static void addCriterion(String nestedName, Object entity, String[] excludePropertes, String path,
            Object value, List<Criterion> criterions, MatchMode mode, boolean ignoreZero) {
        if (null == value) {
            return;
        }
        addPrimativeCriterion(nestedName + path, value, criterions, ignoreZero);

        if (value instanceof String) {
            if (StringUtils.isNotEmpty((String) value)) {
                criterions.add(likeCriterion(nestedName + path, (String) value, mode));
            }
        } else if (value instanceof Entity) {
            BeanMap foreignerMap = new BeanMap(value);
            Object foreignKey = foreignerMap.get("id");
            // ???String??String??.
            if (ValidEntityKeyPredicate.getInstance().evaluate(foreignKey)) {
                // .
                criterions.add(eqCriterion(nestedName + path + ".id", foreignKey));
            }
        } else if (value instanceof Component) {
            criterions.addAll(getComponentCriterions(nestedName, entity, path, excludePropertes, mode, ignoreZero));
        }
    }

    /**
     * ?? ?""?0,0
     * 
     * @param name
     * @param value
     * @param criterions
     */
    private static void addPrimativeCriterion(String name, Object value, List<Criterion> criterions,
            boolean ignoreZero) {
        Criterion criterion = null;
        if (value instanceof Number) {
            if (ignoreZero) {
                if (0 != ((Number) value).intValue()) {
                    criterion = eqCriterion(name, value);
                }
            } else {
                criterion = eqCriterion(name, value);
            }
        }
        if ((value instanceof Character) || (value instanceof Boolean)) {
            criterion = eqCriterion(name, value);
        }
        if ((value instanceof Date)) {
            criterion = eqCriterion(name, value);
        }
        if (null != criterion) {
            criterions.add(criterion);
        }
    }

    /**
     * converToMap?
     * 
     * @param datas
     * @param name
     * @param value
     * @param mode
     */
    private static void addTrivialAttr(Map<String, Object> datas, String name, Object value, MatchMode mode) {
        if (value instanceof Number && ((Number) value).intValue() != 0) {
            datas.put(name, value);
        }
        if (value instanceof String && StringUtils.isNotBlank((String) value)) {
            StringBuilder strBuilder = new StringBuilder((String) value);
            if (mode.equals(MatchMode.ANYWHERE)) {
                strBuilder.insert(0, '%').append('%');
            } else if (mode.equals(MatchMode.START)) {
                strBuilder.append('%');
            } else if (mode.equals(MatchMode.END)) {
                strBuilder.insert(0, '%');
            }
            datas.put(name, strBuilder.toString());
        }
        if (value instanceof Component) {
            datas.putAll(converToMap(name, (Component) value, mode));
        }
        if (value instanceof Entity) {
            try {
                String key = "id";
                Object propertyValue = PropertyUtils.getProperty(value, key);
                if (ValidEntityKeyPredicate.getInstance().evaluate(propertyValue)) {
                    datas.put(name + "." + key, propertyValue);
                }
            } catch (Exception e) {
                logger.error("getProperty error", e);
            }
        }
    }

    private static Map<String, Object> converToMap(String prefix, Component component, MatchMode mode) {
        if (null == component) {
            return Collections.EMPTY_MAP;
        }
        Map<String, Object> datas = CollectUtils.newHashMap();
        String attr = "";
        try {
            Map<String, Object> beanMap = PropertyUtils.describe(component);
            for (Iterator<String> iter = beanMap.keySet().iterator(); iter.hasNext();) {
                attr = iter.next();
                Object value = PropertyUtils.getProperty(component, attr);
                if (value == null) {
                    continue;
                } else {
                    addTrivialAttr(datas, prefix + "." + attr, value, mode);
                }
            }
            return datas;

        } catch (Exception e) {
            logger.error(
                    "[converToMap]:error occur in converToMap of component" + component + "with attr named " + attr,
                    e);

        }
        return Collections.EMPTY_MAP;
    }

    /**
     * ?
     * 
     * @param entity
     * @param property
     *            ????outcomponent.innercomponent
     * @param excludePropertes
     *            ??entityProperty.componentProperty
     * @param enableLike
     * @return
     */
    private static List<Criterion> getComponentCriterions(String nestedName, Object entity, String property,
            String[] excludePropertes, MatchMode mode, boolean ignoreZero) {
        List<Criterion> criterions = CollectUtils.newArrayList();
        Component component = null;
        try {
            component = (Component) PropertyUtils.getProperty(entity, property);
        } catch (Exception e) {
            return Collections.emptyList();
        }
        if (null == component) {
            return Collections.emptyList();
        }
        BeanMap map = new BeanMap(component);
        Set<String> properties = map.keySet();
        Set<String> excludeSet = null;
        if (null == excludePropertes) {
            excludeSet = Collections.emptySet();
        } else {
            excludeSet = CollectUtils.newHashSet();
            excludeSet.addAll(Arrays.asList(excludePropertes));
        }
        for (Iterator<String> iter = properties.iterator(); iter.hasNext();) {
            String propertyName = iter.next();
            String cascadeName = property + "." + propertyName;
            if (excludeSet.contains(cascadeName) || "class".equals(propertyName)) {
                continue;
            }
            if (!PropertyUtils.isWriteable(component, propertyName)) {
                continue;
            }
            Object value = map.get(propertyName);

            addCriterion(nestedName, entity, excludePropertes, cascadeName, value, criterions, mode, ignoreZero);
        }
        return criterions;
    }

    public static void addSortListFor(Criteria criteria, List<org.beangle.commons.collection.Order> sortList) {
        if (null == sortList) {
            return;
        }
        for (final org.beangle.commons.collection.Order order : sortList) {
            if (order.isAscending()) {
                criteria.addOrder(Order.asc(order.getProperty()));
            } else {
                criteria.addOrder(Order.desc(order.getProperty()));
            }
        }
    }
}