The Marshaller takes an object in memory and all its references (and
their references and so on) and marshals it into a
FreeMind mindmap
representation in memory. This representation can then be further
manipulated and saved to disk. Self-referential structures (such as
LinkedList
instances) are supported. The first time an
object is encountered,
a node in the map is created for it and all its children. Subsequent
times, a graphical link is drawn to the existing object.
The Marshaller is especially handy for comparing
the results of methods over time (or over different input values)
or for comparing return values between people separated geographically.
FreeMind is an open source tool for visualizing mind maps. The use of FreeMind as an output format allows for large nodes to be automatically closed when the mind map is viewed. The user then never gets lost in detail.
The JavaDoc is available here.
The following examples have source code together with the resulting mindmap:
package ca.quine.jcommons.marshaller.test; import java.io.BufferedWriter; import java.io.FileWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import ca.quine.jcommons.freemind.maputil.MapUtils; import ca.quine.jcommons.freemind.xml.Map; import ca.quine.jcommons.freemind.xml.Node; import ca.quine.jcommons.marshaller.Marshaller; import junit.framework.TestCase; public class MarshallerTest extends TestCase { /** * Test the <code>fqcn</code> method on <code>Marshaller</code>. * * @throws Exception */ public void testFqcn() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_ALWAYS, Marshaller.SHOW_ACTUAL_TYPE); Map map = marshaller.marshal("Foo"); assertEquals("java.lang.String", map.getNode().getTEXT()); marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); map = marshaller.marshal("Foo"); assertEquals("String", map.getNode().getTEXT()); } /** * Test <code>String</code> marshalling. * * @throws Exception */ public void testString() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_ALWAYS, Marshaller.SHOW_ACTUAL_TYPE); Map map = marshaller.marshal("Foo"); Node node = MapUtils.getRightNode(map); assertEquals("Foo", node.getTEXT()); } /** * Ensures that an Integer is marshalled with the type "Integer", and an * int is marshalled with the type "int". * * @throws Exception */ public void testIntegerVsIntType() throws Exception { Object object = new Object() { private Integer one = new Integer(1); private int two = 2; /** * Actually use the fields so that Eclipse doesn't give us a * warning. */ public String toString() { return "Object: " + one + ", " + two; } }; Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); Map map = marshaller.marshal(object); // Check the first Node to the right of the root node. Node node = MapUtils.getRightNode(map, 1); assertEquals("private Integer one", node.getTEXT()); // Node 2 is a reference to the outer class (i.e. "this") // since the fields are sorted by name. // Check the third Node to the right of the root node. node = MapUtils.getRightNode(map, 3); assertEquals("private int two", node.getTEXT()); } /** * Ensures the ArrayList marshaller can request default marshalling of * each object in the ArrayList (in this case, they are * <code>String</code>s). * * @throws Exception */ public void testArrayList() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); ArrayList list = new ArrayList(); list.add("one"); list.add("two"); list.add("three"); Map map = marshaller.marshal(list); Node node = MapUtils.getRightNode(map); assertEquals("one", node.getTEXT()); node = MapUtils.getRightNode(map, 2); assertEquals("two", node.getTEXT()); node = MapUtils.getRightNode(map, 3); assertEquals("three", node.getTEXT()); } /** * Mostly this test ensures that an infinite loop of some kind doesn't * occur, since many of the Objects held by a LinkedList point to internal * structures held by it. * * @throws Exception */ public void testLinkedList() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); LinkedList list = new LinkedList(); list.add("one"); list.add("two"); list.add("three"); Map map = marshaller.marshal(list); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\linked-list.mm")); map.marshal(bw); bw.close(); }View the mind map for the linked list
/** * Tests that a <code>HashMap</code> is correctly marshalled. * * @throws Exception */ public void testHashMap() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); HashMap hashMap = new HashMap(); hashMap.put("a", "one"); hashMap.put("b", "two"); hashMap.put("c", "three"); Map map = marshaller.marshal(hashMap); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\hashmap.mm")); map.marshal(bw); bw.close(); } public void testHashMapOfClasses() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); HashMap hashMap = new HashMap(); hashMap.put(String.class, "String"); hashMap.put(Integer.class, "Integer"); hashMap.put(Long.class, "Long"); Map map = marshaller.marshal(hashMap); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\hashmap-of-classes.mm")); map.marshal(bw); bw.close(); }View the mind map for the HashMap of classes.
public void testCharArray() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); char[] object = "abc".toCharArray(); Map map = marshaller.marshal(object); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\char-array.mm")); map.marshal(bw); bw.close(); } public void test2DCharArray() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); char[] object1 = "abc".toCharArray(); char[] object2 = "def".toCharArray(); char[] object3 = "ghi".toCharArray(); char[][] object = { object1, object2, object3 }; Map map = marshaller.marshal(object); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\2d-char-array.mm")); map.marshal(bw); bw.close(); } public void test3DCharArray() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); char[] object11 = "abc".toCharArray(); char[] object21 = "def".toCharArray(); char[] object31 = "ghi".toCharArray(); char[][] object1 = { object11, object21, object31 }; char[] object12 = "abc".toCharArray(); char[] object22 = "def".toCharArray(); char[] object32 = "ghi".toCharArray(); char[][] object2 = { object12, object22, object32 }; char[][][] object = { object1, object2 }; Map map = marshaller.marshal(object); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\3d-char-array.mm")); map.marshal(bw); bw.close(); }View the mind map for the 3D char array.
public void testIntArray() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); int[] object = { 1, 2, 3 }; Map map = marshaller.marshal(object); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\int-array.mm")); map.marshal(bw); bw.close(); } public void test2DIntArray() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); int[][] object = { {1, 2}, {3, 4}, {5, 6} }; Map map = marshaller.marshal(object); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\2d-int-array.mm")); map.marshal(bw); bw.close(); } public void test3DIntArray() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); int[][] object1 = { {1, 2}, {3, 4}, {5, 6} }; int[][] object2 = { {7, 8}, {9, 10}, {11, 12} }; int[][][] object = { object1, object2 }; Map map = marshaller.marshal(object); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\3d-int-array.mm")); map.marshal(bw); bw.close(); } public void test4DIntArray() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); int[][] object11 = { {1, 2}, {3, 4}, {5, 6} }; int[][] object21 = { {7, 8}, {9, 10}, {11, 12} }; int[][][] object1 = { object11, object21 }; int[][] object12 = { {1, 2}, {3, 4}, {5, 6} }; int[][] object22 = { {7, 8}, {9, 10}, {11, 12} }; int[][][] object2 = { object12, object22 }; int[][][][] object = { object1, object2 }; Map map = marshaller.marshal(object); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\4d-int-array.mm")); map.marshal(bw); bw.close(); }View the mind map for the 4D int array.
public void test2DShortArray() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); short[][] object = { {1, 2}, {3, 4}, {5, 6} }; Map map = marshaller.marshal(object); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\2d-short-array.mm")); map.marshal(bw); bw.close(); } public void test2DBooleanArray() throws Exception { Marshaller marshaller = new Marshaller( Marshaller.FQCN_NEVER, Marshaller.SHOW_ACTUAL_TYPE); boolean[][] object = { {true, false}, {true, false}, {true, false} }; Map map = marshaller.marshal(object); BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\temp\\2d-boolean-array.mm")); map.marshal(bw); bw.close(); } }