In this tutorial we will render a mindmap as formatted characters. Our algotithm will need the input data split into left and right sides. The task of splitting the mindmap will be done by the projection.
public interface MindMap { public interface Node { @XBRead("./node") Node[] getSubNodes(); @XBRead("@TEXT") String getText(); } @XBRead("/map/node") Node getRootNode(); @XBRead("//node[@POSITION='left']") Node[] getLeftNodes(); @XBRead("//node[@POSITION='right']") Node[] getRightNodes(); @XBRead("count(descendant-or-self::node)") int getNodeCount();} |
This is the complete code as JUnit testcase.
public class TestDumpMindMap { private static final Comparator<? super String> STRING_LENGTH_COMPARATOR = new Comparator<String>() { @Override public int compare(String o1, String o2) { return Integer.valueOf(o1.length()).compareTo(o2.length()); } }; @Test public void dump() throws IOException { MindMap mindMap = new XBProjector().io().fromURLAnnotation(MindMap.class); List<String> leftLines = new LinkedList<String>(); List<String> rightLines= new LinkedList<String>(); walkNodes("", mindMap.getLeftNodes(), leftLines,true); walkNodes("",mindMap.getRightNodes(),rightLines,false); int maxLength = Collections.max(leftLines, STRING_LENGTH_COMPARATOR).length(); String rootText = mindMap.getRootNode().getText(); System.out.println(String.format("%1$-" + maxLength + "s", "")+rootText); String midSpace=rootText.replaceAll(".", " "); for (String s : leftLines) { String right=rightLines.isEmpty()?"":rightLines.get(0); if (!rightLines.isEmpty()){rightLines.remove(0);}; String line = reverse(String.format("%1$-" + maxLength + "s", s))+midSpace+right; System.out.println(line); } for (String s:rightLines) { String line=String.format("%1$-" + maxLength + "s", "")+midSpace+s; System.out.println(line); } } private void walkNodes(String prefix, Node[] leftNodes, List<String> lines,boolean reverse) { for (Node n : leftNodes) { lines.add((prefix + (reverse ? reverse(n.getText()) : n.getText()) )); walkNodes(prefix + (n.getText()).replaceAll(".", " "), n.getSubNodes(), lines,reverse); } } private String reverse(final String s) { return new StringBuffer(s).reverse().toString(); }} |
XMLBeam
Projector Metadata
Configuration Definition
Factories @XBead
Parser XPath
Document Builder TargetComponentType
XPath @XBWrite
must be serializeable Limited XPath
NamespacePhilosophy @XBDelete
Instantiation Parameterizing
Projection Externalization
Projection Types Properties
Projection Interface By package.class.method
Subprojection By class.method
External Projections By method
Projection Method By Key
Instances Custom
Instantiation must be serializeable
"Virtual Projections" IO
POJO like Input
Equals & HashCode String
Serialization File
Mixins Stream
Inheritance URL
DataTypes HTTP GET
Converting Request Customization
CustomTypes Document
Collections ExternalDocumentProjection
Primitives Resource
Subprojections Output
DOM Access Document Building
Projection Document PrettyPrinting
Projection Element XML Header control
Simple Casting Encoding
interface inheritance asString()
DOM is backend, can be changed anytime File
append
Stream
URL
HTTP POST
DocumentOrigins
@XBDocULR