1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import org.clearsilver.HDF; 18 19 import java.util.ArrayList; 20 21 public class NavTree { 22 23 public static void writeNavTree(String dir) { 24 ArrayList<Node> children = new ArrayList(); 25 for (PackageInfo pkg: DroidDoc.choosePackages()) { 26 children.add(makePackageNode(pkg)); 27 } 28 Node node = new Node("Reference", dir + "packages.html", children, null); 29 30 StringBuilder buf = new StringBuilder(); 31 if (false) { 32 // if you want a root node 33 buf.append("["); 34 node.render(buf); 35 buf.append("]"); 36 } else { 37 // if you don't want a root node 38 node.renderChildren(buf); 39 } 40 41 HDF data = DroidDoc.makeHDF(); 42 data.setValue("reference_tree", buf.toString()); 43 ClearPage.write(data, "navtree_data.cs", "navtree_data.js"); 44 } 45 46 private static Node makePackageNode(PackageInfo pkg) { 47 ArrayList<Node> children = new ArrayList(); 48 49 children.add(new Node("Description", pkg.fullDescriptionHtmlPage(), null, null)); 50 51 addClassNodes(children, "Interfaces", pkg.interfaces()); 52 addClassNodes(children, "Classes", pkg.ordinaryClasses()); 53 addClassNodes(children, "Enums", pkg.enums()); 54 addClassNodes(children, "Exceptions", pkg.exceptions()); 55 addClassNodes(children, "Errors", pkg.errors()); 56 57 return new Node(pkg.name(), pkg.htmlPage(), children, pkg.getSince()); 58 } 59 60 private static void addClassNodes(ArrayList<Node> parent, String label, ClassInfo[] classes) { 61 ArrayList<Node> children = new ArrayList(); 62 63 for (ClassInfo cl: classes) { 64 if (cl.checkLevel()) { 65 children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince())); 66 } 67 } 68 69 if (children.size() > 0) { 70 parent.add(new Node(label, null, children, null)); 71 } 72 } 73 74 private static class Node { 75 private String mLabel; 76 private String mLink; 77 ArrayList<Node> mChildren; 78 private String mSince; 79 80 Node(String label, String link, ArrayList<Node> children, String since) { 81 mLabel = label; 82 mLink = link; 83 mChildren = children; 84 mSince = since; 85 } 86 87 static void renderString(StringBuilder buf, String s) { 88 if (s == null) { 89 buf.append("null"); 90 } else { 91 buf.append('"'); 92 final int N = s.length(); 93 for (int i=0; i<N; i++) { 94 char c = s.charAt(i); 95 if (c >= ' ' && c <= '~' && c != '"' && c != '\\') { 96 buf.append(c); 97 } else { 98 buf.append("\\u"); 99 for (int j=0; i<4; i++) { 100 char x = (char)(c & 0x000f); 101 if (x > 10) { 102 x = (char)(x - 10 + 'a'); 103 } else { 104 x = (char)(x + '0'); 105 } 106 buf.append(x); 107 c >>= 4; 108 } 109 } 110 } 111 buf.append('"'); 112 } 113 } 114 115 void renderChildren(StringBuilder buf) { 116 ArrayList<Node> list = mChildren; 117 if (list == null || list.size() == 0) { 118 // We output null for no children. That way empty lists here can just 119 // be a byproduct of how we generate the lists. 120 buf.append("null"); 121 } else { 122 buf.append("[ "); 123 final int N = list.size(); 124 for (int i=0; i<N; i++) { 125 list.get(i).render(buf); 126 if (i != N-1) { 127 buf.append(", "); 128 } 129 } 130 buf.append(" ]\n"); 131 } 132 } 133 134 void render(StringBuilder buf) { 135 buf.append("[ "); 136 renderString(buf, mLabel); 137 buf.append(", "); 138 renderString(buf, mLink); 139 buf.append(", "); 140 renderChildren(buf); 141 buf.append(", "); 142 renderString(buf, mSince); 143 buf.append(" ]"); 144 } 145 } 146 } 147