1/* 2 * Copyright (C) 2010 Google Inc. 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 17package com.google.doclava; 18 19import com.google.clearsilver.jsilver.data.Data; 20 21import java.util.ArrayList; 22import java.util.List; 23 24public class NavTree { 25 26 public static void writeNavTree(String dir) { 27 List<Node> children = new ArrayList<Node>(); 28 for (PackageInfo pkg : Doclava.choosePackages()) { 29 children.add(makePackageNode(pkg)); 30 } 31 Node node = new Node("Reference", dir + "packages.html", children, null); 32 33 StringBuilder buf = new StringBuilder(); 34 if (false) { 35 // if you want a root node 36 buf.append("["); 37 node.render(buf); 38 buf.append("]"); 39 } else { 40 // if you don't want a root node 41 node.renderChildren(buf); 42 } 43 44 Data data = Doclava.makeHDF(); 45 data.setValue("reference_tree", buf.toString()); 46 ClearPage.write(data, "navtree_data.cs", "navtree_data.js"); 47 } 48 49 private static Node makePackageNode(PackageInfo pkg) { 50 List<Node> children = new ArrayList<Node>(); 51 52 addClassNodes(children, "Interfaces", pkg.interfaces()); 53 addClassNodes(children, "Classes", pkg.ordinaryClasses()); 54 addClassNodes(children, "Enums", pkg.enums()); 55 addClassNodes(children, "Exceptions", pkg.exceptions()); 56 addClassNodes(children, "Errors", pkg.errors()); 57 58 return new Node(pkg.name(), pkg.htmlPage(), children, pkg.getSince()); 59 } 60 61 private static void addClassNodes(List<Node> parent, String label, ClassInfo[] classes) { 62 List<Node> children = new ArrayList<Node>(); 63 64 for (ClassInfo cl : classes) { 65 if (cl.checkLevel()) { 66 children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince())); 67 } 68 } 69 70 if (children.size() > 0) { 71 parent.add(new Node(label, null, children, null)); 72 } 73 } 74 75 private static class Node { 76 private String mLabel; 77 private String mLink; 78 List<Node> mChildren; 79 private String mSince; 80 81 Node(String label, String link, List<Node> children, String since) { 82 mLabel = label; 83 mLink = link; 84 mChildren = children; 85 mSince = since; 86 } 87 88 static void renderString(StringBuilder buf, String s) { 89 if (s == null) { 90 buf.append("null"); 91 } else { 92 buf.append('"'); 93 final int N = s.length(); 94 for (int i = 0; i < N; i++) { 95 char c = s.charAt(i); 96 if (c >= ' ' && c <= '~' && c != '"' && c != '\\') { 97 buf.append(c); 98 } else { 99 buf.append("\\u"); 100 for (int j = 0; i < 4; i++) { 101 char x = (char) (c & 0x000f); 102 if (x > 10) { 103 x = (char) (x - 10 + 'a'); 104 } else { 105 x = (char) (x + '0'); 106 } 107 buf.append(x); 108 c >>= 4; 109 } 110 } 111 } 112 buf.append('"'); 113 } 114 } 115 116 void renderChildren(StringBuilder buf) { 117 List<Node> list = mChildren; 118 if (list == null || list.size() == 0) { 119 // We output null for no children. That way empty lists here can just 120 // be a byproduct of how we generate the lists. 121 buf.append("null"); 122 } else { 123 buf.append("[ "); 124 final int N = list.size(); 125 for (int i = 0; i < N; i++) { 126 list.get(i).render(buf); 127 if (i != N - 1) { 128 buf.append(", "); 129 } 130 } 131 buf.append(" ]\n"); 132 } 133 } 134 135 void render(StringBuilder buf) { 136 buf.append("[ "); 137 renderString(buf, mLabel); 138 buf.append(", "); 139 renderString(buf, mLink); 140 buf.append(", "); 141 renderChildren(buf); 142 buf.append(", "); 143 renderString(buf, mSince); 144 buf.append(" ]"); 145 } 146 } 147} 148