SampleCode.java revision 1b45d1d08a4ff984e1d0741dd13f0759f6527ebf
1920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson/*
2920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Copyright (C) 2010 Google Inc.
3920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson *
4920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Licensed under the Apache License, Version 2.0 (the "License");
5920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * you may not use this file except in compliance with the License.
6920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * You may obtain a copy of the License at
7920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson *
8920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * http://www.apache.org/licenses/LICENSE-2.0
9920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson *
10920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Unless required by applicable law or agreed to in writing, software
11920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * distributed under the License is distributed on an "AS IS" BASIS,
12920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * See the License for the specific language governing permissions and
14920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * limitations under the License.
15920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */
16920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
17920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpackage com.google.doclava;
18920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
19920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.data.Data;
20920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
21920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.*;
22920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.io.*;
23920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
24920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
25920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpublic class SampleCode {
26920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  String mSource;
27920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  String mDest;
28920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  String mTitle;
29920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
30920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public SampleCode(String source, String dest, String title) {
31920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mSource = source;
32920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mTitle = title;
331b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
34920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int len = dest.length();
35920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (len > 1 && dest.charAt(len - 1) != '/') {
36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mDest = dest + '/';
37920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
38920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mDest = dest;
39920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
401b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
411b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    //System.out.println("SampleCode init: source: " + mSource);
421b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    //System.out.println("SampleCode init: dest: " + mDest);
431b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    //System.out.println("SampleCode init: title: " + mTitle);
441b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
45920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
46920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
471b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  public Node write(boolean offlineMode) {
481b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    List<Node> filelist = new ArrayList<Node>();
49920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    File f = new File(mSource);
501b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String name = f.getName();
511b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String startname = name;
521b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String subdir = mDest;
531b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String mOut = subdir + name;
54920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (!f.isDirectory()) {
55920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      System.out.println("-samplecode not a directory: " + mSource);
561b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      return null;
57920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
581b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
591b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    if (offlineMode)
601b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      writeIndexOnly(f, mDest, offlineMode);
611b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    else {
621b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      Data hdf = Doclava.makeHDF();
631b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("samples", "true");
641b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      writeProjectDirectory(filelist, f, mDest, false, hdf, "Files.");
651b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      // values for handling breadcrumb for project.html file
661b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("page.title", "Project Structure");
671b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.removeTree("parentdirs");
681b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("parentdirs.0.Name", name);
691b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("showProjectPaths","true");
701b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("samples", "true");
711b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      ClearPage.write(hdf, "sampleindex.cs", mDest + "project" + Doclava.htmlExtension); //write the project.html file
721b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      // return a root SC node for the sample with children appended
731b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      return new Node(mTitle, "samples/" + startname + "/index.html", filelist, null);
741b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
751b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    return null;
76920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
77920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
78920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String convertExtension(String s, String ext) {
79920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return s.substring(0, s.lastIndexOf('.')) + ext;
80920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
81920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
82920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static String[] IMAGES = {".png", ".jpg", ".gif"};
831b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  public static String[] TEMPLATED = {".java", ".xml", ".aidl", ".rs",".txt", ".TXT"};
84920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
85920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static boolean inList(String s, String[] list) {
86920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String t : list) {
87920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (s.endsWith(t)) {
88920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return true;
89920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
90920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
91920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return false;
92920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
931b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
941b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  public static String mapTypes(String name) {
951b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String type = name.substring(name.lastIndexOf('.') + 1, name.length());
961b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    if (type.equals("xml") || type.equals("java")) {
971b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      if (name.equals("AndroidManifest.xml")) type = "manifest";
981b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      return type;
991b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    } else {
1001b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      return type = "file";
1011b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
1021b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  }
1031b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
1041b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  public void writeProjectDirectory(List<Node> parent, File dir, String relative, Boolean recursed, Data hdf, String newkey) {
1051b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    TreeSet<String> dirs = new TreeSet<String>(); //dirs for project structure and breadcrumb
1061b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    TreeSet<String> files = new TreeSet<String>(); //files for project structure and breadcrumb
1071b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
1081b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String subdir = relative;
1091b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String name = "";
1101b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String label = "";
1111b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String link = "";
1121b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String type = "";
1131b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    int i = 0;
1141b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String expansion = ".Sub.";
1151b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String key = newkey;
1161b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
1171b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    if (recursed) {
1181b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      key = (key + expansion);
1191b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    } else {
1201b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      expansion = "";
1211b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
1221b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
1231b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    for (File f: dir.listFiles()) {
1241b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      name = f.getName();
1251b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      // don't process certain types of files
1261b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      if (name.startsWith(".") ||
1271b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          name.startsWith("_") ||
1281b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          name.equals("default.properties") ||
1291b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          name.equals("build.properties") ||
1301b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          name.endsWith(".ttf") ||
1311b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          name.equals("Android.mk")) {
1321b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         //System.out.println("Invalid File Type, bypassing: " + name);
1331b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         continue;
1341b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty       }
1351b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty       if (f.isFile() && name.contains(".")){
1361b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         String path = relative + name;
1371b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         type = mapTypes(name);
1381b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         link = convertExtension(path, ".html");
1391b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         hdf.setValue("samples", "true");//dd needed?
1401b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
1411b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         if (inList(path, IMAGES)) {
1421b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           // copy these files to output directly
1431b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           type = "img";
1441b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           ClearPage.copyFile(false, f, path);
1451b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           writeImagePage(f, convertExtension(path, Doclava.htmlExtension), relative);
1461b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           files.add(name);
1471b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           hdf.setValue(key + i + ".Type", "img");
1481b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           hdf.setValue(key + i + ".Name", name);
1491b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           hdf.setValue(key + i + ".Href", link);
1501b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         }
1511b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         if (inList(path, TEMPLATED)) {
1521b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           // copied and goes through the template
1531b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           ClearPage.copyFile(false, f, path);
1541b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           writePage(f, convertExtension(path, Doclava.htmlExtension), relative);
1551b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           files.add(name);
1561b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           hdf.setValue(key + i + ".Type", type);
1571b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           hdf.setValue(key + i + ".Name", name);
1581b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           hdf.setValue(key + i + ".Href", link);
1591b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         }
1601b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         // add file to the navtree
1611b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         parent.add(new Node(name, link , null, type));
1621b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         i++;
1631b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty       } else if (f.isDirectory()) {
1641b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         List<Node> mchildren = new ArrayList<Node>();
1651b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         type = "dir";
1661b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         String dirpath = relative + name;
1671b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         link = dirpath + "/index.html";
1681b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         String hdfkeyName = (key + i + ".Name");
1691b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         String hdfkeyType = (key + i + ".Type");
1701b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         String hdfkeyHref = (key + i + ".Href");
1711b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         hdf.setValue(hdfkeyName, name);
1721b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         hdf.setValue(hdfkeyType, type);
1731b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         hdf.setValue(hdfkeyHref, relative + name + "/" + "index.html");
1741b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         //System.out.println("Found directory, recursing. Current key: " + hdfkeyName);
1751b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         writeProjectDirectory(mchildren, f, relative + name + "/", true, hdf, (key + i));
1761b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         if (mchildren.size() > 0) {
1771b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           //dir is processed, now add it to the navtree
1781b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty           //don't link sidenav subdirs at this point (but cab use "link" to do so)
1791b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          parent.add(new Node(name, null, mchildren, type));
1801b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         }
1811b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         //dirs.add(name); //dd not used?
1821b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         i++;
1831b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty       }
1841b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
1851b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    //dd not working yet
1861b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    getSummaryFromDir(hdf, dir, newkey);
1871b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("resType", "Sample Code");
1881b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("resTag", "sample");
1891b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("showProjectPaths","false");
1901b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    //If this is an index for the project root (assumed root if split length is 3 (development/samples/nn)),
1911b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    //then remove the root dir so that it won't appear in the breadcrumb. Else just pass it through to
1921b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    //setParentDirs as usual.
1931b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String mpath = dir + "";
1941b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String sdir[] = mpath.split("/");
1951b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    if (sdir.length == 3 ) {
1961b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      System.out.println("-----------------> this must be the root: [sdir len]" + sdir.length + "[dir]" + dir);
1971b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("showProjectPaths","true");
1981b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
1991b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    setParentDirs(hdf, relative, name, false);
2001b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    System.out.println("writing  sample index -- " + relative + "index" + Doclava.htmlExtension);
2011b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    ClearPage.write(hdf, "sampleindex.cs", relative + "/index" + Doclava.htmlExtension);
202e27c950134c99151d1d9914eaaf28848327e4f63Scott Main  }
203e27c950134c99151d1d9914eaaf28848327e4f63Scott Main
204e27c950134c99151d1d9914eaaf28848327e4f63Scott Main  public void writeDirectory(File dir, String relative, boolean offline) {
205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TreeSet<String> dirs = new TreeSet<String>();
206920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TreeSet<String> files = new TreeSet<String>();
207920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String subdir = relative; // .substring(mDest.length());
209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (File f : dir.listFiles()) {
211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name = f.getName();
212920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (name.startsWith(".") || name.startsWith("_")) {
213920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        continue;
214920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
215920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (f.isFile()) {
216920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        String out = relative + name;
217920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (inList(out, IMAGES)) {
218920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          // copied directly
21988c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly          ClearPage.copyFile(false, f, out);
220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          writeImagePage(f, convertExtension(out, Doclava.htmlExtension), subdir);
221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          files.add(name);
222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (inList(out, TEMPLATED)) {
224920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          // copied and goes through the template
22588c435bb4d6c81c41107e23503b59af2e08acd8dRobert Ly          ClearPage.copyFile(false, f, out);
226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          writePage(f, convertExtension(out, Doclava.htmlExtension), subdir);
227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          files.add(name);
2281b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
229920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
230920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // else ignored
231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (f.isDirectory()) {
2324d505bf1fae392f3fb48bcaf62e9623d69724fa5Scott Main        writeDirectory(f, relative + name + "/", offline);
233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        dirs.add(name);
234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
235920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // write the index page
238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int i;
239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data hdf = writeIndex(dir);
241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("subdir", subdir);
242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    i = 0;
243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String d : dirs) {
2441b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("subdirs." + i + ".Name", d);
2451b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("files." + i + ".Href", convertExtension(d, ".html"));
246920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
247920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
248920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    i = 0;
249920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (String f : files) {
2501b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("files." + i + ".Name", f);
2511b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      hdf.setValue("files." + i + ".Href", convertExtension(f, ".html"));
252920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i++;
253920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (!offline) relative = "/" + relative;
256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(hdf, "sampleindex.cs", relative + "index" + Doclava.htmlExtension);
257920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
258920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
2591b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  public void writeIndexOnly(File dir, String relative, Boolean offline) {
2601b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    Data hdf = writeIndex(dir);
2611b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    if (!offline) relative = "/" + relative;
2621b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
2631b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      System.out.println("writing indexonly at " + relative + "/index" + Doclava.htmlExtension);
2641b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      ClearPage.write(hdf, "sampleindex.cs", relative + "index" + Doclava.htmlExtension);
2651b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  }
2661b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public Data writeIndex(File dir) {
268920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data hdf = Doclava.makeHDF();
269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("page.title", dir.getName() + " - " + mTitle);
271920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("projectTitle", mTitle);
272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String filename = dir.getPath() + "/_index.html";
274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String summary =
275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        SampleTagInfo.readFile(new SourcePositionInfo(filename, -1, -1), filename, "sample code",
2761b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            true, false, false, true);
277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
278920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (summary == null) {
279920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      summary = "";
280920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("summary", summary);
282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return hdf;
284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
2861b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty//dd START reformat this
2871b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    public Boolean getSummaryFromDir(Data hdf, File dir, String key) {
2881b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        hdf.setValue("page.title", dir.getName());
2891b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        hdf.setValue("projectTitle", mTitle);
2901b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
2911b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        String filename = dir.getPath() + "/_index.html";
2921b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        String summary = SampleTagInfo.readFile(new SourcePositionInfo(filename,
2931b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty                          -1,-1), filename, "sample code", true, false, false, true);
2941b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
2951b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        if (summary != null) {
2961b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            hdf.setValue(key + "SummaryFlag", "true");
2971b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            hdf.setValue("summary", summary);
2981b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            //set the target for [info] link
2991b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            hdf.setValue(key + "Href", dir + "/index.html");
3001b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            return true;
3011b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        }
3021b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        else {
3031b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            hdf.setValue("summary", "");
3041b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            return false;
3051b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        }
3061b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
3071b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3081b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    Data setParentDirs(Data hdf, String subdir, String name, Boolean isFile) {
3091b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        isFile = false;
3101b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        int iter;
3111b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        hdf.removeTree("parentdirs");
3121b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        //System.out.println("setParentDirs for " + subdir + name);
3131b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        String s = subdir;
3141b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        String urlParts[] = s.split("/");
3151b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        int n, l = (isFile)?1:0;
3161b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        for (iter=2; iter < urlParts.length - l; iter++) {
3171b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            n = iter-2;
3181b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         //System.out.println("parentdirs." + n + ".Name == " + urlParts[iter]);
3191b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty                hdf.setValue("parentdirs." + n + ".Name", urlParts[iter]);
3201b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            }
3211b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        return hdf;
3221b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }//dd END reformat this
3231b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3241b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3251b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3261b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3271b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3281b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3291b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3301b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3311b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
332920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void writePage(File f, String out, String subdir) {
333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String name = f.getName();
3341b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String path = f.getPath();
335920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String data =
3361b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        SampleTagInfo.readFile(new SourcePositionInfo(path, -1, -1), path, "sample code",
3371b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            true, true, true, true);
338920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data = Doclava.escape(data);
339920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
340920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data hdf = Doclava.makeHDF();
3411b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("samples", "true");
3421b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    setParentDirs(hdf, subdir, name, true);
3431b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("projectTitle", mTitle);
344920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("page.title", name);
345920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("subdir", subdir);
346920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("realFile", name);
347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("fileContents", data);
3481b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("resTag", "sample");
3491b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("resType", "Sample Code");
350920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
351920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(hdf, "sample.cs", out);
352920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
353920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
354920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void writeImagePage(File f, String out, String subdir) {
355920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String name = f.getName();
356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
357920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String data = "<img src=\"" + name + "\" title=\"" + name + "\" />";
358920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
359920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data hdf = Doclava.makeHDF();
3601b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("samples", "true");
3611b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    setParentDirs(hdf, subdir, name, true);
362920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("page.title", name);
3631b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("projectTitle", mTitle);
364920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("subdir", subdir);
365920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("realFile", name);
366920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("fileContents", data);
3671b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("resTag", "sample");
3681b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("resType", "Sample Code");
369920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(hdf, "sample.cs", out);
370920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
3711b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3721b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  /**
3731b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  * Render a SC node to a navtree js file.
3741b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  */
3751b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  public static void writeSamplesNavTree(List<Node> tnode) {
3761b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    Node node = new Node("Reference", "packages.html", tnode, null);
3771b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3781b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    StringBuilder buf = new StringBuilder();
3791b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    if (false) {
3801b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    // if you want a root node
3811b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      buf.append("[");
3821b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      node.render(buf);
3831b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      buf.append("]");
3841b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    } else {
3851b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      // if you don't want a root node
3861b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      node.renderChildren(buf);
3871b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
3881b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3891b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    Data data = Doclava.makeHDF();
3901b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    data.setValue("reference_tree", buf.toString());
3911b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    ClearPage.write(data, "samples_navtree_data.cs", "samples_navtree_data.js");
3921b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  }
3931b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
3941b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  /**
3951b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  * SampleCode variant of NavTree node.
3961b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  */
3971b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  public static class Node {
3981b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    private String mLabel;
3991b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    private String mLink;
4001b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    List<Node> mChildren;
4011b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    private String mType;
4021b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
4031b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    Node(String label, String link, List<Node> children, String type) {
4041b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      mLabel = label;
4051b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      mLink = link;
4061b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      mChildren = children;
4071b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      mType = type;
4081b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
4091b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
4101b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    static void renderString(StringBuilder buf, String s) {
4111b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      if (s == null) {
4121b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        buf.append("null");
4131b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      } else {
4141b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        buf.append('"');
4151b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        final int N = s.length();
4161b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        for (int i = 0; i < N; i++) {
4171b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          char c = s.charAt(i);
4181b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          if (c >= ' ' && c <= '~' && c != '"' && c != '\\') {
4191b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            buf.append(c);
4201b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          } else {
4211b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            buf.append("\\u");
4221b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            for (int j = 0; i < 4; i++) {
4231b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty              char x = (char) (c & 0x000f);
4241b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty              if (x > 10) {
4251b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty                x = (char) (x - 10 + 'a');
4261b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty              } else {
4271b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty                x = (char) (x + '0');
4281b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty              }
4291b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty              buf.append(x);
4301b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty              c >>= 4;
4311b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            }
4321b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          }
4331b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        }
4341b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        buf.append('"');
4351b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      }
4361b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
4371b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
4381b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    void renderChildren(StringBuilder buf) {
4391b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      List<Node> list = mChildren;
4401b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      if (list == null || list.size() == 0) {
4411b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        // We output null for no children. That way empty lists here can just
4421b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        // be a byproduct of how we generate the lists.
4431b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        buf.append("null");
4441b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      } else {
4451b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        buf.append("[ ");
4461b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        final int N = list.size();
4471b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        for (int i = 0; i < N; i++) {
4481b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          list.get(i).render(buf);
4491b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          if (i != N - 1) {
4501b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty            buf.append(", ");
4511b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          }
4521b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        }
4531b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        buf.append(" ]\n");
4541b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      }
4551b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
4561b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
4571b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    void render(StringBuilder buf) {
4581b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      buf.append("[ ");
4591b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      renderString(buf, mLabel);
4601b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      buf.append(", ");
4611b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      renderString(buf, mLink);
4621b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      buf.append(", ");
4631b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      renderChildren(buf);
4641b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      buf.append(", ");
4651b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      renderString(buf, mType);
4661b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      buf.append(" ]");
4671b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
4681b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  }
4691b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
470920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
471