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