• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.google.doclava;
18 
19 import com.google.clearsilver.jsilver.data.Data;
20 
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.SortedMap;
24 import java.util.TreeMap;
25 
26 public class NavTree {
27 
writeNavTree(String dir, String refPrefix)28   public static void writeNavTree(String dir, String refPrefix) {
29     List<Node> children = new ArrayList<Node>();
30     for (PackageInfo pkg : Doclava.choosePackages()) {
31       children.add(makePackageNode(pkg));
32     }
33     Node node = new Node("Reference", dir + refPrefix + "packages.html", children, null);
34 
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());
48     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 if (Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS && (Doclava.libraryRoot != null)) {
53         ClearPage.write(data, "navtree_data.cs", dir + Doclava.libraryRoot
54           + "navtree_data.js");
55     } else {
56       ClearPage.write(data, "navtree_data.cs", "navtree_data.js");
57     }
58   }
59 
60   /**
61    * Write the YAML formatted navigation tree.
62    * @see "http://yaml.org/"
63    */
writeYamlTree(String dir, String fileName)64   public static void writeYamlTree(String dir, String fileName){
65     Data data = Doclava.makeHDF();
66     ClassInfo[] classes = Converter.rootClasses();
67 
68     SortedMap<String, Object> sorted = new TreeMap<String, Object>();
69     for (ClassInfo cl : classes) {
70       if (cl.isHiddenOrRemoved()) {
71         continue;
72       }
73       sorted.put(cl.qualifiedName(), cl);
74 
75       PackageInfo pkg = cl.containingPackage();
76       String name;
77       if (pkg == null) {
78         name = "";
79       } else {
80         name = pkg.name();
81       }
82       sorted.put(name, pkg);
83     }
84 
85     data = makeYamlHDF(sorted, "docs.pages", data);
86 
87     if (Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS && (Doclava.libraryRoot != null)) {
88       dir = Doclava.ensureSlash(dir) + Doclava.libraryRoot;
89     }
90 
91     data.setValue("docs.classes.link", Doclava.ensureSlash(dir) + "classes.html");
92     data.setValue("docs.packages.link", Doclava.ensureSlash(dir) + "packages.html");
93 
94     ClearPage.write(data, "yaml_navtree.cs", Doclava.ensureSlash(dir) + fileName);
95   }
96 
makeYamlHDF(SortedMap<String, Object> sorted, String base, Data data)97   public static Data makeYamlHDF(SortedMap<String, Object> sorted, String base, Data data) {
98 
99     String key = "docs.pages.";
100     int i = 0;
101     for (String s : sorted.keySet()) {
102       Object o = sorted.get(s);
103 
104       if (o instanceof PackageInfo) {
105         PackageInfo pkg = (PackageInfo) o;
106 
107         data.setValue("docs.pages." + i + ".id", "" + i);
108         data.setValue("docs.pages." + i + ".label", pkg.name());
109         data.setValue("docs.pages." + i + ".shortname", "API");
110         data.setValue("docs.pages." + i + ".apilevel", pkg.getSince());
111         data.setValue("docs.pages." + i + ".link", pkg.htmlPage());
112         data.setValue("docs.pages." + i + ".type", "package");
113       } else if (o instanceof ClassInfo) {
114         ClassInfo cl = (ClassInfo) o;
115 
116         // skip classes that are the child of another class, recursion will handle those.
117         if (cl.containingClass() == null) {
118 
119           data.setValue("docs.pages." + i + ".id", "" + i);
120           data = makeYamlHDF(cl, "docs.pages."+i, data);
121         }
122       }
123 
124       i++;
125     }
126 
127     return data;
128   }
129 
makeYamlHDF(ClassInfo cl, String base, Data data)130   public static Data makeYamlHDF(ClassInfo cl, String base, Data data) {
131     data.setValue(base + ".label", cl.name());
132     data.setValue(base + ".shortname", cl.name().substring(cl.name().lastIndexOf(".")+1));
133     data.setValue(base + ".link", cl.htmlPage());
134     data.setValue(base + ".type", cl.kind());
135 
136     if (cl.innerClasses().size() > 0) {
137       int j = 0;
138       for (ClassInfo cl2 : cl.innerClasses()) {
139         if (cl2.isHiddenOrRemoved()) {
140           continue;
141         }
142         data = makeYamlHDF(cl2, base + ".children." + j, data);
143         j++;
144       }
145     }
146 
147     return data;
148   }
149 
makePackageNode(PackageInfo pkg)150   private static Node makePackageNode(PackageInfo pkg) {
151     List<Node> children = new ArrayList<Node>();
152 
153     addClassNodes(children, "Annotations", pkg.annotations());
154     addClassNodes(children, "Interfaces", pkg.interfaces());
155     addClassNodes(children, "Classes", pkg.ordinaryClasses());
156     addClassNodes(children, "Enums", pkg.enums());
157     addClassNodes(children, "Exceptions", pkg.exceptions());
158     addClassNodes(children, "Errors", pkg.errors());
159 
160     return new Node(pkg.name(), pkg.htmlPage(), children, pkg.getSince());
161   }
162 
addClassNodes(List<Node> parent, String label, ClassInfo[] classes)163   private static void addClassNodes(List<Node> parent, String label, ClassInfo[] classes) {
164     List<Node> children = new ArrayList<Node>();
165 
166     for (ClassInfo cl : classes) {
167       if (cl.checkLevel()) {
168         children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince(), cl.getArtifact()));
169       }
170     }
171 
172     if (children.size() > 0) {
173       parent.add(new Node(label, null, children, null));
174     }
175   }
176 
177   private static class Node {
178     private String mLabel;
179     private String mLink;
180     List<Node> mChildren;
181     private String mSince;
182     private String mArtifact;
183 
Node(String label, String link, List<Node> children, String since)184     Node(String label, String link, List<Node> children, String since) {
185       this(label, link, children, since, null);
186     }
187 
Node(String label, String link, List<Node> children, String since, String artifact)188     Node(String label, String link, List<Node> children, String since, String artifact) {
189       mLabel = label;
190       mLink = link;
191       mChildren = children;
192       mSince = since;
193       mArtifact = artifact;
194     }
195 
renderString(StringBuilder buf, String s)196     static void renderString(StringBuilder buf, String s) {
197       if (s == null) {
198         buf.append("null");
199       } else {
200         buf.append('"');
201         final int N = s.length();
202         for (int i = 0; i < N; i++) {
203           char c = s.charAt(i);
204           if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
205             buf.append(c);
206           } else {
207             buf.append("\\u");
208             for (int j = 0; i < 4; i++) {
209               char x = (char) (c & 0x000f);
210               if (x >= 10) {
211                 x = (char) (x - 10 + 'a');
212               } else {
213                 x = (char) (x + '0');
214               }
215               buf.append(x);
216               c >>= 4;
217             }
218           }
219         }
220         buf.append('"');
221       }
222     }
223 
renderChildren(StringBuilder buf)224     void renderChildren(StringBuilder buf) {
225       List<Node> list = mChildren;
226       if (list == null || list.size() == 0) {
227         // We output null for no children. That way empty lists here can just
228         // be a byproduct of how we generate the lists.
229         buf.append("null");
230       } else {
231         buf.append("[ ");
232         final int N = list.size();
233         for (int i = 0; i < N; i++) {
234           list.get(i).render(buf);
235           if (i != N - 1) {
236             buf.append(", ");
237           }
238         }
239         buf.append(" ]\n");
240       }
241     }
242 
render(StringBuilder buf)243     void render(StringBuilder buf) {
244       buf.append("[ ");
245       renderString(buf, mLabel);
246       buf.append(", ");
247       renderString(buf, mLink);
248       buf.append(", ");
249       renderChildren(buf);
250       buf.append(", ");
251       renderString(buf, mSince);
252       buf.append(", ");
253       renderString(buf, mArtifact);
254       buf.append(" ]");
255     }
256   }
257 }
258