diff --git a/common/source/java/ch/systemsx/cisd/common/utilities/ReflectionStringTraverser.java b/common/source/java/ch/systemsx/cisd/common/utilities/ReflectionStringTraverser.java index 88142aa3f37ca02db411ebe5b817fcd9924df7c6..4e1a68e3fe4a7f3d12a27ba8e1bf8a0b5c1beda9 100644 --- a/common/source/java/ch/systemsx/cisd/common/utilities/ReflectionStringTraverser.java +++ b/common/source/java/ch/systemsx/cisd/common/utilities/ReflectionStringTraverser.java @@ -25,6 +25,11 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.apache.log4j.Logger; + +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; + /** * Allows to change all non-final and non-static strings referenced within the specified object. If * isDeep is true, traverses the object recursively; otherwise, performs a shallow traversal. @@ -34,6 +39,9 @@ import java.util.Set; */ public class ReflectionStringTraverser { + private static final Logger log = LogFactory.getLogger(LogCategory.OPERATION, + ReflectionStringTraverser.class); + public static interface ReflectionFieldVisitor { /** @@ -114,7 +122,7 @@ public class ReflectionStringTraverser return; } - Field[] fields = clazz.getDeclaredFields(); + Field[] fields = getAllFields(clazz); for (Field field : fields) { int modifiers = field.getModifiers(); @@ -122,11 +130,16 @@ public class ReflectionStringTraverser { try { + if (log.isDebugEnabled()) + { + log.debug("Traverse field <" + field.getName() + "> of " + + object.getClass() + ":\n\t" + object); + } traverseField(object, field); } catch (Exception ex) { - System.err.println("Failed accessing field <" + field.getName() + "> of " - + object.getClass() + ":\n\t" + field); + log.error("Failed accessing field <" + field.getName() + "> of " + + object.getClass() + ":\n\t" + object); ex.printStackTrace(); throw new IllegalStateException("Should not happen: " + ex.getMessage()); } @@ -134,6 +147,31 @@ public class ReflectionStringTraverser } } + /** + * Return a list of all fields (whatever access status, and on whatever superclass they were + * defined) that can be found on this class. + * <p> + * This works like a union of {@link Class#getDeclaredFields()} which ignores super-classes, + * and {@link Class#getFields()} which ignores non-public fields + * + * @param clazz The class to introspect + * @return The complete list of fields + */ + private Field[] getAllFields(Class<?> clazz) + { + final Set<Field> result = new HashSet<Field>(); + Class<?> currentClass = clazz; + while (currentClass != null) + { + for (Field field : currentClass.getDeclaredFields()) + { + result.add(field); + } + currentClass = currentClass.getSuperclass(); + } + return result.toArray(new Field[result.size()]); + } + private void traverseField(Object object, Field field) throws IllegalAccessException { field.setAccessible(true);