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);
}
}