//$Id: EntityUtils.java,v 1.1 2007-2-9 下午11:52:56 chaostone Exp $ /* * 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 2007-2-9 Created * ********************************************************************************/ package org.beanfuse.model; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.commons.beanutils.BeanMap; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.StringUtils; import org.beanfuse.model.predicates.EmptyKeyPredicate; import org.beanfuse.model.predicates.ValidEntityKeyPredicate; import org.beanfuse.model.predicates.ValidEntityPredicate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 实体类辅助工具箱 * * @author chaostone 2005-10-31 */ public final class EntityUtils { protected static final Logger logger = LoggerFactory .getLogger(EntityUtils.class); private EntityUtils() { } /** * <pre> * merge函数主要用来将页面回传对象(orig)的参数合并到数据库已经存在的对象中.(浅拷贝) * 合并的依据是待合并对象是否为空.如果对象是平面的component 则递归处理,如果是entity则检查是否是 * 有效的持久化对象(id不为空或者0),那么将该对象复制过去,否则复制null. * * 这些页面对象中的集合属性不包括在复制和合并范围内.因为大多数页面参数中,很少有集合(Set)参数 * 况且如果把空集合合并到已有对象上,反而会造成(hibernate)删除已有对象和这些对象的关联,甚至对象本身 * 将orig中不为空的属性复制到dest中 added at * 两个对象必须是同一类型的 * </pre> * * @deprecated * @see EntityUtil#evictEmptyProperty * @param dest * @param orig * 影响dest */ public static void merge(Object dest, Object orig) { String attr = ""; try { Set attrs = PropertyUtils.describe(orig).keySet(); attrs.remove("class"); for (Iterator it = attrs.iterator(); it.hasNext();) { attr = (String) it.next(); if (!PropertyUtils.isWriteable(orig, attr)) { continue; } Object value = PropertyUtils.getProperty(orig, attr); if (null != value) { if (value instanceof Component) { Object savedValue = PropertyUtils.getProperty(dest, attr); if (null == savedValue) { PropertyUtils.setProperty(dest, attr, value); } else { merge(savedValue, value); } } else if (value instanceof Collection) { continue; } else if (value instanceof Entity) { Serializable key = (Serializable) PropertyUtils .getProperty(value, ((Entity) value).key()); if (null == key) { continue; } else if (new EmptyKeyPredicate().evaluate(key)) { PropertyUtils.setProperty(dest, attr, null); } else { PropertyUtils.setProperty(dest, attr, value); } } else { PropertyUtils.setProperty(dest, attr, value); } } } } catch (Exception e) { logger.error("meger error", e); if (logger.isDebugEnabled()) { logger.debug("error occur in reflection of attr:" + attr + " of entity " + dest.getClass().getName()); } return; } } /** * 清除实体类中引用的无效(外键)属性.<br> * * <pre> * hibernate在保存对象是检查对象是否引用了未持久化的对象,如果引用则保存出错. * 实体类(Entity)是否已经持久化通过检查其id是否为有效值来判断的. * 对于实体类中包含的 * <code> * Component * </code> * 则递归处理 * 因为集合为空仍有其含义,这里对集合不做随意处理.如 * // evict collection * if (value instanceof Collection) { * if (((Collection) value).isEmpty()) * map.put(attr, null); * } * </pre> * * @see ValidEntityPredicate * @param entity */ public static void evictEmptyProperty(Object entity) { if (null == entity) { return; } boolean isEntity = false; if (entity instanceof Entity) { isEntity = true; } BeanMap map = new BeanMap(entity); List attList = new ArrayList(); attList.addAll(map.keySet()); attList.remove("class"); for (Iterator iter = attList.iterator(); iter.hasNext();) { String attr = (String) iter.next(); if (!PropertyUtils.isWriteable(entity, attr)) { continue; } Object value = map.get(attr); if (null == value) { continue; } else { // evict invalid entity key if (isEntity && attr.equals(((Entity) entity).key())) { if (!ValidEntityKeyPredicate.getInstance().evaluate(value)) { map.put(attr, null); } } // evict invalid entity if (value instanceof Entity && !ValidEntityPredicate.getInstance().evaluate(value)) { map.put(attr, null); } else if (value instanceof Component) { // evict component recursively evictEmptyProperty(value); } } } } public static List extractIds(Collection entities) { List idList = new ArrayList(); for (Iterator iter = entities.iterator(); iter.hasNext();) { Object element = (Object) iter.next(); if (element instanceof Entity) { try { idList.add(PropertyUtils.getProperty(element, ((Entity) element).key())); } catch (Exception e) { logger.error("getProperty error", e); continue; } } } return idList; } public static String getCommandName(Class clazz) { String name = clazz.getName(); return StringUtils.uncapitalize(name .substring(name.lastIndexOf('.') + 1)); } public static String getCommandName(String entityName) { return StringUtils.uncapitalize(StringUtils.substringAfterLast( entityName, ".")); } public static String getCommandName(Object obj) { String name = obj.getClass().getName(); int dollar = name.indexOf('$'); if (-1 != dollar) { name = name.substring(name.lastIndexOf('.') + 1, dollar); } else { name = name.substring(name.lastIndexOf('.') + 1); } return StringUtils.uncapitalize(name); } public static String extractIdSeq(Collection entities) { if (null == entities || entities.isEmpty()) { return ""; } StringBuilder idBuf = new StringBuilder(","); for (Iterator iter = entities.iterator(); iter.hasNext();) { Object element = (Object) iter.next(); if (element instanceof Entity) { try { idBuf.append(PropertyUtils.getProperty(element, ((Entity) element).key())); idBuf.append(','); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } } } return idBuf.toString(); } /** * 判断实体类中的属性是否全部为空 * * @param entity * @param ignoreDefault * 忽略数字和字符串的默认值 * @return */ public static boolean isEmpty(Entity entity, boolean ignoreDefault) { BeanMap map = new BeanMap(entity); List attList = new ArrayList(); attList.addAll(map.keySet()); attList.remove("class"); try { for (Iterator iter = attList.iterator(); iter.hasNext();) { String attr = (String) iter.next(); if (!PropertyUtils.isWriteable(entity, attr)) { continue; } Object value = map.get(attr); if (null == value) { continue; } if (ignoreDefault) { if (value instanceof Number) { if (((Number) value).intValue() != 0) { return false; } } else if (value instanceof String) { String str = (String) value; if (StringUtils.isNotEmpty(str)) { return false; } } else { return false; } } else { return false; } } } catch (Exception e) { logger.error("isEmpty error", e); } return true; } /** * 为了取出CGLIB代来的代理命名 * * @param clazz * @return */ public static String getEntityClassName(Class clazz) { String name = clazz.getName(); int dollar = name.indexOf('$'); if (-1 == dollar) { return name; } else { return name.substring(0, dollar); } } }