Rather helpful code for testing Externalizable classes

Karl Wettin <[email protected]>
Newsgroups gmane.comp.java.prevayler
Message-ID <[email protected]>
Sorry for hammering the list..

Here is an updated and better version that also handle arrays. It  
still doesn't do fields that are defined with abstract types, but I'll  
fix that too sooner or later. At least they are reported.


     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()) {
         Object theArray =  
Array.newInstance(field.getType().getComponentType(), i);
         setter.invoke(object, theArray);
       } 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.Byte.class |  
field.getType() == byte.class) {
         if (i > 128) { throw new RuntimeException("This code handle  
128 attributes safe. Fix it up!"); }
         setter.invoke(object, (byte) i); // todo better not be more  
than 128 attributes..
       } 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.
           manuallyRequiredChecks.add(field);
         } 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);
       if (field.getType().isArray()) {
         arraysEquals(field, getter.invoke(object),  
getter.invoke(clone));
       } else {
         assertEquals("Field " + field.getName() + " in class " +  
object.getClass().getName() + " does not match.",  
getter.invoke(object), getter.invoke(clone));
       }

     }

     System.out.println();

   }

   private boolean arraysEquals(Field field, Object a, Object b) {

     if (!a.getClass().equals(b.getClass())) {
       fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: Not  
the same Class");
     }

     if (Array.getLength(a) != Array.getLength(b)) {
       fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: Not  
the same length");
     }

     for (int i = 0; i < Array.getLength(a); i++) {
       if (field.getType().isPrimitive()) {

         if (field.getType() == boolean.class) {
           if (Array.getBoolean(a, i) != (Array.getBoolean(b, i))) {
             fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: a["  
+ i + "] != b[" + i + "]");
           }

         } else if (field.getType() == byte.class) {
           if (Array.getByte(a, i) != (Array.getByte(b, i))) {
             fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: a["  
+ i + "] != b[" + i + "]");
           }
         } else if (field.getType() == short.class) {
           if (Array.getShort(a, i) != (Array.getShort(b, i))) {
             fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: a["  
+ i + "] != b[" + i + "]");
           }

         } else if (field.getType() == int.class) {
           if (Array.getInt(a, i) != (Array.getInt(b, i))) {
             fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: a["  
+ i + "] != b[" + i + "]");
           }

         } else if (field.getType() == long.class) {
           if (Array.getLong(a, i) != (Array.getLong(b, i))) {
             fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: a["  
+ i + "] != b[" + i + "]");
           }

         } else if (field.getType() == float.class) {
           if (Array.getFloat(a, i) != (Array.getFloat(b, i))) {
             fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: a["  
+ i + "] != b[" + i + "]");
           }

         } else if (field.getType() == double.class) {
           if (Array.getDouble(a, i) != (Array.getDouble(b, i))) {
             fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: a["  
+ i + "] != b[" + i + "]");
           }
         }
       } else {
         if (!Array.get(a, i).equals(Array.get(b, i))) {
           fail("Array field " + field.getName() + " in class " +  
field.getDeclaringClass().getClass().getName() + " does not match: a["  
+ i + "] != b[" + i + "]");
         }
       }
     }

     return false;
   }

   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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.