package com.javaranch.dynadto; import java.util.*; import org.apache.commons.beanutils.*; /** * DynaBean implementation for DynaDTOs. Contains an implementation of * equals() which checks for content equality between * DynaDTODynaBean objects. * @author Jason Menard * @version 1.0, 08 SEP 2003 */ public class DynaDTODynaBean extends BasicDynaBean { /** * Constructor * @param dynaClass DynaClass for this DynaBean */ public DynaDTODynaBean(DynaClass dynaClass) { super(dynaClass); } /** * Tests for content equality between DynaDTODynaBean objects. * @param o an object to test for equality * @return true if o is a DynaDTODynaBean * containing only the same properties as the DynaDTODynaBean being * tested against and all values of those properties have their * equals() methods also evaluate to true. Any property * which is a Collection will have each element checked for * equality as well (with Collections of Collections * being recursively checked as well). Otherwise returns false. */ public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof DynaDTODynaBean)) { return false; } DynaDTODynaBean oBean = (DynaDTODynaBean)o; return dynaBeanEquals(this, oBean); } /** * Returns a hash code value for the object. * @return a hash code value for this object. */ public int hashCode() { int result = 17; DynaProperty[] props = this.getDynaClass().getDynaProperties(); for (int i = 0; i < props.length; i++) { int propHashCode = props[i].getName().hashCode() ^ props[i].getType().hashCode(); Object propVal = get(props[i].getName()); int valHashCode = (propVal == null ? 0 : propVal.hashCode()); int c = propHashCode ^ valHashCode; result = 37 * result + c; } return result; } /** * Returns a String representation of this object. * @return a String representation of this object. */ public String toString() { StringBuffer out = new StringBuffer(); out.append("[" + this.getDynaClass().getName() + ": "); DynaProperty[] properties = getDynaClass().getDynaProperties(); for (int i = 0; i < properties.length; i++) { String propName = properties[i].getName(); String propType = properties[i].getType().getName(); Object propValue = this.get(propName); out.append("name=" + properties[i].getName()); out.append(" type=" + properties[i].getType()); if (propValue instanceof Collection) { Collection collection = (Collection)propValue; for (Iterator it = collection.iterator(); it.hasNext(); ) { out.append(" value=" + it.next()); } } else { out.append(" value=" + propValue); } if (i < properties.length - 1) { out.append(", "); } } out.append("]"); return out.toString(); } private boolean dynaBeanEquals(DynaBean bean1, DynaBean bean2) { if (bean1 == bean2) { return true; } if (bean1 == null || bean2 == null) { return false; } DynaClass dynaClass1 = bean1.getDynaClass(); DynaProperty[] props1 = dynaClass1.getDynaProperties(); if (props1.length != bean2.getDynaClass().getDynaProperties().length) { return false; } boolean isEqual = true; int i = 0; while (i < props1.length && isEqual) { DynaProperty prop1 = props1[i]; DynaProperty prop2 = bean2.getDynaClass().getDynaProperty(prop1.getName()); isEqual = dynaPropertyEquals(prop1, prop2, bean1.get(prop1.getName()), bean2.get(prop2.getName())); i++; } return isEqual; } private boolean dynaPropertyEquals(DynaProperty prop1, DynaProperty prop2, Object value1, Object value2) { if (prop1 == prop2) { return true; } if (prop1 == null || prop2 == null) { return false; } String name1 = prop1.getName(); String name2 = prop2.getName(); Class type1 = prop1.getType(); Class type2 = prop2.getType(); if (name1.equals(name2) && type1.equals(type2)) { return valueEquals(value1, value2); } return false; } private boolean valueEquals(Object value1, Object value2) { if (value1 == value2) { return true; } if (value1 == null) { return false; } return value1.equals(value2); } }