added pretty good pretty-printing
[sbp.git] / src / edu / berkeley / sbp / util / PrintableTree.java
1 package edu.berkeley.sbp.util;
2 import edu.berkeley.sbp.*;
3 import edu.berkeley.sbp.util.*;
4 import java.io.*;
5 import java.util.*;
6 import java.lang.reflect.*;
7
8 public abstract class PrintableTree<T extends PrintableTree> implements Iterable<T>, ToJava {
9
10     protected abstract String headToString();
11     protected abstract String headToJava();    
12     protected abstract int    numChildren();
13
14     private static final int MAXCHARS=40;
15
16     private boolean basic() { return toString().length() < MAXCHARS; }
17     public String toPrettyString() { return toPrettyString("\n"); }
18     private String toPrettyString(String nl) {
19         String str = toString();
20         if (str.length() < MAXCHARS) return str;
21         String head = headToString();
22         StringBuffer ret = new StringBuffer();
23         if (numChildren()==0) return head==null ? "{}" : head;
24         ret.append(head==null?"{ ":(head+":"+nl));
25         boolean first = true;
26         int len = 0;
27         for(T t : this) {
28             String s = t.basic() ? t.toString() : t.toPrettyString(nl+"  ");
29             if (!first) {
30                 if (!t.basic())                ret.append(nl);
31                 if (s.length()+len>MAXCHARS) { ret.append(nl); len = 0; }
32                 else                         { ret.append(" "); len++; }
33             }
34             first = false;
35             ret.append(s);
36             len += s.length();
37         }
38         if (head==null) ret.append(" }");
39         return ret.toString();
40     }
41
42     public String toString() {
43         StringBuffer ret = new StringBuffer();
44         for(T t : this) {
45             String q = t==null ? "null" : t.toString();
46             if (q.length() > 0) { ret.append(q); ret.append(" "); }
47         }
48         String tail = ret.toString().trim();
49         String head = headToString();
50         String h = (head!=null && !head.toString().equals("")) ? (tail.length() > 0 ? head+":" : head+"") : "";
51         if (tail.length() > 0) tail = "{" + tail + "}";
52         return h + tail;
53     }
54
55     /** append Java code to <tt>sb</tt> which evaluates to this instance */
56     public void toJava(StringBuffer sb) {
57         sb.append("new "+this.getClass().getName()+"(null, ");
58         String head = headToJava();
59         sb.append(head==null ? "null" : "\"" + head + "\"");
60         sb.append(", new "+this.getClass().getName()+"[] { ");
61         boolean first = true;
62         for(T t : this) {
63             if (!first) sb.append(",\n        ");
64             if (t==null)   sb.append("null");
65             else           t.toJava(sb);
66             first = false;
67         }
68         sb.append("})");
69     }
70
71 }