Rather helpful code for testing Externalizable classes
Karl Wettin <[email protected]>
| Newsgroups | gmane.comp.java.prevayler |
|---|---|
| Message-ID | <[email protected]> |
This is what I use to make sure my readExternal and writeExternal work
as they should. I've found lots of human errors in my code using this.
Ihe code does not yet handle arrays. There are two todos that needs to
be handled.
// todo String[].getClass().what() == String.class?
// todo should really make sure that the default value is not
the same as the value we set it to!
There is a method in there that sets the id of my domain objects. You
might want to remove or modify that.
karl
public void test() throws Exception {
assertSerializationMatches(MyClass.class);
assertSerializationMatches(MyOtherClass.class);
if (manuallyRequiredChecks.size() > 0) {
System.out.println("Manual checking of serialization is
required for the following fields:");
for (Field field : manuallyRequiredChecks) {
System.out.println(field.getDeclaringClass().getName() + "#"
+ field.getName());
}
}
}
private static List<Field> manuallyRequiredChecks = new
ArrayList<Field>();
/**
* sets the id of my entity domain objects.
*/
public void setNonNullableField(Object object) {
if (object instanceof EntityDomainObject) {
((EntityDomainObject)
object).setId(UUID.randomUUID().toString());
}
}
public void assertSerializationMatches(Class _class) throws
Exception {
System.out.println("Testing " + _class.getName());
Object object = _class.newInstance();
setNonNullableField(object);
List<Field> allFields = getAllFields(_class);
for (int i = 0; i < allFields.size(); i++) {
Field field = allFields.get(i);
System.out.println("Setting " + _class.getName() + "#" +
field.getName());
// todo should really make sure that the default value is not
the same as the value we set it to!
Method setter = getSetter(field);
Method getter = getGetter(field);
if (field.getType().isArray()) {
// todo String[].getClass().what() == String.class?
// setter.invoke(Array.newInstance(field.getType(), i));
manuallyRequiredChecks.add(field);
} else if (field.getType() == java.lang.Boolean.class ||
field.getType() == boolean.class) {
setter.invoke(object, !((Boolean) getter.invoke(object))); //
set to the !default
} else if (field.getType() == java.lang.Short.class |
field.getType() == short.class) {
setter.invoke(object, (short) i);
} else if (field.getType() == java.lang.Integer.class ||
field.getType() == int.class) {
setter.invoke(object, Integer.valueOf(i));
} else if (field.getType() == java.lang.Long.class ||
field.getType() == long.class) {
setter.invoke(object, Long.valueOf(i));
} else if (field.getType() == java.lang.Float.class ||
field.getType() == float.class) {
setter.invoke(object, Float.valueOf(i));
} else if (field.getType() == java.lang.Double.class ||
field.getType() == double.class) {
setter.invoke(object, Double.valueOf(i));
} else if (field.getType() == java.lang.String.class) {
setter.invoke(object, String.valueOf(i));
} else if (field.getType() == java.util.List.class) {
List list = (List) getter.invoke(object);
if (list == null) {
setter.invoke(object, new ArrayList());
} else {
setter.invoke(object, list.getClass().newInstance());
}
} else if (field.getType() == java.util.Set.class) {
Set set = (Set) getter.invoke(object);
if (set == null) {
setter.invoke(object, new HashSet());
} else {
setter.invoke(object, set.getClass().newInstance());
}
} else if (field.getType() == java.util.Map.class) {
Map map = (Map) getter.invoke(object);
if (map == null) {
setter.invoke(object, new HashMap());
} else {
setter.invoke(object, map.getClass().newInstance());
}
} else if (field.getType().isEnum()) {
// set value to something different than default value.
Object value = getter.invoke(object);
if (value != field.getType().getEnumConstants()[0]) {
setter.invoke(object, field.getType().getEnumConstants()[0]);
} else {
setter.invoke(object, field.getType().getEnumConstants()[1]);
}
} else {
Object instance = null;
if (Modifier.isAbstract(field.getType().getModifiers())) {
// todo i have no clue how to handle this. need to set one
of the implementations.
} else {
instance = field.getType().newInstance();
}
setNonNullableField(instance);
setter.invoke(object, instance);
}
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.close();
baos.close();
ObjectInputStream os = new ObjectInputStream(new
ByteArrayInputStream(baos.toByteArray()));
Object clone = os.readObject();
for (Field field : getAllFields(object.getClass())) {
System.out.println("Testing " + _class.getName() + "#" +
field.getName());
Method getter = getGetter(field);
assertEquals("Field " + field.getName() + " in class " +
object.getClass().getName() + " does not match.",
getter.invoke(object), getter.invoke(clone));
}
System.out.println();
}
private Method getGetter(Field field) throws Exception {
StringBuilder getterName = new
StringBuilder(field.getName().length() + 3);
if (field.getType() == java.lang.Boolean.class || field.getType()
== boolean.class) {
getterName.append("is");
} else {
getterName.append("get");
}
getterName.append(field.getName().substring(0, 1).toUpperCase());
getterName.append(field.getName().substring(1));
return field.getDeclaringClass().getMethod(getterName.toString());
}
private Method getSetter(Field field) throws Exception {
StringBuilder setterName = new
StringBuilder(field.getName().length() + 3);
setterName.append("set");
setterName.append(field.getName().substring(0, 1).toUpperCase());
setterName.append(field.getName().substring(1));
return field.getDeclaringClass().getMethod(setterName.toString(),
field.getType());
}
private List<Field> getAllFields(Class serializable) {
// search super classes
Set<Class> allClasses = new HashSet<Class>();
findSuperClasses(allClasses, serializable);
List<Field> allFields = new ArrayList<Field>();
for (Class _class : allClasses) {
for (Field field : Arrays.asList(_class.getDeclaredFields())) {
if (!Modifier.isFinal(field.getModifiers())
&& !Modifier.isStatic(field.getModifiers())) {
allFields.add(field);
}
}
}
return allFields;
}
private void findSuperClasses(Set<Class> classes, Class current) {
classes.add(current);
if (current.getSuperclass() != null &&
classes.add(current.getSuperclass())) {
findSuperClasses(classes, current.getSuperclass());
}
for (Class _class : current.getInterfaces()) {
if (classes.add(_class)) {
findSuperClasses(classes, _class);
}
}
}
------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev
_______________________________________________
To unsubscribe go to the end of this page: http://lists.sourceforge.net/lists/listinfo/prevayler-discussion
_______________________________________________
"Databases in Memoriam" -- http://www.prevayler.org