NavTree.java revision 9af82c2937fa7652dab0a34dc111b43447c41351
15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*
25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2010 Google Inc.
35b790feeeb211c42bf78ca3ae9c26aa30e516765Jakub Pawlowski *
45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License.
65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at
75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0
95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *
105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and
145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License.
155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project */
165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectpackage com.google.doclava;
185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectimport com.google.clearsilver.jsilver.data.Data;
205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectimport java.util.ArrayList;
225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectimport java.util.List;
235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectimport java.util.SortedMap;
245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectimport java.util.TreeMap;
25911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectpublic class NavTree {
275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  public static void writeNavTree(String dir, String refPrefix) {
29911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    List<Node> children = new ArrayList<Node>();
305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (PackageInfo pkg : Doclava.choosePackages()) {
315cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen      children.add(makePackageNode(pkg));
325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    Node node = new Node("Reference", dir + refPrefix + "packages.html", children, null);
345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    StringBuilder buf = new StringBuilder();
365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    if (false) {
37d7ffd64accbd50a27289a388856e56244ccbb5daMyles Watson      // if you want a root node
385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      buf.append("[");
395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      node.render(buf);
40911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      buf.append("]");
415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    } else {
425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      // if you don't want a root node
435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      node.renderChildren(buf);
445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
45ee96a3c60fca590d38025925c072d264e06493c4Myles Watson
469ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson    Data data = Doclava.makeHDF();
47ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    data.setValue("reference_tree", buf.toString());
48911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (refPrefix == "gms-"){
495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      ClearPage.write(data, "gms_navtree_data.cs", "gms_navtree_data.js");
50ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    } else if (refPrefix == "gcm-"){
519ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson      ClearPage.write(data, "gcm_navtree_data.cs", "gcm_navtree_data.js");
52ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    } else if ((Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS)
53a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowski          && (Doclava.testSupportRef)){
54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        ClearPage.write(data, "navtree_data.cs", dir + Doclava.testSupportPath
55911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          + "navtree_data.js");
56911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else if ((Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS)
57911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          && (Doclava.wearableSupportRef)){
58911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        ClearPage.write(data, "navtree_data.cs", dir + Doclava.wearableSupportPath
59d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen          + "navtree_data.js");
60911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      ClearPage.write(data, "navtree_data.cs", "navtree_data.js");
625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
64ee96a3c60fca590d38025925c072d264e06493c4Myles Watson
65ee96a3c60fca590d38025925c072d264e06493c4Myles Watson  /**
66ee96a3c60fca590d38025925c072d264e06493c4Myles Watson   * Write the YAML formatted navigation tree.
67ee96a3c60fca590d38025925c072d264e06493c4Myles Watson   * @see "http://yaml.org/"
68ee96a3c60fca590d38025925c072d264e06493c4Myles Watson   */
69ee96a3c60fca590d38025925c072d264e06493c4Myles Watson  public static void writeYamlTree(String dir, String fileName){
70ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    Data data = Doclava.makeHDF();
71ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    ClassInfo[] classes = Converter.rootClasses();
72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    SortedMap<String, Object> sorted = new TreeMap<String, Object>();
74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    for (ClassInfo cl : classes) {
755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (cl.isHiddenOrRemoved()) {
760dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov        continue;
770dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov      }
780dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov      sorted.put(cl.qualifiedName(), cl);
790dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov
80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      PackageInfo pkg = cl.containingPackage();
81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      String name;
82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (pkg == null) {
83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        name = "";
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        name = pkg.name();
86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      sorted.put(name, pkg);
885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    }
89d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen
90911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    data = makeYamlHDF(sorted, "docs.pages", data);
91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if ((Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS) && (Doclava.testSupportRef)) {
92911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      dir = Doclava.ensureSlash(dir) + Doclava.testSupportPath;
93911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else if ((Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS) && (Doclava.wearableSupportRef)) {
94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      dir = Doclava.ensureSlash(dir) + Doclava.wearableSupportPath;
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else if ((Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS) && (Doclava.androidSupportRef)) {
965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      dir = Doclava.ensureSlash(dir) + Doclava.androidSupportPath;
975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    } else if ((Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS) && (Doclava.constraintSupportRef)) {
98911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      dir = Doclava.ensureSlash(dir) + Doclava.constraintSupportRef;
99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
100911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ClearPage.write(data, "yaml_navtree.cs", Doclava.ensureSlash(dir) + fileName);
101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  public static Data makeYamlHDF(SortedMap<String, Object> sorted, String base, Data data) {
1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    String key = "docs.pages.";
106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    int i = 0;
1075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    for (String s : sorted.keySet()) {
108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      Object o = sorted.get(s);
1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      if (o instanceof PackageInfo) {
111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        PackageInfo pkg = (PackageInfo) o;
112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        data.setValue("docs.pages." + i + ".id", "" + i);
114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        data.setValue("docs.pages." + i + ".label", pkg.name());
115911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        data.setValue("docs.pages." + i + ".shortname", "API");
116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        data.setValue("docs.pages." + i + ".apilevel", pkg.getSince());
117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        data.setValue("docs.pages." + i + ".link", pkg.htmlPage());
118911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        data.setValue("docs.pages." + i + ".type", "package");
119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else if (o instanceof ClassInfo) {
120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        ClassInfo cl = (ClassInfo) o;
121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        // skip classes that are the child of another class, recursion will handle those.
123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (cl.containingClass() == null) {
124911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
125911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          data.setValue("docs.pages." + i + ".id", "" + i);
126911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          data = makeYamlHDF(cl, "docs.pages."+i, data);
1275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project        }
1285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
1290dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov
1300dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov      i++;
1310dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov    }
1320dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov    return data;
1330dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov  }
1340dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov
1350dbe21d88e05a43d6882248144e4e9128f4c1928Pavlin Radoslavov  public static Data makeYamlHDF(ClassInfo cl, String base, Data data) {
136d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    data.setValue(base + ".label", cl.name());
1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    data.setValue(base + ".shortname", cl.name().substring(cl.name().lastIndexOf(".")+1));
138ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    data.setValue(base + ".link", cl.htmlPage());
139ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    data.setValue(base + ".type", cl.kind());
140ee96a3c60fca590d38025925c072d264e06493c4Myles Watson
141ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    if (cl.innerClasses().size() > 0) {
142ee96a3c60fca590d38025925c072d264e06493c4Myles Watson      int j = 0;
143ee96a3c60fca590d38025925c072d264e06493c4Myles Watson      for (ClassInfo cl2 : cl.innerClasses()) {
144ee96a3c60fca590d38025925c072d264e06493c4Myles Watson        if (cl2.isHiddenOrRemoved()) {
145ee96a3c60fca590d38025925c072d264e06493c4Myles Watson          continue;
146911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        }
147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        data = makeYamlHDF(cl2, base + ".children." + j, data);
148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        j++;
1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      }
150911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
152911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return data;
1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  }
1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project
1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project  private static Node makePackageNode(PackageInfo pkg) {
1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    List<Node> children = new ArrayList<Node>();
157ee96a3c60fca590d38025925c072d264e06493c4Myles Watson
158ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    addClassNodes(children, "Annotations", pkg.annotations());
159ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    addClassNodes(children, "Interfaces", pkg.interfaces());
160ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    addClassNodes(children, "Classes", pkg.ordinaryClasses());
161ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    addClassNodes(children, "Enums", pkg.enums());
162ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    addClassNodes(children, "Exceptions", pkg.exceptions());
163ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    addClassNodes(children, "Errors", pkg.errors());
164ee96a3c60fca590d38025925c072d264e06493c4Myles Watson
165ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    return new Node(pkg.name(), pkg.htmlPage(), children, pkg.getSince());
166ee96a3c60fca590d38025925c072d264e06493c4Myles Watson  }
167a484a888196ddf8bcbf1ad3226d6451bc735a94bJakub Pawlowski
168911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  private static void addClassNodes(List<Node> parent, String label, ClassInfo[] classes) {
169d19e0785e662e640191a075eda07acce61c2aedaMarie Janssen    List<Node> children = new ArrayList<Node>();
170911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    for (ClassInfo cl : classes) {
172911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (cl.checkLevel()) {
173911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince()));
174911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
175911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
176911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
177911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (children.size() > 0) {
178911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      parent.add(new Node(label, null, children, null));
179911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
180135b7f68e4404872b9c5541146702c079e987877Jakub Pawlowski  }
181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
182911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  private static class Node {
183911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    private String mLabel;
184911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    private String mLink;
185911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    List<Node> mChildren;
186911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    private String mSince;
187911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
188911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    Node(String label, String link, List<Node> children, String since) {
189911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      mLabel = label;
190911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      mLink = link;
191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      mChildren = children;
192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      mSince = since;
193911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
194911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
1955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project    static void renderString(StringBuilder buf, String s) {
196911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (s == null) {
197911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        buf.append("null");
198911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
199911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        buf.append('"');
200911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        final int N = s.length();
201911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        for (int i = 0; i < N; i++) {
2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project          char c = s.charAt(i);
203911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project            buf.append(c);
205911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          } else {
206911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            buf.append("\\u");
207911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            for (int j = 0; i < 4; i++) {
208911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              char x = (char) (c & 0x000f);
209911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              if (x >= 10) {
2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                x = (char) (x - 10 + 'a');
2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              } else {
2125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project                x = (char) (x + '0');
2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project              }
214ee96a3c60fca590d38025925c072d264e06493c4Myles Watson              buf.append(x);
215ee96a3c60fca590d38025925c072d264e06493c4Myles Watson              c >>= 4;
216ee96a3c60fca590d38025925c072d264e06493c4Myles Watson            }
217ee96a3c60fca590d38025925c072d264e06493c4Myles Watson          }
218ee96a3c60fca590d38025925c072d264e06493c4Myles Watson        }
219ee96a3c60fca590d38025925c072d264e06493c4Myles Watson        buf.append('"');
220ee96a3c60fca590d38025925c072d264e06493c4Myles Watson      }
221ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    }
222ee96a3c60fca590d38025925c072d264e06493c4Myles Watson
223ee96a3c60fca590d38025925c072d264e06493c4Myles Watson    void renderChildren(StringBuilder buf) {
224911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      List<Node> list = mChildren;
225911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (list == null || list.size() == 0) {
226911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        // We output null for no children. That way empty lists here can just
227911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        // be a byproduct of how we generate the lists.
228911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        buf.append("null");
229911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      } else {
230911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        buf.append("[ ");
231911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        final int N = list.size();
232911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        for (int i = 0; i < N; i++) {
233911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          list.get(i).render(buf);
234911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          if (i != N - 1) {
235911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson            buf.append(", ");
236911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          }
237911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        }
238911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        buf.append(" ]\n");
239911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
241911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
242911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    void render(StringBuilder buf) {
243911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      buf.append("[ ");
244911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      renderString(buf, mLabel);
245911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      buf.append(", ");
246911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      renderString(buf, mLink);
247911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      buf.append(", ");
2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      renderChildren(buf);
2495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project      buf.append(", ");
250911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      renderString(buf, mSince);
251911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      buf.append(" ]");
252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
254911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson}
255911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson