/* * * Copyright c 2005-2009. * * Licensed under GNU LESSER General Public License, Version 3. * http://www.gnu.org/licenses * */ /******************************************************************************** * @author chaostone * * MODIFICATION DESCRIPTION * * Name Date Description * ============ ============ ============ * chaostone 2006-10-11 Created * ********************************************************************************/ package org.beanfuse.query; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.StringUtils; import org.beanfuse.model.Component; import org.beanfuse.model.Entity; import org.beanfuse.model.predicates.ValidEntityKeyPredicate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 条件提取辅助类 * * @author chaostone * */ public final class ConditionUtils { private static final Logger logger = LoggerFactory.getLogger(ConditionUtils.class); private ConditionUtils() { super(); } public static String toQueryString(final List conditions) { if (null == conditions || conditions.isEmpty()) { return ""; } final StringBuilder buf = new StringBuilder(""); for (final Iterator iter = conditions.iterator(); iter.hasNext();) { final Condition conditioin = (Condition) iter.next(); buf.append('(').append(conditioin.getContent()).append(')'); if (iter.hasNext()) { buf.append(" and "); } } return buf.toString(); } /** * 提取对象中的条件<br> * 提取的属性仅限"平面"属性(允许包括component)<br> * 过滤掉属性:null,或者空Collection * * @param alias * @param entity * @param mode * @return */ public static List extractConditions(String alias, final Entity entity) { if (null == entity) { return Collections.EMPTY_LIST; } final List conditions = new ArrayList(); StringBuilder aliasBuilder = new StringBuilder(alias == null ? "" : alias); if (aliasBuilder.length() > 0 && !alias.endsWith(".")) { aliasBuilder.append("."); } String attr = ""; try { final Map beanMap = PropertyUtils.describe(entity); for (final Iterator iter = beanMap.keySet().iterator(); iter.hasNext();) { attr = (String) iter.next(); // 条件描述的应该是属性 if (!PropertyUtils.isWriteable(entity, attr)) { continue; } final Object value = PropertyUtils.getProperty(entity, attr); if (null == value) { continue; } if (!(value instanceof Collection)) { addAttrCondition(conditions, alias + attr, value); } } } catch (Exception e) { logger.debug("error occur in extractConditions for bean {} with attr named {}", entity, attr); } return conditions; } /** * 获得条件的绑定参数映射 * * @param query * @param conditions */ public static Map getParamMap(final List conditions) { final Map params = new HashMap(); for (final Iterator iter = conditions.iterator(); iter.hasNext();) { final Condition condition = (Condition) iter.next(); params.putAll(getParamMap(condition)); } return params; } /** * 获得条件的绑定参数映射 * * @param query * @param conditions */ public static Map getParamMap(final Condition condition) { final Map params = new HashMap(); if (!StringUtils.contains(condition.getContent(), "?")) { final List paramNames = condition.getNamedParams(); if (paramNames.size() > condition.getValues().size()) { throw new RuntimeException("condition params not setted [" + condition.getContent() + "] with value:" + condition.getValues()); } for (int i = 0; i < paramNames.size(); i++) { params.put((String) paramNames.get(i), condition.getValues().get(i)); } } return params; } /** * 为extractConditions使用的私有方法<br> * * @param conditions * @param name * @param value * @param mode */ private static void addAttrCondition(final List conditions, final String name, Object value) { if (value instanceof String) { if (StringUtils.isBlank((String) value)) { return; } StringBuilder content = new StringBuilder(name); content.append(" like :").append(name.replace('.', '_')); conditions.add(new Condition(content.toString(), "%" + value + "%")); } else if (value instanceof Component) { conditions.addAll(extractComponent(name, (Component) value)); return; } else if (value instanceof Entity) { try { final String key = ((Entity) value).key(); Object property = PropertyUtils.getProperty(value, key); if (ValidEntityKeyPredicate.getInstance().evaluate(property)) { StringBuilder content = new StringBuilder(name); content.append('.').append(key).append(" = :").append(name.replace('.', '_')) .append('_').append(key); conditions.add(new Condition(content.toString(), property)); } } catch (Exception e) { logger.warn("getProperty " + value + "error", e); } } else { conditions.add(new Condition(name + " = :" + name.replace('.', '_'), value)); } } private static List extractComponent(final String prefix, final Component component) { if (null == component) { return Collections.EMPTY_LIST; } final List conditions = new ArrayList(); String attr = ""; try { final Map beanMap = PropertyUtils.describe(component); for (final Iterator iter = beanMap.keySet().iterator(); iter.hasNext();) { attr = (String) iter.next(); if ("class".equals(attr)) { continue; } if (!PropertyUtils.isWriteable(component, attr)) { continue; } final Object value = PropertyUtils.getProperty(component, attr); if (value == null) { continue; } else if (value instanceof Collection) { if (((Collection) value).isEmpty()) { continue; } } else { addAttrCondition(conditions, prefix + "." + attr, value); } } } catch (Exception e) { logger.warn("error occur in extractComponent of component:" + component + "with attr named :" + attr); } return conditions; } }