blob: 466d247c9eb1bc3b5f187da8afc50e211bf65f51 [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;
Ben Dodson920dbbb2010-08-04 15:21:06 -070018import com.google.clearsilver.jsilver.data.Data;
19
20import java.util.*;
21import java.io.*;
Dirk Doughertye52f6d82013-09-04 17:27:29 -070022import java.util.regex.Pattern;
23import java.util.regex.Matcher;
Ben Dodson920dbbb2010-08-04 15:21:06 -070024
25public class SampleCode {
26 String mSource;
27 String mDest;
28 String mTitle;
Dirk Doughertyc11a4672013-08-23 19:14:10 -070029 String mProjectDir;
Dirk Dougherty25586c02013-08-30 16:21:15 -070030 String mTags;
Ben Dodson920dbbb2010-08-04 15:21:06 -070031
32 public SampleCode(String source, String dest, String title) {
33 mSource = source;
34 mTitle = title;
Dirk Dougherty25586c02013-08-30 16:21:15 -070035 mTags = null;
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070036
Dirk Dougherty815f9342013-09-12 00:30:28 -070037 if (dest != null) {
38 int len = dest.length();
39 if (len > 1 && dest.charAt(len - 1) != '/') {
40 mDest = dest + '/';
41 } else {
42 mDest = dest;
43 }
Ben Dodson920dbbb2010-08-04 15:21:06 -070044 }
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070045 //System.out.println("SampleCode init: source: " + mSource);
46 //System.out.println("SampleCode init: dest: " + mDest);
47 //System.out.println("SampleCode init: title: " + mTitle);
48
Ben Dodson920dbbb2010-08-04 15:21:06 -070049 }
50
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070051 public Node write(boolean offlineMode) {
52 List<Node> filelist = new ArrayList<Node>();
Ben Dodson920dbbb2010-08-04 15:21:06 -070053 File f = new File(mSource);
Dirk Doughertyc11a4672013-08-23 19:14:10 -070054 mProjectDir = f.getName();
55 String name = mProjectDir;
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070056 String startname = name;
57 String subdir = mDest;
58 String mOut = subdir + name;
Ben Dodson920dbbb2010-08-04 15:21:06 -070059 if (!f.isDirectory()) {
60 System.out.println("-samplecode not a directory: " + mSource);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070061 return null;
Ben Dodson920dbbb2010-08-04 15:21:06 -070062 }
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070063
64 if (offlineMode)
65 writeIndexOnly(f, mDest, offlineMode);
66 else {
67 Data hdf = Doclava.makeHDF();
68 hdf.setValue("samples", "true");
Dirk Doughertyc11a4672013-08-23 19:14:10 -070069 hdf.setValue("projectDir", mProjectDir);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070070 writeProjectDirectory(filelist, f, mDest, false, hdf, "Files.");
Dirk Doughertyc11a4672013-08-23 19:14:10 -070071 writeProjectStructure(name, hdf);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070072 hdf.removeTree("parentdirs");
73 hdf.setValue("parentdirs.0.Name", name);
Dirk Doughertye52f6d82013-09-04 17:27:29 -070074 //Write root _index.jd to out and add metadata to Node.
75 Node rootNode = writeProjectIndexCs(hdf, f, null, new Node(mProjectDir,
76 "samples/" + startname + "/index.html", null, null, filelist, null));
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070077 // return a root SC node for the sample with children appended
Dirk Doughertye52f6d82013-09-04 17:27:29 -070078 return rootNode;
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070079 }
80 return null;
Ben Dodson920dbbb2010-08-04 15:21:06 -070081 }
82
83 public static String convertExtension(String s, String ext) {
84 return s.substring(0, s.lastIndexOf('.')) + ext;
85 }
86
87 public static String[] IMAGES = {".png", ".jpg", ".gif"};
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070088 public static String[] TEMPLATED = {".java", ".xml", ".aidl", ".rs",".txt", ".TXT"};
Ben Dodson920dbbb2010-08-04 15:21:06 -070089
90 public static boolean inList(String s, String[] list) {
91 for (String t : list) {
92 if (s.endsWith(t)) {
93 return true;
94 }
95 }
96 return false;
97 }
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -070098
99 public static String mapTypes(String name) {
100 String type = name.substring(name.lastIndexOf('.') + 1, name.length());
101 if (type.equals("xml") || type.equals("java")) {
102 if (name.equals("AndroidManifest.xml")) type = "manifest";
103 return type;
104 } else {
105 return type = "file";
106 }
107 }
108
109 public void writeProjectDirectory(List<Node> parent, File dir, String relative, Boolean recursed, Data hdf, String newkey) {
110 TreeSet<String> dirs = new TreeSet<String>(); //dirs for project structure and breadcrumb
111 TreeSet<String> files = new TreeSet<String>(); //files for project structure and breadcrumb
112
113 String subdir = relative;
114 String name = "";
115 String label = "";
116 String link = "";
117 String type = "";
118 int i = 0;
119 String expansion = ".Sub.";
120 String key = newkey;
121
122 if (recursed) {
123 key = (key + expansion);
124 } else {
125 expansion = "";
126 }
127
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700128 File[] dirContents = dir.listFiles();
129 Arrays.sort(dirContents, byTypeAndName);
130 for (File f: dirContents) {
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700131 name = f.getName();
132 // don't process certain types of files
133 if (name.startsWith(".") ||
134 name.startsWith("_") ||
135 name.equals("default.properties") ||
136 name.equals("build.properties") ||
137 name.endsWith(".ttf") ||
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700138 name.endsWith(".gradle") ||
139 name.endsWith(".bat") ||
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700140 name.equals("Android.mk")) {
141 //System.out.println("Invalid File Type, bypassing: " + name);
142 continue;
143 }
144 if (f.isFile() && name.contains(".")){
145 String path = relative + name;
146 type = mapTypes(name);
147 link = convertExtension(path, ".html");
148 hdf.setValue("samples", "true");//dd needed?
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700149 if (inList(path, IMAGES)) {
150 // copy these files to output directly
151 type = "img";
152 ClearPage.copyFile(false, f, path);
153 writeImagePage(f, convertExtension(path, Doclava.htmlExtension), relative);
154 files.add(name);
155 hdf.setValue(key + i + ".Type", "img");
156 hdf.setValue(key + i + ".Name", name);
157 hdf.setValue(key + i + ".Href", link);
Dirk Dougherty25586c02013-08-30 16:21:15 -0700158 hdf.setValue(key + i + ".RelPath", relative);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700159 }
160 if (inList(path, TEMPLATED)) {
161 // copied and goes through the template
162 ClearPage.copyFile(false, f, path);
163 writePage(f, convertExtension(path, Doclava.htmlExtension), relative);
164 files.add(name);
165 hdf.setValue(key + i + ".Type", type);
166 hdf.setValue(key + i + ".Name", name);
167 hdf.setValue(key + i + ".Href", link);
Dirk Dougherty25586c02013-08-30 16:21:15 -0700168 hdf.setValue(key + i + ".RelPath", relative);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700169 }
170 // add file to the navtree
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700171 parent.add(new Node(name, link, null, null, null, type));
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700172 i++;
173 } else if (f.isDirectory()) {
174 List<Node> mchildren = new ArrayList<Node>();
175 type = "dir";
176 String dirpath = relative + name;
177 link = dirpath + "/index.html";
178 String hdfkeyName = (key + i + ".Name");
179 String hdfkeyType = (key + i + ".Type");
180 String hdfkeyHref = (key + i + ".Href");
181 hdf.setValue(hdfkeyName, name);
182 hdf.setValue(hdfkeyType, type);
183 hdf.setValue(hdfkeyHref, relative + name + "/" + "index.html");
184 //System.out.println("Found directory, recursing. Current key: " + hdfkeyName);
185 writeProjectDirectory(mchildren, f, relative + name + "/", true, hdf, (key + i));
186 if (mchildren.size() > 0) {
187 //dir is processed, now add it to the navtree
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700188 //don't link sidenav subdirs at this point (but can use "link" to do so)
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700189 parent.add(new Node(name, null, null, null, mchildren, type));
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700190 }
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700191 dirs.add(name);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700192 i++;
193 }
Dirk Dougherty25586c02013-08-30 16:21:15 -0700194
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700195 }
196 //dd not working yet
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700197 //Get summary from any _index files in any project dirs (currently disabled)
198 // getSummaryFromDir(hdf, dir, newkey);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700199 //If this is an index for the project root (assumed root if split length is 3 (development/samples/nn)),
200 //then remove the root dir so that it won't appear in the breadcrumb. Else just pass it through to
201 //setParentDirs as usual.
202 String mpath = dir + "";
203 String sdir[] = mpath.split("/");
204 if (sdir.length == 3 ) {
205 System.out.println("-----------------> this must be the root: [sdir len]" + sdir.length + "[dir]" + dir);
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700206 hdf.setValue("showProjectPaths","true");//dd remove here?
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700207 }
208 setParentDirs(hdf, relative, name, false);
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700209 //Generate an index.html page for each dir being processed
210 ClearPage.write(hdf, "sampleindex.cs", relative + "/index" + Doclava.htmlExtension);
211 //concatenate dirs in the navtree. Comment out or remove to restore normal navtree
Dirk Dougherty25586c02013-08-30 16:21:15 -0700212 squashNodes(parent);
Scott Maine27c9502011-01-19 14:07:39 -0800213 }
214
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700215 public void writeProjectStructure(String dir, Data hdf) {
216 //System.out.println(">>-- writing project structure for " + dir );
217 hdf.setValue("projectStructure", "true");
218 hdf.setValue("projectDir", mProjectDir);
219 hdf.setValue("page.title", mProjectDir + " Structure");
220 hdf.setValue("projectTitle", mTitle);
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700221 //write the project.html file
222 ClearPage.write(hdf, "sampleindex.cs", mDest + "project" + Doclava.htmlExtension);
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700223 hdf.setValue("projectStructure", "");
Ben Dodson920dbbb2010-08-04 15:21:06 -0700224 }
225
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700226 /**
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700227 * Processes a templated project index page from _index.jd in a project root.
228 * Each sample project must have an index, and each index locally defines it's own
229 * page.tags and sample.group cs vars. This method takes a SC node on input, reads
230 * any local vars from the _index.jd, generates an html file to out, then updates
231 * the SC node with the page vars and returns it to the caller.
232 *
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700233 */
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700234 public Node writeProjectIndexCs(Data hdf, File dir, String key, Node tnode) {
235 //hdf.setValue("summary", "");
236 //hdf.setValue("summaryFlag", "");
237 String filename = dir.getAbsolutePath() + "/_index.jd";
238 File f = new File(filename);
239 String rel = dir.getPath();
240 String mGroup = "";
241 hdf.setValue("samples", "true");
242 //set any default page variables for root index
243 hdf.setValue("page.title", mProjectDir);
Dirk Dougherty25586c02013-08-30 16:21:15 -0700244 hdf.setValue("projectDir", mProjectDir);
Dirk Dougherty25586c02013-08-30 16:21:15 -0700245 hdf.setValue("projectTitle", mTitle);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700246
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700247 if (!f.isFile()) {
248 //The sample didn't have any _index.jd, so create a stub.
249 ClearPage.write(hdf, "sampleindex.cs", mDest + "index" + Doclava.htmlExtension);
250 //Errors.error(Errors.INVALID_SAMPLE_INDEX, null, "Sample " + mProjectDir
251 // + ": Root _index.jd must be present and must define sample.group"
252 // + " tag. Please see ... for details.");
253 } else {
254 DocFile.writePage(filename, rel, mDest + "index" + Doclava.htmlExtension, hdf);
255 tnode.setTags(hdf.getValue("page.tags", ""));
256 mGroup = hdf.getValue("sample.group", "");
257 if (mGroup.equals("")) {
258 //Errors.error(Errors.INVALID_SAMPLE_INDEX, null, "Sample " + mProjectDir
259 // + ": Root _index.jd must be present and must define sample.group"
260 // + " tag. Please see ... for details.");
261 } else {
262 tnode.setGroup(hdf.getValue("sample.group", ""));
263 }
264 }
265 return tnode;
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700266 }
Ben Dodson920dbbb2010-08-04 15:21:06 -0700267
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700268 /**
269 * Keep track of file parents
270 */
271 Data setParentDirs(Data hdf, String subdir, String name, Boolean isFile) {
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700272 //set whether to linkify the crumb dirs on each sample code page
273 hdf.setValue("pathCrumbLinks", "");
274 //isFile = false;
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700275 int iter;
276 hdf.removeTree("parentdirs");
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700277 String s = subdir;
278 String urlParts[] = s.split("/");
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700279 //int n, l = (isFile)?1:0;
280 int n, l = 1;
281 //System.out.println("setParentDirs for " + subdir + name);
282 for (iter=1; iter < urlParts.length; iter++) {
283 n = iter-1;
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700284 //System.out.println("parentdirs." + n + ".Name == " + urlParts[iter]);
285 hdf.setValue("parentdirs." + n + ".Name", urlParts[iter]);
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700286 hdf.setValue("parentdirs." + n + ".Link", subdir + "index" + Doclava.htmlExtension);
Ben Dodson920dbbb2010-08-04 15:21:06 -0700287 }
Ben Dodson920dbbb2010-08-04 15:21:06 -0700288 return hdf;
289 }
290
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700291 /**
292 * Write a templated source code file to out.
293 */
Ben Dodson920dbbb2010-08-04 15:21:06 -0700294 public void writePage(File f, String out, String subdir) {
295 String name = f.getName();
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700296 String path = f.getPath();
Ben Dodson920dbbb2010-08-04 15:21:06 -0700297 String data =
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700298 SampleTagInfo.readFile(new SourcePositionInfo(path, -1, -1), path, "sample code",
299 true, true, true, true);
Ben Dodson920dbbb2010-08-04 15:21:06 -0700300 data = Doclava.escape(data);
301
302 Data hdf = Doclava.makeHDF();
Dirk Dougherty25586c02013-08-30 16:21:15 -0700303
304 String relative = subdir.replaceFirst("samples/", "");
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700305 hdf.setValue("samples", "true");
306 setParentDirs(hdf, subdir, name, true);
307 hdf.setValue("projectTitle", mTitle);
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700308 hdf.setValue("projectDir", mProjectDir);
Ben Dodson920dbbb2010-08-04 15:21:06 -0700309 hdf.setValue("page.title", name);
310 hdf.setValue("subdir", subdir);
Dirk Dougherty25586c02013-08-30 16:21:15 -0700311 hdf.setValue("relative", relative);
Ben Dodson920dbbb2010-08-04 15:21:06 -0700312 hdf.setValue("realFile", name);
313 hdf.setValue("fileContents", data);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700314 hdf.setValue("resTag", "sample");
315 hdf.setValue("resType", "Sample Code");
Ben Dodson920dbbb2010-08-04 15:21:06 -0700316
317 ClearPage.write(hdf, "sample.cs", out);
318 }
319
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700320 /**
321 * Write a templated image file to out.
322 */
Ben Dodson920dbbb2010-08-04 15:21:06 -0700323 public void writeImagePage(File f, String out, String subdir) {
324 String name = f.getName();
325
326 String data = "<img src=\"" + name + "\" title=\"" + name + "\" />";
327
328 Data hdf = Doclava.makeHDF();
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700329 hdf.setValue("samples", "true");
330 setParentDirs(hdf, subdir, name, true);
Ben Dodson920dbbb2010-08-04 15:21:06 -0700331 hdf.setValue("page.title", name);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700332 hdf.setValue("projectTitle", mTitle);
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700333 hdf.setValue("projectDir", mProjectDir);
Ben Dodson920dbbb2010-08-04 15:21:06 -0700334 hdf.setValue("subdir", subdir);
335 hdf.setValue("realFile", name);
336 hdf.setValue("fileContents", data);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700337 hdf.setValue("resTag", "sample");
338 hdf.setValue("resType", "Sample Code");
Ben Dodson920dbbb2010-08-04 15:21:06 -0700339 ClearPage.write(hdf, "sample.cs", out);
340 }
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700341
342 /**
343 * Render a SC node to a navtree js file.
344 */
Dirk Dougherty815f9342013-09-12 00:30:28 -0700345 public static void writeSamplesNavTree(List<Node> tnode, List<Node> groupnodes) {
346
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700347 Node node = new Node("Reference", "packages.html", null, null, tnode, null);
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700348
Dirk Dougherty815f9342013-09-12 00:30:28 -0700349 if (groupnodes != null) {
350 for (int i = 0; i < tnode.size(); i++) {
351 groupnodes = appendNodeGroups(tnode.get(i), groupnodes);
352 }
353 node.setChildren(groupnodes);
354 }
355
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700356 StringBuilder buf = new StringBuilder();
357 if (false) {
358 // if you want a root node
359 buf.append("[");
360 node.render(buf);
361 buf.append("]");
362 } else {
363 // if you don't want a root node
364 node.renderChildren(buf);
365 }
366
367 Data data = Doclava.makeHDF();
368 data.setValue("reference_tree", buf.toString());
369 ClearPage.write(data, "samples_navtree_data.cs", "samples_navtree_data.js");
370 }
371
Dirk Dougherty25586c02013-08-30 16:21:15 -0700372 /**
Dirk Dougherty815f9342013-09-12 00:30:28 -0700373 * Iterate the list of projects and sort them by their groups. Samples the reference
374 * a valid sample group tag are added to a list for that group. Samples declare a
375 * sample.group tag in their _index.jd files.
376 */
377 private static List<Node> appendNodeGroups(Node gNode, List<Node> groupnodes) {
378 List<Node> mgrouplist = new ArrayList<Node>();
379 final int N = groupnodes.size();
380 for (int i = 0; i < N; i++) {
381 if (groupnodes.get(i).getLabel().equals(gNode.getGroup())) {
382 if (groupnodes.get(i).getChildren() == null) {
383 groupnodes.get(i).setChildren(mgrouplist);
384 }
385 mgrouplist.add(gNode);
386 //System.out.println("Added " + gNode.getLabel() + " to group " + group);
387 break;
388 } //?? no match
389 }
390 return groupnodes;
391 }
392
393 /**
Dirk Dougherty25586c02013-08-30 16:21:15 -0700394 * Sort by type and name (alpha), with manifest and src always at top.
395 */
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700396 Comparator<File> byTypeAndName = new Comparator<File>() {
397 public int compare (File one, File other) {
398 if (one.isDirectory() && !other.isDirectory()) {
399 return 1;
400 } else if (!one.isDirectory() && other.isDirectory()) {
401 return -1;
Dirk Dougherty25586c02013-08-30 16:21:15 -0700402 } else if (one.getName().equals("AndroidManifest.xml")) {
403 return -1;
404 } else if (one.getName().equals("src")) {
405 return -1;
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700406 } else {
407 return one.compareTo(other);
408 }
409 }
410 };
411
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700412 /**
Dirk Dougherty25586c02013-08-30 16:21:15 -0700413 * Concatenate dirs that only hold dirs to simplify nav tree
414 */
Dirk Dougherty815f9342013-09-12 00:30:28 -0700415 public static List<Node> squashNodes(List<Node> tnode) {
Dirk Dougherty25586c02013-08-30 16:21:15 -0700416 List<Node> list = tnode;
417
418 for(int i = 0; i < list.size(); ++i) {
419 //only squash dirs that contain another dir whose list size is 1 and
420 //that don't contain endpoints
421 if ((list.get(i).getType().equals("dir")) &&
422 (list.size() == 1) &&
423 (list.get(i).getChildren().get(0).getChildren() != null)) {
424 String thisLabel = list.get(i).getLabel();
425 String childLabel = list.get(i).getChildren().get(0).getLabel();
426 String newLabel = thisLabel + "/" + childLabel;
427 //Set label of parent and mChildren to those of child-child, skipping
428 //squashed dir
429 list.get(i).setLabel(newLabel);
430 list.get(i).setChildren(list.get(i).getChildren().get(0).getChildren());
431 } else {
432 continue;
433 }
434 }
435 return list;
436 }
437
438 /**
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700439 * SampleCode variant of NavTree node.
440 */
441 public static class Node {
442 private String mLabel;
443 private String mLink;
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700444 private String mGroup; // from sample.group in _index.jd
445 private List<String> mTags; // from page.tags in _index.jd
Dirk Dougherty25586c02013-08-30 16:21:15 -0700446 private List<Node> mChildren;
447 private String mType;
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700448
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700449 Node(String label, String link, String group, List<String> tags, List<Node> children, String type) {
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700450 mLabel = label;
451 mLink = link;
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700452 mGroup = group;
Dirk Dougherty25586c02013-08-30 16:21:15 -0700453 mTags = tags;
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700454 mChildren = children;
455 mType = type;
456 }
457
458 static void renderString(StringBuilder buf, String s) {
459 if (s == null) {
460 buf.append("null");
461 } else {
462 buf.append('"');
463 final int N = s.length();
464 for (int i = 0; i < N; i++) {
465 char c = s.charAt(i);
466 if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
467 buf.append(c);
468 } else {
469 buf.append("\\u");
470 for (int j = 0; i < 4; i++) {
471 char x = (char) (c & 0x000f);
472 if (x > 10) {
473 x = (char) (x - 10 + 'a');
474 } else {
475 x = (char) (x + '0');
476 }
477 buf.append(x);
478 c >>= 4;
479 }
480 }
481 }
482 buf.append('"');
483 }
484 }
485
486 void renderChildren(StringBuilder buf) {
487 List<Node> list = mChildren;
488 if (list == null || list.size() == 0) {
489 // We output null for no children. That way empty lists here can just
490 // be a byproduct of how we generate the lists.
491 buf.append("null");
492 } else {
493 buf.append("[ ");
494 final int N = list.size();
495 for (int i = 0; i < N; i++) {
496 list.get(i).render(buf);
497 if (i != N - 1) {
498 buf.append(", ");
499 }
500 }
501 buf.append(" ]\n");
502 }
503 }
504
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700505 void renderTags(StringBuilder buf) {
506 List<String> list = mTags;
507 if (list == null || list.size() == 0) {
508 buf.append("null");
509 } else {
510 buf.append("[ ");
511 final int N = list.size();
512 for (int i = 0; i < N; i++) {
513 String tagval = list.get(i).toString();
514 buf.append('"');
515 final int L = tagval.length();
516 for (int t = 0; t < L; t++) {
517 char c = tagval.charAt(t);
518 if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
519 buf.append(c);
520 } else {
521 buf.append("\\u");
522 for (int m = 0; m < 4; m++) {
523 char x = (char) (c & 0x000f);
524 if (x > 10) {
525 x = (char) (x - 10 + 'a');
526 } else {
527 x = (char) (x + '0');
528 }
529 buf.append(x);
530 c >>= 4;
531 }
532 }
533 }
534 buf.append('"');
535 if (i != N - 1) {
536 buf.append(", ");
537 }
538 }
539 buf.append(" ]");
540 }
541 }
542
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700543 void render(StringBuilder buf) {
544 buf.append("[ ");
545 renderString(buf, mLabel);
546 buf.append(", ");
547 renderString(buf, mLink);
548 buf.append(", ");
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700549 renderString(buf, mGroup);
550 buf.append(", ");
551 renderTags(buf);
552 buf.append(", ");
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700553 renderChildren(buf);
554 buf.append(", ");
555 renderString(buf, mType);
556 buf.append(" ]");
557 }
Dirk Dougherty25586c02013-08-30 16:21:15 -0700558
559 public List<Node> getChildren() {
560 if (mChildren != null) {
561 return mChildren;
562 } else {
563 return null;
564 }
565 }
566
567 public void setChildren(List<Node> node) {
568 mChildren = node;
569 }
570
571 public String getLabel() {
572 return mLabel;
573 }
574
575 public void setLabel(String label) {
576 mLabel = label;
577 }
578
579 public String getType() {
580 return mType.toString();
581 }
582
583 public String getHref() {
584 return mLink;
585 }
586
587 public void setHref(String link) {
588 mLink = link;
589 }
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700590
Dirk Dougherty815f9342013-09-12 00:30:28 -0700591 public String getGroup() {
592 return mGroup;
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700593 }
594
Dirk Dougherty815f9342013-09-12 00:30:28 -0700595 public void setGroup(String group) {
596 mGroup = group;
Dirk Doughertye52f6d82013-09-04 17:27:29 -0700597 }
598
599 public void setTags(String tags) {
600 List<String> tagList = new ArrayList();
601 String[] tagParts = tags.split(",");
602
603 for (int iter = 0; iter < tagParts.length; iter++) {
604 String item = tagParts[iter].replaceAll("\"", "").trim();
605 tagList.add(item);
606 }
607 mTags = tagList;
608 }
609 }
610
611 /**
612 * Write the project's templated _index.html
613 * @deprecated
614 *
615 */
616 public void writeProjectIndex(Data hdf) {
617 //System.out.println(">>-- writing project index for " + mDest );
618 hdf.setValue("projectDir", mProjectDir);
619 hdf.setValue("page.title", mProjectDir + " Sample");
620 hdf.setValue("projectTitle", mTitle);
621 ClearPage.write(hdf, "sampleindex.cs", mDest + "index" + Doclava.htmlExtension);
622 }
623
624 /**
625 * Grab the contents of an _index.html summary from a dir.
626 * @deprecated
627 */
628 public void getSummaryFromDir(Data hdf, File dir, String key) {
629 //System.out.println("Getting summary for " + dir + "/_index.html");
630 hdf.setValue("summary", "");
631 hdf.setValue("summaryFlag", "");
632 String filename = dir.getPath() + "/_index.html";
633 String summary = SampleTagInfo.readFile(new SourcePositionInfo(filename,
634 -1,-1), filename, "sample code", true, false, false, true);
635 if (summary != null) {
636 hdf.setValue(key + "SummaryFlag", "true");
637 hdf.setValue("summary", summary);
638 //set the target for [info] link
639 //hdf.setValue(key + "Href", dir + "/index.html");
640 //return true;
641 }
Dirk Dougherty1b45d1d2010-08-17 17:25:36 -0700642 }
643
Dirk Doughertyc11a4672013-08-23 19:14:10 -0700644 /**
645 * @deprecated
646 */
647 public void writeDirectory(File dir, String relative, boolean offline) {
648 TreeSet<String> dirs = new TreeSet<String>();
649 TreeSet<String> files = new TreeSet<String>();
650
651 String subdir = relative; // .substring(mDest.length());
652
653 for (File f : dir.listFiles()) {
654 String name = f.getName();
655 if (name.startsWith(".") || name.startsWith("_")) {
656 continue;
657 }
658 if (f.isFile()) {
659 String out = relative + name;
660 if (inList(out, IMAGES)) {
661 // copied directly
662 ClearPage.copyFile(false, f, out);
663 writeImagePage(f, convertExtension(out, Doclava.htmlExtension), subdir);
664 files.add(name);
665 }
666 if (inList(out, TEMPLATED)) {
667 // copied and goes through the template
668 ClearPage.copyFile(false, f, out);
669 writePage(f, convertExtension(out, Doclava.htmlExtension), subdir);
670 files.add(name);
671
672 }
673 // else ignored
674 } else if (f.isDirectory()) {
675 writeDirectory(f, relative + name + "/", offline);
676 dirs.add(name);
677 }
678 }
679
680 // write the index page
681 int i;
682
683 Data hdf = writeIndex(dir);
684 hdf.setValue("subdir", subdir);
685 i = 0;
686 for (String d : dirs) {
687 hdf.setValue("subdirs." + i + ".Name", d);
688 hdf.setValue("files." + i + ".Href", convertExtension(d, ".html"));
689 i++;
690 }
691 i = 0;
692 for (String f : files) {
693 hdf.setValue("files." + i + ".Name", f);
694 hdf.setValue("files." + i + ".Href", convertExtension(f, ".html"));
695 i++;
696 }
697
698 if (!offline) relative = "/" + relative;
699 ClearPage.write(hdf, "sampleindex.cs", relative + "index" + Doclava.htmlExtension);
700 }
701
702 /**
703 * @deprecated
704 */
705 public void writeIndexOnly(File dir, String relative, Boolean offline) {
706 Data hdf = writeIndex(dir);
707 if (!offline) relative = "/" + relative;
708
709 System.out.println("writing indexonly at " + relative + "/index" + Doclava.htmlExtension);
710 ClearPage.write(hdf, "sampleindex.cs", relative + "index" + Doclava.htmlExtension);
711 }
712
713 /**
714 * @deprecated
715 */
716 public Data writeIndex(File dir) {
717 Data hdf = Doclava.makeHDF();
718 hdf.setValue("page.title", dir.getName() + " - " + mTitle);
719 hdf.setValue("projectTitle", mTitle);
720
721 String filename = dir.getPath() + "/_index.html";
722 String summary =
723 SampleTagInfo.readFile(new SourcePositionInfo(filename, -1, -1), filename, "sample code",
724 true, false, false, true);
725
726 if (summary == null) {
727 summary = "";
728 }
729 hdf.setValue("summary", summary);
730
731 return hdf;
732 }
733
Ben Dodson920dbbb2010-08-04 15:21:06 -0700734}