package utile;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class UniformementRepresentable {
private static final Set<Class<?>> WRAPPER_TYPES = getWrapperTypes();
public static String toString(StringBuilder sb, Object obj) {
Class<? extends Object> cls = obj.getClass();
Field[] f = cls.getDeclaredFields();
for (int i = 0; i < f.length; i++) {
try {
f[i].setAccessible(true);
String sep = ((i+1) < f.length)? "; " : "";
if(f[i].get(obj)!=obj){
if(f[i].get(obj)!=null&&!f[i].get(obj).getClass().isPrimitive()&&!isWrapperType(f[i].get(obj).getClass())){
sb=new StringBuilder("[ "+f[i].getType().getSimpleName()+" " +f[i].getName()+toString(sb,f[i].get(obj))+" ]");
}
else {
sb.append(f[i].getName() + " = " + f[i].get(obj) + " ");
}
} else {
sb.append(f[i].getName() + " = this ");
}
} catch (Exception e) {
e.printStackTrace();
}
}
return sb + "";
}
public static boolean equals(Object obj1, Object obj2) {
Class<? extends Object> cls = obj1.getClass();
Class<? extends Object> cls2 = obj2.getClass();
if (obj1 == obj2)
return true;
if (cls != cls2)
return false;
// we can't get fields that come from a superclass
Field[] f1 = getFields(cls);
Field[] f2 = getFields(cls2);
boolean ok;
for (int i = 0; i < f1.length; i++) {
ok = false;
f1[i].setAccessible(true);
for (int j = 0; j < f2.length; j++) {
f2[j].setAccessible(true);
try {
if(f1[i].get(obj1)!=null&&f2[j].get(obj2)!=null&&f1[i].get(obj1)!=obj1&&f2[j].get(obj2)!=obj2){
if(f1[i].getName().equals(f2[j].getName())){
if(!f1[i].get(obj1).getClass().isPrimitive()&&!isWrapperType(f1[i].get(obj1).getClass())||!f2[j].get(obj2).getClass().isPrimitive()&&!isWrapperType(f2[j].get(obj2).getClass())){
if(equals(f1[i].get(obj1),f2[j].get(obj2))){
ok=true;
break;
}
} else {
if (f1[i].get(obj1).getClass().isPrimitive()
&& f2[j].get(obj2).getClass()
.isPrimitive()
|| isWrapperType(f1[i].get(obj1)
.getClass())
&& isWrapperType(f2[j].get(obj2)
.getClass())) {
if (f1[i].get(obj1).equals(f2[j].get(obj2))) {
ok = true;
}
}
break;
}
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if (!ok)
return false;
}
return true;
}
public static Field[] getFields(Class<?> type) {
ArrayList<Field> ret = new ArrayList<Field>();
ret = getAllFields(new ArrayList<Field>(), type);
return ret.toArray(new Field[ret.size()]);
}
private static ArrayList<Field> getAllFields(ArrayList<Field> fields,
Class<?> type) {
for (Field field : type.getDeclaredFields()) {
fields.add(field);
}
if (type.getSuperclass() != null) {
fields = getAllFields(fields, type.getSuperclass());
}
return fields;
}
public static boolean isWrapperType(Class<?> clazz) {
return WRAPPER_TYPES.contains(clazz);
}
private static Set<Class<?>> getWrapperTypes() {
Set<Class<?>> ret = new HashSet<Class<?>>();
ret.add(Boolean.class);
ret.add(Character.class);
ret.add(Byte.class);
ret.add(Short.class);
ret.add(Integer.class);
ret.add(Long.class);
ret.add(Float.class);
ret.add(Double.class);
ret.add(Void.class);
ret.add(String.class);
ret.add(null);
return ret;
}
}