blob: cbe9fee15d9790a0bb6910c35855afadd7f8c737 [file] [log] [blame]
Ben Dodson920dbbb2010-08-04 15:21:06 -07001/*
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;
Chirag Shah18b25552012-08-09 13:57:54 -070023import java.util.SortedMap;
24import java.util.TreeMap;
Ben Dodson920dbbb2010-08-04 15:21:06 -070025
26public class NavTree {
27
Robert Ly5ab9cb52012-11-30 02:57:14 -080028 public static void writeNavTree(String dir, String refPrefix) {
Ben Dodson920dbbb2010-08-04 15:21:06 -070029 List<Node> children = new ArrayList<Node>();
30 for (PackageInfo pkg : Doclava.choosePackages()) {
31 children.add(makePackageNode(pkg));
32 }
Robert Ly5ab9cb52012-11-30 02:57:14 -080033 Node node = new Node("Reference", dir + refPrefix + "packages.html", children, null);
Ben Dodson920dbbb2010-08-04 15:21:06 -070034
35 StringBuilder buf = new StringBuilder();
36 if (false) {
37 // if you want a root node
38 buf.append("[");
39 node.render(buf);
40 buf.append("]");
41 } else {
42 // if you don't want a root node
43 node.renderChildren(buf);
44 }
45
46 Data data = Doclava.makeHDF();
47 data.setValue("reference_tree", buf.toString());
Robert Ly5ab9cb52012-11-30 02:57:14 -080048 if (refPrefix == "gms-"){
49 ClearPage.write(data, "gms_navtree_data.cs", "gms_navtree_data.js");
50 } else if (refPrefix == "gcm-"){
51 ClearPage.write(data, "gcm_navtree_data.cs", "gcm_navtree_data.js");
52 } else {
53 ClearPage.write(data, "navtree_data.cs", "navtree_data.js");
54 }
Ben Dodson920dbbb2010-08-04 15:21:06 -070055 }
56
Chirag Shah18b25552012-08-09 13:57:54 -070057 /**
58 * Write the YAML formatted navigation tree.
59 * @see "http://yaml.org/"
60 */
61 public static void writeYamlTree(String dir, String fileName){
62 Data data = Doclava.makeHDF();
63 ClassInfo[] classes = Converter.rootClasses();
64
65 SortedMap<String, Object> sorted = new TreeMap<String, Object>();
66 for (ClassInfo cl : classes) {
Hui Shu5118ffe2014-02-18 14:06:42 -080067 if (cl.isHiddenOrRemoved()) {
Chirag Shah18b25552012-08-09 13:57:54 -070068 continue;
69 }
70 sorted.put(cl.qualifiedName(), cl);
71
72 PackageInfo pkg = cl.containingPackage();
73 String name;
74 if (pkg == null) {
75 name = "";
76 } else {
77 name = pkg.name();
78 }
79 sorted.put(name, pkg);
80 }
81
82 data = makeYamlHDF(sorted, "docs.pages", data);
83 ClearPage.write(data, "yaml_navtree.cs", Doclava.ensureSlash(dir) + fileName);
84 }
85
86 public static Data makeYamlHDF(SortedMap<String, Object> sorted, String base, Data data) {
87
88 String key = "docs.pages.";
89 int i = 0;
90 for (String s : sorted.keySet()) {
91 Object o = sorted.get(s);
92
93 if (o instanceof PackageInfo) {
94 PackageInfo pkg = (PackageInfo) o;
95
96 data.setValue("docs.pages." + i + ".id", "" + i);
97 data.setValue("docs.pages." + i + ".label", pkg.name());
98 data.setValue("docs.pages." + i + ".shortname", "API");
99 data.setValue("docs.pages." + i + ".link", pkg.htmlPage());
100 data.setValue("docs.pages." + i + ".type", "package");
101 } else if (o instanceof ClassInfo) {
102 ClassInfo cl = (ClassInfo) o;
103
104 // skip classes that are the child of another class, recursion will handle those.
105 if (cl.containingClass() == null){
106
107 data.setValue("docs.pages." + i + ".id", "" + i);
108 data = makeYamlHDF(cl, "docs.pages."+i, data);
109 }
110 }
111
112 i++;
113 }
114 return data;
115 }
116
117 public static Data makeYamlHDF(ClassInfo cl, String base, Data data) {
118 data.setValue(base + ".label", cl.name());
119 data.setValue(base + ".shortname", cl.name().substring(cl.name().lastIndexOf(".")+1));
120 data.setValue(base + ".link", cl.htmlPage());
121 data.setValue(base + ".type", cl.kind());
122
123 if (cl.innerClasses().size() > 0){
124 int j = 0;
125 for (ClassInfo cl2 : cl.innerClasses()){
126 data = makeYamlHDF(cl2, base + ".children." + j, data);
127 j++;
128 }
129 }
130
131 return data;
132 }
Ben Dodson920dbbb2010-08-04 15:21:06 -0700133 private static Node makePackageNode(PackageInfo pkg) {
134 List<Node> children = new ArrayList<Node>();
135
Brett Chabot700b9f22013-10-04 16:57:39 -0700136 addClassNodes(children, "Annotations", pkg.annotations());
Ben Dodson920dbbb2010-08-04 15:21:06 -0700137 addClassNodes(children, "Interfaces", pkg.interfaces());
138 addClassNodes(children, "Classes", pkg.ordinaryClasses());
139 addClassNodes(children, "Enums", pkg.enums());
140 addClassNodes(children, "Exceptions", pkg.exceptions());
141 addClassNodes(children, "Errors", pkg.errors());
142
143 return new Node(pkg.name(), pkg.htmlPage(), children, pkg.getSince());
144 }
145
146 private static void addClassNodes(List<Node> parent, String label, ClassInfo[] classes) {
147 List<Node> children = new ArrayList<Node>();
148
149 for (ClassInfo cl : classes) {
150 if (cl.checkLevel()) {
151 children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince()));
152 }
153 }
154
155 if (children.size() > 0) {
156 parent.add(new Node(label, null, children, null));
157 }
158 }
159
160 private static class Node {
161 private String mLabel;
162 private String mLink;
163 List<Node> mChildren;
164 private String mSince;
165
166 Node(String label, String link, List<Node> children, String since) {
167 mLabel = label;
168 mLink = link;
169 mChildren = children;
170 mSince = since;
171 }
172
173 static void renderString(StringBuilder buf, String s) {
174 if (s == null) {
175 buf.append("null");
176 } else {
177 buf.append('"');
178 final int N = s.length();
179 for (int i = 0; i < N; i++) {
180 char c = s.charAt(i);
181 if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
182 buf.append(c);
183 } else {
184 buf.append("\\u");
185 for (int j = 0; i < 4; i++) {
186 char x = (char) (c & 0x000f);
Dirk Dougherty54004372015-07-02 13:10:45 -0700187 if (x >= 10) {
Ben Dodson920dbbb2010-08-04 15:21:06 -0700188 x = (char) (x - 10 + 'a');
189 } else {
190 x = (char) (x + '0');
191 }
192 buf.append(x);
193 c >>= 4;
194 }
195 }
196 }
197 buf.append('"');
198 }
199 }
200
201 void renderChildren(StringBuilder buf) {
202 List<Node> list = mChildren;
203 if (list == null || list.size() == 0) {
204 // We output null for no children. That way empty lists here can just
205 // be a byproduct of how we generate the lists.
206 buf.append("null");
207 } else {
208 buf.append("[ ");
209 final int N = list.size();
210 for (int i = 0; i < N; i++) {
211 list.get(i).render(buf);
212 if (i != N - 1) {
213 buf.append(", ");
214 }
215 }
216 buf.append(" ]\n");
217 }
218 }
219
220 void render(StringBuilder buf) {
221 buf.append("[ ");
222 renderString(buf, mLabel);
223 buf.append(", ");
224 renderString(buf, mLink);
225 buf.append(", ");
226 renderChildren(buf);
227 buf.append(", ");
228 renderString(buf, mSince);
229 buf.append(" ]");
230 }
231 }
232}