ObjectGraphUtil { public static void walkObjectGraph(Object object, Visitor visitor) { Queue<Object> queue = new LinkedList<>(); queue.offer(object); Set<Object> visitedObjects = Collections.newSetFromMap( new IdentityHashMap<>()); while ((object = queue.poll()) != null) { if (!visitedObjects.add(object)) { continue; } Class<?> clazz = object.getClass(); if (clazz.isArray()) { clazz = clazz.getComponentType(); if (clazz.isPrimitive()) { continue; } for (int i = 0; i < Array.getLength(object); i++) { Object element = Array.get(object, i); if (element != null) { queue.offer(element); } } continue; } while (clazz != null) { for (Field field : clazz.getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers())) { continue; } field.setAccessible(true); try { Object value = visitor.visit(field, object); Class<?> type = field.getType(); if ((value != null) && !type.isPrimitive()) { queue.offer(value); } } catch (Exception exception) { ReflectionUtil.throwException(exception); } } clazz = clazz.getSuperclass(); } } }  static void walkObjectGraph(Object object, Visitor visitor);  }
@Test public void testWalkObjectGraphNullReference() throws Exception { NullReference nullReference = new NullReference(); ObjectGraphUtil.walkObjectGraph(nullReference, _recordVisitor); Assert.assertEquals(_entries.toString(), 1, _entries.size()); Map.Entry<Field, Object> entry = _entries.get(0); Assert.assertEquals( ReflectionUtil.getDeclaredField(NullReference.class, "_object"), entry.getKey()); Assert.assertSame(nullReference, entry.getValue()); }
@Test public void testWalkObjectGraphNullReferenceWithException() { final Exception exception1 = new Exception(); try { ObjectGraphUtil.walkObjectGraph( new NullReference(), new ObjectGraphUtil.Visitor() { @Override public Object visit(Field field, Object target) throws Exception { throw exception1; } }); Assert.fail(); } catch (Exception exception2) { Assert.assertSame(exception1, exception2); } }
@Test public void testWalkObjectGraphObject() { ObjectGraphUtil.walkObjectGraph(new Object(), _recordVisitor); Assert.assertTrue(_entries.isEmpty()); }
@Test public void testWalkObjectGraphPrimitive() throws Exception { Primitive primitive = new Primitive(); ObjectGraphUtil.walkObjectGraph(primitive, _recordVisitor); Assert.assertEquals(_entries.toString(), 1, _entries.size()); Map.Entry<Field, Object> entry = _entries.get(0); Assert.assertEquals( ReflectionUtil.getDeclaredField(Primitive.class, "_int"), entry.getKey()); Assert.assertSame(primitive, entry.getValue()); }
@Test public void testWalkObjectGraphPrimitiveArray() throws Exception { PrimitiveArray primitiveArray = new PrimitiveArray(); ObjectGraphUtil.walkObjectGraph(primitiveArray, _recordVisitor); Assert.assertEquals(_entries.toString(), 1, _entries.size()); Map.Entry<Field, Object> entry = _entries.get(0); Assert.assertEquals( ReflectionUtil.getDeclaredField(PrimitiveArray.class, "_ints"), entry.getKey()); Assert.assertSame(primitiveArray, entry.getValue()); }
@Test public void testWalkObjectGraphSelfReference() throws Exception { SelfReference selfReference = new SelfReference(); ObjectGraphUtil.walkObjectGraph(selfReference, _recordVisitor); Assert.assertEquals(_entries.toString(), 1, _entries.size()); Map.Entry<Field, Object> entry = _entries.get(0); Assert.assertEquals( ReflectionUtil.getDeclaredField( SelfReference.class, "_selfReference"), entry.getKey()); Assert.assertSame(selfReference, entry.getValue()); }
@Test public void testWalkObjectGraphSelfReferenceArray() throws Exception { SelfReferenceArray selfReferenceArray = new SelfReferenceArray(); ObjectGraphUtil.walkObjectGraph(selfReferenceArray, _recordVisitor); Assert.assertEquals(_entries.toString(), 1, _entries.size()); Map.Entry<Field, Object> entry = _entries.get(0); Assert.assertEquals( ReflectionUtil.getDeclaredField( SelfReferenceArray.class, "_selfReferenceArray"), entry.getKey()); Assert.assertSame(selfReferenceArray, entry.getValue()); }
@Test public void testWalkObjectGraphStaticField() { ObjectGraphUtil.walkObjectGraph(new StaticField(), _recordVisitor); Assert.assertTrue(_entries.isEmpty()); }