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
198a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Doughertyimport java.util.Arrays;
208a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Doughertyimport java.util.ArrayList;
218a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Doughertyimport java.util.Collections;
228a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Doughertyimport java.util.Comparator;
238a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Doughertyimport java.util.List;
24e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Doughertyimport java.util.regex.Pattern;
25e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Doughertyimport java.util.regex.Matcher;
268a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Doughertyimport java.io.File;
278a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
288a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Doughertyimport com.google.clearsilver.jsilver.data.Data;
29920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
308a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty/**
318a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty* Represents a browsable sample code project, with methods for managing
328a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty* metadata collection, file output, sorting, etc.
338a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty*/
34920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpublic class SampleCode {
35920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  String mSource;
36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  String mDest;
37920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  String mTitle;
38c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  String mProjectDir;
3925586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty  String mTags;
40920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
418a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /** Max size for browseable images/video. If a source file exceeds this size,
428a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * a file is generated with a generic placeholder and the original file is not
438a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * copied to out.
448a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
458a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  private static final double MAX_FILE_SIZE_BYTES = 2097152;
468a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
478a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /** When full tree nav is enabled, generate an index for every dir
488a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * and linkify the breadcrumb paths in all files.
498a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
508a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  private static final boolean FULL_TREE_NAVIGATION = false;
518a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
52920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public SampleCode(String source, String dest, String title) {
53920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mSource = source;
54920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mTitle = title;
5525586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    mTags = null;
561b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
57815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    if (dest != null) {
58815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      int len = dest.length();
59815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      if (len > 1 && dest.charAt(len - 1) != '/') {
60815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty        mDest = dest + '/';
61815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      } else {
62815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty        mDest = dest;
63815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      }
64920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
65920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
66920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
678a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /**
688a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Iterates a given sample code project gathering  metadata for files and building
698a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * a node tree that reflects the project's directory structure. After iterating
708a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * the project, this method adds the project's metadata to jd_lists_unified,
718a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * so that it is accessible for dynamic content and search suggestions.
728a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *
738a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param offlineMode Ignored -- offline-docs mode is not currently supported for
748a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *        browsable sample code projects.
758a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @return A root Node for the project containing its metadata and tree structure.
768a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
778a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public Node setSamplesTOC(boolean offlineMode) {
781b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    List<Node> filelist = new ArrayList<Node>();
79920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    File f = new File(mSource);
80c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    mProjectDir = f.getName();
81c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    String name = mProjectDir;
828a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    String mOut = mDest + name;
83920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (!f.isDirectory()) {
84920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      System.out.println("-samplecode not a directory: " + mSource);
851b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      return null;
86920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
871b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
888a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    Data hdf = Doclava.makeHDF();
898a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    setProjectStructure(filelist, f, mDest);
908a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    String link = ClearPage.toroot + "samples/" + name + "/index" + Doclava.htmlExtension;
918a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    Node rootNode = writeSampleIndexCs(hdf, f,
928a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        new Node.Builder().setLabel(mProjectDir).setLink(link).setChildren(filelist).build(),false);
938a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    return rootNode;
94920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
95920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
968a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /**
978a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * For a given sample code project dir, iterate through the project generating
988a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * browsable html for all valid sample code files. After iterating the project
998a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * generate a templated index file to the project output root.
1008a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *
1018a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param offlineMode Ignored -- offline-docs mode is not currently supported for
1028a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *        browsable sample code projects.
1038a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
1048a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public void writeSamplesFiles(boolean offlineMode) {
1058a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    List<Node> filelist = new ArrayList<Node>();
1068a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    File f = new File(mSource);
1078a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    mProjectDir = f.getName();
1088a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    String name = mProjectDir;
1098a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    String mOut = mDest + name;
1108a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    if (!f.isDirectory()) {
1118a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      System.out.println("-samplecode not a directory: " + mSource);
1128a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    }
113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1148a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    Data hdf = Doclava.makeHDF();
1158a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    if (Doclava.samplesNavTree != null) {
1168a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      hdf.setValue("samples_toc_tree", Doclava.samplesNavTree.getValue("samples_toc_tree", ""));
117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
1188a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.setValue("samples", "true");
1198a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.setValue("projectDir", mProjectDir);
1208a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    writeProjectDirectory(f, mDest, false, hdf, "Files.");
1218a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    writeProjectStructure(name, hdf);
1228a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.removeTree("parentdirs");
1238a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.setValue("parentdirs.0.Name", name);
1248a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    boolean writeFiles = true;
1258a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    String link = "samples/" + name + "/index" + Doclava.htmlExtension;
1268a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    //Write root _index.jd to out and add metadata to Node.
1278a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    writeSampleIndexCs(hdf, f,
1288a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        new Node.Builder().setLabel(mProjectDir).setLink(link).build(), true);
129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
1301b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
1318a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /**
1328a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Given the root Node for a sample code project, iterates through the project
1338a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * gathering metadata and project tree structure. Unsupported file types are
1348a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * filtered from the project output. The collected project Nodes are appended to
1358a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * the root project node.
1368a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *
1378a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param parent The root Node that represents this sample code project.
1388a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param dir The current dir being processed.
1398a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param relative Relative path for creating links to this file.
1408a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
1418a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public void setProjectStructure(List<Node> parent, File dir, String relative) {
1428a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    String name, link;
1438a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    File[] dirContents = dir.listFiles();
1448a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    Arrays.sort(dirContents, byTypeAndName);
1458a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    for (File f: dirContents) {
1468a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      name = f.getName();
1478a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      if (!isValidFiletype(name)) {
1488a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        continue;
1498a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      }
1508a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      if (f.isFile() && name.contains(".")) {
1518a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        String path = relative + name;
1528a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        link = convertExtension(path, Doclava.htmlExtension);
1538a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        if (inList(path, IMAGES) || inList(path, VIDEOS) || inList(path, TEMPLATED)) {
1548a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          parent.add(new Node.Builder().setLabel(name).setLink(ClearPage.toroot + link).build());
1558a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        }
1568a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      } else if (f.isDirectory()) {
1578a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        List<Node> mchildren = new ArrayList<Node>();
1588a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        String dirpath = relative + name + "/";
1598a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        setProjectStructure(mchildren, f, dirpath);
1608a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        if (mchildren.size() > 0) {
1618a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          parent.add(new Node.Builder().setLabel(name).setLink(ClearPage.toroot
1628a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            + dirpath).setChildren(mchildren).build());
1638a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        }
1648a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      }
1651b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
1661b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  }
1671b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
1688a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /**
1698a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Given a root sample code project path, iterates through the project
1708a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * setting page metadata to manage html output and writing/copying files to
1718a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * the output directory. Source files are templated and images are templated
1728a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * and linked to the original image.
1738a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *
1748a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param dir The current dir being processed.
1758a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param relative Relative path for creating links to this file.
1768a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param recursed Whether the method is being called recursively.
1778a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param hdf The data to read/write for files in this project.
1788a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param newKey Key passed in recursion for managing cs child trees.
1798a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
1808a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public void writeProjectDirectory(File dir, String relative, Boolean recursed,
1818a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      Data hdf, String newkey) {
1821b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String name = "";
1831b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String link = "";
1841b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String type = "";
1851b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    int i = 0;
1861b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String expansion = ".Sub.";
1871b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String key = newkey;
1881b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
1891b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    if (recursed) {
1901b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      key = (key + expansion);
1911b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    } else {
1921b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      expansion = "";
1931b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
1941b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
195c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    File[] dirContents = dir.listFiles();
196c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    Arrays.sort(dirContents, byTypeAndName);
197c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    for (File f: dirContents) {
1981b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      name = f.getName();
1998a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      if (!isValidFiletype(name)) {
2008a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        continue;
2018a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      }
2028a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      if (f.isFile() && name.contains(".")) {
2038a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        String path = relative + name;
2048a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        type = mapTypes(name);
2058a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        link = convertExtension(path, Doclava.htmlExtension);
2068a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        if (inList(path, IMAGES)) {
2078a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          type = "img";
2088a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          if (f.length() < MAX_FILE_SIZE_BYTES) {
2098a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            ClearPage.copyFile(false, f, path);
2108a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            writeImageVideoPage(f, convertExtension(path, Doclava.htmlExtension),
2113542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty                relative, type, true);
2128a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          } else {
2138a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            writeImageVideoPage(f, convertExtension(path, Doclava.htmlExtension),
2143542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty                relative, type, false);
2158a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          }
2168a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".Type", "img");
2178a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".Name", name);
2188a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".Href", link);
2198a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".RelPath", relative);
2208a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        } else if (inList(path, VIDEOS)) {
2218a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          type = "video";
2228a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          if (f.length() < MAX_FILE_SIZE_BYTES) {
2238a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            ClearPage.copyFile(false, f, path);
2248a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            writeImageVideoPage(f, convertExtension(path, Doclava.htmlExtension),
2253542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty                relative, type, true);
2268a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          } else {
2278a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            writeImageVideoPage(f, convertExtension(path, Doclava.htmlExtension),
2283542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty                relative, type, false);
2298a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          }
2308a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".Type", "video");
2318a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".Name", name);
2328a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".Href", link);
2338a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".RelPath", relative);
2348a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        } else if (inList(path, TEMPLATED)) {
2358a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          writePage(f, convertExtension(path, Doclava.htmlExtension), relative, hdf);
2368a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".Type", type);
2378a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".Name", name);
2388a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".Href", link);
2398a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          hdf.setValue(key + i + ".RelPath", relative);
2408a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        }
2418a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        i++;
2428a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      } else if (f.isDirectory()) {
2438a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        List<Node> mchildren = new ArrayList<Node>();
2448a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        type = "dir";
2458a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        String dirpath = relative + name;
2468a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        link = dirpath + "/index" + Doclava.htmlExtension;
2471b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         String hdfkeyName = (key + i + ".Name");
2481b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         String hdfkeyType = (key + i + ".Type");
2491b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty         String hdfkeyHref = (key + i + ".Href");
2508a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        hdf.setValue(hdfkeyName, name);
2518a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        hdf.setValue(hdfkeyType, type);
2528a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        hdf.setValue(hdfkeyHref, relative + name + "/" + "index" + Doclava.htmlExtension);
2538a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        writeProjectDirectory(f, relative + name + "/", true, hdf, (key + i));
2548a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        i++;
2558a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      }
2568a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    }
2578a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
2581b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    setParentDirs(hdf, relative, name, false);
259e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    //Generate an index.html page for each dir being processed
2608a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    if (FULL_TREE_NAVIGATION) {
2618a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      ClearPage.write(hdf, "sampleindex.cs", relative + "/index" + Doclava.htmlExtension);
2628a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    }
263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
264920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
265c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  /**
266e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty  * Processes a templated project index page from _index.jd in a project root.
267e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty  * Each sample project must have an index, and each index locally defines it's own
268e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty  * page.tags and sample.group cs vars. This method takes a SC node on input, reads
2698a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * any local vars from the _index.jd, optionally generates an html file to out,
2708a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * then updates the SC node with the page vars and returns it to the caller.
271e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty  *
2728a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param hdf The data source to read/write for this index file.
2738a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param dir The sample project root directory.
2748a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param tnode A Node to serve as the project's root node.
2758a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param writeFiles If true, generates output files only. If false, collects
2768a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *        metadata only.
2778a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @return The tnode root with any metadata/child Nodes appended.
278c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  */
2798a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public Node writeSampleIndexCs(Data hdf, File dir, Node tnode, boolean writeFiles) {
2808a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
281e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    String filename = dir.getAbsolutePath() + "/_index.jd";
2828a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    String mGroup = "";
283e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    File f = new File(filename);
284e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    String rel = dir.getPath();
2858a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    if (writeFiles) {
2868a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
2878a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      hdf.setValue("samples", "true");
2888a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      //set any default page variables for root index
2898a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      hdf.setValue("page.title", mProjectDir);
2908a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      hdf.setValue("projectDir", mProjectDir);
2918a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      hdf.setValue("projectTitle", mTitle);
2928a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      //add the download/project links to the landing pages.
2938a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      hdf.setValue("samplesProjectIndex", "true");
2948a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      if (!f.isFile()) {
2958a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        //The directory didn't have an _index.jd, so create a stub.
2968a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        ClearPage.write(hdf, "sampleindex.cs", mDest + "index" + Doclava.htmlExtension);
2978a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      } else {
2988a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        DocFile.writePage(filename, rel, mDest + "index" + Doclava.htmlExtension, hdf);
2998a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      }
3008a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    } else if (f.isFile()) {
3018a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      //gather metadata for toc and jd_lists_unified
3028a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      DocFile.getPageMetadata(filename, hdf);
303e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty      mGroup = hdf.getValue("sample.group", "");
3048a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      if (!"".equals(mGroup)) {
3058a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        tnode.setGroup(hdf.getValue("sample.group", ""));
3068a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      } else {
307e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty        //Errors.error(Errors.INVALID_SAMPLE_INDEX, null, "Sample " + mProjectDir
308e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty        //          + ": Root _index.jd must be present and must define sample.group"
309e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty        //          + " tag. Please see ... for details.");
310e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty      }
311e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    }
312e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    return tnode;
313c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  }
314920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
315c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  /**
3168a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Sets metadata for managing html output and generates the project view page
3178a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * for a project.
3188a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *
3198a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param dir The project root dir.
3208a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param hdf The data to read/write for files in this project.
3218a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
3228a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public void writeProjectStructure(String dir, Data hdf) {
3238a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.setValue("projectStructure", "true");
3248a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.setValue("projectDir", mProjectDir);
3258a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.setValue("page.title", mProjectDir + " Structure");
3268a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.setValue("projectTitle", mTitle);
3278a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    ClearPage.write(hdf, "sampleindex.cs", mDest + "project" + Doclava.htmlExtension);
3288a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.setValue("projectStructure", "");
3298a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  }
3308a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
3318a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /**
3328a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Keeps track of each file's parent dirs. Used for generating path breadcrumbs in html.
3338a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *
3348a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param dir The data to read/write for this file.
3358a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param hdf The relative path for this file, from samples root.
3368a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param subdir The relative path for this file, from samples root.
3378a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param name The name of the file (minus extension).
3388a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param isFile Whether this is a file (not a dir).
339c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  */
340c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  Data setParentDirs(Data hdf, String subdir, String name, Boolean isFile) {
3418a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    if (FULL_TREE_NAVIGATION) {
3428a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      hdf.setValue("linkfyPathCrumb", "");
3438a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    }
344c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    int iter;
345c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    hdf.removeTree("parentdirs");
346c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    String s = subdir;
347c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    String urlParts[] = s.split("/");
348e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    int n, l = 1;
349e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    for (iter=1; iter < urlParts.length; iter++) {
350e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty      n = iter-1;
351c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty      hdf.setValue("parentdirs." + n + ".Name", urlParts[iter]);
352e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty      hdf.setValue("parentdirs." + n + ".Link", subdir + "index" + Doclava.htmlExtension);
353920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
354920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return hdf;
355920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
357c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  /**
3588a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Writes a templated source code file to out.
359c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  */
3608a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public void writePage(File f, String out, String subdir, Data hdf) {
361920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String name = f.getName();
3621b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    String path = f.getPath();
3638a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    String data = SampleTagInfo.readFile(new SourcePositionInfo(path, -1, -1), path,
3648a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        "sample code", true, true, true, true);
365920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data = Doclava.escape(data);
366920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
36725586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    String relative = subdir.replaceFirst("samples/", "");
3681b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    setParentDirs(hdf, subdir, name, true);
3691b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("projectTitle", mTitle);
370c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    hdf.setValue("projectDir", mProjectDir);
371920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("page.title", name);
372920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("subdir", subdir);
37325586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    hdf.setValue("relative", relative);
374920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("realFile", name);
375920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("fileContents", data);
3761b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("resTag", "sample");
377920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
378920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(hdf, "sample.cs", out);
379920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
380920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
381c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  /**
3828a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Writes a templated image or video file to out.
383c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  */
3843542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty  public void writeImageVideoPage(File f, String out, String subdir,
3858a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        String resourceType, boolean browsable) {
386920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Data hdf = Doclava.makeHDF();
3878a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    if (Doclava.samplesNavTree != null) {
3888a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      hdf.setValue("samples_toc_tree", Doclava.samplesNavTree.getValue("samples_toc_tree", ""));
3898a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    }
3908a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    hdf.setValue("samples", "true");
3918a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
3923542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty    String name = f.getName();
3933542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty    if (!browsable) {
3943542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty      hdf.setValue("noDisplay", "true");
3953542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty    }
3961b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    setParentDirs(hdf, subdir, name, true);
3973542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty    hdf.setValue("samples", "true");
398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("page.title", name);
3991b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    hdf.setValue("projectTitle", mTitle);
400c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    hdf.setValue("projectDir", mProjectDir);
401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("subdir", subdir);
4023542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty    hdf.setValue("resType", resourceType);
403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    hdf.setValue("realFile", name);
4048a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
405920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClearPage.write(hdf, "sample.cs", out);
406920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
4071b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
4081b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  /**
4098a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Given a node containing sample code projects and a node containing all valid
4108a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * group nodes, extract project nodes from tnode and append them to the group node
4118a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * that matches their sample.group metadata.
4128a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *
4138a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param tnode A list of nodes containing sample code projects.
4148a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @param groupnodes A list of nodes that represent the valid sample groups.
4158a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * @return The groupnodes list with all projects appended properly to their
4168a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  *         associated sample groups.
4171b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  */
418815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty  public static void writeSamplesNavTree(List<Node> tnode, List<Node> groupnodes) {
419815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty
4208a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    Node node = new Node.Builder().setLabel("Samples").setLink(ClearPage.toroot
4218a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        + "samples/index" + Doclava.htmlExtension).setChildren(tnode).build();
4221b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
423815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    if (groupnodes != null) {
424815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      for (int i = 0; i < tnode.size(); i++) {
425187b985f817b4a0181c5127270a2aab9915cf60aDirk Dougherty        if (tnode.get(i) != null) {
426187b985f817b4a0181c5127270a2aab9915cf60aDirk Dougherty          groupnodes = appendNodeGroups(tnode.get(i), groupnodes);
427187b985f817b4a0181c5127270a2aab9915cf60aDirk Dougherty        }
428815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      }
4291d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty      for (int n = 0; n < groupnodes.size(); n++) {
4301d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty        if (groupnodes.get(n).getChildren() == null) {
4311d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty          groupnodes.remove(n);
4321d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty          n--;
4338a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        } else {
4348a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          Collections.sort(groupnodes.get(n).getChildren(), byLabel);
4351d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty        }
4361d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty      }
437815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      node.setChildren(groupnodes);
438815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    }
439815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty
4401b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    StringBuilder buf = new StringBuilder();
4418a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    node.renderGroupNodesTOC(buf);
4428a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    if (Doclava.samplesNavTree != null) {
4438a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          Doclava.samplesNavTree.setValue("samples_toc_tree", buf.toString());
4441b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
4451b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
4461b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  }
4471b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
44825586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty  /**
4491d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty  * For a given project root node, get the group and then iterate the list of valid
4501d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty  * groups looking for a match. If found, append the project to that group node.
451f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty  * Samples that reference a valid sample group tag are added to a list for that
4521d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty  * group. Samples declare a sample.group tag in their _index.jd files.
453815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty  */
454815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty  private static List<Node> appendNodeGroups(Node gNode, List<Node> groupnodes) {
455815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    List<Node> mgrouplist = new ArrayList<Node>();
4561d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty    for (int i = 0; i < groupnodes.size(); i++) {
457187b985f817b4a0181c5127270a2aab9915cf60aDirk Dougherty      if (gNode.getGroup().equals(groupnodes.get(i).getLabel())) {
458815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty        if (groupnodes.get(i).getChildren() == null) {
4591d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty          mgrouplist.add(gNode);
460815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty          groupnodes.get(i).setChildren(mgrouplist);
4611d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty        } else {
4621d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty          groupnodes.get(i).getChildren().add(gNode);
463815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty        }
464815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty        break;
4651d8fa8ddfef0080a63faf8ec09c69bd5f00ee601Dirk Dougherty      }
466815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    }
467815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    return groupnodes;
468815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty  }
469815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty
470815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty  /**
4718a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Sorts an array of files by type and name (alpha), with manifest always at top.
47225586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty  */
473c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  Comparator<File> byTypeAndName = new Comparator<File>() {
474c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    public int compare (File one, File other) {
475c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty      if (one.isDirectory() && !other.isDirectory()) {
476c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty        return 1;
477c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty      } else if (!one.isDirectory() && other.isDirectory()) {
478c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty        return -1;
479187b985f817b4a0181c5127270a2aab9915cf60aDirk Dougherty      } else if ("AndroidManifest.xml".equals(one.getName())) {
48025586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty        return -1;
481c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty      } else {
482c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty        return one.compareTo(other);
483c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty      }
484c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    }
485c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty  };
486c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty
4871b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  /**
4888a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Sorts a list of Nodes by label.
4898a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
4908a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public static Comparator<Node> byLabel = new Comparator<Node>() {
4918a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    public int compare(Node one, Node other) {
4928a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      return one.getLabel().compareTo(other.getLabel());
4938a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    }
4948a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  };
4958a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
4968a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /**
4978a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Concatenates dirs that only hold dirs, to simplify nav tree
49825586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty  */
499815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty  public static List<Node> squashNodes(List<Node> tnode) {
50025586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    List<Node> list = tnode;
50125586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty
50225586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    for(int i = 0; i < list.size(); ++i) {
503187b985f817b4a0181c5127270a2aab9915cf60aDirk Dougherty      if (("dir".equals(list.get(i).getType())) &&
50425586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty          (list.size() == 1) &&
50525586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty          (list.get(i).getChildren().get(0).getChildren() != null)) {
50625586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty        String thisLabel = list.get(i).getLabel();
50725586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty        String childLabel =  list.get(i).getChildren().get(0).getLabel();
50825586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty        String newLabel = thisLabel + "/" + childLabel;
50925586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty        list.get(i).setLabel(newLabel);
51025586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty        list.get(i).setChildren(list.get(i).getChildren().get(0).getChildren());
51125586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty      } else {
51225586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty        continue;
51325586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty      }
51425586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    }
51525586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    return list;
51625586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty  }
51725586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty
5188a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public static String convertExtension(String s, String ext) {
5198a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    return s.substring(0, s.lastIndexOf('.')) + ext;
5208a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  }
5218a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
5228a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /**
5238a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Whitelists of valid image/video and source code types.
5248a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
5258a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public static String[] IMAGES = {".png", ".jpg", ".gif"};
5268a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public static String[] VIDEOS = {".mp4", ".ogv", ".webm"};
5278a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public static String[] TEMPLATED = {".java", ".xml", ".aidl", ".rs",".txt", ".TXT"};
5288a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
5298a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public static boolean inList(String s, String[] list) {
5308a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    for (String t : list) {
5318a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      if (s.endsWith(t)) {
5328a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        return true;
5338a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      }
5348a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    }
5358a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    return false;
5368a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  }
5378a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
5388a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /**
5398a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Maps filenames to a set of generic types. Used for displaying files/dirs
5408a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * in the project view page.
5418a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
5428a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public static String mapTypes(String name) {
5438a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    String type = name.substring(name.lastIndexOf('.') + 1, name.length());
5448a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    if ("xml".equals(type) || "java".equals(type)) {
5458a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      if ("AndroidManifest.xml".equals(name)) type = "manifest";
5468a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      return type;
5478a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    } else {
5488a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      return type = "file";
5498a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    }
5508a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  }
5518a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
5528a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  /**
5538a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * Validates a source file from a project against restrictions to determine
5548a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  * whether to include the file in the browsable project output.
5558a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  */
5568a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  public boolean isValidFiletype(String name) {
5578a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    if (name.startsWith(".") ||
5588a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        name.startsWith("_") ||
5598a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        "default.properties".equals(name) ||
5608a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        "build.properties".equals(name) ||
5618a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        name.endsWith(".ttf") ||
5628a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        name.endsWith(".gradle") ||
5638a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        name.endsWith(".bat") ||
5648a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        "Android.mk".equals(name)) {
5658a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      return false;
5668a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    } else {
5678a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      return true;
5688a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    }
5698a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty  }
5708a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty
57125586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty  /**
5721b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  * SampleCode variant of NavTree node.
5731b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  */
5741b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty  public static class Node {
5751b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    private String mLabel;
5761b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    private String mLink;
577e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    private String mGroup; // from sample.group in _index.jd
57825586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    private List<Node> mChildren;
57925586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    private String mType;
5801b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
581f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty    private Node(Builder builder) {
582f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      mLabel = builder.mLabel;
583f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      mLink = builder.mLink;
584f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      mGroup = builder.mGroup;
585f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      mChildren = builder.mChildren;
586f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      mType = builder.mType;
5871b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
588f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty
589f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty    public static class Builder {
590f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      private String mLabel, mLink, mGroup, mType;
591f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      private List<Node> mChildren = null;
592f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      public Builder setLabel(String mLabel) { this.mLabel = mLabel; return this;}
593f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      public Builder setLink(String mLink) { this.mLink = mLink; return this;}
594f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      public Builder setGroup(String mGroup) { this.mGroup = mGroup; return this;}
595f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      public Builder setChildren(List<Node> mChildren) { this.mChildren = mChildren; return this;}
596f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      public Builder setType(String mType) { this.mType = mType; return this;}
597f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty      public Node build() {return new Node(this);}
598f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty    }
599f9d9cb045339e902b36391d19be3c665b1585ab8Dirk Dougherty
6008a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    /**
6018a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    * Renders browsable sample groups and projects to an html list, starting
6028a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    * from the group nodes and then rendering their project nodes and finally their
6038a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    * child dirs and files.
6048a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    */
6058a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    void renderGroupNodesTOC(StringBuilder buf) {
6068a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      List<Node> list = mChildren;
6078a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      if (list == null || list.size() == 0) {
6088a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        return;
6091b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      } else {
6108a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        final int n = list.size();
6118a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        for (int i = 0; i < n; i++) {
6128a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          if (list.get(i).getChildren() == null) {
6138a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            continue;
6141b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          } else {
6158a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<li class=\"nav-section\">");
6168a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<div class=\"nav-section-header\">");
6178a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<a href=\"" + list.get(i).getLink() + "\" title=\""
6188a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty                + list.get(i).getLabel() + "\">"
6198a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty                + list.get(i).getLabel() + "</a>");
6208a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("</div>");
6218a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<ul>");
6228a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            list.get(i).renderProjectNodesTOC(buf);
6231b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          }
6241b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        }
6258a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        buf.append("</ul>");
6268a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        buf.append("</li>");
6271b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      }
6281b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
6291b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
6308a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    /**
6318a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    * Renders a list of sample code projects associated with a group node.
6328a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    */
6338a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    void renderProjectNodesTOC(StringBuilder buf) {
6341b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      List<Node> list = mChildren;
6351b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      if (list == null || list.size() == 0) {
6368a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        return;
6371b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      } else {
6388a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        final int n = list.size();
6398a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        for (int i = 0; i < n; i++) {
6408a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          if (list.get(i).getChildren() == null) {
6418a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            continue;
6428a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          } else {
6438a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<li class=\"nav-section\">");
6448a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<div class=\"nav-section-header\">");
6458a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<a href=\"" + list.get(i).getLink() + "\" title=\""
6468a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty                + list.get(i).getLabel() + "\">"
6478a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty                + list.get(i).getLabel() + "</a>");
6488a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("</div>");
6498a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<ul>");
6508a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            list.get(i).renderChildrenToc(buf);
6511b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty          }
6521b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty        }
6538a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        buf.append("</ul>");
6548a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        buf.append("</li>");
6551b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty      }
6561b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty    }
6571b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
6588a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    /**
6598a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    * Renders child dirs and files associated with a project node.
6608a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    */
6618a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    void renderChildrenToc(StringBuilder buf) {
6628a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      List<Node> list = mChildren;
663e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty      if (list == null || list.size() == 0) {
664e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty        buf.append("null");
665e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty      } else {
6668a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        final int n = list.size();
6678a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        for (int i = 0; i < n; i++) {
6688a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          if (list.get(i).getChildren() == null) {
6698a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<li>");
6708a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<a href=\"" + list.get(i).getLink() + "\" title=\""
6718a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty                + list.get(i).getLabel() + "\">"
6728a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty                + list.get(i).getLabel() + "</a>");
6738a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("  </li>");
6748a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty          } else {
6758a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<li class=\"nav-section sticky\">");
6768a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<div class=\"nav-section-header empty\">");
6778a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<a href=\"#\" onclick=\"return false;\" title=\""
6788a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty                + list.get(i).getLabel() + "\">"
6798a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty                + list.get(i).getLabel() + "/</a>");
6808a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("</div>");
6818a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            buf.append("<ul>");
6828a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty            list.get(i).renderChildrenToc(buf);
683e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty          }
684e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty        }
6858a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        buf.append("</ul>");
6868a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        buf.append("</li>");
68725586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty      }
68825586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    }
68925586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty
6908a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    /**
6918a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    * Node getters and setters
6928a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    */
69325586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    public String getLabel() {
69425586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty      return mLabel;
69525586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    }
69625586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty
69725586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    public void setLabel(String label) {
69825586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty       mLabel = label;
69925586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    }
70025586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty
7018a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    public String getLink() {
70225586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty      return mLink;
70325586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    }
70425586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty
7058a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    public void setLink(String ref) {
7068a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty       mLink = ref;
70725586c08d0a5068159d1c9482f0eaec0d8cc3d50Dirk Dougherty    }
708e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty
709815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    public String getGroup() {
710815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      return mGroup;
711e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    }
712e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty
713815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty    public void setGroup(String group) {
714815f9342d2b82cf61e56e64cbea46079215041beDirk Dougherty      mGroup = group;
715e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    }
716e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty
7178a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    public List<Node> getChildren() {
7188a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        return mChildren;
719e52f6d819e7d95e19e9b315f358bb7ac293413d8Dirk Dougherty    }
7201b45d1d08a4ff984e1d0741dd13f0759f6527ebfDirk Dougherty
7218a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    public void setChildren(List<Node> node) {
7228a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty        mChildren = node;
723c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    }
724c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty
7258a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    public String getType() {
7268a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      return mType;
727c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    }
728c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty
7298a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty    public void setType(String type) {
7308a8f7912692bcf9f984a7a24eaf47da69b6d2992Dirk Dougherty      mType = type;
731c11a467135f9118604f31fadc99d2edd494edb0bDirk Dougherty    }
7323542770e7b9e121d1a3107300af1aac1b2555128Dirk Dougherty  }
733920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
734