lundi 25 mai 2015

Trying to detect a circular reference in Java with reflection

I've inherited some legacy code that fails if there's a circular reference. The code takes an object and builds the entire graph of objects for conversion to XML. The legacy code can't be modified, so I want to detect the reference and handle it accordingly.

For now, I'm building up a Set of all the fields on each object in the graph, and then later running through each objects fields and trying to detect if the objects are equal.

This is the portion of legacy code where the Set is built.

// declaration of set for this instance
 Set<Object> noduplicates = new HashSet<Object>();


private Iterator<Field> findAllFields(Object o) {
    Collection<Field> result = new LinkedList<Field>();j
    Class<? extends Object> c = o.getClass();
    while (c != null) {
        Field[] f = c.getDeclaredFields();
        for (int i = 0; i < f.length; i++) {
            if (!Modifier.isStatic(f[i].getModifiers())) {
                result.add(f[i]);
            }
        }
        c = c.getSuperclass();
    }
// add the fields for each object, for later comparison
    noduplicates.addAll((Collection<?>) result);
    testForDuplicates(noduplicates)
}

This is the current attempt at detecting circularity:

private void testForDublicates(Set<Object> noduplicates) throws ... {
    for (Object object : noduplicates) {
        Field[] fields = object.getClass().getFields();
        for (Field field : fields) {
            for (PropertyDescriptor pd : Introspector.getBeanInfo(field.getClass()).getPropertyDescriptors()) {
                  if (pd.getReadMethod() != null && !"class".equals(pd.getName())) {
                      Object possibleDuplicate = pd.getReadMethod().possibleDuplicate(object);
                      if (object.hashCode() == possibleDuplicate.hashCode()) {
                          System.out.println("Duplicated detected");
                          throw new RuntimeException();
                      }

                }
            }

        }
    }
}

I've tried several variations on the above, including direct testing of object equality.

Any pointers gratefully received.





Aucun commentaire:

Enregistrer un commentaire