• 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 {
53       ClearPage.write(data, "navtree_data.cs", "navtree_data.js");
54     }
55   }
56 
57   /**
58    * Write the YAML formatted navigation tree.
59    * @see "http://yaml.org/"
60    */
writeYamlTree(String dir, String fileName)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) {
67       if (cl.isHidden()) {
68         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 
makeYamlHDF(SortedMap<String, Object> sorted, String base, Data data)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 
makeYamlHDF(ClassInfo cl, String base, Data data)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   }
makePackageNode(PackageInfo pkg)133   private static Node makePackageNode(PackageInfo pkg) {
134     List<Node> children = new ArrayList<Node>();
135 
136     addClassNodes(children, "Interfaces", pkg.interfaces());
137     addClassNodes(children, "Classes", pkg.ordinaryClasses());
138     addClassNodes(children, "Enums", pkg.enums());
139     addClassNodes(children, "Exceptions", pkg.exceptions());
140     addClassNodes(children, "Errors", pkg.errors());
141 
142     return new Node(pkg.name(), pkg.htmlPage(), children, pkg.getSince());
143   }
144 
addClassNodes(List<Node> parent, String label, ClassInfo[] classes)145   private static void addClassNodes(List<Node> parent, String label, ClassInfo[] classes) {
146     List<Node> children = new ArrayList<Node>();
147 
148     for (ClassInfo cl : classes) {
149       if (cl.checkLevel()) {
150         children.add(new Node(cl.name(), cl.htmlPage(), null, cl.getSince()));
151       }
152     }
153 
154     if (children.size() > 0) {
155       parent.add(new Node(label, null, children, null));
156     }
157   }
158 
159   private static class Node {
160     private String mLabel;
161     private String mLink;
162     List<Node> mChildren;
163     private String mSince;
164 
Node(String label, String link, List<Node> children, String since)165     Node(String label, String link, List<Node> children, String since) {
166       mLabel = label;
167       mLink = link;
168       mChildren = children;
169       mSince = since;
170     }
171 
renderString(StringBuilder buf, String s)172     static void renderString(StringBuilder buf, String s) {
173       if (s == null) {
174         buf.append("null");
175       } else {
176         buf.append('"');
177         final int N = s.length();
178         for (int i = 0; i < N; i++) {
179           char c = s.charAt(i);
180           if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
181             buf.append(c);
182           } else {
183             buf.append("\\u");
184             for (int j = 0; i < 4; i++) {
185               char x = (char) (c & 0x000f);
186               if (x > 10) {
187                 x = (char) (x - 10 + 'a');
188               } else {
189                 x = (char) (x + '0');
190               }
191               buf.append(x);
192               c >>= 4;
193             }
194           }
195         }
196         buf.append('"');
197       }
198     }
199 
renderChildren(StringBuilder buf)200     void renderChildren(StringBuilder buf) {
201       List<Node> list = mChildren;
202       if (list == null || list.size() == 0) {
203         // We output null for no children. That way empty lists here can just
204         // be a byproduct of how we generate the lists.
205         buf.append("null");
206       } else {
207         buf.append("[ ");
208         final int N = list.size();
209         for (int i = 0; i < N; i++) {
210           list.get(i).render(buf);
211           if (i != N - 1) {
212             buf.append(", ");
213           }
214         }
215         buf.append(" ]\n");
216       }
217     }
218 
render(StringBuilder buf)219     void render(StringBuilder buf) {
220       buf.append("[ ");
221       renderString(buf, mLabel);
222       buf.append(", ");
223       renderString(buf, mLink);
224       buf.append(", ");
225       renderChildren(buf);
226       buf.append(", ");
227       renderString(buf, mSince);
228       buf.append(" ]");
229     }
230   }
231 }
232