• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 
23 /**
24 * Class for writing a JSON dictionary of Android package/class/member info that can be used for
25 * dereferencing javadoc style {@link} tags.
26 */
27 
28 public class AtLinksNavTree {
29 
30   /**
31   * Write a JSON dictionary of Android package/class/member info. The hierarchy will follow this
32   * format: package name -> class name -> member name and signature -> parent package.class name
33   * if the member was inherited (or an empty string if the member was not inherited).
34   *
35   * <p>For example:
36   * <pre>{
37   *   "android": {
38   *     "Manifest": {
39   *       "Manifest()": "",
40   *       "clone()": "java.lang.Object",
41   *       "equals(java.lang.Object)": "java.lang.Object",
42   *       ...
43   *     },
44   *     ...
45   *   },
46   *   ...
47   * }</pre>
48   *
49   * @param dir The directory path to prepend to the output path if the generated navtree is for
50   *        one the a supplemental library references (such as the wearable support library)
51   */
writeAtLinksNavTree(String dir)52   public static void writeAtLinksNavTree(String dir) {
53     StringBuilder buf = new StringBuilder();
54 
55     buf.append("{");
56     addPackages(buf, Doclava.choosePackages());
57     buf.append("\n}");
58 
59     Data data = Doclava.makeHDF();
60     data.setValue("navtree", buf.toString());
61 
62     String output_path;
63     if (Doclava.USE_DEVSITE_LOCALE_OUTPUT_PATHS && (Doclava.libraryRoot != null)) {
64       output_path = dir + Doclava.libraryRoot + "at_links_navtree.json";
65     } else {
66       output_path = "at_links_navtree.json";
67     }
68 
69     ClearPage.write(data, "at_links_navtree.cs", output_path);
70   }
71 
72   /**
73   * Append the provided string builder with the navtree info for the provided list of packages.
74   *
75   * @param buf The string builder to append to.
76   * @param packages A list of PackageInfo objects. Navtree info for each package will be appended
77   *        to the provided string builder.
78   */
addPackages(StringBuilder buf, PackageInfo[] packages)79   private static void addPackages(StringBuilder buf, PackageInfo[] packages) {
80     boolean is_first_package = true;
81     for (PackageInfo pkg : Doclava.choosePackages()) {
82       if (!pkg.name().contains(".internal.")) {
83         if (!is_first_package) {
84           buf.append(",");
85         }
86         buf.append("\n  \"" + pkg.name() + "\": {");
87 
88         boolean is_first_class = true;
89         is_first_class = addClasses(buf, pkg.annotations(), is_first_class);
90         is_first_class = addClasses(buf, pkg.interfaces(), is_first_class);
91         is_first_class = addClasses(buf, pkg.ordinaryClasses(), is_first_class);
92         is_first_class = addClasses(buf, pkg.enums(), is_first_class);
93         is_first_class = addClasses(buf, pkg.exceptions(), is_first_class);
94         addClasses(buf, pkg.errors(), is_first_class);
95 
96         buf.append("\n  }");
97         is_first_package = false;
98       }
99     }
100   }
101 
102   /**
103   * Append the provided string builder with the navtree info for the provided list of classes.
104   *
105   * @param buf The string builder to append to.
106   * @param classes A list of ClassInfo objects. Navtree info for each class will be appended
107   *        to the provided string builder.
108   * @param is_first_class True if this is the first child class listed under the parent package.
109   */
addClasses(StringBuilder buf, ClassInfo[] classes, boolean is_first_class)110   private static boolean addClasses(StringBuilder buf, ClassInfo[] classes,
111       boolean is_first_class) {
112     for (ClassInfo cl : classes) {
113       if (!is_first_class) {
114         buf.append(",");
115       }
116       buf.append("\n    \"" + cl.name() + "\": {");
117 
118       boolean is_first_member = true;
119       is_first_member = addFields(buf, cl.fields(), is_first_member, cl);
120       is_first_member = addMethods(buf, cl.constructors(), is_first_member, cl);
121       addMethods(buf, cl.methods(), is_first_member, cl);
122 
123       buf.append("\n    }");
124       is_first_class = false;
125     }
126     return is_first_class;
127   }
128 
129   /**
130   * Append the provided string builder with the navtree info for the provided list of fields.
131   *
132   * @param buf The string builder to append to.
133   * @param fields A list of FieldInfo objects. Navtree info for each field will be appended
134   *        to the provided string builder.
135   * @param is_first_member True if this is the first child member listed under the parent class.
136   * @param cl The ClassInfo object for the parent class of this field.
137   */
addFields(StringBuilder buf, ArrayList<FieldInfo> fields, boolean is_first_member, ClassInfo cl)138   private static boolean addFields(StringBuilder buf, ArrayList<FieldInfo> fields,
139       boolean is_first_member, ClassInfo cl) {
140     for (FieldInfo field : fields) {
141       if (!field.containingClass().qualifiedName().contains(".internal.")) {
142         if (!is_first_member) {
143           buf.append(",");
144         }
145         buf.append("\n      \"" + field.name() + "\": \"");
146         if (!field.containingClass().qualifiedName().equals(cl.qualifiedName())) {
147           buf.append(field.containingClass().qualifiedName());
148         }
149         buf.append("\"");
150         is_first_member = false;
151       }
152     }
153     return is_first_member;
154   }
155 
156   /**
157   * Append the provided string builder with the navtree info for the provided list of methods.
158   *
159   * @param buf The string builder to append to.
160   * @param methods A list of MethodInfo objects. Navtree info for each method will be appended
161   *        to the provided string builder.
162   * @param is_first_member True if this is the first child member listed under the parent class.
163   * @param cl The ClassInfo object for the parent class of this method.
164   */
addMethods(StringBuilder buf, ArrayList<MethodInfo> methods, boolean is_first_member, ClassInfo cl)165   private static boolean addMethods(StringBuilder buf, ArrayList<MethodInfo> methods,
166       boolean is_first_member, ClassInfo cl) {
167     for (MethodInfo method : methods) {
168       if (!method.containingClass().qualifiedName().contains(".internal.")) {
169         if (!is_first_member) {
170           buf.append(",");
171         }
172         buf.append("\n      \"" + method.name() + method.signature() + "\": \"");
173         if (!method.containingClass().qualifiedName().equals(cl.qualifiedName())) {
174           buf.append(method.containingClass().qualifiedName());
175         }
176         buf.append("\"");
177         is_first_member = false;
178       }
179     }
180     return is_first_member;
181   }
182 
183 }
184